Merge git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
diff --git a/Documentation/devicetree/bindings/sound/sgtl5000.txt b/Documentation/devicetree/bindings/sound/sgtl5000.txt index 2c3cd41..9cc4444 100644 --- a/Documentation/devicetree/bindings/sound/sgtl5000.txt +++ b/Documentation/devicetree/bindings/sound/sgtl5000.txt
@@ -3,6 +3,8 @@ Required properties: - compatible : "fsl,sgtl5000". +- reg : the I2C address of the device + Example: codec: sgtl5000@0a {
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 968ed08..04d81d2 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt
@@ -551,3 +551,13 @@ Why: setitimer is not returning -EFAULT if user pointer is NULL. This violates the spec. Who: Sasikantha Babu <sasikanth.v19@gmail.com> + +---------------------------- + +What: V4L2_CID_HCENTER, V4L2_CID_VCENTER V4L2 controls +When: 3.7 +Why: The V4L2_CID_VCENTER, V4L2_CID_HCENTER controls have been deprecated + for about 4 years and they are not used by any mainline driver. + There are newer controls (V4L2_CID_PAN*, V4L2_CID_TILT*) that provide + similar functionality. +Who: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index b7413cb..ef088e5 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt
@@ -996,7 +996,6 @@ snmp SNMP data sockstat Socket statistics tcp TCP sockets - tr_rif Token ring RIF routing table udp UDP sockets unix UNIX domain sockets wireless Wireless interface data (Wavelan etc)
diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX index 9ad9ddeb..2cc3c77 100644 --- a/Documentation/networking/00-INDEX +++ b/Documentation/networking/00-INDEX
@@ -1,7 +1,5 @@ 00-INDEX - this file -3c359.txt - - information on the 3Com TokenLink Velocity XL (3c5359) driver. 3c505.txt - information on the 3Com EtherLink Plus (3c505) driver. 3c509.txt @@ -142,8 +140,6 @@ - Design of the network interface message level setting (NETIF_MSG_*). nfc.txt - The Linux Near Field Communication (NFS) subsystem. -olympic.txt - - IBM PCI Pit/Pit-Phy/Olympic Token Ring driver info. openvswitch.txt - Open vSwitch developer documentation. operstates.txt @@ -184,8 +180,6 @@ - SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info. smc9.txt - the driver for SMC's 9000 series of Ethernet cards -smctr.txt - - SMC TokenCard TokenRing Linux driver info. spider-net.txt - README for the Spidernet Driver (as found in PS3 / Cell BE). stmmac.txt @@ -200,8 +194,6 @@ - kernel tuning options for low rate 'thin' TCP streams. tlan.txt - ThunderLAN (Compaq Netelligent 10/100, Olicom OC-2xxx) driver info. -tms380tr.txt - - SysKonnect Token Ring ISA/PCI adapter driver info. tproxy.txt - Transparent proxy support user guide. tuntap.txt
diff --git a/Documentation/networking/3c359.txt b/Documentation/networking/3c359.txt deleted file mode 100644 index dadfe81..0000000 --- a/Documentation/networking/3c359.txt +++ /dev/null
@@ -1,58 +0,0 @@ - -3COM PCI TOKEN LINK VELOCITY XL TOKEN RING CARDS README - -Release 0.9.0 - Release - Jul 17th 2000 Mike Phillips - - 1.2.0 - Final - Feb 17th 2002 Mike Phillips - Updated for submission to the 2.4.x kernel. - -Thanks: - Terry Murphy from 3Com for tech docs and support, - Adam D. Ligas for testing the driver. - -Note: - This driver will NOT work with the 3C339 Token Ring cards, you need -to use the tms380 driver instead. - -Options: - -The driver accepts three options: ringspeed, pkt_buf_sz and message_level. - -These options can be specified differently for each card found. - -ringspeed: Has one of three settings 0 (default), 4 or 16. 0 will -make the card autosense the ringspeed and join at the appropriate speed, -this will be the default option for most people. 4 or 16 allow you to -explicitly force the card to operate at a certain speed. The card will fail -if you try to insert it at the wrong speed. (Although some hubs will allow -this so be *very* careful). The main purpose for explicitly setting the ring -speed is for when the card is first on the ring. In autosense mode, if the card -cannot detect any active monitors on the ring it will open at the same speed as -its last opening. This can be hazardous if this speed does not match the speed -you want the ring to operate at. - -pkt_buf_sz: This is this initial receive buffer allocation size. This will -default to 4096 if no value is entered. You may increase performance of the -driver by setting this to a value larger than the network packet size, although -the driver now re-sizes buffers based on MTU settings as well. - -message_level: Controls level of messages created by the driver. Defaults to 0: -which only displays start-up and critical messages. Presently any non-zero -value will display all soft messages as well. NB This does not turn -debugging messages on, that must be done by modified the source code. - -Variable MTU size: - -The driver can handle a MTU size up to either 4500 or 18000 depending upon -ring speed. The driver also changes the size of the receive buffers as part -of the mtu re-sizing, so if you set mtu = 18000, you will need to be able -to allocate 16 * (sk_buff with 18000 buffer size) call it 18500 bytes per ring -position = 296,000 bytes of memory space, plus of course anything -necessary for the tx sk_buff's. Remember this is per card, so if you are -building routers, gateway's etc, you could start to use a lot of memory -real fast. - -2/17/02 Mike Phillips -
diff --git a/Documentation/networking/3c509.txt b/Documentation/networking/3c509.txt index dcc9eaf..fbf722e 100644 --- a/Documentation/networking/3c509.txt +++ b/Documentation/networking/3c509.txt
@@ -25,7 +25,6 @@ 3c509B (later revision of the ISA card; supports full-duplex) 3c589 (PCMCIA) 3c589B (later revision of the 3c589; supports full-duplex) - 3c529 (MCA) 3c579 (EISA) Large portions of this documentation were heavily borrowed from the guide
diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt index 220a58c2..75a5923 100644 --- a/Documentation/networking/batman-adv.txt +++ b/Documentation/networking/batman-adv.txt
@@ -1,5 +1,3 @@ -[state: 21-08-2011] - BATMAN-ADV ---------- @@ -68,10 +66,11 @@ folder: # ls /sys/class/net/bat0/mesh/ -# aggregated_ogms fragmentation hop_penalty -# ap_isolation gw_bandwidth log_level -# bonding gw_mode orig_interval -# bridge_loop_avoidance gw_sel_class vis_mode +# aggregated_ogms gw_bandwidth log_level +# ap_isolation gw_mode orig_interval +# bonding gw_sel_class routing_algo +# bridge_loop_avoidance hop_penalty vis_mode +# fragmentation There is a special folder for debugging information:
diff --git a/Documentation/networking/fore200e.txt b/Documentation/networking/fore200e.txt index f648eb2..d52af53 100644 --- a/Documentation/networking/fore200e.txt +++ b/Documentation/networking/fore200e.txt
@@ -11,12 +11,10 @@ The intent is to enable the use of different models of FORE adapters at the same time, by hosts that have several bus interfaces (such as PCI+SBUS, -PCI+MCA or PCI+EISA). +or PCI+EISA). Only PCI and SBUS devices are currently supported by the driver, but support -for other bus interfaces such as EISA should not be too hard to add (this may -be more tricky for the MCA bus, though, as FORE made some MCA-specific -modifications to the adapter's AALI interface). +for other bus interfaces such as EISA should not be too hard to add. Firmware Copyright Notice
diff --git a/Documentation/networking/ieee802154.txt b/Documentation/networking/ieee802154.txt index 1dc1c24..703cf43 100644 --- a/Documentation/networking/ieee802154.txt +++ b/Documentation/networking/ieee802154.txt
@@ -4,15 +4,22 @@ Introduction ============ +The IEEE 802.15.4 working group focuses on standartization of bottom +two layers: Medium Accsess Control (MAC) and Physical (PHY). And there +are mainly two options available for upper layers: + - ZigBee - proprietary protocol from ZigBee Alliance + - 6LowPAN - IPv6 networking over low rate personal area networks The Linux-ZigBee project goal is to provide complete implementation -of IEEE 802.15.4 / ZigBee / 6LoWPAN protocols. IEEE 802.15.4 is a stack +of IEEE 802.15.4 and 6LoWPAN protocols. IEEE 802.15.4 is a stack of protocols for organizing Low-Rate Wireless Personal Area Networks. -Currently only IEEE 802.15.4 layer is implemented. We have chosen -to use plain Berkeley socket API, the generic Linux networking stack -to transfer IEEE 802.15.4 messages and a special protocol over genetlink -for configuration/management +The stack is composed of three main parts: + - IEEE 802.15.4 layer; We have chosen to use plain Berkeley socket API, + the generic Linux networking stack to transfer IEEE 802.15.4 messages + and a special protocol over genetlink for configuration/management + - MAC - provides access to shared channel and reliable data delivery + - PHY - represents device drivers Socket API @@ -29,15 +36,6 @@ One can use SOCK_RAW for passing raw data towards device xmit function. YMMV. -MLME - MAC Level Management -============================ - -Most of IEEE 802.15.4 MLME interfaces are directly mapped on netlink commands. -See the include/net/nl802154.h header. Our userspace tools package -(see above) provides CLI configuration utility for radio interfaces and simple -coordinator for IEEE 802.15.4 networks as an example users of MLME protocol. - - Kernel side ============= @@ -51,6 +49,15 @@ Those types of devices require different approach to be hooked into Linux kernel. +MLME - MAC Level Management +============================ + +Most of IEEE 802.15.4 MLME interfaces are directly mapped on netlink commands. +See the include/net/nl802154.h header. Our userspace tools package +(see above) provides CLI configuration utility for radio interfaces and simple +coordinator for IEEE 802.15.4 networks as an example users of MLME protocol. + + HardMAC ======= @@ -73,11 +80,47 @@ SoftMAC ======= -We are going to provide intermediate layer implementing IEEE 802.15.4 MAC -in software. This is currently WIP. +The MAC is the middle layer in the IEEE 802.15.4 Linux stack. This moment it +provides interface for drivers registration and management of slave interfaces. + +NOTE: Currently the only monitor device type is supported - it's IEEE 802.15.4 +stack interface for network sniffers (e.g. WireShark). + +This layer is going to be extended soon. See header include/net/mac802154.h and several drivers in drivers/ieee802154/. + +Device drivers API +================== + +The include/net/mac802154.h defines following functions: + - struct ieee802154_dev *ieee802154_alloc_device + (size_t priv_size, struct ieee802154_ops *ops): + allocation of IEEE 802.15.4 compatible device + + - void ieee802154_free_device(struct ieee802154_dev *dev): + freeing allocated device + + - int ieee802154_register_device(struct ieee802154_dev *dev): + register PHY in the system + + - void ieee802154_unregister_device(struct ieee802154_dev *dev): + freeing registered PHY + +Moreover IEEE 802.15.4 device operations structure should be filled. + +Fake drivers +============ + +In addition there are two drivers available which simulate real devices with +HardMAC (fakehard) and SoftMAC (fakelb - IEEE 802.15.4 loopback driver) +interfaces. This option provides possibility to test and debug stack without +usage of real hardware. + +See sources in drivers/ieee802154 folder for more details. + + 6LoWPAN Linux implementation ============================
diff --git a/Documentation/networking/olympic.txt b/Documentation/networking/olympic.txt deleted file mode 100644 index b95b5bf..0000000 --- a/Documentation/networking/olympic.txt +++ /dev/null
@@ -1,79 +0,0 @@ - -IBM PCI Pit/Pit-Phy/Olympic CHIPSET BASED TOKEN RING CARDS README - -Release 0.2.0 - Release - June 8th 1999 Peter De Schrijver & Mike Phillips -Release 0.9.C - Release - April 18th 2001 Mike Phillips - -Thanks: -Erik De Cock, Adrian Bridgett and Frank Fiene for their -patience and testing. -Donald Champion for the cardbus support -Kyle Lucke for the dma api changes. -Jonathon Bitner for hardware support. -Everybody on linux-tr for their continued support. - -Options: - -The driver accepts four options: ringspeed, pkt_buf_sz, -message_level and network_monitor. - -These options can be specified differently for each card found. - -ringspeed: Has one of three settings 0 (default), 4 or 16. 0 will -make the card autosense the ringspeed and join at the appropriate speed, -this will be the default option for most people. 4 or 16 allow you to -explicitly force the card to operate at a certain speed. The card will fail -if you try to insert it at the wrong speed. (Although some hubs will allow -this so be *very* careful). The main purpose for explicitly setting the ring -speed is for when the card is first on the ring. In autosense mode, if the card -cannot detect any active monitors on the ring it will not open, so you must -re-init the card at the appropriate speed. Unfortunately at present the only -way of doing this is rmmod and insmod which is a bit tough if it is compiled -in the kernel. - -pkt_buf_sz: This is this initial receive buffer allocation size. This will -default to 4096 if no value is entered. You may increase performance of the -driver by setting this to a value larger than the network packet size, although -the driver now re-sizes buffers based on MTU settings as well. - -message_level: Controls level of messages created by the driver. Defaults to 0: -which only displays start-up and critical messages. Presently any non-zero -value will display all soft messages as well. NB This does not turn -debugging messages on, that must be done by modified the source code. - -network_monitor: Any non-zero value will provide a quasi network monitoring -mode. All unexpected MAC frames (beaconing etc.) will be received -by the driver and the source and destination addresses printed. -Also an entry will be added in /proc/net called olympic_tr%d, where tr%d -is the registered device name, i.e tr0, tr1, etc. This displays low -level information about the configuration of the ring and the adapter. -This feature has been designed for network administrators to assist in -the diagnosis of network / ring problems. (This used to OLYMPIC_NETWORK_MONITOR, -but has now changed to allow each adapter to be configured differently and -to alleviate the necessity to re-compile olympic to turn the option on). - -Multi-card: - -The driver will detect multiple cards and will work with shared interrupts, -each card is assigned the next token ring device, i.e. tr0 , tr1, tr2. The -driver should also happily reside in the system with other drivers. It has -been tested with ibmtr.c running, and I personally have had one Olicom PCI -card and two IBM olympic cards (all on the same interrupt), all running -together. - -Variable MTU size: - -The driver can handle a MTU size up to either 4500 or 18000 depending upon -ring speed. The driver also changes the size of the receive buffers as part -of the mtu re-sizing, so if you set mtu = 18000, you will need to be able -to allocate 16 * (sk_buff with 18000 buffer size) call it 18500 bytes per ring -position = 296,000 bytes of memory space, plus of course anything -necessary for the tx sk_buff's. Remember this is per card, so if you are -building routers, gateway's etc, you could start to use a lot of memory -real fast. - - -6/8/99 Peter De Schrijver and Mike Phillips -
diff --git a/Documentation/networking/smctr.txt b/Documentation/networking/smctr.txt deleted file mode 100644 index 9af25b8..0000000 --- a/Documentation/networking/smctr.txt +++ /dev/null
@@ -1,66 +0,0 @@ -Text File for the SMC TokenCard TokenRing Linux driver (smctr.c). - By Jay Schulist <jschlst@samba.org> - -The Linux SMC Token Ring driver works with the SMC TokenCard Elite (8115T) -ISA and SMC TokenCard Elite/A (8115T/A) MCA adapters. - -Latest information on this driver can be obtained on the Linux-SNA WWW site. -Please point your browser to: http://www.linux-sna.org - -This driver is rather simple to use. Select Y to Token Ring adapter support -in the kernel configuration. A choice for SMC Token Ring adapters will -appear. This drives supports all SMC ISA/MCA adapters. Choose this -option. I personally recommend compiling the driver as a module (M), but if you -you would like to compile it statically answer Y instead. - -This driver supports multiple adapters without the need to load multiple copies -of the driver. You should be able to load up to 7 adapters without any kernel -modifications, if you are in need of more please contact the maintainer of this -driver. - -Load the driver either by lilo/loadlin or as a module. When a module using the -following command will suffice for most: - -# modprobe smctr -smctr.c: v1.00 12/6/99 by jschlst@samba.org -tr0: SMC TokenCard 8115T at Io 0x300, Irq 10, Rom 0xd8000, Ram 0xcc000. - -Now just setup the device via ifconfig and set and routes you may have. After -this you are ready to start sending some tokens. - -Errata: -1). For anyone wondering where to pick up the SMC adapters please browse - to http://www.smc.com - -2). If you are the first/only Token Ring Client on a Token Ring LAN, please - specify the ringspeed with the ringspeed=[4/16] module option. If no - ringspeed is specified the driver will attempt to autodetect the ring - speed and/or if the adapter is the first/only station on the ring take - the appropriate actions. - - NOTE: Default ring speed is 16MB UTP. - -3). PnP support for this adapter sucks. I recommend hard setting the - IO/MEM/IRQ by the jumpers on the adapter. If this is not possible - load the module with the following io=[ioaddr] mem=[mem_addr] - irq=[irq_num]. - - The following IRQ, IO, and MEM settings are supported. - - IO ports: - 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300, - 0x320, 0x340, 0x360, 0x380. - - IRQs: - 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15 - - Memory addresses: - 0xA0000, 0xA4000, 0xA8000, 0xAC000, 0xB0000, 0xB4000, - 0xB8000, 0xBC000, 0xC0000, 0xC4000, 0xC8000, 0xCC000, - 0xD0000, 0xD4000, 0xD8000, 0xDC000, 0xE0000, 0xE4000, - 0xE8000, 0xEC000, 0xF0000, 0xF4000, 0xF8000, 0xFC000 - -This driver is under the GNU General Public License. Its Firmware image is -included as an initialized C-array and is licensed by SMC to the Linux -users of this driver. However no warranty about its fitness is expressed or -implied by SMC.
diff --git a/Documentation/networking/tms380tr.txt b/Documentation/networking/tms380tr.txt deleted file mode 100644 index 1f73e13..0000000 --- a/Documentation/networking/tms380tr.txt +++ /dev/null
@@ -1,147 +0,0 @@ -Text file for the Linux SysKonnect Token Ring ISA/PCI Adapter Driver. - Text file by: Jay Schulist <jschlst@samba.org> - -The Linux SysKonnect Token Ring driver works with the SysKonnect TR4/16(+) ISA, -SysKonnect TR4/16(+) PCI, SysKonnect TR4/16 PCI, and older revisions of the -SK NET TR4/16 ISA card. - -Latest information on this driver can be obtained on the Linux-SNA WWW site. -Please point your browser to: -http://www.linux-sna.org - -Many thanks to Christoph Goos for his excellent work on this driver and -SysKonnect for donating the adapters to Linux-SNA for the testing and -maintenance of this device driver. - -Important information to be noted: -1. Adapters can be slow to open (~20 secs) and close (~5 secs), please be - patient. -2. This driver works very well when autoprobing for adapters. Why even - think about those nasty io/int/dma settings of modprobe when the driver - will do it all for you! - -This driver is rather simple to use. Select Y to Token Ring adapter support -in the kernel configuration. A choice for SysKonnect Token Ring adapters will -appear. This drives supports all SysKonnect ISA and PCI adapters. Choose this -option. I personally recommend compiling the driver as a module (M), but if you -you would like to compile it statically answer Y instead. - -This driver supports multiple adapters without the need to load multiple copies -of the driver. You should be able to load up to 7 adapters without any kernel -modifications, if you are in need of more please contact the maintainer of this -driver. - -Load the driver either by lilo/loadlin or as a module. When a module using the -following command will suffice for most: - -# modprobe sktr - -This will produce output similar to the following: (Output is user specific) - -sktr.c: v1.01 08/29/97 by Christoph Goos -tr0: SK NET TR 4/16 PCI found at 0x6100, using IRQ 17. -tr1: SK NET TR 4/16 PCI found at 0x6200, using IRQ 16. -tr2: SK NET TR 4/16 ISA found at 0xa20, using IRQ 10 and DMA 5. - -Now just setup the device via ifconfig and set and routes you may have. After -this you are ready to start sending some tokens. - -Errata: -For anyone wondering where to pick up the SysKonnect adapters please browse -to http://www.syskonnect.com - -This driver is under the GNU General Public License. Its Firmware image is -included as an initialized C-array and is licensed by SysKonnect to the Linux -users of this driver. However no warranty about its fitness is expressed or -implied by SysKonnect. - -Below find attached the setting for the SK NET TR 4/16 ISA adapters -------------------------------------------------------------------- - - *************************** - *** C O N T E N T S *** - *************************** - - 1) Location of DIP-Switch W1 - 2) Default settings - 3) DIP-Switch W1 description - - - ============================================================== - CHAPTER 1 LOCATION OF DIP-SWITCH - ============================================================== - -UÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ -þUÄÄÄÄÄÄ¿ UÄÄÄÄÄ¿ UÄÄÄ¿ þ -þAÄÄÄÄÄÄU W1 AÄÄÄÄÄU UÄÄÄÄ¿ þ þ þ -þUÄÄÄÄÄÄ¿ þ þ þ þ UÄÄÅ¿ -þAÄÄÄÄÄÄU UÄÄÄÄÄÄÄÄÄÄÄ¿ AÄÄÄÄU þ þ þ þþ -þUÄÄÄÄÄÄ¿ þ þ UÄÄÄ¿ AÄÄÄU AÄÄÅU -þAÄÄÄÄÄÄU þ TMS380C26 þ þ þ þ -þUÄÄÄÄÄÄ¿ þ þ AÄÄÄU AÄ¿ -þAÄÄÄÄÄÄU þ þ þ þ -þ AÄÄÄÄÄÄÄÄÄÄÄU þ þ -þ þ þ -þ AÄU -þ þ -þ þ -þ þ -þ þ -AÄÄÄÄÄÄÄÄÄÄÄÄAÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄAÄÄAÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄAÄÄÄÄÄÄÄÄÄU - AÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄU AÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄU - - ============================================================== - CHAPTER 2 DEFAULT SETTINGS - ============================================================== - - W1 1 2 3 4 5 6 7 8 - +------------------------------+ - | ON X | - | OFF X X X X X X X | - +------------------------------+ - - W1.1 = ON Adapter drives address lines SA17..19 - W1.2 - 1.5 = OFF BootROM disabled - W1.6 - 1.8 = OFF I/O address 0A20h - - ============================================================== - CHAPTER 3 DIP SWITCH W1 DESCRIPTION - ============================================================== - - UÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄ¿ ON - þ 1 þ 2 þ 3 þ 4 þ 5 þ 6 þ 7 þ 8 þ - AÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄU OFF - |AD | BootROM Addr. | I/O | - +-+-+-------+-------+-----+-----+ - | | | - | | +------ 6 7 8 - | | ON ON ON 1900h - | | ON ON OFF 0900h - | | ON OFF ON 1980h - | | ON OFF OFF 0980h - | | OFF ON ON 1b20h - | | OFF ON OFF 0b20h - | | OFF OFF ON 1a20h - | | OFF OFF OFF 0a20h (+) - | | - | | - | +-------- 2 3 4 5 - | OFF x x x disabled (+) - | ON ON ON ON C0000 - | ON ON ON OFF C4000 - | ON ON OFF ON C8000 - | ON ON OFF OFF CC000 - | ON OFF ON ON D0000 - | ON OFF ON OFF D4000 - | ON OFF OFF ON D8000 - | ON OFF OFF OFF DC000 - | - | - +----- 1 - OFF adapter does NOT drive SA<17..19> - ON adapter drives SA<17..19> (+) - - - (+) means default setting - - ********************************
diff --git a/Documentation/sparc/README-2.5 b/Documentation/sparc/README-2.5 deleted file mode 100644 index 806fe49..0000000 --- a/Documentation/sparc/README-2.5 +++ /dev/null
@@ -1,46 +0,0 @@ -BTFIXUP -------- - -To build new kernels you have to issue "make image". The ready kernel -in ELF format is placed in arch/sparc/boot/image. Explanation is below. - -BTFIXUP is a unique feature of Linux/sparc among other architectures, -developed by Jakub Jelinek (I think... Obviously David S. Miller took -part, too). It allows to boot the same kernel at different -sub-architectures, such as sun4c, sun4m, sun4d, where SunOS uses -different kernels. This feature is convinient for people who you move -disks between boxes and for distrution builders. - -To function, BTFIXUP must link the kernel "in the draft" first, -analyze the result, write a special stub code based on that, and -build the final kernel with the stub (btfix.o). - -Kai Germaschewski improved the build system of the kernel in the 2.5 series -significantly. Unfortunately, the traditional way of running the draft -linking from architecture specific Makefile before the actual linking -by generic Makefile is nearly impossible to support properly in the -new build system. Therefore, the way we integrate BTFIXUP with the -build system was changed in 2.5.40. Now, generic Makefile performs -the draft linking and stores the result in file vmlinux. Architecture -specific post-processing invokes BTFIXUP machinery and final linking -in the same way as other architectures do bootstraps. - -Implications of that change are as follows. - -1. Hackers must type "make image" now, instead of just "make", in the same - way as s390 people do now. It is analogous to "make bzImage" on i386. - This does NOT affect sparc64, you continue to use "make" to build sparc64 - kernels. - -2. vmlinux is not the final kernel, so RPM builders have to adjust - their spec files (if they delivered vmlinux for debugging). - System.map generated for vmlinux is still valid. - -3. Scripts that produce a.out images have to be changed. First, if they - invoke make, they have to use "make image". Second, they have to pick up - the new kernel in arch/sparc/boot/image instead of vmlinux. - -4. Since we are compliant with Kai's build system now, make -j is permitted. - --- Pete Zaitcev -zaitcev@yahoo.com
diff --git a/MAINTAINERS b/MAINTAINERS index 887c965..490dd6e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS
@@ -1969,10 +1969,9 @@ F: drivers/net/ethernet/ti/cpmac.c CPU FREQUENCY DRIVERS -M: Dave Jones <davej@redhat.com> +M: Rafael J. Wysocki <rjw@sisk.pl> L: cpufreq@vger.kernel.org -W: http://www.codemonkey.org.uk/projects/cpufreq/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git +L: linux-pm@vger.kernel.org S: Maintained F: drivers/cpufreq/ F: include/linux/cpufreq.h @@ -4032,6 +4031,7 @@ F: drivers/scsi/53c700* LED SUBSYSTEM +M: Bryan Wu <bryan.wu@canonical.com> M: Richard Purdie <rpurdie@rpsys.net> S: Maintained F: drivers/leds/
diff --git a/Makefile b/Makefile index a06ee9f..a687963 100644 --- a/Makefile +++ b/Makefile
@@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -rc5 +EXTRAVERSION = NAME = Saber-toothed Squirrel # *DOCUMENTATION* @@ -442,7 +442,7 @@ no-dot-config-targets := clean mrproper distclean \ cscope gtags TAGS tags help %docs check% coccicheck \ - include/linux/version.h headers_% archheaders \ + include/linux/version.h headers_% archheaders archscripts \ kernelversion %src-pkg config-targets := 0 @@ -979,7 +979,7 @@ include/config/auto.conf $(cmd_crmodverdir) -archprepare: archheaders prepare1 scripts_basic +archprepare: archheaders archscripts prepare1 scripts_basic prepare0: archprepare FORCE $(Q)$(MAKE) $(build)=. @@ -1049,8 +1049,11 @@ PHONY += archheaders archheaders: +PHONY += archscripts +archscripts: + PHONY += __headers -__headers: include/linux/version.h scripts_basic asm-generic archheaders FORCE +__headers: include/linux/version.h scripts_basic asm-generic archheaders archscripts FORCE $(Q)$(MAKE) $(build)=scripts build_unifdef PHONY += headers_install_all
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 56a4df9..22e58a9 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig
@@ -477,7 +477,7 @@ config VGA_HOSE bool - depends on ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI + depends on VGA_CONSOLE && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI) default y help Support VGA on an arbitrary hose; needed for several platforms
diff --git a/arch/alpha/include/asm/rtc.h b/arch/alpha/include/asm/rtc.h index 1f7fba6..d70408d 100644 --- a/arch/alpha/include/asm/rtc.h +++ b/arch/alpha/include/asm/rtc.h
@@ -1,14 +1,10 @@ #ifndef _ALPHA_RTC_H #define _ALPHA_RTC_H -#if defined(CONFIG_ALPHA_GENERIC) +#if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP) \ + || defined(CONFIG_ALPHA_GENERIC) # define get_rtc_time alpha_mv.rtc_get_time # define set_rtc_time alpha_mv.rtc_set_time -#else -# if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP) -# define get_rtc_time marvel_get_rtc_time -# define set_rtc_time marvel_set_rtc_time -# endif #endif #include <asm-generic/rtc.h>
diff --git a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c index 5e7c28f9..61893d7 100644 --- a/arch/alpha/kernel/core_tsunami.c +++ b/arch/alpha/kernel/core_tsunami.c
@@ -11,6 +11,7 @@ #include <asm/core_tsunami.h> #undef __EXTERN_INLINE +#include <linux/module.h> #include <linux/types.h> #include <linux/pci.h> #include <linux/sched.h>
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index 14a4b6a..407accc 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c
@@ -317,7 +317,7 @@ } static int -marvel_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +marvel_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { struct pci_controller *hose = dev->sysdata; struct io7_port *io7_port = hose->sysdata;
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 36586dba..e19ed3f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig
@@ -33,7 +33,7 @@ select GENERIC_IRQ_SHOW select CPU_PM if (SUSPEND || CPU_IDLE) select GENERIC_PCI_IOMAP - select HAVE_BPF_JIT if NET + select HAVE_BPF_JIT help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 80abafb..9650c14 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c
@@ -906,27 +906,14 @@ return ret; } -#ifdef __ARMEB__ -#define AUDIT_ARCH_NR AUDIT_ARCH_ARMEB -#else -#define AUDIT_ARCH_NR AUDIT_ARCH_ARM -#endif - asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) { unsigned long ip; - /* - * Save IP. IP is used to denote syscall entry/exit: - * IP = 0 -> entry, = 1 -> exit - */ - ip = regs->ARM_ip; - regs->ARM_ip = why; - - if (!ip) + if (why) audit_syscall_exit(regs); else - audit_syscall_entry(AUDIT_ARCH_NR, scno, regs->ARM_r0, + audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); if (!test_thread_flag(TIF_SYSCALL_TRACE)) @@ -936,6 +923,13 @@ current_thread_info()->syscall = scno; + /* + * IP is used to denote syscall entry/exit: + * IP = 0 -> entry, =1 -> exit + */ + ip = regs->ARM_ip; + regs->ARM_ip = why; + /* the 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index f6a4d32..8f46446 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c
@@ -251,8 +251,6 @@ struct mm_struct *mm = &init_mm; unsigned int cpu = smp_processor_id(); - printk("CPU%u: Booted secondary processor\n", cpu); - /* * All kernel threads share the same mm context; grab a * reference and switch to it. @@ -264,6 +262,8 @@ enter_lazy_tlb(mm, current); local_flush_tlb_all(); + printk("CPU%u: Booted secondary processor\n", cpu); + cpu_init(); preempt_disable(); trace_hardirqs_off();
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index d2b1779..76cbb05 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c
@@ -115,7 +115,7 @@ "Ir" (THREAD_START_SP - sizeof(regs)), "r" (®s), "Ir" (sizeof(regs)) - : "r0", "r1", "r2", "r3", "ip", "lr", "memory"); + : "r0", "r1", "r2", "r3", "r8", "r9", "ip", "lr", "memory"); out: return ret;
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index e81c35f..b8df521 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig
@@ -232,6 +232,9 @@ config MACH_UNIVERSAL_C210 bool "Mobile UNIVERSAL_C210 Board" select CPU_EXYNOS4210 + select S5P_HRT + select CLKSRC_MMIO + select HAVE_SCHED_CLOCK select S5P_GPIO_INT select S5P_DEV_FIMC0 select S5P_DEV_FIMC1
diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c index 5cd7a8b..7ac6ff4 100644 --- a/arch/arm/mach-exynos/clock-exynos5.c +++ b/arch/arm/mach-exynos/clock-exynos5.c
@@ -678,7 +678,7 @@ .name = "dma", .devname = "dma-pl330.1", .enable = exynos5_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 1), + .ctrlbit = (1 << 2), }; static struct clk exynos5_clk_mdma1 = {
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c index cb2b027..a34036e 100644 --- a/arch/arm/mach-exynos/mach-universal_c210.c +++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -40,6 +40,7 @@ #include <plat/pd.h> #include <plat/regs-fb-v4.h> #include <plat/fimc-core.h> +#include <plat/s5p-time.h> #include <plat/camport.h> #include <plat/mipi_csis.h> @@ -1063,6 +1064,7 @@ exynos_init_io(NULL, 0); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs)); + s5p_set_timer_source(S5P_PWM2, S5P_PWM4); } static void s5p_tv_setup(void) @@ -1113,7 +1115,7 @@ .map_io = universal_map_io, .handle_irq = gic_handle_irq, .init_machine = universal_machine_init, - .timer = &exynos4_timer, + .timer = &s5p_timer, .reserve = &universal_reserve, .restart = exynos4_restart, MACHINE_END
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c index 1c672d9..f7fe1b9 100644 --- a/arch/arm/mach-kirkwood/board-dt.c +++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -14,6 +14,7 @@ #include <linux/init.h> #include <linux/of.h> #include <linux/of_platform.h> +#include <linux/kexec.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <mach/bridge-regs.h>
diff --git a/arch/arm/mach-omap1/ams-delta-fiq.c b/arch/arm/mach-omap1/ams-delta-fiq.c index fcce7ff..cfd98b1 100644 --- a/arch/arm/mach-omap1/ams-delta-fiq.c +++ b/arch/arm/mach-omap1/ams-delta-fiq.c
@@ -48,7 +48,7 @@ struct irq_chip *irq_chip = NULL; int gpio, irq_num, fiq_count; - irq_desc = irq_to_desc(IH_GPIO_BASE); + irq_desc = irq_to_desc(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK)); if (irq_desc) irq_chip = irq_desc->irq_data.chip;
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 930c0d3..740cee9 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -641,7 +641,7 @@ static void __init igep_init(void) { - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); + regulator_register_fixed(1, dummy_supplies, ARRAY_SIZE(dummy_supplies)); omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); /* Get IGEP2 hardware revision */
diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h index 1e2d332..c88420d 100644 --- a/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h +++ b/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h
@@ -941,10 +941,10 @@ #define OMAP4_DSI2_LANEENABLE_MASK (0x7 << 29) #define OMAP4_DSI1_LANEENABLE_SHIFT 24 #define OMAP4_DSI1_LANEENABLE_MASK (0x1f << 24) -#define OMAP4_DSI2_PIPD_SHIFT 19 -#define OMAP4_DSI2_PIPD_MASK (0x1f << 19) -#define OMAP4_DSI1_PIPD_SHIFT 14 -#define OMAP4_DSI1_PIPD_MASK (0x1f << 14) +#define OMAP4_DSI1_PIPD_SHIFT 19 +#define OMAP4_DSI1_PIPD_MASK (0x1f << 19) +#define OMAP4_DSI2_PIPD_SHIFT 14 +#define OMAP4_DSI2_PIPD_MASK (0x1f << 14) /* CONTROL_MCBSPLP */ #define OMAP4_ALBCTRLRX_FSX_SHIFT 31
diff --git a/arch/arm/mach-orion5x/mpp.h b/arch/arm/mach-orion5x/mpp.h index eac6897..db70e79 100644 --- a/arch/arm/mach-orion5x/mpp.h +++ b/arch/arm/mach-orion5x/mpp.h
@@ -65,8 +65,8 @@ #define MPP8_GIGE MPP(8, 0x1, 0, 0, 1, 1, 1) #define MPP9_UNUSED MPP(9, 0x0, 0, 0, 1, 1, 1) -#define MPP9_GPIO MPP(9, 0x0, 0, 0, 1, 1, 1) -#define MPP9_GIGE MPP(9, 0x1, 1, 1, 1, 1, 1) +#define MPP9_GPIO MPP(9, 0x0, 1, 1, 1, 1, 1) +#define MPP9_GIGE MPP(9, 0x1, 0, 0, 1, 1, 1) #define MPP10_UNUSED MPP(10, 0x0, 0, 0, 1, 1, 1) #define MPP10_GPIO MPP(10, 0x0, 1, 1, 1, 1, 1)
diff --git a/arch/arm/mach-prima2/irq.c b/arch/arm/mach-prima2/irq.c index 37c2de9..a7b9415 100644 --- a/arch/arm/mach-prima2/irq.c +++ b/arch/arm/mach-prima2/irq.c
@@ -42,7 +42,8 @@ static __init void sirfsoc_irq_init(void) { sirfsoc_alloc_gc(sirfsoc_intc_base, 0, 32); - sirfsoc_alloc_gc(sirfsoc_intc_base + 4, 32, SIRFSOC_INTENAL_IRQ_END - 32); + sirfsoc_alloc_gc(sirfsoc_intc_base + 4, 32, + SIRFSOC_INTENAL_IRQ_END + 1 - 32); writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL0); writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL1); @@ -68,7 +69,8 @@ if (!sirfsoc_intc_base) panic("unable to map intc cpu registers\n"); - irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL); + irq_domain_add_legacy(np, SIRFSOC_INTENAL_IRQ_END + 1, 0, 0, + &irq_domain_simple_ops, NULL); of_node_put(np);
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index cb224a3..0891ec6 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -365,23 +365,13 @@ }; /* SDHI0 */ -static irqreturn_t ag5evm_sdhi0_gpio_cd(int irq, void *arg) -{ - struct device *dev = arg; - struct sh_mobile_sdhi_info *info = dev->platform_data; - struct tmio_mmc_data *pdata = info->pdata; - - tmio_mmc_cd_wakeup(pdata); - - return IRQ_HANDLED; -} - static struct sh_mobile_sdhi_info sdhi0_info = { .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, - .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, + .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD, .tmio_caps = MMC_CAP_SD_HIGHSPEED, .tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29, + .cd_gpio = GPIO_PORT251, }; static struct resource sdhi0_resources[] = { @@ -557,7 +547,6 @@ lcd_backlight_reset(); /* enable SDHI0 on CN15 [SD I/F] */ - gpio_request(GPIO_FN_SDHICD0, NULL); gpio_request(GPIO_FN_SDHIWP0, NULL); gpio_request(GPIO_FN_SDHICMD0, NULL); gpio_request(GPIO_FN_SDHICLK0, NULL); @@ -566,13 +555,6 @@ gpio_request(GPIO_FN_SDHID0_1, NULL); gpio_request(GPIO_FN_SDHID0_0, NULL); - if (!request_irq(intcs_evt2irq(0x3c0), ag5evm_sdhi0_gpio_cd, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - "sdhi0 cd", &sdhi0_device.dev)) - sdhi0_info.tmio_flags |= TMIO_MMC_HAS_COLD_CD; - else - pr_warn("Unable to setup SDHI0 GPIO IRQ\n"); - /* enable SDHI1 on CN4 [WLAN I/F] */ gpio_request(GPIO_FN_SDHICLK1, NULL); gpio_request(GPIO_FN_SDHICMD1_PU, NULL);
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index f49e28a..8c6202b 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1011,21 +1011,12 @@ } /* SDHI0 */ -static irqreturn_t mackerel_sdhi0_gpio_cd(int irq, void *arg) -{ - struct device *dev = arg; - struct sh_mobile_sdhi_info *info = dev->platform_data; - struct tmio_mmc_data *pdata = info->pdata; - - tmio_mmc_cd_wakeup(pdata); - - return IRQ_HANDLED; -} - static struct sh_mobile_sdhi_info sdhi0_info = { .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, + .tmio_flags = TMIO_MMC_USE_GPIO_CD, .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, + .cd_gpio = GPIO_PORT172, }; static struct resource sdhi0_resources[] = { @@ -1384,7 +1375,6 @@ { u32 srcr4; struct clk *clk; - int ret; /* External clock source */ clk_set_rate(&sh7372_dv_clki_clk, 27000000); @@ -1481,7 +1471,6 @@ irq_set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH); /* enable SDHI0 */ - gpio_request(GPIO_FN_SDHICD0, NULL); gpio_request(GPIO_FN_SDHIWP0, NULL); gpio_request(GPIO_FN_SDHICMD0, NULL); gpio_request(GPIO_FN_SDHICLK0, NULL); @@ -1490,13 +1479,6 @@ gpio_request(GPIO_FN_SDHID0_1, NULL); gpio_request(GPIO_FN_SDHID0_0, NULL); - ret = request_irq(evt2irq(0x3340), mackerel_sdhi0_gpio_cd, - IRQF_TRIGGER_FALLING, "sdhi0 cd", &sdhi0_device.dev); - if (!ret) - sdhi0_info.tmio_flags |= TMIO_MMC_HAS_COLD_CD; - else - pr_err("Cannot get IRQ #%d: %d\n", evt2irq(0x3340), ret); - #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) /* enable SDHI1 */ gpio_request(GPIO_FN_SDHICMD1, NULL);
diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S index 6ac015c..b202c12 100644 --- a/arch/arm/mach-shmobile/headsmp.S +++ b/arch/arm/mach-shmobile/headsmp.S
@@ -16,6 +16,59 @@ __CPUINIT +/* Cache invalidation nicked from arch/arm/mach-imx/head-v7.S, thanks! + * + * The secondary kernel init calls v7_flush_dcache_all before it enables + * the L1; however, the L1 comes out of reset in an undefined state, so + * the clean + invalidate performed by v7_flush_dcache_all causes a bunch + * of cache lines with uninitialized data and uninitialized tags to get + * written out to memory, which does really unpleasant things to the main + * processor. We fix this by performing an invalidate, rather than a + * clean + invalidate, before jumping into the kernel. + * + * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs + * to be called for both secondary cores startup and primary core resume + * procedures. Ideally, it should be moved into arch/arm/mm/cache-v7.S. + */ +ENTRY(v7_invalidate_l1) + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 2, r0, c0, c0, 0 + mrc p15, 1, r0, c0, c0, 0 + + ldr r1, =0x7fff + and r2, r1, r0, lsr #13 + + ldr r1, =0x3ff + + and r3, r1, r0, lsr #3 @ NumWays - 1 + add r2, r2, #1 @ NumSets + + and r0, r0, #0x7 + add r0, r0, #4 @ SetShift + + clz r1, r3 @ WayShift + add r4, r3, #1 @ NumWays +1: sub r2, r2, #1 @ NumSets-- + mov r3, r4 @ Temp = NumWays +2: subs r3, r3, #1 @ Temp-- + mov r5, r3, lsl r1 + mov r6, r2, lsl r0 + orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift) + mcr p15, 0, r5, c7, c6, 2 + bgt 2b + cmp r2, #0 + bgt 1b + dsb + isb + mov pc, lr +ENDPROC(v7_invalidate_l1) + +ENTRY(shmobile_invalidate_start) + bl v7_invalidate_l1 + b secondary_startup +ENDPROC(shmobile_invalidate_start) + /* * Reset vector for secondary CPUs. * This will be mapped at address 0 by SBAR register. @@ -24,4 +77,5 @@ .align 12 ENTRY(shmobile_secondary_vector) ldr pc, 1f -1: .long secondary_startup - PAGE_OFFSET + PLAT_PHYS_OFFSET +1: .long shmobile_invalidate_start - PAGE_OFFSET + PLAT_PHYS_OFFSET +ENDPROC(shmobile_secondary_vector)
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 83ad3fe..c85e6ec 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -4,7 +4,6 @@ extern void shmobile_earlytimer_init(void); extern struct sys_timer shmobile_timer; struct twd_local_timer; -void shmobile_twd_init(struct twd_local_timer *twd_local_timer); extern void shmobile_setup_console(void); extern void shmobile_secondary_vector(void); extern int shmobile_platform_cpu_kill(unsigned int cpu); @@ -82,5 +81,6 @@ extern void r8a7779_secondary_init(unsigned int cpu); extern int r8a7779_boot_secondary(unsigned int cpu); extern void r8a7779_smp_prepare_cpus(void); +extern void r8a7779_register_twd(void); #endif /* __ARCH_MACH_COMMON_H */
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 12c6f52..e98e46f 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -262,10 +262,14 @@ ARRAY_SIZE(r8a7779_late_devices)); } +/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ +void __init __weak r8a7779_register_twd(void) { } + static void __init r8a7779_earlytimer_init(void) { r8a7779_clock_init(); shmobile_earlytimer_init(); + r8a7779_register_twd(); } void __init r8a7779_add_early_devices(void)
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index 5bebffc..04a0dfe 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -688,10 +688,14 @@ ARRAY_SIZE(sh73a0_late_devices)); } +/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ +void __init __weak sh73a0_register_twd(void) { } + static void __init sh73a0_earlytimer_init(void) { sh73a0_clock_init(); shmobile_earlytimer_init(); + sh73a0_register_twd(); } void __init sh73a0_add_early_devices(void)
diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index b62e19d..6d1d0238 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c
@@ -64,8 +64,15 @@ static DEFINE_SPINLOCK(scu_lock); static unsigned long tmp; +#ifdef CONFIG_HAVE_ARM_TWD static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); +void __init r8a7779_register_twd(void) +{ + twd_local_timer_register(&twd_local_timer); +} +#endif + static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) { void __iomem *scu_base = scu_base_addr(); @@ -84,7 +91,6 @@ { void __iomem *scu_base = scu_base_addr(); - shmobile_twd_init(&twd_local_timer); return scu_get_core_count(scu_base); }
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index 14ad8b05..e36c41c 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -42,7 +42,13 @@ static DEFINE_SPINLOCK(scu_lock); static unsigned long tmp; +#ifdef CONFIG_HAVE_ARM_TWD static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); +void __init sh73a0_register_twd(void) +{ + twd_local_timer_register(&twd_local_timer); +} +#endif static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) { @@ -62,7 +68,6 @@ { void __iomem *scu_base = scu_base_addr(); - shmobile_twd_init(&twd_local_timer); return scu_get_core_count(scu_base); }
diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c index 2fba5f3..8b79e79 100644 --- a/arch/arm/mach-shmobile/timer.c +++ b/arch/arm/mach-shmobile/timer.c
@@ -46,15 +46,6 @@ { } -void __init shmobile_twd_init(struct twd_local_timer *twd_local_timer) -{ -#ifdef CONFIG_HAVE_ARM_TWD - int err = twd_local_timer_register(twd_local_timer); - if (err) - pr_err("twd_local_timer_register failed %d\n", err); -#endif -} - struct sys_timer shmobile_timer = { .init = shmobile_timer_init, };
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c index fef66a7..f07488e 100644 --- a/arch/arm/mach-tegra/flowctrl.c +++ b/arch/arm/mach-tegra/flowctrl.c
@@ -53,10 +53,10 @@ void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value) { - return flowctrl_update(flowctrl_offset_halt_cpu[cpuid], value); + return flowctrl_update(flowctrl_offset_cpu_csr[cpuid], value); } void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value) { - return flowctrl_update(flowctrl_offset_cpu_csr[cpuid], value); + return flowctrl_update(flowctrl_offset_halt_cpu[cpuid], value); }
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index f074675..5bb4835 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c
@@ -247,7 +247,9 @@ return handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); check_stack: - if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr)) + /* Don't allow expansion below FIRST_USER_ADDRESS */ + if (vma->vm_flags & VM_GROWSDOWN && + addr >= FIRST_USER_ADDRESS && !expand_stack(vma, addr)) goto good_area; out: return fault;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 2c7cf2f..aa78de8 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c
@@ -489,7 +489,8 @@ */ for (i = 0; i < ARRAY_SIZE(mem_types); i++) { mem_types[i].prot_pte |= PTE_EXT_AF; - mem_types[i].prot_sect |= PMD_SECT_AF; + if (mem_types[i].prot_sect) + mem_types[i].prot_sect |= PMD_SECT_AF; } kern_pgprot |= PTE_EXT_AF; vecs_pgprot |= PTE_EXT_AF;
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index bc683b8..b0197b2 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c
@@ -11,6 +11,7 @@ #include <linux/types.h> #include <linux/cpu.h> #include <linux/cpu_pm.h> +#include <linux/hardirq.h> #include <linux/kernel.h> #include <linux/notifier.h> #include <linux/signal.h> @@ -432,7 +433,10 @@ static void vfp_enable(void *unused) { - u32 access = get_copro_access(); + u32 access; + + BUG_ON(preemptible()); + access = get_copro_access(); /* * Enable full access to VFP (cp10 and cp11) @@ -573,12 +577,6 @@ * entry. */ hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK); - - /* - * Disable VFP in the hwstate so that we can detect if it gets - * used. - */ - hwstate->fpexc &= ~FPEXC_EN; return 0; } @@ -591,12 +589,8 @@ unsigned long fpexc; int err = 0; - /* - * If VFP has been used, then disable it to avoid corrupting - * the new thread state. - */ - if (hwstate->fpexc & FPEXC_EN) - vfp_flush_hwstate(thread); + /* Disable VFP to avoid corrupting the new thread state. */ + vfp_flush_hwstate(thread); /* * Copy the floating point registers. There can be unused @@ -657,7 +651,7 @@ unsigned int cpu_arch = cpu_architecture(); if (cpu_arch >= CPU_ARCH_ARMv6) - vfp_enable(NULL); + on_each_cpu(vfp_enable, NULL, 1); /* * First check that there is a VFP that we can use. @@ -678,8 +672,6 @@ } else { hotcpu_notifier(vfp_hotplug, 0); - smp_call_function(vfp_enable, NULL, 1); - VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ printk("implementor %02x architecture %d part %02x variant %x rev %x\n", (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,
diff --git a/arch/blackfin/ADI_BSD.txt b/arch/blackfin/ADI_BSD.txt deleted file mode 100644 index 501d0b6..0000000 --- a/arch/blackfin/ADI_BSD.txt +++ /dev/null
@@ -1,41 +0,0 @@ -This BSD-Style License applies to a few files in ./arch/blackfin directory, -and is included here, so people understand which code they can use outside -the Linux kernel, in non-GPL based projects. - -Using the files released under the "ADI BSD" license, must comply with -these license terms. - --------------------------------------------------------------------------- - -Copyright Analog 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 Analog 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. - - The use of this software may or may not infringe the patent rights - of one or more patent holders. This license does not release you - from the requirement that you obtain separate licenses from these - patent holders to use this software. - -THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, 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
diff --git a/arch/blackfin/Clear_BSD.txt b/arch/blackfin/Clear_BSD.txt new file mode 100644 index 0000000..bfa4b37 --- /dev/null +++ b/arch/blackfin/Clear_BSD.txt
@@ -0,0 +1,33 @@ +The Clear BSD license: + +Copyright (c) 2012, Analog Devices, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted (subject to the limitations in the +disclaimer below) 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 Analog 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. + +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE +GRANTED BY THIS 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.
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 373a690..383e7ec 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig
@@ -226,6 +226,12 @@ help BF561 Processor Support. +config BF609 + bool "BF609" + select CLKDEV_LOOKUP + help + BF609 Processor Support. + endchoice config SMP @@ -251,27 +257,27 @@ config BF_REV_MIN int - default 0 if (BF51x || BF52x || (BF54x && !BF54xM)) + default 0 if (BF51x || BF52x || (BF54x && !BF54xM)) || BF60x default 2 if (BF537 || BF536 || BF534) default 3 if (BF561 || BF533 || BF532 || BF531 || BF54xM) default 4 if (BF538 || BF539) config BF_REV_MAX int - default 2 if (BF51x || BF52x || (BF54x && !BF54xM)) + default 2 if (BF51x || BF52x || (BF54x && !BF54xM)) || BF60x default 3 if (BF537 || BF536 || BF534 || BF54xM) default 5 if (BF561 || BF538 || BF539) default 6 if (BF533 || BF532 || BF531) choice prompt "Silicon Rev" - default BF_REV_0_0 if (BF51x || BF52x) + default BF_REV_0_0 if (BF51x || BF52x || BF60x) default BF_REV_0_2 if (BF534 || BF536 || BF537 || (BF54x && !BF54xM)) default BF_REV_0_3 if (BF531 || BF532 || BF533 || BF54xM || BF561) config BF_REV_0_0 bool "0.0" - depends on (BF51x || BF52x || (BF54x && !BF54xM)) + depends on (BF51x || BF52x || (BF54x && !BF54xM) || BF60x) config BF_REV_0_1 bool "0.1" @@ -350,6 +356,7 @@ source "arch/blackfin/mach-bf537/Kconfig" source "arch/blackfin/mach-bf538/Kconfig" source "arch/blackfin/mach-bf548/Kconfig" +source "arch/blackfin/mach-bf609/Kconfig" menu "Board customizations" @@ -379,6 +386,12 @@ memory region is used to capture NULL pointer references as well as some core kernel functions. +config PHY_RAM_BASE_ADDRESS + hex "Physical RAM Base" + default 0x0 + help + set BF609 FPGA physical SRAM base address + config ROM_BASE hex "Kernel ROM Base" depends on ROMKERNEL @@ -422,7 +435,7 @@ config PLL_BYPASS bool "Bypass PLL" - depends on BFIN_KERNEL_CLOCK + depends on BFIN_KERNEL_CLOCK && (!BF60x) default n config CLKIN_HALF @@ -441,7 +454,7 @@ default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN527_EZKIT_V2 || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM || BFIN538_EZKIT) default "22" if BFIN533_BLUETECHNIX_CM default "20" if (BFIN537_BLUETECHNIX_CM_E || BFIN537_BLUETECHNIX_CM_U || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM) - default "20" if BFIN561_EZKIT + default "20" if (BFIN561_EZKIT || BF609) default "16" if (H8606_HVSISTEMAS || BLACKSTAMP || BFIN526_EZBRD || BFIN518F_EZBRD) default "25" if BFIN527_AD7160EVAL help @@ -473,12 +486,45 @@ int "System Clock Divider" depends on BFIN_KERNEL_CLOCK range 1 15 - default 5 + default 4 help - This sets the frequency of the system clock (including SDRAM or DDR). + This sets the frequency of the system clock (including SDRAM or DDR) on + !BF60x else it set the clock for system buses and provides the + source from which SCLK0 and SCLK1 are derived. This can be between 1 and 15 System Clock = (PLL frequency) / (this setting) +config SCLK0_DIV + int "System Clock0 Divider" + depends on BFIN_KERNEL_CLOCK && BF60x + range 1 15 + default 1 + help + This sets the frequency of the system clock0 for PVP and all other + peripherals not clocked by SCLK1. + This can be between 1 and 15 + System Clock0 = (System Clock) / (this setting) + +config SCLK1_DIV + int "System Clock1 Divider" + depends on BFIN_KERNEL_CLOCK && BF60x + range 1 15 + default 1 + help + This sets the frequency of the system clock1 (including SPORT, SPI and ACM). + This can be between 1 and 15 + System Clock1 = (System Clock) / (this setting) + +config DCLK_DIV + int "DDR Clock Divider" + depends on BFIN_KERNEL_CLOCK && BF60x + range 1 15 + default 2 + help + This sets the frequency of the DDR memory. + This can be between 1 and 15 + DDR Clock = (PLL frequency) / (this setting) + choice prompt "DDR SDRAM Chip Type" depends on BFIN_KERNEL_CLOCK @@ -494,7 +540,7 @@ choice prompt "DDR/SDRAM Timing" - depends on BFIN_KERNEL_CLOCK + depends on BFIN_KERNEL_CLOCK && !BF60x default BFIN_KERNEL_CLOCK_MEMINIT_CALC help This option allows you to specify Blackfin SDRAM/DDR Timing parameters @@ -576,6 +622,7 @@ default 600000000 if BF548 default 533333333 if BF549 default 600000000 if BF561 + default 800000000 if BF609 config MIN_VCO_HZ int @@ -583,6 +630,7 @@ config MAX_SCLK_HZ int + default 200000000 if BF609 default 133333333 config MIN_SCLK_HZ @@ -1051,7 +1099,7 @@ config BFIN_L2_DCACHEABLE bool "Enable DCACHE for L2 SRAM" depends on BFIN_DCACHE - depends on (BF54x || BF561) && !SMP + depends on (BF54x || BF561 || BF60x) && !SMP default n choice prompt "L2 SRAM DCACHE policy" @@ -1077,6 +1125,7 @@ comment "Asynchronous Memory Configuration" menu "EBIU_AMGCTL Global Control" + depends on !BF60x config C_AMCKEN bool "Enable CLKOUT" default y @@ -1127,6 +1176,7 @@ endmenu menu "EBIU_AMBCTL Control" + depends on !BF60x config BANK_0 hex "Bank 0 (AMBCTL0.L)" default 0x7BB0 @@ -1206,7 +1256,7 @@ choice prompt "Standby Power Saving Mode" - depends on PM + depends on PM && !BF60x default PM_BFIN_SLEEP_DEEPER config PM_BFIN_SLEEP_DEEPER bool "Sleep Deeper" @@ -1261,6 +1311,118 @@ On ADSP-BF549 this option enables the the same functionality on the /MRXON pin also PH7. +config PM_BFIN_WAKE_PA15 + bool "Allow Wake-Up from PA15" + depends on PM && BF60x + default n + help + Enable PA15 Wake-Up + +config PM_BFIN_WAKE_PA15_POL + int "Wake-up priority" + depends on PM_BFIN_WAKE_PA15 + default 0 + help + Wake-Up priority 0(low) 1(high) + +config PM_BFIN_WAKE_PB15 + bool "Allow Wake-Up from PB15" + depends on PM && BF60x + default n + help + Enable PB15 Wake-Up + +config PM_BFIN_WAKE_PB15_POL + int "Wake-up priority" + depends on PM_BFIN_WAKE_PB15 + default 0 + help + Wake-Up priority 0(low) 1(high) + +config PM_BFIN_WAKE_PC15 + bool "Allow Wake-Up from PC15" + depends on PM && BF60x + default n + help + Enable PC15 Wake-Up + +config PM_BFIN_WAKE_PC15_POL + int "Wake-up priority" + depends on PM_BFIN_WAKE_PC15 + default 0 + help + Wake-Up priority 0(low) 1(high) + +config PM_BFIN_WAKE_PD06 + bool "Allow Wake-Up from PD06(ETH0_PHYINT)" + depends on PM && BF60x + default n + help + Enable PD06(ETH0_PHYINT) Wake-up + +config PM_BFIN_WAKE_PD06_POL + int "Wake-up priority" + depends on PM_BFIN_WAKE_PD06 + default 0 + help + Wake-Up priority 0(low) 1(high) + +config PM_BFIN_WAKE_PE12 + bool "Allow Wake-Up from PE12(ETH1_PHYINT, PUSH BUTTON)" + depends on PM && BF60x + default n + help + Enable PE12(ETH1_PHYINT, PUSH BUTTON) Wake-up + +config PM_BFIN_WAKE_PE12_POL + int "Wake-up priority" + depends on PM_BFIN_WAKE_PE12 + default 0 + help + Wake-Up priority 0(low) 1(high) + +config PM_BFIN_WAKE_PG04 + bool "Allow Wake-Up from PG04(CAN0_RX)" + depends on PM && BF60x + default n + help + Enable PG04(CAN0_RX) Wake-up + +config PM_BFIN_WAKE_PG04_POL + int "Wake-up priority" + depends on PM_BFIN_WAKE_PG04 + default 0 + help + Wake-Up priority 0(low) 1(high) + +config PM_BFIN_WAKE_PG13 + bool "Allow Wake-Up from PG13" + depends on PM && BF60x + default n + help + Enable PG13 Wake-Up + +config PM_BFIN_WAKE_PG13_POL + int "Wake-up priority" + depends on PM_BFIN_WAKE_PG13 + default 0 + help + Wake-Up priority 0(low) 1(high) + +config PM_BFIN_WAKE_USB + bool "Allow Wake-Up from (USB)" + depends on PM && BF60x + default n + help + Enable (USB) Wake-up + +config PM_BFIN_WAKE_USB_POL + int "Wake-up priority" + depends on PM_BFIN_WAKE_USB + default 0 + help + Wake-Up priority 0(low) 1(high) + endmenu menu "CPU Frequency scaling"
diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug index e2a3d4c..79594694 100644 --- a/arch/blackfin/Kconfig.debug +++ b/arch/blackfin/Kconfig.debug
@@ -253,4 +253,11 @@ Most people should say N here. +config BFIN_PM_WAKEUP_TIME_BENCH + bool "Display the total time for kernel to resume from power saving mode" + default n + help + Display the total time when kernel resumes normal from standby or + suspend to mem mode. + endmenu
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index 46f42b2..74fdf67 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile
@@ -54,6 +54,7 @@ machine-$(CONFIG_BF549) := bf548 machine-$(CONFIG_BF549M) := bf548 machine-$(CONFIG_BF561) := bf561 +machine-$(CONFIG_BF609) := bf609 MACHINE := $(machine-y) export MACHINE @@ -86,6 +87,7 @@ cpu-$(CONFIG_BF549) := bf549 cpu-$(CONFIG_BF549M) := bf549m cpu-$(CONFIG_BF561) := bf561 +cpu-$(CONFIG_BF609) := bf609 rev-$(CONFIG_BF_REV_0_0) := 0.0 rev-$(CONFIG_BF_REV_0_1) := 0.1
diff --git a/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig b/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig index 680730e..e2a2fa5 100644 --- a/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig +++ b/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig
@@ -21,14 +21,12 @@ # CONFIG_IOSCHED_CFQ is not set CONFIG_PREEMPT_VOLUNTARY=y CONFIG_BF561=y +CONFIG_SMP=y CONFIG_IRQ_TIMER0=10 CONFIG_CLKIN_HZ=30000000 CONFIG_HIGH_RES_TIMERS=y CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=m -CONFIG_BFIN_EXTMEM_WRITETHROUGH=y -CONFIG_BFIN_L2_DCACHEABLE=y -CONFIG_BFIN_L2_WRITETHROUGH=y CONFIG_C_CDPRIO=y CONFIG_BANK_3=0xAAC2 CONFIG_BINFMT_FLAT=y
diff --git a/arch/blackfin/configs/BF609-EZKIT_defconfig b/arch/blackfin/configs/BF609-EZKIT_defconfig new file mode 100644 index 0000000..be9526b --- /dev/null +++ b/arch/blackfin/configs/BF609-EZKIT_defconfig
@@ -0,0 +1,155 @@ +CONFIG_EXPERIMENTAL=y +CONFIG_SYSVIPC=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +# CONFIG_ELF_CORE is not set +# CONFIG_FUTEX is not set +# CONFIG_SIGNALFD is not set +# CONFIG_TIMERFD is not set +# CONFIG_EVENTFD is not set +# CONFIG_AIO is not set +CONFIG_SLAB=y +CONFIG_MMAP_ALLOW_UNINITIALIZED=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_LBDAF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_BF609=y +CONFIG_PINT1_ASSIGN=0x01010000 +CONFIG_PINT2_ASSIGN=0x07000101 +CONFIG_PINT3_ASSIGN=0x02020303 +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IP_CHECKSUM_L1=y +CONFIG_SYSCALL_TAB_L1=y +CONFIG_CPLB_SWITCH_TAB_L1=y +# CONFIG_APP_STACK_L1 is not set +# CONFIG_BFIN_INS_LOWOVERHEAD is not set +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 +CONFIG_BINFMT_FLAT=y +CONFIG_BINFMT_ZFLAT=y +CONFIG_PM_BFIN_WAKE_PE12=y +CONFIG_PM_BFIN_WAKE_PE12_POL=1 +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_IPV6 is not set +CONFIG_NETFILTER=y +CONFIG_CAN=y +CONFIG_CAN_BFIN=y +CONFIG_IRDA=y +CONFIG_IRTTY_SIR=y +# CONFIG_WIRELESS is not set +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_FW_LOADER=m +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_M25P80=y +CONFIG_MTD_UBI=m +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_NETDEVICES=y +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +CONFIG_STMMAC_ETH=y +CONFIG_STMMAC_IEEE1588=y +# CONFIG_WLAN is not set +# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_BFIN_ROTARY=y +# CONFIG_SERIO is not set +# CONFIG_LEGACY_PTYS is not set +CONFIG_BFIN_SIMPLE_TIMER=m +CONFIG_BFIN_LINKPORT=y +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_BFIN=y +CONFIG_SERIAL_BFIN_CONSOLE=y +CONFIG_SERIAL_BFIN_UART0=y +# CONFIG_HW_RANDOM is not set +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_BLACKFIN_TWI=y +CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 +CONFIG_SPI=y +CONFIG_SPI_BFIN6XX=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_BFIN_WDT=y +CONFIG_SOUND=m +CONFIG_SND=m +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_SPI is not set +# CONFIG_SND_USB is not set +CONFIG_SND_SOC=m +CONFIG_SND_BF6XX_I2S=m +CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61=m +CONFIG_SND_SOC_ALL_CODECS=m +CONFIG_USB=y +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_BLACKFIN=m +CONFIG_USB_STORAGE=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MUSB_HDRC=y +CONFIG_USB_ZERO=y +CONFIG_MMC=y +CONFIG_SDH_BFIN=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT2_FS=y +# CONFIG_DNOTIFY is not set +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_JFFS2_FS=m +CONFIG_UBIFS_FS=m +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_SHIRQ=y +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEBUG_INFO=y +CONFIG_FRAME_POINTER=y +# CONFIG_FTRACE is not set +CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE=y +CONFIG_EARLY_PRINTK=y +CONFIG_CPLB_INFO=y +CONFIG_BFIN_PSEUDODBG_INSNS=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/blackfin/include/asm/bfin-global.h b/arch/blackfin/include/asm/bfin-global.h index 17bcbf6..608be5e 100644 --- a/arch/blackfin/include/asm/bfin-global.h +++ b/arch/blackfin/include/asm/bfin-global.h
@@ -35,6 +35,11 @@ extern unsigned long get_cclk(void); extern unsigned long get_sclk(void); +#ifdef CONFIG_BF60x +extern unsigned long get_sclk0(void); +extern unsigned long get_sclk1(void); +extern unsigned long get_dclk(void); +#endif extern unsigned long sclk_to_usecs(unsigned long sclk); extern unsigned long usecs_to_sclk(unsigned long usecs);
diff --git a/arch/blackfin/include/asm/bfin6xx_spi.h b/arch/blackfin/include/asm/bfin6xx_spi.h new file mode 100644 index 0000000..89370b6 --- /dev/null +++ b/arch/blackfin/include/asm/bfin6xx_spi.h
@@ -0,0 +1,258 @@ +/* + * Analog Devices SPI3 controller driver + * + * Copyright (c) 2011 Analog Devices Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _SPI_CHANNEL_H_ +#define _SPI_CHANNEL_H_ + +#include <linux/types.h> + +/* SPI_CONTROL */ +#define SPI_CTL_EN 0x00000001 /* Enable */ +#define SPI_CTL_MSTR 0x00000002 /* Master/Slave */ +#define SPI_CTL_PSSE 0x00000004 /* controls modf error in master mode */ +#define SPI_CTL_ODM 0x00000008 /* Open Drain Mode */ +#define SPI_CTL_CPHA 0x00000010 /* Clock Phase */ +#define SPI_CTL_CPOL 0x00000020 /* Clock Polarity */ +#define SPI_CTL_ASSEL 0x00000040 /* Slave Select Pin Control */ +#define SPI_CTL_SELST 0x00000080 /* Slave Select Polarity in-between transfers */ +#define SPI_CTL_EMISO 0x00000100 /* Enable MISO */ +#define SPI_CTL_SIZE 0x00000600 /* Word Transfer Size */ +#define SPI_CTL_SIZE08 0x00000000 /* SIZE: 8 bits */ +#define SPI_CTL_SIZE16 0x00000200 /* SIZE: 16 bits */ +#define SPI_CTL_SIZE32 0x00000400 /* SIZE: 32 bits */ +#define SPI_CTL_LSBF 0x00001000 /* LSB First */ +#define SPI_CTL_FCEN 0x00002000 /* Flow-Control Enable */ +#define SPI_CTL_FCCH 0x00004000 /* Flow-Control Channel Selection */ +#define SPI_CTL_FCPL 0x00008000 /* Flow-Control Polarity */ +#define SPI_CTL_FCWM 0x00030000 /* Flow-Control Water-Mark */ +#define SPI_CTL_FIFO0 0x00000000 /* FCWM: TFIFO empty or RFIFO Full */ +#define SPI_CTL_FIFO1 0x00010000 /* FCWM: TFIFO 75% or more empty or RFIFO 75% or more full */ +#define SPI_CTL_FIFO2 0x00020000 /* FCWM: TFIFO 50% or more empty or RFIFO 50% or more full */ +#define SPI_CTL_FMODE 0x00040000 /* Fast-mode Enable */ +#define SPI_CTL_MIOM 0x00300000 /* Multiple I/O Mode */ +#define SPI_CTL_MIO_DIS 0x00000000 /* MIOM: Disable */ +#define SPI_CTL_MIO_DUAL 0x00100000 /* MIOM: Enable DIOM (Dual I/O Mode) */ +#define SPI_CTL_MIO_QUAD 0x00200000 /* MIOM: Enable QUAD (Quad SPI Mode) */ +#define SPI_CTL_SOSI 0x00400000 /* Start on MOSI */ +/* SPI_RX_CONTROL */ +#define SPI_RXCTL_REN 0x00000001 /* Receive Channel Enable */ +#define SPI_RXCTL_RTI 0x00000004 /* Receive Transfer Initiate */ +#define SPI_RXCTL_RWCEN 0x00000008 /* Receive Word Counter Enable */ +#define SPI_RXCTL_RDR 0x00000070 /* Receive Data Request */ +#define SPI_RXCTL_RDR_DIS 0x00000000 /* RDR: Disabled */ +#define SPI_RXCTL_RDR_NE 0x00000010 /* RDR: RFIFO not empty */ +#define SPI_RXCTL_RDR_25 0x00000020 /* RDR: RFIFO 25% full */ +#define SPI_RXCTL_RDR_50 0x00000030 /* RDR: RFIFO 50% full */ +#define SPI_RXCTL_RDR_75 0x00000040 /* RDR: RFIFO 75% full */ +#define SPI_RXCTL_RDR_FULL 0x00000050 /* RDR: RFIFO full */ +#define SPI_RXCTL_RDO 0x00000100 /* Receive Data Over-Run */ +#define SPI_RXCTL_RRWM 0x00003000 /* FIFO Regular Water-Mark */ +#define SPI_RXCTL_RWM_0 0x00000000 /* RRWM: RFIFO Empty */ +#define SPI_RXCTL_RWM_25 0x00001000 /* RRWM: RFIFO 25% full */ +#define SPI_RXCTL_RWM_50 0x00002000 /* RRWM: RFIFO 50% full */ +#define SPI_RXCTL_RWM_75 0x00003000 /* RRWM: RFIFO 75% full */ +#define SPI_RXCTL_RUWM 0x00070000 /* FIFO Urgent Water-Mark */ +#define SPI_RXCTL_UWM_DIS 0x00000000 /* RUWM: Disabled */ +#define SPI_RXCTL_UWM_25 0x00010000 /* RUWM: RFIFO 25% full */ +#define SPI_RXCTL_UWM_50 0x00020000 /* RUWM: RFIFO 50% full */ +#define SPI_RXCTL_UWM_75 0x00030000 /* RUWM: RFIFO 75% full */ +#define SPI_RXCTL_UWM_FULL 0x00040000 /* RUWM: RFIFO full */ +/* SPI_TX_CONTROL */ +#define SPI_TXCTL_TEN 0x00000001 /* Transmit Channel Enable */ +#define SPI_TXCTL_TTI 0x00000004 /* Transmit Transfer Initiate */ +#define SPI_TXCTL_TWCEN 0x00000008 /* Transmit Word Counter Enable */ +#define SPI_TXCTL_TDR 0x00000070 /* Transmit Data Request */ +#define SPI_TXCTL_TDR_DIS 0x00000000 /* TDR: Disabled */ +#define SPI_TXCTL_TDR_NF 0x00000010 /* TDR: TFIFO not full */ +#define SPI_TXCTL_TDR_25 0x00000020 /* TDR: TFIFO 25% empty */ +#define SPI_TXCTL_TDR_50 0x00000030 /* TDR: TFIFO 50% empty */ +#define SPI_TXCTL_TDR_75 0x00000040 /* TDR: TFIFO 75% empty */ +#define SPI_TXCTL_TDR_EMPTY 0x00000050 /* TDR: TFIFO empty */ +#define SPI_TXCTL_TDU 0x00000100 /* Transmit Data Under-Run */ +#define SPI_TXCTL_TRWM 0x00003000 /* FIFO Regular Water-Mark */ +#define SPI_TXCTL_RWM_FULL 0x00000000 /* TRWM: TFIFO full */ +#define SPI_TXCTL_RWM_25 0x00001000 /* TRWM: TFIFO 25% empty */ +#define SPI_TXCTL_RWM_50 0x00002000 /* TRWM: TFIFO 50% empty */ +#define SPI_TXCTL_RWM_75 0x00003000 /* TRWM: TFIFO 75% empty */ +#define SPI_TXCTL_TUWM 0x00070000 /* FIFO Urgent Water-Mark */ +#define SPI_TXCTL_UWM_DIS 0x00000000 /* TUWM: Disabled */ +#define SPI_TXCTL_UWM_25 0x00010000 /* TUWM: TFIFO 25% empty */ +#define SPI_TXCTL_UWM_50 0x00020000 /* TUWM: TFIFO 50% empty */ +#define SPI_TXCTL_UWM_75 0x00030000 /* TUWM: TFIFO 75% empty */ +#define SPI_TXCTL_UWM_EMPTY 0x00040000 /* TUWM: TFIFO empty */ +/* SPI_CLOCK */ +#define SPI_CLK_BAUD 0x0000FFFF /* Baud Rate */ +/* SPI_DELAY */ +#define SPI_DLY_STOP 0x000000FF /* Transfer delay time in multiples of SCK period */ +#define SPI_DLY_LEADX 0x00000100 /* Extended (1 SCK) LEAD Control */ +#define SPI_DLY_LAGX 0x00000200 /* Extended (1 SCK) LAG control */ +/* SPI_SSEL */ +#define SPI_SLVSEL_SSE1 0x00000002 /* SPISSEL1 Enable */ +#define SPI_SLVSEL_SSE2 0x00000004 /* SPISSEL2 Enable */ +#define SPI_SLVSEL_SSE3 0x00000008 /* SPISSEL3 Enable */ +#define SPI_SLVSEL_SSE4 0x00000010 /* SPISSEL4 Enable */ +#define SPI_SLVSEL_SSE5 0x00000020 /* SPISSEL5 Enable */ +#define SPI_SLVSEL_SSE6 0x00000040 /* SPISSEL6 Enable */ +#define SPI_SLVSEL_SSE7 0x00000080 /* SPISSEL7 Enable */ +#define SPI_SLVSEL_SSEL1 0x00000200 /* SPISSEL1 Value */ +#define SPI_SLVSEL_SSEL2 0x00000400 /* SPISSEL2 Value */ +#define SPI_SLVSEL_SSEL3 0x00000800 /* SPISSEL3 Value */ +#define SPI_SLVSEL_SSEL4 0x00001000 /* SPISSEL4 Value */ +#define SPI_SLVSEL_SSEL5 0x00002000 /* SPISSEL5 Value */ +#define SPI_SLVSEL_SSEL6 0x00004000 /* SPISSEL6 Value */ +#define SPI_SLVSEL_SSEL7 0x00008000 /* SPISSEL7 Value */ +/* SPI_RWC */ +#define SPI_RWC_VALUE 0x0000FFFF /* Received Word-Count */ +/* SPI_RWCR */ +#define SPI_RWCR_VALUE 0x0000FFFF /* Received Word-Count Reload */ +/* SPI_TWC */ +#define SPI_TWC_VALUE 0x0000FFFF /* Transmitted Word-Count */ +/* SPI_TWCR */ +#define SPI_TWCR_VALUE 0x0000FFFF /* Transmitted Word-Count Reload */ +/* SPI_IMASK */ +#define SPI_IMSK_RUWM 0x00000002 /* Receive Urgent Water-Mark Interrupt Mask */ +#define SPI_IMSK_TUWM 0x00000004 /* Transmit Urgent Water-Mark Interrupt Mask */ +#define SPI_IMSK_ROM 0x00000010 /* Receive Over-Run Error Interrupt Mask */ +#define SPI_IMSK_TUM 0x00000020 /* Transmit Under-Run Error Interrupt Mask */ +#define SPI_IMSK_TCM 0x00000040 /* Transmit Collision Error Interrupt Mask */ +#define SPI_IMSK_MFM 0x00000080 /* Mode Fault Error Interrupt Mask */ +#define SPI_IMSK_RSM 0x00000100 /* Receive Start Interrupt Mask */ +#define SPI_IMSK_TSM 0x00000200 /* Transmit Start Interrupt Mask */ +#define SPI_IMSK_RFM 0x00000400 /* Receive Finish Interrupt Mask */ +#define SPI_IMSK_TFM 0x00000800 /* Transmit Finish Interrupt Mask */ +/* SPI_IMASKCL */ +#define SPI_IMSK_CLR_RUW 0x00000002 /* Receive Urgent Water-Mark Interrupt Mask */ +#define SPI_IMSK_CLR_TUWM 0x00000004 /* Transmit Urgent Water-Mark Interrupt Mask */ +#define SPI_IMSK_CLR_ROM 0x00000010 /* Receive Over-Run Error Interrupt Mask */ +#define SPI_IMSK_CLR_TUM 0x00000020 /* Transmit Under-Run Error Interrupt Mask */ +#define SPI_IMSK_CLR_TCM 0x00000040 /* Transmit Collision Error Interrupt Mask */ +#define SPI_IMSK_CLR_MFM 0x00000080 /* Mode Fault Error Interrupt Mask */ +#define SPI_IMSK_CLR_RSM 0x00000100 /* Receive Start Interrupt Mask */ +#define SPI_IMSK_CLR_TSM 0x00000200 /* Transmit Start Interrupt Mask */ +#define SPI_IMSK_CLR_RFM 0x00000400 /* Receive Finish Interrupt Mask */ +#define SPI_IMSK_CLR_TFM 0x00000800 /* Transmit Finish Interrupt Mask */ +/* SPI_IMASKST */ +#define SPI_IMSK_SET_RUWM 0x00000002 /* Receive Urgent Water-Mark Interrupt Mask */ +#define SPI_IMSK_SET_TUWM 0x00000004 /* Transmit Urgent Water-Mark Interrupt Mask */ +#define SPI_IMSK_SET_ROM 0x00000010 /* Receive Over-Run Error Interrupt Mask */ +#define SPI_IMSK_SET_TUM 0x00000020 /* Transmit Under-Run Error Interrupt Mask */ +#define SPI_IMSK_SET_TCM 0x00000040 /* Transmit Collision Error Interrupt Mask */ +#define SPI_IMSK_SET_MFM 0x00000080 /* Mode Fault Error Interrupt Mask */ +#define SPI_IMSK_SET_RSM 0x00000100 /* Receive Start Interrupt Mask */ +#define SPI_IMSK_SET_TSM 0x00000200 /* Transmit Start Interrupt Mask */ +#define SPI_IMSK_SET_RFM 0x00000400 /* Receive Finish Interrupt Mask */ +#define SPI_IMSK_SET_TFM 0x00000800 /* Transmit Finish Interrupt Mask */ +/* SPI_STATUS */ +#define SPI_STAT_SPIF 0x00000001 /* SPI Finished */ +#define SPI_STAT_RUWM 0x00000002 /* Receive Urgent Water-Mark Breached */ +#define SPI_STAT_TUWM 0x00000004 /* Transmit Urgent Water-Mark Breached */ +#define SPI_STAT_ROE 0x00000010 /* Receive Over-Run Error Indication */ +#define SPI_STAT_TUE 0x00000020 /* Transmit Under-Run Error Indication */ +#define SPI_STAT_TCE 0x00000040 /* Transmit Collision Error Indication */ +#define SPI_STAT_MODF 0x00000080 /* Mode Fault Error Indication */ +#define SPI_STAT_RS 0x00000100 /* Receive Start Indication */ +#define SPI_STAT_TS 0x00000200 /* Transmit Start Indication */ +#define SPI_STAT_RF 0x00000400 /* Receive Finish Indication */ +#define SPI_STAT_TF 0x00000800 /* Transmit Finish Indication */ +#define SPI_STAT_RFS 0x00007000 /* SPI_RFIFO status */ +#define SPI_STAT_RFIFO_EMPTY 0x00000000 /* RFS: RFIFO Empty */ +#define SPI_STAT_RFIFO_25 0x00001000 /* RFS: RFIFO 25% Full */ +#define SPI_STAT_RFIFO_50 0x00002000 /* RFS: RFIFO 50% Full */ +#define SPI_STAT_RFIFO_75 0x00003000 /* RFS: RFIFO 75% Full */ +#define SPI_STAT_RFIFO_FULL 0x00004000 /* RFS: RFIFO Full */ +#define SPI_STAT_TFS 0x00070000 /* SPI_TFIFO status */ +#define SPI_STAT_TFIFO_FULL 0x00000000 /* TFS: TFIFO full */ +#define SPI_STAT_TFIFO_25 0x00010000 /* TFS: TFIFO 25% empty */ +#define SPI_STAT_TFIFO_50 0x00020000 /* TFS: TFIFO 50% empty */ +#define SPI_STAT_TFIFO_75 0x00030000 /* TFS: TFIFO 75% empty */ +#define SPI_STAT_TFIFO_EMPTY 0x00040000 /* TFS: TFIFO empty */ +#define SPI_STAT_FCS 0x00100000 /* Flow-Control Stall Indication */ +#define SPI_STAT_RFE 0x00400000 /* SPI_RFIFO Empty */ +#define SPI_STAT_TFF 0x00800000 /* SPI_TFIFO Full */ +/* SPI_ILAT */ +#define SPI_ILAT_RUWMI 0x00000002 /* Receive Urgent Water Mark Interrupt */ +#define SPI_ILAT_TUWMI 0x00000004 /* Transmit Urgent Water Mark Interrupt */ +#define SPI_ILAT_ROI 0x00000010 /* Receive Over-Run Error Indication */ +#define SPI_ILAT_TUI 0x00000020 /* Transmit Under-Run Error Indication */ +#define SPI_ILAT_TCI 0x00000040 /* Transmit Collision Error Indication */ +#define SPI_ILAT_MFI 0x00000080 /* Mode Fault Error Indication */ +#define SPI_ILAT_RSI 0x00000100 /* Receive Start Indication */ +#define SPI_ILAT_TSI 0x00000200 /* Transmit Start Indication */ +#define SPI_ILAT_RFI 0x00000400 /* Receive Finish Indication */ +#define SPI_ILAT_TFI 0x00000800 /* Transmit Finish Indication */ +/* SPI_ILATCL */ +#define SPI_ILAT_CLR_RUWMI 0x00000002 /* Receive Urgent Water Mark Interrupt */ +#define SPI_ILAT_CLR_TUWMI 0x00000004 /* Transmit Urgent Water Mark Interrupt */ +#define SPI_ILAT_CLR_ROI 0x00000010 /* Receive Over-Run Error Indication */ +#define SPI_ILAT_CLR_TUI 0x00000020 /* Transmit Under-Run Error Indication */ +#define SPI_ILAT_CLR_TCI 0x00000040 /* Transmit Collision Error Indication */ +#define SPI_ILAT_CLR_MFI 0x00000080 /* Mode Fault Error Indication */ +#define SPI_ILAT_CLR_RSI 0x00000100 /* Receive Start Indication */ +#define SPI_ILAT_CLR_TSI 0x00000200 /* Transmit Start Indication */ +#define SPI_ILAT_CLR_RFI 0x00000400 /* Receive Finish Indication */ +#define SPI_ILAT_CLR_TFI 0x00000800 /* Transmit Finish Indication */ + +/* + * bfin spi3 registers layout + */ +struct bfin_spi_regs { + u32 revid; + u32 control; + u32 rx_control; + u32 tx_control; + u32 clock; + u32 delay; + u32 ssel; + u32 rwc; + u32 rwcr; + u32 twc; + u32 twcr; + u32 reserved0; + u32 emask; + u32 emaskcl; + u32 emaskst; + u32 reserved1; + u32 status; + u32 elat; + u32 elatcl; + u32 reserved2; + u32 rfifo; + u32 reserved3; + u32 tfifo; +}; + +#define MAX_CTRL_CS 8 /* cs in spi controller */ + +/* device.platform_data for SSP controller devices */ +struct bfin6xx_spi_master { + u16 num_chipselect; + u16 pin_req[7]; +}; + +/* spi_board_info.controller_data for SPI slave devices, + * copied to spi_device.platform_data ... mostly for dma tuning + */ +struct bfin6xx_spi_chip { + u32 control; + u16 cs_chg_udelay; /* Some devices require 16-bit delays */ + u32 tx_dummy_val; /* tx value for rx only transfer */ + bool enable_dma; +}; + +#endif /* _SPI_CHANNEL_H_ */
diff --git a/arch/blackfin/include/asm/bfin_crc.h b/arch/blackfin/include/asm/bfin_crc.h new file mode 100644 index 0000000..3deb4452 --- /dev/null +++ b/arch/blackfin/include/asm/bfin_crc.h
@@ -0,0 +1,139 @@ +/* + * bfin_crc.h - interface to Blackfin CRC controllers + * + * Copyright 2012 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __BFIN_CRC_H__ +#define __BFIN_CRC_H__ + +/* Function driver which use hardware crc must initialize the structure */ +struct crc_info { + /* Input data address */ + unsigned char *in_addr; + /* Output data address */ + unsigned char *out_addr; + /* Input or output bytes */ + unsigned long datasize; + union { + /* CRC to compare with that of input buffer */ + unsigned long crc_compare; + /* Value to compare with input data */ + unsigned long val_verify; + /* Value to fill */ + unsigned long val_fill; + }; + /* Value to program the 32b CRC Polynomial */ + unsigned long crc_poly; + union { + /* CRC calculated from the input data */ + unsigned long crc_result; + /* First failed position to verify input data */ + unsigned long pos_verify; + }; + /* CRC mirror flags */ + unsigned int bitmirr:1; + unsigned int bytmirr:1; + unsigned int w16swp:1; + unsigned int fdsel:1; + unsigned int rsltmirr:1; + unsigned int polymirr:1; + unsigned int cmpmirr:1; +}; + +/* Userspace interface */ +#define CRC_IOC_MAGIC 'C' +#define CRC_IOC_CALC_CRC _IOWR('C', 0x01, unsigned int) +#define CRC_IOC_MEMCPY_CRC _IOWR('C', 0x02, unsigned int) +#define CRC_IOC_VERIFY_VAL _IOWR('C', 0x03, unsigned int) +#define CRC_IOC_FILL_VAL _IOWR('C', 0x04, unsigned int) + + +#ifdef __KERNEL__ + +#include <linux/types.h> +#include <linux/spinlock.h> +#include <linux/miscdevice.h> + +struct crc_register { + u32 control; + u32 datacnt; + u32 datacntrld; + u32 __pad_1[2]; + u32 compare; + u32 fillval; + u32 datafifo; + u32 intren; + u32 intrenset; + u32 intrenclr; + u32 poly; + u32 __pad_2[4]; + u32 status; + u32 datacntcap; + u32 __pad_3; + u32 result; + u32 curresult; + u32 __pad_4[3]; + u32 revid; +}; + +struct bfin_crc { + struct miscdevice mdev; + struct list_head list; + int irq; + int dma_ch_src; + int dma_ch_dest; + volatile struct crc_register *regs; + struct crc_info *info; + struct mutex mutex; + struct completion c; + unsigned short opmode; + char name[20]; +}; + +/* CRC_STATUS Masks */ +#define CMPERR 0x00000002 /* Compare error */ +#define DCNTEXP 0x00000010 /* datacnt register expired */ +#define IBR 0x00010000 /* Input buffer ready */ +#define OBR 0x00020000 /* Output buffer ready */ +#define IRR 0x00040000 /* Immediate result readt */ +#define LUTDONE 0x00080000 /* Look-up table generation done */ +#define FSTAT 0x00700000 /* FIFO status */ +#define MAX_FIFO 4 /* Max fifo size */ + +/* CRC_CONTROL Masks */ +#define BLKEN 0x00000001 /* Block enable */ +#define OPMODE 0x000000F0 /* Operation mode */ +#define OPMODE_OFFSET 4 /* Operation mode mask offset*/ +#define MODE_DMACPY_CRC 1 /* MTM CRC compute and compare */ +#define MODE_DATA_FILL 2 /* MTM data fill */ +#define MODE_CALC_CRC 3 /* MSM CRC compute and compare */ +#define MODE_DATA_VERIFY 4 /* MSM data verify */ +#define AUTOCLRZ 0x00000100 /* Auto clear to zero */ +#define AUTOCLRF 0x00000200 /* Auto clear to one */ +#define OBRSTALL 0x00001000 /* Stall on output buffer ready */ +#define IRRSTALL 0x00002000 /* Stall on immediate result ready */ +#define BITMIRR 0x00010000 /* Mirror bits within each byte of 32-bit input data */ +#define BITMIRR_OFFSET 16 /* Mirror bits offset */ +#define BYTMIRR 0x00020000 /* Mirror bytes of 32-bit input data */ +#define BYTMIRR_OFFSET 17 /* Mirror bytes offset */ +#define W16SWP 0x00040000 /* Mirror uppper and lower 16-bit word of 32-bit input data */ +#define W16SWP_OFFSET 18 /* Mirror 16-bit word offset */ +#define FDSEL 0x00080000 /* FIFO is written after input data is mirrored */ +#define FDSEL_OFFSET 19 /* Mirror FIFO offset */ +#define RSLTMIRR 0x00100000 /* CRC result registers are mirrored. */ +#define RSLTMIRR_OFFSET 20 /* Mirror CRC result offset. */ +#define POLYMIRR 0x00200000 /* CRC poly register is mirrored. */ +#define POLYMIRR_OFFSET 21 /* Mirror CRC poly offset. */ +#define CMPMIRR 0x00400000 /* CRC compare register is mirrored. */ +#define CMPMIRR_OFFSET 22 /* Mirror CRC compare offset. */ + +/* CRC_INTREN Masks */ +#define CMPERRI 0x02 /* CRC_ERROR_INTR */ +#define DCNTEXPI 0x10 /* CRC_STATUS_INTR */ + +#endif + +#endif
diff --git a/arch/blackfin/include/asm/bfin_dma.h b/arch/blackfin/include/asm/bfin_dma.h index d511207..6319f4e 100644 --- a/arch/blackfin/include/asm/bfin_dma.h +++ b/arch/blackfin/include/asm/bfin_dma.h
@@ -15,12 +15,55 @@ #define DMAEN 0x0001 /* DMA Channel Enable */ #define WNR 0x0002 /* Channel Direction (W/R*) */ #define WDSIZE_8 0x0000 /* Transfer Word Size = 8 */ +#define PSIZE_8 0x00000000 /* Transfer Word Size = 16 */ + +#ifdef CONFIG_BF60x + +#define PSIZE_16 0x00000010 /* Transfer Word Size = 16 */ +#define PSIZE_32 0x00000020 /* Transfer Word Size = 32 */ +#define PSIZE_64 0x00000030 /* Transfer Word Size = 32 */ +#define WDSIZE_16 0x00000100 /* Transfer Word Size = 16 */ +#define WDSIZE_32 0x00000200 /* Transfer Word Size = 32 */ +#define WDSIZE_64 0x00000300 /* Transfer Word Size = 32 */ +#define WDSIZE_128 0x00000400 /* Transfer Word Size = 32 */ +#define WDSIZE_256 0x00000500 /* Transfer Word Size = 32 */ +#define DMA2D 0x04000000 /* DMA Mode (2D/1D*) */ +#define RESTART 0x00000004 /* DMA Buffer Clear SYNC */ +#define DI_EN_X 0x00100000 /* Data Interrupt Enable in X count */ +#define DI_EN_Y 0x00200000 /* Data Interrupt Enable in Y count */ +#define DI_EN_P 0x00300000 /* Data Interrupt Enable in Peripheral */ +#define DI_EN DI_EN_X /* Data Interrupt Enable */ +#define NDSIZE_0 0x00000000 /* Next Descriptor Size = 1 */ +#define NDSIZE_1 0x00010000 /* Next Descriptor Size = 2 */ +#define NDSIZE_2 0x00020000 /* Next Descriptor Size = 3 */ +#define NDSIZE_3 0x00030000 /* Next Descriptor Size = 4 */ +#define NDSIZE_4 0x00040000 /* Next Descriptor Size = 5 */ +#define NDSIZE_5 0x00050000 /* Next Descriptor Size = 6 */ +#define NDSIZE_6 0x00060000 /* Next Descriptor Size = 7 */ +#define NDSIZE 0x00070000 /* Next Descriptor Size */ +#define NDSIZE_OFFSET 16 /* Next Descriptor Size Offset */ +#define DMAFLOW_LIST 0x00004000 /* Descriptor List Mode */ +#define DMAFLOW_LARGE DMAFLOW_LIST +#define DMAFLOW_ARRAY 0x00005000 /* Descriptor Array Mode */ +#define DMAFLOW_LIST_DEMAND 0x00006000 /* Descriptor Demand List Mode */ +#define DMAFLOW_ARRAY_DEMAND 0x00007000 /* Descriptor Demand Array Mode */ +#define DMA_RUN_DFETCH 0x00000100 /* DMA Channel Running Indicator (DFETCH) */ +#define DMA_RUN 0x00000200 /* DMA Channel Running Indicator */ +#define DMA_RUN_WAIT_TRIG 0x00000300 /* DMA Channel Running Indicator (WAIT TRIG) */ +#define DMA_RUN_WAIT_ACK 0x00000400 /* DMA Channel Running Indicator (WAIT ACK) */ + +#else + +#define PSIZE_16 0x0000 /* Transfer Word Size = 16 */ +#define PSIZE_32 0x0000 /* Transfer Word Size = 32 */ #define WDSIZE_16 0x0004 /* Transfer Word Size = 16 */ #define WDSIZE_32 0x0008 /* Transfer Word Size = 32 */ #define DMA2D 0x0010 /* DMA Mode (2D/1D*) */ #define RESTART 0x0020 /* DMA Buffer Clear */ #define DI_SEL 0x0040 /* Data Interrupt Timing Select */ #define DI_EN 0x0080 /* Data Interrupt Enable */ +#define DI_EN_X 0x00C0 /* Data Interrupt Enable in X count*/ +#define DI_EN_Y 0x0080 /* Data Interrupt Enable in Y count*/ #define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */ #define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */ #define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */ @@ -32,18 +75,26 @@ #define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */ #define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */ #define NDSIZE 0x0f00 /* Next Descriptor Size */ -#define DMAFLOW 0x7000 /* Flow Control */ -#define DMAFLOW_STOP 0x0000 /* Stop Mode */ -#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */ +#define NDSIZE_OFFSET 8 /* Next Descriptor Size Offset */ #define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */ #define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */ #define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */ +#define DFETCH 0x0004 /* DMA Descriptor Fetch Indicator */ +#define DMA_RUN 0x0008 /* DMA Channel Running Indicator */ + +#endif +#define DMAFLOW 0x7000 /* Flow Control */ +#define DMAFLOW_STOP 0x0000 /* Stop Mode */ +#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */ /* DMA_IRQ_STATUS Masks */ #define DMA_DONE 0x0001 /* DMA Completion Interrupt Status */ #define DMA_ERR 0x0002 /* DMA Error Interrupt Status */ -#define DFETCH 0x0004 /* DMA Descriptor Fetch Indicator */ -#define DMA_RUN 0x0008 /* DMA Channel Running Indicator */ +#ifdef CONFIG_BF60x +#define DMA_PIRQ 0x0004 /* DMA Peripheral Error Interrupt Status */ +#else +#define DMA_PIRQ 0 +#endif /* * All Blackfin system MMRs are padded to 32bits even if the register @@ -57,6 +108,26 @@ struct bfin_dma_regs { u32 next_desc_ptr; u32 start_addr; +#ifdef CONFIG_BF60x + u32 cfg; + u32 x_count; + u32 x_modify; + u32 y_count; + u32 y_modify; + u32 pad1; + u32 pad2; + u32 curr_desc_ptr; + u32 prev_desc_ptr; + u32 curr_addr; + u32 irq_status; + u32 curr_x_count; + u32 curr_y_count; + u32 pad3; + u32 bw_limit_count; + u32 curr_bw_limit_count; + u32 bw_monitor_count; + u32 curr_bw_monitor_count; +#else __BFP(config); u32 __pad0; __BFP(x_count); @@ -71,8 +142,10 @@ u32 __pad1; __BFP(curr_y_count); u32 __pad2; +#endif }; +#ifndef CONFIG_BF60x /* * bfin handshake mdma registers layout */ @@ -85,6 +158,7 @@ __BFP(ecount); __BFP(bcount); }; +#endif #undef __BFP
diff --git a/arch/blackfin/include/asm/bfin_pfmon.h b/arch/blackfin/include/asm/bfin_pfmon.h index accd47e..bf52e1f 100644 --- a/arch/blackfin/include/asm/bfin_pfmon.h +++ b/arch/blackfin/include/asm/bfin_pfmon.h
@@ -3,7 +3,7 @@ * * Copyright 2005-2011 Analog Devices Inc. * - * Licensed under the ADI BSD license or GPL-2 (or later). + * Licensed under the Clear BSD license or GPL-2 (or later). */ #ifndef __ASM_BFIN_PFMON_H__
diff --git a/arch/blackfin/include/asm/bfin_ppi.h b/arch/blackfin/include/asm/bfin_ppi.h index 3be05fa..a4e872e 100644 --- a/arch/blackfin/include/asm/bfin_ppi.h +++ b/arch/blackfin/include/asm/bfin_ppi.h
@@ -10,6 +10,7 @@ #define __ASM_BFIN_PPI_H__ #include <linux/types.h> +#include <asm/blackfin.h> /* * All Blackfin system MMRs are padded to 32bits even if the register @@ -48,6 +49,133 @@ u32 clip; }; +/* + * bfin eppi3 registers layout + */ +struct bfin_eppi3_regs { + u32 stat; + u32 hcnt; + u32 hdly; + u32 vcnt; + u32 vdly; + u32 frame; + u32 line; + u32 clkdiv; + u32 ctl; + u32 fs1_wlhb; + u32 fs1_paspl; + u32 fs2_wlvb; + u32 fs2_palpf; + u32 imsk; + u32 oddclip; + u32 evenclip; + u32 fs1_dly; + u32 fs2_dly; + u32 ctl2; +}; + #undef __BFP +#ifdef EPPI0_CTL2 +#define EPPI_STAT_CFIFOERR 0x00000001 /* Chroma FIFO Error */ +#define EPPI_STAT_YFIFOERR 0x00000002 /* Luma FIFO Error */ +#define EPPI_STAT_LTERROVR 0x00000004 /* Line Track Overflow */ +#define EPPI_STAT_LTERRUNDR 0x00000008 /* Line Track Underflow */ +#define EPPI_STAT_FTERROVR 0x00000010 /* Frame Track Overflow */ +#define EPPI_STAT_FTERRUNDR 0x00000020 /* Frame Track Underflow */ +#define EPPI_STAT_ERRNCOR 0x00000040 /* Preamble Error Not Corrected */ +#define EPPI_STAT_PXPERR 0x00000080 /* PxP Ready Error */ +#define EPPI_STAT_ERRDET 0x00004000 /* Preamble Error Detected */ +#define EPPI_STAT_FLD 0x00008000 /* Current Field Received by EPPI */ + +#define EPPI_HCNT_VALUE 0x0000FFFF /* Holds the number of samples to read in or write out per line, after PPIx_HDLY number of cycles have expired since the last assertion of PPIx_FS1 */ + +#define EPPI_HDLY_VALUE 0x0000FFFF /* Number of PPIx_CLK cycles to delay after assertion of PPIx_FS1 before starting to read or write data */ + +#define EPPI_VCNT_VALUE 0x0000FFFF /* Holds the number of lines to read in or write out, after PPIx_VDLY number of lines from the start of frame */ + +#define EPPI_VDLY_VALUE 0x0000FFFF /* Number of lines to wait after the start of a new frame before starting to read/transmit data */ + +#define EPPI_FRAME_VALUE 0x0000FFFF /* Holds the number of lines expected per frame of data */ + +#define EPPI_LINE_VALUE 0x0000FFFF /* Holds the number of samples expected per line */ + +#define EPPI_CLKDIV_VALUE 0x0000FFFF /* Internal clock divider */ + +#define EPPI_CTL_EN 0x00000001 /* PPI Enable */ +#define EPPI_CTL_DIR 0x00000002 /* PPI Direction */ +#define EPPI_CTL_XFRTYPE 0x0000000C /* PPI Operating Mode */ +#define EPPI_CTL_ACTIVE656 0x00000000 /* XFRTYPE: ITU656 Active Video Only Mode */ +#define EPPI_CTL_ENTIRE656 0x00000004 /* XFRTYPE: ITU656 Entire Field Mode */ +#define EPPI_CTL_VERT656 0x00000008 /* XFRTYPE: ITU656 Vertical Blanking Only Mode */ +#define EPPI_CTL_NON656 0x0000000C /* XFRTYPE: Non-ITU656 Mode (GP Mode) */ +#define EPPI_CTL_FSCFG 0x00000030 /* Frame Sync Configuration */ +#define EPPI_CTL_SYNC0 0x00000000 /* FSCFG: Sync Mode 0 */ +#define EPPI_CTL_SYNC1 0x00000010 /* FSCFG: Sync Mode 1 */ +#define EPPI_CTL_SYNC2 0x00000020 /* FSCFG: Sync Mode 2 */ +#define EPPI_CTL_SYNC3 0x00000030 /* FSCFG: Sync Mode 3 */ +#define EPPI_CTL_FLDSEL 0x00000040 /* Field Select/Trigger */ +#define EPPI_CTL_ITUTYPE 0x00000080 /* ITU Interlace or Progressive */ +#define EPPI_CTL_BLANKGEN 0x00000100 /* ITU Output Mode with Internal Blanking Generation */ +#define EPPI_CTL_ICLKGEN 0x00000200 /* Internal Clock Generation */ +#define EPPI_CTL_IFSGEN 0x00000400 /* Internal Frame Sync Generation */ +#define EPPI_CTL_SIGNEXT 0x00000800 /* Sign Extension */ +#define EPPI_CTL_POLC 0x00003000 /* Frame Sync and Data Driving and Sampling Edges */ +#define EPPI_CTL_POLC0 0x00000000 /* POLC: Clock/Sync polarity mode 0 */ +#define EPPI_CTL_POLC1 0x00001000 /* POLC: Clock/Sync polarity mode 1 */ +#define EPPI_CTL_POLC2 0x00002000 /* POLC: Clock/Sync polarity mode 2 */ +#define EPPI_CTL_POLC3 0x00003000 /* POLC: Clock/Sync polarity mode 3 */ +#define EPPI_CTL_POLS 0x0000C000 /* Frame Sync Polarity */ +#define EPPI_CTL_FS1HI_FS2HI 0x00000000 /* POLS: FS1 and FS2 are active high */ +#define EPPI_CTL_FS1LO_FS2HI 0x00004000 /* POLS: FS1 is active low. FS2 is active high */ +#define EPPI_CTL_FS1HI_FS2LO 0x00008000 /* POLS: FS1 is active high. FS2 is active low */ +#define EPPI_CTL_FS1LO_FS2LO 0x0000C000 /* POLS: FS1 and FS2 are active low */ +#define EPPI_CTL_DLEN 0x00070000 /* Data Length */ +#define EPPI_CTL_DLEN08 0x00000000 /* DLEN: 8 bits */ +#define EPPI_CTL_DLEN10 0x00010000 /* DLEN: 10 bits */ +#define EPPI_CTL_DLEN12 0x00020000 /* DLEN: 12 bits */ +#define EPPI_CTL_DLEN14 0x00030000 /* DLEN: 14 bits */ +#define EPPI_CTL_DLEN16 0x00040000 /* DLEN: 16 bits */ +#define EPPI_CTL_DLEN18 0x00050000 /* DLEN: 18 bits */ +#define EPPI_CTL_DLEN20 0x00060000 /* DLEN: 20 bits */ +#define EPPI_CTL_DLEN24 0x00070000 /* DLEN: 24 bits */ +#define EPPI_CTL_DMIRR 0x00080000 /* Data Mirroring */ +#define EPPI_CTL_SKIPEN 0x00100000 /* Skip Enable */ +#define EPPI_CTL_SKIPEO 0x00200000 /* Skip Even or Odd */ +#define EPPI_CTL_PACKEN 0x00400000 /* Pack/Unpack Enable */ +#define EPPI_CTL_SWAPEN 0x00800000 /* Swap Enable */ +#define EPPI_CTL_SPLTEO 0x01000000 /* Split Even and Odd Data Samples */ +#define EPPI_CTL_SUBSPLTODD 0x02000000 /* Sub-Split Odd Samples */ +#define EPPI_CTL_SPLTWRD 0x04000000 /* Split Word */ +#define EPPI_CTL_RGBFMTEN 0x08000000 /* RGB Formatting Enable */ +#define EPPI_CTL_DMACFG 0x10000000 /* One or Two DMA Channels Mode */ +#define EPPI_CTL_DMAFINEN 0x20000000 /* DMA Finish Enable */ +#define EPPI_CTL_MUXSEL 0x40000000 /* MUX Select */ +#define EPPI_CTL_CLKGATEN 0x80000000 /* Clock Gating Enable */ + +#define EPPI_FS2_WLVB_F2VBAD 0xFF000000 /* In GP transmit mode with BLANKGEN = 1, contains number of lines of vertical blanking after field 2 */ +#define EPPI_FS2_WLVB_F2VBBD 0x00FF0000 /* In GP transmit mode with BLANKGEN = 1, contains number of lines of vertical blanking before field 2 */ +#define EPPI_FS2_WLVB_F1VBAD 0x0000FF00 /* In GP transmit mode with, BLANKGEN = 1, contains number of lines of vertical blanking after field 1 */ +#define EPPI_FS2_WLVB_F1VBBD 0x000000FF /* In GP 2, or 3 FS modes used to generate PPIx_FS2 width (32-bit). In GP Transmit mode, with BLANKGEN=1, contains the number of lines of Vertical blanking before field 1. */ + +#define EPPI_FS2_PALPF_F2ACT 0xFFFF0000 /* Number of lines of Active Data in Field 2 */ +#define EPPI_FS2_PALPF_F1ACT 0x0000FFFF /* Number of lines of Active Data in Field 1 */ + +#define EPPI_IMSK_CFIFOERR 0x00000001 /* Mask CFIFO Underflow or Overflow Error Interrupt */ +#define EPPI_IMSK_YFIFOERR 0x00000002 /* Mask YFIFO Underflow or Overflow Error Interrupt */ +#define EPPI_IMSK_LTERROVR 0x00000004 /* Mask Line Track Overflow Error Interrupt */ +#define EPPI_IMSK_LTERRUNDR 0x00000008 /* Mask Line Track Underflow Error Interrupt */ +#define EPPI_IMSK_FTERROVR 0x00000010 /* Mask Frame Track Overflow Error Interrupt */ +#define EPPI_IMSK_FTERRUNDR 0x00000020 /* Mask Frame Track Underflow Error Interrupt */ +#define EPPI_IMSK_ERRNCOR 0x00000040 /* Mask ITU Preamble Error Not Corrected Interrupt */ +#define EPPI_IMSK_PXPERR 0x00000080 /* Mask PxP Ready Error Interrupt */ + +#define EPPI_ODDCLIP_HIGHODD 0xFFFF0000 +#define EPPI_ODDCLIP_LOWODD 0x0000FFFF + +#define EPPI_EVENCLIP_HIGHEVEN 0xFFFF0000 +#define EPPI_EVENCLIP_LOWEVEN 0x0000FFFF + +#define EPPI_CTL2_FS1FINEN 0x00000002 /* HSYNC Finish Enable */ +#endif #endif
diff --git a/arch/blackfin/include/asm/bfin_rotary.h b/arch/blackfin/include/asm/bfin_rotary.h index 0b6910bd..8895a75 100644 --- a/arch/blackfin/include/asm/bfin_rotary.h +++ b/arch/blackfin/include/asm/bfin_rotary.h
@@ -39,6 +39,7 @@ unsigned int rotary_rel_code; unsigned short debounce; /* 0..17 */ unsigned short mode; + unsigned short pm_wakeup; }; /* CNT_CONFIG bitmasks */
diff --git a/arch/blackfin/include/asm/bfin_serial.h b/arch/blackfin/include/asm/bfin_serial.h index 68bcc3d..8597158 100644 --- a/arch/blackfin/include/asm/bfin_serial.h +++ b/arch/blackfin/include/asm/bfin_serial.h
@@ -18,7 +18,7 @@ defined(CONFIG_BFIN_UART1_CTSRTS) || \ defined(CONFIG_BFIN_UART2_CTSRTS) || \ defined(CONFIG_BFIN_UART3_CTSRTS) -# ifdef BFIN_UART_BF54X_STYLE +# if defined(BFIN_UART_BF54X_STYLE) || defined(BFIN_UART_BF60X_STYLE) # define CONFIG_SERIAL_BFIN_HARD_CTSRTS # else # define CONFIG_SERIAL_BFIN_CTSRTS @@ -58,14 +58,69 @@ #endif }; +#ifdef BFIN_UART_BF60X_STYLE + +/* UART_CTL Masks */ +#define UCEN 0x1 /* Enable UARTx Clocks */ +#define LOOP_ENA 0x2 /* Loopback Mode Enable */ +#define UMOD_MDB 0x10 /* Enable MDB Mode */ +#define UMOD_IRDA 0x20 /* Enable IrDA Mode */ +#define UMOD_MASK 0x30 /* Uart Mode Mask */ +#define WLS(x) (((x-5) & 0x03) << 8) /* Word Length Select */ +#define WLS_MASK 0x300 /* Word length Select Mask */ +#define WLS_OFFSET 8 /* Word length Select Offset */ +#define STB 0x1000 /* Stop Bits */ +#define STBH 0x2000 /* Half Stop Bits */ +#define PEN 0x4000 /* Parity Enable */ +#define EPS 0x8000 /* Even Parity Select */ +#define STP 0x10000 /* Stick Parity */ +#define FPE 0x20000 /* Force Parity Error On Transmit */ +#define FFE 0x40000 /* Force Framing Error On Transmit */ +#define SB 0x80000 /* Set Break */ +#define LCR_MASK (SB | STP | EPS | PEN | STB | WLS_MASK) +#define FCPOL 0x400000 /* Flow Control Pin Polarity */ +#define RPOLC 0x800000 /* IrDA RX Polarity Change */ +#define TPOLC 0x1000000 /* IrDA TX Polarity Change */ +#define MRTS 0x2000000 /* Manual Request To Send */ +#define XOFF 0x4000000 /* Transmitter Off */ +#define ARTS 0x8000000 /* Automatic Request To Send */ +#define ACTS 0x10000000 /* Automatic Clear To Send */ +#define RFIT 0x20000000 /* Receive FIFO IRQ Threshold */ +#define RFRT 0x40000000 /* Receive FIFO RTS Threshold */ + +/* UART_STAT Masks */ +#define DR 0x01 /* Data Ready */ +#define OE 0x02 /* Overrun Error */ +#define PE 0x04 /* Parity Error */ +#define FE 0x08 /* Framing Error */ +#define BI 0x10 /* Break Interrupt */ +#define THRE 0x20 /* THR Empty */ +#define TEMT 0x80 /* TSR and UART_THR Empty */ +#define TFI 0x100 /* Transmission Finished Indicator */ + +#define ASTKY 0x200 /* Address Sticky */ +#define ADDR 0x400 /* Address bit status */ +#define RO 0x800 /* Reception Ongoing */ +#define SCTS 0x1000 /* Sticky CTS */ +#define CTS 0x10000 /* Clear To Send */ +#define RFCS 0x20000 /* Receive FIFO Count Status */ + +/* UART_CLOCK Masks */ +#define EDBO 0x80000000 /* Enable Devide by One */ + +#else /* BFIN_UART_BF60X_STYLE */ + /* UART_LCR Masks */ #define WLS(x) (((x)-5) & 0x03) /* Word Length Select */ +#define WLS_MASK 0x03 /* Word length Select Mask */ +#define WLS_OFFSET 0 /* Word length Select Offset */ #define STB 0x04 /* Stop Bits */ #define PEN 0x08 /* Parity Enable */ #define EPS 0x10 /* Even Parity Select */ #define STP 0x20 /* Stick Parity */ #define SB 0x40 /* Set Break */ #define DLAB 0x80 /* Divisor Latch Access */ +#define LCR_MASK (SB | STP | EPS | PEN | STB | WLS_MASK) /* UART_LSR Masks */ #define DR 0x01 /* Data Ready */ @@ -77,15 +132,6 @@ #define TEMT 0x40 /* TSR and UART_THR Empty */ #define TFI 0x80 /* Transmission Finished Indicator */ -/* UART_IER Masks */ -#define ERBFI 0x01 /* Enable Receive Buffer Full Interrupt */ -#define ETBEI 0x02 /* Enable Transmit Buffer Empty Interrupt */ -#define ELSI 0x04 /* Enable RX Status Interrupt */ -#define EDSSI 0x08 /* Enable Modem Status Interrupt */ -#define EDTPTI 0x10 /* Enable DMA Transmit PIRQ Interrupt */ -#define ETFI 0x20 /* Enable Transmission Finished Interrupt */ -#define ERFCI 0x40 /* Enable Receive FIFO Count Interrupt */ - /* UART_MCR Masks */ #define XOFF 0x01 /* Transmitter Off */ #define MRTS 0x02 /* Manual Request To Send */ @@ -103,13 +149,36 @@ /* UART_GCTL Masks */ #define UCEN 0x01 /* Enable UARTx Clocks */ -#define IREN 0x02 /* Enable IrDA Mode */ +#define UMOD_IRDA 0x02 /* Enable IrDA Mode */ +#define UMOD_MASK 0x02 /* Uart Mode Mask */ #define TPOLC 0x04 /* IrDA TX Polarity Change */ #define RPOLC 0x08 /* IrDA RX Polarity Change */ #define FPE 0x10 /* Force Parity Error On Transmit */ #define FFE 0x20 /* Force Framing Error On Transmit */ -#ifdef BFIN_UART_BF54X_STYLE +#endif /* BFIN_UART_BF60X_STYLE */ + +/* UART_IER Masks */ +#define ERBFI 0x01 /* Enable Receive Buffer Full Interrupt */ +#define ETBEI 0x02 /* Enable Transmit Buffer Empty Interrupt */ +#define ELSI 0x04 /* Enable RX Status Interrupt */ +#define EDSSI 0x08 /* Enable Modem Status Interrupt */ +#define EDTPTI 0x10 /* Enable DMA Transmit PIRQ Interrupt */ +#define ETFI 0x20 /* Enable Transmission Finished Interrupt */ +#define ERFCI 0x40 /* Enable Receive FIFO Count Interrupt */ + +#if defined(BFIN_UART_BF60X_STYLE) +# define OFFSET_REDIV 0x00 /* Version ID Register */ +# define OFFSET_CTL 0x04 /* Control Register */ +# define OFFSET_STAT 0x08 /* Status Register */ +# define OFFSET_SCR 0x0C /* SCR Scratch Register */ +# define OFFSET_CLK 0x10 /* Clock Rate Register */ +# define OFFSET_IER 0x14 /* Interrupt Enable Register */ +# define OFFSET_IER_SET 0x18 /* Set Interrupt Enable Register */ +# define OFFSET_IER_CLEAR 0x1C /* Clear Interrupt Enable Register */ +# define OFFSET_RBR 0x20 /* Receive Buffer register */ +# define OFFSET_THR 0x24 /* Transmit Holding register */ +#elif defined(BFIN_UART_BF54X_STYLE) # define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */ # define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */ # define OFFSET_GCTL 0x08 /* Global Control Register */ @@ -145,7 +214,23 @@ */ #define __BFP(m) u16 m; u16 __pad_##m struct bfin_uart_regs { -#ifdef BFIN_UART_BF54X_STYLE +#if defined(BFIN_UART_BF60X_STYLE) + u32 revid; + u32 ctl; + u32 stat; + u32 scr; + u32 clk; + u32 ier; + u32 ier_set; + u32 ier_clear; + u32 rbr; + u32 thr; + u32 taip; + u32 tsr; + u32 rsr; + u32 txdiv; + u32 rxdiv; +#elif defined(BFIN_UART_BF54X_STYLE) __BFP(dll); __BFP(dlh); __BFP(gctl); @@ -182,13 +267,70 @@ }; #undef __BFP +#define port_membase(uart) (((struct bfin_serial_port *)(uart))->port.membase) + +/* #ifndef port_membase # define port_membase(p) 0 #endif +*/ +#ifdef BFIN_UART_BF60X_STYLE + +#define UART_GET_CHAR(p) bfin_read32(port_membase(p) + OFFSET_RBR) +#define UART_GET_CLK(p) bfin_read32(port_membase(p) + OFFSET_CLK) +#define UART_GET_CTL(p) bfin_read32(port_membase(p) + OFFSET_CTL) +#define UART_GET_GCTL(p) UART_GET_CTL(p) +#define UART_GET_LCR(p) UART_GET_CTL(p) +#define UART_GET_MCR(p) UART_GET_CTL(p) +#if ANOMALY_05001001 +#define UART_GET_STAT(p) \ +({ \ + u32 __ret; \ + unsigned long flags; \ + flags = hard_local_irq_save(); \ + __ret = bfin_read32(port_membase(p) + OFFSET_STAT); \ + hard_local_irq_restore(flags); \ + __ret; \ +}) +#else +#define UART_GET_STAT(p) bfin_read32(port_membase(p) + OFFSET_STAT) +#endif +#define UART_GET_MSR(p) UART_GET_STAT(p) + +#define UART_PUT_CHAR(p, v) bfin_write32(port_membase(p) + OFFSET_THR, v) +#define UART_PUT_CLK(p, v) bfin_write32(port_membase(p) + OFFSET_CLK, v) +#define UART_PUT_CTL(p, v) bfin_write32(port_membase(p) + OFFSET_CTL, v) +#define UART_PUT_GCTL(p, v) UART_PUT_CTL(p, v) +#define UART_PUT_LCR(p, v) UART_PUT_CTL(p, v) +#define UART_PUT_MCR(p, v) UART_PUT_CTL(p, v) +#define UART_PUT_STAT(p, v) bfin_write32(port_membase(p) + OFFSET_STAT, v) + +#define UART_CLEAR_IER(p, v) bfin_write32(port_membase(p) + OFFSET_IER_CLEAR, v) +#define UART_GET_IER(p) bfin_read32(port_membase(p) + OFFSET_IER) +#define UART_SET_IER(p, v) bfin_write32(port_membase(p) + OFFSET_IER_SET, v) + +#define UART_CLEAR_DLAB(p) /* MMRs not muxed on BF60x */ +#define UART_SET_DLAB(p) /* MMRs not muxed on BF60x */ + +#define UART_CLEAR_LSR(p) UART_PUT_STAT(p, -1) +#define UART_GET_LSR(p) UART_GET_STAT(p) +#define UART_PUT_LSR(p, v) UART_PUT_STAT(p, v) + +/* This handles hard CTS/RTS */ +#define BFIN_UART_CTSRTS_HARD +#define UART_CLEAR_SCTS(p) UART_PUT_STAT(p, SCTS) +#define UART_GET_CTS(x) (UART_GET_MSR(x) & CTS) +#define UART_DISABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) & ~(ARTS | MRTS)) +#define UART_ENABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) | MRTS | ARTS) +#define UART_ENABLE_INTS(x, v) UART_SET_IER(x, v) +#define UART_DISABLE_INTS(x) UART_CLEAR_IER(x, 0xF) + +#else /* BFIN_UART_BF60X_STYLE */ #define UART_GET_CHAR(p) bfin_read16(port_membase(p) + OFFSET_RBR) #define UART_GET_DLL(p) bfin_read16(port_membase(p) + OFFSET_DLL) #define UART_GET_DLH(p) bfin_read16(port_membase(p) + OFFSET_DLH) +#define UART_GET_CLK(p) ((UART_GET_DLH(p) << 8) | UART_GET_DLL(p)) #define UART_GET_GCTL(p) bfin_read16(port_membase(p) + OFFSET_GCTL) #define UART_GET_LCR(p) bfin_read16(port_membase(p) + OFFSET_LCR) #define UART_GET_MCR(p) bfin_read16(port_membase(p) + OFFSET_MCR) @@ -197,6 +339,11 @@ #define UART_PUT_CHAR(p, v) bfin_write16(port_membase(p) + OFFSET_THR, v) #define UART_PUT_DLL(p, v) bfin_write16(port_membase(p) + OFFSET_DLL, v) #define UART_PUT_DLH(p, v) bfin_write16(port_membase(p) + OFFSET_DLH, v) +#define UART_PUT_CLK(p, v) do \ +{\ +UART_PUT_DLL(p, v & 0xFF); \ +UART_PUT_DLH(p, (v >> 8) & 0xFF); } while (0); + #define UART_PUT_GCTL(p, v) bfin_write16(port_membase(p) + OFFSET_GCTL, v) #define UART_PUT_LCR(p, v) bfin_write16(port_membase(p) + OFFSET_LCR, v) #define UART_PUT_MCR(p, v) bfin_write16(port_membase(p) + OFFSET_MCR, v) @@ -233,12 +380,17 @@ #define UART_CLEAR_DLAB(p) do { UART_PUT_LCR(p, UART_GET_LCR(p) & ~DLAB); SSYNC(); } while (0) #define UART_SET_DLAB(p) do { UART_PUT_LCR(p, UART_GET_LCR(p) | DLAB); SSYNC(); } while (0) +#define get_lsr_cache(uart) (((struct bfin_serial_port *)(uart))->lsr) +#define put_lsr_cache(uart, v) (((struct bfin_serial_port *)(uart))->lsr = (v)) + +/* #ifndef put_lsr_cache # define put_lsr_cache(p, v) #endif #ifndef get_lsr_cache # define get_lsr_cache(p) 0 #endif +*/ /* The hardware clears the LSR bits upon read, so we need to cache * some of the more fun bits in software so they don't get lost @@ -267,7 +419,9 @@ #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) #define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0) -#endif +#endif /* BFIN_UART_BF54X_STYLE */ + +#endif /* BFIN_UART_BF60X_STYLE */ #ifndef BFIN_UART_TX_FIFO_SIZE # define BFIN_UART_TX_FIFO_SIZE 2
diff --git a/arch/blackfin/include/asm/bfin_sport.h b/arch/blackfin/include/asm/bfin_sport.h index 0afcfbd..f8907ea 100644 --- a/arch/blackfin/include/asm/bfin_sport.h +++ b/arch/blackfin/include/asm/bfin_sport.h
@@ -24,6 +24,7 @@ struct sport_config { /* TDM (multichannels), I2S or other mode */ unsigned int mode:3; + unsigned int polled; /* use poll instead of irq when set */ /* if TDM mode is selected, channels must be set */ int channels; /* Must be in 8 units */
diff --git a/arch/blackfin/include/asm/bfin_sport3.h b/arch/blackfin/include/asm/bfin_sport3.h new file mode 100644 index 0000000..03c0022 --- /dev/null +++ b/arch/blackfin/include/asm/bfin_sport3.h
@@ -0,0 +1,107 @@ +/* + * bfin_sport - Analog Devices BF6XX SPORT registers + * + * Copyright (c) 2012 Analog Devices Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _BFIN_SPORT3_H_ +#define _BFIN_SPORT3_H_ + +#include <linux/types.h> + +#define SPORT_CTL_SPENPRI 0x00000001 /* Enable Primary Channel */ +#define SPORT_CTL_DTYPE 0x00000006 /* Data type select */ +#define SPORT_CTL_RJUSTIFY_ZFILL 0x00000000 /* DTYPE: MCM mode: Right-justify, zero-fill unused MSBs */ +#define SPORT_CTL_RJUSTIFY_SFILL 0x00000002 /* DTYPE: MCM mode: Right-justify, sign-extend unused MSBs */ +#define SPORT_CTL_USE_U_LAW 0x00000004 /* DTYPE: MCM mode: Compand using u-law */ +#define SPORT_CTL_USE_A_LAW 0x00000006 /* DTYPE: MCM mode: Compand using A-law */ +#define SPORT_CTL_LSBF 0x00000008 /* Serial bit endian select */ +#define SPORT_CTL_SLEN 0x000001F0 /* Serial Word length select */ +#define SPORT_CTL_PACK 0x00000200 /* 16-bit to 32-bit packing enable */ +#define SPORT_CTL_ICLK 0x00000400 /* Internal Clock Select */ +#define SPORT_CTL_OPMODE 0x00000800 /* Operation mode */ +#define SPORT_CTL_CKRE 0x00001000 /* Clock rising edge select */ +#define SPORT_CTL_FSR 0x00002000 /* Frame Sync required */ +#define SPORT_CTL_IFS 0x00004000 /* Internal Frame Sync select */ +#define SPORT_CTL_DIFS 0x00008000 /* Data-independent frame sync select */ +#define SPORT_CTL_LFS 0x00010000 /* Active low frame sync select */ +#define SPORT_CTL_LAFS 0x00020000 /* Late Transmit frame select */ +#define SPORT_CTL_RJUST 0x00040000 /* Right Justified mode select */ +#define SPORT_CTL_FSED 0x00080000 /* External frame sync edge select */ +#define SPORT_CTL_TFIEN 0x00100000 /* Transmit finish interrrupt enable select */ +#define SPORT_CTL_GCLKEN 0x00200000 /* Gated clock mode select */ +#define SPORT_CTL_SPENSEC 0x01000000 /* Enable secondary channel */ +#define SPORT_CTL_SPTRAN 0x02000000 /* Data direction control */ +#define SPORT_CTL_DERRSEC 0x04000000 /* Secondary channel error status */ +#define SPORT_CTL_DXSSEC 0x18000000 /* Secondary channel data buffer status */ +#define SPORT_CTL_SEC_EMPTY 0x00000000 /* DXSSEC: Empty */ +#define SPORT_CTL_SEC_PART_FULL 0x10000000 /* DXSSEC: Partially full */ +#define SPORT_CTL_SEC_FULL 0x18000000 /* DXSSEC: Full */ +#define SPORT_CTL_DERRPRI 0x20000000 /* Primary channel error status */ +#define SPORT_CTL_DXSPRI 0xC0000000 /* Primary channel data buffer status */ +#define SPORT_CTL_PRM_EMPTY 0x00000000 /* DXSPRI: Empty */ +#define SPORT_CTL_PRM_PART_FULL 0x80000000 /* DXSPRI: Partially full */ +#define SPORT_CTL_PRM_FULL 0xC0000000 /* DXSPRI: Full */ + +#define SPORT_DIV_CLKDIV 0x0000FFFF /* Clock divisor */ +#define SPORT_DIV_FSDIV 0xFFFF0000 /* Frame sync divisor */ + +#define SPORT_MCTL_MCE 0x00000001 /* Multichannel enable */ +#define SPORT_MCTL_MCPDE 0x00000004 /* Multichannel data packing select */ +#define SPORT_MCTL_MFD 0x000000F0 /* Multichannel frame delay */ +#define SPORT_MCTL_WSIZE 0x00007F00 /* Number of multichannel slots */ +#define SPORT_MCTL_WOFFSET 0x03FF0000 /* Window offset size */ + +#define SPORT_CNT_CLKCNT 0x0000FFFF /* Current state of clk div counter */ +#define SPORT_CNT_FSDIVCNT 0xFFFF0000 /* Current state of frame div counter */ + +#define SPORT_ERR_DERRPMSK 0x00000001 /* Primary channel data error interrupt enable */ +#define SPORT_ERR_DERRSMSK 0x00000002 /* Secondary channel data error interrupt enable */ +#define SPORT_ERR_FSERRMSK 0x00000004 /* Frame sync error interrupt enable */ +#define SPORT_ERR_DERRPSTAT 0x00000010 /* Primary channel data error status */ +#define SPORT_ERR_DERRSSTAT 0x00000020 /* Secondary channel data error status */ +#define SPORT_ERR_FSERRSTAT 0x00000040 /* Frame sync error status */ + +#define SPORT_MSTAT_CURCHAN 0x000003FF /* Channel which is being serviced in the multichannel operation */ + +#define SPORT_CTL2_FSMUXSEL 0x00000001 /* Frame Sync MUX Select */ +#define SPORT_CTL2_CKMUXSEL 0x00000002 /* Clock MUX Select */ +#define SPORT_CTL2_LBSEL 0x00000004 /* Loopback Select */ + +struct sport_register { + u32 spctl; + u32 div; + u32 spmctl; + u32 spcs0; + u32 spcs1; + u32 spcs2; + u32 spcs3; + u32 spcnt; + u32 sperrctl; + u32 spmstat; + u32 spctl2; + u32 txa; + u32 rxa; + u32 txb; + u32 rxb; + u32 revid; +}; + +struct bfin_snd_platform_data { + const unsigned short *pin_req; +}; + +#endif
diff --git a/arch/blackfin/include/asm/bfin_twi.h b/arch/blackfin/include/asm/bfin_twi.h index e767d64..2f3339a 100644 --- a/arch/blackfin/include/asm/bfin_twi.h +++ b/arch/blackfin/include/asm/bfin_twi.h
@@ -10,6 +10,7 @@ #define __ASM_BFIN_TWI_H__ #include <linux/types.h> +#include <linux/i2c.h> /* * All Blackfin system MMRs are padded to 32bits even if the register @@ -42,4 +43,145 @@ #undef __BFP +struct bfin_twi_iface { + int irq; + spinlock_t lock; + char read_write; + u8 command; + u8 *transPtr; + int readNum; + int writeNum; + int cur_mode; + int manual_stop; + int result; + struct i2c_adapter adap; + struct completion complete; + struct i2c_msg *pmsg; + int msg_num; + int cur_msg; + u16 saved_clkdiv; + u16 saved_control; + struct bfin_twi_regs *regs_base; +}; + +#define DEFINE_TWI_REG(reg_name, reg) \ +static inline u16 read_##reg_name(struct bfin_twi_iface *iface) \ + { return iface->regs_base->reg; } \ +static inline void write_##reg_name(struct bfin_twi_iface *iface, u16 v) \ + { iface->regs_base->reg = v; } + +DEFINE_TWI_REG(CLKDIV, clkdiv) +DEFINE_TWI_REG(CONTROL, control) +DEFINE_TWI_REG(SLAVE_CTL, slave_ctl) +DEFINE_TWI_REG(SLAVE_STAT, slave_stat) +DEFINE_TWI_REG(SLAVE_ADDR, slave_addr) +DEFINE_TWI_REG(MASTER_CTL, master_ctl) +DEFINE_TWI_REG(MASTER_STAT, master_stat) +DEFINE_TWI_REG(MASTER_ADDR, master_addr) +DEFINE_TWI_REG(INT_STAT, int_stat) +DEFINE_TWI_REG(INT_MASK, int_mask) +DEFINE_TWI_REG(FIFO_CTL, fifo_ctl) +DEFINE_TWI_REG(FIFO_STAT, fifo_stat) +DEFINE_TWI_REG(XMT_DATA8, xmt_data8) +DEFINE_TWI_REG(XMT_DATA16, xmt_data16) +#if !ANOMALY_05001001 +DEFINE_TWI_REG(RCV_DATA8, rcv_data8) +DEFINE_TWI_REG(RCV_DATA16, rcv_data16) +#else +static inline u16 read_RCV_DATA8(struct bfin_twi_iface *iface) +{ + u16 ret; + unsigned long flags; + + flags = hard_local_irq_save(); + ret = iface->regs_base->rcv_data8; + hard_local_irq_restore(flags); + + return ret; +} + +static inline u16 read_RCV_DATA16(struct bfin_twi_iface *iface) +{ + u16 ret; + unsigned long flags; + + flags = hard_local_irq_save(); + ret = iface->regs_base->rcv_data16; + hard_local_irq_restore(flags); + + return ret; +} +#endif + + +/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ***********************/ +/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */ +#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */ +#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */ + +/* TWI_PRESCALE Masks */ +#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */ +#define TWI_ENA 0x0080 /* TWI Enable */ +#define SCCB 0x0200 /* SCCB Compatibility Enable */ + +/* TWI_SLAVE_CTL Masks */ +#define SEN 0x0001 /* Slave Enable */ +#define SADD_LEN 0x0002 /* Slave Address Length */ +#define STDVAL 0x0004 /* Slave Transmit Data Valid */ +#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ +#define GEN 0x0010 /* General Call Address Matching Enabled */ + +/* TWI_SLAVE_STAT Masks */ +#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ +#define GCALL 0x0002 /* General Call Indicator */ + +/* TWI_MASTER_CTL Masks */ +#define MEN 0x0001 /* Master Mode Enable */ +#define MADD_LEN 0x0002 /* Master Address Length */ +#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */ +#define FAST 0x0008 /* Use Fast Mode Timing Specs */ +#define STOP 0x0010 /* Issue Stop Condition */ +#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */ +#define DCNT 0x3FC0 /* Data Bytes To Transfer */ +#define SDAOVR 0x4000 /* Serial Data Override */ +#define SCLOVR 0x8000 /* Serial Clock Override */ + +/* TWI_MASTER_STAT Masks */ +#define MPROG 0x0001 /* Master Transfer In Progress */ +#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */ +#define ANAK 0x0004 /* Address Not Acknowledged */ +#define DNAK 0x0008 /* Data Not Acknowledged */ +#define BUFRDERR 0x0010 /* Buffer Read Error */ +#define BUFWRERR 0x0020 /* Buffer Write Error */ +#define SDASEN 0x0040 /* Serial Data Sense */ +#define SCLSEN 0x0080 /* Serial Clock Sense */ +#define BUSBUSY 0x0100 /* Bus Busy Indicator */ + +/* TWI_INT_SRC and TWI_INT_ENABLE Masks */ +#define SINIT 0x0001 /* Slave Transfer Initiated */ +#define SCOMP 0x0002 /* Slave Transfer Complete */ +#define SERR 0x0004 /* Slave Transfer Error */ +#define SOVF 0x0008 /* Slave Overflow */ +#define MCOMP 0x0010 /* Master Transfer Complete */ +#define MERR 0x0020 /* Master Transfer Error */ +#define XMTSERV 0x0040 /* Transmit FIFO Service */ +#define RCVSERV 0x0080 /* Receive FIFO Service */ + +/* TWI_FIFO_CTRL Masks */ +#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */ +#define RCVFLUSH 0x0002 /* Receive Buffer Flush */ +#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */ +#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */ + +/* TWI_FIFO_STAT Masks */ +#define XMTSTAT 0x0003 /* Transmit FIFO Status */ +#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */ +#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */ +#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */ + +#define RCVSTAT 0x000C /* Receive FIFO Status */ +#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */ +#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ +#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ + #endif
diff --git a/arch/blackfin/include/asm/blackfin.h b/arch/blackfin/include/asm/blackfin.h index 7be5368..f111f366 100644 --- a/arch/blackfin/include/asm/blackfin.h +++ b/arch/blackfin/include/asm/blackfin.h
@@ -63,20 +63,16 @@ #if ANOMALY_05000312 || ANOMALY_05000244 #define SSYNC(scratch) \ -do { \ cli scratch; \ nop; nop; nop; \ SSYNC; \ - sti scratch; \ -} while (0) + sti scratch; #define CSYNC(scratch) \ -do { \ cli scratch; \ nop; nop; nop; \ CSYNC; \ - sti scratch; \ -} while (0) + sti scratch; #else #define SSYNC(scratch) SSYNC;
diff --git a/arch/blackfin/include/asm/clkdev.h b/arch/blackfin/include/asm/clkdev.h new file mode 100644 index 0000000..9053bed --- /dev/null +++ b/arch/blackfin/include/asm/clkdev.h
@@ -0,0 +1,14 @@ +#ifndef __ASM_CLKDEV__H_ +#define __ASM_CLKDEV__H_ + +#include <linux/slab.h> + +static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size) +{ + return kzalloc(size, GFP_KERNEL); +} + +#define __clk_put(clk) +#define __clk_get(clk) ({ 1; }) + +#endif
diff --git a/arch/blackfin/include/asm/clocks.h b/arch/blackfin/include/asm/clocks.h index 6f0b618..9b3c85b 100644 --- a/arch/blackfin/include/asm/clocks.h +++ b/arch/blackfin/include/asm/clocks.h
@@ -48,4 +48,27 @@ # define CONFIG_VCO_MULT 0 #endif +#include <linux/clk.h> + +struct clk_ops { + unsigned long (*get_rate)(struct clk *clk); + unsigned long (*round_rate)(struct clk *clk, unsigned long rate); + int (*set_rate)(struct clk *clk, unsigned long rate); + int (*enable)(struct clk *clk); + int (*disable)(struct clk *clk); +}; + +struct clk { + struct clk *parent; + const char *name; + unsigned long rate; + spinlock_t lock; + u32 flags; + const struct clk_ops *ops; + void __iomem *reg; + u32 mask; + u32 shift; +}; + +int clk_init(void); #endif
diff --git a/arch/blackfin/include/asm/cplb.h b/arch/blackfin/include/asm/cplb.h index fda9626..5c37f62 100644 --- a/arch/blackfin/include/asm/cplb.h +++ b/arch/blackfin/include/asm/cplb.h
@@ -62,6 +62,10 @@ #define SIZE_4K 0x00001000 /* 4K */ #define SIZE_1M 0x00100000 /* 1M */ #define SIZE_4M 0x00400000 /* 4M */ +#define SIZE_16K 0x00004000 /* 16K */ +#define SIZE_64K 0x00010000 /* 64K */ +#define SIZE_16M 0x01000000 /* 16M */ +#define SIZE_64M 0x04000000 /* 64M */ #define MAX_CPLBS 16
diff --git a/arch/blackfin/include/asm/def_LPBlackfin.h b/arch/blackfin/include/asm/def_LPBlackfin.h index 8236790..fe0ca03 100644 --- a/arch/blackfin/include/asm/def_LPBlackfin.h +++ b/arch/blackfin/include/asm/def_LPBlackfin.h
@@ -3,7 +3,7 @@ * * Copyright 2005-2008 Analog Devices Inc. * - * Licensed under the ADI BSD license or GPL-2 (or later). + * Licensed under the Clear BSD license or GPL-2 (or later). */ #ifndef _DEF_LPBLACKFIN_H @@ -622,6 +622,10 @@ #define PAGE_SIZE_4KB 0x00010000 /* 4 KB page size */ #define PAGE_SIZE_1MB 0x00020000 /* 1 MB page size */ #define PAGE_SIZE_4MB 0x00030000 /* 4 MB page size */ +#define PAGE_SIZE_16KB 0x00040000 /* 16 KB page size */ +#define PAGE_SIZE_64KB 0x00050000 /* 64 KB page size */ +#define PAGE_SIZE_16MB 0x00060000 /* 16 MB page size */ +#define PAGE_SIZE_64MB 0x00070000 /* 64 MB page size */ #define CPLB_L1SRAM 0x00000020 /* 0=SRAM mapped in L1, 0=SRAM not * mapped to L1 */
diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index dac0c97..40e9c2b 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h
@@ -22,12 +22,22 @@ #define DATA_SIZE_8 0 #define DATA_SIZE_16 1 #define DATA_SIZE_32 2 +#ifdef CONFIG_BF60x +#define DATA_SIZE_64 3 +#endif #define DMA_FLOW_STOP 0 #define DMA_FLOW_AUTO 1 +#ifdef CONFIG_BF60x +#define DMA_FLOW_LIST 4 +#define DMA_FLOW_ARRAY 5 +#define DMA_FLOW_LIST_DEMAND 6 +#define DMA_FLOW_ARRAY_DEMAND 7 +#else #define DMA_FLOW_ARRAY 4 #define DMA_FLOW_SMALL 6 #define DMA_FLOW_LARGE 7 +#endif #define DIMENSION_LINEAR 0 #define DIMENSION_2D 1 @@ -36,26 +46,80 @@ #define DIR_WRITE 1 #define INTR_DISABLE 0 +#ifdef CONFIG_BF60x +#define INTR_ON_PERI 1 +#endif #define INTR_ON_BUF 2 #define INTR_ON_ROW 3 #define DMA_NOSYNC_KEEP_DMA_BUF 0 #define DMA_SYNC_RESTART 1 +#ifdef DMA_MMR_SIZE_32 +#define DMA_MMR_SIZE_TYPE long +#define DMA_MMR_READ bfin_read32 +#define DMA_MMR_WRITE bfin_write32 +#else +#define DMA_MMR_SIZE_TYPE short +#define DMA_MMR_READ bfin_read16 +#define DMA_MMR_WRITE bfin_write16 +#endif + +struct dma_desc_array { + unsigned long start_addr; + unsigned DMA_MMR_SIZE_TYPE cfg; + unsigned DMA_MMR_SIZE_TYPE x_count; + DMA_MMR_SIZE_TYPE x_modify; +} __attribute__((packed)); + struct dmasg { void *next_desc_addr; unsigned long start_addr; - unsigned short cfg; - unsigned short x_count; - short x_modify; - unsigned short y_count; - short y_modify; + unsigned DMA_MMR_SIZE_TYPE cfg; + unsigned DMA_MMR_SIZE_TYPE x_count; + DMA_MMR_SIZE_TYPE x_modify; + unsigned DMA_MMR_SIZE_TYPE y_count; + DMA_MMR_SIZE_TYPE y_modify; } __attribute__((packed)); struct dma_register { void *next_desc_ptr; /* DMA Next Descriptor Pointer register */ unsigned long start_addr; /* DMA Start address register */ +#ifdef CONFIG_BF60x + unsigned long cfg; /* DMA Configuration register */ + unsigned long x_count; /* DMA x_count register */ + + long x_modify; /* DMA x_modify register */ + + unsigned long y_count; /* DMA y_count register */ + + long y_modify; /* DMA y_modify register */ + + unsigned long reserved; + unsigned long reserved2; + + void *curr_desc_ptr; /* DMA Current Descriptor Pointer + register */ + void *prev_desc_ptr; /* DMA previous initial Descriptor Pointer + register */ + unsigned long curr_addr_ptr; /* DMA Current Address Pointer + register */ + unsigned long irq_status; /* DMA irq status register */ + + unsigned long curr_x_count; /* DMA Current x-count register */ + + unsigned long curr_y_count; /* DMA Current y-count register */ + + unsigned long reserved3; + + unsigned long bw_limit_count; /* DMA band width limit count register */ + unsigned long curr_bw_limit_count; /* DMA Current band width limit + count register */ + unsigned long bw_monitor_count; /* DMA band width limit count register */ + unsigned long curr_bw_monitor_count; /* DMA Current band width limit + count register */ +#else unsigned short cfg; /* DMA Configuration register */ unsigned short dummy1; /* DMA Configuration register */ @@ -92,6 +156,7 @@ unsigned short dummy9; unsigned long reserved3; +#endif }; @@ -131,23 +196,23 @@ { dma_ch[channel].regs->curr_desc_ptr = addr; } -static inline void set_dma_x_count(unsigned int channel, unsigned short x_count) +static inline void set_dma_x_count(unsigned int channel, unsigned DMA_MMR_SIZE_TYPE x_count) { dma_ch[channel].regs->x_count = x_count; } -static inline void set_dma_y_count(unsigned int channel, unsigned short y_count) +static inline void set_dma_y_count(unsigned int channel, unsigned DMA_MMR_SIZE_TYPE y_count) { dma_ch[channel].regs->y_count = y_count; } -static inline void set_dma_x_modify(unsigned int channel, short x_modify) +static inline void set_dma_x_modify(unsigned int channel, DMA_MMR_SIZE_TYPE x_modify) { dma_ch[channel].regs->x_modify = x_modify; } -static inline void set_dma_y_modify(unsigned int channel, short y_modify) +static inline void set_dma_y_modify(unsigned int channel, DMA_MMR_SIZE_TYPE y_modify) { dma_ch[channel].regs->y_modify = y_modify; } -static inline void set_dma_config(unsigned int channel, unsigned short config) +static inline void set_dma_config(unsigned int channel, unsigned DMA_MMR_SIZE_TYPE config) { dma_ch[channel].regs->cfg = config; } @@ -156,23 +221,55 @@ dma_ch[channel].regs->curr_addr_ptr = addr; } -static inline unsigned short -set_bfin_dma_config(char direction, char flow_mode, - char intr_mode, char dma_mode, char width, char syncmode) +#ifdef CONFIG_BF60x +static inline unsigned long +set_bfin_dma_config2(char direction, char flow_mode, char intr_mode, + char dma_mode, char mem_width, char syncmode, char peri_width) { - return (direction << 1) | (width << 2) | (dma_mode << 4) | + unsigned long config = 0; + + switch (intr_mode) { + case INTR_ON_BUF: + if (dma_mode == DIMENSION_2D) + config = DI_EN_Y; + else + config = DI_EN_X; + break; + case INTR_ON_ROW: + config = DI_EN_X; + break; + case INTR_ON_PERI: + config = DI_EN_P; + break; + }; + + return config | (direction << 1) | (mem_width << 8) | (dma_mode << 26) | + (flow_mode << 12) | (syncmode << 2) | (peri_width << 4); +} +#endif + +static inline unsigned DMA_MMR_SIZE_TYPE +set_bfin_dma_config(char direction, char flow_mode, + char intr_mode, char dma_mode, char mem_width, char syncmode) +{ +#ifdef CONFIG_BF60x + return set_bfin_dma_config2(direction, flow_mode, intr_mode, dma_mode, + mem_width, syncmode, mem_width); +#else + return (direction << 1) | (mem_width << 2) | (dma_mode << 4) | (intr_mode << 6) | (flow_mode << 12) | (syncmode << 5); +#endif } -static inline unsigned short get_dma_curr_irqstat(unsigned int channel) +static inline unsigned DMA_MMR_SIZE_TYPE get_dma_curr_irqstat(unsigned int channel) { return dma_ch[channel].regs->irq_status; } -static inline unsigned short get_dma_curr_xcount(unsigned int channel) +static inline unsigned DMA_MMR_SIZE_TYPE get_dma_curr_xcount(unsigned int channel) { return dma_ch[channel].regs->curr_x_count; } -static inline unsigned short get_dma_curr_ycount(unsigned int channel) +static inline unsigned DMA_MMR_SIZE_TYPE get_dma_curr_ycount(unsigned int channel) { return dma_ch[channel].regs->curr_y_count; } @@ -184,7 +281,7 @@ { return dma_ch[channel].regs->curr_desc_ptr; } -static inline unsigned short get_dma_config(unsigned int channel) +static inline unsigned DMA_MMR_SIZE_TYPE get_dma_config(unsigned int channel) { return dma_ch[channel].regs->cfg; } @@ -203,8 +300,8 @@ dma_ch[channel].regs->next_desc_ptr = sg; dma_ch[channel].regs->cfg = - (dma_ch[channel].regs->cfg & ~(0xf << 8)) | - ((ndsize & 0xf) << 8); + (dma_ch[channel].regs->cfg & ~NDSIZE) | + ((ndsize << NDSIZE_OFFSET) & NDSIZE); } static inline int dma_channel_active(unsigned int channel) @@ -239,7 +336,7 @@ } static inline void clear_dma_irqstat(unsigned int channel) { - dma_ch[channel].regs->irq_status = DMA_DONE | DMA_ERR; + dma_ch[channel].regs->irq_status = DMA_DONE | DMA_ERR | DMA_PIRQ; } void *dma_memcpy(void *dest, const void *src, size_t count);
diff --git a/arch/blackfin/include/asm/dpmc.h b/arch/blackfin/include/asm/dpmc.h index c4ec959..e91eae8 100644 --- a/arch/blackfin/include/asm/dpmc.h +++ b/arch/blackfin/include/asm/dpmc.h
@@ -9,6 +9,651 @@ #ifndef _BLACKFIN_DPMC_H_ #define _BLACKFIN_DPMC_H_ +#ifdef __ASSEMBLY__ +#define PM_REG0 R7 +#define PM_REG1 R6 +#define PM_REG2 R5 +#define PM_REG3 R4 +#define PM_REG4 R3 +#define PM_REG5 R2 +#define PM_REG6 R1 +#define PM_REG7 R0 +#define PM_REG8 P5 +#define PM_REG9 P4 +#define PM_REG10 P3 +#define PM_REG11 P2 +#define PM_REG12 P1 +#define PM_REG13 P0 + +#define PM_REGSET0 R7:7 +#define PM_REGSET1 R7:6 +#define PM_REGSET2 R7:5 +#define PM_REGSET3 R7:4 +#define PM_REGSET4 R7:3 +#define PM_REGSET5 R7:2 +#define PM_REGSET6 R7:1 +#define PM_REGSET7 R7:0 +#define PM_REGSET8 R7:0, P5:5 +#define PM_REGSET9 R7:0, P5:4 +#define PM_REGSET10 R7:0, P5:3 +#define PM_REGSET11 R7:0, P5:2 +#define PM_REGSET12 R7:0, P5:1 +#define PM_REGSET13 R7:0, P5:0 + +#define _PM_PUSH(n, x, w, base) PM_REG##n = w[FP + ((x) - (base))]; +#define _PM_POP(n, x, w, base) w[FP + ((x) - (base))] = PM_REG##n; +#define PM_PUSH_SYNC(n) [--sp] = (PM_REGSET##n); +#define PM_POP_SYNC(n) (PM_REGSET##n) = [sp++]; +#define PM_PUSH(n, x) PM_REG##n = [FP++]; +#define PM_POP(n, x) [FP--] = PM_REG##n; +#define PM_CORE_PUSH(n, x) _PM_PUSH(n, x, , COREMMR_BASE) +#define PM_CORE_POP(n, x) _PM_POP(n, x, , COREMMR_BASE) +#define PM_SYS_PUSH(n, x) _PM_PUSH(n, x, , SYSMMR_BASE) +#define PM_SYS_POP(n, x) _PM_POP(n, x, , SYSMMR_BASE) +#define PM_SYS_PUSH16(n, x) _PM_PUSH(n, x, w, SYSMMR_BASE) +#define PM_SYS_POP16(n, x) _PM_POP(n, x, w, SYSMMR_BASE) + + .macro bfin_init_pm_bench_cycles +#ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH + R4 = 0; + CYCLES = R4; + CYCLES2 = R4; + R4 = SYSCFG; + BITSET(R4, 1); + SYSCFG = R4; +#endif + .endm + + .macro bfin_cpu_reg_save + /* + * Save the core regs early so we can blow them away when + * saving/restoring MMR states + */ + [--sp] = (R7:0, P5:0); + [--sp] = fp; + [--sp] = usp; + + [--sp] = i0; + [--sp] = i1; + [--sp] = i2; + [--sp] = i3; + + [--sp] = m0; + [--sp] = m1; + [--sp] = m2; + [--sp] = m3; + + [--sp] = l0; + [--sp] = l1; + [--sp] = l2; + [--sp] = l3; + + [--sp] = b0; + [--sp] = b1; + [--sp] = b2; + [--sp] = b3; + [--sp] = a0.x; + [--sp] = a0.w; + [--sp] = a1.x; + [--sp] = a1.w; + + [--sp] = LC0; + [--sp] = LC1; + [--sp] = LT0; + [--sp] = LT1; + [--sp] = LB0; + [--sp] = LB1; + + /* We can't push RETI directly as that'll change IPEND[4] */ + r7 = RETI; + [--sp] = RETS; + [--sp] = ASTAT; +#ifndef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH + [--sp] = CYCLES; + [--sp] = CYCLES2; +#endif + [--sp] = SYSCFG; + [--sp] = RETX; + [--sp] = SEQSTAT; + [--sp] = r7; + + /* Save first func arg in M3 */ + M3 = R0; + .endm + + .macro bfin_cpu_reg_restore + /* Restore Core Registers */ + RETI = [sp++]; + SEQSTAT = [sp++]; + RETX = [sp++]; + SYSCFG = [sp++]; +#ifndef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH + CYCLES2 = [sp++]; + CYCLES = [sp++]; +#endif + ASTAT = [sp++]; + RETS = [sp++]; + + LB1 = [sp++]; + LB0 = [sp++]; + LT1 = [sp++]; + LT0 = [sp++]; + LC1 = [sp++]; + LC0 = [sp++]; + + a1.w = [sp++]; + a1.x = [sp++]; + a0.w = [sp++]; + a0.x = [sp++]; + b3 = [sp++]; + b2 = [sp++]; + b1 = [sp++]; + b0 = [sp++]; + + l3 = [sp++]; + l2 = [sp++]; + l1 = [sp++]; + l0 = [sp++]; + + m3 = [sp++]; + m2 = [sp++]; + m1 = [sp++]; + m0 = [sp++]; + + i3 = [sp++]; + i2 = [sp++]; + i1 = [sp++]; + i0 = [sp++]; + + usp = [sp++]; + fp = [sp++]; + (R7:0, P5:0) = [sp++]; + + .endm + + .macro bfin_sys_mmr_save + /* Save system MMRs */ + FP.H = hi(SYSMMR_BASE); + FP.L = lo(SYSMMR_BASE); +#ifdef SIC_IMASK0 + PM_SYS_PUSH(0, SIC_IMASK0) + PM_SYS_PUSH(1, SIC_IMASK1) +# ifdef SIC_IMASK2 + PM_SYS_PUSH(2, SIC_IMASK2) +# endif +#else +# ifdef SIC_IMASK + PM_SYS_PUSH(0, SIC_IMASK) +# endif +#endif + +#ifdef SIC_IAR0 + PM_SYS_PUSH(3, SIC_IAR0) + PM_SYS_PUSH(4, SIC_IAR1) + PM_SYS_PUSH(5, SIC_IAR2) +#endif +#ifdef SIC_IAR3 + PM_SYS_PUSH(6, SIC_IAR3) +#endif +#ifdef SIC_IAR4 + PM_SYS_PUSH(7, SIC_IAR4) + PM_SYS_PUSH(8, SIC_IAR5) + PM_SYS_PUSH(9, SIC_IAR6) +#endif +#ifdef SIC_IAR7 + PM_SYS_PUSH(10, SIC_IAR7) +#endif +#ifdef SIC_IAR8 + PM_SYS_PUSH(11, SIC_IAR8) + PM_SYS_PUSH(12, SIC_IAR9) + PM_SYS_PUSH(13, SIC_IAR10) +#endif + PM_PUSH_SYNC(13) +#ifdef SIC_IAR11 + PM_SYS_PUSH(0, SIC_IAR11) +#endif + +#ifdef SIC_IWR + PM_SYS_PUSH(1, SIC_IWR) +#endif +#ifdef SIC_IWR0 + PM_SYS_PUSH(1, SIC_IWR0) +#endif +#ifdef SIC_IWR1 + PM_SYS_PUSH(2, SIC_IWR1) +#endif +#ifdef SIC_IWR2 + PM_SYS_PUSH(3, SIC_IWR2) +#endif + +#ifdef PINT0_ASSIGN + PM_SYS_PUSH(4, PINT0_MASK_SET) + PM_SYS_PUSH(5, PINT1_MASK_SET) + PM_SYS_PUSH(6, PINT2_MASK_SET) + PM_SYS_PUSH(7, PINT3_MASK_SET) + PM_SYS_PUSH(8, PINT0_ASSIGN) + PM_SYS_PUSH(9, PINT1_ASSIGN) + PM_SYS_PUSH(10, PINT2_ASSIGN) + PM_SYS_PUSH(11, PINT3_ASSIGN) + PM_SYS_PUSH(12, PINT0_INVERT_SET) + PM_SYS_PUSH(13, PINT1_INVERT_SET) + PM_PUSH_SYNC(13) + PM_SYS_PUSH(0, PINT2_INVERT_SET) + PM_SYS_PUSH(1, PINT3_INVERT_SET) + PM_SYS_PUSH(2, PINT0_EDGE_SET) + PM_SYS_PUSH(3, PINT1_EDGE_SET) + PM_SYS_PUSH(4, PINT2_EDGE_SET) + PM_SYS_PUSH(5, PINT3_EDGE_SET) +#endif + +#ifdef SYSCR + PM_SYS_PUSH16(6, SYSCR) +#endif + +#ifdef EBIU_AMGCTL + PM_SYS_PUSH16(7, EBIU_AMGCTL) + PM_SYS_PUSH(8, EBIU_AMBCTL0) + PM_SYS_PUSH(9, EBIU_AMBCTL1) +#endif +#ifdef EBIU_FCTL + PM_SYS_PUSH(10, EBIU_MBSCTL) + PM_SYS_PUSH(11, EBIU_MODE) + PM_SYS_PUSH(12, EBIU_FCTL) + PM_PUSH_SYNC(12) +#else + PM_PUSH_SYNC(9) +#endif + .endm + + + .macro bfin_sys_mmr_restore +/* Restore System MMRs */ + FP.H = hi(SYSMMR_BASE); + FP.L = lo(SYSMMR_BASE); + +#ifdef EBIU_FCTL + PM_POP_SYNC(12) + PM_SYS_POP(12, EBIU_FCTL) + PM_SYS_POP(11, EBIU_MODE) + PM_SYS_POP(10, EBIU_MBSCTL) +#else + PM_POP_SYNC(9) +#endif + +#ifdef EBIU_AMBCTL + PM_SYS_POP(9, EBIU_AMBCTL1) + PM_SYS_POP(8, EBIU_AMBCTL0) + PM_SYS_POP16(7, EBIU_AMGCTL) +#endif + +#ifdef SYSCR + PM_SYS_POP16(6, SYSCR) +#endif + +#ifdef PINT0_ASSIGN + PM_SYS_POP(5, PINT3_EDGE_SET) + PM_SYS_POP(4, PINT2_EDGE_SET) + PM_SYS_POP(3, PINT1_EDGE_SET) + PM_SYS_POP(2, PINT0_EDGE_SET) + PM_SYS_POP(1, PINT3_INVERT_SET) + PM_SYS_POP(0, PINT2_INVERT_SET) + PM_POP_SYNC(13) + PM_SYS_POP(13, PINT1_INVERT_SET) + PM_SYS_POP(12, PINT0_INVERT_SET) + PM_SYS_POP(11, PINT3_ASSIGN) + PM_SYS_POP(10, PINT2_ASSIGN) + PM_SYS_POP(9, PINT1_ASSIGN) + PM_SYS_POP(8, PINT0_ASSIGN) + PM_SYS_POP(7, PINT3_MASK_SET) + PM_SYS_POP(6, PINT2_MASK_SET) + PM_SYS_POP(5, PINT1_MASK_SET) + PM_SYS_POP(4, PINT0_MASK_SET) +#endif + +#ifdef SIC_IWR2 + PM_SYS_POP(3, SIC_IWR2) +#endif +#ifdef SIC_IWR1 + PM_SYS_POP(2, SIC_IWR1) +#endif +#ifdef SIC_IWR0 + PM_SYS_POP(1, SIC_IWR0) +#endif +#ifdef SIC_IWR + PM_SYS_POP(1, SIC_IWR) +#endif + +#ifdef SIC_IAR11 + PM_SYS_POP(0, SIC_IAR11) +#endif + PM_POP_SYNC(13) +#ifdef SIC_IAR8 + PM_SYS_POP(13, SIC_IAR10) + PM_SYS_POP(12, SIC_IAR9) + PM_SYS_POP(11, SIC_IAR8) +#endif +#ifdef SIC_IAR7 + PM_SYS_POP(10, SIC_IAR7) +#endif +#ifdef SIC_IAR6 + PM_SYS_POP(9, SIC_IAR6) + PM_SYS_POP(8, SIC_IAR5) + PM_SYS_POP(7, SIC_IAR4) +#endif +#ifdef SIC_IAR3 + PM_SYS_POP(6, SIC_IAR3) +#endif +#ifdef SIC_IAR0 + PM_SYS_POP(5, SIC_IAR2) + PM_SYS_POP(4, SIC_IAR1) + PM_SYS_POP(3, SIC_IAR0) +#endif +#ifdef SIC_IMASK0 +# ifdef SIC_IMASK2 + PM_SYS_POP(2, SIC_IMASK2) +# endif + PM_SYS_POP(1, SIC_IMASK1) + PM_SYS_POP(0, SIC_IMASK0) +#else +# ifdef SIC_IMASK + PM_SYS_POP(0, SIC_IMASK) +# endif +#endif + .endm + + .macro bfin_core_mmr_save + /* Save Core MMRs */ + I0.H = hi(COREMMR_BASE); + I0.L = lo(COREMMR_BASE); + I1 = I0; + I2 = I0; + I3 = I0; + B0 = I0; + B1 = I0; + B2 = I0; + B3 = I0; + I1.L = lo(DCPLB_ADDR0); + I2.L = lo(DCPLB_DATA0); + I3.L = lo(ICPLB_ADDR0); + B0.L = lo(ICPLB_DATA0); + B1.L = lo(EVT2); + B2.L = lo(IMASK); + B3.L = lo(TCNTL); + + /* Event Vectors */ + FP = B1; + PM_PUSH(0, EVT2) + PM_PUSH(1, EVT3) + FP += 4; /* EVT4 */ + PM_PUSH(2, EVT5) + PM_PUSH(3, EVT6) + PM_PUSH(4, EVT7) + PM_PUSH(5, EVT8) + PM_PUSH_SYNC(5) + + PM_PUSH(0, EVT9) + PM_PUSH(1, EVT10) + PM_PUSH(2, EVT11) + PM_PUSH(3, EVT12) + PM_PUSH(4, EVT13) + PM_PUSH(5, EVT14) + PM_PUSH(6, EVT15) + + /* CEC */ + FP = B2; + PM_PUSH(7, IMASK) + FP += 4; /* IPEND */ + PM_PUSH(8, ILAT) + PM_PUSH(9, IPRIO) + + /* Core Timer */ + FP = B3; + PM_PUSH(10, TCNTL) + PM_PUSH(11, TPERIOD) + PM_PUSH(12, TSCALE) + PM_PUSH(13, TCOUNT) + PM_PUSH_SYNC(13) + + /* Misc non-contiguous registers */ + FP = I0; + PM_CORE_PUSH(0, DMEM_CONTROL); + PM_CORE_PUSH(1, IMEM_CONTROL); + PM_CORE_PUSH(2, TBUFCTL); + PM_PUSH_SYNC(2) + + /* DCPLB Addr */ + FP = I1; + PM_PUSH(0, DCPLB_ADDR0) + PM_PUSH(1, DCPLB_ADDR1) + PM_PUSH(2, DCPLB_ADDR2) + PM_PUSH(3, DCPLB_ADDR3) + PM_PUSH(4, DCPLB_ADDR4) + PM_PUSH(5, DCPLB_ADDR5) + PM_PUSH(6, DCPLB_ADDR6) + PM_PUSH(7, DCPLB_ADDR7) + PM_PUSH(8, DCPLB_ADDR8) + PM_PUSH(9, DCPLB_ADDR9) + PM_PUSH(10, DCPLB_ADDR10) + PM_PUSH(11, DCPLB_ADDR11) + PM_PUSH(12, DCPLB_ADDR12) + PM_PUSH(13, DCPLB_ADDR13) + PM_PUSH_SYNC(13) + PM_PUSH(0, DCPLB_ADDR14) + PM_PUSH(1, DCPLB_ADDR15) + + /* DCPLB Data */ + FP = I2; + PM_PUSH(2, DCPLB_DATA0) + PM_PUSH(3, DCPLB_DATA1) + PM_PUSH(4, DCPLB_DATA2) + PM_PUSH(5, DCPLB_DATA3) + PM_PUSH(6, DCPLB_DATA4) + PM_PUSH(7, DCPLB_DATA5) + PM_PUSH(8, DCPLB_DATA6) + PM_PUSH(9, DCPLB_DATA7) + PM_PUSH(10, DCPLB_DATA8) + PM_PUSH(11, DCPLB_DATA9) + PM_PUSH(12, DCPLB_DATA10) + PM_PUSH(13, DCPLB_DATA11) + PM_PUSH_SYNC(13) + PM_PUSH(0, DCPLB_DATA12) + PM_PUSH(1, DCPLB_DATA13) + PM_PUSH(2, DCPLB_DATA14) + PM_PUSH(3, DCPLB_DATA15) + + /* ICPLB Addr */ + FP = I3; + PM_PUSH(4, ICPLB_ADDR0) + PM_PUSH(5, ICPLB_ADDR1) + PM_PUSH(6, ICPLB_ADDR2) + PM_PUSH(7, ICPLB_ADDR3) + PM_PUSH(8, ICPLB_ADDR4) + PM_PUSH(9, ICPLB_ADDR5) + PM_PUSH(10, ICPLB_ADDR6) + PM_PUSH(11, ICPLB_ADDR7) + PM_PUSH(12, ICPLB_ADDR8) + PM_PUSH(13, ICPLB_ADDR9) + PM_PUSH_SYNC(13) + PM_PUSH(0, ICPLB_ADDR10) + PM_PUSH(1, ICPLB_ADDR11) + PM_PUSH(2, ICPLB_ADDR12) + PM_PUSH(3, ICPLB_ADDR13) + PM_PUSH(4, ICPLB_ADDR14) + PM_PUSH(5, ICPLB_ADDR15) + + /* ICPLB Data */ + FP = B0; + PM_PUSH(6, ICPLB_DATA0) + PM_PUSH(7, ICPLB_DATA1) + PM_PUSH(8, ICPLB_DATA2) + PM_PUSH(9, ICPLB_DATA3) + PM_PUSH(10, ICPLB_DATA4) + PM_PUSH(11, ICPLB_DATA5) + PM_PUSH(12, ICPLB_DATA6) + PM_PUSH(13, ICPLB_DATA7) + PM_PUSH_SYNC(13) + PM_PUSH(0, ICPLB_DATA8) + PM_PUSH(1, ICPLB_DATA9) + PM_PUSH(2, ICPLB_DATA10) + PM_PUSH(3, ICPLB_DATA11) + PM_PUSH(4, ICPLB_DATA12) + PM_PUSH(5, ICPLB_DATA13) + PM_PUSH(6, ICPLB_DATA14) + PM_PUSH(7, ICPLB_DATA15) + PM_PUSH_SYNC(7) + .endm + + .macro bfin_core_mmr_restore + /* Restore Core MMRs */ + I0.H = hi(COREMMR_BASE); + I0.L = lo(COREMMR_BASE); + I1 = I0; + I2 = I0; + I3 = I0; + B0 = I0; + B1 = I0; + B2 = I0; + B3 = I0; + I1.L = lo(DCPLB_ADDR15); + I2.L = lo(DCPLB_DATA15); + I3.L = lo(ICPLB_ADDR15); + B0.L = lo(ICPLB_DATA15); + B1.L = lo(EVT15); + B2.L = lo(IPRIO); + B3.L = lo(TCOUNT); + + /* ICPLB Data */ + FP = B0; + PM_POP_SYNC(7) + PM_POP(7, ICPLB_DATA15) + PM_POP(6, ICPLB_DATA14) + PM_POP(5, ICPLB_DATA13) + PM_POP(4, ICPLB_DATA12) + PM_POP(3, ICPLB_DATA11) + PM_POP(2, ICPLB_DATA10) + PM_POP(1, ICPLB_DATA9) + PM_POP(0, ICPLB_DATA8) + PM_POP_SYNC(13) + PM_POP(13, ICPLB_DATA7) + PM_POP(12, ICPLB_DATA6) + PM_POP(11, ICPLB_DATA5) + PM_POP(10, ICPLB_DATA4) + PM_POP(9, ICPLB_DATA3) + PM_POP(8, ICPLB_DATA2) + PM_POP(7, ICPLB_DATA1) + PM_POP(6, ICPLB_DATA0) + + /* ICPLB Addr */ + FP = I3; + PM_POP(5, ICPLB_ADDR15) + PM_POP(4, ICPLB_ADDR14) + PM_POP(3, ICPLB_ADDR13) + PM_POP(2, ICPLB_ADDR12) + PM_POP(1, ICPLB_ADDR11) + PM_POP(0, ICPLB_ADDR10) + PM_POP_SYNC(13) + PM_POP(13, ICPLB_ADDR9) + PM_POP(12, ICPLB_ADDR8) + PM_POP(11, ICPLB_ADDR7) + PM_POP(10, ICPLB_ADDR6) + PM_POP(9, ICPLB_ADDR5) + PM_POP(8, ICPLB_ADDR4) + PM_POP(7, ICPLB_ADDR3) + PM_POP(6, ICPLB_ADDR2) + PM_POP(5, ICPLB_ADDR1) + PM_POP(4, ICPLB_ADDR0) + + /* DCPLB Data */ + FP = I2; + PM_POP(3, DCPLB_DATA15) + PM_POP(2, DCPLB_DATA14) + PM_POP(1, DCPLB_DATA13) + PM_POP(0, DCPLB_DATA12) + PM_POP_SYNC(13) + PM_POP(13, DCPLB_DATA11) + PM_POP(12, DCPLB_DATA10) + PM_POP(11, DCPLB_DATA9) + PM_POP(10, DCPLB_DATA8) + PM_POP(9, DCPLB_DATA7) + PM_POP(8, DCPLB_DATA6) + PM_POP(7, DCPLB_DATA5) + PM_POP(6, DCPLB_DATA4) + PM_POP(5, DCPLB_DATA3) + PM_POP(4, DCPLB_DATA2) + PM_POP(3, DCPLB_DATA1) + PM_POP(2, DCPLB_DATA0) + + /* DCPLB Addr */ + FP = I1; + PM_POP(1, DCPLB_ADDR15) + PM_POP(0, DCPLB_ADDR14) + PM_POP_SYNC(13) + PM_POP(13, DCPLB_ADDR13) + PM_POP(12, DCPLB_ADDR12) + PM_POP(11, DCPLB_ADDR11) + PM_POP(10, DCPLB_ADDR10) + PM_POP(9, DCPLB_ADDR9) + PM_POP(8, DCPLB_ADDR8) + PM_POP(7, DCPLB_ADDR7) + PM_POP(6, DCPLB_ADDR6) + PM_POP(5, DCPLB_ADDR5) + PM_POP(4, DCPLB_ADDR4) + PM_POP(3, DCPLB_ADDR3) + PM_POP(2, DCPLB_ADDR2) + PM_POP(1, DCPLB_ADDR1) + PM_POP(0, DCPLB_ADDR0) + + + /* Misc non-contiguous registers */ + + /* icache & dcache will enable later + drop IMEM_CONTROL, DMEM_CONTROL pop + */ + FP = I0; + PM_POP_SYNC(2) + PM_CORE_POP(2, TBUFCTL) + PM_CORE_POP(1, IMEM_CONTROL) + PM_CORE_POP(0, DMEM_CONTROL) + + /* Core Timer */ + FP = B3; + R0 = 0x1; + [FP - 0xC] = R0; + + PM_POP_SYNC(13) + FP = B3; + PM_POP(13, TCOUNT) + PM_POP(12, TSCALE) + PM_POP(11, TPERIOD) + PM_POP(10, TCNTL) + + /* CEC */ + FP = B2; + PM_POP(9, IPRIO) + PM_POP(8, ILAT) + FP += -4; /* IPEND */ + PM_POP(7, IMASK) + + /* Event Vectors */ + FP = B1; + PM_POP(6, EVT15) + PM_POP(5, EVT14) + PM_POP(4, EVT13) + PM_POP(3, EVT12) + PM_POP(2, EVT11) + PM_POP(1, EVT10) + PM_POP(0, EVT9) + PM_POP_SYNC(5) + PM_POP(5, EVT8) + PM_POP(4, EVT7) + PM_POP(3, EVT6) + PM_POP(2, EVT5) + FP += -4; /* EVT4 */ + PM_POP(1, EVT3) + PM_POP(0, EVT2) + .endm +#endif + #include <mach/pll.h> /* PLL_CTL Masks */ @@ -98,6 +743,16 @@ #define VLEV_130 0x00F0 /* VLEV = 1.30 V (-5% - +10% Accuracy) */ #endif +#ifdef CONFIG_BF60x +#define PA15WE 0x00000001 /* Allow Wake-Up from PA15 */ +#define PB15WE 0x00000002 /* Allow Wake-Up from PB15 */ +#define PC15WE 0x00000004 /* Allow Wake-Up from PC15 */ +#define PD06WE 0x00000008 /* Allow Wake-Up from PD06(ETH0_PHYINT) */ +#define PE12WE 0x00000010 /* Allow Wake-Up from PE12(ETH1_PHYINT, PUSH BUTTON) */ +#define PG04WE 0x00000020 /* Allow Wake-Up from PG04(CAN0_RX) */ +#define PG13WE 0x00000040 /* Allow Wake-Up from PG13 */ +#define USBWE 0x00000080 /* Allow Wake-Up from (USB) */ +#else #define WAKE 0x0100 /* Enable RTC/Reset Wakeup From Hibernate */ #define CANWE 0x0200 /* Enable CAN Wakeup From Hibernate */ #define PHYWE 0x0400 /* Enable PHY Wakeup From Hibernate */ @@ -113,6 +768,7 @@ #else #define USBWE 0x0800 /* Enable USB Wakeup From Hibernate */ #endif +#endif #ifndef __ASSEMBLY__
diff --git a/arch/blackfin/include/asm/fixed_code.h b/arch/blackfin/include/asm/fixed_code.h index 73fe53e..5395088 100644 --- a/arch/blackfin/include/asm/fixed_code.h +++ b/arch/blackfin/include/asm/fixed_code.h
@@ -29,24 +29,28 @@ #endif #endif -#define FIXED_CODE_START 0x400 +#ifndef CONFIG_PHY_RAM_BASE_ADDRESS +#define CONFIG_PHY_RAM_BASE_ADDRESS 0x0 +#endif -#define SIGRETURN_STUB 0x400 +#define FIXED_CODE_START (CONFIG_PHY_RAM_BASE_ADDRESS + 0x400) -#define ATOMIC_SEQS_START 0x410 +#define SIGRETURN_STUB (CONFIG_PHY_RAM_BASE_ADDRESS + 0x400) -#define ATOMIC_XCHG32 0x410 -#define ATOMIC_CAS32 0x420 -#define ATOMIC_ADD32 0x430 -#define ATOMIC_SUB32 0x440 -#define ATOMIC_IOR32 0x450 -#define ATOMIC_AND32 0x460 -#define ATOMIC_XOR32 0x470 +#define ATOMIC_SEQS_START (CONFIG_PHY_RAM_BASE_ADDRESS + 0x410) -#define ATOMIC_SEQS_END 0x480 +#define ATOMIC_XCHG32 (CONFIG_PHY_RAM_BASE_ADDRESS + 0x410) +#define ATOMIC_CAS32 (CONFIG_PHY_RAM_BASE_ADDRESS + 0x420) +#define ATOMIC_ADD32 (CONFIG_PHY_RAM_BASE_ADDRESS + 0x430) +#define ATOMIC_SUB32 (CONFIG_PHY_RAM_BASE_ADDRESS + 0x440) +#define ATOMIC_IOR32 (CONFIG_PHY_RAM_BASE_ADDRESS + 0x450) +#define ATOMIC_AND32 (CONFIG_PHY_RAM_BASE_ADDRESS + 0x460) +#define ATOMIC_XOR32 (CONFIG_PHY_RAM_BASE_ADDRESS + 0x470) -#define SAFE_USER_INSTRUCTION 0x480 +#define ATOMIC_SEQS_END (CONFIG_PHY_RAM_BASE_ADDRESS + 0x480) -#define FIXED_CODE_END 0x490 +#define SAFE_USER_INSTRUCTION (CONFIG_PHY_RAM_BASE_ADDRESS + 0x480) + +#define FIXED_CODE_END (CONFIG_PHY_RAM_BASE_ADDRESS + 0x490) #endif
diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h index 12d3571..3d84d96 100644 --- a/arch/blackfin/include/asm/gpio.h +++ b/arch/blackfin/include/asm/gpio.h
@@ -26,6 +26,7 @@ #ifndef __ASSEMBLY__ #include <linux/compiler.h> +#include <linux/gpio.h> /*********************************************************** * @@ -244,6 +245,49 @@ return -EINVAL; } +static inline int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) +{ + int err; + + err = bfin_gpio_request(gpio, label); + if (err) + return err; + + if (flags & GPIOF_DIR_IN) + err = bfin_gpio_direction_input(gpio); + else + err = bfin_gpio_direction_output(gpio, + (flags & GPIOF_INIT_HIGH) ? 1 : 0); + + if (err) + bfin_gpio_free(gpio); + + return err; +} + +static inline int gpio_request_array(const struct gpio *array, size_t num) +{ + int i, err; + + for (i = 0; i < num; i++, array++) { + err = gpio_request_one(array->gpio, array->flags, array->label); + if (err) + goto err_free; + } + return 0; + +err_free: + while (i--) + bfin_gpio_free((--array)->gpio); + return err; +} + +static inline void gpio_free_array(const struct gpio *array, size_t num) +{ + while (num--) + bfin_gpio_free((array++)->gpio); +} + static inline int __gpio_get_value(unsigned gpio) { return bfin_gpio_get_value(gpio);
diff --git a/arch/blackfin/include/asm/gptimers.h b/arch/blackfin/include/asm/gptimers.h index 38bddcb..381e3d6 100644 --- a/arch/blackfin/include/asm/gptimers.h +++ b/arch/blackfin/include/asm/gptimers.h
@@ -44,6 +44,13 @@ # define TIMER_GROUP2 1 #endif /* + * BF609: 8 timers: + */ +#if defined(CONFIG_BF60x) +# define MAX_BLACKFIN_GPTIMERS 8 +# define TIMER0_GROUP_REG TIMER_RUN +#endif +/* * All others: 3 timers: */ #define TIMER_GROUP1 0 @@ -104,6 +111,72 @@ # define FS2_TIMER_BIT TIMER1bit #endif +#ifdef CONFIG_BF60x +/* + * Timer Configuration Register Bits + */ +#define TIMER_EMU_RUN 0x8000 +#define TIMER_BPER_EN 0x4000 +#define TIMER_BWID_EN 0x2000 +#define TIMER_BDLY_EN 0x1000 +#define TIMER_OUT_DIS 0x0800 +#define TIMER_TIN_SEL 0x0400 +#define TIMER_CLK_SEL 0x0300 +#define TIMER_CLK_SCLK 0x0000 +#define TIMER_CLK_ALT_CLK0 0x0100 +#define TIMER_CLK_ALT_CLK1 0x0300 +#define TIMER_PULSE_HI 0x0080 +#define TIMER_SLAVE_TRIG 0x0040 +#define TIMER_IRQ_MODE 0x0030 +#define TIMER_IRQ_ACT_EDGE 0x0000 +#define TIMER_IRQ_DLY 0x0010 +#define TIMER_IRQ_WID_DLY 0x0020 +#define TIMER_IRQ_PER 0x0030 +#define TIMER_MODE 0x000f +#define TIMER_MODE_WDOG_P 0x0008 +#define TIMER_MODE_WDOG_W 0x0009 +#define TIMER_MODE_PWM_CONT 0x000c +#define TIMER_MODE_PWM 0x000d +#define TIMER_MODE_WDTH 0x000a +#define TIMER_MODE_WDTH_D 0x000b +#define TIMER_MODE_EXT_CLK 0x000e +#define TIMER_MODE_PININT 0x000f + +/* + * Timer Status Register Bits + */ +#define TIMER_STATUS_TIMIL0 0x0001 +#define TIMER_STATUS_TIMIL1 0x0002 +#define TIMER_STATUS_TIMIL2 0x0004 +#define TIMER_STATUS_TIMIL3 0x0008 +#define TIMER_STATUS_TIMIL4 0x0010 +#define TIMER_STATUS_TIMIL5 0x0020 +#define TIMER_STATUS_TIMIL6 0x0040 +#define TIMER_STATUS_TIMIL7 0x0080 + +#define TIMER_STATUS_TOVF0 0x0001 /* timer 0 overflow error */ +#define TIMER_STATUS_TOVF1 0x0002 +#define TIMER_STATUS_TOVF2 0x0004 +#define TIMER_STATUS_TOVF3 0x0008 +#define TIMER_STATUS_TOVF4 0x0010 +#define TIMER_STATUS_TOVF5 0x0020 +#define TIMER_STATUS_TOVF6 0x0040 +#define TIMER_STATUS_TOVF7 0x0080 + +/* + * Timer Slave Enable Status : write 1 to clear + */ +#define TIMER_STATUS_TRUN0 0x0001 +#define TIMER_STATUS_TRUN1 0x0002 +#define TIMER_STATUS_TRUN2 0x0004 +#define TIMER_STATUS_TRUN3 0x0008 +#define TIMER_STATUS_TRUN4 0x0010 +#define TIMER_STATUS_TRUN5 0x0020 +#define TIMER_STATUS_TRUN6 0x0040 +#define TIMER_STATUS_TRUN7 0x0080 + +#else + /* * Timer Configuration Register Bits */ @@ -170,12 +243,18 @@ #define TIMER_STATUS_TRUN10 0x4000 #define TIMER_STATUS_TRUN11 0x8000 +#endif + /* The actual gptimer API */ void set_gptimer_pwidth(unsigned int timer_id, uint32_t width); uint32_t get_gptimer_pwidth(unsigned int timer_id); void set_gptimer_period(unsigned int timer_id, uint32_t period); uint32_t get_gptimer_period(unsigned int timer_id); +#ifdef CONFIG_BF60x +void set_gptimer_delay(unsigned int timer_id, uint32_t delay); +uint32_t get_gptimer_delay(unsigned int timer_id); +#endif uint32_t get_gptimer_count(unsigned int timer_id); int get_gptimer_intr(unsigned int timer_id); void clear_gptimer_intr(unsigned int timer_id); @@ -217,16 +296,41 @@ u32 counter; u32 period; u32 width; +#ifdef CONFIG_BF60x + u32 delay; +#endif }; /* * bfin group timer registers layout */ +#ifndef CONFIG_BF60x struct bfin_gptimer_group_regs { __BFP(enable); __BFP(disable); u32 status; }; +#else +struct bfin_gptimer_group_regs { + __BFP(run); + __BFP(enable); + __BFP(disable); + __BFP(stop_cfg); + __BFP(stop_cfg_set); + __BFP(stop_cfg_clr); + __BFP(data_imsk); + __BFP(stat_imsk); + __BFP(tr_msk); + __BFP(tr_ie); + __BFP(data_ilat); + __BFP(stat_ilat); + __BFP(err_status); + __BFP(bcast_per); + __BFP(bcast_wid); + __BFP(bcast_dly); + +}; +#endif #undef __BFP
diff --git a/arch/blackfin/include/asm/irqflags.h b/arch/blackfin/include/asm/irqflags.h index 43eb474..07aff23 100644 --- a/arch/blackfin/include/asm/irqflags.h +++ b/arch/blackfin/include/asm/irqflags.h
@@ -67,7 +67,11 @@ static inline notrace int hard_irqs_disabled_flags(unsigned long flags) { +#ifdef CONFIG_BF60x + return (flags & IMASK_IVG11) == 0; +#else return (flags & ~0x3f) == 0; +#endif } static inline notrace int hard_irqs_disabled(void) @@ -224,7 +228,7 @@ * Direct interface to linux/irqflags.h. */ #define arch_local_save_flags() hard_local_save_flags() -#define arch_local_irq_save(flags) __hard_local_irq_save() +#define arch_local_irq_save() __hard_local_irq_save() #define arch_local_irq_restore(flags) __hard_local_irq_restore(flags) #define arch_local_irq_enable() __hard_local_irq_enable() #define arch_local_irq_disable() __hard_local_irq_disable()
diff --git a/arch/blackfin/include/asm/page.h b/arch/blackfin/include/asm/page.h index 7202404..b93474d 100644 --- a/arch/blackfin/include/asm/page.h +++ b/arch/blackfin/include/asm/page.h
@@ -7,14 +7,15 @@ #ifndef _BLACKFIN_PAGE_H #define _BLACKFIN_PAGE_H -#include <asm-generic/page.h> -#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT) +#define ARCH_PFN_OFFSET (CONFIG_PHY_RAM_BASE_ADDRESS >> PAGE_SHIFT) +#define MAP_NR(addr) ((unsigned long)(addr) >> PAGE_SHIFT) #define VM_DATA_DEFAULT_FLAGS \ (VM_READ | VM_WRITE | \ ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#include <asm-generic/page.h> #include <asm-generic/memory_model.h> #include <asm-generic/getorder.h>
diff --git a/arch/blackfin/include/asm/pda.h b/arch/blackfin/include/asm/pda.h index 28c2498..68d6f66 100644 --- a/arch/blackfin/include/asm/pda.h +++ b/arch/blackfin/include/asm/pda.h
@@ -13,7 +13,9 @@ #ifndef __ASSEMBLY__ struct blackfin_pda { /* Per-processor Data Area */ +#ifdef CONFIG_SMP struct blackfin_pda *next; +#endif unsigned long syscfg; #ifdef CONFIG_SMP
diff --git a/arch/blackfin/include/asm/pm.h b/arch/blackfin/include/asm/pm.h new file mode 100644 index 0000000..f72239b --- /dev/null +++ b/arch/blackfin/include/asm/pm.h
@@ -0,0 +1,31 @@ +/* + * Blackfin bf609 power management + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 + */ + +#ifndef __PM_H__ +#define __PM_H__ + +#include <linux/suspend.h> + +struct bfin_cpu_pm_fns { + void (*save)(unsigned long *); + void (*restore)(unsigned long *); + int (*valid)(suspend_state_t state); + void (*enter)(suspend_state_t state); + int (*prepare)(void); + void (*finish)(void); +}; + +extern struct bfin_cpu_pm_fns *bfin_cpu_pm; + +# ifdef CONFIG_BFIN_COREB +void bfin_coreb_start(void); +void bfin_coreb_stop(void); +void bfin_coreb_reset(void); +# endif + +#endif
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h index 75ec9df..3287222 100644 --- a/arch/blackfin/include/asm/unistd.h +++ b/arch/blackfin/include/asm/unistd.h
@@ -11,7 +11,7 @@ */ #define __NR_restart_syscall 0 #define __NR_exit 1 -#define __NR_fork 2 + /* 2 __NR_fork not supported on nommu */ #define __NR_read 3 #define __NR_write 4 #define __NR_open 5
diff --git a/arch/blackfin/kernel/bfin_dma.c b/arch/blackfin/kernel/bfin_dma.c index 40c2ed6..c166939 100644 --- a/arch/blackfin/kernel/bfin_dma.c +++ b/arch/blackfin/kernel/bfin_dma.c
@@ -45,9 +45,15 @@ atomic_set(&dma_ch[i].chan_status, 0); dma_ch[i].regs = dma_io_base_addr[i]; } +#ifdef CH_MEM_STREAM3_SRC + /* Mark MEMDMA Channel 3 as requested since we're using it internally */ + request_dma(CH_MEM_STREAM3_DEST, "Blackfin dma_memcpy"); + request_dma(CH_MEM_STREAM3_SRC, "Blackfin dma_memcpy"); +#else /* Mark MEMDMA Channel 0 as requested since we're using it internally */ request_dma(CH_MEM_STREAM0_DEST, "Blackfin dma_memcpy"); request_dma(CH_MEM_STREAM0_SRC, "Blackfin dma_memcpy"); +#endif #if defined(CONFIG_DEB_DMA_URGENT) bfin_write_EBIU_DDRQUE(bfin_read_EBIU_DDRQUE() @@ -84,7 +90,8 @@ static int __init proc_dma_init(void) { - return proc_create("dma", 0, NULL, &proc_dma_operations) != NULL; + proc_create("dma", 0, NULL, &proc_dma_operations); + return 0; } late_initcall(proc_dma_init); #endif @@ -204,6 +211,7 @@ # ifndef MAX_DMA_SUSPEND_CHANNELS # define MAX_DMA_SUSPEND_CHANNELS MAX_DMA_CHANNELS # endif +# ifndef CONFIG_BF60x int blackfin_dma_suspend(void) { int i; @@ -213,7 +221,6 @@ printk(KERN_ERR "DMA Channel %d failed to suspend\n", i); return -EBUSY; } - if (i < MAX_DMA_SUSPEND_CHANNELS) dma_ch[i].saved_peripheral_map = dma_ch[i].regs->peripheral_map; } @@ -230,7 +237,6 @@ for (i = 0; i < MAX_DMA_CHANNELS; ++i) { dma_ch[i].regs->cfg = 0; - if (i < MAX_DMA_SUSPEND_CHANNELS) dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map; } @@ -238,6 +244,16 @@ bfin_write_DMAC_TC_PER(0x0111); #endif } +# else +int blackfin_dma_suspend(void) +{ + return 0; +} + +void blackfin_dma_resume(void) +{ +} +#endif #endif /** @@ -279,10 +295,10 @@ src_ch = (struct dma_register *)MDMA_S0_NEXT_DESC_PTR; } - if (!bfin_read16(&src_ch->cfg)) + if (!DMA_MMR_READ(&src_ch->cfg)) break; - else if (bfin_read16(&dst_ch->irq_status) & DMA_DONE) { - bfin_write16(&src_ch->cfg, 0); + else if (DMA_MMR_READ(&dst_ch->irq_status) & DMA_DONE) { + DMA_MMR_WRITE(&src_ch->cfg, 0); break; } } @@ -295,22 +311,31 @@ /* Destination */ bfin_write32(&dst_ch->start_addr, dst); - bfin_write16(&dst_ch->x_count, size >> 2); - bfin_write16(&dst_ch->x_modify, 1 << 2); - bfin_write16(&dst_ch->irq_status, DMA_DONE | DMA_ERR); + DMA_MMR_WRITE(&dst_ch->x_count, size >> 2); + DMA_MMR_WRITE(&dst_ch->x_modify, 1 << 2); + DMA_MMR_WRITE(&dst_ch->irq_status, DMA_DONE | DMA_ERR); /* Source */ bfin_write32(&src_ch->start_addr, src); - bfin_write16(&src_ch->x_count, size >> 2); - bfin_write16(&src_ch->x_modify, 1 << 2); - bfin_write16(&src_ch->irq_status, DMA_DONE | DMA_ERR); + DMA_MMR_WRITE(&src_ch->x_count, size >> 2); + DMA_MMR_WRITE(&src_ch->x_modify, 1 << 2); + DMA_MMR_WRITE(&src_ch->irq_status, DMA_DONE | DMA_ERR); /* Enable */ - bfin_write16(&src_ch->cfg, DMAEN | WDSIZE_32); - bfin_write16(&dst_ch->cfg, WNR | DI_EN | DMAEN | WDSIZE_32); + DMA_MMR_WRITE(&src_ch->cfg, DMAEN | WDSIZE_32); + DMA_MMR_WRITE(&dst_ch->cfg, WNR | DI_EN_X | DMAEN | WDSIZE_32); /* Since we are atomic now, don't use the workaround ssync */ __builtin_bfin_ssync(); + +#ifdef CONFIG_BF60x + /* Work around a possible MDMA anomaly. Running 2 MDMA channels to + * transfer DDR data to L1 SRAM may corrupt data. + * Should be reverted after this issue is root caused. + */ + while (!(DMA_MMR_READ(&dst_ch->irq_status) & DMA_DONE)) + continue; +#endif } void __init early_dma_memcpy_done(void) @@ -336,6 +361,42 @@ __builtin_bfin_ssync(); } +#ifdef CH_MEM_STREAM3_SRC +#define bfin_read_MDMA_S_CONFIG bfin_read_MDMA_S3_CONFIG +#define bfin_write_MDMA_S_CONFIG bfin_write_MDMA_S3_CONFIG +#define bfin_write_MDMA_S_START_ADDR bfin_write_MDMA_S3_START_ADDR +#define bfin_write_MDMA_S_IRQ_STATUS bfin_write_MDMA_S3_IRQ_STATUS +#define bfin_write_MDMA_S_X_COUNT bfin_write_MDMA_S3_X_COUNT +#define bfin_write_MDMA_S_X_MODIFY bfin_write_MDMA_S3_X_MODIFY +#define bfin_write_MDMA_S_Y_COUNT bfin_write_MDMA_S3_Y_COUNT +#define bfin_write_MDMA_S_Y_MODIFY bfin_write_MDMA_S3_Y_MODIFY +#define bfin_write_MDMA_D_CONFIG bfin_write_MDMA_D3_CONFIG +#define bfin_write_MDMA_D_START_ADDR bfin_write_MDMA_D3_START_ADDR +#define bfin_read_MDMA_D_IRQ_STATUS bfin_read_MDMA_D3_IRQ_STATUS +#define bfin_write_MDMA_D_IRQ_STATUS bfin_write_MDMA_D3_IRQ_STATUS +#define bfin_write_MDMA_D_X_COUNT bfin_write_MDMA_D3_X_COUNT +#define bfin_write_MDMA_D_X_MODIFY bfin_write_MDMA_D3_X_MODIFY +#define bfin_write_MDMA_D_Y_COUNT bfin_write_MDMA_D3_Y_COUNT +#define bfin_write_MDMA_D_Y_MODIFY bfin_write_MDMA_D3_Y_MODIFY +#else +#define bfin_read_MDMA_S_CONFIG bfin_read_MDMA_S0_CONFIG +#define bfin_write_MDMA_S_CONFIG bfin_write_MDMA_S0_CONFIG +#define bfin_write_MDMA_S_START_ADDR bfin_write_MDMA_S0_START_ADDR +#define bfin_write_MDMA_S_IRQ_STATUS bfin_write_MDMA_S0_IRQ_STATUS +#define bfin_write_MDMA_S_X_COUNT bfin_write_MDMA_S0_X_COUNT +#define bfin_write_MDMA_S_X_MODIFY bfin_write_MDMA_S0_X_MODIFY +#define bfin_write_MDMA_S_Y_COUNT bfin_write_MDMA_S0_Y_COUNT +#define bfin_write_MDMA_S_Y_MODIFY bfin_write_MDMA_S0_Y_MODIFY +#define bfin_write_MDMA_D_CONFIG bfin_write_MDMA_D0_CONFIG +#define bfin_write_MDMA_D_START_ADDR bfin_write_MDMA_D0_START_ADDR +#define bfin_read_MDMA_D_IRQ_STATUS bfin_read_MDMA_D0_IRQ_STATUS +#define bfin_write_MDMA_D_IRQ_STATUS bfin_write_MDMA_D0_IRQ_STATUS +#define bfin_write_MDMA_D_X_COUNT bfin_write_MDMA_D0_X_COUNT +#define bfin_write_MDMA_D_X_MODIFY bfin_write_MDMA_D0_X_MODIFY +#define bfin_write_MDMA_D_Y_COUNT bfin_write_MDMA_D0_Y_COUNT +#define bfin_write_MDMA_D_Y_MODIFY bfin_write_MDMA_D0_Y_MODIFY +#endif + /** * __dma_memcpy - program the MDMA registers * @@ -358,8 +419,8 @@ */ __builtin_bfin_ssync(); - if (bfin_read_MDMA_S0_CONFIG()) - while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) + if (bfin_read_MDMA_S_CONFIG()) + while (!(bfin_read_MDMA_D_IRQ_STATUS() & DMA_DONE)) continue; if (conf & DMA2D) { @@ -374,39 +435,42 @@ u32 shift = abs(dmod) >> 1; size_t ycnt = cnt >> (16 - shift); cnt = 1 << (16 - shift); - bfin_write_MDMA_D0_Y_COUNT(ycnt); - bfin_write_MDMA_S0_Y_COUNT(ycnt); - bfin_write_MDMA_D0_Y_MODIFY(dmod); - bfin_write_MDMA_S0_Y_MODIFY(smod); + bfin_write_MDMA_D_Y_COUNT(ycnt); + bfin_write_MDMA_S_Y_COUNT(ycnt); + bfin_write_MDMA_D_Y_MODIFY(dmod); + bfin_write_MDMA_S_Y_MODIFY(smod); } - bfin_write_MDMA_D0_START_ADDR(daddr); - bfin_write_MDMA_D0_X_COUNT(cnt); - bfin_write_MDMA_D0_X_MODIFY(dmod); - bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); + bfin_write_MDMA_D_START_ADDR(daddr); + bfin_write_MDMA_D_X_COUNT(cnt); + bfin_write_MDMA_D_X_MODIFY(dmod); + bfin_write_MDMA_D_IRQ_STATUS(DMA_DONE | DMA_ERR); - bfin_write_MDMA_S0_START_ADDR(saddr); - bfin_write_MDMA_S0_X_COUNT(cnt); - bfin_write_MDMA_S0_X_MODIFY(smod); - bfin_write_MDMA_S0_IRQ_STATUS(DMA_DONE | DMA_ERR); + bfin_write_MDMA_S_START_ADDR(saddr); + bfin_write_MDMA_S_X_COUNT(cnt); + bfin_write_MDMA_S_X_MODIFY(smod); + bfin_write_MDMA_S_IRQ_STATUS(DMA_DONE | DMA_ERR); - bfin_write_MDMA_S0_CONFIG(DMAEN | conf); - bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | conf); + bfin_write_MDMA_S_CONFIG(DMAEN | conf); + if (conf & DMA2D) + bfin_write_MDMA_D_CONFIG(WNR | DI_EN_Y | DMAEN | conf); + else + bfin_write_MDMA_D_CONFIG(WNR | DI_EN_X | DMAEN | conf); spin_unlock_irqrestore(&mdma_lock, flags); SSYNC(); - while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) - if (bfin_read_MDMA_S0_CONFIG()) + while (!(bfin_read_MDMA_D_IRQ_STATUS() & DMA_DONE)) + if (bfin_read_MDMA_S_CONFIG()) continue; else return; - bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); + bfin_write_MDMA_D_IRQ_STATUS(DMA_DONE | DMA_ERR); - bfin_write_MDMA_S0_CONFIG(0); - bfin_write_MDMA_D0_CONFIG(0); + bfin_write_MDMA_S_CONFIG(0); + bfin_write_MDMA_D_CONFIG(0); } /** @@ -448,8 +512,10 @@ } size >>= shift; +#ifndef DMA_MMR_SIZE_32 if (size > 0x10000) conf |= DMA2D; +#endif __dma_memcpy(dst, mod, src, mod, size, conf); @@ -488,6 +554,9 @@ */ void *dma_memcpy_nocache(void *pdst, const void *psrc, size_t size) { +#ifdef DMA_MMR_SIZE_32 + _dma_memcpy(pdst, psrc, size); +#else size_t bulk, rest; bulk = size & ~0xffff; @@ -495,6 +564,7 @@ if (bulk) _dma_memcpy(pdst, psrc, bulk); _dma_memcpy(pdst + bulk, psrc + bulk, rest); +#endif return pdst; } EXPORT_SYMBOL(dma_memcpy_nocache); @@ -514,14 +584,14 @@ } EXPORT_SYMBOL(safe_dma_memcpy); -static void _dma_out(unsigned long addr, unsigned long buf, unsigned short len, +static void _dma_out(unsigned long addr, unsigned long buf, unsigned DMA_MMR_SIZE_TYPE len, u16 size, u16 dma_size) { blackfin_dcache_flush_range(buf, buf + len * size); __dma_memcpy(addr, 0, buf, size, len, dma_size); } -static void _dma_in(unsigned long addr, unsigned long buf, unsigned short len, +static void _dma_in(unsigned long addr, unsigned long buf, unsigned DMA_MMR_SIZE_TYPE len, u16 size, u16 dma_size) { blackfin_dcache_invalidate_range(buf, buf + len * size); @@ -529,7 +599,7 @@ } #define MAKE_DMA_IO(io, bwl, isize, dmasize, cnst) \ -void dma_##io##s##bwl(unsigned long addr, cnst void *buf, unsigned short len) \ +void dma_##io##s##bwl(unsigned long addr, cnst void *buf, unsigned DMA_MMR_SIZE_TYPE len) \ { \ _dma_##io(addr, (unsigned long)buf, len, isize, WDSIZE_##dmasize); \ } \
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 02796b8..83139aa 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -58,7 +58,7 @@ (struct gpio_port_t *) FIO0_FLAG_D, (struct gpio_port_t *) FIO1_FLAG_D, (struct gpio_port_t *) FIO2_FLAG_D, -#elif defined(CONFIG_BF54x) +#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) (struct gpio_port_t *)PORTA_FER, (struct gpio_port_t *)PORTB_FER, (struct gpio_port_t *)PORTC_FER, @@ -66,9 +66,11 @@ (struct gpio_port_t *)PORTE_FER, (struct gpio_port_t *)PORTF_FER, (struct gpio_port_t *)PORTG_FER, +# if defined(CONFIG_BF54x) (struct gpio_port_t *)PORTH_FER, (struct gpio_port_t *)PORTI_FER, (struct gpio_port_t *)PORTJ_FER, +# endif #else # error no gpio arrays defined #endif @@ -210,7 +212,7 @@ else *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); SSYNC(); -#elif defined(CONFIG_BF54x) +#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) if (usage == GPIO_USAGE) gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio); else @@ -299,7 +301,7 @@ pmux |= (function << offset); bfin_write_PORT_MUX(pmux); } -#elif defined(CONFIG_BF54x) +#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) inline void portmux_setup(unsigned short per) { u16 ident = P_IDENT(per); @@ -377,7 +379,7 @@ } #endif -#ifndef CONFIG_BF54x +#if !(defined(CONFIG_BF54x) || defined(CONFIG_BF60x)) /*********************************************************** * * FUNCTIONS: Blackfin General Purpose Ports Access Functions @@ -680,7 +682,7 @@ #endif -#else /* CONFIG_BF54x */ +#else /* CONFIG_BF54x || CONFIG_BF60x */ #ifdef CONFIG_PM int bfin_pm_standby_ctrl(unsigned ctrl) @@ -726,7 +728,7 @@ } EXPORT_SYMBOL(get_gpio_dir); -#endif /* CONFIG_BF54x */ +#endif /* CONFIG_BF54x || CONFIG_BF60x */ /*********************************************************** * @@ -783,7 +785,7 @@ * be requested and used by several drivers */ -#ifdef CONFIG_BF54x +#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) { #else if (!(per & P_MAYSHARE)) { @@ -937,7 +939,7 @@ printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!" " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio); } -#ifndef CONFIG_BF54x +#if !(defined(CONFIG_BF54x) || defined(CONFIG_BF60x)) else { /* Reset POLAR setting when acquiring a gpio for the first time */ set_gpio_polar(gpio, 0); } @@ -1110,7 +1112,7 @@ static inline void __bfin_gpio_direction_input(unsigned gpio) { -#ifdef CONFIG_BF54x +#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio); #else gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); @@ -1138,13 +1140,13 @@ void bfin_gpio_irq_prepare(unsigned gpio) { -#ifdef CONFIG_BF54x +#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) unsigned long flags; #endif port_setup(gpio, GPIO_USAGE); -#ifdef CONFIG_BF54x +#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) flags = hard_local_irq_save(); __bfin_gpio_direction_input(gpio); hard_local_irq_restore(flags); @@ -1173,7 +1175,7 @@ gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); gpio_set_value(gpio, value); -#ifdef CONFIG_BF54x +#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio); #else gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio); @@ -1188,7 +1190,7 @@ int bfin_gpio_get_value(unsigned gpio) { -#ifdef CONFIG_BF54x +#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio))); #else unsigned long flags;
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index 886e000..3e366dc 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
@@ -139,7 +139,7 @@ dcplb_bounds[i_d].eaddr = BOOT_ROM_START; dcplb_bounds[i_d++].data = 0; /* BootROM -- largest one should be less than 1 meg. */ - dcplb_bounds[i_d].eaddr = BOOT_ROM_START + (1 * 1024 * 1024); + dcplb_bounds[i_d].eaddr = BOOT_ROM_START + BOOT_ROM_LENGTH; dcplb_bounds[i_d++].data = SDRAM_DGENERIC; if (L2_LENGTH) { /* Addressing hole up to L2 SRAM. */ @@ -178,7 +178,7 @@ icplb_bounds[i_i].eaddr = BOOT_ROM_START; icplb_bounds[i_i++].data = 0; /* BootROM -- largest one should be less than 1 meg. */ - icplb_bounds[i_i].eaddr = BOOT_ROM_START + (1 * 1024 * 1024); + icplb_bounds[i_i].eaddr = BOOT_ROM_START + BOOT_ROM_LENGTH; icplb_bounds[i_i++].data = SDRAM_IGENERIC; if (L2_LENGTH) {
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c index 5b88861..e854f906 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
@@ -179,6 +179,12 @@ addr = addr1; } +#ifdef CONFIG_BF60x + if ((addr >= ASYNC_BANK0_BASE) + && (addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE)) + d_data |= PAGE_SIZE_64MB; +#endif + /* Pick entry to evict */ idx = evict_one_dcplb(cpu);
diff --git a/arch/blackfin/kernel/debug-mmrs.c b/arch/blackfin/kernel/debug-mmrs.c index 92f6648..01232a1 100644 --- a/arch/blackfin/kernel/debug-mmrs.c +++ b/arch/blackfin/kernel/debug-mmrs.c
@@ -105,6 +105,7 @@ DEFINE_SYSREG(syscfg, , CSYNC()); #define D_SYSREG(sr) debugfs_create_file(#sr, S_IRUSR|S_IWUSR, parent, NULL, &fops_sysreg_##sr) +#ifndef CONFIG_BF60x /* * CAN */ @@ -223,8 +224,10 @@ __DMA(CURR_DESC_PTR, curr_desc_ptr); __DMA(CURR_ADDR, curr_addr); __DMA(IRQ_STATUS, irq_status); +#ifndef CONFIG_BF60x if (strcmp(pfx, "IMDMA") != 0) __DMA(PERIPHERAL_MAP, peripheral_map); +#endif __DMA(CURR_X_COUNT, curr_x_count); __DMA(CURR_Y_COUNT, curr_y_count); } @@ -568,7 +571,7 @@ #endif } #define UART(num) bfin_debug_mmrs_uart(parent, UART##num##_DLL, num) - +#endif /* CONFIG_BF60x */ /* * The actual debugfs generation */ @@ -740,7 +743,7 @@ D32(WPDACNT0); D32(WPDACNT1); D32(WPSTAT); - +#ifndef CONFIG_BF60x /* System MMRs */ #ifdef ATAPI_CONTROL parent = debugfs_create_dir("atapi", top); @@ -1873,7 +1876,7 @@ } #endif /* BF54x */ - +#endif /* CONFIG_BF60x */ debug_mmrs_dentry = top; return 0;
diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S index 686478f..f33792c 100644 --- a/arch/blackfin/kernel/entry.S +++ b/arch/blackfin/kernel/entry.S
@@ -64,16 +64,6 @@ jump (p0); ENDPROC(_ret_from_fork) -ENTRY(_sys_fork) - r0 = -EINVAL; -#if (ANOMALY_05000371) - nop; - nop; - nop; -#endif - rts; -ENDPROC(_sys_fork) - ENTRY(_sys_vfork) r0 = sp; r0 += 24;
diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c index 06459f4..d776773 100644 --- a/arch/blackfin/kernel/gptimers.c +++ b/arch/blackfin/kernel/gptimers.c
@@ -23,7 +23,11 @@ printk(KERN_DEBUG "%s:%s:%i: Assertion failed: " #expr "\n", __FILE__, __func__, __LINE__); #endif -#define BFIN_TIMER_NUM_GROUP (BFIN_TIMER_OCTET(MAX_BLACKFIN_GPTIMERS - 1) + 1) +#ifndef CONFIG_BF60x +# define BFIN_TIMER_NUM_GROUP (BFIN_TIMER_OCTET(MAX_BLACKFIN_GPTIMERS - 1) + 1) +#else +# define BFIN_TIMER_NUM_GROUP 1 +#endif static struct bfin_gptimer_regs * const timer_regs[MAX_BLACKFIN_GPTIMERS] = { @@ -158,6 +162,74 @@ } EXPORT_SYMBOL(get_gptimer_count); +#ifdef CONFIG_BF60x +void set_gptimer_delay(unsigned int timer_id, uint32_t delay) +{ + tassert(timer_id < MAX_BLACKFIN_GPTIMERS); + bfin_write(&timer_regs[timer_id]->delay, delay); + SSYNC(); +} +EXPORT_SYMBOL(set_gptimer_delay); + +uint32_t get_gptimer_delay(unsigned int timer_id) +{ + tassert(timer_id < MAX_BLACKFIN_GPTIMERS); + return bfin_read(&timer_regs[timer_id]->delay); +} +EXPORT_SYMBOL(get_gptimer_delay); +#endif + +#ifdef CONFIG_BF60x +int get_gptimer_intr(unsigned int timer_id) +{ + tassert(timer_id < MAX_BLACKFIN_GPTIMERS); + return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->data_ilat) & timil_mask[timer_id]); +} +EXPORT_SYMBOL(get_gptimer_intr); + +void clear_gptimer_intr(unsigned int timer_id) +{ + tassert(timer_id < MAX_BLACKFIN_GPTIMERS); + bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->data_ilat, timil_mask[timer_id]); +} +EXPORT_SYMBOL(clear_gptimer_intr); + +int get_gptimer_over(unsigned int timer_id) +{ + tassert(timer_id < MAX_BLACKFIN_GPTIMERS); + return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->stat_ilat) & tovf_mask[timer_id]); +} +EXPORT_SYMBOL(get_gptimer_over); + +void clear_gptimer_over(unsigned int timer_id) +{ + tassert(timer_id < MAX_BLACKFIN_GPTIMERS); + bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->stat_ilat, tovf_mask[timer_id]); +} +EXPORT_SYMBOL(clear_gptimer_over); + +int get_gptimer_run(unsigned int timer_id) +{ + tassert(timer_id < MAX_BLACKFIN_GPTIMERS); + return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->run) & trun_mask[timer_id]); +} +EXPORT_SYMBOL(get_gptimer_run); + +uint32_t get_gptimer_status(unsigned int group) +{ + tassert(group < BFIN_TIMER_NUM_GROUP); + return bfin_read(&group_regs[group]->data_ilat); +} +EXPORT_SYMBOL(get_gptimer_status); + +void set_gptimer_status(unsigned int group, uint32_t value) +{ + tassert(group < BFIN_TIMER_NUM_GROUP); + bfin_write(&group_regs[group]->data_ilat, value); + SSYNC(); +} +EXPORT_SYMBOL(set_gptimer_status); +#else uint32_t get_gptimer_status(unsigned int group) { tassert(group < BFIN_TIMER_NUM_GROUP); @@ -212,6 +284,7 @@ return !!(read_gptimer_status(timer_id) & trun_mask[timer_id]); } EXPORT_SYMBOL(get_gptimer_run); +#endif void set_gptimer_config(unsigned int timer_id, uint16_t config) { @@ -231,6 +304,12 @@ void enable_gptimers(uint16_t mask) { int i; +#ifdef CONFIG_BF60x + uint16_t imask; + imask = bfin_read16(TIMER_DATA_IMSK); + imask &= ~mask; + bfin_write16(TIMER_DATA_IMSK, imask); +#endif tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0); for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) { bfin_write(&group_regs[i]->enable, mask & 0xFF); @@ -253,12 +332,16 @@ void disable_gptimers(uint16_t mask) { +#ifndef CONFIG_BF60x int i; _disable_gptimers(mask); for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i) if (mask & (1 << i)) bfin_write(&group_regs[BFIN_TIMER_OCTET(i)]->status, trun_mask[i]); SSYNC(); +#else + _disable_gptimers(mask); +#endif } EXPORT_SYMBOL(disable_gptimers);
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index c0f4fe2..2e3994b 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c
@@ -95,7 +95,9 @@ idle(); rcu_idle_exit(); tick_nohz_idle_exit(); - schedule_preempt_disabled(); + preempt_enable_no_resched(); + schedule(); + preempt_disable(); } } @@ -329,12 +331,16 @@ { return in_mem_const_off(addr, size, 0, const_addr, const_size); } +#ifdef CONFIG_BF60x +#define ASYNC_ENABLED(bnum, bctlnum) 1 +#else #define ASYNC_ENABLED(bnum, bctlnum) \ ({ \ (bfin_read_EBIU_AMGCTL() & 0xe) < ((bnum + 1) << 1) ? 0 : \ bfin_read_EBIU_AMBCTL##bctlnum() & B##bnum##RDYEN ? 0 : \ 1; \ }) +#endif /* * We can't read EBIU banks that aren't enabled or we end up hanging * on the access to the async space. Make sure we validate accesses
diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c index b0434f8..5272e6e 100644 --- a/arch/blackfin/kernel/reboot.c +++ b/arch/blackfin/kernel/reboot.c
@@ -22,6 +22,7 @@ __attribute__ ((__l1_text__, __noreturn__)) static void bfin_reset(void) { +#ifndef CONFIG_BF60x if (!ANOMALY_05000353 && !ANOMALY_05000386) bfrom_SoftReset((void *)(L1_SCRATCH_START + L1_SCRATCH_LENGTH - 20)); @@ -57,7 +58,6 @@ if (__SILICON_REVISION__ < 1 && bfin_revid() < 1) bfin_read_SWRST(); #endif - /* Wait for the SWRST write to complete. Cannot rely on SSYNC * though as the System state is all reset now. */ @@ -72,6 +72,10 @@ while (1) /* Issue core reset */ asm("raise 1"); +#else + while (1) + bfin_write_RCU0_CTL(0x1); +#endif } __attribute__((weak))
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 2ad747e..ada8f0f 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c
@@ -25,12 +25,16 @@ #include <asm/cacheflush.h> #include <asm/blackfin.h> #include <asm/cplbinit.h> +#include <asm/clocks.h> #include <asm/div64.h> #include <asm/cpu.h> #include <asm/fixed_code.h> #include <asm/early_printk.h> #include <asm/irq_handler.h> #include <asm/pda.h> +#ifdef CONFIG_BF60x +#include <mach/pm.h> +#endif u16 _bfin_swrst; EXPORT_SYMBOL(_bfin_swrst); @@ -550,7 +554,6 @@ { #ifdef CONFIG_MTD_UCLINUX unsigned long mtd_phys = 0; - unsigned long n; #endif unsigned long max_mem; @@ -594,9 +597,9 @@ mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 8))); # if defined(CONFIG_EXT2_FS) || defined(CONFIG_EXT3_FS) - n = ext2_image_size((void *)(mtd_phys + 0x400)); - if (n) - mtd_size = PAGE_ALIGN(n * 1024); + if (*((unsigned short *)(mtd_phys + 0x438)) == EXT2_SUPER_MAGIC) + mtd_size = + PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x404)) << 10); # endif # if defined(CONFIG_CRAMFS) @@ -612,7 +615,8 @@ /* ROM_FS is XIP, so if we found it, we need to limit memory */ if (memory_end > max_mem) { - pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", max_mem >> 20); + pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", + (max_mem - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20); memory_end = max_mem; } } @@ -642,7 +646,8 @@ * doesn't exist, or we don't need to - then dont. */ if (memory_end > max_mem) { - pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", max_mem >> 20); + pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", + (max_mem - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20); memory_end = max_mem; } @@ -661,8 +666,8 @@ init_mm.end_data = (unsigned long)_edata; init_mm.brk = (unsigned long)0; - printk(KERN_INFO "Board Memory: %ldMB\n", physical_mem_end >> 20); - printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20); + printk(KERN_INFO "Board Memory: %ldMB\n", (physical_mem_end - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20); + printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", (_ramend - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20); printk(KERN_INFO "Memory map:\n" " fixedcode = 0x%p-0x%p\n" @@ -705,7 +710,7 @@ int i; max_pfn = 0; - min_low_pfn = memory_end; + min_low_pfn = PFN_DOWN(memory_end); for (i = 0; i < bfin_memmap.nr_map; i++) { unsigned long start, end; @@ -748,8 +753,7 @@ /* pfn of the first usable page frame after kernel image*/ if (min_low_pfn < memory_start >> PAGE_SHIFT) min_low_pfn = memory_start >> PAGE_SHIFT; - - start_pfn = PAGE_OFFSET >> PAGE_SHIFT; + start_pfn = CONFIG_PHY_RAM_BASE_ADDRESS >> PAGE_SHIFT; end_pfn = memory_end >> PAGE_SHIFT; /* @@ -794,8 +798,8 @@ } /* reserve memory before memory_start, including bootmap */ - reserve_bootmem(PAGE_OFFSET, - memory_start + bootmap_size + PAGE_SIZE - 1 - PAGE_OFFSET, + reserve_bootmem(CONFIG_PHY_RAM_BASE_ADDRESS, + memory_start + bootmap_size + PAGE_SIZE - 1 - CONFIG_PHY_RAM_BASE_ADDRESS, BOOTMEM_DEFAULT); } @@ -844,13 +848,40 @@ break; } switch (ddrctl & 0x30000) { - case DEVWD_4: ret *= 2; - case DEVWD_8: ret *= 2; - case DEVWD_16: break; + case DEVWD_4: + ret *= 2; + case DEVWD_8: + ret *= 2; + case DEVWD_16: + break; } if ((ddrctl & 0xc000) == 0x4000) ret *= 2; return ret; +#elif defined(CONFIG_BF60x) + u32 ddrctl = bfin_read_DMC0_CFG(); + int ret; + switch (ddrctl & 0xf00) { + case DEVSZ_64: + ret = 64 / 8; + break; + case DEVSZ_128: + ret = 128 / 8; + break; + case DEVSZ_256: + ret = 256 / 8; + break; + case DEVSZ_512: + ret = 512 / 8; + break; + case DEVSZ_1G: + ret = 1024 / 8; + break; + case DEVSZ_2G: + ret = 2048 / 8; + break; + } + return ret; #endif BUG(); } @@ -860,6 +891,22 @@ { } +#ifdef CONFIG_BF60x +static inline u_long bfin_get_clk(char *name) +{ + struct clk *clk; + u_long clk_rate; + + clk = clk_get(NULL, name); + if (IS_ERR(clk)) + return 0; + + clk_rate = clk_get_rate(clk); + clk_put(clk); + return clk_rate; +} +#endif + void __init setup_arch(char **cmdline_p) { u32 mmr; @@ -870,6 +917,7 @@ enable_shadow_console(); /* Check to make sure we are running on the right processor */ + mmr = bfin_cpuid(); if (unlikely(CPUID != bfin_cpuid())) printk(KERN_ERR "ERROR: Not running on ADSP-%s: unknown CPUID 0x%04x Rev 0.%d\n", CPU, bfin_cpuid(), bfin_revid()); @@ -890,6 +938,10 @@ memset(&bfin_memmap, 0, sizeof(bfin_memmap)); +#ifdef CONFIG_BF60x + /* Should init clock device before parse command early */ + clk_init(); +#endif /* If the user does not specify things on the command line, use * what the bootloader set things up as */ @@ -904,6 +956,7 @@ memory_setup(); +#ifndef CONFIG_BF60x /* Initialize Async memory banks */ bfin_write_EBIU_AMBCTL0(AMBCTL0VAL); bfin_write_EBIU_AMBCTL1(AMBCTL1VAL); @@ -913,6 +966,7 @@ bfin_write_EBIU_MODE(CONFIG_EBIU_MODEVAL); bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTLVAL); #endif +#endif #ifdef CONFIG_BFIN_HYSTERESIS_CONTROL bfin_write_PORTF_HYSTERESIS(HYST_PORTF_0_15); bfin_write_PORTG_HYSTERESIS(HYST_PORTG_0_15); @@ -938,7 +992,7 @@ printk(KERN_INFO "Hardware Trace %s and %sabled\n", (mmr & 0x1) ? "active" : "off", (mmr & 0x2) ? "en" : "dis"); - +#ifndef CONFIG_BF60x mmr = bfin_read_SYSCR(); printk(KERN_INFO "Boot Mode: %i\n", mmr & 0xF); @@ -980,7 +1034,7 @@ printk(KERN_INFO "Recovering from Watchdog event\n"); else if (_bfin_swrst & RESET_SOFTWARE) printk(KERN_NOTICE "Reset caused by Software reset\n"); - +#endif printk(KERN_INFO "Blackfin support (C) 2004-2010 Analog Devices, Inc.\n"); if (bfin_compiled_revid() == 0xffff) printk(KERN_INFO "Compiled for ADSP-%s Rev any, running on 0.%d\n", CPU, bfin_revid()); @@ -1008,8 +1062,13 @@ printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); +#ifdef CONFIG_BF60x + printk(KERN_INFO "Processor Speed: %lu MHz core clock, %lu MHz SCLk, %lu MHz SCLK0, %lu MHz SCLK1 and %lu MHz DCLK\n", + cclk / 1000000, bfin_get_clk("SYSCLK") / 1000000, get_sclk0() / 1000000, get_sclk1() / 1000000, get_dclk() / 1000000); +#else printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n", cclk / 1000000, sclk / 1000000); +#endif setup_bootmem_allocator(); @@ -1060,10 +1119,12 @@ /* Get the input clock frequency */ static u_long cached_clkin_hz = CONFIG_CLKIN_HZ; +#ifndef CONFIG_BF60x static u_long get_clkin_hz(void) { return cached_clkin_hz; } +#endif static int __init early_init_clkin_hz(char *buf) { cached_clkin_hz = simple_strtoul(buf, NULL, 0); @@ -1075,6 +1136,7 @@ } early_param("clkin_hz=", early_init_clkin_hz); +#ifndef CONFIG_BF60x /* Get the voltage input multiplier */ static u_long get_vco(void) { @@ -1097,10 +1159,14 @@ cached_vco *= msel; return cached_vco; } +#endif /* Get the Core clock */ u_long get_cclk(void) { +#ifdef CONFIG_BF60x + return bfin_get_clk("CCLK"); +#else static u_long cached_cclk_pll_div, cached_cclk; u_long csel, ssel; @@ -1120,12 +1186,39 @@ else cached_cclk = get_vco() >> csel; return cached_cclk; +#endif } EXPORT_SYMBOL(get_cclk); -/* Get the System clock */ +#ifdef CONFIG_BF60x +/* Get the bf60x clock of SCLK0 domain */ +u_long get_sclk0(void) +{ + return bfin_get_clk("SCLK0"); +} +EXPORT_SYMBOL(get_sclk0); + +/* Get the bf60x clock of SCLK1 domain */ +u_long get_sclk1(void) +{ + return bfin_get_clk("SCLK1"); +} +EXPORT_SYMBOL(get_sclk1); + +/* Get the bf60x DRAM clock */ +u_long get_dclk(void) +{ + return bfin_get_clk("DCLK"); +} +EXPORT_SYMBOL(get_dclk); +#endif + +/* Get the default system clock */ u_long get_sclk(void) { +#ifdef CONFIG_BF60x + return get_sclk0(); +#else static u_long cached_sclk; u_long ssel; @@ -1146,6 +1239,7 @@ cached_sclk = get_vco() / ssel; return cached_sclk; +#endif } EXPORT_SYMBOL(get_sclk);
diff --git a/arch/blackfin/kernel/shadow_console.c b/arch/blackfin/kernel/shadow_console.c index 557e9fe..aeb8343 100644 --- a/arch/blackfin/kernel/shadow_console.c +++ b/arch/blackfin/kernel/shadow_console.c
@@ -15,9 +15,9 @@ #include <asm/irq_handler.h> #include <asm/early_printk.h> -#define SHADOW_CONSOLE_START (0x500) -#define SHADOW_CONSOLE_END (0x1000) -#define SHADOW_CONSOLE_MAGIC_LOC (0x4F0) +#define SHADOW_CONSOLE_START (CONFIG_PHY_RAM_BASE_ADDRESS + 0x500) +#define SHADOW_CONSOLE_END (CONFIG_PHY_RAM_BASE_ADDRESS + 0x1000) +#define SHADOW_CONSOLE_MAGIC_LOC (CONFIG_PHY_RAM_BASE_ADDRESS + 0x4F0) #define SHADOW_CONSOLE_MAGIC (0xDEADBEEF) static __initdata char *shadow_console_buffer = (char *)SHADOW_CONSOLE_START;
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index d98f2d6..f608f02 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c
@@ -66,8 +66,14 @@ { disable_gptimers(TIMER0bit); +#ifdef CONFIG_BF60x + bfin_write16(TIMER_DATA_IMSK, 0); + set_gptimer_config(TIMER0_id, TIMER_OUT_DIS + | TIMER_MODE_PWM_CONT | TIMER_PULSE_HI | TIMER_IRQ_PER); +#else set_gptimer_config(TIMER0_id, \ TIMER_OUT_DIS | TIMER_PERIOD_CNT | TIMER_MODE_PWM); +#endif set_gptimer_period(TIMER0_id, -1); set_gptimer_pwidth(TIMER0_id, -2); SSYNC(); @@ -135,9 +141,15 @@ { switch (mode) { case CLOCK_EVT_MODE_PERIODIC: { +#ifndef CONFIG_BF60x set_gptimer_config(TIMER0_id, \ TIMER_OUT_DIS | TIMER_IRQ_ENA | \ TIMER_PERIOD_CNT | TIMER_MODE_PWM); +#else + set_gptimer_config(TIMER0_id, TIMER_OUT_DIS + | TIMER_MODE_PWM_CONT | TIMER_PULSE_HI | TIMER_IRQ_PER); +#endif + set_gptimer_period(TIMER0_id, get_sclk() / HZ); set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1); enable_gptimers(TIMER0bit); @@ -145,8 +157,14 @@ } case CLOCK_EVT_MODE_ONESHOT: disable_gptimers(TIMER0bit); +#ifndef CONFIG_BF60x set_gptimer_config(TIMER0_id, \ TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM); +#else + set_gptimer_config(TIMER0_id, TIMER_OUT_DIS | TIMER_MODE_PWM + | TIMER_PULSE_HI | TIMER_IRQ_WID_DLY); +#endif + set_gptimer_period(TIMER0_id, 0); break; case CLOCK_EVT_MODE_UNUSED: @@ -160,7 +178,7 @@ static void bfin_gptmr0_ack(void) { - set_gptimer_status(TIMER_GROUP1, TIMER_STATUS_TIMIL0); + clear_gptimer_intr(TIMER0_id); } static void __init bfin_gptmr0_init(void) @@ -197,7 +215,7 @@ .rating = 300, .irq = IRQ_TIMER0, .shift = 32, - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .set_next_event = bfin_gptmr0_set_next_event, .set_mode = bfin_gptmr0_set_mode, }; @@ -312,6 +330,11 @@ #endif +#ifdef CONFIG_SMP + evt->broadcast = smp_timer_broadcast; +#endif + + evt->name = "bfin_core_timer"; evt->rating = 350; evt->irq = -1;
diff --git a/arch/blackfin/lib/divsi3.S b/arch/blackfin/lib/divsi3.S index f89c5a4..ef2cd99 100644 --- a/arch/blackfin/lib/divsi3.S +++ b/arch/blackfin/lib/divsi3.S
@@ -1,7 +1,7 @@ /* * Copyright 2004-2009 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) * * 16 / 32 bit signed division. * Special cases :
diff --git a/arch/blackfin/lib/memchr.S b/arch/blackfin/lib/memchr.S index 542e40f..bcfc8a1 100644 --- a/arch/blackfin/lib/memchr.S +++ b/arch/blackfin/lib/memchr.S
@@ -1,7 +1,7 @@ /* * Copyright 2005-2009 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #include <linux/linkage.h>
diff --git a/arch/blackfin/lib/memcmp.S b/arch/blackfin/lib/memcmp.S index ce5b9f1..2e1c947 100644 --- a/arch/blackfin/lib/memcmp.S +++ b/arch/blackfin/lib/memcmp.S
@@ -1,7 +1,7 @@ /* * Copyright 2004-2009 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #include <linux/linkage.h>
diff --git a/arch/blackfin/lib/memcpy.S b/arch/blackfin/lib/memcpy.S index c31bf22..53cb369 100644 --- a/arch/blackfin/lib/memcpy.S +++ b/arch/blackfin/lib/memcpy.S
@@ -7,7 +7,7 @@ * * Copyright 2004-2009 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #include <linux/linkage.h>
diff --git a/arch/blackfin/lib/memmove.S b/arch/blackfin/lib/memmove.S index 4eca566..e0b7820 100644 --- a/arch/blackfin/lib/memmove.S +++ b/arch/blackfin/lib/memmove.S
@@ -1,7 +1,7 @@ /* * Copyright 2005-2009 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #include <linux/linkage.h>
diff --git a/arch/blackfin/lib/memset.S b/arch/blackfin/lib/memset.S index eab1bef..cdcf914 100644 --- a/arch/blackfin/lib/memset.S +++ b/arch/blackfin/lib/memset.S
@@ -1,7 +1,7 @@ /* * Copyright 2004-2009 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #include <linux/linkage.h>
diff --git a/arch/blackfin/lib/modsi3.S b/arch/blackfin/lib/modsi3.S index 8b0c7d4..f7026ce 100644 --- a/arch/blackfin/lib/modsi3.S +++ b/arch/blackfin/lib/modsi3.S
@@ -6,7 +6,7 @@ * * Copyright 2004-2009 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ .global ___modsi3;
diff --git a/arch/blackfin/lib/muldi3.S b/arch/blackfin/lib/muldi3.S index 953a38a..abf9b2a 100644 --- a/arch/blackfin/lib/muldi3.S +++ b/arch/blackfin/lib/muldi3.S
@@ -1,7 +1,7 @@ /* * Copyright 2008 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ .align 2
diff --git a/arch/blackfin/lib/smulsi3_highpart.S b/arch/blackfin/lib/smulsi3_highpart.S index 99ee8c5..e50d6c4 100644 --- a/arch/blackfin/lib/smulsi3_highpart.S +++ b/arch/blackfin/lib/smulsi3_highpart.S
@@ -1,7 +1,7 @@ /* * Copyright 2007 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ .align 2
diff --git a/arch/blackfin/lib/strcmp.S b/arch/blackfin/lib/strcmp.S index d7c1d15..9c8b986 100644 --- a/arch/blackfin/lib/strcmp.S +++ b/arch/blackfin/lib/strcmp.S
@@ -1,7 +1,7 @@ /* * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #include <linux/linkage.h>
diff --git a/arch/blackfin/lib/strcpy.S b/arch/blackfin/lib/strcpy.S index a6a0c63..9495aa7 100644 --- a/arch/blackfin/lib/strcpy.S +++ b/arch/blackfin/lib/strcpy.S
@@ -1,7 +1,7 @@ /* * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #include <linux/linkage.h>
diff --git a/arch/blackfin/lib/strncmp.S b/arch/blackfin/lib/strncmp.S index 6da37c3..3bfaedc 100644 --- a/arch/blackfin/lib/strncmp.S +++ b/arch/blackfin/lib/strncmp.S
@@ -1,7 +1,7 @@ /* * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #include <linux/linkage.h>
diff --git a/arch/blackfin/lib/strncpy.S b/arch/blackfin/lib/strncpy.S index 2c07ddd..92fd182 100644 --- a/arch/blackfin/lib/strncpy.S +++ b/arch/blackfin/lib/strncpy.S
@@ -1,7 +1,7 @@ /* * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #include <linux/linkage.h>
diff --git a/arch/blackfin/lib/udivsi3.S b/arch/blackfin/lib/udivsi3.S index 97e9043..748a6a2 100644 --- a/arch/blackfin/lib/udivsi3.S +++ b/arch/blackfin/lib/udivsi3.S
@@ -1,7 +1,7 @@ /* * Copyright 2004-2009 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #include <linux/linkage.h>
diff --git a/arch/blackfin/lib/umodsi3.S b/arch/blackfin/lib/umodsi3.S index 168eba7..3794c00 100644 --- a/arch/blackfin/lib/umodsi3.S +++ b/arch/blackfin/lib/umodsi3.S
@@ -3,7 +3,7 @@ * * Copyright 2004-2009 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifdef CONFIG_ARITHMETIC_OPS_L1
diff --git a/arch/blackfin/lib/umulsi3_highpart.S b/arch/blackfin/lib/umulsi3_highpart.S index 051824a..0dcace9 100644 --- a/arch/blackfin/lib/umulsi3_highpart.S +++ b/arch/blackfin/lib/umulsi3_highpart.S
@@ -1,7 +1,7 @@ /* * Copyright 2007 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ .align 2
diff --git a/arch/blackfin/mach-bf518/boards/ezbrd.c b/arch/blackfin/mach-bf518/boards/ezbrd.c index a173957..f8047ca 100644 --- a/arch/blackfin/mach-bf518/boards/ezbrd.c +++ b/arch/blackfin/mach-bf518/boards/ezbrd.c
@@ -529,6 +529,8 @@ #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -547,6 +549,9 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; #endif
diff --git a/arch/blackfin/mach-bf518/boards/tcm-bf518.c b/arch/blackfin/mach-bf518/boards/tcm-bf518.c index 6eebee4..0bedc73 100644 --- a/arch/blackfin/mach-bf518/boards/tcm-bf518.c +++ b/arch/blackfin/mach-bf518/boards/tcm-bf518.c
@@ -455,6 +455,8 @@ #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -473,6 +475,9 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; #endif
diff --git a/arch/blackfin/mach-bf518/include/mach/anomaly.h b/arch/blackfin/mach-bf518/include/mach/anomaly.h index 56383f7..845e6bc 100644 --- a/arch/blackfin/mach-bf518/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf518/include/mach/anomaly.h
@@ -6,8 +6,7 @@ * DO NOT EDIT THIS FILE * * Copyright 2004-2011 Analog Devices Inc. - * Licensed under the ADI BSD license. - * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd + * Licensed under the Clear BSD license. */ /* This file should be up to date with:
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF512.h b/arch/blackfin/mach-bf518/include/mach/cdefBF512.h index bb79627..1c03ad4 100644 --- a/arch/blackfin/mach-bf518/include/mach/cdefBF512.h +++ b/arch/blackfin/mach-bf518/include/mach/cdefBF512.h
@@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _CDEF_BF512_H
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF514.h b/arch/blackfin/mach-bf518/include/mach/cdefBF514.h index dc98866..861221d 100644 --- a/arch/blackfin/mach-bf518/include/mach/cdefBF514.h +++ b/arch/blackfin/mach-bf518/include/mach/cdefBF514.h
@@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _CDEF_BF514_H
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF516.h b/arch/blackfin/mach-bf518/include/mach/cdefBF516.h index 142e45c..cc9bf0d 100644 --- a/arch/blackfin/mach-bf518/include/mach/cdefBF516.h +++ b/arch/blackfin/mach-bf518/include/mach/cdefBF516.h
@@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _CDEF_BF516_H
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF518.h b/arch/blackfin/mach-bf518/include/mach/cdefBF518.h index e638197..96a82fd 100644 --- a/arch/blackfin/mach-bf518/include/mach/cdefBF518.h +++ b/arch/blackfin/mach-bf518/include/mach/cdefBF518.h
@@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _CDEF_BF518_H
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF512.h b/arch/blackfin/mach-bf518/include/mach/defBF512.h index 7297040..e6a017f 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF512.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF512.h
@@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF512_H @@ -1083,77 +1083,6 @@ #define ERR_NCOR 0x8000 /* Error Not Corrected Indicator */ -/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ***********************/ -/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */ -#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */ -#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */ - -/* TWI_PRESCALE Masks */ -#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */ -#define TWI_ENA 0x0080 /* TWI Enable */ -#define SCCB 0x0200 /* SCCB Compatibility Enable */ - -/* TWI_SLAVE_CTL Masks */ -#define SEN 0x0001 /* Slave Enable */ -#define SADD_LEN 0x0002 /* Slave Address Length */ -#define STDVAL 0x0004 /* Slave Transmit Data Valid */ -#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ -#define GEN 0x0010 /* General Call Adrress Matching Enabled */ - -/* TWI_SLAVE_STAT Masks */ -#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ -#define GCALL 0x0002 /* General Call Indicator */ - -/* TWI_MASTER_CTL Masks */ -#define MEN 0x0001 /* Master Mode Enable */ -#define MADD_LEN 0x0002 /* Master Address Length */ -#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */ -#define FAST 0x0008 /* Use Fast Mode Timing Specs */ -#define STOP 0x0010 /* Issue Stop Condition */ -#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */ -#define DCNT 0x3FC0 /* Data Bytes To Transfer */ -#define SDAOVR 0x4000 /* Serial Data Override */ -#define SCLOVR 0x8000 /* Serial Clock Override */ - -/* TWI_MASTER_STAT Masks */ -#define MPROG 0x0001 /* Master Transfer In Progress */ -#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */ -#define ANAK 0x0004 /* Address Not Acknowledged */ -#define DNAK 0x0008 /* Data Not Acknowledged */ -#define BUFRDERR 0x0010 /* Buffer Read Error */ -#define BUFWRERR 0x0020 /* Buffer Write Error */ -#define SDASEN 0x0040 /* Serial Data Sense */ -#define SCLSEN 0x0080 /* Serial Clock Sense */ -#define BUSBUSY 0x0100 /* Bus Busy Indicator */ - -/* TWI_INT_SRC and TWI_INT_ENABLE Masks */ -#define SINIT 0x0001 /* Slave Transfer Initiated */ -#define SCOMP 0x0002 /* Slave Transfer Complete */ -#define SERR 0x0004 /* Slave Transfer Error */ -#define SOVF 0x0008 /* Slave Overflow */ -#define MCOMP 0x0010 /* Master Transfer Complete */ -#define MERR 0x0020 /* Master Transfer Error */ -#define XMTSERV 0x0040 /* Transmit FIFO Service */ -#define RCVSERV 0x0080 /* Receive FIFO Service */ - -/* TWI_FIFO_CTRL Masks */ -#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */ -#define RCVFLUSH 0x0002 /* Receive Buffer Flush */ -#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */ -#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */ - -/* TWI_FIFO_STAT Masks */ -#define XMTSTAT 0x0003 /* Transmit FIFO Status */ -#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */ -#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */ -#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */ - -#define RCVSTAT 0x000C /* Receive FIFO Status */ -#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */ -#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ -#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ - - /* ******************* PIN CONTROL REGISTER MASKS ************************/ /* PORT_MUX Masks */ #define PJSE 0x0001 /* Port J SPI/SPORT Enable */
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF514.h b/arch/blackfin/mach-bf518/include/mach/defBF514.h index cfab428..97feaa6 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF514.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF514.h
@@ -1,7 +1,7 @@ /* * Copyright 2008-2009 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF514_H
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF516.h b/arch/blackfin/mach-bf518/include/mach/defBF516.h index 22a3aa0..7c79cb6 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF516.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF516.h
@@ -1,7 +1,7 @@ /* * Copyright 2008-2009 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF516_H
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF518.h b/arch/blackfin/mach-bf518/include/mach/defBF518.h index cb18270..12042ff 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF518.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF518.h
@@ -1,7 +1,7 @@ /* * Copyright 2008-2009 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF518_H
diff --git a/arch/blackfin/mach-bf527/boards/ad7160eval.c b/arch/blackfin/mach-bf527/boards/ad7160eval.c index fad7fea..d58f50e 100644 --- a/arch/blackfin/mach-bf527/boards/ad7160eval.c +++ b/arch/blackfin/mach-bf527/boards/ad7160eval.c
@@ -569,6 +569,8 @@ #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -587,6 +589,9 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; #endif @@ -681,6 +686,7 @@ .rotary_button_key = KEY_ENTER, .debounce = 10, /* 0..17 */ .mode = ROT_QUAD_ENC | ROT_DEBE, + .pm_wakeup = 1, }; static struct resource bfin_rotary_resources[] = {
diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c index 65b7fbd..413d0132 100644 --- a/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c
@@ -698,6 +698,8 @@ #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -716,6 +718,9 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; #endif
diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c index 17c6a24..50bda79 100644 --- a/arch/blackfin/mach-bf527/boards/ezbrd.c +++ b/arch/blackfin/mach-bf527/boards/ezbrd.c
@@ -576,6 +576,8 @@ #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -594,6 +596,9 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; #endif
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 2f9a2bd..af732eb 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -869,6 +869,8 @@ #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -887,6 +889,9 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; #endif @@ -1105,6 +1110,7 @@ .rotary_button_key = KEY_ENTER, .debounce = 10, /* 0..17 */ .mode = ROT_QUAD_ENC | ROT_DEBE, + .pm_wakeup = 1, }; static struct resource bfin_rotary_resources[] = {
diff --git a/arch/blackfin/mach-bf527/boards/tll6527m.c b/arch/blackfin/mach-bf527/boards/tll6527m.c index d192c0a..1509c5a 100644 --- a/arch/blackfin/mach-bf527/boards/tll6527m.c +++ b/arch/blackfin/mach-bf527/boards/tll6527m.c
@@ -656,6 +656,8 @@ #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -674,6 +676,9 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; #endif
diff --git a/arch/blackfin/mach-bf527/include/mach/anomaly.h b/arch/blackfin/mach-bf527/include/mach/anomaly.h index 6884706..aa14110 100644 --- a/arch/blackfin/mach-bf527/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf527/include/mach/anomaly.h
@@ -6,8 +6,7 @@ * DO NOT EDIT THIS FILE * * Copyright 2004-2011 Analog Devices Inc. - * Licensed under the ADI BSD license. - * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd + * Licensed under the Clear BSD license. */ /* This file should be up to date with:
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF522.h b/arch/blackfin/mach-bf527/include/mach/defBF522.h index 37d353a..e007017 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF522.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF522.h
@@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF522_H @@ -1084,77 +1084,6 @@ #define ERR_NCOR 0x8000 /* Error Not Corrected Indicator */ -/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ***********************/ -/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */ -#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */ -#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */ - -/* TWI_PRESCALE Masks */ -#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */ -#define TWI_ENA 0x0080 /* TWI Enable */ -#define SCCB 0x0200 /* SCCB Compatibility Enable */ - -/* TWI_SLAVE_CTL Masks */ -#define SEN 0x0001 /* Slave Enable */ -#define SADD_LEN 0x0002 /* Slave Address Length */ -#define STDVAL 0x0004 /* Slave Transmit Data Valid */ -#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ -#define GEN 0x0010 /* General Call Adrress Matching Enabled */ - -/* TWI_SLAVE_STAT Masks */ -#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ -#define GCALL 0x0002 /* General Call Indicator */ - -/* TWI_MASTER_CTL Masks */ -#define MEN 0x0001 /* Master Mode Enable */ -#define MADD_LEN 0x0002 /* Master Address Length */ -#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */ -#define FAST 0x0008 /* Use Fast Mode Timing Specs */ -#define STOP 0x0010 /* Issue Stop Condition */ -#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */ -#define DCNT 0x3FC0 /* Data Bytes To Transfer */ -#define SDAOVR 0x4000 /* Serial Data Override */ -#define SCLOVR 0x8000 /* Serial Clock Override */ - -/* TWI_MASTER_STAT Masks */ -#define MPROG 0x0001 /* Master Transfer In Progress */ -#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */ -#define ANAK 0x0004 /* Address Not Acknowledged */ -#define DNAK 0x0008 /* Data Not Acknowledged */ -#define BUFRDERR 0x0010 /* Buffer Read Error */ -#define BUFWRERR 0x0020 /* Buffer Write Error */ -#define SDASEN 0x0040 /* Serial Data Sense */ -#define SCLSEN 0x0080 /* Serial Clock Sense */ -#define BUSBUSY 0x0100 /* Bus Busy Indicator */ - -/* TWI_INT_SRC and TWI_INT_ENABLE Masks */ -#define SINIT 0x0001 /* Slave Transfer Initiated */ -#define SCOMP 0x0002 /* Slave Transfer Complete */ -#define SERR 0x0004 /* Slave Transfer Error */ -#define SOVF 0x0008 /* Slave Overflow */ -#define MCOMP 0x0010 /* Master Transfer Complete */ -#define MERR 0x0020 /* Master Transfer Error */ -#define XMTSERV 0x0040 /* Transmit FIFO Service */ -#define RCVSERV 0x0080 /* Receive FIFO Service */ - -/* TWI_FIFO_CTRL Masks */ -#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */ -#define RCVFLUSH 0x0002 /* Receive Buffer Flush */ -#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */ -#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */ - -/* TWI_FIFO_STAT Masks */ -#define XMTSTAT 0x0003 /* Transmit FIFO Status */ -#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */ -#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */ -#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */ - -#define RCVSTAT 0x000C /* Receive FIFO Status */ -#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */ -#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ -#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ - - /* Omit CAN masks from defBF534.h */ /* ******************* PIN CONTROL REGISTER MASKS ************************/
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF525.h b/arch/blackfin/mach-bf527/include/mach/defBF525.h index aab80bb..71578d9 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF525.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF525.h
@@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF525_H
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF527.h b/arch/blackfin/mach-bf527/include/mach/defBF527.h index 05369a9..aeb8479 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF527.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF527.h
@@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF527_H
diff --git a/arch/blackfin/mach-bf533/include/mach/anomaly.h b/arch/blackfin/mach-bf533/include/mach/anomaly.h index 03f2b40..3a8f73a 100644 --- a/arch/blackfin/mach-bf533/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf533/include/mach/anomaly.h
@@ -6,8 +6,7 @@ * DO NOT EDIT THIS FILE * * Copyright 2004-2011 Analog Devices Inc. - * Licensed under the ADI BSD license. - * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd + * Licensed under the Clear BSD license. */ /* This file should be up to date with:
diff --git a/arch/blackfin/mach-bf533/include/mach/defBF532.h b/arch/blackfin/mach-bf533/include/mach/defBF532.h index 2376d53..d438150 100644 --- a/arch/blackfin/mach-bf533/include/mach/defBF532.h +++ b/arch/blackfin/mach-bf533/include/mach/defBF532.h
@@ -3,7 +3,7 @@ * * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF532_H
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c index 27fd2c3..9408ab5 100644 --- a/arch/blackfin/mach-bf537/boards/cm_bf537e.c +++ b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
@@ -486,6 +486,8 @@ #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -504,6 +506,9 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; #endif
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537u.c b/arch/blackfin/mach-bf537/boards/cm_bf537u.c index 3f3abad..0143d8be 100644 --- a/arch/blackfin/mach-bf537/boards/cm_bf537u.c +++ b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
@@ -451,6 +451,8 @@ #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -469,6 +471,9 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; #endif
diff --git a/arch/blackfin/mach-bf537/boards/dnp5370.c b/arch/blackfin/mach-bf537/boards/dnp5370.c index 6f77bf7..8bbf0a2 100644 --- a/arch/blackfin/mach-bf537/boards/dnp5370.c +++ b/arch/blackfin/mach-bf537/boards/dnp5370.c
@@ -329,6 +329,8 @@ #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -347,6 +349,9 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; #endif
diff --git a/arch/blackfin/mach-bf537/boards/minotaur.c b/arch/blackfin/mach-bf537/boards/minotaur.c index d2d7128..a10f90e 100644 --- a/arch/blackfin/mach-bf537/boards/minotaur.c +++ b/arch/blackfin/mach-bf537/boards/minotaur.c
@@ -386,6 +386,8 @@ #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -404,6 +406,9 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; #endif
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index f3562b0..c9d9473 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -1790,6 +1790,8 @@ #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -1808,6 +1810,9 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; #endif @@ -2361,7 +2366,13 @@ }, #endif }; - +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) \ +|| defined(CONFIG_BFIN_SPORT) || defined(CONFIG_BFIN_SPORT_MODULE) +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; +#endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) #ifdef CONFIG_SERIAL_BFIN_SPORT0_UART static struct resource bfin_sport0_uart_resources[] = { @@ -2382,11 +2393,6 @@ }, }; -static unsigned short bfin_sport0_peripherals[] = { - P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, - P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0 -}; - static struct platform_device bfin_sport0_uart_device = { .name = "bfin-sport-uart", .id = 0, @@ -2432,7 +2438,49 @@ }; #endif #endif - +#if defined(CONFIG_BFIN_SPORT) || defined(CONFIG_BFIN_SPORT_MODULE) +static struct resource bfin_sport0_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_TX, + .end = IRQ_SPORT0_TX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_SPORT0_TX, + .end = CH_SPORT0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_SPORT0_RX, + .end = CH_SPORT0_RX, + .flags = IORESOURCE_DMA, + }, +}; +static struct platform_device bfin_sport0_device = { + .name = "bfin_sport_raw", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_resources), + .resource = bfin_sport0_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) #define CF_IDE_NAND_CARD_USE_HDD_INTERFACE /* #define CF_IDE_NAND_CARD_USE_CF_IN_COMMON_MEMORY_MODE */ @@ -2754,7 +2802,9 @@ static struct platform_device *stamp_devices[] __initdata = { &bfin_dpmc, - +#if defined(CONFIG_BFIN_SPORT) || defined(CONFIG_BFIN_SPORT_MODULE) + &bfin_sport0_device, +#endif #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) &bfin_pcmcia_cf_device, #endif
diff --git a/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/arch/blackfin/mach-bf537/boards/tcm_bf537.c index 3fb4218..e285c36 100644 --- a/arch/blackfin/mach-bf537/boards/tcm_bf537.c +++ b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
@@ -453,6 +453,8 @@ #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -471,6 +473,9 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; #endif
diff --git a/arch/blackfin/mach-bf537/include/mach/anomaly.h b/arch/blackfin/mach-bf537/include/mach/anomaly.h index 543cd3f..df92126 100644 --- a/arch/blackfin/mach-bf537/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf537/include/mach/anomaly.h
@@ -6,8 +6,7 @@ * DO NOT EDIT THIS FILE * * Copyright 2004-2011 Analog Devices Inc. - * Licensed under the ADI BSD license. - * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd + * Licensed under the Clear BSD license. */ /* This file should be up to date with:
diff --git a/arch/blackfin/mach-bf537/include/mach/defBF534.h b/arch/blackfin/mach-bf537/include/mach/defBF534.h index 4a031dd..ef6a98c 100644 --- a/arch/blackfin/mach-bf537/include/mach/defBF534.h +++ b/arch/blackfin/mach-bf537/include/mach/defBF534.h
@@ -1,7 +1,7 @@ /* * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF534_H @@ -1403,75 +1403,6 @@ #define ERR_DET 0x4000 /* Error Detected Indicator */ #define ERR_NCOR 0x8000 /* Error Not Corrected Indicator */ -/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ***********************/ -/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */ -#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */ -#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */ - -/* TWI_PRESCALE Masks */ -#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */ -#define TWI_ENA 0x0080 /* TWI Enable */ -#define SCCB 0x0200 /* SCCB Compatibility Enable */ - -/* TWI_SLAVE_CTL Masks */ -#define SEN 0x0001 /* Slave Enable */ -#define SADD_LEN 0x0002 /* Slave Address Length */ -#define STDVAL 0x0004 /* Slave Transmit Data Valid */ -#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ -#define GEN 0x0010 /* General Call Address Matching Enabled */ - -/* TWI_SLAVE_STAT Masks */ -#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ -#define GCALL 0x0002 /* General Call Indicator */ - -/* TWI_MASTER_CTL Masks */ -#define MEN 0x0001 /* Master Mode Enable */ -#define MADD_LEN 0x0002 /* Master Address Length */ -#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */ -#define FAST 0x0008 /* Use Fast Mode Timing Specs */ -#define STOP 0x0010 /* Issue Stop Condition */ -#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */ -#define DCNT 0x3FC0 /* Data Bytes To Transfer */ -#define SDAOVR 0x4000 /* Serial Data Override */ -#define SCLOVR 0x8000 /* Serial Clock Override */ - -/* TWI_MASTER_STAT Masks */ -#define MPROG 0x0001 /* Master Transfer In Progress */ -#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */ -#define ANAK 0x0004 /* Address Not Acknowledged */ -#define DNAK 0x0008 /* Data Not Acknowledged */ -#define BUFRDERR 0x0010 /* Buffer Read Error */ -#define BUFWRERR 0x0020 /* Buffer Write Error */ -#define SDASEN 0x0040 /* Serial Data Sense */ -#define SCLSEN 0x0080 /* Serial Clock Sense */ -#define BUSBUSY 0x0100 /* Bus Busy Indicator */ - -/* TWI_INT_SRC and TWI_INT_ENABLE Masks */ -#define SINIT 0x0001 /* Slave Transfer Initiated */ -#define SCOMP 0x0002 /* Slave Transfer Complete */ -#define SERR 0x0004 /* Slave Transfer Error */ -#define SOVF 0x0008 /* Slave Overflow */ -#define MCOMP 0x0010 /* Master Transfer Complete */ -#define MERR 0x0020 /* Master Transfer Error */ -#define XMTSERV 0x0040 /* Transmit FIFO Service */ -#define RCVSERV 0x0080 /* Receive FIFO Service */ - -/* TWI_FIFO_CTRL Masks */ -#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */ -#define RCVFLUSH 0x0002 /* Receive Buffer Flush */ -#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */ -#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */ - -/* TWI_FIFO_STAT Masks */ -#define XMTSTAT 0x0003 /* Transmit FIFO Status */ -#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */ -#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */ -#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */ - -#define RCVSTAT 0x000C /* Receive FIFO Status */ -#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */ -#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ -#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ /* ******************* PIN CONTROL REGISTER MASKS ************************/ /* PORT_MUX Masks */
diff --git a/arch/blackfin/mach-bf537/include/mach/defBF537.h b/arch/blackfin/mach-bf537/include/mach/defBF537.h index 3d471d7..e10332c 100644 --- a/arch/blackfin/mach-bf537/include/mach/defBF537.h +++ b/arch/blackfin/mach-bf537/include/mach/defBF537.h
@@ -1,7 +1,7 @@ /* * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF537_H
diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c index 85038f54..a4fce03 100644 --- a/arch/blackfin/mach-bf538/boards/ezkit.c +++ b/arch/blackfin/mach-bf538/boards/ezkit.c
@@ -718,6 +718,8 @@ }; #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -736,9 +738,13 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; -#if !defined(CONFIG_BF542) /* The BF542 only has 1 TWI */ +static const u16 bfin_twi1_pins[] = {P_TWI1_SCL, P_TWI1_SDA, 0}; + static struct resource bfin_twi1_resource[] = { [0] = { .start = TWI1_REGBASE,
diff --git a/arch/blackfin/mach-bf538/include/mach/anomaly.h b/arch/blackfin/mach-bf538/include/mach/anomaly.h index b6ca997..318d922 100644 --- a/arch/blackfin/mach-bf538/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf538/include/mach/anomaly.h
@@ -6,8 +6,7 @@ * DO NOT EDIT THIS FILE * * Copyright 2004-2011 Analog Devices Inc. - * Licensed under the ADI BSD license. - * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd + * Licensed under the Clear BSD license. */ /* This file should be up to date with:
diff --git a/arch/blackfin/mach-bf538/include/mach/defBF538.h b/arch/blackfin/mach-bf538/include/mach/defBF538.h index d27f81d..876a770 100644 --- a/arch/blackfin/mach-bf538/include/mach/defBF538.h +++ b/arch/blackfin/mach-bf538/include/mach/defBF538.h
@@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF538_H @@ -1746,80 +1746,4 @@ #define SDEASE 0x00000010 /* SDRAM EAB sticky error status - W1C */ #define BGSTAT 0x00000020 /* Bus granted */ - -/* ******************** TWO-WIRE INTERFACE (TWIx) MASKS ***********************/ -/* TWIx_CLKDIV Macros (Use: *pTWIx_CLKDIV = CLKLOW(x)|CLKHI(y); ) */ -#ifdef _MISRA_RULES -#define CLKLOW(x) ((x) & 0xFFu) /* Periods Clock Is Held Low */ -#define CLKHI(y) (((y)&0xFFu)<<0x8) /* Periods Before New Clock Low */ -#else -#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */ -#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */ -#endif /* _MISRA_RULES */ - -/* TWIx_PRESCALE Masks */ -#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */ -#define TWI_ENA 0x0080 /* TWI Enable */ -#define SCCB 0x0200 /* SCCB Compatibility Enable */ - -/* TWIx_SLAVE_CTRL Masks */ -#define SEN 0x0001 /* Slave Enable */ -#define SADD_LEN 0x0002 /* Slave Address Length */ -#define STDVAL 0x0004 /* Slave Transmit Data Valid */ -#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ -#define GEN 0x0010 /* General Call Adrress Matching Enabled */ - -/* TWIx_SLAVE_STAT Masks */ -#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ -#define GCALL 0x0002 /* General Call Indicator */ - -/* TWIx_MASTER_CTRL Masks */ -#define MEN 0x0001 /* Master Mode Enable */ -#define MADD_LEN 0x0002 /* Master Address Length */ -#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */ -#define FAST 0x0008 /* Use Fast Mode Timing Specs */ -#define STOP 0x0010 /* Issue Stop Condition */ -#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */ -#define DCNT 0x3FC0 /* Data Bytes To Transfer */ -#define SDAOVR 0x4000 /* Serial Data Override */ -#define SCLOVR 0x8000 /* Serial Clock Override */ - -/* TWIx_MASTER_STAT Masks */ -#define MPROG 0x0001 /* Master Transfer In Progress */ -#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */ -#define ANAK 0x0004 /* Address Not Acknowledged */ -#define DNAK 0x0008 /* Data Not Acknowledged */ -#define BUFRDERR 0x0010 /* Buffer Read Error */ -#define BUFWRERR 0x0020 /* Buffer Write Error */ -#define SDASEN 0x0040 /* Serial Data Sense */ -#define SCLSEN 0x0080 /* Serial Clock Sense */ -#define BUSBUSY 0x0100 /* Bus Busy Indicator */ - -/* TWIx_INT_SRC and TWIx_INT_ENABLE Masks */ -#define SINIT 0x0001 /* Slave Transfer Initiated */ -#define SCOMP 0x0002 /* Slave Transfer Complete */ -#define SERR 0x0004 /* Slave Transfer Error */ -#define SOVF 0x0008 /* Slave Overflow */ -#define MCOMP 0x0010 /* Master Transfer Complete */ -#define MERR 0x0020 /* Master Transfer Error */ -#define XMTSERV 0x0040 /* Transmit FIFO Service */ -#define RCVSERV 0x0080 /* Receive FIFO Service */ - -/* TWIx_FIFO_CTL Masks */ -#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */ -#define RCVFLUSH 0x0002 /* Receive Buffer Flush */ -#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */ -#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */ - -/* TWIx_FIFO_STAT Masks */ -#define XMTSTAT 0x0003 /* Transmit FIFO Status */ -#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */ -#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */ -#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */ - -#define RCVSTAT 0x000C /* Receive FIFO Status */ -#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */ -#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ -#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ - #endif
diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h index 8100bcd..199e871 100644 --- a/arch/blackfin/mach-bf538/include/mach/defBF539.h +++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h
@@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF539_H
diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c index 68af594..e925433 100644 --- a/arch/blackfin/mach-bf548/boards/cm_bf548.c +++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c
@@ -1007,6 +1007,8 @@ #endif /* spi master and devices */ #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -1025,9 +1027,14 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; #if !defined(CONFIG_BF542) /* The BF542 only has 1 TWI */ +static const u16 bfin_twi1_pins[] = {P_TWI1_SCL, P_TWI1_SDA, 0}; + static struct resource bfin_twi1_resource[] = { [0] = { .start = TWI1_REGBASE, @@ -1046,6 +1053,9 @@ .id = 1, .num_resources = ARRAY_SIZE(bfin_twi1_resource), .resource = bfin_twi1_resource, + .dev = { + .platform_data = &bfin_twi1_pins, + }, }; #endif #endif
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 4cadaf8..3bd75ba 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -165,6 +165,7 @@ .rotary_button_key = KEY_ENTER, .debounce = 10, /* 0..17 */ .mode = ROT_QUAD_ENC | ROT_DEBE, + .pm_wakeup = 1, }; static struct resource bfin_rotary_resources[] = { @@ -1251,6 +1252,8 @@ #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -1269,9 +1272,14 @@ .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, }; #if !defined(CONFIG_BF542) /* The BF542 only has 1 TWI */ +static const u16 bfin_twi1_pins[] = {P_TWI1_SCL, P_TWI1_SDA, 0}; + static struct resource bfin_twi1_resource[] = { [0] = { .start = TWI1_REGBASE, @@ -1290,6 +1298,9 @@ .id = 1, .num_resources = ARRAY_SIZE(bfin_twi1_resource), .resource = bfin_twi1_resource, + .dev = { + .platform_data = &bfin_twi1_pins, + }, }; #endif #endif
diff --git a/arch/blackfin/mach-bf548/include/mach/anomaly.h b/arch/blackfin/mach-bf548/include/mach/anomaly.h index ac96ee8..5b711d8 100644 --- a/arch/blackfin/mach-bf548/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf548/include/mach/anomaly.h
@@ -6,8 +6,7 @@ * DO NOT EDIT THIS FILE * * Copyright 2004-2011 Analog Devices Inc. - * Licensed under the ADI BSD license. - * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd + * Licensed under the Clear BSD license. */ /* This file should be up to date with:
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF542.h b/arch/blackfin/mach-bf548/include/mach/defBF542.h index 629bf21..5116157 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF542.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF542.h
@@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF542_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF544.h b/arch/blackfin/mach-bf548/include/mach/defBF544.h index bcccab3..329b2c5 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF544.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF544.h
@@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF544_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF547.h b/arch/blackfin/mach-bf548/include/mach/defBF547.h index 1fa41ec..e18de21 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF547.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF547.h
@@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF547_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF548.h b/arch/blackfin/mach-bf548/include/mach/defBF548.h index 3c7f1b6..27f2948 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF548.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF548.h
@@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF548_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF549.h b/arch/blackfin/mach-bf548/include/mach/defBF549.h index 9a45cb6..ac569fc 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF549.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF549.h
@@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF549_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h index 0867c2b..8f6e192 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
@@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF54X_H @@ -2062,115 +2062,6 @@ #define LOW_EVEN 0xff0000 /* Lower Limit for Even Bytes (Luma) */ #define HIGH_EVEN 0xff000000 /* Upper Limit for Even Bytes (Luma) */ -/* ************************************************ */ -/* The TWI bit masks fields are from the ADSP-BF538 */ -/* and they have not been verified as the final */ -/* ones for the Moab processors ... bz 1/19/2007 */ -/* ************************************************ */ - -/* Bit masks for TWIx_CONTROL */ - -#define PRESCALE 0x7f /* Prescale Value */ -#define TWI_ENA 0x80 /* TWI Enable */ -#define SCCB 0x200 /* Serial Camera Control Bus */ - -/* Bit maskes for TWIx_CLKDIV */ - -#define CLKLOW 0xff /* Clock Low */ -#define CLKHI 0xff00 /* Clock High */ - -/* Bit maskes for TWIx_SLAVE_CTL */ - -#define SEN 0x1 /* Slave Enable */ -#define STDVAL 0x4 /* Slave Transmit Data Valid */ -#define NAK 0x8 /* Not Acknowledge */ -#define GEN 0x10 /* General Call Enable */ - -/* Bit maskes for TWIx_SLAVE_ADDR */ - -#define SADDR 0x7f /* Slave Mode Address */ - -/* Bit maskes for TWIx_SLAVE_STAT */ - -#define SDIR 0x1 /* Slave Transfer Direction */ -#define GCALL 0x2 /* General Call */ - -/* Bit maskes for TWIx_MASTER_CTL */ - -#define MEN 0x1 /* Master Mode Enable */ -#define MDIR 0x4 /* Master Transfer Direction */ -#define FAST 0x8 /* Fast Mode */ -#define STOP 0x10 /* Issue Stop Condition */ -#define RSTART 0x20 /* Repeat Start */ -#define DCNT 0x3fc0 /* Data Transfer Count */ -#define SDAOVR 0x4000 /* Serial Data Override */ -#define SCLOVR 0x8000 /* Serial Clock Override */ - -/* Bit maskes for TWIx_MASTER_ADDR */ - -#define MADDR 0x7f /* Master Mode Address */ - -/* Bit maskes for TWIx_MASTER_STAT */ - -#define MPROG 0x1 /* Master Transfer in Progress */ -#define LOSTARB 0x2 /* Lost Arbitration */ -#define ANAK 0x4 /* Address Not Acknowledged */ -#define DNAK 0x8 /* Data Not Acknowledged */ -#define BUFRDERR 0x10 /* Buffer Read Error */ -#define BUFWRERR 0x20 /* Buffer Write Error */ -#define SDASEN 0x40 /* Serial Data Sense */ -#define SCLSEN 0x80 /* Serial Clock Sense */ -#define BUSBUSY 0x100 /* Bus Busy */ - -/* Bit maskes for TWIx_FIFO_CTL */ - -#define XMTFLUSH 0x1 /* Transmit Buffer Flush */ -#define RCVFLUSH 0x2 /* Receive Buffer Flush */ -#define XMTINTLEN 0x4 /* Transmit Buffer Interrupt Length */ -#define RCVINTLEN 0x8 /* Receive Buffer Interrupt Length */ - -/* Bit maskes for TWIx_FIFO_STAT */ - -#define XMTSTAT 0x3 /* Transmit FIFO Status */ -#define RCVSTAT 0xc /* Receive FIFO Status */ - -/* Bit maskes for TWIx_INT_MASK */ - -#define SINITM 0x1 /* Slave Transfer Initiated Interrupt Mask */ -#define SCOMPM 0x2 /* Slave Transfer Complete Interrupt Mask */ -#define SERRM 0x4 /* Slave Transfer Error Interrupt Mask */ -#define SOVFM 0x8 /* Slave Overflow Interrupt Mask */ -#define MCOMPM 0x10 /* Master Transfer Complete Interrupt Mask */ -#define MERRM 0x20 /* Master Transfer Error Interrupt Mask */ -#define XMTSERVM 0x40 /* Transmit FIFO Service Interrupt Mask */ -#define RCVSERVM 0x80 /* Receive FIFO Service Interrupt Mask */ - -/* Bit maskes for TWIx_INT_STAT */ - -#define SINIT 0x1 /* Slave Transfer Initiated */ -#define SCOMP 0x2 /* Slave Transfer Complete */ -#define SERR 0x4 /* Slave Transfer Error */ -#define SOVF 0x8 /* Slave Overflow */ -#define MCOMP 0x10 /* Master Transfer Complete */ -#define MERR 0x20 /* Master Transfer Error */ -#define XMTSERV 0x40 /* Transmit FIFO Service */ -#define RCVSERV 0x80 /* Receive FIFO Service */ - -/* Bit maskes for TWIx_XMT_DATA8 */ - -#define XMTDATA8 0xff /* Transmit FIFO 8-Bit Data */ - -/* Bit maskes for TWIx_XMT_DATA16 */ - -#define XMTDATA16 0xffff /* Transmit FIFO 16-Bit Data */ - -/* Bit maskes for TWIx_RCV_DATA8 */ - -#define RCVDATA8 0xff /* Receive FIFO 8-Bit Data */ - -/* Bit maskes for TWIx_RCV_DATA16 */ - -#define RCVDATA16 0xffff /* Receive FIFO 16-Bit Data */ /* ******************************************* */ /* MULTI BIT MACRO ENUMERATIONS */
diff --git a/arch/blackfin/mach-bf561/include/mach/anomaly.h b/arch/blackfin/mach-bf561/include/mach/anomaly.h index 836baee..72476ff 100644 --- a/arch/blackfin/mach-bf561/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf561/include/mach/anomaly.h
@@ -6,8 +6,7 @@ * DO NOT EDIT THIS FILE * * Copyright 2004-2011 Analog Devices Inc. - * Licensed under the ADI BSD license. - * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd + * Licensed under the Clear BSD license. */ /* This file should be up to date with:
diff --git a/arch/blackfin/mach-bf561/include/mach/defBF561.h b/arch/blackfin/mach-bf561/include/mach/defBF561.h index 5f0ac5a..9f21f76 100644 --- a/arch/blackfin/mach-bf561/include/mach/defBF561.h +++ b/arch/blackfin/mach-bf561/include/mach/defBF561.h
@@ -1,7 +1,7 @@ /* * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the ADI BSD license or the GPL-2 (or later) + * Licensed under the Clear BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF561_H
diff --git a/arch/blackfin/mach-bf609/Kconfig b/arch/blackfin/mach-bf609/Kconfig new file mode 100644 index 0000000..2cb7272 --- /dev/null +++ b/arch/blackfin/mach-bf609/Kconfig
@@ -0,0 +1,56 @@ +config BF60x + def_bool y + depends on (BF609) + select IRQ_PREFLOW_FASTEOI + +if (BF60x) + +source "arch/blackfin/mach-bf609/boards/Kconfig" + +menu "BF609 Specific Configuration" + +comment "Pin Interrupt to Port Assignment" +menu "Assignment" + +config PINTx_REASSIGN + bool "Reprogram PINT Assignment" + default y + help + The interrupt assignment registers controls the pin-to-interrupt + assignment in a byte-wide manner. Each option allows you to select + a set of pins (High/Low Byte) of an specific Port being mapped + to one of the four PIN Interrupts IRQ_PINTx. + + You shouldn't change any of these unless you know exactly what you're doing. + Please consult the Blackfin BF60x Processor Hardware Reference Manual. + +config PINT0_ASSIGN + hex "PINT0_ASSIGN" + depends on PINTx_REASSIGN + default 0x00000101 +config PINT1_ASSIGN + hex "PINT1_ASSIGN" + depends on PINTx_REASSIGN + default 0x00000101 +config PINT2_ASSIGN + hex "PINT2_ASSIGN" + depends on PINTx_REASSIGN + default 0x00000101 +config PINT3_ASSIGN + hex "PINT3_ASSIGN" + depends on PINTx_REASSIGN + default 0x00000101 +config PINT4_ASSIGN + hex "PINT3_ASSIGN" + depends on PINTx_REASSIGN + default 0x00000101 +config PINT5_ASSIGN + hex "PINT3_ASSIGN" + depends on PINTx_REASSIGN + default 0x00000101 + +endmenu + +endmenu + +endif
diff --git a/arch/blackfin/mach-bf609/Makefile b/arch/blackfin/mach-bf609/Makefile new file mode 100644 index 0000000..2a27f817 --- /dev/null +++ b/arch/blackfin/mach-bf609/Makefile
@@ -0,0 +1,6 @@ +# +# arch/blackfin/mach-bf609/Makefile +# + +obj-y := dma.o clock.o +obj-$(CONFIG_PM) += pm.o hibernate.o
diff --git a/arch/blackfin/mach-bf609/boards/Kconfig b/arch/blackfin/mach-bf609/boards/Kconfig new file mode 100644 index 0000000..30e8b6b --- /dev/null +++ b/arch/blackfin/mach-bf609/boards/Kconfig
@@ -0,0 +1,12 @@ +choice + prompt "System type" + default BFIN609_EZKIT + help + Select your board! + +config BFIN609_EZKIT + bool "BF609-EZKIT" + help + BFIN609-EZKIT board support. + +endchoice
diff --git a/arch/blackfin/mach-bf609/boards/Makefile b/arch/blackfin/mach-bf609/boards/Makefile new file mode 100644 index 0000000..11f98b0 --- /dev/null +++ b/arch/blackfin/mach-bf609/boards/Makefile
@@ -0,0 +1,5 @@ +# +# arch/blackfin/mach-bf609/boards/Makefile +# + +obj-$(CONFIG_BFIN609_EZKIT) += ezkit.o
diff --git a/arch/blackfin/mach-bf609/boards/ezkit.c b/arch/blackfin/mach-bf609/boards/ezkit.c new file mode 100644 index 0000000..ac64f47 --- /dev/null +++ b/arch/blackfin/mach-bf609/boards/ezkit.c
@@ -0,0 +1,1340 @@ +/* + * Copyright 2004-2009 Analog Devices Inc. + * 2005 National ICT Australia (NICTA) + * Aidan Williams <aidan@nicta.com.au> + * + * Licensed under the GPL-2 or later. + */ + +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/spi/spi.h> +#include <linux/spi/flash.h> +#include <linux/irq.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/usb/musb.h> +#include <asm/bfin6xx_spi.h> +#include <asm/dma.h> +#include <asm/gpio.h> +#include <asm/nand.h> +#include <asm/dpmc.h> +#include <asm/portmux.h> +#include <asm/bfin_sdh.h> +#include <linux/input.h> +#include <linux/spi/ad7877.h> + +/* + * Name the Board for the /proc/cpuinfo + */ +const char bfin_board_name[] = "ADI BF609-EZKIT"; + +/* + * Driver needs to know address, irq and flag pin. + */ + +#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) +#include <linux/usb/isp1760.h> +static struct resource bfin_isp1760_resources[] = { + [0] = { + .start = 0x2C0C0000, + .end = 0x2C0C0000 + 0xfffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_PG7, + .end = IRQ_PG7, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct isp1760_platform_data isp1760_priv = { + .is_isp1761 = 0, + .bus_width_16 = 1, + .port1_otg = 0, + .analog_oc = 0, + .dack_polarity_high = 0, + .dreq_polarity_high = 0, +}; + +static struct platform_device bfin_isp1760_device = { + .name = "isp1760", + .id = 0, + .dev = { + .platform_data = &isp1760_priv, + }, + .num_resources = ARRAY_SIZE(bfin_isp1760_resources), + .resource = bfin_isp1760_resources, +}; +#endif + +#if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE) +#include <asm/bfin_rotary.h> + +static struct bfin_rotary_platform_data bfin_rotary_data = { + /*.rotary_up_key = KEY_UP,*/ + /*.rotary_down_key = KEY_DOWN,*/ + .rotary_rel_code = REL_WHEEL, + .rotary_button_key = KEY_ENTER, + .debounce = 10, /* 0..17 */ + .mode = ROT_QUAD_ENC | ROT_DEBE, +}; + +static struct resource bfin_rotary_resources[] = { + { + .start = IRQ_CNT, + .end = IRQ_CNT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_rotary_device = { + .name = "bfin-rotary", + .id = -1, + .num_resources = ARRAY_SIZE(bfin_rotary_resources), + .resource = bfin_rotary_resources, + .dev = { + .platform_data = &bfin_rotary_data, + }, +}; +#endif + +#if defined(CONFIG_STMMAC_ETH) || defined(CONFIG_STMMAC_ETH_MODULE) +#include <linux/stmmac.h> + +static unsigned short pins[] = P_RMII0; + +static struct stmmac_mdio_bus_data phy_private_data = { + .bus_id = 0, + .phy_mask = 1, +}; + +static struct plat_stmmacenet_data eth_private_data = { + .bus_id = 0, + .enh_desc = 1, + .phy_addr = 1, + .mdio_bus_data = &phy_private_data, +}; + +static struct platform_device bfin_eth_device = { + .name = "stmmaceth", + .id = 0, + .num_resources = 2, + .resource = (struct resource[]) { + { + .start = EMAC0_MACCFG, + .end = EMAC0_MACCFG + 0x1274, + .flags = IORESOURCE_MEM, + }, + { + .name = "macirq", + .start = IRQ_EMAC0_STAT, + .end = IRQ_EMAC0_STAT, + .flags = IORESOURCE_IRQ, + }, + }, + .dev = { + .power.can_wakeup = 1, + .platform_data = ð_private_data, + } +}; +#endif + +#if defined(CONFIG_INPUT_ADXL34X) || defined(CONFIG_INPUT_ADXL34X_MODULE) +#include <linux/input/adxl34x.h> +static const struct adxl34x_platform_data adxl34x_info = { + .x_axis_offset = 0, + .y_axis_offset = 0, + .z_axis_offset = 0, + .tap_threshold = 0x31, + .tap_duration = 0x10, + .tap_latency = 0x60, + .tap_window = 0xF0, + .tap_axis_control = ADXL_TAP_X_EN | ADXL_TAP_Y_EN | ADXL_TAP_Z_EN, + .act_axis_control = 0xFF, + .activity_threshold = 5, + .inactivity_threshold = 3, + .inactivity_time = 4, + .free_fall_threshold = 0x7, + .free_fall_time = 0x20, + .data_rate = 0x8, + .data_range = ADXL_FULL_RES, + + .ev_type = EV_ABS, + .ev_code_x = ABS_X, /* EV_REL */ + .ev_code_y = ABS_Y, /* EV_REL */ + .ev_code_z = ABS_Z, /* EV_REL */ + + .ev_code_tap = {BTN_TOUCH, BTN_TOUCH, BTN_TOUCH}, /* EV_KEY x,y,z */ + +/* .ev_code_ff = KEY_F,*/ /* EV_KEY */ +/* .ev_code_act_inactivity = KEY_A,*/ /* EV_KEY */ + .power_mode = ADXL_AUTO_SLEEP | ADXL_LINK, + .fifo_mode = ADXL_FIFO_STREAM, + .orientation_enable = ADXL_EN_ORIENTATION_3D, + .deadzone_angle = ADXL_DEADZONE_ANGLE_10p8, + .divisor_length = ADXL_LP_FILTER_DIVISOR_16, + /* EV_KEY {+Z, +Y, +X, -X, -Y, -Z} */ + .ev_codes_orient_3d = {BTN_Z, BTN_Y, BTN_X, BTN_A, BTN_B, BTN_C}, +}; +#endif + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) +static struct platform_device rtc_device = { + .name = "rtc-bfin", + .id = -1, +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { + { + .start = UART0_REVID, + .end = UART0_RXDIV+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_UART0_TX, + .end = IRQ_UART0_TX, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_STAT, + .end = IRQ_UART0_STAT, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +#ifdef CONFIG_BFIN_UART0_CTSRTS + { /* CTS pin -- 0 means not supported */ + .start = GPIO_PD10, + .end = GPIO_PD10, + .flags = IORESOURCE_IO, + }, + { /* RTS pin -- 0 means not supported */ + .start = GPIO_PD9, + .end = GPIO_PD9, + .flags = IORESOURCE_IO, + }, +#endif +}; + +static unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, +#ifdef CONFIG_BFIN_UART0_CTSRTS + P_UART0_RTS, P_UART0_CTS, +#endif + 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 +static struct resource bfin_uart1_resources[] = { + { + .start = UART1_REVID, + .end = UART1_RXDIV+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_UART1_TX, + .end = IRQ_UART1_TX, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_STAT, + .end = IRQ_UART1_STAT, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX, + .flags = IORESOURCE_DMA, + }, +#ifdef CONFIG_BFIN_UART1_CTSRTS + { /* CTS pin -- 0 means not supported */ + .start = GPIO_PG13, + .end = GPIO_PG13, + .flags = IORESOURCE_IO, + }, + { /* RTS pin -- 0 means not supported */ + .start = GPIO_PG10, + .end = GPIO_PG10, + .flags = IORESOURCE_IO, + }, +#endif +}; + +static unsigned short bfin_uart1_peripherals[] = { + P_UART1_TX, P_UART1_RX, +#ifdef CONFIG_BFIN_UART1_CTSRTS + P_UART1_RTS, P_UART1_CTS, +#endif + 0 +}; + +static struct platform_device bfin_uart1_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart1_resources), + .resource = bfin_uart1_resources, + .dev = { + .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ + }, +}; +#endif +#endif + +#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) +#ifdef CONFIG_BFIN_SIR0 +static struct resource bfin_sir0_resources[] = { + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_UART0_TX, + .end = IRQ_UART0_TX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX+1, + .flags = IORESOURCE_DMA, + }, +}; +static struct platform_device bfin_sir0_device = { + .name = "bfin_sir", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_sir0_resources), + .resource = bfin_sir0_resources, +}; +#endif +#ifdef CONFIG_BFIN_SIR1 +static struct resource bfin_sir1_resources[] = { + { + .start = 0xFFC02000, + .end = 0xFFC020FF, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_UART1_TX, + .end = IRQ_UART1_TX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX+1, + .flags = IORESOURCE_DMA, + }, +}; +static struct platform_device bfin_sir1_device = { + .name = "bfin_sir", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_sir1_resources), + .resource = bfin_sir1_resources, +}; +#endif +#endif + +#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) +static struct resource musb_resources[] = { + [0] = { + .start = 0xFFCC1000, + .end = 0xFFCC1398, + .flags = IORESOURCE_MEM, + }, + [1] = { /* general IRQ */ + .start = IRQ_USB_STAT, + .end = IRQ_USB_STAT, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + .name = "mc" + }, + [2] = { /* DMA IRQ */ + .start = IRQ_USB_DMA, + .end = IRQ_USB_DMA, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + .name = "dma" + }, +}; + +static struct musb_hdrc_config musb_config = { + .multipoint = 1, + .dyn_fifo = 0, + .dma = 1, + .num_eps = 16, + .dma_channels = 8, + .clkin = 48, /* musb CLKIN in MHZ */ +}; + +static struct musb_hdrc_platform_data musb_plat = { +#if defined(CONFIG_USB_MUSB_HDRC) && defined(CONFIG_USB_GADGET_MUSB_HDRC) + .mode = MUSB_OTG, +#elif defined(CONFIG_USB_MUSB_HDRC) + .mode = MUSB_HOST, +#elif defined(CONFIG_USB_GADGET_MUSB_HDRC) + .mode = MUSB_PERIPHERAL, +#endif + .config = &musb_config, +}; + +static u64 musb_dmamask = ~(u32)0; + +static struct platform_device musb_device = { + .name = "musb-blackfin", + .id = 0, + .dev = { + .dma_mask = &musb_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &musb_plat, + }, + .num_resources = ARRAY_SIZE(musb_resources), + .resource = musb_resources, +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +static unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0 +}; + +static struct platform_device bfin_sport0_uart_device = { + .name = "bfin-sport-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +static unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0 +}; + +static struct platform_device bfin_sport1_uart_device = { + .name = "bfin-sport-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART +static struct resource bfin_sport2_uart_resources[] = { + { + .start = SPORT2_TCR1, + .end = SPORT2_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT2_RX, + .end = IRQ_SPORT2_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT2_ERROR, + .end = IRQ_SPORT2_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +static unsigned short bfin_sport2_peripherals[] = { + P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS, + P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0 +}; + +static struct platform_device bfin_sport2_uart_device = { + .name = "bfin-sport-uart", + .id = 2, + .num_resources = ARRAY_SIZE(bfin_sport2_uart_resources), + .resource = bfin_sport2_uart_resources, + .dev = { + .platform_data = &bfin_sport2_peripherals, /* Passed to driver */ + }, +}; +#endif +#endif + +#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) + +static unsigned short bfin_can0_peripherals[] = { + P_CAN0_RX, P_CAN0_TX, 0 +}; + +static struct resource bfin_can0_resources[] = { + { + .start = 0xFFC00A00, + .end = 0xFFC00FFF, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_CAN0_RX, + .end = IRQ_CAN0_RX, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_CAN0_TX, + .end = IRQ_CAN0_TX, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_CAN0_STAT, + .end = IRQ_CAN0_STAT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_can0_device = { + .name = "bfin_can", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_can0_resources), + .resource = bfin_can0_resources, + .dev = { + .platform_data = &bfin_can0_peripherals, /* Passed to driver */ + }, +}; + +#endif + +#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) +static struct mtd_partition partition_info[] = { + { + .name = "bootloader(nand)", + .offset = 0, + .size = 0x80000, + }, { + .name = "linux kernel(nand)", + .offset = MTDPART_OFS_APPEND, + .size = 4 * 1024 * 1024, + }, + { + .name = "file system(nand)", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct bf5xx_nand_platform bfin_nand_platform = { + .data_width = NFC_NWIDTH_8, + .partitions = partition_info, + .nr_partitions = ARRAY_SIZE(partition_info), + .rd_dly = 3, + .wr_dly = 3, +}; + +static struct resource bfin_nand_resources[] = { + { + .start = 0xFFC03B00, + .end = 0xFFC03B4F, + .flags = IORESOURCE_MEM, + }, + { + .start = CH_NFC, + .end = CH_NFC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_nand_device = { + .name = "bfin-nand", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_nand_resources), + .resource = bfin_nand_resources, + .dev = { + .platform_data = &bfin_nand_platform, + }, +}; +#endif + +#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE) + +static struct bfin_sd_host bfin_sdh_data = { + .dma_chan = CH_RSI, + .irq_int0 = IRQ_RSI_INT0, + .pin_req = {P_RSI_DATA0, P_RSI_DATA1, P_RSI_DATA2, P_RSI_DATA3, P_RSI_CMD, P_RSI_CLK, 0}, +}; + +static struct platform_device bfin_sdh_device = { + .name = "bfin-sdh", + .id = 0, + .dev = { + .platform_data = &bfin_sdh_data, + }, +}; +#endif + +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition ezkit_partitions[] = { + { + .name = "bootloader(nor)", + .size = 0x80000, + .offset = 0, + }, { + .name = "linux kernel(nor)", + .size = 0x400000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "file system(nor)", + .size = 0x1000000 - 0x80000 - 0x400000, + .offset = MTDPART_OFS_APPEND, + }, +}; + +int bf609_nor_flash_init(struct platform_device *dev) +{ +#define CONFIG_SMC_GCTL_VAL 0x00000010 + const unsigned short pins[] = { + P_A3, P_A4, P_A5, P_A6, P_A7, P_A8, P_A9, P_A10, P_A11, P_A12, + P_A13, P_A14, P_A15, P_A16, P_A17, P_A18, P_A19, P_A20, P_A21, + P_A22, P_A23, P_A24, P_A25, P_NORCK, 0, + }; + + peripheral_request_list(pins, "smc0"); + + bfin_write32(SMC_GCTL, CONFIG_SMC_GCTL_VAL); + bfin_write32(SMC_B0CTL, 0x01002011); + bfin_write32(SMC_B0TIM, 0x08170977); + bfin_write32(SMC_B0ETIM, 0x00092231); + return 0; +} + +static struct physmap_flash_data ezkit_flash_data = { + .width = 2, + .parts = ezkit_partitions, + .init = bf609_nor_flash_init, + .nr_parts = ARRAY_SIZE(ezkit_partitions), +}; + +static struct resource ezkit_flash_resource = { + .start = 0xb0000000, + .end = 0xb0ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ezkit_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &ezkit_flash_data, + }, + .num_resources = 1, + .resource = &ezkit_flash_resource, +}; +#endif + +#if defined(CONFIG_MTD_M25P80) \ + || defined(CONFIG_MTD_M25P80_MODULE) +/* SPI flash chip (w25q32) */ +static struct mtd_partition bfin_spi_flash_partitions[] = { + { + .name = "bootloader(spi)", + .size = 0x00080000, + .offset = 0, + .mask_flags = MTD_CAP_ROM + }, { + .name = "linux kernel(spi)", + .size = 0x00180000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "file system(spi)", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct flash_platform_data bfin_spi_flash_data = { + .name = "m25p80", + .parts = bfin_spi_flash_partitions, + .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), + .type = "w25q32", +}; + +static struct bfin6xx_spi_chip spi_flash_chip_info = { + .enable_dma = true, /* use dma transfer with this chip*/ +}; +#endif + +#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) +static struct bfin6xx_spi_chip spidev_chip_info = { + .enable_dma = true, +}; +#endif + +#if defined(CONFIG_SND_BF6XX_I2S) || defined(CONFIG_SND_BF6XX_I2S_MODULE) +static struct platform_device bfin_i2s_pcm = { + .name = "bfin-i2s-pcm-audio", + .id = -1, +}; +#endif + +#if defined(CONFIG_SND_BF6XX_SOC_I2S) || \ + defined(CONFIG_SND_BF6XX_SOC_I2S_MODULE) +#include <asm/bfin_sport3.h> +static struct resource bfin_snd_resources[] = { + { + .start = SPORT0_CTL_A, + .end = SPORT0_CTL_A, + .flags = IORESOURCE_MEM, + }, + { + .start = SPORT0_CTL_B, + .end = SPORT0_CTL_B, + .flags = IORESOURCE_MEM, + }, + { + .start = CH_SPORT0_TX, + .end = CH_SPORT0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_SPORT0_RX, + .end = CH_SPORT0_RX, + .flags = IORESOURCE_DMA, + }, + { + .start = IRQ_SPORT0_TX_STAT, + .end = IRQ_SPORT0_TX_STAT, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_RX_STAT, + .end = IRQ_SPORT0_RX_STAT, + .flags = IORESOURCE_IRQ, + }, +}; + +static const unsigned short bfin_snd_pin[] = { + P_SPORT0_ACLK, P_SPORT0_AFS, P_SPORT0_AD0, P_SPORT0_BCLK, + P_SPORT0_BFS, P_SPORT0_BD0, 0, +}; + +static struct bfin_snd_platform_data bfin_snd_data = { + .pin_req = bfin_snd_pin, +}; + +static struct platform_device bfin_i2s = { + .name = "bfin-i2s", + .num_resources = ARRAY_SIZE(bfin_snd_resources), + .resource = bfin_snd_resources, + .dev = { + .platform_data = &bfin_snd_data, + }, +}; +#endif + +#if defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61) || \ + defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61_MODULE) +static struct platform_device adau1761_device = { + .name = "bfin-eval-adau1x61", +}; +#endif + +#if defined(CONFIG_SND_SOC_ADAU1761) || defined(CONFIG_SND_SOC_ADAU1761_MODULE) +#include <sound/adau17x1.h> +static struct adau1761_platform_data adau1761_info = { + .lineout_mode = ADAU1761_OUTPUT_MODE_LINE, + .headphone_mode = ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS, +}; +#endif + +#if defined(CONFIG_VIDEO_BLACKFIN_CAPTURE) \ + || defined(CONFIG_VIDEO_BLACKFIN_CAPTURE_MODULE) +#include <linux/videodev2.h> +#include <media/blackfin/bfin_capture.h> +#include <media/blackfin/ppi.h> + +static const unsigned short ppi_req[] = { + P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, + P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7, + P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, + 0, +}; + +static const struct ppi_info ppi_info = { + .type = PPI_TYPE_EPPI3, + .dma_ch = CH_EPPI0_CH0, + .irq_err = IRQ_EPPI0_STAT, + .base = (void __iomem *)EPPI0_STAT, + .pin_req = ppi_req, +}; + +#if defined(CONFIG_VIDEO_VS6624) \ + || defined(CONFIG_VIDEO_VS6624_MODULE) +static struct v4l2_input vs6624_inputs[] = { + { + .index = 0, + .name = "Camera", + .type = V4L2_INPUT_TYPE_CAMERA, + .std = V4L2_STD_UNKNOWN, + }, +}; + +static struct bcap_route vs6624_routes[] = { + { + .input = 0, + .output = 0, + }, +}; + +static const unsigned vs6624_ce_pin = GPIO_PD1; + +static struct bfin_capture_config bfin_capture_data = { + .card_name = "BF609", + .inputs = vs6624_inputs, + .num_inputs = ARRAY_SIZE(vs6624_inputs), + .routes = vs6624_routes, + .i2c_adapter_id = 0, + .board_info = { + .type = "vs6624", + .addr = 0x10, + .platform_data = (void *)&vs6624_ce_pin, + }, + .ppi_info = &ppi_info, + .ppi_control = (PACK_EN | DLEN_8 | EPPI_CTL_FS1HI_FS2HI + | EPPI_CTL_POLC3 | EPPI_CTL_SYNC2 | EPPI_CTL_NON656), + .blank_clocks = 8, +}; +#endif + +static struct platform_device bfin_capture_device = { + .name = "bfin_capture", + .dev = { + .platform_data = &bfin_capture_data, + }, +}; +#endif + +#if defined(CONFIG_BFIN_CRC) +#define BFIN_CRC_NAME "bfin-crc" + +static struct resource bfin_crc0_resources[] = { + { + .start = REG_CRC0_CTL, + .end = REG_CRC0_REVID+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_CRC0_DCNTEXP, + .end = IRQ_CRC0_DCNTEXP, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_MEM_STREAM0_SRC_CRC0, + .end = CH_MEM_STREAM0_SRC_CRC0, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_MEM_STREAM0_DEST_CRC0, + .end = CH_MEM_STREAM0_DEST_CRC0, + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device bfin_crc0_device = { + .name = BFIN_CRC_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(bfin_crc0_resources), + .resource = bfin_crc0_resources, +}; + +static struct resource bfin_crc1_resources[] = { + { + .start = REG_CRC1_CTL, + .end = REG_CRC1_REVID+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_CRC1_DCNTEXP, + .end = IRQ_CRC1_DCNTEXP, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_MEM_STREAM1_SRC_CRC1, + .end = CH_MEM_STREAM1_SRC_CRC1, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_MEM_STREAM1_DEST_CRC1, + .end = CH_MEM_STREAM1_DEST_CRC1, + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device bfin_crc1_device = { + .name = BFIN_CRC_NAME, + .id = 1, + .num_resources = ARRAY_SIZE(bfin_crc1_resources), + .resource = bfin_crc1_resources, +}; +#endif + +#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) +static const struct ad7877_platform_data bfin_ad7877_ts_info = { + .model = 7877, + .vref_delay_usecs = 50, /* internal, no capacitor */ + .x_plate_ohms = 419, + .y_plate_ohms = 486, + .pressure_max = 1000, + .pressure_min = 0, + .stopacq_polarity = 1, + .first_conversion_delay = 3, + .acquisition_time = 1, + .averaging = 1, + .pen_down_acc_interval = 1, +}; +#endif + +static struct spi_board_info bfin_spi_board_info[] __initdata = { +#if defined(CONFIG_MTD_M25P80) \ + || defined(CONFIG_MTD_M25P80_MODULE) + { + /* the modalias must be the same as spi device driver name */ + .modalias = "m25p80", /* Name of spi_driver for this device */ + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, /* Framework bus number */ + .chip_select = 1, /* SPI_SSEL1*/ + .platform_data = &bfin_spi_flash_data, + .controller_data = &spi_flash_chip_info, + .mode = SPI_MODE_3, + }, +#endif +#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) + { + .modalias = "ad7877", + .platform_data = &bfin_ad7877_ts_info, + .irq = IRQ_PB4, /* old boards (<=Rev 1.3) use IRQ_PJ11 */ + .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 2, + }, +#endif +#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) + { + .modalias = "spidev", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 1, + .controller_data = &spidev_chip_info, + }, +#endif +#if defined(CONFIG_INPUT_ADXL34X_SPI) || defined(CONFIG_INPUT_ADXL34X_SPI_MODULE) + { + .modalias = "adxl34x", + .platform_data = &adxl34x_info, + .irq = IRQ_PC5, + .max_speed_hz = 5000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 2, + .mode = SPI_MODE_3, + }, +#endif +}; +#if defined(CONFIG_SPI_BFIN6XX) || defined(CONFIG_SPI_BFIN6XX_MODULE) +/* SPI (0) */ +static struct resource bfin_spi0_resource[] = { + { + .start = SPI0_REGBASE, + .end = SPI0_REGBASE + 0xFF, + .flags = IORESOURCE_MEM, + }, + { + .start = CH_SPI0_TX, + .end = CH_SPI0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_SPI0_RX, + .end = CH_SPI0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +/* SPI (1) */ +static struct resource bfin_spi1_resource[] = { + { + .start = SPI1_REGBASE, + .end = SPI1_REGBASE + 0xFF, + .flags = IORESOURCE_MEM, + }, + { + .start = CH_SPI1_TX, + .end = CH_SPI1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_SPI1_RX, + .end = CH_SPI1_RX, + .flags = IORESOURCE_DMA, + }, + +}; + +/* SPI controller data */ +static struct bfin6xx_spi_master bf60x_spi_master_info0 = { + .num_chipselect = 4, + .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0}, +}; + +static struct platform_device bf60x_spi_master0 = { + .name = "bfin-spi", + .id = 0, /* Bus number */ + .num_resources = ARRAY_SIZE(bfin_spi0_resource), + .resource = bfin_spi0_resource, + .dev = { + .platform_data = &bf60x_spi_master_info0, /* Passed to driver */ + }, +}; + +static struct bfin6xx_spi_master bf60x_spi_master_info1 = { + .num_chipselect = 4, + .pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0}, +}; + +static struct platform_device bf60x_spi_master1 = { + .name = "bfin-spi", + .id = 1, /* Bus number */ + .num_resources = ARRAY_SIZE(bfin_spi1_resource), + .resource = bfin_spi1_resource, + .dev = { + .platform_data = &bf60x_spi_master_info1, /* Passed to driver */ + }, +}; +#endif /* spi master and devices */ + +#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; + +static struct resource bfin_twi0_resource[] = { + [0] = { + .start = TWI0_CLKDIV, + .end = TWI0_CLKDIV + 0xFF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TWI0, + .end = IRQ_TWI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device i2c_bfin_twi0_device = { + .name = "i2c-bfin-twi", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_twi0_resource), + .resource = bfin_twi0_resource, + .dev = { + .platform_data = &bfin_twi0_pins, + }, +}; + +static const u16 bfin_twi1_pins[] = {P_TWI1_SCL, P_TWI1_SDA, 0}; + +static struct resource bfin_twi1_resource[] = { + [0] = { + .start = TWI1_CLKDIV, + .end = TWI1_CLKDIV + 0xFF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TWI1, + .end = IRQ_TWI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device i2c_bfin_twi1_device = { + .name = "i2c-bfin-twi", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_twi1_resource), + .resource = bfin_twi1_resource, + .dev = { + .platform_data = &bfin_twi1_pins, + }, +}; +#endif + +static struct i2c_board_info __initdata bfin_i2c_board_info0[] = { +#if defined(CONFIG_INPUT_ADXL34X_I2C) || defined(CONFIG_INPUT_ADXL34X_I2C_MODULE) + { + I2C_BOARD_INFO("adxl34x", 0x53), + .irq = IRQ_PC5, + .platform_data = (void *)&adxl34x_info, + }, +#endif +#if defined(CONFIG_SND_SOC_ADAU1761) || defined(CONFIG_SND_SOC_ADAU1761_MODULE) + { + I2C_BOARD_INFO("adau1761", 0x38), + .platform_data = (void *)&adau1761_info + }, +#endif +}; + +static struct i2c_board_info __initdata bfin_i2c_board_info1[] = { +}; + +static const unsigned int cclk_vlev_datasheet[] = +{ +/* + * Internal VLEV BF54XSBBC1533 + ****temporarily using these values until data sheet is updated + */ + VRPAIR(VLEV_085, 150000000), + VRPAIR(VLEV_090, 250000000), + VRPAIR(VLEV_110, 276000000), + VRPAIR(VLEV_115, 301000000), + VRPAIR(VLEV_120, 525000000), + VRPAIR(VLEV_125, 550000000), + VRPAIR(VLEV_130, 600000000), +}; + +static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { + .tuple_tab = cclk_vlev_datasheet, + .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), + .vr_settling_time = 25 /* us */, +}; + +static struct platform_device bfin_dpmc = { + .name = "bfin dpmc", + .dev = { + .platform_data = &bfin_dmpc_vreg_data, + }, +}; + +static struct platform_device *ezkit_devices[] __initdata = { + + &bfin_dpmc, + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) + &rtc_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#endif + +#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) +#ifdef CONFIG_BFIN_SIR0 + &bfin_sir0_device, +#endif +#ifdef CONFIG_BFIN_SIR1 + &bfin_sir1_device, +#endif +#endif + +#if defined(CONFIG_STMMAC_ETH) || defined(CONFIG_STMMAC_ETH_MODULE) + &bfin_eth_device, +#endif + +#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) + &musb_device, +#endif + +#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) + &bfin_isp1760_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART + &bfin_sport2_uart_device, +#endif +#endif + +#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) + &bfin_can0_device, +#endif + +#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) + &bfin_nand_device, +#endif + +#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE) + &bfin_sdh_device, +#endif + +#if defined(CONFIG_SPI_BFIN6XX) || defined(CONFIG_SPI_BFIN6XX_MODULE) + &bf60x_spi_master0, + &bf60x_spi_master1, +#endif + +#if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE) + &bfin_rotary_device, +#endif + +#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) + &i2c_bfin_twi0_device, +#if !defined(CONFIG_BF542) + &i2c_bfin_twi1_device, +#endif +#endif + +#if defined(CONFIG_BFIN_CRC) + &bfin_crc0_device, + &bfin_crc1_device, +#endif + +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) + &bfin_device_gpiokeys, +#endif + +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) + &ezkit_flash_device, +#endif +#if defined(CONFIG_SND_BF6XX_I2S) || defined(CONFIG_SND_BF6XX_I2S_MODULE) + &bfin_i2s_pcm, +#endif +#if defined(CONFIG_SND_BF6XX_SOC_I2S) || \ + defined(CONFIG_SND_BF6XX_SOC_I2S_MODULE) + &bfin_i2s, +#endif +#if defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61) || \ + defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61_MODULE) + &adau1761_device, +#endif +#if defined(CONFIG_VIDEO_BLACKFIN_CAPTURE) \ + || defined(CONFIG_VIDEO_BLACKFIN_CAPTURE_MODULE) + &bfin_capture_device, +#endif +}; + +static int __init ezkit_init(void) +{ + printk(KERN_INFO "%s(): registering device resources\n", __func__); + + i2c_register_board_info(0, bfin_i2c_board_info0, + ARRAY_SIZE(bfin_i2c_board_info0)); + i2c_register_board_info(1, bfin_i2c_board_info1, + ARRAY_SIZE(bfin_i2c_board_info1)); + +#if defined(CONFIG_STMMAC_ETH) || defined(CONFIG_STMMAC_ETH_MODULE) + if (!peripheral_request_list(pins, "emac0")) + printk(KERN_ERR "%s(): request emac pins failed\n", __func__); +#endif + + platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices)); + + spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); + + return 0; +} + +arch_initcall(ezkit_init); + +static struct platform_device *ezkit_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART + &bfin_sport2_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(ezkit_early_devices, + ARRAY_SIZE(ezkit_early_devices)); +}
diff --git a/arch/blackfin/mach-bf609/clock.c b/arch/blackfin/mach-bf609/clock.c new file mode 100644 index 0000000..7f8f529 --- /dev/null +++ b/arch/blackfin/mach-bf609/clock.c
@@ -0,0 +1,390 @@ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/string.h> +#include <linux/clk.h> +#include <linux/mutex.h> +#include <linux/spinlock.h> +#include <linux/debugfs.h> +#include <linux/device.h> +#include <linux/init.h> +#include <linux/timer.h> +#include <linux/io.h> +#include <linux/seq_file.h> +#include <linux/clkdev.h> + +#include <asm/clocks.h> + +#define CGU0_CTL_DF (1 << 0) + +#define CGU0_CTL_MSEL_SHIFT 8 +#define CGU0_CTL_MSEL_MASK (0x7f << 8) + +#define CGU0_STAT_PLLEN (1 << 0) +#define CGU0_STAT_PLLBP (1 << 1) +#define CGU0_STAT_PLLLK (1 << 2) +#define CGU0_STAT_CLKSALGN (1 << 3) +#define CGU0_STAT_CCBF0 (1 << 4) +#define CGU0_STAT_CCBF1 (1 << 5) +#define CGU0_STAT_SCBF0 (1 << 6) +#define CGU0_STAT_SCBF1 (1 << 7) +#define CGU0_STAT_DCBF (1 << 8) +#define CGU0_STAT_OCBF (1 << 9) +#define CGU0_STAT_ADDRERR (1 << 16) +#define CGU0_STAT_LWERR (1 << 17) +#define CGU0_STAT_DIVERR (1 << 18) +#define CGU0_STAT_WDFMSERR (1 << 19) +#define CGU0_STAT_WDIVERR (1 << 20) +#define CGU0_STAT_PLOCKERR (1 << 21) + +#define CGU0_DIV_CSEL_SHIFT 0 +#define CGU0_DIV_CSEL_MASK 0x0000001F +#define CGU0_DIV_S0SEL_SHIFT 5 +#define CGU0_DIV_S0SEL_MASK (0x3 << CGU0_DIV_S0SEL_SHIFT) +#define CGU0_DIV_SYSSEL_SHIFT 8 +#define CGU0_DIV_SYSSEL_MASK (0x1f << CGU0_DIV_SYSSEL_SHIFT) +#define CGU0_DIV_S1SEL_SHIFT 13 +#define CGU0_DIV_S1SEL_MASK (0x3 << CGU0_DIV_S1SEL_SHIFT) +#define CGU0_DIV_DSEL_SHIFT 16 +#define CGU0_DIV_DSEL_MASK (0x1f << CGU0_DIV_DSEL_SHIFT) +#define CGU0_DIV_OSEL_SHIFT 22 +#define CGU0_DIV_OSEL_MASK (0x7f << CGU0_DIV_OSEL_SHIFT) + +#define CLK(_clk, _devname, _conname) \ + { \ + .clk = &_clk, \ + .dev_id = _devname, \ + .con_id = _conname, \ + } + +#define NEEDS_INITIALIZATION 0x11 + +static LIST_HEAD(clk_list); + +static void clk_reg_write_mask(u32 reg, uint32_t val, uint32_t mask) +{ + u32 val2; + + val2 = bfin_read32(reg); + val2 &= ~mask; + val2 |= val; + bfin_write32(reg, val2); +} + +static void clk_reg_set_bits(u32 reg, uint32_t mask) +{ + u32 val; + + val = bfin_read32(reg); + val |= mask; + bfin_write32(reg, val); +} + +static void clk_reg_clear_bits(u32 reg, uint32_t mask) +{ + u32 val; + + val = bfin_read32(reg); + val &= ~mask; + bfin_write32(reg, val); +} + +int wait_for_pll_align(void) +{ + int i = 10000; + while (i-- && (bfin_read32(CGU0_STAT) & CGU0_STAT_CLKSALGN)); + + if (bfin_read32(CGU0_STAT) & CGU0_STAT_CLKSALGN) { + printk(KERN_DEBUG "fail to align clk\n"); + return -1; + } + return 0; +} + +int clk_enable(struct clk *clk) +{ + int ret = -EIO; + if (clk->ops && clk->ops->enable) + ret = clk->ops->enable(clk); + return ret; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ + if (clk->ops && clk->ops->disable) + clk->ops->disable(clk); +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + unsigned long ret = 0; + if (clk->ops && clk->ops->get_rate) + ret = clk->ops->get_rate(clk); + return ret; +} +EXPORT_SYMBOL(clk_get_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + long ret = -EIO; + if (clk->ops && clk->ops->round_rate) + ret = clk->ops->round_rate(clk, rate); + return ret; +} +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret = -EIO; + if (clk->ops && clk->ops->set_rate) + ret = clk->ops->set_rate(clk, rate); + return ret; +} +EXPORT_SYMBOL(clk_set_rate); + +unsigned long vco_get_rate(struct clk *clk) +{ + return clk->rate; +} + +unsigned long pll_get_rate(struct clk *clk) +{ + u32 df; + u32 msel; + u32 ctl = bfin_read32(CGU0_CTL); + u32 stat = bfin_read32(CGU0_STAT); + if (stat & CGU0_STAT_PLLBP) + return 0; + msel = (ctl & CGU0_CTL_MSEL_MASK) >> CGU0_CTL_MSEL_SHIFT; + df = (ctl & CGU0_CTL_DF); + clk->parent->rate = clk_get_rate(clk->parent); + return clk->parent->rate / (df + 1) * msel * 2; +} + +unsigned long pll_round_rate(struct clk *clk, unsigned long rate) +{ + u32 div; + div = rate / clk->parent->rate; + return clk->parent->rate * div; +} + +int pll_set_rate(struct clk *clk, unsigned long rate) +{ + u32 msel; + u32 stat = bfin_read32(CGU0_STAT); + if (!(stat & CGU0_STAT_PLLEN)) + return -EBUSY; + if (!(stat & CGU0_STAT_PLLLK)) + return -EBUSY; + if (wait_for_pll_align()) + return -EBUSY; + msel = rate / clk->parent->rate / 2; + clk_reg_write_mask(CGU0_CTL, msel << CGU0_CTL_MSEL_SHIFT, + CGU0_CTL_MSEL_MASK); + clk->rate = rate; + return 0; +} + +unsigned long cclk_get_rate(struct clk *clk) +{ + if (clk->parent) + return clk->parent->rate; + else + return 0; +} + +unsigned long sys_clk_get_rate(struct clk *clk) +{ + unsigned long drate; + u32 msel; + u32 df; + u32 ctl = bfin_read32(CGU0_CTL); + u32 div = bfin_read32(CGU0_DIV); + div = (div & clk->mask) >> clk->shift; + msel = (ctl & CGU0_CTL_MSEL_MASK) >> CGU0_CTL_MSEL_SHIFT; + df = (ctl & CGU0_CTL_DF); + + if (!strcmp(clk->parent->name, "SYS_CLKIN")) { + drate = clk->parent->rate / (df + 1); + drate *= msel; + drate /= div; + return drate; + } else { + clk->parent->rate = clk_get_rate(clk->parent); + return clk->parent->rate / div; + } +} + +unsigned long sys_clk_round_rate(struct clk *clk, unsigned long rate) +{ + unsigned long max_rate; + unsigned long drate; + int i; + u32 msel; + u32 df; + u32 ctl = bfin_read32(CGU0_CTL); + + msel = (ctl & CGU0_CTL_MSEL_MASK) >> CGU0_CTL_MSEL_SHIFT; + df = (ctl & CGU0_CTL_DF); + max_rate = clk->parent->rate / (df + 1) * msel; + + if (rate > max_rate) + return 0; + + for (i = 1; i < clk->mask; i++) { + drate = max_rate / i; + if (rate >= drate) + return drate; + } + return 0; +} + +int sys_clk_set_rate(struct clk *clk, unsigned long rate) +{ + u32 div = bfin_read32(CGU0_DIV); + div = (div & clk->mask) >> clk->shift; + + rate = clk_round_rate(clk, rate); + + if (!rate) + return -EINVAL; + + div = (clk_get_rate(clk) * div) / rate; + + if (wait_for_pll_align()) + return -EBUSY; + clk_reg_write_mask(CGU0_DIV, div << clk->shift, + clk->mask); + clk->rate = rate; + return 0; +} + +static struct clk_ops vco_ops = { + .get_rate = vco_get_rate, +}; + +static struct clk_ops pll_ops = { + .get_rate = pll_get_rate, + .set_rate = pll_set_rate, +}; + +static struct clk_ops cclk_ops = { + .get_rate = cclk_get_rate, +}; + +static struct clk_ops sys_clk_ops = { + .get_rate = sys_clk_get_rate, + .set_rate = sys_clk_set_rate, + .round_rate = sys_clk_round_rate, +}; + +static struct clk sys_clkin = { + .name = "SYS_CLKIN", + .rate = CONFIG_CLKIN_HZ, + .ops = &vco_ops, +}; + +static struct clk pll_clk = { + .name = "PLLCLK", + .rate = 500000000, + .parent = &sys_clkin, + .ops = &pll_ops, + .flags = NEEDS_INITIALIZATION, +}; + +static struct clk cclk = { + .name = "CCLK", + .rate = 500000000, + .mask = CGU0_DIV_CSEL_MASK, + .shift = CGU0_DIV_CSEL_SHIFT, + .parent = &sys_clkin, + .ops = &sys_clk_ops, + .flags = NEEDS_INITIALIZATION, +}; + +static struct clk cclk0 = { + .name = "CCLK0", + .parent = &cclk, + .ops = &cclk_ops, +}; + +static struct clk cclk1 = { + .name = "CCLK1", + .parent = &cclk, + .ops = &cclk_ops, +}; + +static struct clk sysclk = { + .name = "SYSCLK", + .rate = 500000000, + .mask = CGU0_DIV_SYSSEL_MASK, + .shift = CGU0_DIV_SYSSEL_SHIFT, + .parent = &sys_clkin, + .ops = &sys_clk_ops, + .flags = NEEDS_INITIALIZATION, +}; + +static struct clk sclk0 = { + .name = "SCLK0", + .rate = 500000000, + .mask = CGU0_DIV_S0SEL_MASK, + .shift = CGU0_DIV_S0SEL_SHIFT, + .parent = &sysclk, + .ops = &sys_clk_ops, +}; + +static struct clk sclk1 = { + .name = "SCLK1", + .rate = 500000000, + .mask = CGU0_DIV_S1SEL_MASK, + .shift = CGU0_DIV_S1SEL_SHIFT, + .parent = &sysclk, + .ops = &sys_clk_ops, +}; + +static struct clk dclk = { + .name = "DCLK", + .rate = 500000000, + .mask = CGU0_DIV_DSEL_MASK, + .shift = CGU0_DIV_DSEL_SHIFT, + .parent = &sys_clkin, + .ops = &sys_clk_ops, +}; + +static struct clk oclk = { + .name = "OCLK", + .rate = 500000000, + .mask = CGU0_DIV_OSEL_MASK, + .shift = CGU0_DIV_OSEL_SHIFT, + .parent = &pll_clk, +}; + +static struct clk_lookup bf609_clks[] = { + CLK(sys_clkin, NULL, "SYS_CLKIN"), + CLK(pll_clk, NULL, "PLLCLK"), + CLK(cclk, NULL, "CCLK"), + CLK(cclk0, NULL, "CCLK0"), + CLK(cclk1, NULL, "CCLK1"), + CLK(sysclk, NULL, "SYSCLK"), + CLK(sclk0, NULL, "SCLK0"), + CLK(sclk1, NULL, "SCLK1"), + CLK(dclk, NULL, "DCLK"), + CLK(oclk, NULL, "OCLK"), +}; + +int __init clk_init(void) +{ + int i; + struct clk *clkp; + for (i = 0; i < ARRAY_SIZE(bf609_clks); i++) { + clkp = bf609_clks[i].clk; + if (clkp->flags & NEEDS_INITIALIZATION) + clk_get_rate(clkp); + } + clkdev_add_table(bf609_clks, ARRAY_SIZE(bf609_clks)); + return 0; +}
diff --git a/arch/blackfin/mach-bf609/dma.c b/arch/blackfin/mach-bf609/dma.c new file mode 100644 index 0000000..1da4b38 --- /dev/null +++ b/arch/blackfin/mach-bf609/dma.c
@@ -0,0 +1,202 @@ +/* + * the simple DMA Implementation for Blackfin + * + * Copyright 2007-2009 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <linux/module.h> + +#include <asm/blackfin.h> +#include <asm/dma.h> + +struct dma_register * const dma_io_base_addr[MAX_DMA_CHANNELS] = { + (struct dma_register *) DMA0_NEXT_DESC_PTR, + (struct dma_register *) DMA1_NEXT_DESC_PTR, + (struct dma_register *) DMA2_NEXT_DESC_PTR, + (struct dma_register *) DMA3_NEXT_DESC_PTR, + (struct dma_register *) DMA4_NEXT_DESC_PTR, + (struct dma_register *) DMA5_NEXT_DESC_PTR, + (struct dma_register *) DMA6_NEXT_DESC_PTR, + (struct dma_register *) DMA7_NEXT_DESC_PTR, + (struct dma_register *) DMA8_NEXT_DESC_PTR, + (struct dma_register *) DMA9_NEXT_DESC_PTR, + (struct dma_register *) DMA10_NEXT_DESC_PTR, + (struct dma_register *) DMA11_NEXT_DESC_PTR, + (struct dma_register *) DMA12_NEXT_DESC_PTR, + (struct dma_register *) DMA13_NEXT_DESC_PTR, + (struct dma_register *) DMA14_NEXT_DESC_PTR, + (struct dma_register *) DMA15_NEXT_DESC_PTR, + (struct dma_register *) DMA16_NEXT_DESC_PTR, + (struct dma_register *) DMA17_NEXT_DESC_PTR, + (struct dma_register *) DMA18_NEXT_DESC_PTR, + (struct dma_register *) DMA19_NEXT_DESC_PTR, + (struct dma_register *) DMA20_NEXT_DESC_PTR, + (struct dma_register *) MDMA0_SRC_CRC0_NEXT_DESC_PTR, + (struct dma_register *) MDMA0_DEST_CRC0_NEXT_DESC_PTR, + (struct dma_register *) MDMA1_SRC_CRC1_NEXT_DESC_PTR, + (struct dma_register *) MDMA1_DEST_CRC1_NEXT_DESC_PTR, + (struct dma_register *) MDMA2_SRC_NEXT_DESC_PTR, + (struct dma_register *) MDMA2_DEST_NEXT_DESC_PTR, + (struct dma_register *) MDMA3_SRC_NEXT_DESC_PTR, + (struct dma_register *) MDMA3_DEST_NEXT_DESC_PTR, + (struct dma_register *) DMA29_NEXT_DESC_PTR, + (struct dma_register *) DMA30_NEXT_DESC_PTR, + (struct dma_register *) DMA31_NEXT_DESC_PTR, + (struct dma_register *) DMA32_NEXT_DESC_PTR, + (struct dma_register *) DMA33_NEXT_DESC_PTR, + (struct dma_register *) DMA34_NEXT_DESC_PTR, + (struct dma_register *) DMA35_NEXT_DESC_PTR, + (struct dma_register *) DMA36_NEXT_DESC_PTR, + (struct dma_register *) DMA37_NEXT_DESC_PTR, + (struct dma_register *) DMA38_NEXT_DESC_PTR, + (struct dma_register *) DMA39_NEXT_DESC_PTR, + (struct dma_register *) DMA40_NEXT_DESC_PTR, + (struct dma_register *) DMA41_NEXT_DESC_PTR, + (struct dma_register *) DMA42_NEXT_DESC_PTR, + (struct dma_register *) DMA43_NEXT_DESC_PTR, + (struct dma_register *) DMA44_NEXT_DESC_PTR, + (struct dma_register *) DMA45_NEXT_DESC_PTR, + (struct dma_register *) DMA46_NEXT_DESC_PTR, +}; +EXPORT_SYMBOL(dma_io_base_addr); + +int channel2irq(unsigned int channel) +{ + int ret_irq = -1; + + switch (channel) { + case CH_SPORT0_RX: + ret_irq = IRQ_SPORT0_RX; + break; + case CH_SPORT0_TX: + ret_irq = IRQ_SPORT0_TX; + break; + case CH_SPORT1_RX: + ret_irq = IRQ_SPORT1_RX; + break; + case CH_SPORT1_TX: + ret_irq = IRQ_SPORT1_TX; + break; + case CH_SPORT2_RX: + ret_irq = IRQ_SPORT2_RX; + break; + case CH_SPORT2_TX: + ret_irq = IRQ_SPORT2_TX; + break; + case CH_SPI0_TX: + ret_irq = IRQ_SPI0_TX; + break; + case CH_SPI0_RX: + ret_irq = IRQ_SPI0_RX; + break; + case CH_SPI1_TX: + ret_irq = IRQ_SPI1_TX; + break; + case CH_SPI1_RX: + ret_irq = IRQ_SPI1_RX; + break; + case CH_RSI: + ret_irq = IRQ_RSI; + break; + case CH_SDU: + ret_irq = IRQ_SDU; + break; + case CH_LP0: + ret_irq = IRQ_LP0; + break; + case CH_LP1: + ret_irq = IRQ_LP1; + break; + case CH_LP2: + ret_irq = IRQ_LP2; + break; + case CH_LP3: + ret_irq = IRQ_LP3; + break; + case CH_UART0_RX: + ret_irq = IRQ_UART0_RX; + break; + case CH_UART0_TX: + ret_irq = IRQ_UART0_TX; + break; + case CH_UART1_RX: + ret_irq = IRQ_UART1_RX; + break; + case CH_UART1_TX: + ret_irq = IRQ_UART1_TX; + break; + case CH_EPPI0_CH0: + ret_irq = IRQ_EPPI0_CH0; + break; + case CH_EPPI0_CH1: + ret_irq = IRQ_EPPI0_CH1; + break; + case CH_EPPI1_CH0: + ret_irq = IRQ_EPPI1_CH0; + break; + case CH_EPPI1_CH1: + ret_irq = IRQ_EPPI1_CH1; + break; + case CH_EPPI2_CH0: + ret_irq = IRQ_EPPI2_CH0; + break; + case CH_EPPI2_CH1: + ret_irq = IRQ_EPPI2_CH1; + break; + case CH_PIXC_CH0: + ret_irq = IRQ_PIXC_CH0; + break; + case CH_PIXC_CH1: + ret_irq = IRQ_PIXC_CH1; + break; + case CH_PIXC_CH2: + ret_irq = IRQ_PIXC_CH2; + break; + case CH_PVP_CPDOB: + ret_irq = IRQ_PVP_CPDOB; + break; + case CH_PVP_CPDOC: + ret_irq = IRQ_PVP_CPDOC; + break; + case CH_PVP_CPSTAT: + ret_irq = IRQ_PVP_CPSTAT; + break; + case CH_PVP_CPCI: + ret_irq = IRQ_PVP_CPCI; + break; + case CH_PVP_MPDO: + ret_irq = IRQ_PVP_MPDO; + break; + case CH_PVP_MPDI: + ret_irq = IRQ_PVP_MPDI; + break; + case CH_PVP_MPSTAT: + ret_irq = IRQ_PVP_MPSTAT; + break; + case CH_PVP_MPCI: + ret_irq = IRQ_PVP_MPCI; + break; + case CH_PVP_CPDOA: + ret_irq = IRQ_PVP_CPDOA; + break; + case CH_MEM_STREAM0_SRC: + case CH_MEM_STREAM0_DEST: + ret_irq = IRQ_MDMAS0; + break; + case CH_MEM_STREAM1_SRC: + case CH_MEM_STREAM1_DEST: + ret_irq = IRQ_MDMAS1; + break; + case CH_MEM_STREAM2_SRC: + case CH_MEM_STREAM2_DEST: + ret_irq = IRQ_MDMAS2; + break; + case CH_MEM_STREAM3_SRC: + case CH_MEM_STREAM3_DEST: + ret_irq = IRQ_MDMAS3; + break; + } + return ret_irq; +}
diff --git a/arch/blackfin/mach-bf609/hibernate.S b/arch/blackfin/mach-bf609/hibernate.S new file mode 100644 index 0000000..d37a532 --- /dev/null +++ b/arch/blackfin/mach-bf609/hibernate.S
@@ -0,0 +1,65 @@ +#include <linux/linkage.h> +#include <asm/blackfin.h> +#include <asm/dpmc.h> + +#define PM_STACK (COREA_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12) + +.section .l1.text +ENTRY(_enter_hibernate) + /* switch stack to L1 scratch, prepare for ddr srfr */ + P0.H = HI(PM_STACK); + P0.L = LO(PM_STACK); + SP = P0; + + call _bf609_ddr_sr; + call _bfin_hibernate_syscontrol; + + P0.H = HI(DPM0_RESTORE4); + P0.L = LO(DPM0_RESTORE4); + P1.H = _bf609_pm_data; + P1.L = _bf609_pm_data; + [P0] = P1; + + P0.H = HI(DPM0_CTL); + P0.L = LO(DPM0_CTL); + R3.H = HI(0x00000010); + R3.L = LO(0x00000010); + + bfin_init_pm_bench_cycles; + + [P0] = R3; + + SSYNC; +ENDPROC(_enter_hibernate_mode) + +.section .text +ENTRY(_bf609_hibernate) + bfin_cpu_reg_save; + bfin_core_mmr_save; + + P0.H = _bf609_pm_data; + P0.L = _bf609_pm_data; + R1.H = 0xDEAD; + R1.L = 0xBEEF; + R2.H = .Lpm_resume_here; + R2.L = .Lpm_resume_here; + [P0++] = R1; + [P0++] = R2; + [P0++] = SP; + + P1.H = _enter_hibernate; + P1.L = _enter_hibernate; + + call (P1); +.Lpm_resume_here: + + bfin_core_mmr_restore; + bfin_cpu_reg_restore; + + [--sp] = RETI; /* Clear Global Interrupt Disable */ + SP += 4; + + RTS; + +ENDPROC(_bf609_hibernate) +
diff --git a/arch/blackfin/mach-bf609/include/mach/anomaly.h b/arch/blackfin/mach-bf609/include/mach/anomaly.h new file mode 100644 index 0000000..bdd39ae --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/anomaly.h
@@ -0,0 +1,130 @@ +/* + * DO NOT EDIT THIS FILE + * This file is under version control at + * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/ + * and can be replaced with that version at any time + * DO NOT EDIT THIS FILE + * + * Copyright 2004-2011 Analog Devices Inc. + * Licensed under the Clear BSD license. + */ + +/* This file should be up to date with: + */ + +#if __SILICON_REVISION__ < 0 +# error will not work on BF506 silicon version +#endif + +#ifndef _MACH_ANOMALY_H_ +#define _MACH_ANOMALY_H_ + +/* Multi-Issue Instruction with dsp32shiftimm in slot1 and P-reg Store in slot2 Not Supported */ +#define ANOMALY_05000074 (1) +/* DMA_RUN Bit Is Not Valid after a Peripheral Receive Channel DMA Stops */ +#define ANOMALY_05000119 (1) +/* Rx.H Cannot Be Used to Access 16-bit System MMR Registers */ +#define ANOMALY_05000122 (1) +/* False Hardware Error from an Access in the Shadow of a Conditional Branch */ +#define ANOMALY_05000245 (1) +/* Incorrect Timer Pulse Width in Single-Shot PWM_OUT Mode with External Clock */ +#define ANOMALY_05000254 (1) +/* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */ +#define ANOMALY_05000265 (1) +/* False Hardware Errors Caused by Fetches at the Boundary of Reserved Memory */ +#define ANOMALY_05000310 (1) +/* PPI Underflow Error Goes Undetected in ITU-R 656 Mode */ +#define ANOMALY_05000366 (1) +/* Speculative Fetches Can Cause Undesired External FIFO Operations */ +#define ANOMALY_05000416 (1) +/* Speculative Fetches of Indirect-Pointer Instructions Can Cause False Hardware Errors */ +#define ANOMALY_05000426 (1) +/* IFLUSH Instruction at End of Hardware Loop Causes Infinite Stall */ +#define ANOMALY_05000443 (1) +/* UART IrDA Receiver Fails on Extended Bit Pulses */ +#define ANOMALY_05000447 (1) +/* False Hardware Error when RETI Points to Invalid Memory */ +#define ANOMALY_05000461 (1) +/* PLL Latches Incorrect Settings During Reset */ +#define ANOMALY_05000469 (1) +/* Incorrect Default MSEL Value in PLL_CTL */ +#define ANOMALY_05000472 (1) +/* Interrupted SPORT Receive Data Register Read Results In Underflow when SLEN > 15 */ +#define ANOMALY_05000473 (1) +/* TESTSET Instruction Cannot Be Interrupted */ +#define ANOMALY_05000477 (1) +/* Reads of ITEST_COMMAND and ITEST_DATA Registers Cause Cache Corruption */ +#define ANOMALY_05000481 (1) +/* IFLUSH sucks at life */ +#define ANOMALY_05000491 (1) +/* Tempopary anomaly ID for data loss in MMR read operation if interrupted */ +#define ANOMALY_05001001 (__SILICON_REVISION__ < 1) + +/* Anomalies that don't exist on this proc */ +#define ANOMALY_05000099 (0) +#define ANOMALY_05000120 (0) +#define ANOMALY_05000125 (0) +#define ANOMALY_05000149 (0) +#define ANOMALY_05000158 (0) +#define ANOMALY_05000171 (0) +#define ANOMALY_05000179 (0) +#define ANOMALY_05000182 (0) +#define ANOMALY_05000183 (0) +#define ANOMALY_05000189 (0) +#define ANOMALY_05000198 (0) +#define ANOMALY_05000202 (0) +#define ANOMALY_05000215 (0) +#define ANOMALY_05000219 (0) +#define ANOMALY_05000220 (0) +#define ANOMALY_05000227 (0) +#define ANOMALY_05000230 (0) +#define ANOMALY_05000231 (0) +#define ANOMALY_05000233 (0) +#define ANOMALY_05000234 (0) +#define ANOMALY_05000242 (0) +#define ANOMALY_05000244 (0) +#define ANOMALY_05000248 (0) +#define ANOMALY_05000250 (0) +#define ANOMALY_05000257 (0) +#define ANOMALY_05000261 (0) +#define ANOMALY_05000263 (0) +#define ANOMALY_05000266 (0) +#define ANOMALY_05000273 (0) +#define ANOMALY_05000274 (0) +#define ANOMALY_05000278 (0) +#define ANOMALY_05000281 (0) +#define ANOMALY_05000283 (0) +#define ANOMALY_05000285 (0) +#define ANOMALY_05000287 (0) +#define ANOMALY_05000301 (0) +#define ANOMALY_05000305 (0) +#define ANOMALY_05000307 (0) +#define ANOMALY_05000311 (0) +#define ANOMALY_05000312 (0) +#define ANOMALY_05000315 (0) +#define ANOMALY_05000323 (0) +#define ANOMALY_05000353 (1) +#define ANOMALY_05000357 (0) +#define ANOMALY_05000362 (1) +#define ANOMALY_05000363 (0) +#define ANOMALY_05000364 (0) +#define ANOMALY_05000371 (0) +#define ANOMALY_05000380 (0) +#define ANOMALY_05000386 (0) +#define ANOMALY_05000389 (0) +#define ANOMALY_05000400 (0) +#define ANOMALY_05000402 (0) +#define ANOMALY_05000412 (0) +#define ANOMALY_05000432 (0) +#define ANOMALY_05000440 (0) +#define ANOMALY_05000448 (0) +#define ANOMALY_05000456 (0) +#define ANOMALY_05000450 (0) +#define ANOMALY_05000465 (0) +#define ANOMALY_05000467 (0) +#define ANOMALY_05000474 (0) +#define ANOMALY_05000475 (0) +#define ANOMALY_05000480 (0) +#define ANOMALY_05000485 (0) + +#endif
diff --git a/arch/blackfin/mach-bf609/include/mach/bf609.h b/arch/blackfin/mach-bf609/include/mach/bf609.h new file mode 100644 index 0000000..c897c2a --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/bf609.h
@@ -0,0 +1,93 @@ +/* + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __MACH_BF609_H__ +#define __MACH_BF609_H__ + +#define OFFSET_(x) ((x) & 0x0000FFFF) + +/*some misc defines*/ +#define IMASK_IVG15 0x8000 +#define IMASK_IVG14 0x4000 +#define IMASK_IVG13 0x2000 +#define IMASK_IVG12 0x1000 + +#define IMASK_IVG11 0x0800 +#define IMASK_IVG10 0x0400 +#define IMASK_IVG9 0x0200 +#define IMASK_IVG8 0x0100 + +#define IMASK_IVG7 0x0080 +#define IMASK_IVGTMR 0x0040 +#define IMASK_IVGHW 0x0020 + +/***************************/ + + +#define BFIN_DSUBBANKS 4 +#define BFIN_DWAYS 2 +#define BFIN_DLINES 64 +#define BFIN_ISUBBANKS 4 +#define BFIN_IWAYS 4 +#define BFIN_ILINES 32 + +#define WAY0_L 0x1 +#define WAY1_L 0x2 +#define WAY01_L 0x3 +#define WAY2_L 0x4 +#define WAY02_L 0x5 +#define WAY12_L 0x6 +#define WAY012_L 0x7 + +#define WAY3_L 0x8 +#define WAY03_L 0x9 +#define WAY13_L 0xA +#define WAY013_L 0xB + +#define WAY32_L 0xC +#define WAY320_L 0xD +#define WAY321_L 0xE +#define WAYALL_L 0xF + +#define DMC_ENABLE (2<<2) /*yes, 2, not 1 */ + +/********************************* EBIU Settings ************************************/ +#define AMBCTL0VAL ((CONFIG_BANK_1 << 16) | CONFIG_BANK_0) +#define AMBCTL1VAL ((CONFIG_BANK_3 << 16) | CONFIG_BANK_2) + +#ifdef CONFIG_C_AMBEN_ALL +#define V_AMBEN AMBEN_ALL +#endif +#ifdef CONFIG_C_AMBEN +#define V_AMBEN 0x0 +#endif +#ifdef CONFIG_C_AMBEN_B0 +#define V_AMBEN AMBEN_B0 +#endif +#ifdef CONFIG_C_AMBEN_B0_B1 +#define V_AMBEN AMBEN_B0_B1 +#endif +#ifdef CONFIG_C_AMBEN_B0_B1_B2 +#define V_AMBEN AMBEN_B0_B1_B2 +#endif +#ifdef CONFIG_C_AMCKEN +#define V_AMCKEN AMCKEN +#else +#define V_AMCKEN 0x0 +#endif + +#define AMGCTLVAL (V_AMBEN | V_AMCKEN) + +#if defined(CONFIG_BF609) +# define CPU "BF609" +# define CPUID 0x27fe /* temperary fake value */ +#endif + +#ifndef CPU +#error "Unknown CPU type - This kernel doesn't seem to be configured properly" +#endif + +#endif /* __MACH_BF609_H__ */
diff --git a/arch/blackfin/mach-bf609/include/mach/bfin_serial.h b/arch/blackfin/mach-bf609/include/mach/bfin_serial.h new file mode 100644 index 0000000..1fd39814 --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/bfin_serial.h
@@ -0,0 +1,17 @@ +/* + * mach/bfin_serial.h - Blackfin UART/Serial definitions + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __BFIN_MACH_SERIAL_H__ +#define __BFIN_MACH_SERIAL_H__ + +#define BFIN_UART_NR_PORTS 2 +#define BFIN_UART_TX_FIFO_SIZE 8 + +#define BFIN_UART_BF60X_STYLE + +#endif
diff --git a/arch/blackfin/mach-bf609/include/mach/blackfin.h b/arch/blackfin/mach-bf609/include/mach/blackfin.h new file mode 100644 index 0000000..b1a48c4 --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/blackfin.h
@@ -0,0 +1,25 @@ +/* + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef _MACH_BLACKFIN_H_ +#define _MACH_BLACKFIN_H_ + +#include "bf609.h" +#include "anomaly.h" + +#include <asm/def_LPBlackfin.h> +#ifdef CONFIG_BF609 +# include "defBF609.h" +#endif + +#ifndef __ASSEMBLY__ +# include <asm/cdef_LPBlackfin.h> +# ifdef CONFIG_BF609 +# include "cdefBF609.h" +# endif +#endif + +#endif
diff --git a/arch/blackfin/mach-bf609/include/mach/cdefBF609.h b/arch/blackfin/mach-bf609/include/mach/cdefBF609.h new file mode 100644 index 0000000..c4f3fe1 --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/cdefBF609.h
@@ -0,0 +1,15 @@ +/* + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef _CDEF_BF609_H +#define _CDEF_BF609_H + +/* include cdefBF60x_base.h for the set of #defines that are common to all ADSP-BF60x bfin_read_()rocessors */ +#include "cdefBF60x_base.h" + +/* The following are the #defines needed by ADSP-BF609 that are not in the common header */ + +#endif /* _CDEF_BF609_H */
diff --git a/arch/blackfin/mach-bf609/include/mach/cdefBF60x_base.h b/arch/blackfin/mach-bf609/include/mach/cdefBF60x_base.h new file mode 100644 index 0000000..4954cf3 --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/cdefBF60x_base.h
@@ -0,0 +1,3252 @@ +/* + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef _CDEF_BF60X_H +#define _CDEF_BF60X_H + +/* ************************************************************** */ +/* SYSTEM & MMR ADDRESS DEFINITIONS COMMON TO ALL ADSP-BF60x */ +/* ************************************************************** */ + +/* Debug/MP/Emulation Registers (0xFFC00014 - 0xFFC00014) */ + +#define bfin_read_CHIPID() bfin_read32(CHIPID) +#define bfin_write_CHIPID(val) bfin_write32(CHIPID, val) + +/* System Reset and Interrubfin_read_()t Controller (0xFFC00100 - 0xFFC00104) */ + +/* SEC0 Registers */ +#define bfin_read_SEC0_CCTL() bfin_read32(SEC0_CCTL) +#define bfin_write_SEC0_CCTL(val) bfin_write32(SEC0_CCTL, val) +#define bfin_read_SEC0_CSID() bfin_read32(SEC0_CSID) +#define bfin_write_SEC0_CSID(val) bfin_write32(SEC0_CSID, val) +#define bfin_read_SEC_GCTL() bfin_read32(SEC_GCTL) +#define bfin_write_SEC_GCTL(val) bfin_write32(SEC_GCTL, val) + +#define bfin_read_SEC_FCTL() bfin_read32(SEC_FCTL) +#define bfin_write_SEC_FCTL(val) bfin_write32(SEC_FCTL, val) + +#define bfin_read_SEC_SCTL(sid) bfin_read32((SEC_SCTL0 + (sid) * 8)) +#define bfin_write_SEC_SCTL(sid, val) bfin_write32((SEC_SCTL0 + (sid) * 8), val) + +#define bfin_read_SEC_SSTAT(sid) bfin_read32((SEC_SSTAT0 + (sid) * 8)) +#define bfin_write_SEC_SSTAT(sid, val) bfin_write32((SEC_SSTAT0 + (sid) * 8), val) + +/* RCU0 Registers */ +#define bfin_read_RCU0_CTL() bfin_read32(RCU0_CTL) +#define bfin_write_RCU0_CTL(val) bfin_write32(RCU0_CTL, val) + +/* Watchdog Timer Registers */ +#define bfin_read_WDOG_CTL() bfin_read16(WDOG_CTL) +#define bfin_write_WDOG_CTL(val) bfin_write16(WDOG_CTL, val) +#define bfin_read_WDOG_CNT() bfin_read32(WDOG_CNT) +#define bfin_write_WDOG_CNT(val) bfin_write32(WDOG_CNT, val) +#define bfin_read_WDOG_STAT() bfin_read32(WDOG_STAT) +#define bfin_write_WDOG_STAT(val) bfin_write32(WDOG_STAT, val) + +/* RTC Registers */ + +/* UART0 Registers */ + +#define bfin_read_UART0_REVID() bfin_read32(UART0_REVID) +#define bfin_write_UART0_REVID(val) bfin_write32(UART0_REVID, val) +#define bfin_read_UART0_GCTL() bfin_read32(UART0_GCTL) +#define bfin_write_UART0_GCTL(val) bfin_write32(UART0_GCTL, val) +#define bfin_read_UART0_STAT() bfin_read32(UART0_STAT) +#define bfin_write_UART0_STAT(val) bfin_write32(UART0_STAT, val) +#define bfin_read_UART0_SCR() bfin_read32(UART0_SCR) +#define bfin_write_UART0_SCR(val) bfin_write32(UART0_SCR, val) +#define bfin_read_UART0_CLK() bfin_read32(UART0_CLK) +#define bfin_write_UART0_CLK(val) bfin_write32(UART0_CLK, val) +#define bfin_read_UART0_IER() bfin_read32(UART0_IER) +#define bfin_write_UART0_IER(val) bfin_write32(UART0_IER, val) +#define bfin_read_UART0_IER_SET() bfin_read32(UART0_IER_SET) +#define bfin_write_UART0_IER_SET(val) bfin_write32(UART0_IER_SET, val) +#define bfin_read_UART0_IER_CLEAR() bfin_read32(UART0_IER_CLEAR) +#define bfin_write_UART0_IER_CLEAR(val) bfin_write32(UART0_IER_CLEAR, val) +#define bfin_read_UART0_RBR() bfin_read32(UART0_RBR) +#define bfin_write_UART0_RBR(val) bfin_write32(UART0_RBR, val) +#define bfin_read_UART0_THR() bfin_read32(UART0_THR) +#define bfin_write_UART0_THR(val) bfin_write32(UART0_THR, val) +#define bfin_read_UART0_TAIP() bfin_read32(UART0_TAIP) +#define bfin_write_UART0_TAIP(val) bfin_write32(UART0_TAIP, val) +#define bfin_read_UART0_TSR() bfin_read32(UART0_TSR) +#define bfin_write_UART0_TSR(val) bfin_write32(UART0_TSR, val) +#define bfin_read_UART0_RSR() bfin_read32(UART0_RSR) +#define bfin_write_UART0_RSR(val) bfin_write32(UART0_RSR, val) +#define bfin_read_UART0_TXCNT() bfin_read32(UART0_TXCNT) +#define bfin_write_UART0_TXCNT(val) bfin_write32(UART0_TXCNT, val) +#define bfin_read_UART0_RXCNT() bfin_read32(UART0_RXCNT) +#define bfin_write_UART0_RXCNT(val) bfin_write32(UART0_RXCNT, val) + +/* UART1 Registers */ + +#define bfin_read_UART1_REVID() bfin_read32(UART1_REVID) +#define bfin_write_UART1_REVID(val) bfin_write32(UART1_REVID, val) +#define bfin_read_UART1_GCTL() bfin_read32(UART1_GCTL) +#define bfin_write_UART1_GCTL(val) bfin_write32(UART1_GCTL, val) +#define bfin_read_UART1_STAT() bfin_read32(UART1_STAT) +#define bfin_write_UART1_STAT(val) bfin_write32(UART1_STAT, val) +#define bfin_read_UART1_SCR() bfin_read32(UART1_SCR) +#define bfin_write_UART1_SCR(val) bfin_write32(UART1_SCR, val) +#define bfin_read_UART1_CLK() bfin_read32(UART1_CLK) +#define bfin_write_UART1_CLK(val) bfin_write32(UART1_CLK, val) +#define bfin_read_UART1_IER() bfin_read32(UART1_IER) +#define bfin_write_UART1_IER(val) bfin_write32(UART1_IER, val) +#define bfin_read_UART1_IER_SET() bfin_read32(UART1_IER_SET) +#define bfin_write_UART1_IER_SET(val) bfin_write32(UART1_IER_SET, val) +#define bfin_read_UART1_IER_CLEAR() bfin_read32(UART1_IER_CLEAR) +#define bfin_write_UART1_IER_CLEAR(val) bfin_write32(UART1_IER_CLEAR, val) +#define bfin_read_UART1_RBR() bfin_read32(UART1_RBR) +#define bfin_write_UART1_RBR(val) bfin_write32(UART1_RBR, val) +#define bfin_read_UART1_THR() bfin_read32(UART1_THR) +#define bfin_write_UART1_THR(val) bfin_write32(UART1_THR, val) +#define bfin_read_UART1_TAIP() bfin_read32(UART1_TAIP) +#define bfin_write_UART1_TAIP(val) bfin_write32(UART1_TAIP, val) +#define bfin_read_UART1_TSR() bfin_read32(UART1_TSR) +#define bfin_write_UART1_TSR(val) bfin_write32(UART1_TSR, val) +#define bfin_read_UART1_RSR() bfin_read32(UART1_RSR) +#define bfin_write_UART1_RSR(val) bfin_write32(UART1_RSR, val) +#define bfin_read_UART1_TXCNT() bfin_read32(UART1_TXCNT) +#define bfin_write_UART1_TXCNT(val) bfin_write32(UART1_TXCNT, val) +#define bfin_read_UART1_RXCNT() bfin_read32(UART1_RXCNT) +#define bfin_write_UART1_RXCNT(val) bfin_write32(UART1_RXCNT, val) + + +/* SPI0 Registers */ + +#define bfin_read_SPI0_CTL() bfin_read32(SPI0_CTL) +#define bfin_write_SPI0_CTL(val) bfin_write32(SPI0_CTL, val) +#define bfin_read_SPI0_RXCTL() bfin_read32(SPI0_RXCTL) +#define bfin_write_SPI0_RXCTL(val) bfin_write32(SPI0_RXCTL, val) +#define bfin_read_SPI0_TXCTL() bfin_read32(SPI0_TXCTL) +#define bfin_write_SPI0_TXCTL(val) bfin_write32(SPI0_TXCTL, val) +#define bfin_read_SPI0_CLK() bfin_read32(SPI0_CLK) +#define bfin_write_SPI0_CLK(val) bfin_write32(SPI0_CLK, val) +#define bfin_read_SPI0_DLY() bfin_read32(SPI0_DLY) +#define bfin_write_SPI0_DLY(val) bfin_write32(SPI0_DLY, val) +#define bfin_read_SPI0_SLVSEL() bfin_read32(SPI0_SLVSEL) +#define bfin_write_SPI0_SLVSEL(val) bfin_write32(SPI0_SLVSEL, val) +#define bfin_read_SPI0_RWC() bfin_read32(SPI0_RWC) +#define bfin_write_SPI0_RWC(val) bfin_write32(SPI0_RWC, val) +#define bfin_read_SPI0_RWCR() bfin_read32(SPI0_RWCR) +#define bfin_write_SPI0_RWCR(val) bfin_write32(SPI0_RWCR, val) +#define bfin_read_SPI0_TWC() bfin_read32(SPI0_TWC) +#define bfin_write_SPI0_TWC(val) bfin_write32(SPI0_TWC, val) +#define bfin_read_SPI0_TWCR() bfin_read32(SPI0_TWCR) +#define bfin_write_SPI0_TWCR(val) bfin_write32(SPI0_TWCR, val) +#define bfin_read_SPI0_IMSK() bfin_read32(SPI0_IMSK) +#define bfin_write_SPI0_IMSK(val) bfin_write32(SPI0_IMSK, val) +#define bfin_read_SPI0_IMSK_CLR() bfin_read32(SPI0_IMSK_CLR) +#define bfin_write_SPI0_IMSK_CLR(val) bfin_write32(SPI0_IMSK_CLR, val) +#define bfin_read_SPI0_IMSK_SET() bfin_read32(SPI0_IMSK_SET) +#define bfin_write_SPI0_IMSK_SET(val) bfin_write32(SPI0_IMSK_SET, val) +#define bfin_read_SPI0_STAT() bfin_read32(SPI0_STAT) +#define bfin_write_SPI0_STAT(val) bfin_write32(SPI0_STAT, val) +#define bfin_read_SPI0_ILAT() bfin_read32(SPI0_ILAT) +#define bfin_write_SPI0_ILAT(val) bfin_write32(SPI0_ILAT, val) +#define bfin_read_SPI0_ILAT_CLR() bfin_read32(SPI0_ILAT_CLR) +#define bfin_write_SPI0_ILAT_CLR(val) bfin_write32(SPI0_ILAT_CLR, val) +#define bfin_read_SPI0_RFIFO() bfin_read32(SPI0_RFIFO) +#define bfin_write_SPI0_RFIFO(val) bfin_write32(SPI0_RFIFO, val) +#define bfin_read_SPI0_TFIFO() bfin_read32(SPI0_TFIFO) +#define bfin_write_SPI0_TFIFO(val) bfin_write32(SPI0_TFIFO, val) + +/* SPI1 Registers */ + +#define bfin_read_SPI1_CTL() bfin_read32(SPI1_CTL) +#define bfin_write_SPI1_CTL(val) bfin_write32(SPI1_CTL, val) +#define bfin_read_SPI1_RXCTL() bfin_read32(SPI1_RXCTL) +#define bfin_write_SPI1_RXCTL(val) bfin_write32(SPI1_RXCTL, val) +#define bfin_read_SPI1_TXCTL() bfin_read32(SPI1_TXCTL) +#define bfin_write_SPI1_TXCTL(val) bfin_write32(SPI1_TXCTL, val) +#define bfin_read_SPI1_CLK() bfin_read32(SPI1_CLK) +#define bfin_write_SPI1_CLK(val) bfin_write32(SPI1_CLK, val) +#define bfin_read_SPI1_DLY() bfin_read32(SPI1_DLY) +#define bfin_write_SPI1_DLY(val) bfin_write32(SPI1_DLY, val) +#define bfin_read_SPI1_SLVSEL() bfin_read32(SPI1_SLVSEL) +#define bfin_write_SPI1_SLVSEL(val) bfin_write32(SPI1_SLVSEL, val) +#define bfin_read_SPI1_RWC() bfin_read32(SPI1_RWC) +#define bfin_write_SPI1_RWC(val) bfin_write32(SPI1_RWC, val) +#define bfin_read_SPI1_RWCR() bfin_read32(SPI1_RWCR) +#define bfin_write_SPI1_RWCR(val) bfin_write32(SPI1_RWCR, val) +#define bfin_read_SPI1_TWC() bfin_read32(SPI1_TWC) +#define bfin_write_SPI1_TWC(val) bfin_write32(SPI1_TWC, val) +#define bfin_read_SPI1_TWCR() bfin_read32(SPI1_TWCR) +#define bfin_write_SPI1_TWCR(val) bfin_write32(SPI1_TWCR, val) +#define bfin_read_SPI1_IMSK() bfin_read32(SPI1_IMSK) +#define bfin_write_SPI1_IMSK(val) bfin_write32(SPI1_IMSK, val) +#define bfin_read_SPI1_IMSK_CLR() bfin_read32(SPI1_IMSK_CLR) +#define bfin_write_SPI1_IMSK_CLR(val) bfin_write32(SPI1_IMSK_CLR, val) +#define bfin_read_SPI1_IMSK_SET() bfin_read32(SPI1_IMSK_SET) +#define bfin_write_SPI1_IMSK_SET(val) bfin_write32(SPI1_IMSK_SET, val) +#define bfin_read_SPI1_STAT() bfin_read32(SPI1_STAT) +#define bfin_write_SPI1_STAT(val) bfin_write32(SPI1_STAT, val) +#define bfin_read_SPI1_ILAT() bfin_read32(SPI1_ILAT) +#define bfin_write_SPI1_ILAT(val) bfin_write32(SPI1_ILAT, val) +#define bfin_read_SPI1_ILAT_CLR() bfin_read32(SPI1_ILAT_CLR) +#define bfin_write_SPI1_ILAT_CLR(val) bfin_write32(SPI1_ILAT_CLR, val) +#define bfin_read_SPI1_RFIFO() bfin_read32(SPI1_RFIFO) +#define bfin_write_SPI1_RFIFO(val) bfin_write32(SPI1_RFIFO, val) +#define bfin_read_SPI1_TFIFO() bfin_read32(SPI1_TFIFO) +#define bfin_write_SPI1_TFIFO(val) bfin_write32(SPI1_TFIFO, val) + +/* Timer 0-7 registers */ +#define bfin_read_TIMER0_CONFIG() bfin_read16(TIMER0_CONFIG) +#define bfin_write_TIMER0_CONFIG(val) bfin_write16(TIMER0_CONFIG, val) +#define bfin_read_TIMER0_COUNTER() bfin_read32(TIMER0_COUNTER) +#define bfin_write_TIMER0_COUNTER(val) bfin_write32(TIMER0_COUNTER, val) +#define bfin_read_TIMER0_PERIOD() bfin_read32(TIMER0_PERIOD) +#define bfin_write_TIMER0_PERIOD(val) bfin_write32(TIMER0_PERIOD, val) +#define bfin_read_TIMER0_WIDTH() bfin_read32(TIMER0_WIDTH) +#define bfin_write_TIMER0_WIDTH(val) bfin_write32(TIMER0_WIDTH, val) +#define bfin_read_TIMER1_CONFIG() bfin_read16(TIMER1_CONFIG) +#define bfin_write_TIMER1_CONFIG(val) bfin_write16(TIMER1_CONFIG, val) +#define bfin_read_TIMER1_COUNTER() bfin_read32(TIMER1_COUNTER) +#define bfin_write_TIMER1_COUNTER(val) bfin_write32(TIMER1_COUNTER, val) +#define bfin_read_TIMER1_PERIOD() bfin_read32(TIMER1_PERIOD) +#define bfin_write_TIMER1_PERIOD(val) bfin_write32(TIMER1_PERIOD, val) +#define bfin_read_TIMER1_WIDTH() bfin_read32(TIMER1_WIDTH) +#define bfin_write_TIMER1_WIDTH(val) bfin_write32(TIMER1_WIDTH, val) +#define bfin_read_TIMER2_CONFIG() bfin_read16(TIMER2_CONFIG) +#define bfin_write_TIMER2_CONFIG(val) bfin_write16(TIMER2_CONFIG, val) +#define bfin_read_TIMER2_COUNTER() bfin_read32(TIMER2_COUNTER) +#define bfin_write_TIMER2_COUNTER(val) bfin_write32(TIMER2_COUNTER, val) +#define bfin_read_TIMER2_PERIOD() bfin_read32(TIMER2_PERIOD) +#define bfin_write_TIMER2_PERIOD(val) bfin_write32(TIMER2_PERIOD, val) +#define bfin_read_TIMER2_WIDTH() bfin_read32(TIMER2_WIDTH) +#define bfin_write_TIMER2_WIDTH(val) bfin_write32(TIMER2_WIDTH, val) +#define bfin_read_TIMER3_CONFIG() bfin_read16(TIMER3_CONFIG) +#define bfin_write_TIMER3_CONFIG(val) bfin_write16(TIMER3_CONFIG, val) +#define bfin_read_TIMER3_COUNTER() bfin_read32(TIMER3_COUNTER) +#define bfin_write_TIMER3_COUNTER(val) bfin_write32(TIMER3_COUNTER, val) +#define bfin_read_TIMER3_PERIOD() bfin_read32(TIMER3_PERIOD) +#define bfin_write_TIMER3_PERIOD(val) bfin_write32(TIMER3_PERIOD, val) +#define bfin_read_TIMER3_WIDTH() bfin_read32(TIMER3_WIDTH) +#define bfin_write_TIMER3_WIDTH(val) bfin_write32(TIMER3_WIDTH, val) +#define bfin_read_TIMER4_CONFIG() bfin_read16(TIMER4_CONFIG) +#define bfin_write_TIMER4_CONFIG(val) bfin_write16(TIMER4_CONFIG, val) +#define bfin_read_TIMER4_COUNTER() bfin_read32(TIMER4_COUNTER) +#define bfin_write_TIMER4_COUNTER(val) bfin_write32(TIMER4_COUNTER, val) +#define bfin_read_TIMER4_PERIOD() bfin_read32(TIMER4_PERIOD) +#define bfin_write_TIMER4_PERIOD(val) bfin_write32(TIMER4_PERIOD, val) +#define bfin_read_TIMER4_WIDTH() bfin_read32(TIMER4_WIDTH) +#define bfin_write_TIMER4_WIDTH(val) bfin_write32(TIMER4_WIDTH, val) +#define bfin_read_TIMER5_CONFIG() bfin_read16(TIMER5_CONFIG) +#define bfin_write_TIMER5_CONFIG(val) bfin_write16(TIMER5_CONFIG, val) +#define bfin_read_TIMER5_COUNTER() bfin_read32(TIMER5_COUNTER) +#define bfin_write_TIMER5_COUNTER(val) bfin_write32(TIMER5_COUNTER, val) +#define bfin_read_TIMER5_PERIOD() bfin_read32(TIMER5_PERIOD) +#define bfin_write_TIMER5_PERIOD(val) bfin_write32(TIMER5_PERIOD, val) +#define bfin_read_TIMER5_WIDTH() bfin_read32(TIMER5_WIDTH) +#define bfin_write_TIMER5_WIDTH(val) bfin_write32(TIMER5_WIDTH, val) +#define bfin_read_TIMER6_CONFIG() bfin_read16(TIMER6_CONFIG) +#define bfin_write_TIMER6_CONFIG(val) bfin_write16(TIMER6_CONFIG, val) +#define bfin_read_TIMER6_COUNTER() bfin_read32(TIMER6_COUNTER) +#define bfin_write_TIMER6_COUNTER(val) bfin_write32(TIMER6_COUNTER, val) +#define bfin_read_TIMER6_PERIOD() bfin_read32(TIMER6_PERIOD) +#define bfin_write_TIMER6_PERIOD(val) bfin_write32(TIMER6_PERIOD, val) +#define bfin_read_TIMER6_WIDTH() bfin_read32(TIMER6_WIDTH) +#define bfin_write_TIMER6_WIDTH(val) bfin_write32(TIMER6_WIDTH, val) +#define bfin_read_TIMER7_CONFIG() bfin_read16(TIMER7_CONFIG) +#define bfin_write_TIMER7_CONFIG(val) bfin_write16(TIMER7_CONFIG, val) +#define bfin_read_TIMER7_COUNTER() bfin_read32(TIMER7_COUNTER) +#define bfin_write_TIMER7_COUNTER(val) bfin_write32(TIMER7_COUNTER, val) +#define bfin_read_TIMER7_PERIOD() bfin_read32(TIMER7_PERIOD) +#define bfin_write_TIMER7_PERIOD(val) bfin_write32(TIMER7_PERIOD, val) +#define bfin_read_TIMER7_WIDTH() bfin_read32(TIMER7_WIDTH) +#define bfin_write_TIMER7_WIDTH(val) bfin_write32(TIMER7_WIDTH, val) + + + + +/* Two Wire Interface Registers (TWI0) */ + +/* SPORT1 Registers */ + + +/* SMC Registers */ +#define bfin_read_SMC_GCTL() bfin_read32(SMC_GCTL) +#define bfin_write_SMC_GCTL(val) bfin_write32(SMC_GCTL, val) +#define bfin_read_SMC_GSTAT() bfin_read32(SMC_GSTAT) +#define bfin_read_SMC_B0CTL() bfin_read32(SMC_B0CTL) +#define bfin_write_SMC_B0CTL(val) bfin_write32(SMC_B0CTL, val) +#define bfin_read_SMC_B0TIM() bfin_read32(SMC_B0TIM) +#define bfin_write_SMC_B0TIM(val) bfin_write32(SMC_B0TIM, val) +#define bfin_read_SMC_B0ETIM() bfin_read32(SMC_B0ETIM) +#define bfin_write_SMC_B0ETIM(val) bfin_write32(SMC_B0ETIM, val) +#define bfin_read_SMC_B1CTL() bfin_read32(SMC_B1CTL) +#define bfin_write_SMC_B1CTL(val) bfin_write32(SMC_B1CTL, val) +#define bfin_read_SMC_B1TIM() bfin_read32(SMC_B1TIM) +#define bfin_write_SMC_B1TIM(val) bfin_write32(SMC_B1TIM, val) +#define bfin_read_SMC_B1ETIM() bfin_read32(SMC_B1ETIM) +#define bfin_write_SMC_B1ETIM(val) bfin_write32(SMC_B1ETIM, val) +#define bfin_read_SMC_B2CTL() bfin_read32(SMC_B2CTL) +#define bfin_write_SMC_B2CTL(val) bfin_write32(SMC_B2CTL, val) +#define bfin_read_SMC_B2TIM() bfin_read32(SMC_B2TIM) +#define bfin_write_SMC_B2TIM(val) bfin_write32(SMC_B2TIM, val) +#define bfin_read_SMC_B2ETIM() bfin_read32(SMC_B2ETIM) +#define bfin_write_SMC_B2ETIM(val) bfin_write32(SMC_B2ETIM, val) +#define bfin_read_SMC_B3CTL() bfin_read32(SMC_B3CTL) +#define bfin_write_SMC_B3CTL(val) bfin_write32(SMC_B3CTL, val) +#define bfin_read_SMC_B3TIM() bfin_read32(SMC_B3TIM) +#define bfin_write_SMC_B3TIM(val) bfin_write32(SMC_B3TIM, val) +#define bfin_read_SMC_B3ETIM() bfin_read32(SMC_B3ETIM) +#define bfin_write_SMC_B3ETIM(val) bfin_write32(SMC_B3ETIM, val) + +/* DDR2 Memory Control Registers */ +#define bfin_read_DMC0_CFG() bfin_read32(DMC0_CFG) +#define bfin_write_DMC0_CFG(val) bfin_write32(DMC0_CFG, val) +#define bfin_read_DMC0_TR0() bfin_read32(DMC0_TR0) +#define bfin_write_DMC0_TR0(val) bfin_write32(DMC0_TR0, val) +#define bfin_read_DMC0_TR1() bfin_read32(DMC0_TR1) +#define bfin_write_DMC0_TR1(val) bfin_write32(DMC0_TR1, val) +#define bfin_read_DMC0_TR2() bfin_read32(DMC0_TR2) +#define bfin_write_DMC0_TR2(val) bfin_write32(DMC0_TR2, val) +#define bfin_read_DMC0_MR() bfin_read32(DMC0_MR) +#define bfin_write_DMC0_MR(val) bfin_write32(DMC0_MR, val) +#define bfin_read_DMC0_EMR1() bfin_read32(DMC0_EMR1) +#define bfin_write_DMC0_EMR1(val) bfin_write32(DMC0_EMR1, val) +#define bfin_read_DMC0_CTL() bfin_read32(DMC0_CTL) +#define bfin_write_DMC0_CTL(val) bfin_write32(DMC0_CTL, val) +#define bfin_read_DMC0_STAT() bfin_read32(DMC0_STAT) +#define bfin_write_DMC0_STAT(val) bfin_write32(DMC0_STAT, val) +#define bfin_read_DMC0_DLLCTL() bfin_read32(DMC0_DLLCTL) +#define bfin_write_DMC0_DLLCTL(val) bfin_write32(DMC0_DLLCTL, val) + +/* DDR BankRead and Write Count Registers */ + + +/* DMA Channel 0 Registers */ + +#define bfin_read_DMA0_NEXT_DESC_PTR() bfin_read32(DMA0_NEXT_DESC_PTR) +#define bfin_write_DMA0_NEXT_DESC_PTR(val) bfin_write32(DMA0_NEXT_DESC_PTR, val) +#define bfin_read_DMA0_START_ADDR() bfin_read32(DMA0_START_ADDR) +#define bfin_write_DMA0_START_ADDR(val) bfin_write32(DMA0_START_ADDR, val) +#define bfin_read_DMA0_CONFIG() bfin_read32(DMA0_CONFIG) +#define bfin_write_DMA0_CONFIG(val) bfin_write32(DMA0_CONFIG, val) +#define bfin_read_DMA0_X_COUNT() bfin_read32(DMA0_X_COUNT) +#define bfin_write_DMA0_X_COUNT(val) bfin_write32(DMA0_X_COUNT, val) +#define bfin_read_DMA0_X_MODIFY() bfin_read32(DMA0_X_MODIFY) +#define bfin_write_DMA0_X_MODIFY(val) bfin_write32(DMA0_X_MODIFY, val) +#define bfin_read_DMA0_Y_COUNT() bfin_read32(DMA0_Y_COUNT) +#define bfin_write_DMA0_Y_COUNT(val) bfin_write32(DMA0_Y_COUNT, val) +#define bfin_read_DMA0_Y_MODIFY() bfin_read32(DMA0_Y_MODIFY) +#define bfin_write_DMA0_Y_MODIFY(val) bfin_write32(DMA0_Y_MODIFY, val) +#define bfin_read_DMA0_CURR_DESC_PTR() bfin_read32(DMA0_CURR_DESC_PTR) +#define bfin_write_DMA0_CURR_DESC_PTR(val) bfin_write32(DMA0_CURR_DESC_PTR, val) +#define bfin_read_DMA0_PREV_DESC_PTR() bfin_read32(DMA0_PREV_DESC_PTR) +#define bfin_write_DMA0_PREV_DESC_PTR(val) bfin_write32(DMA0_PREV_DESC_PTR, val) +#define bfin_read_DMA0_CURR_ADDR() bfin_read32(DMA0_CURR_ADDR) +#define bfin_write_DMA0_CURR_ADDR(val) bfin_write32(DMA0_CURR_ADDR, val) +#define bfin_read_DMA0_IRQ_STATUS() bfin_read32(DMA0_IRQ_STATUS) +#define bfin_write_DMA0_IRQ_STATUS(val) bfin_write32(DMA0_IRQ_STATUS, val) +#define bfin_read_DMA0_CURR_X_COUNT() bfin_read32(DMA0_CURR_X_COUNT) +#define bfin_write_DMA0_CURR_X_COUNT(val) bfin_write32(DMA0_CURR_X_COUNT, val) +#define bfin_read_DMA0_CURR_Y_COUNT() bfin_read32(DMA0_CURR_Y_COUNT) +#define bfin_write_DMA0_CURR_Y_COUNT(val) bfin_write32(DMA0_CURR_Y_COUNT, val) +#define bfin_read_DMA0_BWL_COUNT() bfin_read32(DMA0_BWL_COUNT) +#define bfin_write_DMA0_BWL_COUNT(val) bfin_write32(DMA0_BWL_COUNT, val) +#define bfin_read_DMA0_CURR_BWL_COUNT() bfin_read32(DMA0_CURR_BWL_COUNT) +#define bfin_write_DMA0_CURR_BWL_COUNT(val) bfin_write32(DMA0_CURR_BWL_COUNT, val) +#define bfin_read_DMA0_BWM_COUNT() bfin_read32(DMA0_BWM_COUNT) +#define bfin_write_DMA0_BWM_COUNT(val) bfin_write32(DMA0_BWM_COUNT, val) +#define bfin_read_DMA0_CURR_BWM_COUNT() bfin_read32(DMA0_CURR_BWM_COUNT) +#define bfin_write_DMA0_CURR_BWM_COUNT(val) bfin_write32(DMA0_CURR_BWM_COUNT, val) + +/* DMA Channel 1 Registers */ + +#define bfin_read_DMA1_NEXT_DESC_PTR() bfin_read32(DMA1_NEXT_DESC_PTR) +#define bfin_write_DMA1_NEXT_DESC_PTR(val) bfin_write32(DMA1_NEXT_DESC_PTR, val) +#define bfin_read_DMA1_START_ADDR() bfin_read32(DMA1_START_ADDR) +#define bfin_write_DMA1_START_ADDR(val) bfin_write32(DMA1_START_ADDR, val) +#define bfin_read_DMA1_CONFIG() bfin_read32(DMA1_CONFIG) +#define bfin_write_DMA1_CONFIG(val) bfin_write32(DMA1_CONFIG, val) +#define bfin_read_DMA1_X_COUNT() bfin_read32(DMA1_X_COUNT) +#define bfin_write_DMA1_X_COUNT(val) bfin_write32(DMA1_X_COUNT, val) +#define bfin_read_DMA1_X_MODIFY() bfin_read32(DMA1_X_MODIFY) +#define bfin_write_DMA1_X_MODIFY(val) bfin_write32(DMA1_X_MODIFY, val) +#define bfin_read_DMA1_Y_COUNT() bfin_read32(DMA1_Y_COUNT) +#define bfin_write_DMA1_Y_COUNT(val) bfin_write32(DMA1_Y_COUNT, val) +#define bfin_read_DMA1_Y_MODIFY() bfin_read32(DMA1_Y_MODIFY) +#define bfin_write_DMA1_Y_MODIFY(val) bfin_write32(DMA1_Y_MODIFY, val) +#define bfin_read_DMA1_CURR_DESC_PTR() bfin_read32(DMA1_CURR_DESC_PTR) +#define bfin_write_DMA1_CURR_DESC_PTR(val) bfin_write32(DMA1_CURR_DESC_PTR, val) +#define bfin_read_DMA1_PREV_DESC_PTR() bfin_read32(DMA1_PREV_DESC_PTR) +#define bfin_write_DMA1_PREV_DESC_PTR(val) bfin_write32(DMA1_PREV_DESC_PTR, val) +#define bfin_read_DMA1_CURR_ADDR() bfin_read32(DMA1_CURR_ADDR) +#define bfin_write_DMA1_CURR_ADDR(val) bfin_write32(DMA1_CURR_ADDR, val) +#define bfin_read_DMA1_IRQ_STATUS() bfin_read32(DMA1_IRQ_STATUS) +#define bfin_write_DMA1_IRQ_STATUS(val) bfin_write32(DMA1_IRQ_STATUS, val) +#define bfin_read_DMA1_CURR_X_COUNT() bfin_read32(DMA1_CURR_X_COUNT) +#define bfin_write_DMA1_CURR_X_COUNT(val) bfin_write32(DMA1_CURR_X_COUNT, val) +#define bfin_read_DMA1_CURR_Y_COUNT() bfin_read32(DMA1_CURR_Y_COUNT) +#define bfin_write_DMA1_CURR_Y_COUNT(val) bfin_write32(DMA1_CURR_Y_COUNT, val) +#define bfin_read_DMA1_BWL_COUNT() bfin_read32(DMA1_BWL_COUNT) +#define bfin_write_DMA1_BWL_COUNT(val) bfin_write32(DMA1_BWL_COUNT, val) +#define bfin_read_DMA1_CURR_BWL_COUNT() bfin_read32(DMA1_CURR_BWL_COUNT) +#define bfin_write_DMA1_CURR_BWL_COUNT(val) bfin_write32(DMA1_CURR_BWL_COUNT, val) +#define bfin_read_DMA1_BWM_COUNT() bfin_read32(DMA1_BWM_COUNT) +#define bfin_write_DMA1_BWM_COUNT(val) bfin_write32(DMA1_BWM_COUNT, val) +#define bfin_read_DMA1_CURR_BWM_COUNT() bfin_read32(DMA1_CURR_BWM_COUNT) +#define bfin_write_DMA1_CURR_BWM_COUNT(val) bfin_write32(DMA1_CURR_BWM_COUNT, val) + +/* DMA Channel 2 Registers */ + +#define bfin_read_DMA2_NEXT_DESC_PTR() bfin_read32(DMA2_NEXT_DESC_PTR) +#define bfin_write_DMA2_NEXT_DESC_PTR(val) bfin_write32(DMA2_NEXT_DESC_PTR, val) +#define bfin_read_DMA2_START_ADDR() bfin_read32(DMA2_START_ADDR) +#define bfin_write_DMA2_START_ADDR(val) bfin_write32(DMA2_START_ADDR, val) +#define bfin_read_DMA2_CONFIG() bfin_read32(DMA2_CONFIG) +#define bfin_write_DMA2_CONFIG(val) bfin_write32(DMA2_CONFIG, val) +#define bfin_read_DMA2_X_COUNT() bfin_read32(DMA2_X_COUNT) +#define bfin_write_DMA2_X_COUNT(val) bfin_write32(DMA2_X_COUNT, val) +#define bfin_read_DMA2_X_MODIFY() bfin_read32(DMA2_X_MODIFY) +#define bfin_write_DMA2_X_MODIFY(val) bfin_write32(DMA2_X_MODIFY, val) +#define bfin_read_DMA2_Y_COUNT() bfin_read32(DMA2_Y_COUNT) +#define bfin_write_DMA2_Y_COUNT(val) bfin_write32(DMA2_Y_COUNT, val) +#define bfin_read_DMA2_Y_MODIFY() bfin_read32(DMA2_Y_MODIFY) +#define bfin_write_DMA2_Y_MODIFY(val) bfin_write32(DMA2_Y_MODIFY, val) +#define bfin_read_DMA2_CURR_DESC_PTR() bfin_read32(DMA2_CURR_DESC_PTR) +#define bfin_write_DMA2_CURR_DESC_PTR(val) bfin_write32(DMA2_CURR_DESC_PTR, val) +#define bfin_read_DMA2_PREV_DESC_PTR() bfin_read32(DMA2_PREV_DESC_PTR) +#define bfin_write_DMA2_PREV_DESC_PTR(val) bfin_write32(DMA2_PREV_DESC_PTR, val) +#define bfin_read_DMA2_CURR_ADDR() bfin_read32(DMA2_CURR_ADDR) +#define bfin_write_DMA2_CURR_ADDR(val) bfin_write32(DMA2_CURR_ADDR, val) +#define bfin_read_DMA2_IRQ_STATUS() bfin_read32(DMA2_IRQ_STATUS) +#define bfin_write_DMA2_IRQ_STATUS(val) bfin_write32(DMA2_IRQ_STATUS, val) +#define bfin_read_DMA2_CURR_X_COUNT() bfin_read32(DMA2_CURR_X_COUNT) +#define bfin_write_DMA2_CURR_X_COUNT(val) bfin_write32(DMA2_CURR_X_COUNT, val) +#define bfin_read_DMA2_CURR_Y_COUNT() bfin_read32(DMA2_CURR_Y_COUNT) +#define bfin_write_DMA2_CURR_Y_COUNT(val) bfin_write32(DMA2_CURR_Y_COUNT, val) +#define bfin_read_DMA2_BWL_COUNT() bfin_read32(DMA2_BWL_COUNT) +#define bfin_write_DMA2_BWL_COUNT(val) bfin_write32(DMA2_BWL_COUNT, val) +#define bfin_read_DMA2_CURR_BWL_COUNT() bfin_read32(DMA2_CURR_BWL_COUNT) +#define bfin_write_DMA2_CURR_BWL_COUNT(val) bfin_write32(DMA2_CURR_BWL_COUNT, val) +#define bfin_read_DMA2_BWM_COUNT() bfin_read32(DMA2_BWM_COUNT) +#define bfin_write_DMA2_BWM_COUNT(val) bfin_write32(DMA2_BWM_COUNT, val) +#define bfin_read_DMA2_CURR_BWM_COUNT() bfin_read32(DMA2_CURR_BWM_COUNT) +#define bfin_write_DMA2_CURR_BWM_COUNT(val) bfin_write32(DMA2_CURR_BWM_COUNT, val) + +/* DMA Channel 3 Registers */ + +#define bfin_read_DMA3_NEXT_DESC_PTR() bfin_read32(DMA3_NEXT_DESC_PTR) +#define bfin_write_DMA3_NEXT_DESC_PTR(val) bfin_write32(DMA3_NEXT_DESC_PTR, val) +#define bfin_read_DMA3_START_ADDR() bfin_read32(DMA3_START_ADDR) +#define bfin_write_DMA3_START_ADDR(val) bfin_write32(DMA3_START_ADDR, val) +#define bfin_read_DMA3_CONFIG() bfin_read32(DMA3_CONFIG) +#define bfin_write_DMA3_CONFIG(val) bfin_write32(DMA3_CONFIG, val) +#define bfin_read_DMA3_X_COUNT() bfin_read32(DMA3_X_COUNT) +#define bfin_write_DMA3_X_COUNT(val) bfin_write32(DMA3_X_COUNT, val) +#define bfin_read_DMA3_X_MODIFY() bfin_read32(DMA3_X_MODIFY) +#define bfin_write_DMA3_X_MODIFY(val) bfin_write32(DMA3_X_MODIFY, val) +#define bfin_read_DMA3_Y_COUNT() bfin_read32(DMA3_Y_COUNT) +#define bfin_write_DMA3_Y_COUNT(val) bfin_write32(DMA3_Y_COUNT, val) +#define bfin_read_DMA3_Y_MODIFY() bfin_read32(DMA3_Y_MODIFY) +#define bfin_write_DMA3_Y_MODIFY(val) bfin_write32(DMA3_Y_MODIFY, val) +#define bfin_read_DMA3_CURR_DESC_PTR() bfin_read32(DMA3_CURR_DESC_PTR) +#define bfin_write_DMA3_CURR_DESC_PTR(val) bfin_write32(DMA3_CURR_DESC_PTR, val) +#define bfin_read_DMA3_PREV_DESC_PTR() bfin_read32(DMA3_PREV_DESC_PTR) +#define bfin_write_DMA3_PREV_DESC_PTR(val) bfin_write32(DMA3_PREV_DESC_PTR, val) +#define bfin_read_DMA3_CURR_ADDR() bfin_read32(DMA3_CURR_ADDR) +#define bfin_write_DMA3_CURR_ADDR(val) bfin_write32(DMA3_CURR_ADDR, val) +#define bfin_read_DMA3_IRQ_STATUS() bfin_read32(DMA3_IRQ_STATUS) +#define bfin_write_DMA3_IRQ_STATUS(val) bfin_write32(DMA3_IRQ_STATUS, val) +#define bfin_read_DMA3_CURR_X_COUNT() bfin_read32(DMA3_CURR_X_COUNT) +#define bfin_write_DMA3_CURR_X_COUNT(val) bfin_write32(DMA3_CURR_X_COUNT, val) +#define bfin_read_DMA3_CURR_Y_COUNT() bfin_read32(DMA3_CURR_Y_COUNT) +#define bfin_write_DMA3_CURR_Y_COUNT(val) bfin_write32(DMA3_CURR_Y_COUNT, val) +#define bfin_read_DMA3_BWL_COUNT() bfin_read32(DMA3_BWL_COUNT) +#define bfin_write_DMA3_BWL_COUNT(val) bfin_write32(DMA3_BWL_COUNT, val) +#define bfin_read_DMA3_CURR_BWL_COUNT() bfin_read32(DMA3_CURR_BWL_COUNT) +#define bfin_write_DMA3_CURR_BWL_COUNT(val) bfin_write32(DMA3_CURR_BWL_COUNT, val) +#define bfin_read_DMA3_BWM_COUNT() bfin_read32(DMA3_BWM_COUNT) +#define bfin_write_DMA3_BWM_COUNT(val) bfin_write32(DMA3_BWM_COUNT, val) +#define bfin_read_DMA3_CURR_BWM_COUNT() bfin_read32(DMA3_CURR_BWM_COUNT) +#define bfin_write_DMA3_CURR_BWM_COUNT(val) bfin_write32(DMA3_CURR_BWM_COUNT, val) + +/* DMA Channel 4 Registers */ + +#define bfin_read_DMA4_NEXT_DESC_PTR() bfin_read32(DMA4_NEXT_DESC_PTR) +#define bfin_write_DMA4_NEXT_DESC_PTR(val) bfin_write32(DMA4_NEXT_DESC_PTR, val) +#define bfin_read_DMA4_START_ADDR() bfin_read32(DMA4_START_ADDR) +#define bfin_write_DMA4_START_ADDR(val) bfin_write32(DMA4_START_ADDR, val) +#define bfin_read_DMA4_CONFIG() bfin_read32(DMA4_CONFIG) +#define bfin_write_DMA4_CONFIG(val) bfin_write32(DMA4_CONFIG, val) +#define bfin_read_DMA4_X_COUNT() bfin_read32(DMA4_X_COUNT) +#define bfin_write_DMA4_X_COUNT(val) bfin_write32(DMA4_X_COUNT, val) +#define bfin_read_DMA4_X_MODIFY() bfin_read32(DMA4_X_MODIFY) +#define bfin_write_DMA4_X_MODIFY(val) bfin_write32(DMA4_X_MODIFY, val) +#define bfin_read_DMA4_Y_COUNT() bfin_read32(DMA4_Y_COUNT) +#define bfin_write_DMA4_Y_COUNT(val) bfin_write32(DMA4_Y_COUNT, val) +#define bfin_read_DMA4_Y_MODIFY() bfin_read32(DMA4_Y_MODIFY) +#define bfin_write_DMA4_Y_MODIFY(val) bfin_write32(DMA4_Y_MODIFY, val) +#define bfin_read_DMA4_CURR_DESC_PTR() bfin_read32(DMA4_CURR_DESC_PTR) +#define bfin_write_DMA4_CURR_DESC_PTR(val) bfin_write32(DMA4_CURR_DESC_PTR, val) +#define bfin_read_DMA4_PREV_DESC_PTR() bfin_read32(DMA4_PREV_DESC_PTR) +#define bfin_write_DMA4_PREV_DESC_PTR(val) bfin_write32(DMA4_PREV_DESC_PTR, val) +#define bfin_read_DMA4_CURR_ADDR() bfin_read32(DMA4_CURR_ADDR) +#define bfin_write_DMA4_CURR_ADDR(val) bfin_write32(DMA4_CURR_ADDR, val) +#define bfin_read_DMA4_IRQ_STATUS() bfin_read32(DMA4_IRQ_STATUS) +#define bfin_write_DMA4_IRQ_STATUS(val) bfin_write32(DMA4_IRQ_STATUS, val) +#define bfin_read_DMA4_CURR_X_COUNT() bfin_read32(DMA4_CURR_X_COUNT) +#define bfin_write_DMA4_CURR_X_COUNT(val) bfin_write32(DMA4_CURR_X_COUNT, val) +#define bfin_read_DMA4_CURR_Y_COUNT() bfin_read32(DMA4_CURR_Y_COUNT) +#define bfin_write_DMA4_CURR_Y_COUNT(val) bfin_write32(DMA4_CURR_Y_COUNT, val) +#define bfin_read_DMA4_BWL_COUNT() bfin_read32(DMA4_BWL_COUNT) +#define bfin_write_DMA4_BWL_COUNT(val) bfin_write32(DMA4_BWL_COUNT, val) +#define bfin_read_DMA4_CURR_BWL_COUNT() bfin_read32(DMA4_CURR_BWL_COUNT) +#define bfin_write_DMA4_CURR_BWL_COUNT(val) bfin_write32(DMA4_CURR_BWL_COUNT, val) +#define bfin_read_DMA4_BWM_COUNT() bfin_read32(DMA4_BWM_COUNT) +#define bfin_write_DMA4_BWM_COUNT(val) bfin_write32(DMA4_BWM_COUNT, val) +#define bfin_read_DMA4_CURR_BWM_COUNT() bfin_read32(DMA4_CURR_BWM_COUNT) +#define bfin_write_DMA4_CURR_BWM_COUNT(val) bfin_write32(DMA4_CURR_BWM_COUNT, val) + +/* DMA Channel 5 Registers */ + +#define bfin_read_DMA5_NEXT_DESC_PTR() bfin_read32(DMA5_NEXT_DESC_PTR) +#define bfin_write_DMA5_NEXT_DESC_PTR(val) bfin_write32(DMA5_NEXT_DESC_PTR, val) +#define bfin_read_DMA5_START_ADDR() bfin_read32(DMA5_START_ADDR) +#define bfin_write_DMA5_START_ADDR(val) bfin_write32(DMA5_START_ADDR, val) +#define bfin_read_DMA5_CONFIG() bfin_read32(DMA5_CONFIG) +#define bfin_write_DMA5_CONFIG(val) bfin_write32(DMA5_CONFIG, val) +#define bfin_read_DMA5_X_COUNT() bfin_read32(DMA5_X_COUNT) +#define bfin_write_DMA5_X_COUNT(val) bfin_write32(DMA5_X_COUNT, val) +#define bfin_read_DMA5_X_MODIFY() bfin_read32(DMA5_X_MODIFY) +#define bfin_write_DMA5_X_MODIFY(val) bfin_write32(DMA5_X_MODIFY, val) +#define bfin_read_DMA5_Y_COUNT() bfin_read32(DMA5_Y_COUNT) +#define bfin_write_DMA5_Y_COUNT(val) bfin_write32(DMA5_Y_COUNT, val) +#define bfin_read_DMA5_Y_MODIFY() bfin_read32(DMA5_Y_MODIFY) +#define bfin_write_DMA5_Y_MODIFY(val) bfin_write32(DMA5_Y_MODIFY, val) +#define bfin_read_DMA5_CURR_DESC_PTR() bfin_read32(DMA5_CURR_DESC_PTR) +#define bfin_write_DMA5_CURR_DESC_PTR(val) bfin_write32(DMA5_CURR_DESC_PTR, val) +#define bfin_read_DMA5_PREV_DESC_PTR() bfin_read32(DMA5_PREV_DESC_PTR) +#define bfin_write_DMA5_PREV_DESC_PTR(val) bfin_write32(DMA5_PREV_DESC_PTR, val) +#define bfin_read_DMA5_CURR_ADDR() bfin_read32(DMA5_CURR_ADDR) +#define bfin_write_DMA5_CURR_ADDR(val) bfin_write32(DMA5_CURR_ADDR, val) +#define bfin_read_DMA5_IRQ_STATUS() bfin_read32(DMA5_IRQ_STATUS) +#define bfin_write_DMA5_IRQ_STATUS(val) bfin_write32(DMA5_IRQ_STATUS, val) +#define bfin_read_DMA5_CURR_X_COUNT() bfin_read32(DMA5_CURR_X_COUNT) +#define bfin_write_DMA5_CURR_X_COUNT(val) bfin_write32(DMA5_CURR_X_COUNT, val) +#define bfin_read_DMA5_CURR_Y_COUNT() bfin_read32(DMA5_CURR_Y_COUNT) +#define bfin_write_DMA5_CURR_Y_COUNT(val) bfin_write32(DMA5_CURR_Y_COUNT, val) +#define bfin_read_DMA5_BWL_COUNT() bfin_read32(DMA5_BWL_COUNT) +#define bfin_write_DMA5_BWL_COUNT(val) bfin_write32(DMA5_BWL_COUNT, val) +#define bfin_read_DMA5_CURR_BWL_COUNT() bfin_read32(DMA5_CURR_BWL_COUNT) +#define bfin_write_DMA5_CURR_BWL_COUNT(val) bfin_write32(DMA5_CURR_BWL_COUNT, val) +#define bfin_read_DMA5_BWM_COUNT() bfin_read32(DMA5_BWM_COUNT) +#define bfin_write_DMA5_BWM_COUNT(val) bfin_write32(DMA5_BWM_COUNT, val) +#define bfin_read_DMA5_CURR_BWM_COUNT() bfin_read32(DMA5_CURR_BWM_COUNT) +#define bfin_write_DMA5_CURR_BWM_COUNT(val) bfin_write32(DMA5_CURR_BWM_COUNT, val) + +/* DMA Channel 6 Registers */ + +#define bfin_read_DMA6_NEXT_DESC_PTR() bfin_read32(DMA6_NEXT_DESC_PTR) +#define bfin_write_DMA6_NEXT_DESC_PTR(val) bfin_write32(DMA6_NEXT_DESC_PTR, val) +#define bfin_read_DMA6_START_ADDR() bfin_read32(DMA6_START_ADDR) +#define bfin_write_DMA6_START_ADDR(val) bfin_write32(DMA6_START_ADDR, val) +#define bfin_read_DMA6_CONFIG() bfin_read32(DMA6_CONFIG) +#define bfin_write_DMA6_CONFIG(val) bfin_write32(DMA6_CONFIG, val) +#define bfin_read_DMA6_X_COUNT() bfin_read32(DMA6_X_COUNT) +#define bfin_write_DMA6_X_COUNT(val) bfin_write32(DMA6_X_COUNT, val) +#define bfin_read_DMA6_X_MODIFY() bfin_read32(DMA6_X_MODIFY) +#define bfin_write_DMA6_X_MODIFY(val) bfin_write32(DMA6_X_MODIFY, val) +#define bfin_read_DMA6_Y_COUNT() bfin_read32(DMA6_Y_COUNT) +#define bfin_write_DMA6_Y_COUNT(val) bfin_write32(DMA6_Y_COUNT, val) +#define bfin_read_DMA6_Y_MODIFY() bfin_read32(DMA6_Y_MODIFY) +#define bfin_write_DMA6_Y_MODIFY(val) bfin_write32(DMA6_Y_MODIFY, val) +#define bfin_read_DMA6_CURR_DESC_PTR() bfin_read32(DMA6_CURR_DESC_PTR) +#define bfin_write_DMA6_CURR_DESC_PTR(val) bfin_write32(DMA6_CURR_DESC_PTR, val) +#define bfin_read_DMA6_PREV_DESC_PTR() bfin_read32(DMA6_PREV_DESC_PTR) +#define bfin_write_DMA6_PREV_DESC_PTR(val) bfin_write32(DMA6_PREV_DESC_PTR, val) +#define bfin_read_DMA6_CURR_ADDR() bfin_read32(DMA6_CURR_ADDR) +#define bfin_write_DMA6_CURR_ADDR(val) bfin_write32(DMA6_CURR_ADDR, val) +#define bfin_read_DMA6_IRQ_STATUS() bfin_read32(DMA6_IRQ_STATUS) +#define bfin_write_DMA6_IRQ_STATUS(val) bfin_write32(DMA6_IRQ_STATUS, val) +#define bfin_read_DMA6_CURR_X_COUNT() bfin_read32(DMA6_CURR_X_COUNT) +#define bfin_write_DMA6_CURR_X_COUNT(val) bfin_write32(DMA6_CURR_X_COUNT, val) +#define bfin_read_DMA6_CURR_Y_COUNT() bfin_read32(DMA6_CURR_Y_COUNT) +#define bfin_write_DMA6_CURR_Y_COUNT(val) bfin_write32(DMA6_CURR_Y_COUNT, val) +#define bfin_read_DMA6_BWL_COUNT() bfin_read32(DMA6_BWL_COUNT) +#define bfin_write_DMA6_BWL_COUNT(val) bfin_write32(DMA6_BWL_COUNT, val) +#define bfin_read_DMA6_CURR_BWL_COUNT() bfin_read32(DMA6_CURR_BWL_COUNT) +#define bfin_write_DMA6_CURR_BWL_COUNT(val) bfin_write32(DMA6_CURR_BWL_COUNT, val) +#define bfin_read_DMA6_BWM_COUNT() bfin_read32(DMA6_BWM_COUNT) +#define bfin_write_DMA6_BWM_COUNT(val) bfin_write32(DMA6_BWM_COUNT, val) +#define bfin_read_DMA6_CURR_BWM_COUNT() bfin_read32(DMA6_CURR_BWM_COUNT) +#define bfin_write_DMA6_CURR_BWM_COUNT(val) bfin_write32(DMA6_CURR_BWM_COUNT, val) + +/* DMA Channel 7 Registers */ + +#define bfin_read_DMA7_NEXT_DESC_PTR() bfin_read32(DMA7_NEXT_DESC_PTR) +#define bfin_write_DMA7_NEXT_DESC_PTR(val) bfin_write32(DMA7_NEXT_DESC_PTR, val) +#define bfin_read_DMA7_START_ADDR() bfin_read32(DMA7_START_ADDR) +#define bfin_write_DMA7_START_ADDR(val) bfin_write32(DMA7_START_ADDR, val) +#define bfin_read_DMA7_CONFIG() bfin_read32(DMA7_CONFIG) +#define bfin_write_DMA7_CONFIG(val) bfin_write32(DMA7_CONFIG, val) +#define bfin_read_DMA7_X_COUNT() bfin_read32(DMA7_X_COUNT) +#define bfin_write_DMA7_X_COUNT(val) bfin_write32(DMA7_X_COUNT, val) +#define bfin_read_DMA7_X_MODIFY() bfin_read32(DMA7_X_MODIFY) +#define bfin_write_DMA7_X_MODIFY(val) bfin_write32(DMA7_X_MODIFY, val) +#define bfin_read_DMA7_Y_COUNT() bfin_read32(DMA7_Y_COUNT) +#define bfin_write_DMA7_Y_COUNT(val) bfin_write32(DMA7_Y_COUNT, val) +#define bfin_read_DMA7_Y_MODIFY() bfin_read32(DMA7_Y_MODIFY) +#define bfin_write_DMA7_Y_MODIFY(val) bfin_write32(DMA7_Y_MODIFY, val) +#define bfin_read_DMA7_CURR_DESC_PTR() bfin_read32(DMA7_CURR_DESC_PTR) +#define bfin_write_DMA7_CURR_DESC_PTR(val) bfin_write32(DMA7_CURR_DESC_PTR, val) +#define bfin_read_DMA7_PREV_DESC_PTR() bfin_read32(DMA7_PREV_DESC_PTR) +#define bfin_write_DMA7_PREV_DESC_PTR(val) bfin_write32(DMA7_PREV_DESC_PTR, val) +#define bfin_read_DMA7_CURR_ADDR() bfin_read32(DMA7_CURR_ADDR) +#define bfin_write_DMA7_CURR_ADDR(val) bfin_write32(DMA7_CURR_ADDR, val) +#define bfin_read_DMA7_IRQ_STATUS() bfin_read32(DMA7_IRQ_STATUS) +#define bfin_write_DMA7_IRQ_STATUS(val) bfin_write32(DMA7_IRQ_STATUS, val) +#define bfin_read_DMA7_CURR_X_COUNT() bfin_read32(DMA7_CURR_X_COUNT) +#define bfin_write_DMA7_CURR_X_COUNT(val) bfin_write32(DMA7_CURR_X_COUNT, val) +#define bfin_read_DMA7_CURR_Y_COUNT() bfin_read32(DMA7_CURR_Y_COUNT) +#define bfin_write_DMA7_CURR_Y_COUNT(val) bfin_write32(DMA7_CURR_Y_COUNT, val) +#define bfin_read_DMA7_BWL_COUNT() bfin_read32(DMA7_BWL_COUNT) +#define bfin_write_DMA7_BWL_COUNT(val) bfin_write32(DMA7_BWL_COUNT, val) +#define bfin_read_DMA7_CURR_BWL_COUNT() bfin_read32(DMA7_CURR_BWL_COUNT) +#define bfin_write_DMA7_CURR_BWL_COUNT(val) bfin_write32(DMA7_CURR_BWL_COUNT, val) +#define bfin_read_DMA7_BWM_COUNT() bfin_read32(DMA7_BWM_COUNT) +#define bfin_write_DMA7_BWM_COUNT(val) bfin_write32(DMA7_BWM_COUNT, val) +#define bfin_read_DMA7_CURR_BWM_COUNT() bfin_read32(DMA7_CURR_BWM_COUNT) +#define bfin_write_DMA7_CURR_BWM_COUNT(val) bfin_write32(DMA7_CURR_BWM_COUNT, val) + +/* DMA Channel 8 Registers */ + +#define bfin_read_DMA8_NEXT_DESC_PTR() bfin_read32(DMA8_NEXT_DESC_PTR) +#define bfin_write_DMA8_NEXT_DESC_PTR(val) bfin_write32(DMA8_NEXT_DESC_PTR, val) +#define bfin_read_DMA8_START_ADDR() bfin_read32(DMA8_START_ADDR) +#define bfin_write_DMA8_START_ADDR(val) bfin_write32(DMA8_START_ADDR, val) +#define bfin_read_DMA8_CONFIG() bfin_read32(DMA8_CONFIG) +#define bfin_write_DMA8_CONFIG(val) bfin_write32(DMA8_CONFIG, val) +#define bfin_read_DMA8_X_COUNT() bfin_read32(DMA8_X_COUNT) +#define bfin_write_DMA8_X_COUNT(val) bfin_write32(DMA8_X_COUNT, val) +#define bfin_read_DMA8_X_MODIFY() bfin_read32(DMA8_X_MODIFY) +#define bfin_write_DMA8_X_MODIFY(val) bfin_write32(DMA8_X_MODIFY, val) +#define bfin_read_DMA8_Y_COUNT() bfin_read32(DMA8_Y_COUNT) +#define bfin_write_DMA8_Y_COUNT(val) bfin_write32(DMA8_Y_COUNT, val) +#define bfin_read_DMA8_Y_MODIFY() bfin_read32(DMA8_Y_MODIFY) +#define bfin_write_DMA8_Y_MODIFY(val) bfin_write32(DMA8_Y_MODIFY, val) +#define bfin_read_DMA8_CURR_DESC_PTR() bfin_read32(DMA8_CURR_DESC_PTR) +#define bfin_write_DMA8_CURR_DESC_PTR(val) bfin_write32(DMA8_CURR_DESC_PTR, val) +#define bfin_read_DMA8_PREV_DESC_PTR() bfin_read32(DMA8_PREV_DESC_PTR) +#define bfin_write_DMA8_PREV_DESC_PTR(val) bfin_write32(DMA8_PREV_DESC_PTR, val) +#define bfin_read_DMA8_CURR_ADDR() bfin_read32(DMA8_CURR_ADDR) +#define bfin_write_DMA8_CURR_ADDR(val) bfin_write32(DMA8_CURR_ADDR, val) +#define bfin_read_DMA8_IRQ_STATUS() bfin_read32(DMA8_IRQ_STATUS) +#define bfin_write_DMA8_IRQ_STATUS(val) bfin_write32(DMA8_IRQ_STATUS, val) +#define bfin_read_DMA8_CURR_X_COUNT() bfin_read32(DMA8_CURR_X_COUNT) +#define bfin_write_DMA8_CURR_X_COUNT(val) bfin_write32(DMA8_CURR_X_COUNT, val) +#define bfin_read_DMA8_CURR_Y_COUNT() bfin_read32(DMA8_CURR_Y_COUNT) +#define bfin_write_DMA8_CURR_Y_COUNT(val) bfin_write32(DMA8_CURR_Y_COUNT, val) +#define bfin_read_DMA8_BWL_COUNT() bfin_read32(DMA8_BWL_COUNT) +#define bfin_write_DMA8_BWL_COUNT(val) bfin_write32(DMA8_BWL_COUNT, val) +#define bfin_read_DMA8_CURR_BWL_COUNT() bfin_read32(DMA8_CURR_BWL_COUNT) +#define bfin_write_DMA8_CURR_BWL_COUNT(val) bfin_write32(DMA8_CURR_BWL_COUNT, val) +#define bfin_read_DMA8_BWM_COUNT() bfin_read32(DMA8_BWM_COUNT) +#define bfin_write_DMA8_BWM_COUNT(val) bfin_write32(DMA8_BWM_COUNT, val) +#define bfin_read_DMA8_CURR_BWM_COUNT() bfin_read32(DMA8_CURR_BWM_COUNT) +#define bfin_write_DMA8_CURR_BWM_COUNT(val) bfin_write32(DMA8_CURR_BWM_COUNT, val) + +/* DMA Channel 9 Registers */ + +#define bfin_read_DMA9_NEXT_DESC_PTR() bfin_read32(DMA9_NEXT_DESC_PTR) +#define bfin_write_DMA9_NEXT_DESC_PTR(val) bfin_write32(DMA9_NEXT_DESC_PTR, val) +#define bfin_read_DMA9_START_ADDR() bfin_read32(DMA9_START_ADDR) +#define bfin_write_DMA9_START_ADDR(val) bfin_write32(DMA9_START_ADDR, val) +#define bfin_read_DMA9_CONFIG() bfin_read32(DMA9_CONFIG) +#define bfin_write_DMA9_CONFIG(val) bfin_write32(DMA9_CONFIG, val) +#define bfin_read_DMA9_X_COUNT() bfin_read32(DMA9_X_COUNT) +#define bfin_write_DMA9_X_COUNT(val) bfin_write32(DMA9_X_COUNT, val) +#define bfin_read_DMA9_X_MODIFY() bfin_read32(DMA9_X_MODIFY) +#define bfin_write_DMA9_X_MODIFY(val) bfin_write32(DMA9_X_MODIFY, val) +#define bfin_read_DMA9_Y_COUNT() bfin_read32(DMA9_Y_COUNT) +#define bfin_write_DMA9_Y_COUNT(val) bfin_write32(DMA9_Y_COUNT, val) +#define bfin_read_DMA9_Y_MODIFY() bfin_read32(DMA9_Y_MODIFY) +#define bfin_write_DMA9_Y_MODIFY(val) bfin_write32(DMA9_Y_MODIFY, val) +#define bfin_read_DMA9_CURR_DESC_PTR() bfin_read32(DMA9_CURR_DESC_PTR) +#define bfin_write_DMA9_CURR_DESC_PTR(val) bfin_write32(DMA9_CURR_DESC_PTR, val) +#define bfin_read_DMA9_PREV_DESC_PTR() bfin_read32(DMA9_PREV_DESC_PTR) +#define bfin_write_DMA9_PREV_DESC_PTR(val) bfin_write32(DMA9_PREV_DESC_PTR, val) +#define bfin_read_DMA9_CURR_ADDR() bfin_read32(DMA9_CURR_ADDR) +#define bfin_write_DMA9_CURR_ADDR(val) bfin_write32(DMA9_CURR_ADDR, val) +#define bfin_read_DMA9_IRQ_STATUS() bfin_read32(DMA9_IRQ_STATUS) +#define bfin_write_DMA9_IRQ_STATUS(val) bfin_write32(DMA9_IRQ_STATUS, val) +#define bfin_read_DMA9_CURR_X_COUNT() bfin_read32(DMA9_CURR_X_COUNT) +#define bfin_write_DMA9_CURR_X_COUNT(val) bfin_write32(DMA9_CURR_X_COUNT, val) +#define bfin_read_DMA9_CURR_Y_COUNT() bfin_read32(DMA9_CURR_Y_COUNT) +#define bfin_write_DMA9_CURR_Y_COUNT(val) bfin_write32(DMA9_CURR_Y_COUNT, val) +#define bfin_read_DMA9_BWL_COUNT() bfin_read32(DMA9_BWL_COUNT) +#define bfin_write_DMA9_BWL_COUNT(val) bfin_write32(DMA9_BWL_COUNT, val) +#define bfin_read_DMA9_CURR_BWL_COUNT() bfin_read32(DMA9_CURR_BWL_COUNT) +#define bfin_write_DMA9_CURR_BWL_COUNT(val) bfin_write32(DMA9_CURR_BWL_COUNT, val) +#define bfin_read_DMA9_BWM_COUNT() bfin_read32(DMA9_BWM_COUNT) +#define bfin_write_DMA9_BWM_COUNT(val) bfin_write32(DMA9_BWM_COUNT, val) +#define bfin_read_DMA9_CURR_BWM_COUNT() bfin_read32(DMA9_CURR_BWM_COUNT) +#define bfin_write_DMA9_CURR_BWM_COUNT(val) bfin_write32(DMA9_CURR_BWM_COUNT, val) + +/* DMA Channel 10 Registers */ + +#define bfin_read_DMA10_NEXT_DESC_PTR() bfin_read32(DMA10_NEXT_DESC_PTR) +#define bfin_write_DMA10_NEXT_DESC_PTR(val) bfin_write32(DMA10_NEXT_DESC_PTR, val) +#define bfin_read_DMA10_START_ADDR() bfin_read32(DMA10_START_ADDR) +#define bfin_write_DMA10_START_ADDR(val) bfin_write32(DMA10_START_ADDR, val) +#define bfin_read_DMA10_CONFIG() bfin_read32(DMA10_CONFIG) +#define bfin_write_DMA10_CONFIG(val) bfin_write32(DMA10_CONFIG, val) +#define bfin_read_DMA10_X_COUNT() bfin_read32(DMA10_X_COUNT) +#define bfin_write_DMA10_X_COUNT(val) bfin_write32(DMA10_X_COUNT, val) +#define bfin_read_DMA10_X_MODIFY() bfin_read32(DMA10_X_MODIFY) +#define bfin_write_DMA10_X_MODIFY(val) bfin_write32(DMA10_X_MODIFY, val) +#define bfin_read_DMA10_Y_COUNT() bfin_read32(DMA10_Y_COUNT) +#define bfin_write_DMA10_Y_COUNT(val) bfin_write32(DMA10_Y_COUNT, val) +#define bfin_read_DMA10_Y_MODIFY() bfin_read32(DMA10_Y_MODIFY) +#define bfin_write_DMA10_Y_MODIFY(val) bfin_write32(DMA10_Y_MODIFY, val) +#define bfin_read_DMA10_CURR_DESC_PTR() bfin_read32(DMA10_CURR_DESC_PTR) +#define bfin_write_DMA10_CURR_DESC_PTR(val) bfin_write32(DMA10_CURR_DESC_PTR, val) +#define bfin_read_DMA10_PREV_DESC_PTR() bfin_read32(DMA10_PREV_DESC_PTR) +#define bfin_write_DMA10_PREV_DESC_PTR(val) bfin_write32(DMA10_PREV_DESC_PTR, val) +#define bfin_read_DMA10_CURR_ADDR() bfin_read32(DMA10_CURR_ADDR) +#define bfin_write_DMA10_CURR_ADDR(val) bfin_write32(DMA10_CURR_ADDR, val) +#define bfin_read_DMA10_IRQ_STATUS() bfin_read32(DMA10_IRQ_STATUS) +#define bfin_write_DMA10_IRQ_STATUS(val) bfin_write32(DMA10_IRQ_STATUS, val) +#define bfin_read_DMA10_CURR_X_COUNT() bfin_read32(DMA10_CURR_X_COUNT) +#define bfin_write_DMA10_CURR_X_COUNT(val) bfin_write32(DMA10_CURR_X_COUNT, val) +#define bfin_read_DMA10_CURR_Y_COUNT() bfin_read32(DMA10_CURR_Y_COUNT) +#define bfin_write_DMA10_CURR_Y_COUNT(val) bfin_write32(DMA10_CURR_Y_COUNT, val) +#define bfin_read_DMA10_BWL_COUNT() bfin_read32(DMA10_BWL_COUNT) +#define bfin_write_DMA10_BWL_COUNT(val) bfin_write32(DMA10_BWL_COUNT, val) +#define bfin_read_DMA10_CURR_BWL_COUNT() bfin_read32(DMA10_CURR_BWL_COUNT) +#define bfin_write_DMA10_CURR_BWL_COUNT(val) bfin_write32(DMA10_CURR_BWL_COUNT, val) +#define bfin_read_DMA10_BWM_COUNT() bfin_read32(DMA10_BWM_COUNT) +#define bfin_write_DMA10_BWM_COUNT(val) bfin_write32(DMA10_BWM_COUNT, val) +#define bfin_read_DMA10_CURR_BWM_COUNT() bfin_read32(DMA10_CURR_BWM_COUNT) +#define bfin_write_DMA10_CURR_BWM_COUNT(val) bfin_write32(DMA10_CURR_BWM_COUNT, val) + +/* DMA Channel 11 Registers */ + +#define bfin_read_DMA11_NEXT_DESC_PTR() bfin_read32(DMA11_NEXT_DESC_PTR) +#define bfin_write_DMA11_NEXT_DESC_PTR(val) bfin_write32(DMA11_NEXT_DESC_PTR, val) +#define bfin_read_DMA11_START_ADDR() bfin_read32(DMA11_START_ADDR) +#define bfin_write_DMA11_START_ADDR(val) bfin_write32(DMA11_START_ADDR, val) +#define bfin_read_DMA11_CONFIG() bfin_read32(DMA11_CONFIG) +#define bfin_write_DMA11_CONFIG(val) bfin_write32(DMA11_CONFIG, val) +#define bfin_read_DMA11_X_COUNT() bfin_read32(DMA11_X_COUNT) +#define bfin_write_DMA11_X_COUNT(val) bfin_write32(DMA11_X_COUNT, val) +#define bfin_read_DMA11_X_MODIFY() bfin_read32(DMA11_X_MODIFY) +#define bfin_write_DMA11_X_MODIFY(val) bfin_write32(DMA11_X_MODIFY, val) +#define bfin_read_DMA11_Y_COUNT() bfin_read32(DMA11_Y_COUNT) +#define bfin_write_DMA11_Y_COUNT(val) bfin_write32(DMA11_Y_COUNT, val) +#define bfin_read_DMA11_Y_MODIFY() bfin_read32(DMA11_Y_MODIFY) +#define bfin_write_DMA11_Y_MODIFY(val) bfin_write32(DMA11_Y_MODIFY, val) +#define bfin_read_DMA11_CURR_DESC_PTR() bfin_read32(DMA11_CURR_DESC_PTR) +#define bfin_write_DMA11_CURR_DESC_PTR(val) bfin_write32(DMA11_CURR_DESC_PTR, val) +#define bfin_read_DMA11_PREV_DESC_PTR() bfin_read32(DMA11_PREV_DESC_PTR) +#define bfin_write_DMA11_PREV_DESC_PTR(val) bfin_write32(DMA11_PREV_DESC_PTR, val) +#define bfin_read_DMA11_CURR_ADDR() bfin_read32(DMA11_CURR_ADDR) +#define bfin_write_DMA11_CURR_ADDR(val) bfin_write32(DMA11_CURR_ADDR, val) +#define bfin_read_DMA11_IRQ_STATUS() bfin_read32(DMA11_IRQ_STATUS) +#define bfin_write_DMA11_IRQ_STATUS(val) bfin_write32(DMA11_IRQ_STATUS, val) +#define bfin_read_DMA11_CURR_X_COUNT() bfin_read32(DMA11_CURR_X_COUNT) +#define bfin_write_DMA11_CURR_X_COUNT(val) bfin_write32(DMA11_CURR_X_COUNT, val) +#define bfin_read_DMA11_CURR_Y_COUNT() bfin_read32(DMA11_CURR_Y_COUNT) +#define bfin_write_DMA11_CURR_Y_COUNT(val) bfin_write32(DMA11_CURR_Y_COUNT, val) +#define bfin_read_DMA11_BWL_COUNT() bfin_read32(DMA11_BWL_COUNT) +#define bfin_write_DMA11_BWL_COUNT(val) bfin_write32(DMA11_BWL_COUNT, val) +#define bfin_read_DMA11_CURR_BWL_COUNT() bfin_read32(DMA11_CURR_BWL_COUNT) +#define bfin_write_DMA11_CURR_BWL_COUNT(val) bfin_write32(DMA11_CURR_BWL_COUNT, val) +#define bfin_read_DMA11_BWM_COUNT() bfin_read32(DMA11_BWM_COUNT) +#define bfin_write_DMA11_BWM_COUNT(val) bfin_write32(DMA11_BWM_COUNT, val) +#define bfin_read_DMA11_CURR_BWM_COUNT() bfin_read32(DMA11_CURR_BWM_COUNT) +#define bfin_write_DMA11_CURR_BWM_COUNT(val) bfin_write32(DMA11_CURR_BWM_COUNT, val) + +/* DMA Channel 12 Registers */ + +#define bfin_read_DMA12_NEXT_DESC_PTR() bfin_read32(DMA12_NEXT_DESC_PTR) +#define bfin_write_DMA12_NEXT_DESC_PTR(val) bfin_write32(DMA12_NEXT_DESC_PTR, val) +#define bfin_read_DMA12_START_ADDR() bfin_read32(DMA12_START_ADDR) +#define bfin_write_DMA12_START_ADDR(val) bfin_write32(DMA12_START_ADDR, val) +#define bfin_read_DMA12_CONFIG() bfin_read32(DMA12_CONFIG) +#define bfin_write_DMA12_CONFIG(val) bfin_write32(DMA12_CONFIG, val) +#define bfin_read_DMA12_X_COUNT() bfin_read32(DMA12_X_COUNT) +#define bfin_write_DMA12_X_COUNT(val) bfin_write32(DMA12_X_COUNT, val) +#define bfin_read_DMA12_X_MODIFY() bfin_read32(DMA12_X_MODIFY) +#define bfin_write_DMA12_X_MODIFY(val) bfin_write32(DMA12_X_MODIFY, val) +#define bfin_read_DMA12_Y_COUNT() bfin_read32(DMA12_Y_COUNT) +#define bfin_write_DMA12_Y_COUNT(val) bfin_write32(DMA12_Y_COUNT, val) +#define bfin_read_DMA12_Y_MODIFY() bfin_read32(DMA12_Y_MODIFY) +#define bfin_write_DMA12_Y_MODIFY(val) bfin_write32(DMA12_Y_MODIFY, val) +#define bfin_read_DMA12_CURR_DESC_PTR() bfin_read32(DMA12_CURR_DESC_PTR) +#define bfin_write_DMA12_CURR_DESC_PTR(val) bfin_write32(DMA12_CURR_DESC_PTR, val) +#define bfin_read_DMA12_PREV_DESC_PTR() bfin_read32(DMA12_PREV_DESC_PTR) +#define bfin_write_DMA12_PREV_DESC_PTR(val) bfin_write32(DMA12_PREV_DESC_PTR, val) +#define bfin_read_DMA12_CURR_ADDR() bfin_read32(DMA12_CURR_ADDR) +#define bfin_write_DMA12_CURR_ADDR(val) bfin_write32(DMA12_CURR_ADDR, val) +#define bfin_read_DMA12_IRQ_STATUS() bfin_read32(DMA12_IRQ_STATUS) +#define bfin_write_DMA12_IRQ_STATUS(val) bfin_write32(DMA12_IRQ_STATUS, val) +#define bfin_read_DMA12_CURR_X_COUNT() bfin_read32(DMA12_CURR_X_COUNT) +#define bfin_write_DMA12_CURR_X_COUNT(val) bfin_write32(DMA12_CURR_X_COUNT, val) +#define bfin_read_DMA12_CURR_Y_COUNT() bfin_read32(DMA12_CURR_Y_COUNT) +#define bfin_write_DMA12_CURR_Y_COUNT(val) bfin_write32(DMA12_CURR_Y_COUNT, val) +#define bfin_read_DMA12_BWL_COUNT() bfin_read32(DMA12_BWL_COUNT) +#define bfin_write_DMA12_BWL_COUNT(val) bfin_write32(DMA12_BWL_COUNT, val) +#define bfin_read_DMA12_CURR_BWL_COUNT() bfin_read32(DMA12_CURR_BWL_COUNT) +#define bfin_write_DMA12_CURR_BWL_COUNT(val) bfin_write32(DMA12_CURR_BWL_COUNT, val) +#define bfin_read_DMA12_BWM_COUNT() bfin_read32(DMA12_BWM_COUNT) +#define bfin_write_DMA12_BWM_COUNT(val) bfin_write32(DMA12_BWM_COUNT, val) +#define bfin_read_DMA12_CURR_BWM_COUNT() bfin_read32(DMA12_CURR_BWM_COUNT) +#define bfin_write_DMA12_CURR_BWM_COUNT(val) bfin_write32(DMA12_CURR_BWM_COUNT, val) + +/* DMA Channel 13 Registers */ + +#define bfin_read_DMA13_NEXT_DESC_PTR() bfin_read32(DMA13_NEXT_DESC_PTR) +#define bfin_write_DMA13_NEXT_DESC_PTR(val) bfin_write32(DMA13_NEXT_DESC_PTR, val) +#define bfin_read_DMA13_START_ADDR() bfin_read32(DMA13_START_ADDR) +#define bfin_write_DMA13_START_ADDR(val) bfin_write32(DMA13_START_ADDR, val) +#define bfin_read_DMA13_CONFIG() bfin_read32(DMA13_CONFIG) +#define bfin_write_DMA13_CONFIG(val) bfin_write32(DMA13_CONFIG, val) +#define bfin_read_DMA13_X_COUNT() bfin_read32(DMA13_X_COUNT) +#define bfin_write_DMA13_X_COUNT(val) bfin_write32(DMA13_X_COUNT, val) +#define bfin_read_DMA13_X_MODIFY() bfin_read32(DMA13_X_MODIFY) +#define bfin_write_DMA13_X_MODIFY(val) bfin_write32(DMA13_X_MODIFY, val) +#define bfin_read_DMA13_Y_COUNT() bfin_read32(DMA13_Y_COUNT) +#define bfin_write_DMA13_Y_COUNT(val) bfin_write32(DMA13_Y_COUNT, val) +#define bfin_read_DMA13_Y_MODIFY() bfin_read32(DMA13_Y_MODIFY) +#define bfin_write_DMA13_Y_MODIFY(val) bfin_write32(DMA13_Y_MODIFY, val) +#define bfin_read_DMA13_CURR_DESC_PTR() bfin_read32(DMA13_CURR_DESC_PTR) +#define bfin_write_DMA13_CURR_DESC_PTR(val) bfin_write32(DMA13_CURR_DESC_PTR, val) +#define bfin_read_DMA13_PREV_DESC_PTR() bfin_read32(DMA13_PREV_DESC_PTR) +#define bfin_write_DMA13_PREV_DESC_PTR(val) bfin_write32(DMA13_PREV_DESC_PTR, val) +#define bfin_read_DMA13_CURR_ADDR() bfin_read32(DMA13_CURR_ADDR) +#define bfin_write_DMA13_CURR_ADDR(val) bfin_write32(DMA13_CURR_ADDR, val) +#define bfin_read_DMA13_IRQ_STATUS() bfin_read32(DMA13_IRQ_STATUS) +#define bfin_write_DMA13_IRQ_STATUS(val) bfin_write32(DMA13_IRQ_STATUS, val) +#define bfin_read_DMA13_CURR_X_COUNT() bfin_read32(DMA13_CURR_X_COUNT) +#define bfin_write_DMA13_CURR_X_COUNT(val) bfin_write32(DMA13_CURR_X_COUNT, val) +#define bfin_read_DMA13_CURR_Y_COUNT() bfin_read32(DMA13_CURR_Y_COUNT) +#define bfin_write_DMA13_CURR_Y_COUNT(val) bfin_write32(DMA13_CURR_Y_COUNT, val) +#define bfin_read_DMA13_BWL_COUNT() bfin_read32(DMA13_BWL_COUNT) +#define bfin_write_DMA13_BWL_COUNT(val) bfin_write32(DMA13_BWL_COUNT, val) +#define bfin_read_DMA13_CURR_BWL_COUNT() bfin_read32(DMA13_CURR_BWL_COUNT) +#define bfin_write_DMA13_CURR_BWL_COUNT(val) bfin_write32(DMA13_CURR_BWL_COUNT, val) +#define bfin_read_DMA13_BWM_COUNT() bfin_read32(DMA13_BWM_COUNT) +#define bfin_write_DMA13_BWM_COUNT(val) bfin_write32(DMA13_BWM_COUNT, val) +#define bfin_read_DMA13_CURR_BWM_COUNT() bfin_read32(DMA13_CURR_BWM_COUNT) +#define bfin_write_DMA13_CURR_BWM_COUNT(val) bfin_write32(DMA13_CURR_BWM_COUNT, val) + +/* DMA Channel 14 Registers */ + +#define bfin_read_DMA14_NEXT_DESC_PTR() bfin_read32(DMA14_NEXT_DESC_PTR) +#define bfin_write_DMA14_NEXT_DESC_PTR(val) bfin_write32(DMA14_NEXT_DESC_PTR, val) +#define bfin_read_DMA14_START_ADDR() bfin_read32(DMA14_START_ADDR) +#define bfin_write_DMA14_START_ADDR(val) bfin_write32(DMA14_START_ADDR, val) +#define bfin_read_DMA14_CONFIG() bfin_read32(DMA14_CONFIG) +#define bfin_write_DMA14_CONFIG(val) bfin_write32(DMA14_CONFIG, val) +#define bfin_read_DMA14_X_COUNT() bfin_read32(DMA14_X_COUNT) +#define bfin_write_DMA14_X_COUNT(val) bfin_write32(DMA14_X_COUNT, val) +#define bfin_read_DMA14_X_MODIFY() bfin_read32(DMA14_X_MODIFY) +#define bfin_write_DMA14_X_MODIFY(val) bfin_write32(DMA14_X_MODIFY, val) +#define bfin_read_DMA14_Y_COUNT() bfin_read32(DMA14_Y_COUNT) +#define bfin_write_DMA14_Y_COUNT(val) bfin_write32(DMA14_Y_COUNT, val) +#define bfin_read_DMA14_Y_MODIFY() bfin_read32(DMA14_Y_MODIFY) +#define bfin_write_DMA14_Y_MODIFY(val) bfin_write32(DMA14_Y_MODIFY, val) +#define bfin_read_DMA14_CURR_DESC_PTR() bfin_read32(DMA14_CURR_DESC_PTR) +#define bfin_write_DMA14_CURR_DESC_PTR(val) bfin_write32(DMA14_CURR_DESC_PTR, val) +#define bfin_read_DMA14_PREV_DESC_PTR() bfin_read32(DMA14_PREV_DESC_PTR) +#define bfin_write_DMA14_PREV_DESC_PTR(val) bfin_write32(DMA14_PREV_DESC_PTR, val) +#define bfin_read_DMA14_CURR_ADDR() bfin_read32(DMA14_CURR_ADDR) +#define bfin_write_DMA14_CURR_ADDR(val) bfin_write32(DMA14_CURR_ADDR, val) +#define bfin_read_DMA14_IRQ_STATUS() bfin_read32(DMA14_IRQ_STATUS) +#define bfin_write_DMA14_IRQ_STATUS(val) bfin_write32(DMA14_IRQ_STATUS, val) +#define bfin_read_DMA14_CURR_X_COUNT() bfin_read32(DMA14_CURR_X_COUNT) +#define bfin_write_DMA14_CURR_X_COUNT(val) bfin_write32(DMA14_CURR_X_COUNT, val) +#define bfin_read_DMA14_CURR_Y_COUNT() bfin_read32(DMA14_CURR_Y_COUNT) +#define bfin_write_DMA14_CURR_Y_COUNT(val) bfin_write32(DMA14_CURR_Y_COUNT, val) +#define bfin_read_DMA14_BWL_COUNT() bfin_read32(DMA14_BWL_COUNT) +#define bfin_write_DMA14_BWL_COUNT(val) bfin_write32(DMA14_BWL_COUNT, val) +#define bfin_read_DMA14_CURR_BWL_COUNT() bfin_read32(DMA14_CURR_BWL_COUNT) +#define bfin_write_DMA14_CURR_BWL_COUNT(val) bfin_write32(DMA14_CURR_BWL_COUNT, val) +#define bfin_read_DMA14_BWM_COUNT() bfin_read32(DMA14_BWM_COUNT) +#define bfin_write_DMA14_BWM_COUNT(val) bfin_write32(DMA14_BWM_COUNT, val) +#define bfin_read_DMA14_CURR_BWM_COUNT() bfin_read32(DMA14_CURR_BWM_COUNT) +#define bfin_write_DMA14_CURR_BWM_COUNT(val) bfin_write32(DMA14_CURR_BWM_COUNT, val) + +/* DMA Channel 15 Registers */ + +#define bfin_read_DMA15_NEXT_DESC_PTR() bfin_read32(DMA15_NEXT_DESC_PTR) +#define bfin_write_DMA15_NEXT_DESC_PTR(val) bfin_write32(DMA15_NEXT_DESC_PTR, val) +#define bfin_read_DMA15_START_ADDR() bfin_read32(DMA15_START_ADDR) +#define bfin_write_DMA15_START_ADDR(val) bfin_write32(DMA15_START_ADDR, val) +#define bfin_read_DMA15_CONFIG() bfin_read32(DMA15_CONFIG) +#define bfin_write_DMA15_CONFIG(val) bfin_write32(DMA15_CONFIG, val) +#define bfin_read_DMA15_X_COUNT() bfin_read32(DMA15_X_COUNT) +#define bfin_write_DMA15_X_COUNT(val) bfin_write32(DMA15_X_COUNT, val) +#define bfin_read_DMA15_X_MODIFY() bfin_read32(DMA15_X_MODIFY) +#define bfin_write_DMA15_X_MODIFY(val) bfin_write32(DMA15_X_MODIFY, val) +#define bfin_read_DMA15_Y_COUNT() bfin_read32(DMA15_Y_COUNT) +#define bfin_write_DMA15_Y_COUNT(val) bfin_write32(DMA15_Y_COUNT, val) +#define bfin_read_DMA15_Y_MODIFY() bfin_read32(DMA15_Y_MODIFY) +#define bfin_write_DMA15_Y_MODIFY(val) bfin_write32(DMA15_Y_MODIFY, val) +#define bfin_read_DMA15_CURR_DESC_PTR() bfin_read32(DMA15_CURR_DESC_PTR) +#define bfin_write_DMA15_CURR_DESC_PTR(val) bfin_write32(DMA15_CURR_DESC_PTR, val) +#define bfin_read_DMA15_PREV_DESC_PTR() bfin_read32(DMA15_PREV_DESC_PTR) +#define bfin_write_DMA15_PREV_DESC_PTR(val) bfin_write32(DMA15_PREV_DESC_PTR, val) +#define bfin_read_DMA15_CURR_ADDR() bfin_read32(DMA15_CURR_ADDR) +#define bfin_write_DMA15_CURR_ADDR(val) bfin_write32(DMA15_CURR_ADDR, val) +#define bfin_read_DMA15_IRQ_STATUS() bfin_read32(DMA15_IRQ_STATUS) +#define bfin_write_DMA15_IRQ_STATUS(val) bfin_write32(DMA15_IRQ_STATUS, val) +#define bfin_read_DMA15_CURR_X_COUNT() bfin_read32(DMA15_CURR_X_COUNT) +#define bfin_write_DMA15_CURR_X_COUNT(val) bfin_write32(DMA15_CURR_X_COUNT, val) +#define bfin_read_DMA15_CURR_Y_COUNT() bfin_read32(DMA15_CURR_Y_COUNT) +#define bfin_write_DMA15_CURR_Y_COUNT(val) bfin_write32(DMA15_CURR_Y_COUNT, val) +#define bfin_read_DMA15_BWL_COUNT() bfin_read32(DMA15_BWL_COUNT) +#define bfin_write_DMA15_BWL_COUNT(val) bfin_write32(DMA15_BWL_COUNT, val) +#define bfin_read_DMA15_CURR_BWL_COUNT() bfin_read32(DMA15_CURR_BWL_COUNT) +#define bfin_write_DMA15_CURR_BWL_COUNT(val) bfin_write32(DMA15_CURR_BWL_COUNT, val) +#define bfin_read_DMA15_BWM_COUNT() bfin_read32(DMA15_BWM_COUNT) +#define bfin_write_DMA15_BWM_COUNT(val) bfin_write32(DMA15_BWM_COUNT, val) +#define bfin_read_DMA15_CURR_BWM_COUNT() bfin_read32(DMA15_CURR_BWM_COUNT) +#define bfin_write_DMA15_CURR_BWM_COUNT(val) bfin_write32(DMA15_CURR_BWM_COUNT, val) + +/* DMA Channel 16 Registers */ + +#define bfin_read_DMA16_NEXT_DESC_PTR() bfin_read32(DMA16_NEXT_DESC_PTR) +#define bfin_write_DMA16_NEXT_DESC_PTR(val) bfin_write32(DMA16_NEXT_DESC_PTR, val) +#define bfin_read_DMA16_START_ADDR() bfin_read32(DMA16_START_ADDR) +#define bfin_write_DMA16_START_ADDR(val) bfin_write32(DMA16_START_ADDR, val) +#define bfin_read_DMA16_CONFIG() bfin_read32(DMA16_CONFIG) +#define bfin_write_DMA16_CONFIG(val) bfin_write32(DMA16_CONFIG, val) +#define bfin_read_DMA16_X_COUNT() bfin_read32(DMA16_X_COUNT) +#define bfin_write_DMA16_X_COUNT(val) bfin_write32(DMA16_X_COUNT, val) +#define bfin_read_DMA16_X_MODIFY() bfin_read32(DMA16_X_MODIFY) +#define bfin_write_DMA16_X_MODIFY(val) bfin_write32(DMA16_X_MODIFY, val) +#define bfin_read_DMA16_Y_COUNT() bfin_read32(DMA16_Y_COUNT) +#define bfin_write_DMA16_Y_COUNT(val) bfin_write32(DMA16_Y_COUNT, val) +#define bfin_read_DMA16_Y_MODIFY() bfin_read32(DMA16_Y_MODIFY) +#define bfin_write_DMA16_Y_MODIFY(val) bfin_write32(DMA16_Y_MODIFY, val) +#define bfin_read_DMA16_CURR_DESC_PTR() bfin_read32(DMA16_CURR_DESC_PTR) +#define bfin_write_DMA16_CURR_DESC_PTR(val) bfin_write32(DMA16_CURR_DESC_PTR, val) +#define bfin_read_DMA16_PREV_DESC_PTR() bfin_read32(DMA16_PREV_DESC_PTR) +#define bfin_write_DMA16_PREV_DESC_PTR(val) bfin_write32(DMA16_PREV_DESC_PTR, val) +#define bfin_read_DMA16_CURR_ADDR() bfin_read32(DMA16_CURR_ADDR) +#define bfin_write_DMA16_CURR_ADDR(val) bfin_write32(DMA16_CURR_ADDR, val) +#define bfin_read_DMA16_IRQ_STATUS() bfin_read32(DMA16_IRQ_STATUS) +#define bfin_write_DMA16_IRQ_STATUS(val) bfin_write32(DMA16_IRQ_STATUS, val) +#define bfin_read_DMA16_CURR_X_COUNT() bfin_read32(DMA16_CURR_X_COUNT) +#define bfin_write_DMA16_CURR_X_COUNT(val) bfin_write32(DMA16_CURR_X_COUNT, val) +#define bfin_read_DMA16_CURR_Y_COUNT() bfin_read32(DMA16_CURR_Y_COUNT) +#define bfin_write_DMA16_CURR_Y_COUNT(val) bfin_write32(DMA16_CURR_Y_COUNT, val) +#define bfin_read_DMA16_BWL_COUNT() bfin_read32(DMA16_BWL_COUNT) +#define bfin_write_DMA16_BWL_COUNT(val) bfin_write32(DMA16_BWL_COUNT, val) +#define bfin_read_DMA16_CURR_BWL_COUNT() bfin_read32(DMA16_CURR_BWL_COUNT) +#define bfin_write_DMA16_CURR_BWL_COUNT(val) bfin_write32(DMA16_CURR_BWL_COUNT, val) +#define bfin_read_DMA16_BWM_COUNT() bfin_read32(DMA16_BWM_COUNT) +#define bfin_write_DMA16_BWM_COUNT(val) bfin_write32(DMA16_BWM_COUNT, val) +#define bfin_read_DMA16_CURR_BWM_COUNT() bfin_read32(DMA16_CURR_BWM_COUNT) +#define bfin_write_DMA16_CURR_BWM_COUNT(val) bfin_write32(DMA16_CURR_BWM_COUNT, val) + +/* DMA Channel 17 Registers */ + +#define bfin_read_DMA17_NEXT_DESC_PTR() bfin_read32(DMA17_NEXT_DESC_PTR) +#define bfin_write_DMA17_NEXT_DESC_PTR(val) bfin_write32(DMA17_NEXT_DESC_PTR, val) +#define bfin_read_DMA17_START_ADDR() bfin_read32(DMA17_START_ADDR) +#define bfin_write_DMA17_START_ADDR(val) bfin_write32(DMA17_START_ADDR, val) +#define bfin_read_DMA17_CONFIG() bfin_read32(DMA17_CONFIG) +#define bfin_write_DMA17_CONFIG(val) bfin_write32(DMA17_CONFIG, val) +#define bfin_read_DMA17_X_COUNT() bfin_read32(DMA17_X_COUNT) +#define bfin_write_DMA17_X_COUNT(val) bfin_write32(DMA17_X_COUNT, val) +#define bfin_read_DMA17_X_MODIFY() bfin_read32(DMA17_X_MODIFY) +#define bfin_write_DMA17_X_MODIFY(val) bfin_write32(DMA17_X_MODIFY, val) +#define bfin_read_DMA17_Y_COUNT() bfin_read32(DMA17_Y_COUNT) +#define bfin_write_DMA17_Y_COUNT(val) bfin_write32(DMA17_Y_COUNT, val) +#define bfin_read_DMA17_Y_MODIFY() bfin_read32(DMA17_Y_MODIFY) +#define bfin_write_DMA17_Y_MODIFY(val) bfin_write32(DMA17_Y_MODIFY, val) +#define bfin_read_DMA17_CURR_DESC_PTR() bfin_read32(DMA17_CURR_DESC_PTR) +#define bfin_write_DMA17_CURR_DESC_PTR(val) bfin_write32(DMA17_CURR_DESC_PTR, val) +#define bfin_read_DMA17_PREV_DESC_PTR() bfin_read32(DMA17_PREV_DESC_PTR) +#define bfin_write_DMA17_PREV_DESC_PTR(val) bfin_write32(DMA17_PREV_DESC_PTR, val) +#define bfin_read_DMA17_CURR_ADDR() bfin_read32(DMA17_CURR_ADDR) +#define bfin_write_DMA17_CURR_ADDR(val) bfin_write32(DMA17_CURR_ADDR, val) +#define bfin_read_DMA17_IRQ_STATUS() bfin_read32(DMA17_IRQ_STATUS) +#define bfin_write_DMA17_IRQ_STATUS(val) bfin_write32(DMA17_IRQ_STATUS, val) +#define bfin_read_DMA17_CURR_X_COUNT() bfin_read32(DMA17_CURR_X_COUNT) +#define bfin_write_DMA17_CURR_X_COUNT(val) bfin_write32(DMA17_CURR_X_COUNT, val) +#define bfin_read_DMA17_CURR_Y_COUNT() bfin_read32(DMA17_CURR_Y_COUNT) +#define bfin_write_DMA17_CURR_Y_COUNT(val) bfin_write32(DMA17_CURR_Y_COUNT, val) +#define bfin_read_DMA17_BWL_COUNT() bfin_read32(DMA17_BWL_COUNT) +#define bfin_write_DMA17_BWL_COUNT(val) bfin_write32(DMA17_BWL_COUNT, val) +#define bfin_read_DMA17_CURR_BWL_COUNT() bfin_read32(DMA17_CURR_BWL_COUNT) +#define bfin_write_DMA17_CURR_BWL_COUNT(val) bfin_write32(DMA17_CURR_BWL_COUNT, val) +#define bfin_read_DMA17_BWM_COUNT() bfin_read32(DMA17_BWM_COUNT) +#define bfin_write_DMA17_BWM_COUNT(val) bfin_write32(DMA17_BWM_COUNT, val) +#define bfin_read_DMA17_CURR_BWM_COUNT() bfin_read32(DMA17_CURR_BWM_COUNT) +#define bfin_write_DMA17_CURR_BWM_COUNT(val) bfin_write32(DMA17_CURR_BWM_COUNT, val) + +/* DMA Channel 18 Registers */ + +#define bfin_read_DMA18_NEXT_DESC_PTR() bfin_read32(DMA18_NEXT_DESC_PTR) +#define bfin_write_DMA18_NEXT_DESC_PTR(val) bfin_write32(DMA18_NEXT_DESC_PTR, val) +#define bfin_read_DMA18_START_ADDR() bfin_read32(DMA18_START_ADDR) +#define bfin_write_DMA18_START_ADDR(val) bfin_write32(DMA18_START_ADDR, val) +#define bfin_read_DMA18_CONFIG() bfin_read32(DMA18_CONFIG) +#define bfin_write_DMA18_CONFIG(val) bfin_write32(DMA18_CONFIG, val) +#define bfin_read_DMA18_X_COUNT() bfin_read32(DMA18_X_COUNT) +#define bfin_write_DMA18_X_COUNT(val) bfin_write32(DMA18_X_COUNT, val) +#define bfin_read_DMA18_X_MODIFY() bfin_read32(DMA18_X_MODIFY) +#define bfin_write_DMA18_X_MODIFY(val) bfin_write32(DMA18_X_MODIFY, val) +#define bfin_read_DMA18_Y_COUNT() bfin_read32(DMA18_Y_COUNT) +#define bfin_write_DMA18_Y_COUNT(val) bfin_write32(DMA18_Y_COUNT, val) +#define bfin_read_DMA18_Y_MODIFY() bfin_read32(DMA18_Y_MODIFY) +#define bfin_write_DMA18_Y_MODIFY(val) bfin_write32(DMA18_Y_MODIFY, val) +#define bfin_read_DMA18_CURR_DESC_PTR() bfin_read32(DMA18_CURR_DESC_PTR) +#define bfin_write_DMA18_CURR_DESC_PTR(val) bfin_write32(DMA18_CURR_DESC_PTR, val) +#define bfin_read_DMA18_PREV_DESC_PTR() bfin_read32(DMA18_PREV_DESC_PTR) +#define bfin_write_DMA18_PREV_DESC_PTR(val) bfin_write32(DMA18_PREV_DESC_PTR, val) +#define bfin_read_DMA18_CURR_ADDR() bfin_read32(DMA18_CURR_ADDR) +#define bfin_write_DMA18_CURR_ADDR(val) bfin_write32(DMA18_CURR_ADDR, val) +#define bfin_read_DMA18_IRQ_STATUS() bfin_read32(DMA18_IRQ_STATUS) +#define bfin_write_DMA18_IRQ_STATUS(val) bfin_write32(DMA18_IRQ_STATUS, val) +#define bfin_read_DMA18_CURR_X_COUNT() bfin_read32(DMA18_CURR_X_COUNT) +#define bfin_write_DMA18_CURR_X_COUNT(val) bfin_write32(DMA18_CURR_X_COUNT, val) +#define bfin_read_DMA18_CURR_Y_COUNT() bfin_read32(DMA18_CURR_Y_COUNT) +#define bfin_write_DMA18_CURR_Y_COUNT(val) bfin_write32(DMA18_CURR_Y_COUNT, val) +#define bfin_read_DMA18_BWL_COUNT() bfin_read32(DMA18_BWL_COUNT) +#define bfin_write_DMA18_BWL_COUNT(val) bfin_write32(DMA18_BWL_COUNT, val) +#define bfin_read_DMA18_CURR_BWL_COUNT() bfin_read32(DMA18_CURR_BWL_COUNT) +#define bfin_write_DMA18_CURR_BWL_COUNT(val) bfin_write32(DMA18_CURR_BWL_COUNT, val) +#define bfin_read_DMA18_BWM_COUNT() bfin_read32(DMA18_BWM_COUNT) +#define bfin_write_DMA18_BWM_COUNT(val) bfin_write32(DMA18_BWM_COUNT, val) +#define bfin_read_DMA18_CURR_BWM_COUNT() bfin_read32(DMA18_CURR_BWM_COUNT) +#define bfin_write_DMA18_CURR_BWM_COUNT(val) bfin_write32(DMA18_CURR_BWM_COUNT, val) + +/* DMA Channel 19 Registers */ + +#define bfin_read_DMA19_NEXT_DESC_PTR() bfin_read32(DMA19_NEXT_DESC_PTR) +#define bfin_write_DMA19_NEXT_DESC_PTR(val) bfin_write32(DMA19_NEXT_DESC_PTR, val) +#define bfin_read_DMA19_START_ADDR() bfin_read32(DMA19_START_ADDR) +#define bfin_write_DMA19_START_ADDR(val) bfin_write32(DMA19_START_ADDR, val) +#define bfin_read_DMA19_CONFIG() bfin_read32(DMA19_CONFIG) +#define bfin_write_DMA19_CONFIG(val) bfin_write32(DMA19_CONFIG, val) +#define bfin_read_DMA19_X_COUNT() bfin_read32(DMA19_X_COUNT) +#define bfin_write_DMA19_X_COUNT(val) bfin_write32(DMA19_X_COUNT, val) +#define bfin_read_DMA19_X_MODIFY() bfin_read32(DMA19_X_MODIFY) +#define bfin_write_DMA19_X_MODIFY(val) bfin_write32(DMA19_X_MODIFY, val) +#define bfin_read_DMA19_Y_COUNT() bfin_read32(DMA19_Y_COUNT) +#define bfin_write_DMA19_Y_COUNT(val) bfin_write32(DMA19_Y_COUNT, val) +#define bfin_read_DMA19_Y_MODIFY() bfin_read32(DMA19_Y_MODIFY) +#define bfin_write_DMA19_Y_MODIFY(val) bfin_write32(DMA19_Y_MODIFY, val) +#define bfin_read_DMA19_CURR_DESC_PTR() bfin_read32(DMA19_CURR_DESC_PTR) +#define bfin_write_DMA19_CURR_DESC_PTR(val) bfin_write32(DMA19_CURR_DESC_PTR, val) +#define bfin_read_DMA19_PREV_DESC_PTR() bfin_read32(DMA19_PREV_DESC_PTR) +#define bfin_write_DMA19_PREV_DESC_PTR(val) bfin_write32(DMA19_PREV_DESC_PTR, val) +#define bfin_read_DMA19_CURR_ADDR() bfin_read32(DMA19_CURR_ADDR) +#define bfin_write_DMA19_CURR_ADDR(val) bfin_write32(DMA19_CURR_ADDR, val) +#define bfin_read_DMA19_IRQ_STATUS() bfin_read32(DMA19_IRQ_STATUS) +#define bfin_write_DMA19_IRQ_STATUS(val) bfin_write32(DMA19_IRQ_STATUS, val) +#define bfin_read_DMA19_CURR_X_COUNT() bfin_read32(DMA19_CURR_X_COUNT) +#define bfin_write_DMA19_CURR_X_COUNT(val) bfin_write32(DMA19_CURR_X_COUNT, val) +#define bfin_read_DMA19_CURR_Y_COUNT() bfin_read32(DMA19_CURR_Y_COUNT) +#define bfin_write_DMA19_CURR_Y_COUNT(val) bfin_write32(DMA19_CURR_Y_COUNT, val) +#define bfin_read_DMA19_BWL_COUNT() bfin_read32(DMA19_BWL_COUNT) +#define bfin_write_DMA19_BWL_COUNT(val) bfin_write32(DMA19_BWL_COUNT, val) +#define bfin_read_DMA19_CURR_BWL_COUNT() bfin_read32(DMA19_CURR_BWL_COUNT) +#define bfin_write_DMA19_CURR_BWL_COUNT(val) bfin_write32(DMA19_CURR_BWL_COUNT, val) +#define bfin_read_DMA19_BWM_COUNT() bfin_read32(DMA19_BWM_COUNT) +#define bfin_write_DMA19_BWM_COUNT(val) bfin_write32(DMA19_BWM_COUNT, val) +#define bfin_read_DMA19_CURR_BWM_COUNT() bfin_read32(DMA19_CURR_BWM_COUNT) +#define bfin_write_DMA19_CURR_BWM_COUNT(val) bfin_write32(DMA19_CURR_BWM_COUNT, val) + +/* DMA Channel 20 Registers */ + +#define bfin_read_DMA20_NEXT_DESC_PTR() bfin_read32(DMA20_NEXT_DESC_PTR) +#define bfin_write_DMA20_NEXT_DESC_PTR(val) bfin_write32(DMA20_NEXT_DESC_PTR, val) +#define bfin_read_DMA20_START_ADDR() bfin_read32(DMA20_START_ADDR) +#define bfin_write_DMA20_START_ADDR(val) bfin_write32(DMA20_START_ADDR, val) +#define bfin_read_DMA20_CONFIG() bfin_read32(DMA20_CONFIG) +#define bfin_write_DMA20_CONFIG(val) bfin_write32(DMA20_CONFIG, val) +#define bfin_read_DMA20_X_COUNT() bfin_read32(DMA20_X_COUNT) +#define bfin_write_DMA20_X_COUNT(val) bfin_write32(DMA20_X_COUNT, val) +#define bfin_read_DMA20_X_MODIFY() bfin_read32(DMA20_X_MODIFY) +#define bfin_write_DMA20_X_MODIFY(val) bfin_write32(DMA20_X_MODIFY, val) +#define bfin_read_DMA20_Y_COUNT() bfin_read32(DMA20_Y_COUNT) +#define bfin_write_DMA20_Y_COUNT(val) bfin_write32(DMA20_Y_COUNT, val) +#define bfin_read_DMA20_Y_MODIFY() bfin_read32(DMA20_Y_MODIFY) +#define bfin_write_DMA20_Y_MODIFY(val) bfin_write32(DMA20_Y_MODIFY, val) +#define bfin_read_DMA20_CURR_DESC_PTR() bfin_read32(DMA20_CURR_DESC_PTR) +#define bfin_write_DMA20_CURR_DESC_PTR(val) bfin_write32(DMA20_CURR_DESC_PTR, val) +#define bfin_read_DMA20_PREV_DESC_PTR() bfin_read32(DMA20_PREV_DESC_PTR) +#define bfin_write_DMA20_PREV_DESC_PTR(val) bfin_write32(DMA20_PREV_DESC_PTR, val) +#define bfin_read_DMA20_CURR_ADDR() bfin_read32(DMA20_CURR_ADDR) +#define bfin_write_DMA20_CURR_ADDR(val) bfin_write32(DMA20_CURR_ADDR, val) +#define bfin_read_DMA20_IRQ_STATUS() bfin_read32(DMA20_IRQ_STATUS) +#define bfin_write_DMA20_IRQ_STATUS(val) bfin_write32(DMA20_IRQ_STATUS, val) +#define bfin_read_DMA20_CURR_X_COUNT() bfin_read32(DMA20_CURR_X_COUNT) +#define bfin_write_DMA20_CURR_X_COUNT(val) bfin_write32(DMA20_CURR_X_COUNT, val) +#define bfin_read_DMA20_CURR_Y_COUNT() bfin_read32(DMA20_CURR_Y_COUNT) +#define bfin_write_DMA20_CURR_Y_COUNT(val) bfin_write32(DMA20_CURR_Y_COUNT, val) +#define bfin_read_DMA20_BWL_COUNT() bfin_read32(DMA20_BWL_COUNT) +#define bfin_write_DMA20_BWL_COUNT(val) bfin_write32(DMA20_BWL_COUNT, val) +#define bfin_read_DMA20_CURR_BWL_COUNT() bfin_read32(DMA20_CURR_BWL_COUNT) +#define bfin_write_DMA20_CURR_BWL_COUNT(val) bfin_write32(DMA20_CURR_BWL_COUNT, val) +#define bfin_read_DMA20_BWM_COUNT() bfin_read32(DMA20_BWM_COUNT) +#define bfin_write_DMA20_BWM_COUNT(val) bfin_write32(DMA20_BWM_COUNT, val) +#define bfin_read_DMA20_CURR_BWM_COUNT() bfin_read32(DMA20_CURR_BWM_COUNT) +#define bfin_write_DMA20_CURR_BWM_COUNT(val) bfin_write32(DMA20_CURR_BWM_COUNT, val) + + +/* MDMA Stream 0 Registers (DMA Channel 21 and 22) */ + +#define bfin_read_MDMA0_DEST_CRC0_NEXT_DESC_PTR() bfin_read32(MDMA0_DEST_CRC0_NEXT_DESC_PTR) +#define bfin_write_MDMA0_DEST_CRC0_NEXT_DESC_PTR(val) bfin_write32(MDMA0_DEST_CRC0_NEXT_DESC_PTR, val) +#define bfin_read_MDMA0_DEST_CRC0_START_ADDR() bfin_read32(MDMA0_DEST_CRC0_START_ADDR) +#define bfin_write_MDMA0_DEST_CRC0_START_ADDR(val) bfin_write32(MDMA0_DEST_CRC0_START_ADDR, val) +#define bfin_read_MDMA0_DEST_CRC0_CONFIG() bfin_read32(MDMA0_DEST_CRC0_CONFIG) +#define bfin_write_MDMA0_DEST_CRC0_CONFIG(val) bfin_write32(MDMA0_DEST_CRC0_CONFIG, val) +#define bfin_read_MDMA0_DEST_CRC0_X_COUNT() bfin_read32(MDMA0_DEST_CRC0_X_COUNT) +#define bfin_write_MDMA0_DEST_CRC0_X_COUNT(val) bfin_write32(MDMA0_DEST_CRC0_X_COUNT, val) +#define bfin_read_MDMA0_DEST_CRC0_X_MODIFY() bfin_read32(MDMA0_DEST_CRC0_X_MODIFY) +#define bfin_write_MDMA0_DEST_CRC0_X_MODIFY(val) bfin_write32(MDMA0_DEST_CRC0_X_MODIFY, val) +#define bfin_read_MDMA0_DEST_CRC0_Y_COUNT() bfin_read32(MDMA0_DEST_CRC0_Y_COUNT) +#define bfin_write_MDMA0_DEST_CRC0_Y_COUNT(val) bfin_write32(MDMA0_DEST_CRC0_Y_COUNT, val) +#define bfin_read_MDMA0_DEST_CRC0_Y_MODIFY() bfin_read32(MDMA0_DEST_CRC0_Y_MODIFY) +#define bfin_write_MDMA0_DEST_CRC0_Y_MODIFY(val) bfin_write32(MDMA0_DEST_CRC0_Y_MODIFY, val) +#define bfin_read_MDMA0_DEST_CRC0_CURR_DESC_PTR() bfin_read32(MDMA0_DEST_CRC0_CURR_DESC_PTR) +#define bfin_write_MDMA0_DEST_CRC0_CURR_DESC_PTR(val) bfin_write32(MDMA0_DEST_CRC0_CURR_DESC_PTR, val) +#define bfin_read_MDMA0_DEST_CRC0_PREV_DESC_PTR() bfin_read32(MDMA0_DEST_CRC0_PREV_DESC_PTR) +#define bfin_write_MDMA0_DEST_CRC0_PREV_DESC_PTR(val) bfin_write32(MDMA0_DEST_CRC0_PREV_DESC_PTR, val) +#define bfin_read_MDMA0_DEST_CRC0_CURR_ADDR() bfin_read32(MDMA0_DEST_CRC0_CURR_ADDR) +#define bfin_write_MDMA0_DEST_CRC0_CURR_ADDR(val) bfin_write32(MDMA0_DEST_CRC0_CURR_ADDR, val) +#define bfin_read_MDMA0_DEST_CRC0_IRQ_STATUS() bfin_read32(MDMA0_DEST_CRC0_IRQ_STATUS) +#define bfin_write_MDMA0_DEST_CRC0_IRQ_STATUS(val) bfin_write32(MDMA0_DEST_CRC0_IRQ_STATUS, val) +#define bfin_read_MDMA0_DEST_CRC0_CURR_X_COUNT() bfin_read32(MDMA0_DEST_CRC0_CURR_X_COUNT) +#define bfin_write_MDMA0_DEST_CRC0_CURR_X_COUNT(val) bfin_write32(MDMA0_DEST_CRC0_CURR_X_COUNT, val) +#define bfin_read_MDMA0_DEST_CRC0_CURR_Y_COUNT() bfin_read32(MDMA0_DEST_CRC0_CURR_Y_COUNT) +#define bfin_write_MDMA0_DEST_CRC0_CURR_Y_COUNT(val) bfin_write32(MDMA0_DEST_CRC0_CURR_Y_COUNT, val) +#define bfin_read_MDMA0_SRC_CRC0_NEXT_DESC_PTR() bfin_read32(MDMA0_SRC_CRC0_NEXT_DESC_PTR) +#define bfin_write_MDMA0_SRC_CRC0_NEXT_DESC_PTR(val) bfin_write32(MDMA0_SRC_CRC0_NEXT_DESC_PTR, val) +#define bfin_read_MDMA0_SRC_CRC0_START_ADDR() bfin_read32(MDMA0_SRC_CRC0_START_ADDR) +#define bfin_write_MDMA0_SRC_CRC0_START_ADDR(val) bfin_write32(MDMA0_SRC_CRC0_START_ADDR, val) +#define bfin_read_MDMA0_SRC_CRC0_CONFIG() bfin_read32(MDMA0_SRC_CRC0_CONFIG) +#define bfin_write_MDMA0_SRC_CRC0_CONFIG(val) bfin_write32(MDMA0_SRC_CRC0_CONFIG, val) +#define bfin_read_MDMA0_SRC_CRC0_X_COUNT() bfin_read32(MDMA0_SRC_CRC0_X_COUNT) +#define bfin_write_MDMA0_SRC_CRC0_X_COUNT(val) bfin_write32(MDMA0_SRC_CRC0_X_COUNT, val) +#define bfin_read_MDMA0_SRC_CRC0_X_MODIFY() bfin_read32(MDMA0_SRC_CRC0_X_MODIFY) +#define bfin_write_MDMA0_SRC_CRC0_X_MODIFY(val) bfin_write32(MDMA0_SRC_CRC0_X_MODIFY, val) +#define bfin_read_MDMA0_SRC_CRC0_Y_COUNT() bfin_read32(MDMA0_SRC_CRC0_Y_COUNT) +#define bfin_write_MDMA0_SRC_CRC0_Y_COUNT(val) bfin_write32(MDMA0_SRC_CRC0_Y_COUNT, val) +#define bfin_read_MDMA0_SRC_CRC0_Y_MODIFY() bfin_read32(MDMA0_SRC_CRC0_Y_MODIFY) +#define bfin_write_MDMA0_SRC_CRC0_Y_MODIFY(val) bfin_write32(MDMA0_SRC_CRC0_Y_MODIFY, val) +#define bfin_read_MDMA0_SRC_CRC0_CURR_DESC_PTR() bfin_read32(MDMA0_SRC_CRC0_CURR_DESC_PTR) +#define bfin_write_MDMA0_SRC_CRC0_CURR_DESC_PTR(val) bfin_write32(MDMA0_SRC_CRC0_CURR_DESC_PTR, val) +#define bfin_read_MDMA0_SRC_CRC0_PREV_DESC_PTR() bfin_read32(MDMA0_SRC_CRC0_PREV_DESC_PTR) +#define bfin_write_MDMA0_SRC_CRC0_PREV_DESC_PTR(val) bfin_write32(MDMA0_SRC_CRC0_PREV_DESC_PTR, val) +#define bfin_read_MDMA0_SRC_CRC0_CURR_ADDR() bfin_read32(MDMA0_SRC_CRC0_CURR_ADDR) +#define bfin_write_MDMA0_SRC_CRC0_CURR_ADDR(val) bfin_write32(MDMA0_SRC_CRC0_CURR_ADDR, val) +#define bfin_read_MDMA0_SRC_CRC0_IRQ_STATUS() bfin_read32(MDMA0_SRC_CRC0_IRQ_STATUS) +#define bfin_write_MDMA0_SRC_CRC0_IRQ_STATUS(val) bfin_write32(MDMA0_SRC_CRC0_IRQ_STATUS, val) +#define bfin_read_MDMA0_SRC_CRC0_CURR_X_COUNT() bfin_read32(MDMA0_SRC_CRC0_CURR_X_COUNT) +#define bfin_write_MDMA0_SRC_CRC0_CURR_X_COUNT(val) bfin_write32(MDMA0_SRC_CRC0_CURR_X_COUNT, val) +#define bfin_read_MDMA0_SRC_CRC0_CURR_Y_COUNT() bfin_read32(MDMA0_SRC_CRC0_CURR_Y_COUNT) +#define bfin_write_MDMA0_SRC_CRC0_CURR_Y_COUNT(val) bfin_write32(MDMA0_SRC_CRC0_CURR_Y_COUNT, val) + +/* MDMA Stream 1 Registers (DMA Channel 23 and 24) */ + +#define bfin_read_MDMA1_DEST_CRC1_NEXT_DESC_PTR() bfin_read32(MDMA1_DEST_CRC1_NEXT_DESC_PTR) +#define bfin_write_MDMA1_DEST_CRC1_NEXT_DESC_PTR(val) bfin_write32(MDMA1_DEST_CRC1_NEXT_DESC_PTR, val) +#define bfin_read_MDMA1_DEST_CRC1_START_ADDR() bfin_read32(MDMA1_DEST_CRC1_START_ADDR) +#define bfin_write_MDMA1_DEST_CRC1_START_ADDR(val) bfin_write32(MDMA1_DEST_CRC1_START_ADDR, val) +#define bfin_read_MDMA1_DEST_CRC1_CONFIG() bfin_read32(MDMA1_DEST_CRC1_CONFIG) +#define bfin_write_MDMA1_DEST_CRC1_CONFIG(val) bfin_write32(MDMA1_DEST_CRC1_CONFIG, val) +#define bfin_read_MDMA1_DEST_CRC1_X_COUNT() bfin_read32(MDMA1_DEST_CRC1_X_COUNT) +#define bfin_write_MDMA1_DEST_CRC1_X_COUNT(val) bfin_write32(MDMA1_DEST_CRC1_X_COUNT, val) +#define bfin_read_MDMA1_DEST_CRC1_X_MODIFY() bfin_read32(MDMA1_DEST_CRC1_X_MODIFY) +#define bfin_write_MDMA1_DEST_CRC1_X_MODIFY(val) bfin_write32(MDMA1_DEST_CRC1_X_MODIFY, val) +#define bfin_read_MDMA1_DEST_CRC1_Y_COUNT() bfin_read32(MDMA1_DEST_CRC1_Y_COUNT) +#define bfin_write_MDMA1_DEST_CRC1_Y_COUNT(val) bfin_write32(MDMA1_DEST_CRC1_Y_COUNT, val) +#define bfin_read_MDMA1_DEST_CRC1_Y_MODIFY() bfin_read32(MDMA1_DEST_CRC1_Y_MODIFY) +#define bfin_write_MDMA1_DEST_CRC1_Y_MODIFY(val) bfin_write32(MDMA1_DEST_CRC1_Y_MODIFY, val) +#define bfin_read_MDMA1_DEST_CRC1_CURR_DESC_PTR() bfin_read32(MDMA1_DEST_CRC1_CURR_DESC_PTR) +#define bfin_write_MDMA1_DEST_CRC1_CURR_DESC_PTR(val) bfin_write32(MDMA1_DEST_CRC1_CURR_DESC_PTR, val) +#define bfin_read_MDMA1_DEST_CRC1_PREV_DESC_PTR() bfin_read32(MDMA1_DEST_CRC1_PREV_DESC_PTR) +#define bfin_write_MDMA1_DEST_CRC1_PREV_DESC_PTR(val) bfin_write32(MDMA1_DEST_CRC1_PREV_DESC_PTR, val) +#define bfin_read_MDMA1_DEST_CRC1_CURR_ADDR() bfin_read32(MDMA1_DEST_CRC1_CURR_ADDR) +#define bfin_write_MDMA1_DEST_CRC1_CURR_ADDR(val) bfin_write32(MDMA1_DEST_CRC1_CURR_ADDR, val) +#define bfin_read_MDMA1_DEST_CRC1_IRQ_STATUS() bfin_read32(MDMA1_DEST_CRC1_IRQ_STATUS) +#define bfin_write_MDMA1_DEST_CRC1_IRQ_STATUS(val) bfin_write32(MDMA1_DEST_CRC1_IRQ_STATUS, val) +#define bfin_read_MDMA1_DEST_CRC1_CURR_X_COUNT() bfin_read32(MDMA1_DEST_CRC1_CURR_X_COUNT) +#define bfin_write_MDMA1_DEST_CRC1_CURR_X_COUNT(val) bfin_write32(MDMA1_DEST_CRC1_CURR_X_COUNT, val) +#define bfin_read_MDMA1_DEST_CRC1_CURR_Y_COUNT() bfin_read32(MDMA1_DEST_CRC1_CURR_Y_COUNT) +#define bfin_write_MDMA1_DEST_CRC1_CURR_Y_COUNT(val) bfin_write32(MDMA1_DEST_CRC1_CURR_Y_COUNT, val) +#define bfin_read_MDMA1_SRC_CRC1_NEXT_DESC_PTR() bfin_read32(MDMA1_SRC_CRC1_NEXT_DESC_PTR) +#define bfin_write_MDMA1_SRC_CRC1_NEXT_DESC_PTR(val) bfin_write32(MDMA1_SRC_CRC1_NEXT_DESC_PTR, val) +#define bfin_read_MDMA1_SRC_CRC1_START_ADDR() bfin_read32(MDMA1_SRC_CRC1_START_ADDR) +#define bfin_write_MDMA1_SRC_CRC1_START_ADDR(val) bfin_write32(MDMA1_SRC_CRC1_START_ADDR, val) +#define bfin_read_MDMA1_SRC_CRC1_CONFIG() bfin_read32(MDMA1_SRC_CRC1_CONFIG) +#define bfin_write_MDMA1_SRC_CRC1_CONFIG(val) bfin_write32(MDMA1_SRC_CRC1_CONFIG, val) +#define bfin_read_MDMA1_SRC_CRC1_X_COUNT() bfin_read32(MDMA1_SRC_CRC1_X_COUNT) +#define bfin_write_MDMA1_SRC_CRC1_X_COUNT(val) bfin_write32(MDMA1_SRC_CRC1_X_COUNT, val) +#define bfin_read_MDMA1_SRC_CRC1_X_MODIFY() bfin_read32(MDMA1_SRC_CRC1_X_MODIFY) +#define bfin_write_MDMA1_SRC_CRC1_X_MODIFY(val) bfin_write32(MDMA1_SRC_CRC1_X_MODIFY, val) +#define bfin_read_MDMA1_SRC_CRC1_Y_COUNT() bfin_read32(MDMA1_SRC_CRC1_Y_COUNT) +#define bfin_write_MDMA1_SRC_CRC1_Y_COUNT(val) bfin_write32(MDMA1_SRC_CRC1_Y_COUNT, val) +#define bfin_read_MDMA1_SRC_CRC1_Y_MODIFY() bfin_read32(MDMA1_SRC_CRC1_Y_MODIFY) +#define bfin_write_MDMA1_SRC_CRC1_Y_MODIFY(val) bfin_write32(MDMA1_SRC_CRC1_Y_MODIFY, val) +#define bfin_read_MDMA1_SRC_CRC1_CURR_DESC_PTR() bfin_read32(MDMA1_SRC_CRC1_CURR_DESC_PTR) +#define bfin_write_MDMA1_SRC_CRC1_CURR_DESC_PTR(val) bfin_write32(MDMA1_SRC_CRC1_CURR_DESC_PTR, val) +#define bfin_read_MDMA1_SRC_CRC1_PREV_DESC_PTR() bfin_read32(MDMA1_SRC_CRC1_PREV_DESC_PTR) +#define bfin_write_MDMA1_SRC_CRC1_PREV_DESC_PTR(val) bfin_write32(MDMA1_SRC_CRC1_PREV_DESC_PTR, val) +#define bfin_read_MDMA1_SRC_CRC1_CURR_ADDR() bfin_read32(MDMA1_SRC_CRC1_CURR_ADDR) +#define bfin_write_MDMA1_SRC_CRC1_CURR_ADDR(val) bfin_write32(MDMA1_SRC_CRC1_CURR_ADDR, val) +#define bfin_read_MDMA1_SRC_CRC1_IRQ_STATUS() bfin_read32(MDMA1_SRC_CRC1_IRQ_STATUS) +#define bfin_write_MDMA1_SRC_CRC1_IRQ_STATUS(val) bfin_write32(MDMA1_SRC_CRC1_IRQ_STATUS, val) +#define bfin_read_MDMA1_SRC_CRC1_CURR_X_COUNT() bfin_read32(MDMA1_SRC_CRC1_CURR_X_COUNT) +#define bfin_write_MDMA1_SRC_CRC1_CURR_X_COUNT(val) bfin_write32(MDMA1_SRC_CRC1_CURR_X_COUNT, val) +#define bfin_read_MDMA1_SRC_CRC1_CURR_Y_COUNT() bfin_read32(MDMA1_SRC_CRC1_CURR_Y_COUNT) +#define bfin_write_MDMA1_SRC_CRC1_CURR_Y_COUNT(val) bfin_write32(MDMA1_SRC_CRC1_CURR_Y_COUNT, val) + + +/* MDMA Stream 2 Registers (DMA Channel 25 and 26) */ + +#define bfin_read_MDMA2_DEST_NEXT_DESC_PTR() bfin_read32(MDMA2_DEST_NEXT_DESC_PTR) +#define bfin_write_MDMA2_DEST_NEXT_DESC_PTR(val) bfin_write32(MDMA2_DEST_NEXT_DESC_PTR, val) +#define bfin_read_MDMA2_DEST_START_ADDR() bfin_read32(MDMA2_DEST_START_ADDR) +#define bfin_write_MDMA2_DEST_START_ADDR(val) bfin_write32(MDMA2_DEST_START_ADDR, val) +#define bfin_read_MDMA2_DEST_CONFIG() bfin_read32(MDMA2_DEST_CONFIG) +#define bfin_write_MDMA2_DEST_CONFIG(val) bfin_write32(MDMA2_DEST_CONFIG, val) +#define bfin_read_MDMA2_DEST_X_COUNT() bfin_read32(MDMA2_DEST_X_COUNT) +#define bfin_write_MDMA2_DEST_X_COUNT(val) bfin_write32(MDMA2_DEST_X_COUNT, val) +#define bfin_read_MDMA2_DEST_X_MODIFY() bfin_read32(MDMA2_DEST_X_MODIFY) +#define bfin_write_MDMA2_DEST_X_MODIFY(val) bfin_write32(MDMA2_DEST_X_MODIFY, val) +#define bfin_read_MDMA2_DEST_Y_COUNT() bfin_read32(MDMA2_DEST_Y_COUNT) +#define bfin_write_MDMA2_DEST_Y_COUNT(val) bfin_write32(MDMA2_DEST_Y_COUNT, val) +#define bfin_read_MDMA2_DEST_Y_MODIFY() bfin_read32(MDMA2_DEST_Y_MODIFY) +#define bfin_write_MDMA2_DEST_Y_MODIFY(val) bfin_write32(MDMA2_DEST_Y_MODIFY, val) +#define bfin_read_MDMA2_DEST_CURR_DESC_PTR() bfin_read32(MDMA2_DEST_CURR_DESC_PTR) +#define bfin_write_MDMA2_DEST_CURR_DESC_PTR(val) bfin_write32(MDMA2_DEST_CURR_DESC_PTR, val) +#define bfin_read_MDMA2_DEST_PREV_DESC_PTR() bfin_read32(MDMA2_DEST_PREV_DESC_PTR) +#define bfin_write_MDMA2_DEST_PREV_DESC_PTR(val) bfin_write32(MDMA2_DEST_PREV_DESC_PTR, val) +#define bfin_read_MDMA2_DEST_CURR_ADDR() bfin_read32(MDMA2_DEST_CURR_ADDR) +#define bfin_write_MDMA2_DEST_CURR_ADDR(val) bfin_write32(MDMA2_DEST_CURR_ADDR, val) +#define bfin_read_MDMA2_DEST_IRQ_STATUS() bfin_read32(MDMA2_DEST_IRQ_STATUS) +#define bfin_write_MDMA2_DEST_IRQ_STATUS(val) bfin_write32(MDMA2_DEST_IRQ_STATUS, val) +#define bfin_read_MDMA2_DEST_CURR_X_COUNT() bfin_read32(MDMA2_DEST_CURR_X_COUNT) +#define bfin_write_MDMA2_DEST_CURR_X_COUNT(val) bfin_write32(MDMA2_DEST_CURR_X_COUNT, val) +#define bfin_read_MDMA2_DEST_CURR_Y_COUNT() bfin_read32(MDMA2_DEST_CURR_Y_COUNT) +#define bfin_write_MDMA2_DEST_CURR_Y_COUNT(val) bfin_write32(MDMA2_DEST_CURR_Y_COUNT, val) +#define bfin_read_MDMA2_SRC_NEXT_DESC_PTR() bfin_read32(MDMA2_SRC_NEXT_DESC_PTR) +#define bfin_write_MDMA2_SRC_NEXT_DESC_PTR(val) bfin_write32(MDMA2_SRC_NEXT_DESC_PTR, val) +#define bfin_read_MDMA2_SRC_START_ADDR() bfin_read32(MDMA2_SRC_START_ADDR) +#define bfin_write_MDMA2_SRC_START_ADDR(val) bfin_write32(MDMA2_SRC_START_ADDR, val) +#define bfin_read_MDMA2_SRC_CONFIG() bfin_read32(MDMA2_SRC_CONFIG) +#define bfin_write_MDMA2_SRC_CONFIG(val) bfin_write32(MDMA2_SRC_CONFIG, val) +#define bfin_read_MDMA2_SRC_X_COUNT() bfin_read32(MDMA2_SRC_X_COUNT) +#define bfin_write_MDMA2_SRC_X_COUNT(val) bfin_write32(MDMA2_SRC_X_COUNT, val) +#define bfin_read_MDMA2_SRC_X_MODIFY() bfin_read32(MDMA2_SRC_X_MODIFY) +#define bfin_write_MDMA2_SRC_X_MODIFY(val) bfin_write32(MDMA2_SRC_X_MODIFY, val) +#define bfin_read_MDMA2_SRC_Y_COUNT() bfin_read32(MDMA2_SRC_Y_COUNT) +#define bfin_write_MDMA2_SRC_Y_COUNT(val) bfin_write32(MDMA2_SRC_Y_COUNT, val) +#define bfin_read_MDMA2_SRC_Y_MODIFY() bfin_read32(MDMA2_SRC_Y_MODIFY) +#define bfin_write_MDMA2_SRC_Y_MODIFY(val) bfin_write32(MDMA2_SRC_Y_MODIFY, val) +#define bfin_read_MDMA2_SRC_CURR_DESC_PTR() bfin_read32(MDMA2_SRC_CURR_DESC_PTR) +#define bfin_write_MDMA2_SRC_CURR_DESC_PTR(val) bfin_write32(MDMA2_SRC_CURR_DESC_PTR, val) +#define bfin_read_MDMA2_SRC_PREV_DESC_PTR() bfin_read32(MDMA2_SRC_PREV_DESC_PTR) +#define bfin_write_MDMA2_SRC_PREV_DESC_PTR(val) bfin_write32(MDMA2_SRC_PREV_DESC_PTR, val) +#define bfin_read_MDMA2_SRC_CURR_ADDR() bfin_read32(MDMA2_SRC_CURR_ADDR) +#define bfin_write_MDMA2_SRC_CURR_ADDR(val) bfin_write32(MDMA2_SRC_CURR_ADDR, val) +#define bfin_read_MDMA2_SRC_IRQ_STATUS() bfin_read32(MDMA2_SRC_IRQ_STATUS) +#define bfin_write_MDMA2_SRC_IRQ_STATUS(val) bfin_write32(MDMA2_SRC_IRQ_STATUS, val) +#define bfin_read_MDMA2_SRC_CURR_X_COUNT() bfin_read32(MDMA2_SRC_CURR_X_COUNT) +#define bfin_write_MDMA2_SRC_CURR_X_COUNT(val) bfin_write32(MDMA2_SRC_CURR_X_COUNT, val) +#define bfin_read_MDMA2_SRC_CURR_Y_COUNT() bfin_read32(MDMA2_SRC_CURR_Y_COUNT) +#define bfin_write_MDMA2_SRC_CURR_Y_COUNT(val) bfin_write32(MDMA2_SRC_CURR_Y_COUNT, val) + +/* MDMA Stream 3 Registers (DMA Channel 27 and 28) */ + +#define bfin_read_MDMA3_DEST_NEXT_DESC_PTR() bfin_read32(MDMA3_DEST_NEXT_DESC_PTR) +#define bfin_write_MDMA3_DEST_NEXT_DESC_PTR(val) bfin_write32(MDMA3_DEST_NEXT_DESC_PTR, val) +#define bfin_read_MDMA3_DEST_START_ADDR() bfin_read32(MDMA3_DEST_START_ADDR) +#define bfin_write_MDMA3_DEST_START_ADDR(val) bfin_write32(MDMA3_DEST_START_ADDR, val) +#define bfin_read_MDMA3_DEST_CONFIG() bfin_read32(MDMA3_DEST_CONFIG) +#define bfin_write_MDMA3_DEST_CONFIG(val) bfin_write32(MDMA3_DEST_CONFIG, val) +#define bfin_read_MDMA3_DEST_X_COUNT() bfin_read32(MDMA3_DEST_X_COUNT) +#define bfin_write_MDMA3_DEST_X_COUNT(val) bfin_write32(MDMA3_DEST_X_COUNT, val) +#define bfin_read_MDMA3_DEST_X_MODIFY() bfin_read32(MDMA3_DEST_X_MODIFY) +#define bfin_write_MDMA3_DEST_X_MODIFY(val) bfin_write32(MDMA3_DEST_X_MODIFY, val) +#define bfin_read_MDMA3_DEST_Y_COUNT() bfin_read32(MDMA3_DEST_Y_COUNT) +#define bfin_write_MDMA3_DEST_Y_COUNT(val) bfin_write32(MDMA3_DEST_Y_COUNT, val) +#define bfin_read_MDMA3_DEST_Y_MODIFY() bfin_read32(MDMA3_DEST_Y_MODIFY) +#define bfin_write_MDMA3_DEST_Y_MODIFY(val) bfin_write32(MDMA3_DEST_Y_MODIFY, val) +#define bfin_read_MDMA3_DEST_CURR_DESC_PTR() bfin_read32(MDMA3_DEST_CURR_DESC_PTR) +#define bfin_write_MDMA3_DEST_CURR_DESC_PTR(val) bfin_write32(MDMA3_DEST_CURR_DESC_PTR, val) +#define bfin_read_MDMA3_DEST_PREV_DESC_PTR() bfin_read32(MDMA3_DEST_PREV_DESC_PTR) +#define bfin_write_MDMA3_DEST_PREV_DESC_PTR(val) bfin_write32(MDMA3_DEST_PREV_DESC_PTR, val) +#define bfin_read_MDMA3_DEST_CURR_ADDR() bfin_read32(MDMA3_DEST_CURR_ADDR) +#define bfin_write_MDMA3_DEST_CURR_ADDR(val) bfin_write32(MDMA3_DEST_CURR_ADDR, val) +#define bfin_read_MDMA3_DEST_IRQ_STATUS() bfin_read32(MDMA3_DEST_IRQ_STATUS) +#define bfin_write_MDMA3_DEST_IRQ_STATUS(val) bfin_write32(MDMA3_DEST_IRQ_STATUS, val) +#define bfin_read_MDMA3_DEST_CURR_X_COUNT() bfin_read32(MDMA3_DEST_CURR_X_COUNT) +#define bfin_write_MDMA3_DEST_CURR_X_COUNT(val) bfin_write32(MDMA3_DEST_CURR_X_COUNT, val) +#define bfin_read_MDMA3_DEST_CURR_Y_COUNT() bfin_read32(MDMA3_DEST_CURR_Y_COUNT) +#define bfin_write_MDMA3_DEST_CURR_Y_COUNT(val) bfin_write32(MDMA3_DEST_CURR_Y_COUNT, val) +#define bfin_read_MDMA3_SRC_NEXT_DESC_PTR() bfin_read32(MDMA3_SRC_NEXT_DESC_PTR) +#define bfin_write_MDMA3_SRC_NEXT_DESC_PTR(val) bfin_write32(MDMA3_SRC_NEXT_DESC_PTR, val) +#define bfin_read_MDMA3_SRC_START_ADDR() bfin_read32(MDMA3_SRC_START_ADDR) +#define bfin_write_MDMA3_SRC_START_ADDR(val) bfin_write32(MDMA3_SRC_START_ADDR, val) +#define bfin_read_MDMA3_SRC_CONFIG() bfin_read32(MDMA3_SRC_CONFIG) +#define bfin_write_MDMA3_SRC_CONFIG(val) bfin_write32(MDMA3_SRC_CONFIG, val) +#define bfin_read_MDMA3_SRC_X_COUNT() bfin_read32(MDMA3_SRC_X_COUNT) +#define bfin_write_MDMA3_SRC_X_COUNT(val) bfin_write32(MDMA3_SRC_X_COUNT, val) +#define bfin_read_MDMA3_SRC_X_MODIFY() bfin_read32(MDMA3_SRC_X_MODIFY) +#define bfin_write_MDMA3_SRC_X_MODIFY(val) bfin_write32(MDMA3_SRC_X_MODIFY, val) +#define bfin_read_MDMA3_SRC_Y_COUNT() bfin_read32(MDMA3_SRC_Y_COUNT) +#define bfin_write_MDMA3_SRC_Y_COUNT(val) bfin_write32(MDMA3_SRC_Y_COUNT, val) +#define bfin_read_MDMA3_SRC_Y_MODIFY() bfin_read32(MDMA3_SRC_Y_MODIFY) +#define bfin_write_MDMA3_SRC_Y_MODIFY(val) bfin_write32(MDMA3_SRC_Y_MODIFY, val) +#define bfin_read_MDMA3_SRC_CURR_DESC_PTR() bfin_read32(MDMA3_SRC_CURR_DESC_PTR) +#define bfin_write_MDMA3_SRC_CURR_DESC_PTR(val) bfin_write32(MDMA3_SRC_CURR_DESC_PTR, val) +#define bfin_read_MDMA3_SRC_PREV_DESC_PTR() bfin_read32(MDMA3_SRC_PREV_DESC_PTR) +#define bfin_write_MDMA3_SRC_PREV_DESC_PTR(val) bfin_write32(MDMA3_SRC_PREV_DESC_PTR, val) +#define bfin_read_MDMA3_SRC_CURR_ADDR() bfin_read32(MDMA3_SRC_CURR_ADDR) +#define bfin_write_MDMA3_SRC_CURR_ADDR(val) bfin_write32(MDMA3_SRC_CURR_ADDR, val) +#define bfin_read_MDMA3_SRC_IRQ_STATUS() bfin_read32(MDMA3_SRC_IRQ_STATUS) +#define bfin_write_MDMA3_SRC_IRQ_STATUS(val) bfin_write32(MDMA3_SRC_IRQ_STATUS, val) +#define bfin_read_MDMA3_SRC_CURR_X_COUNT() bfin_read32(MDMA3_SRC_CURR_X_COUNT) +#define bfin_write_MDMA3_SRC_CURR_X_COUNT(val) bfin_write32(MDMA3_SRC_CURR_X_COUNT, val) +#define bfin_read_MDMA3_SRC_CURR_Y_COUNT() bfin_read32(MDMA3_SRC_CURR_Y_COUNT) +#define bfin_write_MDMA3_SRC_CURR_Y_COUNT(val) bfin_write32(MDMA3_SRC_CURR_Y_COUNT, val) + + +/* DMA Channel 29 Registers */ + +#define bfin_read_DMA29_NEXT_DESC_PTR() bfin_read32(DMA29_NEXT_DESC_PTR) +#define bfin_write_DMA29_NEXT_DESC_PTR(val) bfin_write32(DMA29_NEXT_DESC_PTR, val) +#define bfin_read_DMA29_START_ADDR() bfin_read32(DMA29_START_ADDR) +#define bfin_write_DMA29_START_ADDR(val) bfin_write32(DMA29_START_ADDR, val) +#define bfin_read_DMA29_CONFIG() bfin_read32(DMA29_CONFIG) +#define bfin_write_DMA29_CONFIG(val) bfin_write32(DMA29_CONFIG, val) +#define bfin_read_DMA29_X_COUNT() bfin_read32(DMA29_X_COUNT) +#define bfin_write_DMA29_X_COUNT(val) bfin_write32(DMA29_X_COUNT, val) +#define bfin_read_DMA29_X_MODIFY() bfin_read32(DMA29_X_MODIFY) +#define bfin_write_DMA29_X_MODIFY(val) bfin_write32(DMA29_X_MODIFY, val) +#define bfin_read_DMA29_Y_COUNT() bfin_read32(DMA29_Y_COUNT) +#define bfin_write_DMA29_Y_COUNT(val) bfin_write32(DMA29_Y_COUNT, val) +#define bfin_read_DMA29_Y_MODIFY() bfin_read32(DMA29_Y_MODIFY) +#define bfin_write_DMA29_Y_MODIFY(val) bfin_write32(DMA29_Y_MODIFY, val) +#define bfin_read_DMA29_CURR_DESC_PTR() bfin_read32(DMA29_CURR_DESC_PTR) +#define bfin_write_DMA29_CURR_DESC_PTR(val) bfin_write32(DMA29_CURR_DESC_PTR, val) +#define bfin_read_DMA29_PREV_DESC_PTR() bfin_read32(DMA29_PREV_DESC_PTR) +#define bfin_write_DMA29_PREV_DESC_PTR(val) bfin_write32(DMA29_PREV_DESC_PTR, val) +#define bfin_read_DMA29_CURR_ADDR() bfin_read32(DMA29_CURR_ADDR) +#define bfin_write_DMA29_CURR_ADDR(val) bfin_write32(DMA29_CURR_ADDR, val) +#define bfin_read_DMA29_IRQ_STATUS() bfin_read32(DMA29_IRQ_STATUS) +#define bfin_write_DMA29_IRQ_STATUS(val) bfin_write32(DMA29_IRQ_STATUS, val) +#define bfin_read_DMA29_CURR_X_COUNT() bfin_read32(DMA29_CURR_X_COUNT) +#define bfin_write_DMA29_CURR_X_COUNT(val) bfin_write32(DMA29_CURR_X_COUNT, val) +#define bfin_read_DMA29_CURR_Y_COUNT() bfin_read32(DMA29_CURR_Y_COUNT) +#define bfin_write_DMA29_CURR_Y_COUNT(val) bfin_write32(DMA29_CURR_Y_COUNT, val) +#define bfin_read_DMA29_BWL_COUNT() bfin_read32(DMA29_BWL_COUNT) +#define bfin_write_DMA29_BWL_COUNT(val) bfin_write32(DMA29_BWL_COUNT, val) +#define bfin_read_DMA29_CURR_BWL_COUNT() bfin_read32(DMA29_CURR_BWL_COUNT) +#define bfin_write_DMA29_CURR_BWL_COUNT(val) bfin_write32(DMA29_CURR_BWL_COUNT, val) +#define bfin_read_DMA29_BWM_COUNT() bfin_read32(DMA29_BWM_COUNT) +#define bfin_write_DMA29_BWM_COUNT(val) bfin_write32(DMA29_BWM_COUNT, val) +#define bfin_read_DMA29_CURR_BWM_COUNT() bfin_read32(DMA29_CURR_BWM_COUNT) +#define bfin_write_DMA29_CURR_BWM_COUNT(val) bfin_write32(DMA29_CURR_BWM_COUNT, val) + +/* DMA Channel 30 Registers */ + +#define bfin_read_DMA30_NEXT_DESC_PTR() bfin_read32(DMA30_NEXT_DESC_PTR) +#define bfin_write_DMA30_NEXT_DESC_PTR(val) bfin_write32(DMA30_NEXT_DESC_PTR, val) +#define bfin_read_DMA30_START_ADDR() bfin_read32(DMA30_START_ADDR) +#define bfin_write_DMA30_START_ADDR(val) bfin_write32(DMA30_START_ADDR, val) +#define bfin_read_DMA30_CONFIG() bfin_read32(DMA30_CONFIG) +#define bfin_write_DMA30_CONFIG(val) bfin_write32(DMA30_CONFIG, val) +#define bfin_read_DMA30_X_COUNT() bfin_read32(DMA30_X_COUNT) +#define bfin_write_DMA30_X_COUNT(val) bfin_write32(DMA30_X_COUNT, val) +#define bfin_read_DMA30_X_MODIFY() bfin_read32(DMA30_X_MODIFY) +#define bfin_write_DMA30_X_MODIFY(val) bfin_write32(DMA30_X_MODIFY, val) +#define bfin_read_DMA30_Y_COUNT() bfin_read32(DMA30_Y_COUNT) +#define bfin_write_DMA30_Y_COUNT(val) bfin_write32(DMA30_Y_COUNT, val) +#define bfin_read_DMA30_Y_MODIFY() bfin_read32(DMA30_Y_MODIFY) +#define bfin_write_DMA30_Y_MODIFY(val) bfin_write32(DMA30_Y_MODIFY, val) +#define bfin_read_DMA30_CURR_DESC_PTR() bfin_read32(DMA30_CURR_DESC_PTR) +#define bfin_write_DMA30_CURR_DESC_PTR(val) bfin_write32(DMA30_CURR_DESC_PTR, val) +#define bfin_read_DMA30_PREV_DESC_PTR() bfin_read32(DMA30_PREV_DESC_PTR) +#define bfin_write_DMA30_PREV_DESC_PTR(val) bfin_write32(DMA30_PREV_DESC_PTR, val) +#define bfin_read_DMA30_CURR_ADDR() bfin_read32(DMA30_CURR_ADDR) +#define bfin_write_DMA30_CURR_ADDR(val) bfin_write32(DMA30_CURR_ADDR, val) +#define bfin_read_DMA30_IRQ_STATUS() bfin_read32(DMA30_IRQ_STATUS) +#define bfin_write_DMA30_IRQ_STATUS(val) bfin_write32(DMA30_IRQ_STATUS, val) +#define bfin_read_DMA30_CURR_X_COUNT() bfin_read32(DMA30_CURR_X_COUNT) +#define bfin_write_DMA30_CURR_X_COUNT(val) bfin_write32(DMA30_CURR_X_COUNT, val) +#define bfin_read_DMA30_CURR_Y_COUNT() bfin_read32(DMA30_CURR_Y_COUNT) +#define bfin_write_DMA30_CURR_Y_COUNT(val) bfin_write32(DMA30_CURR_Y_COUNT, val) +#define bfin_read_DMA30_BWL_COUNT() bfin_read32(DMA30_BWL_COUNT) +#define bfin_write_DMA30_BWL_COUNT(val) bfin_write32(DMA30_BWL_COUNT, val) +#define bfin_read_DMA30_CURR_BWL_COUNT() bfin_read32(DMA30_CURR_BWL_COUNT) +#define bfin_write_DMA30_CURR_BWL_COUNT(val) bfin_write32(DMA30_CURR_BWL_COUNT, val) +#define bfin_read_DMA30_BWM_COUNT() bfin_read32(DMA30_BWM_COUNT) +#define bfin_write_DMA30_BWM_COUNT(val) bfin_write32(DMA30_BWM_COUNT, val) +#define bfin_read_DMA30_CURR_BWM_COUNT() bfin_read32(DMA30_CURR_BWM_COUNT) +#define bfin_write_DMA30_CURR_BWM_COUNT(val) bfin_write32(DMA30_CURR_BWM_COUNT, val) + +/* DMA Channel 31 Registers */ + +#define bfin_read_DMA31_NEXT_DESC_PTR() bfin_read32(DMA31_NEXT_DESC_PTR) +#define bfin_write_DMA31_NEXT_DESC_PTR(val) bfin_write32(DMA31_NEXT_DESC_PTR, val) +#define bfin_read_DMA31_START_ADDR() bfin_read32(DMA31_START_ADDR) +#define bfin_write_DMA31_START_ADDR(val) bfin_write32(DMA31_START_ADDR, val) +#define bfin_read_DMA31_CONFIG() bfin_read32(DMA31_CONFIG) +#define bfin_write_DMA31_CONFIG(val) bfin_write32(DMA31_CONFIG, val) +#define bfin_read_DMA31_X_COUNT() bfin_read32(DMA31_X_COUNT) +#define bfin_write_DMA31_X_COUNT(val) bfin_write32(DMA31_X_COUNT, val) +#define bfin_read_DMA31_X_MODIFY() bfin_read32(DMA31_X_MODIFY) +#define bfin_write_DMA31_X_MODIFY(val) bfin_write32(DMA31_X_MODIFY, val) +#define bfin_read_DMA31_Y_COUNT() bfin_read32(DMA31_Y_COUNT) +#define bfin_write_DMA31_Y_COUNT(val) bfin_write32(DMA31_Y_COUNT, val) +#define bfin_read_DMA31_Y_MODIFY() bfin_read32(DMA31_Y_MODIFY) +#define bfin_write_DMA31_Y_MODIFY(val) bfin_write32(DMA31_Y_MODIFY, val) +#define bfin_read_DMA31_CURR_DESC_PTR() bfin_read32(DMA31_CURR_DESC_PTR) +#define bfin_write_DMA31_CURR_DESC_PTR(val) bfin_write32(DMA31_CURR_DESC_PTR, val) +#define bfin_read_DMA31_PREV_DESC_PTR() bfin_read32(DMA31_PREV_DESC_PTR) +#define bfin_write_DMA31_PREV_DESC_PTR(val) bfin_write32(DMA31_PREV_DESC_PTR, val) +#define bfin_read_DMA31_CURR_ADDR() bfin_read32(DMA31_CURR_ADDR) +#define bfin_write_DMA31_CURR_ADDR(val) bfin_write32(DMA31_CURR_ADDR, val) +#define bfin_read_DMA31_IRQ_STATUS() bfin_read32(DMA31_IRQ_STATUS) +#define bfin_write_DMA31_IRQ_STATUS(val) bfin_write32(DMA31_IRQ_STATUS, val) +#define bfin_read_DMA31_CURR_X_COUNT() bfin_read32(DMA31_CURR_X_COUNT) +#define bfin_write_DMA31_CURR_X_COUNT(val) bfin_write32(DMA31_CURR_X_COUNT, val) +#define bfin_read_DMA31_CURR_Y_COUNT() bfin_read32(DMA31_CURR_Y_COUNT) +#define bfin_write_DMA31_CURR_Y_COUNT(val) bfin_write32(DMA31_CURR_Y_COUNT, val) +#define bfin_read_DMA31_BWL_COUNT() bfin_read32(DMA31_BWL_COUNT) +#define bfin_write_DMA31_BWL_COUNT(val) bfin_write32(DMA31_BWL_COUNT, val) +#define bfin_read_DMA31_CURR_BWL_COUNT() bfin_read32(DMA31_CURR_BWL_COUNT) +#define bfin_write_DMA31_CURR_BWL_COUNT(val) bfin_write32(DMA31_CURR_BWL_COUNT, val) +#define bfin_read_DMA31_BWM_COUNT() bfin_read32(DMA31_BWM_COUNT) +#define bfin_write_DMA31_BWM_COUNT(val) bfin_write32(DMA31_BWM_COUNT, val) +#define bfin_read_DMA31_CURR_BWM_COUNT() bfin_read32(DMA31_CURR_BWM_COUNT) +#define bfin_write_DMA31_CURR_BWM_COUNT(val) bfin_write32(DMA31_CURR_BWM_COUNT, val) + +/* DMA Channel 32 Registers */ + +#define bfin_read_DMA32_NEXT_DESC_PTR() bfin_read32(DMA32_NEXT_DESC_PTR) +#define bfin_write_DMA32_NEXT_DESC_PTR(val) bfin_write32(DMA32_NEXT_DESC_PTR, val) +#define bfin_read_DMA32_START_ADDR() bfin_read32(DMA32_START_ADDR) +#define bfin_write_DMA32_START_ADDR(val) bfin_write32(DMA32_START_ADDR, val) +#define bfin_read_DMA32_CONFIG() bfin_read32(DMA32_CONFIG) +#define bfin_write_DMA32_CONFIG(val) bfin_write32(DMA32_CONFIG, val) +#define bfin_read_DMA32_X_COUNT() bfin_read32(DMA32_X_COUNT) +#define bfin_write_DMA32_X_COUNT(val) bfin_write32(DMA32_X_COUNT, val) +#define bfin_read_DMA32_X_MODIFY() bfin_read32(DMA32_X_MODIFY) +#define bfin_write_DMA32_X_MODIFY(val) bfin_write32(DMA32_X_MODIFY, val) +#define bfin_read_DMA32_Y_COUNT() bfin_read32(DMA32_Y_COUNT) +#define bfin_write_DMA32_Y_COUNT(val) bfin_write32(DMA32_Y_COUNT, val) +#define bfin_read_DMA32_Y_MODIFY() bfin_read32(DMA32_Y_MODIFY) +#define bfin_write_DMA32_Y_MODIFY(val) bfin_write32(DMA32_Y_MODIFY, val) +#define bfin_read_DMA32_CURR_DESC_PTR() bfin_read32(DMA32_CURR_DESC_PTR) +#define bfin_write_DMA32_CURR_DESC_PTR(val) bfin_write32(DMA32_CURR_DESC_PTR, val) +#define bfin_read_DMA32_PREV_DESC_PTR() bfin_read32(DMA32_PREV_DESC_PTR) +#define bfin_write_DMA32_PREV_DESC_PTR(val) bfin_write32(DMA32_PREV_DESC_PTR, val) +#define bfin_read_DMA32_CURR_ADDR() bfin_read32(DMA32_CURR_ADDR) +#define bfin_write_DMA32_CURR_ADDR(val) bfin_write32(DMA32_CURR_ADDR, val) +#define bfin_read_DMA32_IRQ_STATUS() bfin_read32(DMA32_IRQ_STATUS) +#define bfin_write_DMA32_IRQ_STATUS(val) bfin_write32(DMA32_IRQ_STATUS, val) +#define bfin_read_DMA32_CURR_X_COUNT() bfin_read32(DMA32_CURR_X_COUNT) +#define bfin_write_DMA32_CURR_X_COUNT(val) bfin_write32(DMA32_CURR_X_COUNT, val) +#define bfin_read_DMA32_CURR_Y_COUNT() bfin_read32(DMA32_CURR_Y_COUNT) +#define bfin_write_DMA32_CURR_Y_COUNT(val) bfin_write32(DMA32_CURR_Y_COUNT, val) +#define bfin_read_DMA32_BWL_COUNT() bfin_read32(DMA32_BWL_COUNT) +#define bfin_write_DMA32_BWL_COUNT(val) bfin_write32(DMA32_BWL_COUNT, val) +#define bfin_read_DMA32_CURR_BWL_COUNT() bfin_read32(DMA32_CURR_BWL_COUNT) +#define bfin_write_DMA32_CURR_BWL_COUNT(val) bfin_write32(DMA32_CURR_BWL_COUNT, val) +#define bfin_read_DMA32_BWM_COUNT() bfin_read32(DMA32_BWM_COUNT) +#define bfin_write_DMA32_BWM_COUNT(val) bfin_write32(DMA32_BWM_COUNT, val) +#define bfin_read_DMA32_CURR_BWM_COUNT() bfin_read32(DMA32_CURR_BWM_COUNT) +#define bfin_write_DMA32_CURR_BWM_COUNT(val) bfin_write32(DMA32_CURR_BWM_COUNT, val) + +/* DMA Channel 33 Registers */ + +#define bfin_read_DMA33_NEXT_DESC_PTR() bfin_read32(DMA33_NEXT_DESC_PTR) +#define bfin_write_DMA33_NEXT_DESC_PTR(val) bfin_write32(DMA33_NEXT_DESC_PTR, val) +#define bfin_read_DMA33_START_ADDR() bfin_read32(DMA33_START_ADDR) +#define bfin_write_DMA33_START_ADDR(val) bfin_write32(DMA33_START_ADDR, val) +#define bfin_read_DMA33_CONFIG() bfin_read32(DMA33_CONFIG) +#define bfin_write_DMA33_CONFIG(val) bfin_write32(DMA33_CONFIG, val) +#define bfin_read_DMA33_X_COUNT() bfin_read32(DMA33_X_COUNT) +#define bfin_write_DMA33_X_COUNT(val) bfin_write32(DMA33_X_COUNT, val) +#define bfin_read_DMA33_X_MODIFY() bfin_read32(DMA33_X_MODIFY) +#define bfin_write_DMA33_X_MODIFY(val) bfin_write32(DMA33_X_MODIFY, val) +#define bfin_read_DMA33_Y_COUNT() bfin_read32(DMA33_Y_COUNT) +#define bfin_write_DMA33_Y_COUNT(val) bfin_write32(DMA33_Y_COUNT, val) +#define bfin_read_DMA33_Y_MODIFY() bfin_read32(DMA33_Y_MODIFY) +#define bfin_write_DMA33_Y_MODIFY(val) bfin_write32(DMA33_Y_MODIFY, val) +#define bfin_read_DMA33_CURR_DESC_PTR() bfin_read32(DMA33_CURR_DESC_PTR) +#define bfin_write_DMA33_CURR_DESC_PTR(val) bfin_write32(DMA33_CURR_DESC_PTR, val) +#define bfin_read_DMA33_PREV_DESC_PTR() bfin_read32(DMA33_PREV_DESC_PTR) +#define bfin_write_DMA33_PREV_DESC_PTR(val) bfin_write32(DMA33_PREV_DESC_PTR, val) +#define bfin_read_DMA33_CURR_ADDR() bfin_read32(DMA33_CURR_ADDR) +#define bfin_write_DMA33_CURR_ADDR(val) bfin_write32(DMA33_CURR_ADDR, val) +#define bfin_read_DMA33_IRQ_STATUS() bfin_read32(DMA33_IRQ_STATUS) +#define bfin_write_DMA33_IRQ_STATUS(val) bfin_write32(DMA33_IRQ_STATUS, val) +#define bfin_read_DMA33_CURR_X_COUNT() bfin_read32(DMA33_CURR_X_COUNT) +#define bfin_write_DMA33_CURR_X_COUNT(val) bfin_write32(DMA33_CURR_X_COUNT, val) +#define bfin_read_DMA33_CURR_Y_COUNT() bfin_read32(DMA33_CURR_Y_COUNT) +#define bfin_write_DMA33_CURR_Y_COUNT(val) bfin_write32(DMA33_CURR_Y_COUNT, val) +#define bfin_read_DMA33_BWL_COUNT() bfin_read32(DMA33_BWL_COUNT) +#define bfin_write_DMA33_BWL_COUNT(val) bfin_write32(DMA33_BWL_COUNT, val) +#define bfin_read_DMA33_CURR_BWL_COUNT() bfin_read32(DMA33_CURR_BWL_COUNT) +#define bfin_write_DMA33_CURR_BWL_COUNT(val) bfin_write32(DMA33_CURR_BWL_COUNT, val) +#define bfin_read_DMA33_BWM_COUNT() bfin_read32(DMA33_BWM_COUNT) +#define bfin_write_DMA33_BWM_COUNT(val) bfin_write32(DMA33_BWM_COUNT, val) +#define bfin_read_DMA33_CURR_BWM_COUNT() bfin_read32(DMA33_CURR_BWM_COUNT) +#define bfin_write_DMA33_CURR_BWM_COUNT(val) bfin_write32(DMA33_CURR_BWM_COUNT, val) + +/* DMA Channel 34 Registers */ + +#define bfin_read_DMA34_NEXT_DESC_PTR() bfin_read32(DMA34_NEXT_DESC_PTR) +#define bfin_write_DMA34_NEXT_DESC_PTR(val) bfin_write32(DMA34_NEXT_DESC_PTR, val) +#define bfin_read_DMA34_START_ADDR() bfin_read32(DMA34_START_ADDR) +#define bfin_write_DMA34_START_ADDR(val) bfin_write32(DMA34_START_ADDR, val) +#define bfin_read_DMA34_CONFIG() bfin_read32(DMA34_CONFIG) +#define bfin_write_DMA34_CONFIG(val) bfin_write32(DMA34_CONFIG, val) +#define bfin_read_DMA34_X_COUNT() bfin_read32(DMA34_X_COUNT) +#define bfin_write_DMA34_X_COUNT(val) bfin_write32(DMA34_X_COUNT, val) +#define bfin_read_DMA34_X_MODIFY() bfin_read32(DMA34_X_MODIFY) +#define bfin_write_DMA34_X_MODIFY(val) bfin_write32(DMA34_X_MODIFY, val) +#define bfin_read_DMA34_Y_COUNT() bfin_read32(DMA34_Y_COUNT) +#define bfin_write_DMA34_Y_COUNT(val) bfin_write32(DMA34_Y_COUNT, val) +#define bfin_read_DMA34_Y_MODIFY() bfin_read32(DMA34_Y_MODIFY) +#define bfin_write_DMA34_Y_MODIFY(val) bfin_write32(DMA34_Y_MODIFY, val) +#define bfin_read_DMA34_CURR_DESC_PTR() bfin_read32(DMA34_CURR_DESC_PTR) +#define bfin_write_DMA34_CURR_DESC_PTR(val) bfin_write32(DMA34_CURR_DESC_PTR, val) +#define bfin_read_DMA34_PREV_DESC_PTR() bfin_read32(DMA34_PREV_DESC_PTR) +#define bfin_write_DMA34_PREV_DESC_PTR(val) bfin_write32(DMA34_PREV_DESC_PTR, val) +#define bfin_read_DMA34_CURR_ADDR() bfin_read32(DMA34_CURR_ADDR) +#define bfin_write_DMA34_CURR_ADDR(val) bfin_write32(DMA34_CURR_ADDR, val) +#define bfin_read_DMA34_IRQ_STATUS() bfin_read32(DMA34_IRQ_STATUS) +#define bfin_write_DMA34_IRQ_STATUS(val) bfin_write32(DMA34_IRQ_STATUS, val) +#define bfin_read_DMA34_CURR_X_COUNT() bfin_read32(DMA34_CURR_X_COUNT) +#define bfin_write_DMA34_CURR_X_COUNT(val) bfin_write32(DMA34_CURR_X_COUNT, val) +#define bfin_read_DMA34_CURR_Y_COUNT() bfin_read32(DMA34_CURR_Y_COUNT) +#define bfin_write_DMA34_CURR_Y_COUNT(val) bfin_write32(DMA34_CURR_Y_COUNT, val) +#define bfin_read_DMA34_BWL_COUNT() bfin_read32(DMA34_BWL_COUNT) +#define bfin_write_DMA34_BWL_COUNT(val) bfin_write32(DMA34_BWL_COUNT, val) +#define bfin_read_DMA34_CURR_BWL_COUNT() bfin_read32(DMA34_CURR_BWL_COUNT) +#define bfin_write_DMA34_CURR_BWL_COUNT(val) bfin_write32(DMA34_CURR_BWL_COUNT, val) +#define bfin_read_DMA34_BWM_COUNT() bfin_read32(DMA34_BWM_COUNT) +#define bfin_write_DMA34_BWM_COUNT(val) bfin_write32(DMA34_BWM_COUNT, val) +#define bfin_read_DMA34_CURR_BWM_COUNT() bfin_read32(DMA34_CURR_BWM_COUNT) +#define bfin_write_DMA34_CURR_BWM_COUNT(val) bfin_write32(DMA34_CURR_BWM_COUNT, val) + +/* DMA Channel 35 Registers */ + +#define bfin_read_DMA35_NEXT_DESC_PTR() bfin_read32(DMA35_NEXT_DESC_PTR) +#define bfin_write_DMA35_NEXT_DESC_PTR(val) bfin_write32(DMA35_NEXT_DESC_PTR, val) +#define bfin_read_DMA35_START_ADDR() bfin_read32(DMA35_START_ADDR) +#define bfin_write_DMA35_START_ADDR(val) bfin_write32(DMA35_START_ADDR, val) +#define bfin_read_DMA35_CONFIG() bfin_read32(DMA35_CONFIG) +#define bfin_write_DMA35_CONFIG(val) bfin_write32(DMA35_CONFIG, val) +#define bfin_read_DMA35_X_COUNT() bfin_read32(DMA35_X_COUNT) +#define bfin_write_DMA35_X_COUNT(val) bfin_write32(DMA35_X_COUNT, val) +#define bfin_read_DMA35_X_MODIFY() bfin_read32(DMA35_X_MODIFY) +#define bfin_write_DMA35_X_MODIFY(val) bfin_write32(DMA35_X_MODIFY, val) +#define bfin_read_DMA35_Y_COUNT() bfin_read32(DMA35_Y_COUNT) +#define bfin_write_DMA35_Y_COUNT(val) bfin_write32(DMA35_Y_COUNT, val) +#define bfin_read_DMA35_Y_MODIFY() bfin_read32(DMA35_Y_MODIFY) +#define bfin_write_DMA35_Y_MODIFY(val) bfin_write32(DMA35_Y_MODIFY, val) +#define bfin_read_DMA35_CURR_DESC_PTR() bfin_read32(DMA35_CURR_DESC_PTR) +#define bfin_write_DMA35_CURR_DESC_PTR(val) bfin_write32(DMA35_CURR_DESC_PTR, val) +#define bfin_read_DMA35_PREV_DESC_PTR() bfin_read32(DMA35_PREV_DESC_PTR) +#define bfin_write_DMA35_PREV_DESC_PTR(val) bfin_write32(DMA35_PREV_DESC_PTR, val) +#define bfin_read_DMA35_CURR_ADDR() bfin_read32(DMA35_CURR_ADDR) +#define bfin_write_DMA35_CURR_ADDR(val) bfin_write32(DMA35_CURR_ADDR, val) +#define bfin_read_DMA35_IRQ_STATUS() bfin_read32(DMA35_IRQ_STATUS) +#define bfin_write_DMA35_IRQ_STATUS(val) bfin_write32(DMA35_IRQ_STATUS, val) +#define bfin_read_DMA35_CURR_X_COUNT() bfin_read32(DMA35_CURR_X_COUNT) +#define bfin_write_DMA35_CURR_X_COUNT(val) bfin_write32(DMA35_CURR_X_COUNT, val) +#define bfin_read_DMA35_CURR_Y_COUNT() bfin_read32(DMA35_CURR_Y_COUNT) +#define bfin_write_DMA35_CURR_Y_COUNT(val) bfin_write32(DMA35_CURR_Y_COUNT, val) +#define bfin_read_DMA35_BWL_COUNT() bfin_read32(DMA35_BWL_COUNT) +#define bfin_write_DMA35_BWL_COUNT(val) bfin_write32(DMA35_BWL_COUNT, val) +#define bfin_read_DMA35_CURR_BWL_COUNT() bfin_read32(DMA35_CURR_BWL_COUNT) +#define bfin_write_DMA35_CURR_BWL_COUNT(val) bfin_write32(DMA35_CURR_BWL_COUNT, val) +#define bfin_read_DMA35_BWM_COUNT() bfin_read32(DMA35_BWM_COUNT) +#define bfin_write_DMA35_BWM_COUNT(val) bfin_write32(DMA35_BWM_COUNT, val) +#define bfin_read_DMA35_CURR_BWM_COUNT() bfin_read32(DMA35_CURR_BWM_COUNT) +#define bfin_write_DMA35_CURR_BWM_COUNT(val) bfin_write32(DMA35_CURR_BWM_COUNT, val) + +/* DMA Channel 36 Registers */ + +#define bfin_read_DMA36_NEXT_DESC_PTR() bfin_read32(DMA36_NEXT_DESC_PTR) +#define bfin_write_DMA36_NEXT_DESC_PTR(val) bfin_write32(DMA36_NEXT_DESC_PTR, val) +#define bfin_read_DMA36_START_ADDR() bfin_read32(DMA36_START_ADDR) +#define bfin_write_DMA36_START_ADDR(val) bfin_write32(DMA36_START_ADDR, val) +#define bfin_read_DMA36_CONFIG() bfin_read32(DMA36_CONFIG) +#define bfin_write_DMA36_CONFIG(val) bfin_write32(DMA36_CONFIG, val) +#define bfin_read_DMA36_X_COUNT() bfin_read32(DMA36_X_COUNT) +#define bfin_write_DMA36_X_COUNT(val) bfin_write32(DMA36_X_COUNT, val) +#define bfin_read_DMA36_X_MODIFY() bfin_read32(DMA36_X_MODIFY) +#define bfin_write_DMA36_X_MODIFY(val) bfin_write32(DMA36_X_MODIFY, val) +#define bfin_read_DMA36_Y_COUNT() bfin_read32(DMA36_Y_COUNT) +#define bfin_write_DMA36_Y_COUNT(val) bfin_write32(DMA36_Y_COUNT, val) +#define bfin_read_DMA36_Y_MODIFY() bfin_read32(DMA36_Y_MODIFY) +#define bfin_write_DMA36_Y_MODIFY(val) bfin_write32(DMA36_Y_MODIFY, val) +#define bfin_read_DMA36_CURR_DESC_PTR() bfin_read32(DMA36_CURR_DESC_PTR) +#define bfin_write_DMA36_CURR_DESC_PTR(val) bfin_write32(DMA36_CURR_DESC_PTR, val) +#define bfin_read_DMA36_PREV_DESC_PTR() bfin_read32(DMA36_PREV_DESC_PTR) +#define bfin_write_DMA36_PREV_DESC_PTR(val) bfin_write32(DMA36_PREV_DESC_PTR, val) +#define bfin_read_DMA36_CURR_ADDR() bfin_read32(DMA36_CURR_ADDR) +#define bfin_write_DMA36_CURR_ADDR(val) bfin_write32(DMA36_CURR_ADDR, val) +#define bfin_read_DMA36_IRQ_STATUS() bfin_read32(DMA36_IRQ_STATUS) +#define bfin_write_DMA36_IRQ_STATUS(val) bfin_write32(DMA36_IRQ_STATUS, val) +#define bfin_read_DMA36_CURR_X_COUNT() bfin_read32(DMA36_CURR_X_COUNT) +#define bfin_write_DMA36_CURR_X_COUNT(val) bfin_write32(DMA36_CURR_X_COUNT, val) +#define bfin_read_DMA36_CURR_Y_COUNT() bfin_read32(DMA36_CURR_Y_COUNT) +#define bfin_write_DMA36_CURR_Y_COUNT(val) bfin_write32(DMA36_CURR_Y_COUNT, val) +#define bfin_read_DMA36_BWL_COUNT() bfin_read32(DMA36_BWL_COUNT) +#define bfin_write_DMA36_BWL_COUNT(val) bfin_write32(DMA36_BWL_COUNT, val) +#define bfin_read_DMA36_CURR_BWL_COUNT() bfin_read32(DMA36_CURR_BWL_COUNT) +#define bfin_write_DMA36_CURR_BWL_COUNT(val) bfin_write32(DMA36_CURR_BWL_COUNT, val) +#define bfin_read_DMA36_BWM_COUNT() bfin_read32(DMA36_BWM_COUNT) +#define bfin_write_DMA36_BWM_COUNT(val) bfin_write32(DMA36_BWM_COUNT, val) +#define bfin_read_DMA36_CURR_BWM_COUNT() bfin_read32(DMA36_CURR_BWM_COUNT) +#define bfin_write_DMA36_CURR_BWM_COUNT(val) bfin_write32(DMA36_CURR_BWM_COUNT, val) + +/* DMA Channel 37 Registers */ + +#define bfin_read_DMA37_NEXT_DESC_PTR() bfin_read32(DMA37_NEXT_DESC_PTR) +#define bfin_write_DMA37_NEXT_DESC_PTR(val) bfin_write32(DMA37_NEXT_DESC_PTR, val) +#define bfin_read_DMA37_START_ADDR() bfin_read32(DMA37_START_ADDR) +#define bfin_write_DMA37_START_ADDR(val) bfin_write32(DMA37_START_ADDR, val) +#define bfin_read_DMA37_CONFIG() bfin_read32(DMA37_CONFIG) +#define bfin_write_DMA37_CONFIG(val) bfin_write32(DMA37_CONFIG, val) +#define bfin_read_DMA37_X_COUNT() bfin_read32(DMA37_X_COUNT) +#define bfin_write_DMA37_X_COUNT(val) bfin_write32(DMA37_X_COUNT, val) +#define bfin_read_DMA37_X_MODIFY() bfin_read32(DMA37_X_MODIFY) +#define bfin_write_DMA37_X_MODIFY(val) bfin_write32(DMA37_X_MODIFY, val) +#define bfin_read_DMA37_Y_COUNT() bfin_read32(DMA37_Y_COUNT) +#define bfin_write_DMA37_Y_COUNT(val) bfin_write32(DMA37_Y_COUNT, val) +#define bfin_read_DMA37_Y_MODIFY() bfin_read32(DMA37_Y_MODIFY) +#define bfin_write_DMA37_Y_MODIFY(val) bfin_write32(DMA37_Y_MODIFY, val) +#define bfin_read_DMA37_CURR_DESC_PTR() bfin_read32(DMA37_CURR_DESC_PTR) +#define bfin_write_DMA37_CURR_DESC_PTR(val) bfin_write32(DMA37_CURR_DESC_PTR, val) +#define bfin_read_DMA37_PREV_DESC_PTR() bfin_read32(DMA37_PREV_DESC_PTR) +#define bfin_write_DMA37_PREV_DESC_PTR(val) bfin_write32(DMA37_PREV_DESC_PTR, val) +#define bfin_read_DMA37_CURR_ADDR() bfin_read32(DMA37_CURR_ADDR) +#define bfin_write_DMA37_CURR_ADDR(val) bfin_write32(DMA37_CURR_ADDR, val) +#define bfin_read_DMA37_IRQ_STATUS() bfin_read32(DMA37_IRQ_STATUS) +#define bfin_write_DMA37_IRQ_STATUS(val) bfin_write32(DMA37_IRQ_STATUS, val) +#define bfin_read_DMA37_CURR_X_COUNT() bfin_read32(DMA37_CURR_X_COUNT) +#define bfin_write_DMA37_CURR_X_COUNT(val) bfin_write32(DMA37_CURR_X_COUNT, val) +#define bfin_read_DMA37_CURR_Y_COUNT() bfin_read32(DMA37_CURR_Y_COUNT) +#define bfin_write_DMA37_CURR_Y_COUNT(val) bfin_write32(DMA37_CURR_Y_COUNT, val) +#define bfin_read_DMA37_BWL_COUNT() bfin_read32(DMA37_BWL_COUNT) +#define bfin_write_DMA37_BWL_COUNT(val) bfin_write32(DMA37_BWL_COUNT, val) +#define bfin_read_DMA37_CURR_BWL_COUNT() bfin_read32(DMA37_CURR_BWL_COUNT) +#define bfin_write_DMA37_CURR_BWL_COUNT(val) bfin_write32(DMA37_CURR_BWL_COUNT, val) +#define bfin_read_DMA37_BWM_COUNT() bfin_read32(DMA37_BWM_COUNT) +#define bfin_write_DMA37_BWM_COUNT(val) bfin_write32(DMA37_BWM_COUNT, val) +#define bfin_read_DMA37_CURR_BWM_COUNT() bfin_read32(DMA37_CURR_BWM_COUNT) +#define bfin_write_DMA37_CURR_BWM_COUNT(val) bfin_write32(DMA37_CURR_BWM_COUNT, val) + +/* DMA Channel 38 Registers */ + +#define bfin_read_DMA38_NEXT_DESC_PTR() bfin_read32(DMA38_NEXT_DESC_PTR) +#define bfin_write_DMA38_NEXT_DESC_PTR(val) bfin_write32(DMA38_NEXT_DESC_PTR, val) +#define bfin_read_DMA38_START_ADDR() bfin_read32(DMA38_START_ADDR) +#define bfin_write_DMA38_START_ADDR(val) bfin_write32(DMA38_START_ADDR, val) +#define bfin_read_DMA38_CONFIG() bfin_read32(DMA38_CONFIG) +#define bfin_write_DMA38_CONFIG(val) bfin_write32(DMA38_CONFIG, val) +#define bfin_read_DMA38_X_COUNT() bfin_read32(DMA38_X_COUNT) +#define bfin_write_DMA38_X_COUNT(val) bfin_write32(DMA38_X_COUNT, val) +#define bfin_read_DMA38_X_MODIFY() bfin_read32(DMA38_X_MODIFY) +#define bfin_write_DMA38_X_MODIFY(val) bfin_write32(DMA38_X_MODIFY, val) +#define bfin_read_DMA38_Y_COUNT() bfin_read32(DMA38_Y_COUNT) +#define bfin_write_DMA38_Y_COUNT(val) bfin_write32(DMA38_Y_COUNT, val) +#define bfin_read_DMA38_Y_MODIFY() bfin_read32(DMA38_Y_MODIFY) +#define bfin_write_DMA38_Y_MODIFY(val) bfin_write32(DMA38_Y_MODIFY, val) +#define bfin_read_DMA38_CURR_DESC_PTR() bfin_read32(DMA38_CURR_DESC_PTR) +#define bfin_write_DMA38_CURR_DESC_PTR(val) bfin_write32(DMA38_CURR_DESC_PTR, val) +#define bfin_read_DMA38_PREV_DESC_PTR() bfin_read32(DMA38_PREV_DESC_PTR) +#define bfin_write_DMA38_PREV_DESC_PTR(val) bfin_write32(DMA38_PREV_DESC_PTR, val) +#define bfin_read_DMA38_CURR_ADDR() bfin_read32(DMA38_CURR_ADDR) +#define bfin_write_DMA38_CURR_ADDR(val) bfin_write32(DMA38_CURR_ADDR, val) +#define bfin_read_DMA38_IRQ_STATUS() bfin_read32(DMA38_IRQ_STATUS) +#define bfin_write_DMA38_IRQ_STATUS(val) bfin_write32(DMA38_IRQ_STATUS, val) +#define bfin_read_DMA38_CURR_X_COUNT() bfin_read32(DMA38_CURR_X_COUNT) +#define bfin_write_DMA38_CURR_X_COUNT(val) bfin_write32(DMA38_CURR_X_COUNT, val) +#define bfin_read_DMA38_CURR_Y_COUNT() bfin_read32(DMA38_CURR_Y_COUNT) +#define bfin_write_DMA38_CURR_Y_COUNT(val) bfin_write32(DMA38_CURR_Y_COUNT, val) +#define bfin_read_DMA38_BWL_COUNT() bfin_read32(DMA38_BWL_COUNT) +#define bfin_write_DMA38_BWL_COUNT(val) bfin_write32(DMA38_BWL_COUNT, val) +#define bfin_read_DMA38_CURR_BWL_COUNT() bfin_read32(DMA38_CURR_BWL_COUNT) +#define bfin_write_DMA38_CURR_BWL_COUNT(val) bfin_write32(DMA38_CURR_BWL_COUNT, val) +#define bfin_read_DMA38_BWM_COUNT() bfin_read32(DMA38_BWM_COUNT) +#define bfin_write_DMA38_BWM_COUNT(val) bfin_write32(DMA38_BWM_COUNT, val) +#define bfin_read_DMA38_CURR_BWM_COUNT() bfin_read32(DMA38_CURR_BWM_COUNT) +#define bfin_write_DMA38_CURR_BWM_COUNT(val) bfin_write32(DMA38_CURR_BWM_COUNT, val) + +/* DMA Channel 39 Registers */ + +#define bfin_read_DMA39_NEXT_DESC_PTR() bfin_read32(DMA39_NEXT_DESC_PTR) +#define bfin_write_DMA39_NEXT_DESC_PTR(val) bfin_write32(DMA39_NEXT_DESC_PTR, val) +#define bfin_read_DMA39_START_ADDR() bfin_read32(DMA39_START_ADDR) +#define bfin_write_DMA39_START_ADDR(val) bfin_write32(DMA39_START_ADDR, val) +#define bfin_read_DMA39_CONFIG() bfin_read32(DMA39_CONFIG) +#define bfin_write_DMA39_CONFIG(val) bfin_write32(DMA39_CONFIG, val) +#define bfin_read_DMA39_X_COUNT() bfin_read32(DMA39_X_COUNT) +#define bfin_write_DMA39_X_COUNT(val) bfin_write32(DMA39_X_COUNT, val) +#define bfin_read_DMA39_X_MODIFY() bfin_read32(DMA39_X_MODIFY) +#define bfin_write_DMA39_X_MODIFY(val) bfin_write32(DMA39_X_MODIFY, val) +#define bfin_read_DMA39_Y_COUNT() bfin_read32(DMA39_Y_COUNT) +#define bfin_write_DMA39_Y_COUNT(val) bfin_write32(DMA39_Y_COUNT, val) +#define bfin_read_DMA39_Y_MODIFY() bfin_read32(DMA39_Y_MODIFY) +#define bfin_write_DMA39_Y_MODIFY(val) bfin_write32(DMA39_Y_MODIFY, val) +#define bfin_read_DMA39_CURR_DESC_PTR() bfin_read32(DMA39_CURR_DESC_PTR) +#define bfin_write_DMA39_CURR_DESC_PTR(val) bfin_write32(DMA39_CURR_DESC_PTR, val) +#define bfin_read_DMA39_PREV_DESC_PTR() bfin_read32(DMA39_PREV_DESC_PTR) +#define bfin_write_DMA39_PREV_DESC_PTR(val) bfin_write32(DMA39_PREV_DESC_PTR, val) +#define bfin_read_DMA39_CURR_ADDR() bfin_read32(DMA39_CURR_ADDR) +#define bfin_write_DMA39_CURR_ADDR(val) bfin_write32(DMA39_CURR_ADDR, val) +#define bfin_read_DMA39_IRQ_STATUS() bfin_read32(DMA39_IRQ_STATUS) +#define bfin_write_DMA39_IRQ_STATUS(val) bfin_write32(DMA39_IRQ_STATUS, val) +#define bfin_read_DMA39_CURR_X_COUNT() bfin_read32(DMA39_CURR_X_COUNT) +#define bfin_write_DMA39_CURR_X_COUNT(val) bfin_write32(DMA39_CURR_X_COUNT, val) +#define bfin_read_DMA39_CURR_Y_COUNT() bfin_read32(DMA39_CURR_Y_COUNT) +#define bfin_write_DMA39_CURR_Y_COUNT(val) bfin_write32(DMA39_CURR_Y_COUNT, val) +#define bfin_read_DMA39_BWL_COUNT() bfin_read32(DMA39_BWL_COUNT) +#define bfin_write_DMA39_BWL_COUNT(val) bfin_write32(DMA39_BWL_COUNT, val) +#define bfin_read_DMA39_CURR_BWL_COUNT() bfin_read32(DMA39_CURR_BWL_COUNT) +#define bfin_write_DMA39_CURR_BWL_COUNT(val) bfin_write32(DMA39_CURR_BWL_COUNT, val) +#define bfin_read_DMA39_BWM_COUNT() bfin_read32(DMA39_BWM_COUNT) +#define bfin_write_DMA39_BWM_COUNT(val) bfin_write32(DMA39_BWM_COUNT, val) +#define bfin_read_DMA39_CURR_BWM_COUNT() bfin_read32(DMA39_CURR_BWM_COUNT) +#define bfin_write_DMA39_CURR_BWM_COUNT(val) bfin_write32(DMA39_CURR_BWM_COUNT, val) + +/* DMA Channel 40 Registers */ + +#define bfin_read_DMA40_NEXT_DESC_PTR() bfin_read32(DMA40_NEXT_DESC_PTR) +#define bfin_write_DMA40_NEXT_DESC_PTR(val) bfin_write32(DMA40_NEXT_DESC_PTR, val) +#define bfin_read_DMA40_START_ADDR() bfin_read32(DMA40_START_ADDR) +#define bfin_write_DMA40_START_ADDR(val) bfin_write32(DMA40_START_ADDR, val) +#define bfin_read_DMA40_CONFIG() bfin_read32(DMA40_CONFIG) +#define bfin_write_DMA40_CONFIG(val) bfin_write32(DMA40_CONFIG, val) +#define bfin_read_DMA40_X_COUNT() bfin_read32(DMA40_X_COUNT) +#define bfin_write_DMA40_X_COUNT(val) bfin_write32(DMA40_X_COUNT, val) +#define bfin_read_DMA40_X_MODIFY() bfin_read32(DMA40_X_MODIFY) +#define bfin_write_DMA40_X_MODIFY(val) bfin_write32(DMA40_X_MODIFY, val) +#define bfin_read_DMA40_Y_COUNT() bfin_read32(DMA40_Y_COUNT) +#define bfin_write_DMA40_Y_COUNT(val) bfin_write32(DMA40_Y_COUNT, val) +#define bfin_read_DMA40_Y_MODIFY() bfin_read32(DMA40_Y_MODIFY) +#define bfin_write_DMA40_Y_MODIFY(val) bfin_write32(DMA40_Y_MODIFY, val) +#define bfin_read_DMA40_CURR_DESC_PTR() bfin_read32(DMA40_CURR_DESC_PTR) +#define bfin_write_DMA40_CURR_DESC_PTR(val) bfin_write32(DMA40_CURR_DESC_PTR, val) +#define bfin_read_DMA40_PREV_DESC_PTR() bfin_read32(DMA40_PREV_DESC_PTR) +#define bfin_write_DMA40_PREV_DESC_PTR(val) bfin_write32(DMA40_PREV_DESC_PTR, val) +#define bfin_read_DMA40_CURR_ADDR() bfin_read32(DMA40_CURR_ADDR) +#define bfin_write_DMA40_CURR_ADDR(val) bfin_write32(DMA40_CURR_ADDR, val) +#define bfin_read_DMA40_IRQ_STATUS() bfin_read32(DMA40_IRQ_STATUS) +#define bfin_write_DMA40_IRQ_STATUS(val) bfin_write32(DMA40_IRQ_STATUS, val) +#define bfin_read_DMA40_CURR_X_COUNT() bfin_read32(DMA40_CURR_X_COUNT) +#define bfin_write_DMA40_CURR_X_COUNT(val) bfin_write32(DMA40_CURR_X_COUNT, val) +#define bfin_read_DMA40_CURR_Y_COUNT() bfin_read32(DMA40_CURR_Y_COUNT) +#define bfin_write_DMA40_CURR_Y_COUNT(val) bfin_write32(DMA40_CURR_Y_COUNT, val) +#define bfin_read_DMA40_BWL_COUNT() bfin_read32(DMA40_BWL_COUNT) +#define bfin_write_DMA40_BWL_COUNT(val) bfin_write32(DMA40_BWL_COUNT, val) +#define bfin_read_DMA40_CURR_BWL_COUNT() bfin_read32(DMA40_CURR_BWL_COUNT) +#define bfin_write_DMA40_CURR_BWL_COUNT(val) bfin_write32(DMA40_CURR_BWL_COUNT, val) +#define bfin_read_DMA40_BWM_COUNT() bfin_read32(DMA40_BWM_COUNT) +#define bfin_write_DMA40_BWM_COUNT(val) bfin_write32(DMA40_BWM_COUNT, val) +#define bfin_read_DMA40_CURR_BWM_COUNT() bfin_read32(DMA40_CURR_BWM_COUNT) +#define bfin_write_DMA40_CURR_BWM_COUNT(val) bfin_write32(DMA40_CURR_BWM_COUNT, val) + +/* DMA Channel 41 Registers */ + +#define bfin_read_DMA41_NEXT_DESC_PTR() bfin_read32(DMA41_NEXT_DESC_PTR) +#define bfin_write_DMA41_NEXT_DESC_PTR(val) bfin_write32(DMA41_NEXT_DESC_PTR, val) +#define bfin_read_DMA41_START_ADDR() bfin_read32(DMA41_START_ADDR) +#define bfin_write_DMA41_START_ADDR(val) bfin_write32(DMA41_START_ADDR, val) +#define bfin_read_DMA41_CONFIG() bfin_read32(DMA41_CONFIG) +#define bfin_write_DMA41_CONFIG(val) bfin_write32(DMA41_CONFIG, val) +#define bfin_read_DMA41_X_COUNT() bfin_read32(DMA41_X_COUNT) +#define bfin_write_DMA41_X_COUNT(val) bfin_write32(DMA41_X_COUNT, val) +#define bfin_read_DMA41_X_MODIFY() bfin_read32(DMA41_X_MODIFY) +#define bfin_write_DMA41_X_MODIFY(val) bfin_write32(DMA41_X_MODIFY, val) +#define bfin_read_DMA41_Y_COUNT() bfin_read32(DMA41_Y_COUNT) +#define bfin_write_DMA41_Y_COUNT(val) bfin_write32(DMA41_Y_COUNT, val) +#define bfin_read_DMA41_Y_MODIFY() bfin_read32(DMA41_Y_MODIFY) +#define bfin_write_DMA41_Y_MODIFY(val) bfin_write32(DMA41_Y_MODIFY, val) +#define bfin_read_DMA41_CURR_DESC_PTR() bfin_read32(DMA41_CURR_DESC_PTR) +#define bfin_write_DMA41_CURR_DESC_PTR(val) bfin_write32(DMA41_CURR_DESC_PTR, val) +#define bfin_read_DMA41_PREV_DESC_PTR() bfin_read32(DMA41_PREV_DESC_PTR) +#define bfin_write_DMA41_PREV_DESC_PTR(val) bfin_write32(DMA41_PREV_DESC_PTR, val) +#define bfin_read_DMA41_CURR_ADDR() bfin_read32(DMA41_CURR_ADDR) +#define bfin_write_DMA41_CURR_ADDR(val) bfin_write32(DMA41_CURR_ADDR, val) +#define bfin_read_DMA41_IRQ_STATUS() bfin_read32(DMA41_IRQ_STATUS) +#define bfin_write_DMA41_IRQ_STATUS(val) bfin_write32(DMA41_IRQ_STATUS, val) +#define bfin_read_DMA41_CURR_X_COUNT() bfin_read32(DMA41_CURR_X_COUNT) +#define bfin_write_DMA41_CURR_X_COUNT(val) bfin_write32(DMA41_CURR_X_COUNT, val) +#define bfin_read_DMA41_CURR_Y_COUNT() bfin_read32(DMA41_CURR_Y_COUNT) +#define bfin_write_DMA41_CURR_Y_COUNT(val) bfin_write32(DMA41_CURR_Y_COUNT, val) +#define bfin_read_DMA41_BWL_COUNT() bfin_read32(DMA41_BWL_COUNT) +#define bfin_write_DMA41_BWL_COUNT(val) bfin_write32(DMA41_BWL_COUNT, val) +#define bfin_read_DMA41_CURR_BWL_COUNT() bfin_read32(DMA41_CURR_BWL_COUNT) +#define bfin_write_DMA41_CURR_BWL_COUNT(val) bfin_write32(DMA41_CURR_BWL_COUNT, val) +#define bfin_read_DMA41_BWM_COUNT() bfin_read32(DMA41_BWM_COUNT) +#define bfin_write_DMA41_BWM_COUNT(val) bfin_write32(DMA41_BWM_COUNT, val) +#define bfin_read_DMA41_CURR_BWM_COUNT() bfin_read32(DMA41_CURR_BWM_COUNT) +#define bfin_write_DMA41_CURR_BWM_COUNT(val) bfin_write32(DMA41_CURR_BWM_COUNT, val) + +/* DMA Channel 42 Registers */ + +#define bfin_read_DMA42_NEXT_DESC_PTR() bfin_read32(DMA42_NEXT_DESC_PTR) +#define bfin_write_DMA42_NEXT_DESC_PTR(val) bfin_write32(DMA42_NEXT_DESC_PTR, val) +#define bfin_read_DMA42_START_ADDR() bfin_read32(DMA42_START_ADDR) +#define bfin_write_DMA42_START_ADDR(val) bfin_write32(DMA42_START_ADDR, val) +#define bfin_read_DMA42_CONFIG() bfin_read32(DMA42_CONFIG) +#define bfin_write_DMA42_CONFIG(val) bfin_write32(DMA42_CONFIG, val) +#define bfin_read_DMA42_X_COUNT() bfin_read32(DMA42_X_COUNT) +#define bfin_write_DMA42_X_COUNT(val) bfin_write32(DMA42_X_COUNT, val) +#define bfin_read_DMA42_X_MODIFY() bfin_read32(DMA42_X_MODIFY) +#define bfin_write_DMA42_X_MODIFY(val) bfin_write32(DMA42_X_MODIFY, val) +#define bfin_read_DMA42_Y_COUNT() bfin_read32(DMA42_Y_COUNT) +#define bfin_write_DMA42_Y_COUNT(val) bfin_write32(DMA42_Y_COUNT, val) +#define bfin_read_DMA42_Y_MODIFY() bfin_read32(DMA42_Y_MODIFY) +#define bfin_write_DMA42_Y_MODIFY(val) bfin_write32(DMA42_Y_MODIFY, val) +#define bfin_read_DMA42_CURR_DESC_PTR() bfin_read32(DMA42_CURR_DESC_PTR) +#define bfin_write_DMA42_CURR_DESC_PTR(val) bfin_write32(DMA42_CURR_DESC_PTR, val) +#define bfin_read_DMA42_PREV_DESC_PTR() bfin_read32(DMA42_PREV_DESC_PTR) +#define bfin_write_DMA42_PREV_DESC_PTR(val) bfin_write32(DMA42_PREV_DESC_PTR, val) +#define bfin_read_DMA42_CURR_ADDR() bfin_read32(DMA42_CURR_ADDR) +#define bfin_write_DMA42_CURR_ADDR(val) bfin_write32(DMA42_CURR_ADDR, val) +#define bfin_read_DMA42_IRQ_STATUS() bfin_read32(DMA42_IRQ_STATUS) +#define bfin_write_DMA42_IRQ_STATUS(val) bfin_write32(DMA42_IRQ_STATUS, val) +#define bfin_read_DMA42_CURR_X_COUNT() bfin_read32(DMA42_CURR_X_COUNT) +#define bfin_write_DMA42_CURR_X_COUNT(val) bfin_write32(DMA42_CURR_X_COUNT, val) +#define bfin_read_DMA42_CURR_Y_COUNT() bfin_read32(DMA42_CURR_Y_COUNT) +#define bfin_write_DMA42_CURR_Y_COUNT(val) bfin_write32(DMA42_CURR_Y_COUNT, val) +#define bfin_read_DMA42_BWL_COUNT() bfin_read32(DMA42_BWL_COUNT) +#define bfin_write_DMA42_BWL_COUNT(val) bfin_write32(DMA42_BWL_COUNT, val) +#define bfin_read_DMA42_CURR_BWL_COUNT() bfin_read32(DMA42_CURR_BWL_COUNT) +#define bfin_write_DMA42_CURR_BWL_COUNT(val) bfin_write32(DMA42_CURR_BWL_COUNT, val) +#define bfin_read_DMA42_BWM_COUNT() bfin_read32(DMA42_BWM_COUNT) +#define bfin_write_DMA42_BWM_COUNT(val) bfin_write32(DMA42_BWM_COUNT, val) +#define bfin_read_DMA42_CURR_BWM_COUNT() bfin_read32(DMA42_CURR_BWM_COUNT) +#define bfin_write_DMA42_CURR_BWM_COUNT(val) bfin_write32(DMA42_CURR_BWM_COUNT, val) + +/* DMA Channel 43 Registers */ + +#define bfin_read_DMA43_NEXT_DESC_PTR() bfin_read32(DMA43_NEXT_DESC_PTR) +#define bfin_write_DMA43_NEXT_DESC_PTR(val) bfin_write32(DMA43_NEXT_DESC_PTR, val) +#define bfin_read_DMA43_START_ADDR() bfin_read32(DMA43_START_ADDR) +#define bfin_write_DMA43_START_ADDR(val) bfin_write32(DMA43_START_ADDR, val) +#define bfin_read_DMA43_CONFIG() bfin_read32(DMA43_CONFIG) +#define bfin_write_DMA43_CONFIG(val) bfin_write32(DMA43_CONFIG, val) +#define bfin_read_DMA43_X_COUNT() bfin_read32(DMA43_X_COUNT) +#define bfin_write_DMA43_X_COUNT(val) bfin_write32(DMA43_X_COUNT, val) +#define bfin_read_DMA43_X_MODIFY() bfin_read32(DMA43_X_MODIFY) +#define bfin_write_DMA43_X_MODIFY(val) bfin_write32(DMA43_X_MODIFY, val) +#define bfin_read_DMA43_Y_COUNT() bfin_read32(DMA43_Y_COUNT) +#define bfin_write_DMA43_Y_COUNT(val) bfin_write32(DMA43_Y_COUNT, val) +#define bfin_read_DMA43_Y_MODIFY() bfin_read32(DMA43_Y_MODIFY) +#define bfin_write_DMA43_Y_MODIFY(val) bfin_write32(DMA43_Y_MODIFY, val) +#define bfin_read_DMA43_CURR_DESC_PTR() bfin_read32(DMA43_CURR_DESC_PTR) +#define bfin_write_DMA43_CURR_DESC_PTR(val) bfin_write32(DMA43_CURR_DESC_PTR, val) +#define bfin_read_DMA43_PREV_DESC_PTR() bfin_read32(DMA43_PREV_DESC_PTR) +#define bfin_write_DMA43_PREV_DESC_PTR(val) bfin_write32(DMA43_PREV_DESC_PTR, val) +#define bfin_read_DMA43_CURR_ADDR() bfin_read32(DMA43_CURR_ADDR) +#define bfin_write_DMA43_CURR_ADDR(val) bfin_write32(DMA43_CURR_ADDR, val) +#define bfin_read_DMA43_IRQ_STATUS() bfin_read32(DMA43_IRQ_STATUS) +#define bfin_write_DMA43_IRQ_STATUS(val) bfin_write32(DMA43_IRQ_STATUS, val) +#define bfin_read_DMA43_CURR_X_COUNT() bfin_read32(DMA43_CURR_X_COUNT) +#define bfin_write_DMA43_CURR_X_COUNT(val) bfin_write32(DMA43_CURR_X_COUNT, val) +#define bfin_read_DMA43_CURR_Y_COUNT() bfin_read32(DMA43_CURR_Y_COUNT) +#define bfin_write_DMA43_CURR_Y_COUNT(val) bfin_write32(DMA43_CURR_Y_COUNT, val) +#define bfin_read_DMA43_BWL_COUNT() bfin_read32(DMA43_BWL_COUNT) +#define bfin_write_DMA43_BWL_COUNT(val) bfin_write32(DMA43_BWL_COUNT, val) +#define bfin_read_DMA43_CURR_BWL_COUNT() bfin_read32(DMA43_CURR_BWL_COUNT) +#define bfin_write_DMA43_CURR_BWL_COUNT(val) bfin_write32(DMA43_CURR_BWL_COUNT, val) +#define bfin_read_DMA43_BWM_COUNT() bfin_read32(DMA43_BWM_COUNT) +#define bfin_write_DMA43_BWM_COUNT(val) bfin_write32(DMA43_BWM_COUNT, val) +#define bfin_read_DMA43_CURR_BWM_COUNT() bfin_read32(DMA43_CURR_BWM_COUNT) +#define bfin_write_DMA43_CURR_BWM_COUNT(val) bfin_write32(DMA43_CURR_BWM_COUNT, val) + +/* DMA Channel 44 Registers */ + +#define bfin_read_DMA44_NEXT_DESC_PTR() bfin_read32(DMA44_NEXT_DESC_PTR) +#define bfin_write_DMA44_NEXT_DESC_PTR(val) bfin_write32(DMA44_NEXT_DESC_PTR, val) +#define bfin_read_DMA44_START_ADDR() bfin_read32(DMA44_START_ADDR) +#define bfin_write_DMA44_START_ADDR(val) bfin_write32(DMA44_START_ADDR, val) +#define bfin_read_DMA44_CONFIG() bfin_read32(DMA44_CONFIG) +#define bfin_write_DMA44_CONFIG(val) bfin_write32(DMA44_CONFIG, val) +#define bfin_read_DMA44_X_COUNT() bfin_read32(DMA44_X_COUNT) +#define bfin_write_DMA44_X_COUNT(val) bfin_write32(DMA44_X_COUNT, val) +#define bfin_read_DMA44_X_MODIFY() bfin_read32(DMA44_X_MODIFY) +#define bfin_write_DMA44_X_MODIFY(val) bfin_write32(DMA44_X_MODIFY, val) +#define bfin_read_DMA44_Y_COUNT() bfin_read32(DMA44_Y_COUNT) +#define bfin_write_DMA44_Y_COUNT(val) bfin_write32(DMA44_Y_COUNT, val) +#define bfin_read_DMA44_Y_MODIFY() bfin_read32(DMA44_Y_MODIFY) +#define bfin_write_DMA44_Y_MODIFY(val) bfin_write32(DMA44_Y_MODIFY, val) +#define bfin_read_DMA44_CURR_DESC_PTR() bfin_read32(DMA44_CURR_DESC_PTR) +#define bfin_write_DMA44_CURR_DESC_PTR(val) bfin_write32(DMA44_CURR_DESC_PTR, val) +#define bfin_read_DMA44_PREV_DESC_PTR() bfin_read32(DMA44_PREV_DESC_PTR) +#define bfin_write_DMA44_PREV_DESC_PTR(val) bfin_write32(DMA44_PREV_DESC_PTR, val) +#define bfin_read_DMA44_CURR_ADDR() bfin_read32(DMA44_CURR_ADDR) +#define bfin_write_DMA44_CURR_ADDR(val) bfin_write32(DMA44_CURR_ADDR, val) +#define bfin_read_DMA44_IRQ_STATUS() bfin_read32(DMA44_IRQ_STATUS) +#define bfin_write_DMA44_IRQ_STATUS(val) bfin_write32(DMA44_IRQ_STATUS, val) +#define bfin_read_DMA44_CURR_X_COUNT() bfin_read32(DMA44_CURR_X_COUNT) +#define bfin_write_DMA44_CURR_X_COUNT(val) bfin_write32(DMA44_CURR_X_COUNT, val) +#define bfin_read_DMA44_CURR_Y_COUNT() bfin_read32(DMA44_CURR_Y_COUNT) +#define bfin_write_DMA44_CURR_Y_COUNT(val) bfin_write32(DMA44_CURR_Y_COUNT, val) +#define bfin_read_DMA44_BWL_COUNT() bfin_read32(DMA44_BWL_COUNT) +#define bfin_write_DMA44_BWL_COUNT(val) bfin_write32(DMA44_BWL_COUNT, val) +#define bfin_read_DMA44_CURR_BWL_COUNT() bfin_read32(DMA44_CURR_BWL_COUNT) +#define bfin_write_DMA44_CURR_BWL_COUNT(val) bfin_write32(DMA44_CURR_BWL_COUNT, val) +#define bfin_read_DMA44_BWM_COUNT() bfin_read32(DMA44_BWM_COUNT) +#define bfin_write_DMA44_BWM_COUNT(val) bfin_write32(DMA44_BWM_COUNT, val) +#define bfin_read_DMA44_CURR_BWM_COUNT() bfin_read32(DMA44_CURR_BWM_COUNT) +#define bfin_write_DMA44_CURR_BWM_COUNT(val) bfin_write32(DMA44_CURR_BWM_COUNT, val) + +/* DMA Channel 45 Registers */ + +#define bfin_read_DMA45_NEXT_DESC_PTR() bfin_read32(DMA45_NEXT_DESC_PTR) +#define bfin_write_DMA45_NEXT_DESC_PTR(val) bfin_write32(DMA45_NEXT_DESC_PTR, val) +#define bfin_read_DMA45_START_ADDR() bfin_read32(DMA45_START_ADDR) +#define bfin_write_DMA45_START_ADDR(val) bfin_write32(DMA45_START_ADDR, val) +#define bfin_read_DMA45_CONFIG() bfin_read32(DMA45_CONFIG) +#define bfin_write_DMA45_CONFIG(val) bfin_write32(DMA45_CONFIG, val) +#define bfin_read_DMA45_X_COUNT() bfin_read32(DMA45_X_COUNT) +#define bfin_write_DMA45_X_COUNT(val) bfin_write32(DMA45_X_COUNT, val) +#define bfin_read_DMA45_X_MODIFY() bfin_read32(DMA45_X_MODIFY) +#define bfin_write_DMA45_X_MODIFY(val) bfin_write32(DMA45_X_MODIFY, val) +#define bfin_read_DMA45_Y_COUNT() bfin_read32(DMA45_Y_COUNT) +#define bfin_write_DMA45_Y_COUNT(val) bfin_write32(DMA45_Y_COUNT, val) +#define bfin_read_DMA45_Y_MODIFY() bfin_read32(DMA45_Y_MODIFY) +#define bfin_write_DMA45_Y_MODIFY(val) bfin_write32(DMA45_Y_MODIFY, val) +#define bfin_read_DMA45_CURR_DESC_PTR() bfin_read32(DMA45_CURR_DESC_PTR) +#define bfin_write_DMA45_CURR_DESC_PTR(val) bfin_write32(DMA45_CURR_DESC_PTR, val) +#define bfin_read_DMA45_PREV_DESC_PTR() bfin_read32(DMA45_PREV_DESC_PTR) +#define bfin_write_DMA45_PREV_DESC_PTR(val) bfin_write32(DMA45_PREV_DESC_PTR, val) +#define bfin_read_DMA45_CURR_ADDR() bfin_read32(DMA45_CURR_ADDR) +#define bfin_write_DMA45_CURR_ADDR(val) bfin_write32(DMA45_CURR_ADDR, val) +#define bfin_read_DMA45_IRQ_STATUS() bfin_read32(DMA45_IRQ_STATUS) +#define bfin_write_DMA45_IRQ_STATUS(val) bfin_write32(DMA45_IRQ_STATUS, val) +#define bfin_read_DMA45_CURR_X_COUNT() bfin_read32(DMA45_CURR_X_COUNT) +#define bfin_write_DMA45_CURR_X_COUNT(val) bfin_write32(DMA45_CURR_X_COUNT, val) +#define bfin_read_DMA45_CURR_Y_COUNT() bfin_read32(DMA45_CURR_Y_COUNT) +#define bfin_write_DMA45_CURR_Y_COUNT(val) bfin_write32(DMA45_CURR_Y_COUNT, val) +#define bfin_read_DMA45_BWL_COUNT() bfin_read32(DMA45_BWL_COUNT) +#define bfin_write_DMA45_BWL_COUNT(val) bfin_write32(DMA45_BWL_COUNT, val) +#define bfin_read_DMA45_CURR_BWL_COUNT() bfin_read32(DMA45_CURR_BWL_COUNT) +#define bfin_write_DMA45_CURR_BWL_COUNT(val) bfin_write32(DMA45_CURR_BWL_COUNT, val) +#define bfin_read_DMA45_BWM_COUNT() bfin_read32(DMA45_BWM_COUNT) +#define bfin_write_DMA45_BWM_COUNT(val) bfin_write32(DMA45_BWM_COUNT, val) +#define bfin_read_DMA45_CURR_BWM_COUNT() bfin_read32(DMA45_CURR_BWM_COUNT) +#define bfin_write_DMA45_CURR_BWM_COUNT(val) bfin_write32(DMA45_CURR_BWM_COUNT, val) + +/* DMA Channel 46 Registers */ + +#define bfin_read_DMA46_NEXT_DESC_PTR() bfin_read32(DMA46_NEXT_DESC_PTR) +#define bfin_write_DMA46_NEXT_DESC_PTR(val) bfin_write32(DMA46_NEXT_DESC_PTR, val) +#define bfin_read_DMA46_START_ADDR() bfin_read32(DMA46_START_ADDR) +#define bfin_write_DMA46_START_ADDR(val) bfin_write32(DMA46_START_ADDR, val) +#define bfin_read_DMA46_CONFIG() bfin_read32(DMA46_CONFIG) +#define bfin_write_DMA46_CONFIG(val) bfin_write32(DMA46_CONFIG, val) +#define bfin_read_DMA46_X_COUNT() bfin_read32(DMA46_X_COUNT) +#define bfin_write_DMA46_X_COUNT(val) bfin_write32(DMA46_X_COUNT, val) +#define bfin_read_DMA46_X_MODIFY() bfin_read32(DMA46_X_MODIFY) +#define bfin_write_DMA46_X_MODIFY(val) bfin_write32(DMA46_X_MODIFY, val) +#define bfin_read_DMA46_Y_COUNT() bfin_read32(DMA46_Y_COUNT) +#define bfin_write_DMA46_Y_COUNT(val) bfin_write32(DMA46_Y_COUNT, val) +#define bfin_read_DMA46_Y_MODIFY() bfin_read32(DMA46_Y_MODIFY) +#define bfin_write_DMA46_Y_MODIFY(val) bfin_write32(DMA46_Y_MODIFY, val) +#define bfin_read_DMA46_CURR_DESC_PTR() bfin_read32(DMA46_CURR_DESC_PTR) +#define bfin_write_DMA46_CURR_DESC_PTR(val) bfin_write32(DMA46_CURR_DESC_PTR, val) +#define bfin_read_DMA46_PREV_DESC_PTR() bfin_read32(DMA46_PREV_DESC_PTR) +#define bfin_write_DMA46_PREV_DESC_PTR(val) bfin_write32(DMA46_PREV_DESC_PTR, val) +#define bfin_read_DMA46_CURR_ADDR() bfin_read32(DMA46_CURR_ADDR) +#define bfin_write_DMA46_CURR_ADDR(val) bfin_write32(DMA46_CURR_ADDR, val) +#define bfin_read_DMA46_IRQ_STATUS() bfin_read32(DMA46_IRQ_STATUS) +#define bfin_write_DMA46_IRQ_STATUS(val) bfin_write32(DMA46_IRQ_STATUS, val) +#define bfin_read_DMA46_CURR_X_COUNT() bfin_read32(DMA46_CURR_X_COUNT) +#define bfin_write_DMA46_CURR_X_COUNT(val) bfin_write32(DMA46_CURR_X_COUNT, val) +#define bfin_read_DMA46_CURR_Y_COUNT() bfin_read32(DMA46_CURR_Y_COUNT) +#define bfin_write_DMA46_CURR_Y_COUNT(val) bfin_write32(DMA46_CURR_Y_COUNT, val) +#define bfin_read_DMA46_BWL_COUNT() bfin_read32(DMA46_BWL_COUNT) +#define bfin_write_DMA46_BWL_COUNT(val) bfin_write32(DMA46_BWL_COUNT, val) +#define bfin_read_DMA46_CURR_BWL_COUNT() bfin_read32(DMA46_CURR_BWL_COUNT) +#define bfin_write_DMA46_CURR_BWL_COUNT(val) bfin_write32(DMA46_CURR_BWL_COUNT, val) +#define bfin_read_DMA46_BWM_COUNT() bfin_read32(DMA46_BWM_COUNT) +#define bfin_write_DMA46_BWM_COUNT(val) bfin_write32(DMA46_BWM_COUNT, val) +#define bfin_read_DMA46_CURR_BWM_COUNT() bfin_read32(DMA46_CURR_BWM_COUNT) +#define bfin_write_DMA46_CURR_BWM_COUNT(val) bfin_write32(DMA46_CURR_BWM_COUNT, val) + + +/* EPPI1 Registers */ + + +/* Port Interrubfin_read_()t 0 Registers (32-bit) */ + +#define bfin_read_PINT0_MASK_SET() bfin_read32(PINT0_MASK_SET) +#define bfin_write_PINT0_MASK_SET(val) bfin_write32(PINT0_MASK_SET, val) +#define bfin_read_PINT0_MASK_CLEAR() bfin_read32(PINT0_MASK_CLEAR) +#define bfin_write_PINT0_MASK_CLEAR(val) bfin_write32(PINT0_MASK_CLEAR, val) +#define bfin_read_PINT0_REQUEST() bfin_read32(PINT0_REQUEST) +#define bfin_write_PINT0_REQUEST(val) bfin_write32(PINT0_REQUEST, val) +#define bfin_read_PINT0_ASSIGN() bfin_read32(PINT0_ASSIGN) +#define bfin_write_PINT0_ASSIGN(val) bfin_write32(PINT0_ASSIGN, val) +#define bfin_read_PINT0_EDGE_SET() bfin_read32(PINT0_EDGE_SET) +#define bfin_write_PINT0_EDGE_SET(val) bfin_write32(PINT0_EDGE_SET, val) +#define bfin_read_PINT0_EDGE_CLEAR() bfin_read32(PINT0_EDGE_CLEAR) +#define bfin_write_PINT0_EDGE_CLEAR(val) bfin_write32(PINT0_EDGE_CLEAR, val) +#define bfin_read_PINT0_INVERT_SET() bfin_read32(PINT0_INVERT_SET) +#define bfin_write_PINT0_INVERT_SET(val) bfin_write32(PINT0_INVERT_SET, val) +#define bfin_read_PINT0_INVERT_CLEAR() bfin_read32(PINT0_INVERT_CLEAR) +#define bfin_write_PINT0_INVERT_CLEAR(val) bfin_write32(PINT0_INVERT_CLEAR, val) +#define bfin_read_PINT0_PINSTATE() bfin_read32(PINT0_PINSTATE) +#define bfin_write_PINT0_PINSTATE(val) bfin_write32(PINT0_PINSTATE, val) +#define bfin_read_PINT0_LATCH() bfin_read32(PINT0_LATCH) +#define bfin_write_PINT0_LATCH(val) bfin_write32(PINT0_LATCH, val) + +/* Port Interrubfin_read_()t 1 Registers (32-bit) */ + +#define bfin_read_PINT1_MASK_SET() bfin_read32(PINT1_MASK_SET) +#define bfin_write_PINT1_MASK_SET(val) bfin_write32(PINT1_MASK_SET, val) +#define bfin_read_PINT1_MASK_CLEAR() bfin_read32(PINT1_MASK_CLEAR) +#define bfin_write_PINT1_MASK_CLEAR(val) bfin_write32(PINT1_MASK_CLEAR, val) +#define bfin_read_PINT1_REQUEST() bfin_read32(PINT1_REQUEST) +#define bfin_write_PINT1_REQUEST(val) bfin_write32(PINT1_REQUEST, val) +#define bfin_read_PINT1_ASSIGN() bfin_read32(PINT1_ASSIGN) +#define bfin_write_PINT1_ASSIGN(val) bfin_write32(PINT1_ASSIGN, val) +#define bfin_read_PINT1_EDGE_SET() bfin_read32(PINT1_EDGE_SET) +#define bfin_write_PINT1_EDGE_SET(val) bfin_write32(PINT1_EDGE_SET, val) +#define bfin_read_PINT1_EDGE_CLEAR() bfin_read32(PINT1_EDGE_CLEAR) +#define bfin_write_PINT1_EDGE_CLEAR(val) bfin_write32(PINT1_EDGE_CLEAR, val) +#define bfin_read_PINT1_INVERT_SET() bfin_read32(PINT1_INVERT_SET) +#define bfin_write_PINT1_INVERT_SET(val) bfin_write32(PINT1_INVERT_SET, val) +#define bfin_read_PINT1_INVERT_CLEAR() bfin_read32(PINT1_INVERT_CLEAR) +#define bfin_write_PINT1_INVERT_CLEAR(val) bfin_write32(PINT1_INVERT_CLEAR, val) +#define bfin_read_PINT1_PINSTATE() bfin_read32(PINT1_PINSTATE) +#define bfin_write_PINT1_PINSTATE(val) bfin_write32(PINT1_PINSTATE, val) +#define bfin_read_PINT1_LATCH() bfin_read32(PINT1_LATCH) +#define bfin_write_PINT1_LATCH(val) bfin_write32(PINT1_LATCH, val) + +/* Port Interrubfin_read_()t 2 Registers (32-bit) */ + +#define bfin_read_PINT2_MASK_SET() bfin_read32(PINT2_MASK_SET) +#define bfin_write_PINT2_MASK_SET(val) bfin_write32(PINT2_MASK_SET, val) +#define bfin_read_PINT2_MASK_CLEAR() bfin_read32(PINT2_MASK_CLEAR) +#define bfin_write_PINT2_MASK_CLEAR(val) bfin_write32(PINT2_MASK_CLEAR, val) +#define bfin_read_PINT2_REQUEST() bfin_read32(PINT2_REQUEST) +#define bfin_write_PINT2_REQUEST(val) bfin_write32(PINT2_REQUEST, val) +#define bfin_read_PINT2_ASSIGN() bfin_read32(PINT2_ASSIGN) +#define bfin_write_PINT2_ASSIGN(val) bfin_write32(PINT2_ASSIGN, val) +#define bfin_read_PINT2_EDGE_SET() bfin_read32(PINT2_EDGE_SET) +#define bfin_write_PINT2_EDGE_SET(val) bfin_write32(PINT2_EDGE_SET, val) +#define bfin_read_PINT2_EDGE_CLEAR() bfin_read32(PINT2_EDGE_CLEAR) +#define bfin_write_PINT2_EDGE_CLEAR(val) bfin_write32(PINT2_EDGE_CLEAR, val) +#define bfin_read_PINT2_INVERT_SET() bfin_read32(PINT2_INVERT_SET) +#define bfin_write_PINT2_INVERT_SET(val) bfin_write32(PINT2_INVERT_SET, val) +#define bfin_read_PINT2_INVERT_CLEAR() bfin_read32(PINT2_INVERT_CLEAR) +#define bfin_write_PINT2_INVERT_CLEAR(val) bfin_write32(PINT2_INVERT_CLEAR, val) +#define bfin_read_PINT2_PINSTATE() bfin_read32(PINT2_PINSTATE) +#define bfin_write_PINT2_PINSTATE(val) bfin_write32(PINT2_PINSTATE, val) +#define bfin_read_PINT2_LATCH() bfin_read32(PINT2_LATCH) +#define bfin_write_PINT2_LATCH(val) bfin_write32(PINT2_LATCH, val) + +/* Port Interrubfin_read_()t 3 Registers (32-bit) */ + +#define bfin_read_PINT3_MASK_SET() bfin_read32(PINT3_MASK_SET) +#define bfin_write_PINT3_MASK_SET(val) bfin_write32(PINT3_MASK_SET, val) +#define bfin_read_PINT3_MASK_CLEAR() bfin_read32(PINT3_MASK_CLEAR) +#define bfin_write_PINT3_MASK_CLEAR(val) bfin_write32(PINT3_MASK_CLEAR, val) +#define bfin_read_PINT3_REQUEST() bfin_read32(PINT3_REQUEST) +#define bfin_write_PINT3_REQUEST(val) bfin_write32(PINT3_REQUEST, val) +#define bfin_read_PINT3_ASSIGN() bfin_read32(PINT3_ASSIGN) +#define bfin_write_PINT3_ASSIGN(val) bfin_write32(PINT3_ASSIGN, val) +#define bfin_read_PINT3_EDGE_SET() bfin_read32(PINT3_EDGE_SET) +#define bfin_write_PINT3_EDGE_SET(val) bfin_write32(PINT3_EDGE_SET, val) +#define bfin_read_PINT3_EDGE_CLEAR() bfin_read32(PINT3_EDGE_CLEAR) +#define bfin_write_PINT3_EDGE_CLEAR(val) bfin_write32(PINT3_EDGE_CLEAR, val) +#define bfin_read_PINT3_INVERT_SET() bfin_read32(PINT3_INVERT_SET) +#define bfin_write_PINT3_INVERT_SET(val) bfin_write32(PINT3_INVERT_SET, val) +#define bfin_read_PINT3_INVERT_CLEAR() bfin_read32(PINT3_INVERT_CLEAR) +#define bfin_write_PINT3_INVERT_CLEAR(val) bfin_write32(PINT3_INVERT_CLEAR, val) +#define bfin_read_PINT3_PINSTATE() bfin_read32(PINT3_PINSTATE) +#define bfin_write_PINT3_PINSTATE(val) bfin_write32(PINT3_PINSTATE, val) +#define bfin_read_PINT3_LATCH() bfin_read32(PINT3_LATCH) +#define bfin_write_PINT3_LATCH(val) bfin_write32(PINT3_LATCH, val) + +/* Port Interrubfin_read_()t 4 Registers (32-bit) */ + +#define bfin_read_PINT4_MASK_SET() bfin_read32(PINT4_MASK_SET) +#define bfin_write_PINT4_MASK_SET(val) bfin_write32(PINT4_MASK_SET, val) +#define bfin_read_PINT4_MASK_CLEAR() bfin_read32(PINT4_MASK_CLEAR) +#define bfin_write_PINT4_MASK_CLEAR(val) bfin_write32(PINT4_MASK_CLEAR, val) +#define bfin_read_PINT4_REQUEST() bfin_read32(PINT4_REQUEST) +#define bfin_write_PINT4_REQUEST(val) bfin_write32(PINT4_REQUEST, val) +#define bfin_read_PINT4_ASSIGN() bfin_read32(PINT4_ASSIGN) +#define bfin_write_PINT4_ASSIGN(val) bfin_write32(PINT4_ASSIGN, val) +#define bfin_read_PINT4_EDGE_SET() bfin_read32(PINT4_EDGE_SET) +#define bfin_write_PINT4_EDGE_SET(val) bfin_write32(PINT4_EDGE_SET, val) +#define bfin_read_PINT4_EDGE_CLEAR() bfin_read32(PINT4_EDGE_CLEAR) +#define bfin_write_PINT4_EDGE_CLEAR(val) bfin_write32(PINT4_EDGE_CLEAR, val) +#define bfin_read_PINT4_INVERT_SET() bfin_read32(PINT4_INVERT_SET) +#define bfin_write_PINT4_INVERT_SET(val) bfin_write32(PINT4_INVERT_SET, val) +#define bfin_read_PINT4_INVERT_CLEAR() bfin_read32(PINT4_INVERT_CLEAR) +#define bfin_write_PINT4_INVERT_CLEAR(val) bfin_write32(PINT4_INVERT_CLEAR, val) +#define bfin_read_PINT4_PINSTATE() bfin_read32(PINT4_PINSTATE) +#define bfin_write_PINT4_PINSTATE(val) bfin_write32(PINT4_PINSTATE, val) +#define bfin_read_PINT4_LATCH() bfin_read32(PINT4_LATCH) +#define bfin_write_PINT4_LATCH(val) bfin_write32(PINT4_LATCH, val) + +/* Port Interrubfin_read_()t 5 Registers (32-bit) */ + +#define bfin_read_PINT5_MASK_SET() bfin_read32(PINT5_MASK_SET) +#define bfin_write_PINT5_MASK_SET(val) bfin_write32(PINT5_MASK_SET, val) +#define bfin_read_PINT5_MASK_CLEAR() bfin_read32(PINT5_MASK_CLEAR) +#define bfin_write_PINT5_MASK_CLEAR(val) bfin_write32(PINT5_MASK_CLEAR, val) +#define bfin_read_PINT5_REQUEST() bfin_read32(PINT5_REQUEST) +#define bfin_write_PINT5_REQUEST(val) bfin_write32(PINT5_REQUEST, val) +#define bfin_read_PINT5_ASSIGN() bfin_read32(PINT5_ASSIGN) +#define bfin_write_PINT5_ASSIGN(val) bfin_write32(PINT5_ASSIGN, val) +#define bfin_read_PINT5_EDGE_SET() bfin_read32(PINT5_EDGE_SET) +#define bfin_write_PINT5_EDGE_SET(val) bfin_write32(PINT5_EDGE_SET, val) +#define bfin_read_PINT5_EDGE_CLEAR() bfin_read32(PINT5_EDGE_CLEAR) +#define bfin_write_PINT5_EDGE_CLEAR(val) bfin_write32(PINT5_EDGE_CLEAR, val) +#define bfin_read_PINT5_INVERT_SET() bfin_read32(PINT5_INVERT_SET) +#define bfin_write_PINT5_INVERT_SET(val) bfin_write32(PINT5_INVERT_SET, val) +#define bfin_read_PINT5_INVERT_CLEAR() bfin_read32(PINT5_INVERT_CLEAR) +#define bfin_write_PINT5_INVERT_CLEAR(val) bfin_write32(PINT5_INVERT_CLEAR, val) +#define bfin_read_PINT5_PINSTATE() bfin_read32(PINT5_PINSTATE) +#define bfin_write_PINT5_PINSTATE(val) bfin_write32(PINT5_PINSTATE, val) +#define bfin_read_PINT5_LATCH() bfin_read32(PINT5_LATCH) +#define bfin_write_PINT5_LATCH(val) bfin_write32(PINT5_LATCH, val) + +/* Port A Registers */ + +#define bfin_read_PORTA_FER() bfin_read32(PORTA_FER) +#define bfin_write_PORTA_FER(val) bfin_write32(PORTA_FER, val) +#define bfin_read_PORTA_FER_SET() bfin_read32(PORTA_FER_SET) +#define bfin_write_PORTA_FER_SET(val) bfin_write32(PORTA_FER_SET, val) +#define bfin_read_PORTA_FER_CLEAR() bfin_read32(PORTA_FER_CLEAR) +#define bfin_write_PORTA_FER_CLEAR(val) bfin_write32(PORTA_FER_CLEAR, val) +#define bfin_read_PORTA() bfin_read32(PORTA) +#define bfin_write_PORTA(val) bfin_write32(PORTA, val) +#define bfin_read_PORTA_SET() bfin_read32(PORTA_SET) +#define bfin_write_PORTA_SET(val) bfin_write32(PORTA_SET, val) +#define bfin_read_PORTA_CLEAR() bfin_read32(PORTA_CLEAR) +#define bfin_write_PORTA_CLEAR(val) bfin_write32(PORTA_CLEAR, val) +#define bfin_read_PORTA_DIR() bfin_read32(PORTA_DIR) +#define bfin_write_PORTA_DIR(val) bfin_write32(PORTA_DIR, val) +#define bfin_read_PORTA_DIR_SET() bfin_read32(PORTA_DIR_SET) +#define bfin_write_PORTA_DIR_SET(val) bfin_write32(PORTA_DIR_SET, val) +#define bfin_read_PORTA_DIR_CLEAR() bfin_read32(PORTA_DIR_CLEAR) +#define bfin_write_PORTA_DIR_CLEAR(val) bfin_write32(PORTA_DIR_CLEAR, val) +#define bfin_read_PORTA_INEN() bfin_read32(PORTA_INEN) +#define bfin_write_PORTA_INEN(val) bfin_write32(PORTA_INEN, val) +#define bfin_read_PORTA_INEN_SET() bfin_read32(PORTA_INEN_SET) +#define bfin_write_PORTA_INEN_SET(val) bfin_write32(PORTA_INEN_SET, val) +#define bfin_read_PORTA_INEN_CLEAR() bfin_read32(PORTA_INEN_CLEAR) +#define bfin_write_PORTA_INEN_CLEAR(val) bfin_write32(PORTA_INEN_CLEAR, val) +#define bfin_read_PORTA_MUX() bfin_read32(PORTA_MUX) +#define bfin_write_PORTA_MUX(val) bfin_write32(PORTA_MUX, val) +#define bfin_read_PORTA_DATA_TGL() bfin_read32(PORTA_DATA_TGL) +#define bfin_write_PORTA_DATA_TGL(val) bfin_write32(PORTA_DATA_TGL, val) +#define bfin_read_PORTA_POL() bfin_read32(PORTA_POL) +#define bfin_write_PORTA_POL(val) bfin_write32(PORTA_POL, val) +#define bfin_read_PORTA_POL_SET() bfin_read32(PORTA_POL_SET) +#define bfin_write_PORTA_POL_SET(val) bfin_write32(PORTA_POL_SET, val) +#define bfin_read_PORTA_POL_CLEAR() bfin_read32(PORTA_POL_CLEAR) +#define bfin_write_PORTA_POL_CLEAR(val) bfin_write32(PORTA_POL_CLEAR, val) +#define bfin_read_PORTA_LOCK() bfin_read32(PORTA_LOCK) +#define bfin_write_PORTA_LOCK(val) bfin_write32(PORTA_LOCK, val) +#define bfin_read_PORTA_REVID() bfin_read32(PORTA_REVID) +#define bfin_write_PORTA_REVID(val) bfin_write32(PORTA_REVID, val) + + + +/* Port B Registers */ +#define bfin_read_PORTB_FER() bfin_read32(PORTB_FER) +#define bfin_write_PORTB_FER(val) bfin_write32(PORTB_FER, val) +#define bfin_read_PORTB_FER_SET() bfin_read32(PORTB_FER_SET) +#define bfin_write_PORTB_FER_SET(val) bfin_write32(PORTB_FER_SET, val) +#define bfin_read_PORTB_FER_CLEAR() bfin_read32(PORTB_FER_CLEAR) +#define bfin_write_PORTB_FER_CLEAR(val) bfin_write32(PORTB_FER_CLEAR, val) +#define bfin_read_PORTB() bfin_read32(PORTB) +#define bfin_write_PORTB(val) bfin_write32(PORTB, val) +#define bfin_read_PORTB_SET() bfin_read32(PORTB_SET) +#define bfin_write_PORTB_SET(val) bfin_write32(PORTB_SET, val) +#define bfin_read_PORTB_CLEAR() bfin_read32(PORTB_CLEAR) +#define bfin_write_PORTB_CLEAR(val) bfin_write32(PORTB_CLEAR, val) +#define bfin_read_PORTB_DIR() bfin_read32(PORTB_DIR) +#define bfin_write_PORTB_DIR(val) bfin_write32(PORTB_DIR, val) +#define bfin_read_PORTB_DIR_SET() bfin_read32(PORTB_DIR_SET) +#define bfin_write_PORTB_DIR_SET(val) bfin_write32(PORTB_DIR_SET, val) +#define bfin_read_PORTB_DIR_CLEAR() bfin_read32(PORTB_DIR_CLEAR) +#define bfin_write_PORTB_DIR_CLEAR(val) bfin_write32(PORTB_DIR_CLEAR, val) +#define bfin_read_PORTB_INEN() bfin_read32(PORTB_INEN) +#define bfin_write_PORTB_INEN(val) bfin_write32(PORTB_INEN, val) +#define bfin_read_PORTB_INEN_SET() bfin_read32(PORTB_INEN_SET) +#define bfin_write_PORTB_INEN_SET(val) bfin_write32(PORTB_INEN_SET, val) +#define bfin_read_PORTB_INEN_CLEAR() bfin_read32(PORTB_INEN_CLEAR) +#define bfin_write_PORTB_INEN_CLEAR(val) bfin_write32(PORTB_INEN_CLEAR, val) +#define bfin_read_PORTB_MUX() bfin_read32(PORTB_MUX) +#define bfin_write_PORTB_MUX(val) bfin_write32(PORTB_MUX, val) +#define bfin_read_PORTB_DATA_TGL() bfin_read32(PORTB_DATA_TGL) +#define bfin_write_PORTB_DATA_TGL(val) bfin_write32(PORTB_DATA_TGL, val) +#define bfin_read_PORTB_POL() bfin_read32(PORTB_POL) +#define bfin_write_PORTB_POL(val) bfin_write32(PORTB_POL, val) +#define bfin_read_PORTB_POL_SET() bfin_read32(PORTB_POL_SET) +#define bfin_write_PORTB_POL_SET(val) bfin_write32(PORTB_POL_SET, val) +#define bfin_read_PORTB_POL_CLEAR() bfin_read32(PORTB_POL_CLEAR) +#define bfin_write_PORTB_POL_CLEAR(val) bfin_write32(PORTB_POL_CLEAR, val) +#define bfin_read_PORTB_LOCK() bfin_read32(PORTB_LOCK) +#define bfin_write_PORTB_LOCK(val) bfin_write32(PORTB_LOCK, val) +#define bfin_read_PORTB_REVID() bfin_read32(PORTB_REVID) +#define bfin_write_PORTB_REVID(val) bfin_write32(PORTB_REVID, val) + + +/* Port C Registers */ +#define bfin_read_PORTC_FER() bfin_read32(PORTC_FER) +#define bfin_write_PORTC_FER(val) bfin_write32(PORTC_FER, val) +#define bfin_read_PORTC_FER_SET() bfin_read32(PORTC_FER_SET) +#define bfin_write_PORTC_FER_SET(val) bfin_write32(PORTC_FER_SET, val) +#define bfin_read_PORTC_FER_CLEAR() bfin_read32(PORTC_FER_CLEAR) +#define bfin_write_PORTC_FER_CLEAR(val) bfin_write32(PORTC_FER_CLEAR, val) +#define bfin_read_PORTC() bfin_read32(PORTC) +#define bfin_write_PORTC(val) bfin_write32(PORTC, val) +#define bfin_read_PORTC_SET() bfin_read32(PORTC_SET) +#define bfin_write_PORTC_SET(val) bfin_write32(PORTC_SET, val) +#define bfin_read_PORTC_CLEAR() bfin_read32(PORTC_CLEAR) +#define bfin_write_PORTC_CLEAR(val) bfin_write32(PORTC_CLEAR, val) +#define bfin_read_PORTC_DIR() bfin_read32(PORTC_DIR) +#define bfin_write_PORTC_DIR(val) bfin_write32(PORTC_DIR, val) +#define bfin_read_PORTC_DIR_SET() bfin_read32(PORTC_DIR_SET) +#define bfin_write_PORTC_DIR_SET(val) bfin_write32(PORTC_DIR_SET, val) +#define bfin_read_PORTC_DIR_CLEAR() bfin_read32(PORTC_DIR_CLEAR) +#define bfin_write_PORTC_DIR_CLEAR(val) bfin_write32(PORTC_DIR_CLEAR, val) +#define bfin_read_PORTC_INEN() bfin_read32(PORTC_INEN) +#define bfin_write_PORTC_INEN(val) bfin_write32(PORTC_INEN, val) +#define bfin_read_PORTC_INEN_SET() bfin_read32(PORTC_INEN_SET) +#define bfin_write_PORTC_INEN_SET(val) bfin_write32(PORTC_INEN_SET, val) +#define bfin_read_PORTC_INEN_CLEAR() bfin_read32(PORTC_INEN_CLEAR) +#define bfin_write_PORTC_INEN_CLEAR(val) bfin_write32(PORTC_INEN_CLEAR, val) +#define bfin_read_PORTC_MUX() bfin_read32(PORTC_MUX) +#define bfin_write_PORTC_MUX(val) bfin_write32(PORTC_MUX, val) +#define bfin_read_PORTC_DATA_TGL() bfin_read32(PORTC_DATA_TGL) +#define bfin_write_PORTC_DATA_TGL(val) bfin_write32(PORTC_DATA_TGL, val) +#define bfin_read_PORTC_POL() bfin_read32(PORTC_POL) +#define bfin_write_PORTC_POL(val) bfin_write32(PORTC_POL, val) +#define bfin_read_PORTC_POL_SET() bfin_read32(PORTC_POL_SET) +#define bfin_write_PORTC_POL_SET(val) bfin_write32(PORTC_POL_SET, val) +#define bfin_read_PORTC_POL_CLEAR() bfin_read32(PORTC_POL_CLEAR) +#define bfin_write_PORTC_POL_CLEAR(val) bfin_write32(PORTC_POL_CLEAR, val) +#define bfin_read_PORTC_LOCK() bfin_read32(PORTC_LOCK) +#define bfin_write_PORTC_LOCK(val) bfin_write32(PORTC_LOCK, val) +#define bfin_read_PORTC_REVID() bfin_read32(PORTC_REVID) +#define bfin_write_PORTC_REVID(val) bfin_write32(PORTC_REVID, val) + + +/* Port D Registers */ +#define bfin_read_PORTD_FER() bfin_read32(PORTD_FER) +#define bfin_write_PORTD_FER(val) bfin_write32(PORTD_FER, val) +#define bfin_read_PORTD_FER_SET() bfin_read32(PORTD_FER_SET) +#define bfin_write_PORTD_FER_SET(val) bfin_write32(PORTD_FER_SET, val) +#define bfin_read_PORTD_FER_CLEAR() bfin_read32(PORTD_FER_CLEAR) +#define bfin_write_PORTD_FER_CLEAR(val) bfin_write32(PORTD_FER_CLEAR, val) +#define bfin_read_PORTD() bfin_read32(PORTD) +#define bfin_write_PORTD(val) bfin_write32(PORTD, val) +#define bfin_read_PORTD_SET() bfin_read32(PORTD_SET) +#define bfin_write_PORTD_SET(val) bfin_write32(PORTD_SET, val) +#define bfin_read_PORTD_CLEAR() bfin_read32(PORTD_CLEAR) +#define bfin_write_PORTD_CLEAR(val) bfin_write32(PORTD_CLEAR, val) +#define bfin_read_PORTD_DIR() bfin_read32(PORTD_DIR) +#define bfin_write_PORTD_DIR(val) bfin_write32(PORTD_DIR, val) +#define bfin_read_PORTD_DIR_SET() bfin_read32(PORTD_DIR_SET) +#define bfin_write_PORTD_DIR_SET(val) bfin_write32(PORTD_DIR_SET, val) +#define bfin_read_PORTD_DIR_CLEAR() bfin_read32(PORTD_DIR_CLEAR) +#define bfin_write_PORTD_DIR_CLEAR(val) bfin_write32(PORTD_DIR_CLEAR, val) +#define bfin_read_PORTD_INEN() bfin_read32(PORTD_INEN) +#define bfin_write_PORTD_INEN(val) bfin_write32(PORTD_INEN, val) +#define bfin_read_PORTD_INEN_SET() bfin_read32(PORTD_INEN_SET) +#define bfin_write_PORTD_INEN_SET(val) bfin_write32(PORTD_INEN_SET, val) +#define bfin_read_PORTD_INEN_CLEAR() bfin_read32(PORTD_INEN_CLEAR) +#define bfin_write_PORTD_INEN_CLEAR(val) bfin_write32(PORTD_INEN_CLEAR, val) +#define bfin_read_PORTD_MUX() bfin_read32(PORTD_MUX) +#define bfin_write_PORTD_MUX(val) bfin_write32(PORTD_MUX, val) +#define bfin_read_PORTD_DATA_TGL() bfin_read32(PORTD_DATA_TGL) +#define bfin_write_PORTD_DATA_TGL(val) bfin_write32(PORTD_DATA_TGL, val) +#define bfin_read_PORTD_POL() bfin_read32(PORTD_POL) +#define bfin_write_PORTD_POL(val) bfin_write32(PORTD_POL, val) +#define bfin_read_PORTD_POL_SET() bfin_read32(PORTD_POL_SET) +#define bfin_write_PORTD_POL_SET(val) bfin_write32(PORTD_POL_SET, val) +#define bfin_read_PORTD_POL_CLEAR() bfin_read32(PORTD_POL_CLEAR) +#define bfin_write_PORTD_POL_CLEAR(val) bfin_write32(PORTD_POL_CLEAR, val) +#define bfin_read_PORTD_LOCK() bfin_read32(PORTD_LOCK) +#define bfin_write_PORTD_LOCK(val) bfin_write32(PORTD_LOCK, val) +#define bfin_read_PORTD_REVID() bfin_read32(PORTD_REVID) +#define bfin_write_PORTD_REVID(val) bfin_write32(PORTD_REVID, val) + + +/* Port E Registers */ +#define bfin_read_PORTE_FER() bfin_read32(PORTE_FER) +#define bfin_write_PORTE_FER(val) bfin_write32(PORTE_FER, val) +#define bfin_read_PORTE_FER_SET() bfin_read32(PORTE_FER_SET) +#define bfin_write_PORTE_FER_SET(val) bfin_write32(PORTE_FER_SET, val) +#define bfin_read_PORTE_FER_CLEAR() bfin_read32(PORTE_FER_CLEAR) +#define bfin_write_PORTE_FER_CLEAR(val) bfin_write32(PORTE_FER_CLEAR, val) +#define bfin_read_PORTE() bfin_read32(PORTE) +#define bfin_write_PORTE(val) bfin_write32(PORTE, val) +#define bfin_read_PORTE_SET() bfin_read32(PORTE_SET) +#define bfin_write_PORTE_SET(val) bfin_write32(PORTE_SET, val) +#define bfin_read_PORTE_CLEAR() bfin_read32(PORTE_CLEAR) +#define bfin_write_PORTE_CLEAR(val) bfin_write32(PORTE_CLEAR, val) +#define bfin_read_PORTE_DIR() bfin_read32(PORTE_DIR) +#define bfin_write_PORTE_DIR(val) bfin_write32(PORTE_DIR, val) +#define bfin_read_PORTE_DIR_SET() bfin_read32(PORTE_DIR_SET) +#define bfin_write_PORTE_DIR_SET(val) bfin_write32(PORTE_DIR_SET, val) +#define bfin_read_PORTE_DIR_CLEAR() bfin_read32(PORTE_DIR_CLEAR) +#define bfin_write_PORTE_DIR_CLEAR(val) bfin_write32(PORTE_DIR_CLEAR, val) +#define bfin_read_PORTE_INEN() bfin_read32(PORTE_INEN) +#define bfin_write_PORTE_INEN(val) bfin_write32(PORTE_INEN, val) +#define bfin_read_PORTE_INEN_SET() bfin_read32(PORTE_INEN_SET) +#define bfin_write_PORTE_INEN_SET(val) bfin_write32(PORTE_INEN_SET, val) +#define bfin_read_PORTE_INEN_CLEAR() bfin_read32(PORTE_INEN_CLEAR) +#define bfin_write_PORTE_INEN_CLEAR(val) bfin_write32(PORTE_INEN_CLEAR, val) +#define bfin_read_PORTE_MUX() bfin_read32(PORTE_MUX) +#define bfin_write_PORTE_MUX(val) bfin_write32(PORTE_MUX, val) +#define bfin_read_PORTE_DATA_TGL() bfin_read32(PORTE_DATA_TGL) +#define bfin_write_PORTE_DATA_TGL(val) bfin_write32(PORTE_DATA_TGL, val) +#define bfin_read_PORTE_POL() bfin_read32(PORTE_POL) +#define bfin_write_PORTE_POL(val) bfin_write32(PORTE_POL, val) +#define bfin_read_PORTE_POL_SET() bfin_read32(PORTE_POL_SET) +#define bfin_write_PORTE_POL_SET(val) bfin_write32(PORTE_POL_SET, val) +#define bfin_read_PORTE_POL_CLEAR() bfin_read32(PORTE_POL_CLEAR) +#define bfin_write_PORTE_POL_CLEAR(val) bfin_write32(PORTE_POL_CLEAR, val) +#define bfin_read_PORTE_LOCK() bfin_read32(PORTE_LOCK) +#define bfin_write_PORTE_LOCK(val) bfin_write32(PORTE_LOCK, val) +#define bfin_read_PORTE_REVID() bfin_read32(PORTE_REVID) +#define bfin_write_PORTE_REVID(val) bfin_write32(PORTE_REVID, val) + + +/* Port F Registers */ +#define bfin_read_PORTF_FER() bfin_read32(PORTF_FER) +#define bfin_write_PORTF_FER(val) bfin_write32(PORTF_FER, val) +#define bfin_read_PORTF_FER_SET() bfin_read32(PORTF_FER_SET) +#define bfin_write_PORTF_FER_SET(val) bfin_write32(PORTF_FER_SET, val) +#define bfin_read_PORTF_FER_CLEAR() bfin_read32(PORTF_FER_CLEAR) +#define bfin_write_PORTF_FER_CLEAR(val) bfin_write32(PORTF_FER_CLEAR, val) +#define bfin_read_PORTF() bfin_read32(PORTF) +#define bfin_write_PORTF(val) bfin_write32(PORTF, val) +#define bfin_read_PORTF_SET() bfin_read32(PORTF_SET) +#define bfin_write_PORTF_SET(val) bfin_write32(PORTF_SET, val) +#define bfin_read_PORTF_CLEAR() bfin_read32(PORTF_CLEAR) +#define bfin_write_PORTF_CLEAR(val) bfin_write32(PORTF_CLEAR, val) +#define bfin_read_PORTF_DIR() bfin_read32(PORTF_DIR) +#define bfin_write_PORTF_DIR(val) bfin_write32(PORTF_DIR, val) +#define bfin_read_PORTF_DIR_SET() bfin_read32(PORTF_DIR_SET) +#define bfin_write_PORTF_DIR_SET(val) bfin_write32(PORTF_DIR_SET, val) +#define bfin_read_PORTF_DIR_CLEAR() bfin_read32(PORTF_DIR_CLEAR) +#define bfin_write_PORTF_DIR_CLEAR(val) bfin_write32(PORTF_DIR_CLEAR, val) +#define bfin_read_PORTF_INEN() bfin_read32(PORTF_INEN) +#define bfin_write_PORTF_INEN(val) bfin_write32(PORTF_INEN, val) +#define bfin_read_PORTF_INEN_SET() bfin_read32(PORTF_INEN_SET) +#define bfin_write_PORTF_INEN_SET(val) bfin_write32(PORTF_INEN_SET, val) +#define bfin_read_PORTF_INEN_CLEAR() bfin_read32(PORTF_INEN_CLEAR) +#define bfin_write_PORTF_INEN_CLEAR(val) bfin_write32(PORTF_INEN_CLEAR, val) +#define bfin_read_PORTF_MUX() bfin_read32(PORTF_MUX) +#define bfin_write_PORTF_MUX(val) bfin_write32(PORTF_MUX, val) +#define bfin_read_PORTF_DATA_TGL() bfin_read32(PORTF_DATA_TGL) +#define bfin_write_PORTF_DATA_TGL(val) bfin_write32(PORTF_DATA_TGL, val) +#define bfin_read_PORTF_POL() bfin_read32(PORTF_POL) +#define bfin_write_PORTF_POL(val) bfin_write32(PORTF_POL, val) +#define bfin_read_PORTF_POL_SET() bfin_read32(PORTF_POL_SET) +#define bfin_write_PORTF_POL_SET(val) bfin_write32(PORTF_POL_SET, val) +#define bfin_read_PORTF_POL_CLEAR() bfin_read32(PORTF_POL_CLEAR) +#define bfin_write_PORTF_POL_CLEAR(val) bfin_write32(PORTF_POL_CLEAR, val) +#define bfin_read_PORTF_LOCK() bfin_read32(PORTF_LOCK) +#define bfin_write_PORTF_LOCK(val) bfin_write32(PORTF_LOCK, val) +#define bfin_read_PORTF_REVID() bfin_read32(PORTF_REVID) +#define bfin_write_PORTF_REVID(val) bfin_write32(PORTF_REVID, val) + + +/* Port G Registers */ +#define bfin_read_PORTG_FER() bfin_read32(PORTG_FER) +#define bfin_write_PORTG_FER(val) bfin_write32(PORTG_FER, val) +#define bfin_read_PORTG_FER_SET() bfin_read32(PORTG_FER_SET) +#define bfin_write_PORTG_FER_SET(val) bfin_write32(PORTG_FER_SET, val) +#define bfin_read_PORTG_FER_CLEAR() bfin_read32(PORTG_FER_CLEAR) +#define bfin_write_PORTG_FER_CLEAR(val) bfin_write32(PORTG_FER_CLEAR, val) +#define bfin_read_PORTG() bfin_read32(PORTG) +#define bfin_write_PORTG(val) bfin_write32(PORTG, val) +#define bfin_read_PORTG_SET() bfin_read32(PORTG_SET) +#define bfin_write_PORTG_SET(val) bfin_write32(PORTG_SET, val) +#define bfin_read_PORTG_CLEAR() bfin_read32(PORTG_CLEAR) +#define bfin_write_PORTG_CLEAR(val) bfin_write32(PORTG_CLEAR, val) +#define bfin_read_PORTG_DIR() bfin_read32(PORTG_DIR) +#define bfin_write_PORTG_DIR(val) bfin_write32(PORTG_DIR, val) +#define bfin_read_PORTG_DIR_SET() bfin_read32(PORTG_DIR_SET) +#define bfin_write_PORTG_DIR_SET(val) bfin_write32(PORTG_DIR_SET, val) +#define bfin_read_PORTG_DIR_CLEAR() bfin_read32(PORTG_DIR_CLEAR) +#define bfin_write_PORTG_DIR_CLEAR(val) bfin_write32(PORTG_DIR_CLEAR, val) +#define bfin_read_PORTG_INEN() bfin_read32(PORTG_INEN) +#define bfin_write_PORTG_INEN(val) bfin_write32(PORTG_INEN, val) +#define bfin_read_PORTG_INEN_SET() bfin_read32(PORTG_INEN_SET) +#define bfin_write_PORTG_INEN_SET(val) bfin_write32(PORTG_INEN_SET, val) +#define bfin_read_PORTG_INEN_CLEAR() bfin_read32(PORTG_INEN_CLEAR) +#define bfin_write_PORTG_INEN_CLEAR(val) bfin_write32(PORTG_INEN_CLEAR, val) +#define bfin_read_PORTG_MUX() bfin_read32(PORTG_MUX) +#define bfin_write_PORTG_MUX(val) bfin_write32(PORTG_MUX, val) +#define bfin_read_PORTG_DATA_TGL() bfin_read32(PORTG_DATA_TGL) +#define bfin_write_PORTG_DATA_TGL(val) bfin_write32(PORTG_DATA_TGL, val) +#define bfin_read_PORTG_POL() bfin_read32(PORTG_POL) +#define bfin_write_PORTG_POL(val) bfin_write32(PORTG_POL, val) +#define bfin_read_PORTG_POL_SET() bfin_read32(PORTG_POL_SET) +#define bfin_write_PORTG_POL_SET(val) bfin_write32(PORTG_POL_SET, val) +#define bfin_read_PORTG_POL_CLEAR() bfin_read32(PORTG_POL_CLEAR) +#define bfin_write_PORTG_POL_CLEAR(val) bfin_write32(PORTG_POL_CLEAR, val) +#define bfin_read_PORTG_LOCK() bfin_read32(PORTG_LOCK) +#define bfin_write_PORTG_LOCK(val) bfin_write32(PORTG_LOCK, val) +#define bfin_read_PORTG_REVID() bfin_read32(PORTG_REVID) +#define bfin_write_PORTG_REVID(val) bfin_write32(PORTG_REVID, val) + + + + +/* CAN Controller 0 Config 1 Registers */ + +#define bfin_read_CAN0_MC1() bfin_read16(CAN0_MC1) +#define bfin_write_CAN0_MC1(val) bfin_write16(CAN0_MC1, val) +#define bfin_read_CAN0_MD1() bfin_read16(CAN0_MD1) +#define bfin_write_CAN0_MD1(val) bfin_write16(CAN0_MD1, val) +#define bfin_read_CAN0_TRS1() bfin_read16(CAN0_TRS1) +#define bfin_write_CAN0_TRS1(val) bfin_write16(CAN0_TRS1, val) +#define bfin_read_CAN0_TRR1() bfin_read16(CAN0_TRR1) +#define bfin_write_CAN0_TRR1(val) bfin_write16(CAN0_TRR1, val) +#define bfin_read_CAN0_TA1() bfin_read16(CAN0_TA1) +#define bfin_write_CAN0_TA1(val) bfin_write16(CAN0_TA1, val) +#define bfin_read_CAN0_AA1() bfin_read16(CAN0_AA1) +#define bfin_write_CAN0_AA1(val) bfin_write16(CAN0_AA1, val) +#define bfin_read_CAN0_RMP1() bfin_read16(CAN0_RMP1) +#define bfin_write_CAN0_RMP1(val) bfin_write16(CAN0_RMP1, val) +#define bfin_read_CAN0_RML1() bfin_read16(CAN0_RML1) +#define bfin_write_CAN0_RML1(val) bfin_write16(CAN0_RML1, val) +#define bfin_read_CAN0_MBTIF1() bfin_read16(CAN0_MBTIF1) +#define bfin_write_CAN0_MBTIF1(val) bfin_write16(CAN0_MBTIF1, val) +#define bfin_read_CAN0_MBRIF1() bfin_read16(CAN0_MBRIF1) +#define bfin_write_CAN0_MBRIF1(val) bfin_write16(CAN0_MBRIF1, val) +#define bfin_read_CAN0_MBIM1() bfin_read16(CAN0_MBIM1) +#define bfin_write_CAN0_MBIM1(val) bfin_write16(CAN0_MBIM1, val) +#define bfin_read_CAN0_RFH1() bfin_read16(CAN0_RFH1) +#define bfin_write_CAN0_RFH1(val) bfin_write16(CAN0_RFH1, val) +#define bfin_read_CAN0_OPSS1() bfin_read16(CAN0_OPSS1) +#define bfin_write_CAN0_OPSS1(val) bfin_write16(CAN0_OPSS1, val) + +/* CAN Controller 0 Config 2 Registers */ + +#define bfin_read_CAN0_MC2() bfin_read16(CAN0_MC2) +#define bfin_write_CAN0_MC2(val) bfin_write16(CAN0_MC2, val) +#define bfin_read_CAN0_MD2() bfin_read16(CAN0_MD2) +#define bfin_write_CAN0_MD2(val) bfin_write16(CAN0_MD2, val) +#define bfin_read_CAN0_TRS2() bfin_read16(CAN0_TRS2) +#define bfin_write_CAN0_TRS2(val) bfin_write16(CAN0_TRS2, val) +#define bfin_read_CAN0_TRR2() bfin_read16(CAN0_TRR2) +#define bfin_write_CAN0_TRR2(val) bfin_write16(CAN0_TRR2, val) +#define bfin_read_CAN0_TA2() bfin_read16(CAN0_TA2) +#define bfin_write_CAN0_TA2(val) bfin_write16(CAN0_TA2, val) +#define bfin_read_CAN0_AA2() bfin_read16(CAN0_AA2) +#define bfin_write_CAN0_AA2(val) bfin_write16(CAN0_AA2, val) +#define bfin_read_CAN0_RMP2() bfin_read16(CAN0_RMP2) +#define bfin_write_CAN0_RMP2(val) bfin_write16(CAN0_RMP2, val) +#define bfin_read_CAN0_RML2() bfin_read16(CAN0_RML2) +#define bfin_write_CAN0_RML2(val) bfin_write16(CAN0_RML2, val) +#define bfin_read_CAN0_MBTIF2() bfin_read16(CAN0_MBTIF2) +#define bfin_write_CAN0_MBTIF2(val) bfin_write16(CAN0_MBTIF2, val) +#define bfin_read_CAN0_MBRIF2() bfin_read16(CAN0_MBRIF2) +#define bfin_write_CAN0_MBRIF2(val) bfin_write16(CAN0_MBRIF2, val) +#define bfin_read_CAN0_MBIM2() bfin_read16(CAN0_MBIM2) +#define bfin_write_CAN0_MBIM2(val) bfin_write16(CAN0_MBIM2, val) +#define bfin_read_CAN0_RFH2() bfin_read16(CAN0_RFH2) +#define bfin_write_CAN0_RFH2(val) bfin_write16(CAN0_RFH2, val) +#define bfin_read_CAN0_OPSS2() bfin_read16(CAN0_OPSS2) +#define bfin_write_CAN0_OPSS2(val) bfin_write16(CAN0_OPSS2, val) + +/* CAN Controller 0 Clock/Interrubfin_read_()t/Counter Registers */ + +#define bfin_read_CAN0_CLOCK() bfin_read16(CAN0_CLOCK) +#define bfin_write_CAN0_CLOCK(val) bfin_write16(CAN0_CLOCK, val) +#define bfin_read_CAN0_TIMING() bfin_read16(CAN0_TIMING) +#define bfin_write_CAN0_TIMING(val) bfin_write16(CAN0_TIMING, val) +#define bfin_read_CAN0_DEBUG() bfin_read16(CAN0_DEBUG) +#define bfin_write_CAN0_DEBUG(val) bfin_write16(CAN0_DEBUG, val) +#define bfin_read_CAN0_STATUS() bfin_read16(CAN0_STATUS) +#define bfin_write_CAN0_STATUS(val) bfin_write16(CAN0_STATUS, val) +#define bfin_read_CAN0_CEC() bfin_read16(CAN0_CEC) +#define bfin_write_CAN0_CEC(val) bfin_write16(CAN0_CEC, val) +#define bfin_read_CAN0_GIS() bfin_read16(CAN0_GIS) +#define bfin_write_CAN0_GIS(val) bfin_write16(CAN0_GIS, val) +#define bfin_read_CAN0_GIM() bfin_read16(CAN0_GIM) +#define bfin_write_CAN0_GIM(val) bfin_write16(CAN0_GIM, val) +#define bfin_read_CAN0_GIF() bfin_read16(CAN0_GIF) +#define bfin_write_CAN0_GIF(val) bfin_write16(CAN0_GIF, val) +#define bfin_read_CAN0_CONTROL() bfin_read16(CAN0_CONTROL) +#define bfin_write_CAN0_CONTROL(val) bfin_write16(CAN0_CONTROL, val) +#define bfin_read_CAN0_INTR() bfin_read16(CAN0_INTR) +#define bfin_write_CAN0_INTR(val) bfin_write16(CAN0_INTR, val) +#define bfin_read_CAN0_MBTD() bfin_read16(CAN0_MBTD) +#define bfin_write_CAN0_MBTD(val) bfin_write16(CAN0_MBTD, val) +#define bfin_read_CAN0_EWR() bfin_read16(CAN0_EWR) +#define bfin_write_CAN0_EWR(val) bfin_write16(CAN0_EWR, val) +#define bfin_read_CAN0_ESR() bfin_read16(CAN0_ESR) +#define bfin_write_CAN0_ESR(val) bfin_write16(CAN0_ESR, val) +#define bfin_read_CAN0_UCCNT() bfin_read16(CAN0_UCCNT) +#define bfin_write_CAN0_UCCNT(val) bfin_write16(CAN0_UCCNT, val) +#define bfin_read_CAN0_UCRC() bfin_read16(CAN0_UCRC) +#define bfin_write_CAN0_UCRC(val) bfin_write16(CAN0_UCRC, val) +#define bfin_read_CAN0_UCCNF() bfin_read16(CAN0_UCCNF) +#define bfin_write_CAN0_UCCNF(val) bfin_write16(CAN0_UCCNF, val) + +/* CAN Controller 0 Accebfin_read_()tance Registers */ + +#define bfin_read_CAN0_AM00L() bfin_read16(CAN0_AM00L) +#define bfin_write_CAN0_AM00L(val) bfin_write16(CAN0_AM00L, val) +#define bfin_read_CAN0_AM00H() bfin_read16(CAN0_AM00H) +#define bfin_write_CAN0_AM00H(val) bfin_write16(CAN0_AM00H, val) +#define bfin_read_CAN0_AM01L() bfin_read16(CAN0_AM01L) +#define bfin_write_CAN0_AM01L(val) bfin_write16(CAN0_AM01L, val) +#define bfin_read_CAN0_AM01H() bfin_read16(CAN0_AM01H) +#define bfin_write_CAN0_AM01H(val) bfin_write16(CAN0_AM01H, val) +#define bfin_read_CAN0_AM02L() bfin_read16(CAN0_AM02L) +#define bfin_write_CAN0_AM02L(val) bfin_write16(CAN0_AM02L, val) +#define bfin_read_CAN0_AM02H() bfin_read16(CAN0_AM02H) +#define bfin_write_CAN0_AM02H(val) bfin_write16(CAN0_AM02H, val) +#define bfin_read_CAN0_AM03L() bfin_read16(CAN0_AM03L) +#define bfin_write_CAN0_AM03L(val) bfin_write16(CAN0_AM03L, val) +#define bfin_read_CAN0_AM03H() bfin_read16(CAN0_AM03H) +#define bfin_write_CAN0_AM03H(val) bfin_write16(CAN0_AM03H, val) +#define bfin_read_CAN0_AM04L() bfin_read16(CAN0_AM04L) +#define bfin_write_CAN0_AM04L(val) bfin_write16(CAN0_AM04L, val) +#define bfin_read_CAN0_AM04H() bfin_read16(CAN0_AM04H) +#define bfin_write_CAN0_AM04H(val) bfin_write16(CAN0_AM04H, val) +#define bfin_read_CAN0_AM05L() bfin_read16(CAN0_AM05L) +#define bfin_write_CAN0_AM05L(val) bfin_write16(CAN0_AM05L, val) +#define bfin_read_CAN0_AM05H() bfin_read16(CAN0_AM05H) +#define bfin_write_CAN0_AM05H(val) bfin_write16(CAN0_AM05H, val) +#define bfin_read_CAN0_AM06L() bfin_read16(CAN0_AM06L) +#define bfin_write_CAN0_AM06L(val) bfin_write16(CAN0_AM06L, val) +#define bfin_read_CAN0_AM06H() bfin_read16(CAN0_AM06H) +#define bfin_write_CAN0_AM06H(val) bfin_write16(CAN0_AM06H, val) +#define bfin_read_CAN0_AM07L() bfin_read16(CAN0_AM07L) +#define bfin_write_CAN0_AM07L(val) bfin_write16(CAN0_AM07L, val) +#define bfin_read_CAN0_AM07H() bfin_read16(CAN0_AM07H) +#define bfin_write_CAN0_AM07H(val) bfin_write16(CAN0_AM07H, val) +#define bfin_read_CAN0_AM08L() bfin_read16(CAN0_AM08L) +#define bfin_write_CAN0_AM08L(val) bfin_write16(CAN0_AM08L, val) +#define bfin_read_CAN0_AM08H() bfin_read16(CAN0_AM08H) +#define bfin_write_CAN0_AM08H(val) bfin_write16(CAN0_AM08H, val) +#define bfin_read_CAN0_AM09L() bfin_read16(CAN0_AM09L) +#define bfin_write_CAN0_AM09L(val) bfin_write16(CAN0_AM09L, val) +#define bfin_read_CAN0_AM09H() bfin_read16(CAN0_AM09H) +#define bfin_write_CAN0_AM09H(val) bfin_write16(CAN0_AM09H, val) +#define bfin_read_CAN0_AM10L() bfin_read16(CAN0_AM10L) +#define bfin_write_CAN0_AM10L(val) bfin_write16(CAN0_AM10L, val) +#define bfin_read_CAN0_AM10H() bfin_read16(CAN0_AM10H) +#define bfin_write_CAN0_AM10H(val) bfin_write16(CAN0_AM10H, val) +#define bfin_read_CAN0_AM11L() bfin_read16(CAN0_AM11L) +#define bfin_write_CAN0_AM11L(val) bfin_write16(CAN0_AM11L, val) +#define bfin_read_CAN0_AM11H() bfin_read16(CAN0_AM11H) +#define bfin_write_CAN0_AM11H(val) bfin_write16(CAN0_AM11H, val) +#define bfin_read_CAN0_AM12L() bfin_read16(CAN0_AM12L) +#define bfin_write_CAN0_AM12L(val) bfin_write16(CAN0_AM12L, val) +#define bfin_read_CAN0_AM12H() bfin_read16(CAN0_AM12H) +#define bfin_write_CAN0_AM12H(val) bfin_write16(CAN0_AM12H, val) +#define bfin_read_CAN0_AM13L() bfin_read16(CAN0_AM13L) +#define bfin_write_CAN0_AM13L(val) bfin_write16(CAN0_AM13L, val) +#define bfin_read_CAN0_AM13H() bfin_read16(CAN0_AM13H) +#define bfin_write_CAN0_AM13H(val) bfin_write16(CAN0_AM13H, val) +#define bfin_read_CAN0_AM14L() bfin_read16(CAN0_AM14L) +#define bfin_write_CAN0_AM14L(val) bfin_write16(CAN0_AM14L, val) +#define bfin_read_CAN0_AM14H() bfin_read16(CAN0_AM14H) +#define bfin_write_CAN0_AM14H(val) bfin_write16(CAN0_AM14H, val) +#define bfin_read_CAN0_AM15L() bfin_read16(CAN0_AM15L) +#define bfin_write_CAN0_AM15L(val) bfin_write16(CAN0_AM15L, val) +#define bfin_read_CAN0_AM15H() bfin_read16(CAN0_AM15H) +#define bfin_write_CAN0_AM15H(val) bfin_write16(CAN0_AM15H, val) + +/* CAN Controller 0 Accebfin_read_()tance Registers */ + +#define bfin_read_CAN0_AM16L() bfin_read16(CAN0_AM16L) +#define bfin_write_CAN0_AM16L(val) bfin_write16(CAN0_AM16L, val) +#define bfin_read_CAN0_AM16H() bfin_read16(CAN0_AM16H) +#define bfin_write_CAN0_AM16H(val) bfin_write16(CAN0_AM16H, val) +#define bfin_read_CAN0_AM17L() bfin_read16(CAN0_AM17L) +#define bfin_write_CAN0_AM17L(val) bfin_write16(CAN0_AM17L, val) +#define bfin_read_CAN0_AM17H() bfin_read16(CAN0_AM17H) +#define bfin_write_CAN0_AM17H(val) bfin_write16(CAN0_AM17H, val) +#define bfin_read_CAN0_AM18L() bfin_read16(CAN0_AM18L) +#define bfin_write_CAN0_AM18L(val) bfin_write16(CAN0_AM18L, val) +#define bfin_read_CAN0_AM18H() bfin_read16(CAN0_AM18H) +#define bfin_write_CAN0_AM18H(val) bfin_write16(CAN0_AM18H, val) +#define bfin_read_CAN0_AM19L() bfin_read16(CAN0_AM19L) +#define bfin_write_CAN0_AM19L(val) bfin_write16(CAN0_AM19L, val) +#define bfin_read_CAN0_AM19H() bfin_read16(CAN0_AM19H) +#define bfin_write_CAN0_AM19H(val) bfin_write16(CAN0_AM19H, val) +#define bfin_read_CAN0_AM20L() bfin_read16(CAN0_AM20L) +#define bfin_write_CAN0_AM20L(val) bfin_write16(CAN0_AM20L, val) +#define bfin_read_CAN0_AM20H() bfin_read16(CAN0_AM20H) +#define bfin_write_CAN0_AM20H(val) bfin_write16(CAN0_AM20H, val) +#define bfin_read_CAN0_AM21L() bfin_read16(CAN0_AM21L) +#define bfin_write_CAN0_AM21L(val) bfin_write16(CAN0_AM21L, val) +#define bfin_read_CAN0_AM21H() bfin_read16(CAN0_AM21H) +#define bfin_write_CAN0_AM21H(val) bfin_write16(CAN0_AM21H, val) +#define bfin_read_CAN0_AM22L() bfin_read16(CAN0_AM22L) +#define bfin_write_CAN0_AM22L(val) bfin_write16(CAN0_AM22L, val) +#define bfin_read_CAN0_AM22H() bfin_read16(CAN0_AM22H) +#define bfin_write_CAN0_AM22H(val) bfin_write16(CAN0_AM22H, val) +#define bfin_read_CAN0_AM23L() bfin_read16(CAN0_AM23L) +#define bfin_write_CAN0_AM23L(val) bfin_write16(CAN0_AM23L, val) +#define bfin_read_CAN0_AM23H() bfin_read16(CAN0_AM23H) +#define bfin_write_CAN0_AM23H(val) bfin_write16(CAN0_AM23H, val) +#define bfin_read_CAN0_AM24L() bfin_read16(CAN0_AM24L) +#define bfin_write_CAN0_AM24L(val) bfin_write16(CAN0_AM24L, val) +#define bfin_read_CAN0_AM24H() bfin_read16(CAN0_AM24H) +#define bfin_write_CAN0_AM24H(val) bfin_write16(CAN0_AM24H, val) +#define bfin_read_CAN0_AM25L() bfin_read16(CAN0_AM25L) +#define bfin_write_CAN0_AM25L(val) bfin_write16(CAN0_AM25L, val) +#define bfin_read_CAN0_AM25H() bfin_read16(CAN0_AM25H) +#define bfin_write_CAN0_AM25H(val) bfin_write16(CAN0_AM25H, val) +#define bfin_read_CAN0_AM26L() bfin_read16(CAN0_AM26L) +#define bfin_write_CAN0_AM26L(val) bfin_write16(CAN0_AM26L, val) +#define bfin_read_CAN0_AM26H() bfin_read16(CAN0_AM26H) +#define bfin_write_CAN0_AM26H(val) bfin_write16(CAN0_AM26H, val) +#define bfin_read_CAN0_AM27L() bfin_read16(CAN0_AM27L) +#define bfin_write_CAN0_AM27L(val) bfin_write16(CAN0_AM27L, val) +#define bfin_read_CAN0_AM27H() bfin_read16(CAN0_AM27H) +#define bfin_write_CAN0_AM27H(val) bfin_write16(CAN0_AM27H, val) +#define bfin_read_CAN0_AM28L() bfin_read16(CAN0_AM28L) +#define bfin_write_CAN0_AM28L(val) bfin_write16(CAN0_AM28L, val) +#define bfin_read_CAN0_AM28H() bfin_read16(CAN0_AM28H) +#define bfin_write_CAN0_AM28H(val) bfin_write16(CAN0_AM28H, val) +#define bfin_read_CAN0_AM29L() bfin_read16(CAN0_AM29L) +#define bfin_write_CAN0_AM29L(val) bfin_write16(CAN0_AM29L, val) +#define bfin_read_CAN0_AM29H() bfin_read16(CAN0_AM29H) +#define bfin_write_CAN0_AM29H(val) bfin_write16(CAN0_AM29H, val) +#define bfin_read_CAN0_AM30L() bfin_read16(CAN0_AM30L) +#define bfin_write_CAN0_AM30L(val) bfin_write16(CAN0_AM30L, val) +#define bfin_read_CAN0_AM30H() bfin_read16(CAN0_AM30H) +#define bfin_write_CAN0_AM30H(val) bfin_write16(CAN0_AM30H, val) +#define bfin_read_CAN0_AM31L() bfin_read16(CAN0_AM31L) +#define bfin_write_CAN0_AM31L(val) bfin_write16(CAN0_AM31L, val) +#define bfin_read_CAN0_AM31H() bfin_read16(CAN0_AM31H) +#define bfin_write_CAN0_AM31H(val) bfin_write16(CAN0_AM31H, val) + +/* CAN Controller 0 Mailbox Data Registers */ + +#define bfin_read_CAN0_MB00_DATA0() bfin_read16(CAN0_MB00_DATA0) +#define bfin_write_CAN0_MB00_DATA0(val) bfin_write16(CAN0_MB00_DATA0, val) +#define bfin_read_CAN0_MB00_DATA1() bfin_read16(CAN0_MB00_DATA1) +#define bfin_write_CAN0_MB00_DATA1(val) bfin_write16(CAN0_MB00_DATA1, val) +#define bfin_read_CAN0_MB00_DATA2() bfin_read16(CAN0_MB00_DATA2) +#define bfin_write_CAN0_MB00_DATA2(val) bfin_write16(CAN0_MB00_DATA2, val) +#define bfin_read_CAN0_MB00_DATA3() bfin_read16(CAN0_MB00_DATA3) +#define bfin_write_CAN0_MB00_DATA3(val) bfin_write16(CAN0_MB00_DATA3, val) +#define bfin_read_CAN0_MB00_LENGTH() bfin_read16(CAN0_MB00_LENGTH) +#define bfin_write_CAN0_MB00_LENGTH(val) bfin_write16(CAN0_MB00_LENGTH, val) +#define bfin_read_CAN0_MB00_TIMESTAMP() bfin_read16(CAN0_MB00_TIMESTAMP) +#define bfin_write_CAN0_MB00_TIMESTAMP(val) bfin_write16(CAN0_MB00_TIMESTAMP, val) +#define bfin_read_CAN0_MB00_ID0() bfin_read16(CAN0_MB00_ID0) +#define bfin_write_CAN0_MB00_ID0(val) bfin_write16(CAN0_MB00_ID0, val) +#define bfin_read_CAN0_MB00_ID1() bfin_read16(CAN0_MB00_ID1) +#define bfin_write_CAN0_MB00_ID1(val) bfin_write16(CAN0_MB00_ID1, val) +#define bfin_read_CAN0_MB01_DATA0() bfin_read16(CAN0_MB01_DATA0) +#define bfin_write_CAN0_MB01_DATA0(val) bfin_write16(CAN0_MB01_DATA0, val) +#define bfin_read_CAN0_MB01_DATA1() bfin_read16(CAN0_MB01_DATA1) +#define bfin_write_CAN0_MB01_DATA1(val) bfin_write16(CAN0_MB01_DATA1, val) +#define bfin_read_CAN0_MB01_DATA2() bfin_read16(CAN0_MB01_DATA2) +#define bfin_write_CAN0_MB01_DATA2(val) bfin_write16(CAN0_MB01_DATA2, val) +#define bfin_read_CAN0_MB01_DATA3() bfin_read16(CAN0_MB01_DATA3) +#define bfin_write_CAN0_MB01_DATA3(val) bfin_write16(CAN0_MB01_DATA3, val) +#define bfin_read_CAN0_MB01_LENGTH() bfin_read16(CAN0_MB01_LENGTH) +#define bfin_write_CAN0_MB01_LENGTH(val) bfin_write16(CAN0_MB01_LENGTH, val) +#define bfin_read_CAN0_MB01_TIMESTAMP() bfin_read16(CAN0_MB01_TIMESTAMP) +#define bfin_write_CAN0_MB01_TIMESTAMP(val) bfin_write16(CAN0_MB01_TIMESTAMP, val) +#define bfin_read_CAN0_MB01_ID0() bfin_read16(CAN0_MB01_ID0) +#define bfin_write_CAN0_MB01_ID0(val) bfin_write16(CAN0_MB01_ID0, val) +#define bfin_read_CAN0_MB01_ID1() bfin_read16(CAN0_MB01_ID1) +#define bfin_write_CAN0_MB01_ID1(val) bfin_write16(CAN0_MB01_ID1, val) +#define bfin_read_CAN0_MB02_DATA0() bfin_read16(CAN0_MB02_DATA0) +#define bfin_write_CAN0_MB02_DATA0(val) bfin_write16(CAN0_MB02_DATA0, val) +#define bfin_read_CAN0_MB02_DATA1() bfin_read16(CAN0_MB02_DATA1) +#define bfin_write_CAN0_MB02_DATA1(val) bfin_write16(CAN0_MB02_DATA1, val) +#define bfin_read_CAN0_MB02_DATA2() bfin_read16(CAN0_MB02_DATA2) +#define bfin_write_CAN0_MB02_DATA2(val) bfin_write16(CAN0_MB02_DATA2, val) +#define bfin_read_CAN0_MB02_DATA3() bfin_read16(CAN0_MB02_DATA3) +#define bfin_write_CAN0_MB02_DATA3(val) bfin_write16(CAN0_MB02_DATA3, val) +#define bfin_read_CAN0_MB02_LENGTH() bfin_read16(CAN0_MB02_LENGTH) +#define bfin_write_CAN0_MB02_LENGTH(val) bfin_write16(CAN0_MB02_LENGTH, val) +#define bfin_read_CAN0_MB02_TIMESTAMP() bfin_read16(CAN0_MB02_TIMESTAMP) +#define bfin_write_CAN0_MB02_TIMESTAMP(val) bfin_write16(CAN0_MB02_TIMESTAMP, val) +#define bfin_read_CAN0_MB02_ID0() bfin_read16(CAN0_MB02_ID0) +#define bfin_write_CAN0_MB02_ID0(val) bfin_write16(CAN0_MB02_ID0, val) +#define bfin_read_CAN0_MB02_ID1() bfin_read16(CAN0_MB02_ID1) +#define bfin_write_CAN0_MB02_ID1(val) bfin_write16(CAN0_MB02_ID1, val) +#define bfin_read_CAN0_MB03_DATA0() bfin_read16(CAN0_MB03_DATA0) +#define bfin_write_CAN0_MB03_DATA0(val) bfin_write16(CAN0_MB03_DATA0, val) +#define bfin_read_CAN0_MB03_DATA1() bfin_read16(CAN0_MB03_DATA1) +#define bfin_write_CAN0_MB03_DATA1(val) bfin_write16(CAN0_MB03_DATA1, val) +#define bfin_read_CAN0_MB03_DATA2() bfin_read16(CAN0_MB03_DATA2) +#define bfin_write_CAN0_MB03_DATA2(val) bfin_write16(CAN0_MB03_DATA2, val) +#define bfin_read_CAN0_MB03_DATA3() bfin_read16(CAN0_MB03_DATA3) +#define bfin_write_CAN0_MB03_DATA3(val) bfin_write16(CAN0_MB03_DATA3, val) +#define bfin_read_CAN0_MB03_LENGTH() bfin_read16(CAN0_MB03_LENGTH) +#define bfin_write_CAN0_MB03_LENGTH(val) bfin_write16(CAN0_MB03_LENGTH, val) +#define bfin_read_CAN0_MB03_TIMESTAMP() bfin_read16(CAN0_MB03_TIMESTAMP) +#define bfin_write_CAN0_MB03_TIMESTAMP(val) bfin_write16(CAN0_MB03_TIMESTAMP, val) +#define bfin_read_CAN0_MB03_ID0() bfin_read16(CAN0_MB03_ID0) +#define bfin_write_CAN0_MB03_ID0(val) bfin_write16(CAN0_MB03_ID0, val) +#define bfin_read_CAN0_MB03_ID1() bfin_read16(CAN0_MB03_ID1) +#define bfin_write_CAN0_MB03_ID1(val) bfin_write16(CAN0_MB03_ID1, val) +#define bfin_read_CAN0_MB04_DATA0() bfin_read16(CAN0_MB04_DATA0) +#define bfin_write_CAN0_MB04_DATA0(val) bfin_write16(CAN0_MB04_DATA0, val) +#define bfin_read_CAN0_MB04_DATA1() bfin_read16(CAN0_MB04_DATA1) +#define bfin_write_CAN0_MB04_DATA1(val) bfin_write16(CAN0_MB04_DATA1, val) +#define bfin_read_CAN0_MB04_DATA2() bfin_read16(CAN0_MB04_DATA2) +#define bfin_write_CAN0_MB04_DATA2(val) bfin_write16(CAN0_MB04_DATA2, val) +#define bfin_read_CAN0_MB04_DATA3() bfin_read16(CAN0_MB04_DATA3) +#define bfin_write_CAN0_MB04_DATA3(val) bfin_write16(CAN0_MB04_DATA3, val) +#define bfin_read_CAN0_MB04_LENGTH() bfin_read16(CAN0_MB04_LENGTH) +#define bfin_write_CAN0_MB04_LENGTH(val) bfin_write16(CAN0_MB04_LENGTH, val) +#define bfin_read_CAN0_MB04_TIMESTAMP() bfin_read16(CAN0_MB04_TIMESTAMP) +#define bfin_write_CAN0_MB04_TIMESTAMP(val) bfin_write16(CAN0_MB04_TIMESTAMP, val) +#define bfin_read_CAN0_MB04_ID0() bfin_read16(CAN0_MB04_ID0) +#define bfin_write_CAN0_MB04_ID0(val) bfin_write16(CAN0_MB04_ID0, val) +#define bfin_read_CAN0_MB04_ID1() bfin_read16(CAN0_MB04_ID1) +#define bfin_write_CAN0_MB04_ID1(val) bfin_write16(CAN0_MB04_ID1, val) +#define bfin_read_CAN0_MB05_DATA0() bfin_read16(CAN0_MB05_DATA0) +#define bfin_write_CAN0_MB05_DATA0(val) bfin_write16(CAN0_MB05_DATA0, val) +#define bfin_read_CAN0_MB05_DATA1() bfin_read16(CAN0_MB05_DATA1) +#define bfin_write_CAN0_MB05_DATA1(val) bfin_write16(CAN0_MB05_DATA1, val) +#define bfin_read_CAN0_MB05_DATA2() bfin_read16(CAN0_MB05_DATA2) +#define bfin_write_CAN0_MB05_DATA2(val) bfin_write16(CAN0_MB05_DATA2, val) +#define bfin_read_CAN0_MB05_DATA3() bfin_read16(CAN0_MB05_DATA3) +#define bfin_write_CAN0_MB05_DATA3(val) bfin_write16(CAN0_MB05_DATA3, val) +#define bfin_read_CAN0_MB05_LENGTH() bfin_read16(CAN0_MB05_LENGTH) +#define bfin_write_CAN0_MB05_LENGTH(val) bfin_write16(CAN0_MB05_LENGTH, val) +#define bfin_read_CAN0_MB05_TIMESTAMP() bfin_read16(CAN0_MB05_TIMESTAMP) +#define bfin_write_CAN0_MB05_TIMESTAMP(val) bfin_write16(CAN0_MB05_TIMESTAMP, val) +#define bfin_read_CAN0_MB05_ID0() bfin_read16(CAN0_MB05_ID0) +#define bfin_write_CAN0_MB05_ID0(val) bfin_write16(CAN0_MB05_ID0, val) +#define bfin_read_CAN0_MB05_ID1() bfin_read16(CAN0_MB05_ID1) +#define bfin_write_CAN0_MB05_ID1(val) bfin_write16(CAN0_MB05_ID1, val) +#define bfin_read_CAN0_MB06_DATA0() bfin_read16(CAN0_MB06_DATA0) +#define bfin_write_CAN0_MB06_DATA0(val) bfin_write16(CAN0_MB06_DATA0, val) +#define bfin_read_CAN0_MB06_DATA1() bfin_read16(CAN0_MB06_DATA1) +#define bfin_write_CAN0_MB06_DATA1(val) bfin_write16(CAN0_MB06_DATA1, val) +#define bfin_read_CAN0_MB06_DATA2() bfin_read16(CAN0_MB06_DATA2) +#define bfin_write_CAN0_MB06_DATA2(val) bfin_write16(CAN0_MB06_DATA2, val) +#define bfin_read_CAN0_MB06_DATA3() bfin_read16(CAN0_MB06_DATA3) +#define bfin_write_CAN0_MB06_DATA3(val) bfin_write16(CAN0_MB06_DATA3, val) +#define bfin_read_CAN0_MB06_LENGTH() bfin_read16(CAN0_MB06_LENGTH) +#define bfin_write_CAN0_MB06_LENGTH(val) bfin_write16(CAN0_MB06_LENGTH, val) +#define bfin_read_CAN0_MB06_TIMESTAMP() bfin_read16(CAN0_MB06_TIMESTAMP) +#define bfin_write_CAN0_MB06_TIMESTAMP(val) bfin_write16(CAN0_MB06_TIMESTAMP, val) +#define bfin_read_CAN0_MB06_ID0() bfin_read16(CAN0_MB06_ID0) +#define bfin_write_CAN0_MB06_ID0(val) bfin_write16(CAN0_MB06_ID0, val) +#define bfin_read_CAN0_MB06_ID1() bfin_read16(CAN0_MB06_ID1) +#define bfin_write_CAN0_MB06_ID1(val) bfin_write16(CAN0_MB06_ID1, val) +#define bfin_read_CAN0_MB07_DATA0() bfin_read16(CAN0_MB07_DATA0) +#define bfin_write_CAN0_MB07_DATA0(val) bfin_write16(CAN0_MB07_DATA0, val) +#define bfin_read_CAN0_MB07_DATA1() bfin_read16(CAN0_MB07_DATA1) +#define bfin_write_CAN0_MB07_DATA1(val) bfin_write16(CAN0_MB07_DATA1, val) +#define bfin_read_CAN0_MB07_DATA2() bfin_read16(CAN0_MB07_DATA2) +#define bfin_write_CAN0_MB07_DATA2(val) bfin_write16(CAN0_MB07_DATA2, val) +#define bfin_read_CAN0_MB07_DATA3() bfin_read16(CAN0_MB07_DATA3) +#define bfin_write_CAN0_MB07_DATA3(val) bfin_write16(CAN0_MB07_DATA3, val) +#define bfin_read_CAN0_MB07_LENGTH() bfin_read16(CAN0_MB07_LENGTH) +#define bfin_write_CAN0_MB07_LENGTH(val) bfin_write16(CAN0_MB07_LENGTH, val) +#define bfin_read_CAN0_MB07_TIMESTAMP() bfin_read16(CAN0_MB07_TIMESTAMP) +#define bfin_write_CAN0_MB07_TIMESTAMP(val) bfin_write16(CAN0_MB07_TIMESTAMP, val) +#define bfin_read_CAN0_MB07_ID0() bfin_read16(CAN0_MB07_ID0) +#define bfin_write_CAN0_MB07_ID0(val) bfin_write16(CAN0_MB07_ID0, val) +#define bfin_read_CAN0_MB07_ID1() bfin_read16(CAN0_MB07_ID1) +#define bfin_write_CAN0_MB07_ID1(val) bfin_write16(CAN0_MB07_ID1, val) +#define bfin_read_CAN0_MB08_DATA0() bfin_read16(CAN0_MB08_DATA0) +#define bfin_write_CAN0_MB08_DATA0(val) bfin_write16(CAN0_MB08_DATA0, val) +#define bfin_read_CAN0_MB08_DATA1() bfin_read16(CAN0_MB08_DATA1) +#define bfin_write_CAN0_MB08_DATA1(val) bfin_write16(CAN0_MB08_DATA1, val) +#define bfin_read_CAN0_MB08_DATA2() bfin_read16(CAN0_MB08_DATA2) +#define bfin_write_CAN0_MB08_DATA2(val) bfin_write16(CAN0_MB08_DATA2, val) +#define bfin_read_CAN0_MB08_DATA3() bfin_read16(CAN0_MB08_DATA3) +#define bfin_write_CAN0_MB08_DATA3(val) bfin_write16(CAN0_MB08_DATA3, val) +#define bfin_read_CAN0_MB08_LENGTH() bfin_read16(CAN0_MB08_LENGTH) +#define bfin_write_CAN0_MB08_LENGTH(val) bfin_write16(CAN0_MB08_LENGTH, val) +#define bfin_read_CAN0_MB08_TIMESTAMP() bfin_read16(CAN0_MB08_TIMESTAMP) +#define bfin_write_CAN0_MB08_TIMESTAMP(val) bfin_write16(CAN0_MB08_TIMESTAMP, val) +#define bfin_read_CAN0_MB08_ID0() bfin_read16(CAN0_MB08_ID0) +#define bfin_write_CAN0_MB08_ID0(val) bfin_write16(CAN0_MB08_ID0, val) +#define bfin_read_CAN0_MB08_ID1() bfin_read16(CAN0_MB08_ID1) +#define bfin_write_CAN0_MB08_ID1(val) bfin_write16(CAN0_MB08_ID1, val) +#define bfin_read_CAN0_MB09_DATA0() bfin_read16(CAN0_MB09_DATA0) +#define bfin_write_CAN0_MB09_DATA0(val) bfin_write16(CAN0_MB09_DATA0, val) +#define bfin_read_CAN0_MB09_DATA1() bfin_read16(CAN0_MB09_DATA1) +#define bfin_write_CAN0_MB09_DATA1(val) bfin_write16(CAN0_MB09_DATA1, val) +#define bfin_read_CAN0_MB09_DATA2() bfin_read16(CAN0_MB09_DATA2) +#define bfin_write_CAN0_MB09_DATA2(val) bfin_write16(CAN0_MB09_DATA2, val) +#define bfin_read_CAN0_MB09_DATA3() bfin_read16(CAN0_MB09_DATA3) +#define bfin_write_CAN0_MB09_DATA3(val) bfin_write16(CAN0_MB09_DATA3, val) +#define bfin_read_CAN0_MB09_LENGTH() bfin_read16(CAN0_MB09_LENGTH) +#define bfin_write_CAN0_MB09_LENGTH(val) bfin_write16(CAN0_MB09_LENGTH, val) +#define bfin_read_CAN0_MB09_TIMESTAMP() bfin_read16(CAN0_MB09_TIMESTAMP) +#define bfin_write_CAN0_MB09_TIMESTAMP(val) bfin_write16(CAN0_MB09_TIMESTAMP, val) +#define bfin_read_CAN0_MB09_ID0() bfin_read16(CAN0_MB09_ID0) +#define bfin_write_CAN0_MB09_ID0(val) bfin_write16(CAN0_MB09_ID0, val) +#define bfin_read_CAN0_MB09_ID1() bfin_read16(CAN0_MB09_ID1) +#define bfin_write_CAN0_MB09_ID1(val) bfin_write16(CAN0_MB09_ID1, val) +#define bfin_read_CAN0_MB10_DATA0() bfin_read16(CAN0_MB10_DATA0) +#define bfin_write_CAN0_MB10_DATA0(val) bfin_write16(CAN0_MB10_DATA0, val) +#define bfin_read_CAN0_MB10_DATA1() bfin_read16(CAN0_MB10_DATA1) +#define bfin_write_CAN0_MB10_DATA1(val) bfin_write16(CAN0_MB10_DATA1, val) +#define bfin_read_CAN0_MB10_DATA2() bfin_read16(CAN0_MB10_DATA2) +#define bfin_write_CAN0_MB10_DATA2(val) bfin_write16(CAN0_MB10_DATA2, val) +#define bfin_read_CAN0_MB10_DATA3() bfin_read16(CAN0_MB10_DATA3) +#define bfin_write_CAN0_MB10_DATA3(val) bfin_write16(CAN0_MB10_DATA3, val) +#define bfin_read_CAN0_MB10_LENGTH() bfin_read16(CAN0_MB10_LENGTH) +#define bfin_write_CAN0_MB10_LENGTH(val) bfin_write16(CAN0_MB10_LENGTH, val) +#define bfin_read_CAN0_MB10_TIMESTAMP() bfin_read16(CAN0_MB10_TIMESTAMP) +#define bfin_write_CAN0_MB10_TIMESTAMP(val) bfin_write16(CAN0_MB10_TIMESTAMP, val) +#define bfin_read_CAN0_MB10_ID0() bfin_read16(CAN0_MB10_ID0) +#define bfin_write_CAN0_MB10_ID0(val) bfin_write16(CAN0_MB10_ID0, val) +#define bfin_read_CAN0_MB10_ID1() bfin_read16(CAN0_MB10_ID1) +#define bfin_write_CAN0_MB10_ID1(val) bfin_write16(CAN0_MB10_ID1, val) +#define bfin_read_CAN0_MB11_DATA0() bfin_read16(CAN0_MB11_DATA0) +#define bfin_write_CAN0_MB11_DATA0(val) bfin_write16(CAN0_MB11_DATA0, val) +#define bfin_read_CAN0_MB11_DATA1() bfin_read16(CAN0_MB11_DATA1) +#define bfin_write_CAN0_MB11_DATA1(val) bfin_write16(CAN0_MB11_DATA1, val) +#define bfin_read_CAN0_MB11_DATA2() bfin_read16(CAN0_MB11_DATA2) +#define bfin_write_CAN0_MB11_DATA2(val) bfin_write16(CAN0_MB11_DATA2, val) +#define bfin_read_CAN0_MB11_DATA3() bfin_read16(CAN0_MB11_DATA3) +#define bfin_write_CAN0_MB11_DATA3(val) bfin_write16(CAN0_MB11_DATA3, val) +#define bfin_read_CAN0_MB11_LENGTH() bfin_read16(CAN0_MB11_LENGTH) +#define bfin_write_CAN0_MB11_LENGTH(val) bfin_write16(CAN0_MB11_LENGTH, val) +#define bfin_read_CAN0_MB11_TIMESTAMP() bfin_read16(CAN0_MB11_TIMESTAMP) +#define bfin_write_CAN0_MB11_TIMESTAMP(val) bfin_write16(CAN0_MB11_TIMESTAMP, val) +#define bfin_read_CAN0_MB11_ID0() bfin_read16(CAN0_MB11_ID0) +#define bfin_write_CAN0_MB11_ID0(val) bfin_write16(CAN0_MB11_ID0, val) +#define bfin_read_CAN0_MB11_ID1() bfin_read16(CAN0_MB11_ID1) +#define bfin_write_CAN0_MB11_ID1(val) bfin_write16(CAN0_MB11_ID1, val) +#define bfin_read_CAN0_MB12_DATA0() bfin_read16(CAN0_MB12_DATA0) +#define bfin_write_CAN0_MB12_DATA0(val) bfin_write16(CAN0_MB12_DATA0, val) +#define bfin_read_CAN0_MB12_DATA1() bfin_read16(CAN0_MB12_DATA1) +#define bfin_write_CAN0_MB12_DATA1(val) bfin_write16(CAN0_MB12_DATA1, val) +#define bfin_read_CAN0_MB12_DATA2() bfin_read16(CAN0_MB12_DATA2) +#define bfin_write_CAN0_MB12_DATA2(val) bfin_write16(CAN0_MB12_DATA2, val) +#define bfin_read_CAN0_MB12_DATA3() bfin_read16(CAN0_MB12_DATA3) +#define bfin_write_CAN0_MB12_DATA3(val) bfin_write16(CAN0_MB12_DATA3, val) +#define bfin_read_CAN0_MB12_LENGTH() bfin_read16(CAN0_MB12_LENGTH) +#define bfin_write_CAN0_MB12_LENGTH(val) bfin_write16(CAN0_MB12_LENGTH, val) +#define bfin_read_CAN0_MB12_TIMESTAMP() bfin_read16(CAN0_MB12_TIMESTAMP) +#define bfin_write_CAN0_MB12_TIMESTAMP(val) bfin_write16(CAN0_MB12_TIMESTAMP, val) +#define bfin_read_CAN0_MB12_ID0() bfin_read16(CAN0_MB12_ID0) +#define bfin_write_CAN0_MB12_ID0(val) bfin_write16(CAN0_MB12_ID0, val) +#define bfin_read_CAN0_MB12_ID1() bfin_read16(CAN0_MB12_ID1) +#define bfin_write_CAN0_MB12_ID1(val) bfin_write16(CAN0_MB12_ID1, val) +#define bfin_read_CAN0_MB13_DATA0() bfin_read16(CAN0_MB13_DATA0) +#define bfin_write_CAN0_MB13_DATA0(val) bfin_write16(CAN0_MB13_DATA0, val) +#define bfin_read_CAN0_MB13_DATA1() bfin_read16(CAN0_MB13_DATA1) +#define bfin_write_CAN0_MB13_DATA1(val) bfin_write16(CAN0_MB13_DATA1, val) +#define bfin_read_CAN0_MB13_DATA2() bfin_read16(CAN0_MB13_DATA2) +#define bfin_write_CAN0_MB13_DATA2(val) bfin_write16(CAN0_MB13_DATA2, val) +#define bfin_read_CAN0_MB13_DATA3() bfin_read16(CAN0_MB13_DATA3) +#define bfin_write_CAN0_MB13_DATA3(val) bfin_write16(CAN0_MB13_DATA3, val) +#define bfin_read_CAN0_MB13_LENGTH() bfin_read16(CAN0_MB13_LENGTH) +#define bfin_write_CAN0_MB13_LENGTH(val) bfin_write16(CAN0_MB13_LENGTH, val) +#define bfin_read_CAN0_MB13_TIMESTAMP() bfin_read16(CAN0_MB13_TIMESTAMP) +#define bfin_write_CAN0_MB13_TIMESTAMP(val) bfin_write16(CAN0_MB13_TIMESTAMP, val) +#define bfin_read_CAN0_MB13_ID0() bfin_read16(CAN0_MB13_ID0) +#define bfin_write_CAN0_MB13_ID0(val) bfin_write16(CAN0_MB13_ID0, val) +#define bfin_read_CAN0_MB13_ID1() bfin_read16(CAN0_MB13_ID1) +#define bfin_write_CAN0_MB13_ID1(val) bfin_write16(CAN0_MB13_ID1, val) +#define bfin_read_CAN0_MB14_DATA0() bfin_read16(CAN0_MB14_DATA0) +#define bfin_write_CAN0_MB14_DATA0(val) bfin_write16(CAN0_MB14_DATA0, val) +#define bfin_read_CAN0_MB14_DATA1() bfin_read16(CAN0_MB14_DATA1) +#define bfin_write_CAN0_MB14_DATA1(val) bfin_write16(CAN0_MB14_DATA1, val) +#define bfin_read_CAN0_MB14_DATA2() bfin_read16(CAN0_MB14_DATA2) +#define bfin_write_CAN0_MB14_DATA2(val) bfin_write16(CAN0_MB14_DATA2, val) +#define bfin_read_CAN0_MB14_DATA3() bfin_read16(CAN0_MB14_DATA3) +#define bfin_write_CAN0_MB14_DATA3(val) bfin_write16(CAN0_MB14_DATA3, val) +#define bfin_read_CAN0_MB14_LENGTH() bfin_read16(CAN0_MB14_LENGTH) +#define bfin_write_CAN0_MB14_LENGTH(val) bfin_write16(CAN0_MB14_LENGTH, val) +#define bfin_read_CAN0_MB14_TIMESTAMP() bfin_read16(CAN0_MB14_TIMESTAMP) +#define bfin_write_CAN0_MB14_TIMESTAMP(val) bfin_write16(CAN0_MB14_TIMESTAMP, val) +#define bfin_read_CAN0_MB14_ID0() bfin_read16(CAN0_MB14_ID0) +#define bfin_write_CAN0_MB14_ID0(val) bfin_write16(CAN0_MB14_ID0, val) +#define bfin_read_CAN0_MB14_ID1() bfin_read16(CAN0_MB14_ID1) +#define bfin_write_CAN0_MB14_ID1(val) bfin_write16(CAN0_MB14_ID1, val) +#define bfin_read_CAN0_MB15_DATA0() bfin_read16(CAN0_MB15_DATA0) +#define bfin_write_CAN0_MB15_DATA0(val) bfin_write16(CAN0_MB15_DATA0, val) +#define bfin_read_CAN0_MB15_DATA1() bfin_read16(CAN0_MB15_DATA1) +#define bfin_write_CAN0_MB15_DATA1(val) bfin_write16(CAN0_MB15_DATA1, val) +#define bfin_read_CAN0_MB15_DATA2() bfin_read16(CAN0_MB15_DATA2) +#define bfin_write_CAN0_MB15_DATA2(val) bfin_write16(CAN0_MB15_DATA2, val) +#define bfin_read_CAN0_MB15_DATA3() bfin_read16(CAN0_MB15_DATA3) +#define bfin_write_CAN0_MB15_DATA3(val) bfin_write16(CAN0_MB15_DATA3, val) +#define bfin_read_CAN0_MB15_LENGTH() bfin_read16(CAN0_MB15_LENGTH) +#define bfin_write_CAN0_MB15_LENGTH(val) bfin_write16(CAN0_MB15_LENGTH, val) +#define bfin_read_CAN0_MB15_TIMESTAMP() bfin_read16(CAN0_MB15_TIMESTAMP) +#define bfin_write_CAN0_MB15_TIMESTAMP(val) bfin_write16(CAN0_MB15_TIMESTAMP, val) +#define bfin_read_CAN0_MB15_ID0() bfin_read16(CAN0_MB15_ID0) +#define bfin_write_CAN0_MB15_ID0(val) bfin_write16(CAN0_MB15_ID0, val) +#define bfin_read_CAN0_MB15_ID1() bfin_read16(CAN0_MB15_ID1) +#define bfin_write_CAN0_MB15_ID1(val) bfin_write16(CAN0_MB15_ID1, val) + +/* CAN Controller 0 Mailbox Data Registers */ + +#define bfin_read_CAN0_MB16_DATA0() bfin_read16(CAN0_MB16_DATA0) +#define bfin_write_CAN0_MB16_DATA0(val) bfin_write16(CAN0_MB16_DATA0, val) +#define bfin_read_CAN0_MB16_DATA1() bfin_read16(CAN0_MB16_DATA1) +#define bfin_write_CAN0_MB16_DATA1(val) bfin_write16(CAN0_MB16_DATA1, val) +#define bfin_read_CAN0_MB16_DATA2() bfin_read16(CAN0_MB16_DATA2) +#define bfin_write_CAN0_MB16_DATA2(val) bfin_write16(CAN0_MB16_DATA2, val) +#define bfin_read_CAN0_MB16_DATA3() bfin_read16(CAN0_MB16_DATA3) +#define bfin_write_CAN0_MB16_DATA3(val) bfin_write16(CAN0_MB16_DATA3, val) +#define bfin_read_CAN0_MB16_LENGTH() bfin_read16(CAN0_MB16_LENGTH) +#define bfin_write_CAN0_MB16_LENGTH(val) bfin_write16(CAN0_MB16_LENGTH, val) +#define bfin_read_CAN0_MB16_TIMESTAMP() bfin_read16(CAN0_MB16_TIMESTAMP) +#define bfin_write_CAN0_MB16_TIMESTAMP(val) bfin_write16(CAN0_MB16_TIMESTAMP, val) +#define bfin_read_CAN0_MB16_ID0() bfin_read16(CAN0_MB16_ID0) +#define bfin_write_CAN0_MB16_ID0(val) bfin_write16(CAN0_MB16_ID0, val) +#define bfin_read_CAN0_MB16_ID1() bfin_read16(CAN0_MB16_ID1) +#define bfin_write_CAN0_MB16_ID1(val) bfin_write16(CAN0_MB16_ID1, val) +#define bfin_read_CAN0_MB17_DATA0() bfin_read16(CAN0_MB17_DATA0) +#define bfin_write_CAN0_MB17_DATA0(val) bfin_write16(CAN0_MB17_DATA0, val) +#define bfin_read_CAN0_MB17_DATA1() bfin_read16(CAN0_MB17_DATA1) +#define bfin_write_CAN0_MB17_DATA1(val) bfin_write16(CAN0_MB17_DATA1, val) +#define bfin_read_CAN0_MB17_DATA2() bfin_read16(CAN0_MB17_DATA2) +#define bfin_write_CAN0_MB17_DATA2(val) bfin_write16(CAN0_MB17_DATA2, val) +#define bfin_read_CAN0_MB17_DATA3() bfin_read16(CAN0_MB17_DATA3) +#define bfin_write_CAN0_MB17_DATA3(val) bfin_write16(CAN0_MB17_DATA3, val) +#define bfin_read_CAN0_MB17_LENGTH() bfin_read16(CAN0_MB17_LENGTH) +#define bfin_write_CAN0_MB17_LENGTH(val) bfin_write16(CAN0_MB17_LENGTH, val) +#define bfin_read_CAN0_MB17_TIMESTAMP() bfin_read16(CAN0_MB17_TIMESTAMP) +#define bfin_write_CAN0_MB17_TIMESTAMP(val) bfin_write16(CAN0_MB17_TIMESTAMP, val) +#define bfin_read_CAN0_MB17_ID0() bfin_read16(CAN0_MB17_ID0) +#define bfin_write_CAN0_MB17_ID0(val) bfin_write16(CAN0_MB17_ID0, val) +#define bfin_read_CAN0_MB17_ID1() bfin_read16(CAN0_MB17_ID1) +#define bfin_write_CAN0_MB17_ID1(val) bfin_write16(CAN0_MB17_ID1, val) +#define bfin_read_CAN0_MB18_DATA0() bfin_read16(CAN0_MB18_DATA0) +#define bfin_write_CAN0_MB18_DATA0(val) bfin_write16(CAN0_MB18_DATA0, val) +#define bfin_read_CAN0_MB18_DATA1() bfin_read16(CAN0_MB18_DATA1) +#define bfin_write_CAN0_MB18_DATA1(val) bfin_write16(CAN0_MB18_DATA1, val) +#define bfin_read_CAN0_MB18_DATA2() bfin_read16(CAN0_MB18_DATA2) +#define bfin_write_CAN0_MB18_DATA2(val) bfin_write16(CAN0_MB18_DATA2, val) +#define bfin_read_CAN0_MB18_DATA3() bfin_read16(CAN0_MB18_DATA3) +#define bfin_write_CAN0_MB18_DATA3(val) bfin_write16(CAN0_MB18_DATA3, val) +#define bfin_read_CAN0_MB18_LENGTH() bfin_read16(CAN0_MB18_LENGTH) +#define bfin_write_CAN0_MB18_LENGTH(val) bfin_write16(CAN0_MB18_LENGTH, val) +#define bfin_read_CAN0_MB18_TIMESTAMP() bfin_read16(CAN0_MB18_TIMESTAMP) +#define bfin_write_CAN0_MB18_TIMESTAMP(val) bfin_write16(CAN0_MB18_TIMESTAMP, val) +#define bfin_read_CAN0_MB18_ID0() bfin_read16(CAN0_MB18_ID0) +#define bfin_write_CAN0_MB18_ID0(val) bfin_write16(CAN0_MB18_ID0, val) +#define bfin_read_CAN0_MB18_ID1() bfin_read16(CAN0_MB18_ID1) +#define bfin_write_CAN0_MB18_ID1(val) bfin_write16(CAN0_MB18_ID1, val) +#define bfin_read_CAN0_MB19_DATA0() bfin_read16(CAN0_MB19_DATA0) +#define bfin_write_CAN0_MB19_DATA0(val) bfin_write16(CAN0_MB19_DATA0, val) +#define bfin_read_CAN0_MB19_DATA1() bfin_read16(CAN0_MB19_DATA1) +#define bfin_write_CAN0_MB19_DATA1(val) bfin_write16(CAN0_MB19_DATA1, val) +#define bfin_read_CAN0_MB19_DATA2() bfin_read16(CAN0_MB19_DATA2) +#define bfin_write_CAN0_MB19_DATA2(val) bfin_write16(CAN0_MB19_DATA2, val) +#define bfin_read_CAN0_MB19_DATA3() bfin_read16(CAN0_MB19_DATA3) +#define bfin_write_CAN0_MB19_DATA3(val) bfin_write16(CAN0_MB19_DATA3, val) +#define bfin_read_CAN0_MB19_LENGTH() bfin_read16(CAN0_MB19_LENGTH) +#define bfin_write_CAN0_MB19_LENGTH(val) bfin_write16(CAN0_MB19_LENGTH, val) +#define bfin_read_CAN0_MB19_TIMESTAMP() bfin_read16(CAN0_MB19_TIMESTAMP) +#define bfin_write_CAN0_MB19_TIMESTAMP(val) bfin_write16(CAN0_MB19_TIMESTAMP, val) +#define bfin_read_CAN0_MB19_ID0() bfin_read16(CAN0_MB19_ID0) +#define bfin_write_CAN0_MB19_ID0(val) bfin_write16(CAN0_MB19_ID0, val) +#define bfin_read_CAN0_MB19_ID1() bfin_read16(CAN0_MB19_ID1) +#define bfin_write_CAN0_MB19_ID1(val) bfin_write16(CAN0_MB19_ID1, val) +#define bfin_read_CAN0_MB20_DATA0() bfin_read16(CAN0_MB20_DATA0) +#define bfin_write_CAN0_MB20_DATA0(val) bfin_write16(CAN0_MB20_DATA0, val) +#define bfin_read_CAN0_MB20_DATA1() bfin_read16(CAN0_MB20_DATA1) +#define bfin_write_CAN0_MB20_DATA1(val) bfin_write16(CAN0_MB20_DATA1, val) +#define bfin_read_CAN0_MB20_DATA2() bfin_read16(CAN0_MB20_DATA2) +#define bfin_write_CAN0_MB20_DATA2(val) bfin_write16(CAN0_MB20_DATA2, val) +#define bfin_read_CAN0_MB20_DATA3() bfin_read16(CAN0_MB20_DATA3) +#define bfin_write_CAN0_MB20_DATA3(val) bfin_write16(CAN0_MB20_DATA3, val) +#define bfin_read_CAN0_MB20_LENGTH() bfin_read16(CAN0_MB20_LENGTH) +#define bfin_write_CAN0_MB20_LENGTH(val) bfin_write16(CAN0_MB20_LENGTH, val) +#define bfin_read_CAN0_MB20_TIMESTAMP() bfin_read16(CAN0_MB20_TIMESTAMP) +#define bfin_write_CAN0_MB20_TIMESTAMP(val) bfin_write16(CAN0_MB20_TIMESTAMP, val) +#define bfin_read_CAN0_MB20_ID0() bfin_read16(CAN0_MB20_ID0) +#define bfin_write_CAN0_MB20_ID0(val) bfin_write16(CAN0_MB20_ID0, val) +#define bfin_read_CAN0_MB20_ID1() bfin_read16(CAN0_MB20_ID1) +#define bfin_write_CAN0_MB20_ID1(val) bfin_write16(CAN0_MB20_ID1, val) +#define bfin_read_CAN0_MB21_DATA0() bfin_read16(CAN0_MB21_DATA0) +#define bfin_write_CAN0_MB21_DATA0(val) bfin_write16(CAN0_MB21_DATA0, val) +#define bfin_read_CAN0_MB21_DATA1() bfin_read16(CAN0_MB21_DATA1) +#define bfin_write_CAN0_MB21_DATA1(val) bfin_write16(CAN0_MB21_DATA1, val) +#define bfin_read_CAN0_MB21_DATA2() bfin_read16(CAN0_MB21_DATA2) +#define bfin_write_CAN0_MB21_DATA2(val) bfin_write16(CAN0_MB21_DATA2, val) +#define bfin_read_CAN0_MB21_DATA3() bfin_read16(CAN0_MB21_DATA3) +#define bfin_write_CAN0_MB21_DATA3(val) bfin_write16(CAN0_MB21_DATA3, val) +#define bfin_read_CAN0_MB21_LENGTH() bfin_read16(CAN0_MB21_LENGTH) +#define bfin_write_CAN0_MB21_LENGTH(val) bfin_write16(CAN0_MB21_LENGTH, val) +#define bfin_read_CAN0_MB21_TIMESTAMP() bfin_read16(CAN0_MB21_TIMESTAMP) +#define bfin_write_CAN0_MB21_TIMESTAMP(val) bfin_write16(CAN0_MB21_TIMESTAMP, val) +#define bfin_read_CAN0_MB21_ID0() bfin_read16(CAN0_MB21_ID0) +#define bfin_write_CAN0_MB21_ID0(val) bfin_write16(CAN0_MB21_ID0, val) +#define bfin_read_CAN0_MB21_ID1() bfin_read16(CAN0_MB21_ID1) +#define bfin_write_CAN0_MB21_ID1(val) bfin_write16(CAN0_MB21_ID1, val) +#define bfin_read_CAN0_MB22_DATA0() bfin_read16(CAN0_MB22_DATA0) +#define bfin_write_CAN0_MB22_DATA0(val) bfin_write16(CAN0_MB22_DATA0, val) +#define bfin_read_CAN0_MB22_DATA1() bfin_read16(CAN0_MB22_DATA1) +#define bfin_write_CAN0_MB22_DATA1(val) bfin_write16(CAN0_MB22_DATA1, val) +#define bfin_read_CAN0_MB22_DATA2() bfin_read16(CAN0_MB22_DATA2) +#define bfin_write_CAN0_MB22_DATA2(val) bfin_write16(CAN0_MB22_DATA2, val) +#define bfin_read_CAN0_MB22_DATA3() bfin_read16(CAN0_MB22_DATA3) +#define bfin_write_CAN0_MB22_DATA3(val) bfin_write16(CAN0_MB22_DATA3, val) +#define bfin_read_CAN0_MB22_LENGTH() bfin_read16(CAN0_MB22_LENGTH) +#define bfin_write_CAN0_MB22_LENGTH(val) bfin_write16(CAN0_MB22_LENGTH, val) +#define bfin_read_CAN0_MB22_TIMESTAMP() bfin_read16(CAN0_MB22_TIMESTAMP) +#define bfin_write_CAN0_MB22_TIMESTAMP(val) bfin_write16(CAN0_MB22_TIMESTAMP, val) +#define bfin_read_CAN0_MB22_ID0() bfin_read16(CAN0_MB22_ID0) +#define bfin_write_CAN0_MB22_ID0(val) bfin_write16(CAN0_MB22_ID0, val) +#define bfin_read_CAN0_MB22_ID1() bfin_read16(CAN0_MB22_ID1) +#define bfin_write_CAN0_MB22_ID1(val) bfin_write16(CAN0_MB22_ID1, val) +#define bfin_read_CAN0_MB23_DATA0() bfin_read16(CAN0_MB23_DATA0) +#define bfin_write_CAN0_MB23_DATA0(val) bfin_write16(CAN0_MB23_DATA0, val) +#define bfin_read_CAN0_MB23_DATA1() bfin_read16(CAN0_MB23_DATA1) +#define bfin_write_CAN0_MB23_DATA1(val) bfin_write16(CAN0_MB23_DATA1, val) +#define bfin_read_CAN0_MB23_DATA2() bfin_read16(CAN0_MB23_DATA2) +#define bfin_write_CAN0_MB23_DATA2(val) bfin_write16(CAN0_MB23_DATA2, val) +#define bfin_read_CAN0_MB23_DATA3() bfin_read16(CAN0_MB23_DATA3) +#define bfin_write_CAN0_MB23_DATA3(val) bfin_write16(CAN0_MB23_DATA3, val) +#define bfin_read_CAN0_MB23_LENGTH() bfin_read16(CAN0_MB23_LENGTH) +#define bfin_write_CAN0_MB23_LENGTH(val) bfin_write16(CAN0_MB23_LENGTH, val) +#define bfin_read_CAN0_MB23_TIMESTAMP() bfin_read16(CAN0_MB23_TIMESTAMP) +#define bfin_write_CAN0_MB23_TIMESTAMP(val) bfin_write16(CAN0_MB23_TIMESTAMP, val) +#define bfin_read_CAN0_MB23_ID0() bfin_read16(CAN0_MB23_ID0) +#define bfin_write_CAN0_MB23_ID0(val) bfin_write16(CAN0_MB23_ID0, val) +#define bfin_read_CAN0_MB23_ID1() bfin_read16(CAN0_MB23_ID1) +#define bfin_write_CAN0_MB23_ID1(val) bfin_write16(CAN0_MB23_ID1, val) +#define bfin_read_CAN0_MB24_DATA0() bfin_read16(CAN0_MB24_DATA0) +#define bfin_write_CAN0_MB24_DATA0(val) bfin_write16(CAN0_MB24_DATA0, val) +#define bfin_read_CAN0_MB24_DATA1() bfin_read16(CAN0_MB24_DATA1) +#define bfin_write_CAN0_MB24_DATA1(val) bfin_write16(CAN0_MB24_DATA1, val) +#define bfin_read_CAN0_MB24_DATA2() bfin_read16(CAN0_MB24_DATA2) +#define bfin_write_CAN0_MB24_DATA2(val) bfin_write16(CAN0_MB24_DATA2, val) +#define bfin_read_CAN0_MB24_DATA3() bfin_read16(CAN0_MB24_DATA3) +#define bfin_write_CAN0_MB24_DATA3(val) bfin_write16(CAN0_MB24_DATA3, val) +#define bfin_read_CAN0_MB24_LENGTH() bfin_read16(CAN0_MB24_LENGTH) +#define bfin_write_CAN0_MB24_LENGTH(val) bfin_write16(CAN0_MB24_LENGTH, val) +#define bfin_read_CAN0_MB24_TIMESTAMP() bfin_read16(CAN0_MB24_TIMESTAMP) +#define bfin_write_CAN0_MB24_TIMESTAMP(val) bfin_write16(CAN0_MB24_TIMESTAMP, val) +#define bfin_read_CAN0_MB24_ID0() bfin_read16(CAN0_MB24_ID0) +#define bfin_write_CAN0_MB24_ID0(val) bfin_write16(CAN0_MB24_ID0, val) +#define bfin_read_CAN0_MB24_ID1() bfin_read16(CAN0_MB24_ID1) +#define bfin_write_CAN0_MB24_ID1(val) bfin_write16(CAN0_MB24_ID1, val) +#define bfin_read_CAN0_MB25_DATA0() bfin_read16(CAN0_MB25_DATA0) +#define bfin_write_CAN0_MB25_DATA0(val) bfin_write16(CAN0_MB25_DATA0, val) +#define bfin_read_CAN0_MB25_DATA1() bfin_read16(CAN0_MB25_DATA1) +#define bfin_write_CAN0_MB25_DATA1(val) bfin_write16(CAN0_MB25_DATA1, val) +#define bfin_read_CAN0_MB25_DATA2() bfin_read16(CAN0_MB25_DATA2) +#define bfin_write_CAN0_MB25_DATA2(val) bfin_write16(CAN0_MB25_DATA2, val) +#define bfin_read_CAN0_MB25_DATA3() bfin_read16(CAN0_MB25_DATA3) +#define bfin_write_CAN0_MB25_DATA3(val) bfin_write16(CAN0_MB25_DATA3, val) +#define bfin_read_CAN0_MB25_LENGTH() bfin_read16(CAN0_MB25_LENGTH) +#define bfin_write_CAN0_MB25_LENGTH(val) bfin_write16(CAN0_MB25_LENGTH, val) +#define bfin_read_CAN0_MB25_TIMESTAMP() bfin_read16(CAN0_MB25_TIMESTAMP) +#define bfin_write_CAN0_MB25_TIMESTAMP(val) bfin_write16(CAN0_MB25_TIMESTAMP, val) +#define bfin_read_CAN0_MB25_ID0() bfin_read16(CAN0_MB25_ID0) +#define bfin_write_CAN0_MB25_ID0(val) bfin_write16(CAN0_MB25_ID0, val) +#define bfin_read_CAN0_MB25_ID1() bfin_read16(CAN0_MB25_ID1) +#define bfin_write_CAN0_MB25_ID1(val) bfin_write16(CAN0_MB25_ID1, val) +#define bfin_read_CAN0_MB26_DATA0() bfin_read16(CAN0_MB26_DATA0) +#define bfin_write_CAN0_MB26_DATA0(val) bfin_write16(CAN0_MB26_DATA0, val) +#define bfin_read_CAN0_MB26_DATA1() bfin_read16(CAN0_MB26_DATA1) +#define bfin_write_CAN0_MB26_DATA1(val) bfin_write16(CAN0_MB26_DATA1, val) +#define bfin_read_CAN0_MB26_DATA2() bfin_read16(CAN0_MB26_DATA2) +#define bfin_write_CAN0_MB26_DATA2(val) bfin_write16(CAN0_MB26_DATA2, val) +#define bfin_read_CAN0_MB26_DATA3() bfin_read16(CAN0_MB26_DATA3) +#define bfin_write_CAN0_MB26_DATA3(val) bfin_write16(CAN0_MB26_DATA3, val) +#define bfin_read_CAN0_MB26_LENGTH() bfin_read16(CAN0_MB26_LENGTH) +#define bfin_write_CAN0_MB26_LENGTH(val) bfin_write16(CAN0_MB26_LENGTH, val) +#define bfin_read_CAN0_MB26_TIMESTAMP() bfin_read16(CAN0_MB26_TIMESTAMP) +#define bfin_write_CAN0_MB26_TIMESTAMP(val) bfin_write16(CAN0_MB26_TIMESTAMP, val) +#define bfin_read_CAN0_MB26_ID0() bfin_read16(CAN0_MB26_ID0) +#define bfin_write_CAN0_MB26_ID0(val) bfin_write16(CAN0_MB26_ID0, val) +#define bfin_read_CAN0_MB26_ID1() bfin_read16(CAN0_MB26_ID1) +#define bfin_write_CAN0_MB26_ID1(val) bfin_write16(CAN0_MB26_ID1, val) +#define bfin_read_CAN0_MB27_DATA0() bfin_read16(CAN0_MB27_DATA0) +#define bfin_write_CAN0_MB27_DATA0(val) bfin_write16(CAN0_MB27_DATA0, val) +#define bfin_read_CAN0_MB27_DATA1() bfin_read16(CAN0_MB27_DATA1) +#define bfin_write_CAN0_MB27_DATA1(val) bfin_write16(CAN0_MB27_DATA1, val) +#define bfin_read_CAN0_MB27_DATA2() bfin_read16(CAN0_MB27_DATA2) +#define bfin_write_CAN0_MB27_DATA2(val) bfin_write16(CAN0_MB27_DATA2, val) +#define bfin_read_CAN0_MB27_DATA3() bfin_read16(CAN0_MB27_DATA3) +#define bfin_write_CAN0_MB27_DATA3(val) bfin_write16(CAN0_MB27_DATA3, val) +#define bfin_read_CAN0_MB27_LENGTH() bfin_read16(CAN0_MB27_LENGTH) +#define bfin_write_CAN0_MB27_LENGTH(val) bfin_write16(CAN0_MB27_LENGTH, val) +#define bfin_read_CAN0_MB27_TIMESTAMP() bfin_read16(CAN0_MB27_TIMESTAMP) +#define bfin_write_CAN0_MB27_TIMESTAMP(val) bfin_write16(CAN0_MB27_TIMESTAMP, val) +#define bfin_read_CAN0_MB27_ID0() bfin_read16(CAN0_MB27_ID0) +#define bfin_write_CAN0_MB27_ID0(val) bfin_write16(CAN0_MB27_ID0, val) +#define bfin_read_CAN0_MB27_ID1() bfin_read16(CAN0_MB27_ID1) +#define bfin_write_CAN0_MB27_ID1(val) bfin_write16(CAN0_MB27_ID1, val) +#define bfin_read_CAN0_MB28_DATA0() bfin_read16(CAN0_MB28_DATA0) +#define bfin_write_CAN0_MB28_DATA0(val) bfin_write16(CAN0_MB28_DATA0, val) +#define bfin_read_CAN0_MB28_DATA1() bfin_read16(CAN0_MB28_DATA1) +#define bfin_write_CAN0_MB28_DATA1(val) bfin_write16(CAN0_MB28_DATA1, val) +#define bfin_read_CAN0_MB28_DATA2() bfin_read16(CAN0_MB28_DATA2) +#define bfin_write_CAN0_MB28_DATA2(val) bfin_write16(CAN0_MB28_DATA2, val) +#define bfin_read_CAN0_MB28_DATA3() bfin_read16(CAN0_MB28_DATA3) +#define bfin_write_CAN0_MB28_DATA3(val) bfin_write16(CAN0_MB28_DATA3, val) +#define bfin_read_CAN0_MB28_LENGTH() bfin_read16(CAN0_MB28_LENGTH) +#define bfin_write_CAN0_MB28_LENGTH(val) bfin_write16(CAN0_MB28_LENGTH, val) +#define bfin_read_CAN0_MB28_TIMESTAMP() bfin_read16(CAN0_MB28_TIMESTAMP) +#define bfin_write_CAN0_MB28_TIMESTAMP(val) bfin_write16(CAN0_MB28_TIMESTAMP, val) +#define bfin_read_CAN0_MB28_ID0() bfin_read16(CAN0_MB28_ID0) +#define bfin_write_CAN0_MB28_ID0(val) bfin_write16(CAN0_MB28_ID0, val) +#define bfin_read_CAN0_MB28_ID1() bfin_read16(CAN0_MB28_ID1) +#define bfin_write_CAN0_MB28_ID1(val) bfin_write16(CAN0_MB28_ID1, val) +#define bfin_read_CAN0_MB29_DATA0() bfin_read16(CAN0_MB29_DATA0) +#define bfin_write_CAN0_MB29_DATA0(val) bfin_write16(CAN0_MB29_DATA0, val) +#define bfin_read_CAN0_MB29_DATA1() bfin_read16(CAN0_MB29_DATA1) +#define bfin_write_CAN0_MB29_DATA1(val) bfin_write16(CAN0_MB29_DATA1, val) +#define bfin_read_CAN0_MB29_DATA2() bfin_read16(CAN0_MB29_DATA2) +#define bfin_write_CAN0_MB29_DATA2(val) bfin_write16(CAN0_MB29_DATA2, val) +#define bfin_read_CAN0_MB29_DATA3() bfin_read16(CAN0_MB29_DATA3) +#define bfin_write_CAN0_MB29_DATA3(val) bfin_write16(CAN0_MB29_DATA3, val) +#define bfin_read_CAN0_MB29_LENGTH() bfin_read16(CAN0_MB29_LENGTH) +#define bfin_write_CAN0_MB29_LENGTH(val) bfin_write16(CAN0_MB29_LENGTH, val) +#define bfin_read_CAN0_MB29_TIMESTAMP() bfin_read16(CAN0_MB29_TIMESTAMP) +#define bfin_write_CAN0_MB29_TIMESTAMP(val) bfin_write16(CAN0_MB29_TIMESTAMP, val) +#define bfin_read_CAN0_MB29_ID0() bfin_read16(CAN0_MB29_ID0) +#define bfin_write_CAN0_MB29_ID0(val) bfin_write16(CAN0_MB29_ID0, val) +#define bfin_read_CAN0_MB29_ID1() bfin_read16(CAN0_MB29_ID1) +#define bfin_write_CAN0_MB29_ID1(val) bfin_write16(CAN0_MB29_ID1, val) +#define bfin_read_CAN0_MB30_DATA0() bfin_read16(CAN0_MB30_DATA0) +#define bfin_write_CAN0_MB30_DATA0(val) bfin_write16(CAN0_MB30_DATA0, val) +#define bfin_read_CAN0_MB30_DATA1() bfin_read16(CAN0_MB30_DATA1) +#define bfin_write_CAN0_MB30_DATA1(val) bfin_write16(CAN0_MB30_DATA1, val) +#define bfin_read_CAN0_MB30_DATA2() bfin_read16(CAN0_MB30_DATA2) +#define bfin_write_CAN0_MB30_DATA2(val) bfin_write16(CAN0_MB30_DATA2, val) +#define bfin_read_CAN0_MB30_DATA3() bfin_read16(CAN0_MB30_DATA3) +#define bfin_write_CAN0_MB30_DATA3(val) bfin_write16(CAN0_MB30_DATA3, val) +#define bfin_read_CAN0_MB30_LENGTH() bfin_read16(CAN0_MB30_LENGTH) +#define bfin_write_CAN0_MB30_LENGTH(val) bfin_write16(CAN0_MB30_LENGTH, val) +#define bfin_read_CAN0_MB30_TIMESTAMP() bfin_read16(CAN0_MB30_TIMESTAMP) +#define bfin_write_CAN0_MB30_TIMESTAMP(val) bfin_write16(CAN0_MB30_TIMESTAMP, val) +#define bfin_read_CAN0_MB30_ID0() bfin_read16(CAN0_MB30_ID0) +#define bfin_write_CAN0_MB30_ID0(val) bfin_write16(CAN0_MB30_ID0, val) +#define bfin_read_CAN0_MB30_ID1() bfin_read16(CAN0_MB30_ID1) +#define bfin_write_CAN0_MB30_ID1(val) bfin_write16(CAN0_MB30_ID1, val) +#define bfin_read_CAN0_MB31_DATA0() bfin_read16(CAN0_MB31_DATA0) +#define bfin_write_CAN0_MB31_DATA0(val) bfin_write16(CAN0_MB31_DATA0, val) +#define bfin_read_CAN0_MB31_DATA1() bfin_read16(CAN0_MB31_DATA1) +#define bfin_write_CAN0_MB31_DATA1(val) bfin_write16(CAN0_MB31_DATA1, val) +#define bfin_read_CAN0_MB31_DATA2() bfin_read16(CAN0_MB31_DATA2) +#define bfin_write_CAN0_MB31_DATA2(val) bfin_write16(CAN0_MB31_DATA2, val) +#define bfin_read_CAN0_MB31_DATA3() bfin_read16(CAN0_MB31_DATA3) +#define bfin_write_CAN0_MB31_DATA3(val) bfin_write16(CAN0_MB31_DATA3, val) +#define bfin_read_CAN0_MB31_LENGTH() bfin_read16(CAN0_MB31_LENGTH) +#define bfin_write_CAN0_MB31_LENGTH(val) bfin_write16(CAN0_MB31_LENGTH, val) +#define bfin_read_CAN0_MB31_TIMESTAMP() bfin_read16(CAN0_MB31_TIMESTAMP) +#define bfin_write_CAN0_MB31_TIMESTAMP(val) bfin_write16(CAN0_MB31_TIMESTAMP, val) +#define bfin_read_CAN0_MB31_ID0() bfin_read16(CAN0_MB31_ID0) +#define bfin_write_CAN0_MB31_ID0(val) bfin_write16(CAN0_MB31_ID0, val) +#define bfin_read_CAN0_MB31_ID1() bfin_read16(CAN0_MB31_ID1) +#define bfin_write_CAN0_MB31_ID1(val) bfin_write16(CAN0_MB31_ID1, val) + +/* Counter Registers */ + +#define bfin_read_CNT_CONFIG() bfin_read16(CNT_CONFIG) +#define bfin_write_CNT_CONFIG(val) bfin_write16(CNT_CONFIG, val) +#define bfin_read_CNT_IMASK() bfin_read16(CNT_IMASK) +#define bfin_write_CNT_IMASK(val) bfin_write16(CNT_IMASK, val) +#define bfin_read_CNT_STATUS() bfin_read16(CNT_STATUS) +#define bfin_write_CNT_STATUS(val) bfin_write16(CNT_STATUS, val) +#define bfin_read_CNT_COMMAND() bfin_read16(CNT_COMMAND) +#define bfin_write_CNT_COMMAND(val) bfin_write16(CNT_COMMAND, val) +#define bfin_read_CNT_DEBOUNCE() bfin_read16(CNT_DEBOUNCE) +#define bfin_write_CNT_DEBOUNCE(val) bfin_write16(CNT_DEBOUNCE, val) +#define bfin_read_CNT_COUNTER() bfin_read32(CNT_COUNTER) +#define bfin_write_CNT_COUNTER(val) bfin_write32(CNT_COUNTER, val) +#define bfin_read_CNT_MAX() bfin_read32(CNT_MAX) +#define bfin_write_CNT_MAX(val) bfin_write32(CNT_MAX, val) +#define bfin_read_CNT_MIN() bfin_read32(CNT_MIN) +#define bfin_write_CNT_MIN(val) bfin_write32(CNT_MIN, val) + +/* RSI Register */ +#define bfin_read_RSI_CLK_CTL() bfin_read16(RSI_CLK_CONTROL) +#define bfin_write_RSI_CLK_CTL(val) bfin_write16(RSI_CLK_CONTROL, val) +#define bfin_read_RSI_ARGUMENT() bfin_read32(RSI_ARGUMENT) +#define bfin_write_RSI_ARGUMENT(val) bfin_write32(RSI_ARGUMENT, val) +#define bfin_read_RSI_COMMAND() bfin_read16(RSI_COMMAND) +#define bfin_write_RSI_COMMAND(val) bfin_write16(RSI_COMMAND, val) +#define bfin_read_RSI_RESP_CMD() bfin_read16(RSI_RESP_CMD) +#define bfin_write_RSI_RESP_CMD(val) bfin_write16(RSI_RESP_CMD, val) +#define bfin_read_RSI_RESPONSE0() bfin_read32(RSI_RESPONSE0) +#define bfin_write_RSI_RESPONSE0(val) bfin_write32(RSI_RESPONSE0, val) +#define bfin_read_RSI_RESPONSE1() bfin_read32(RSI_RESPONSE1) +#define bfin_write_RSI_RESPONSE1(val) bfin_write32(RSI_RESPONSE1, val) +#define bfin_read_RSI_RESPONSE2() bfin_read32(RSI_RESPONSE2) +#define bfin_write_RSI_RESPONSE2(val) bfin_write32(RSI_RESPONSE2, val) +#define bfin_read_RSI_RESPONSE3() bfin_read32(RSI_RESPONSE3) +#define bfin_write_RSI_RESPONSE3(val) bfin_write32(RSI_RESPONSE3, val) +#define bfin_read_RSI_DATA_TIMER() bfin_read32(RSI_DATA_TIMER) +#define bfin_write_RSI_DATA_TIMER(val) bfin_write32(RSI_DATA_TIMER, val) +#define bfin_read_RSI_DATA_LGTH() bfin_read16(RSI_DATA_LGTH) +#define bfin_write_RSI_DATA_LGTH(val) bfin_write16(RSI_DATA_LGTH, val) +#define bfin_read_RSI_DATA_CTL() bfin_read16(RSI_DATA_CONTROL) +#define bfin_write_RSI_DATA_CTL(val) bfin_write16(RSI_DATA_CONTROL, val) +#define bfin_read_RSI_DATA_CNT() bfin_read16(RSI_DATA_CNT) +#define bfin_write_RSI_DATA_CNT(val) bfin_write16(RSI_DATA_CNT, val) +#define bfin_read_RSI_STATUS() bfin_read32(RSI_STATUS) +#define bfin_write_RSI_STATUS(val) bfin_write32(RSI_STATUS, val) +#define bfin_read_RSI_STATUS_CLR() bfin_read16(RSI_STATUSCL) +#define bfin_write_RSI_STATUS_CLR(val) bfin_write16(RSI_STATUSCL, val) +#define bfin_read_RSI_MASK0() bfin_read32(RSI_MASK0) +#define bfin_write_RSI_MASK0(val) bfin_write32(RSI_MASK0, val) +#define bfin_read_RSI_MASK1() bfin_read32(RSI_MASK1) +#define bfin_write_RSI_MASK1(val) bfin_write32(RSI_MASK1, val) +#define bfin_read_RSI_FIFO_CNT() bfin_read16(RSI_FIFO_CNT) +#define bfin_write_RSI_FIFO_CNT(val) bfin_write16(RSI_FIFO_CNT, val) +#define bfin_read_RSI_CEATA_CONTROL() bfin_read16(RSI_CEATA_CONTROL) +#define bfin_write_RSI_CEATA_CONTROL(val) bfin_write16(RSI_CEATA_CONTROL, val) +#define bfin_read_RSI_BLKSZ() bfin_read16(RSI_BLKSZ) +#define bfin_write_RSI_BLKSZ(val) bfin_write16(RSI_BLKSZ, val) +#define bfin_read_RSI_FIFO() bfin_read32(RSI_FIFO) +#define bfin_write_RSI_FIFO(val) bfin_write32(RSI_FIFO, val) +#define bfin_read_RSI_E_STATUS() bfin_read32(RSI_ESTAT) +#define bfin_write_RSI_E_STATUS(val) bfin_write32(RSI_ESTAT, val) +#define bfin_read_RSI_E_MASK() bfin_read32(RSI_EMASK) +#define bfin_write_RSI_E_MASK(val) bfin_write32(RSI_EMASK, val) +#define bfin_read_RSI_CFG() bfin_read16(RSI_CONFIG) +#define bfin_write_RSI_CFG(val) bfin_write16(RSI_CONFIG, val) +#define bfin_read_RSI_RD_WAIT_EN() bfin_read16(RSI_RD_WAIT_EN) +#define bfin_write_RSI_RD_WAIT_EN(val) bfin_write16(RSI_RD_WAIT_EN, val) +#define bfin_read_RSI_PID0() bfin_read16(RSI_PID0) +#define bfin_write_RSI_PID0(val) bfin_write16(RSI_PID0, val) +#define bfin_read_RSI_PID1() bfin_read16(RSI_PID1) +#define bfin_write_RSI_PID1(val) bfin_write16(RSI_PID1, val) +#define bfin_read_RSI_PID2() bfin_read16(RSI_PID2) +#define bfin_write_RSI_PID2(val) bfin_write16(RSI_PID2, val) +#define bfin_read_RSI_PID3() bfin_read16(RSI_PID3) +#define bfin_write_RSI_PID3(val) bfin_write16(RSI_PID3, val) + +/* usb register */ +#define bfin_read_USB_PLLOSC_CTRL() bfin_read16(USB_PLL_OSC) +#define bfin_write_USB_PLLOSC_CTRL(val) bfin_write16(USB_PLL_OSC, val) +#define bfin_write_USB_VBUS_CTL(val) bfin_write8(USB_VBUS_CTL, val) +#define bfin_write_USB_APHY_CNTRL(val) bfin_write8(USB_PHY_CTL, val) +#define bfin_read_USB_APHY_CNTRL() bfin_read8(USB_PHY_CTL) + +#endif /* _CDEF_BF60X_H */ +
diff --git a/arch/blackfin/mach-bf609/include/mach/defBF609.h b/arch/blackfin/mach-bf609/include/mach/defBF609.h new file mode 100644 index 0000000..19690cc --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/defBF609.h
@@ -0,0 +1,15 @@ +/* + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the Clear BSD license or the GPL-2 (or later) + */ + +#ifndef _DEF_BF609_H +#define _DEF_BF609_H + +/* Include defBF60x_base.h for the set of #defines that are common to all ADSP-BF60x processors */ +#include "defBF60x_base.h" + +/* The following are the #defines needed by ADSP-BF609 that are not in the common header */ + +#endif /* _DEF_BF609_H */
diff --git a/arch/blackfin/mach-bf609/include/mach/defBF60x_base.h b/arch/blackfin/mach-bf609/include/mach/defBF60x_base.h new file mode 100644 index 0000000..6aac385 --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/defBF60x_base.h
@@ -0,0 +1,3587 @@ +/* + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the Clear BSD license or the GPL-2 (or later) + */ + +#ifndef _DEF_BF60X_H +#define _DEF_BF60X_H + + +/* ************************************************************** */ +/* SYSTEM & MMR ADDRESS DEFINITIONS COMMON TO ALL ADSP-BF60x */ +/* ************************************************************** */ + + +/* ========================= + CNT Registers + ========================= */ + +/* ========================= + CNT0 + ========================= */ +#define CNT_CONFIG 0xFFC00400 /* CNT0 Configuration Register */ +#define CNT_IMASK 0xFFC00404 /* CNT0 Interrupt Mask Register */ +#define CNT_STATUS 0xFFC00408 /* CNT0 Status Register */ +#define CNT_COMMAND 0xFFC0040C /* CNT0 Command Register */ +#define CNT_DEBOUNCE 0xFFC00410 /* CNT0 Debounce Register */ +#define CNT_COUNTER 0xFFC00414 /* CNT0 Counter Register */ +#define CNT_MAX 0xFFC00418 /* CNT0 Maximum Count Register */ +#define CNT_MIN 0xFFC0041C /* CNT0 Minimum Count Register */ + + +/* ========================= + RSI Registers + ========================= */ + +#define RSI_CLK_CONTROL 0xFFC00604 /* RSI0 Clock Control Register */ +#define RSI_ARGUMENT 0xFFC00608 /* RSI0 Argument Register */ +#define RSI_COMMAND 0xFFC0060C /* RSI0 Command Register */ +#define RSI_RESP_CMD 0xFFC00610 /* RSI0 Response Command Register */ +#define RSI_RESPONSE0 0xFFC00614 /* RSI0 Response 0 Register */ +#define RSI_RESPONSE1 0xFFC00618 /* RSI0 Response 1 Register */ +#define RSI_RESPONSE2 0xFFC0061C /* RSI0 Response 2 Register */ +#define RSI_RESPONSE3 0xFFC00620 /* RSI0 Response 3 Register */ +#define RSI_DATA_TIMER 0xFFC00624 /* RSI0 Data Timer Register */ +#define RSI_DATA_LGTH 0xFFC00628 /* RSI0 Data Length Register */ +#define RSI_DATA_CONTROL 0xFFC0062C /* RSI0 Data Control Register */ +#define RSI_DATA_CNT 0xFFC00630 /* RSI0 Data Count Register */ +#define RSI_STATUS 0xFFC00634 /* RSI0 Status Register */ +#define RSI_STATUSCL 0xFFC00638 /* RSI0 Status Clear Register */ +#define RSI_MASK0 0xFFC0063C /* RSI0 Interrupt 0 Mask Register */ +#define RSI_MASK1 0xFFC00640 /* RSI0 Interrupt 1 Mask Register */ +#define RSI_FIFO_CNT 0xFFC00648 /* RSI0 FIFO Counter Register */ +#define RSI_CEATA_CONTROL 0xFFC0064C /* RSI0 This register contains bit to dis CCS gen */ +#define RSI_BOOT_TCNTR 0xFFC00650 /* RSI0 Boot Timing Counter Register */ +#define RSI_BACK_TOUT 0xFFC00654 /* RSI0 Boot Acknowledge Timeout Register */ +#define RSI_SLP_WKUP_TOUT 0xFFC00658 /* RSI0 Sleep Wakeup Timeout Register */ +#define RSI_BLKSZ 0xFFC0065C /* RSI0 Block Size Register */ +#define RSI_FIFO 0xFFC00680 /* RSI0 Data FIFO Register */ +#define RSI_ESTAT 0xFFC006C0 /* RSI0 Exception Status Register */ +#define RSI_EMASK 0xFFC006C4 /* RSI0 Exception Mask Register */ +#define RSI_CONFIG 0xFFC006C8 /* RSI0 Configuration Register */ +#define RSI_RD_WAIT_EN 0xFFC006CC /* RSI0 Read Wait Enable Register */ +#define RSI_PID0 0xFFC006D0 /* RSI0 Peripheral Identification Register */ +#define RSI_PID1 0xFFC006D4 /* RSI0 Peripheral Identification Register */ +#define RSI_PID2 0xFFC006D8 /* RSI0 Peripheral Identification Register */ +#define RSI_PID3 0xFFC006DC /* RSI0 Peripheral Identification Register */ + +/* ========================= + CAN Registers + ========================= */ + +/* ========================= + CAN0 + ========================= */ +#define CAN0_MC1 0xFFC00A00 /* CAN0 Mailbox Configuration Register 1 */ +#define CAN0_MD1 0xFFC00A04 /* CAN0 Mailbox Direction Register 1 */ +#define CAN0_TRS1 0xFFC00A08 /* CAN0 Transmission Request Set Register 1 */ +#define CAN0_TRR1 0xFFC00A0C /* CAN0 Transmission Request Reset Register 1 */ +#define CAN0_TA1 0xFFC00A10 /* CAN0 Transmission Acknowledge Register 1 */ +#define CAN0_AA1 0xFFC00A14 /* CAN0 Abort Acknowledge Register 1 */ +#define CAN0_RMP1 0xFFC00A18 /* CAN0 Receive Message Pending Register 1 */ +#define CAN0_RML1 0xFFC00A1C /* CAN0 Receive Message Lost Register 1 */ +#define CAN0_MBTIF1 0xFFC00A20 /* CAN0 Mailbox Transmit Interrupt Flag Register 1 */ +#define CAN0_MBRIF1 0xFFC00A24 /* CAN0 Mailbox Receive Interrupt Flag Register 1 */ +#define CAN0_MBIM1 0xFFC00A28 /* CAN0 Mailbox Interrupt Mask Register 1 */ +#define CAN0_RFH1 0xFFC00A2C /* CAN0 Remote Frame Handling Register 1 */ +#define CAN0_OPSS1 0xFFC00A30 /* CAN0 Overwrite Protection/Single Shot Transmission Register 1 */ +#define CAN0_MC2 0xFFC00A40 /* CAN0 Mailbox Configuration Register 2 */ +#define CAN0_MD2 0xFFC00A44 /* CAN0 Mailbox Direction Register 2 */ +#define CAN0_TRS2 0xFFC00A48 /* CAN0 Transmission Request Set Register 2 */ +#define CAN0_TRR2 0xFFC00A4C /* CAN0 Transmission Request Reset Register 2 */ +#define CAN0_TA2 0xFFC00A50 /* CAN0 Transmission Acknowledge Register 2 */ +#define CAN0_AA2 0xFFC00A54 /* CAN0 Abort Acknowledge Register 2 */ +#define CAN0_RMP2 0xFFC00A58 /* CAN0 Receive Message Pending Register 2 */ +#define CAN0_RML2 0xFFC00A5C /* CAN0 Receive Message Lost Register 2 */ +#define CAN0_MBTIF2 0xFFC00A60 /* CAN0 Mailbox Transmit Interrupt Flag Register 2 */ +#define CAN0_MBRIF2 0xFFC00A64 /* CAN0 Mailbox Receive Interrupt Flag Register 2 */ +#define CAN0_MBIM2 0xFFC00A68 /* CAN0 Mailbox Interrupt Mask Register 2 */ +#define CAN0_RFH2 0xFFC00A6C /* CAN0 Remote Frame Handling Register 2 */ +#define CAN0_OPSS2 0xFFC00A70 /* CAN0 Overwrite Protection/Single Shot Transmission Register 2 */ +#define CAN0_CLOCK 0xFFC00A80 /* CAN0 Clock Register */ +#define CAN0_TIMING 0xFFC00A84 /* CAN0 Timing Register */ +#define CAN0_DEBUG 0xFFC00A88 /* CAN0 Debug Register */ +#define CAN0_STATUS 0xFFC00A8C /* CAN0 Status Register */ +#define CAN0_CEC 0xFFC00A90 /* CAN0 Error Counter Register */ +#define CAN0_GIS 0xFFC00A94 /* CAN0 Global CAN Interrupt Status */ +#define CAN0_GIM 0xFFC00A98 /* CAN0 Global CAN Interrupt Mask */ +#define CAN0_GIF 0xFFC00A9C /* CAN0 Global CAN Interrupt Flag */ +#define CAN0_CONTROL 0xFFC00AA0 /* CAN0 CAN Master Control Register */ +#define CAN0_INTR 0xFFC00AA4 /* CAN0 Interrupt Pending Register */ +#define CAN0_MBTD 0xFFC00AAC /* CAN0 Temporary Mailbox Disable Register */ +#define CAN0_EWR 0xFFC00AB0 /* CAN0 Error Counter Warning Level Register */ +#define CAN0_ESR 0xFFC00AB4 /* CAN0 Error Status Register */ +#define CAN0_UCCNT 0xFFC00AC4 /* CAN0 Universal Counter Register */ +#define CAN0_UCRC 0xFFC00AC8 /* CAN0 Universal Counter Reload/Capture Register */ +#define CAN0_UCCNF 0xFFC00ACC /* CAN0 Universal Counter Configuration Mode Register */ +#define CAN0_AM00L 0xFFC00B00 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM01L 0xFFC00B08 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM02L 0xFFC00B10 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM03L 0xFFC00B18 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM04L 0xFFC00B20 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM05L 0xFFC00B28 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM06L 0xFFC00B30 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM07L 0xFFC00B38 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM08L 0xFFC00B40 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM09L 0xFFC00B48 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM10L 0xFFC00B50 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM11L 0xFFC00B58 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM12L 0xFFC00B60 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM13L 0xFFC00B68 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM14L 0xFFC00B70 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM15L 0xFFC00B78 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM16L 0xFFC00B80 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM17L 0xFFC00B88 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM18L 0xFFC00B90 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM19L 0xFFC00B98 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM20L 0xFFC00BA0 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM21L 0xFFC00BA8 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM22L 0xFFC00BB0 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM23L 0xFFC00BB8 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM24L 0xFFC00BC0 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM25L 0xFFC00BC8 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM26L 0xFFC00BD0 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM27L 0xFFC00BD8 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM28L 0xFFC00BE0 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM29L 0xFFC00BE8 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM30L 0xFFC00BF0 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM31L 0xFFC00BF8 /* CAN0 Acceptance Mask Register (L) */ +#define CAN0_AM00H 0xFFC00B04 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM01H 0xFFC00B0C /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM02H 0xFFC00B14 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM03H 0xFFC00B1C /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM04H 0xFFC00B24 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM05H 0xFFC00B2C /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM06H 0xFFC00B34 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM07H 0xFFC00B3C /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM08H 0xFFC00B44 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM09H 0xFFC00B4C /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM10H 0xFFC00B54 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM11H 0xFFC00B5C /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM12H 0xFFC00B64 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM13H 0xFFC00B6C /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM14H 0xFFC00B74 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM15H 0xFFC00B7C /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM16H 0xFFC00B84 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM17H 0xFFC00B8C /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM18H 0xFFC00B94 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM19H 0xFFC00B9C /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM20H 0xFFC00BA4 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM21H 0xFFC00BAC /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM22H 0xFFC00BB4 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM23H 0xFFC00BBC /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM24H 0xFFC00BC4 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM25H 0xFFC00BCC /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM26H 0xFFC00BD4 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM27H 0xFFC00BDC /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM28H 0xFFC00BE4 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM29H 0xFFC00BEC /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM30H 0xFFC00BF4 /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_AM31H 0xFFC00BFC /* CAN0 Acceptance Mask Register (H) */ +#define CAN0_MB00_DATA0 0xFFC00C00 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB01_DATA0 0xFFC00C20 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB02_DATA0 0xFFC00C40 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB03_DATA0 0xFFC00C60 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB04_DATA0 0xFFC00C80 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB05_DATA0 0xFFC00CA0 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB06_DATA0 0xFFC00CC0 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB07_DATA0 0xFFC00CE0 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB08_DATA0 0xFFC00D00 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB09_DATA0 0xFFC00D20 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB10_DATA0 0xFFC00D40 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB11_DATA0 0xFFC00D60 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB12_DATA0 0xFFC00D80 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB13_DATA0 0xFFC00DA0 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB14_DATA0 0xFFC00DC0 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB15_DATA0 0xFFC00DE0 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB16_DATA0 0xFFC00E00 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB17_DATA0 0xFFC00E20 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB18_DATA0 0xFFC00E40 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB19_DATA0 0xFFC00E60 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB20_DATA0 0xFFC00E80 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB21_DATA0 0xFFC00EA0 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB22_DATA0 0xFFC00EC0 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB23_DATA0 0xFFC00EE0 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB24_DATA0 0xFFC00F00 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB25_DATA0 0xFFC00F20 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB26_DATA0 0xFFC00F40 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB27_DATA0 0xFFC00F60 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB28_DATA0 0xFFC00F80 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB29_DATA0 0xFFC00FA0 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB30_DATA0 0xFFC00FC0 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB31_DATA0 0xFFC00FE0 /* CAN0 Mailbox Word 0 Register */ +#define CAN0_MB00_DATA1 0xFFC00C04 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB01_DATA1 0xFFC00C24 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB02_DATA1 0xFFC00C44 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB03_DATA1 0xFFC00C64 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB04_DATA1 0xFFC00C84 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB05_DATA1 0xFFC00CA4 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB06_DATA1 0xFFC00CC4 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB07_DATA1 0xFFC00CE4 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB08_DATA1 0xFFC00D04 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB09_DATA1 0xFFC00D24 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB10_DATA1 0xFFC00D44 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB11_DATA1 0xFFC00D64 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB12_DATA1 0xFFC00D84 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB13_DATA1 0xFFC00DA4 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB14_DATA1 0xFFC00DC4 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB15_DATA1 0xFFC00DE4 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB16_DATA1 0xFFC00E04 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB17_DATA1 0xFFC00E24 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB18_DATA1 0xFFC00E44 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB19_DATA1 0xFFC00E64 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB20_DATA1 0xFFC00E84 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB21_DATA1 0xFFC00EA4 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB22_DATA1 0xFFC00EC4 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB23_DATA1 0xFFC00EE4 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB24_DATA1 0xFFC00F04 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB25_DATA1 0xFFC00F24 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB26_DATA1 0xFFC00F44 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB27_DATA1 0xFFC00F64 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB28_DATA1 0xFFC00F84 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB29_DATA1 0xFFC00FA4 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB30_DATA1 0xFFC00FC4 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB31_DATA1 0xFFC00FE4 /* CAN0 Mailbox Word 1 Register */ +#define CAN0_MB00_DATA2 0xFFC00C08 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB01_DATA2 0xFFC00C28 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB02_DATA2 0xFFC00C48 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB03_DATA2 0xFFC00C68 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB04_DATA2 0xFFC00C88 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB05_DATA2 0xFFC00CA8 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB06_DATA2 0xFFC00CC8 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB07_DATA2 0xFFC00CE8 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB08_DATA2 0xFFC00D08 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB09_DATA2 0xFFC00D28 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB10_DATA2 0xFFC00D48 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB11_DATA2 0xFFC00D68 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB12_DATA2 0xFFC00D88 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB13_DATA2 0xFFC00DA8 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB14_DATA2 0xFFC00DC8 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB15_DATA2 0xFFC00DE8 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB16_DATA2 0xFFC00E08 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB17_DATA2 0xFFC00E28 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB18_DATA2 0xFFC00E48 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB19_DATA2 0xFFC00E68 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB20_DATA2 0xFFC00E88 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB21_DATA2 0xFFC00EA8 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB22_DATA2 0xFFC00EC8 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB23_DATA2 0xFFC00EE8 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB24_DATA2 0xFFC00F08 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB25_DATA2 0xFFC00F28 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB26_DATA2 0xFFC00F48 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB27_DATA2 0xFFC00F68 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB28_DATA2 0xFFC00F88 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB29_DATA2 0xFFC00FA8 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB30_DATA2 0xFFC00FC8 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB31_DATA2 0xFFC00FE8 /* CAN0 Mailbox Word 2 Register */ +#define CAN0_MB00_DATA3 0xFFC00C0C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB01_DATA3 0xFFC00C2C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB02_DATA3 0xFFC00C4C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB03_DATA3 0xFFC00C6C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB04_DATA3 0xFFC00C8C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB05_DATA3 0xFFC00CAC /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB06_DATA3 0xFFC00CCC /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB07_DATA3 0xFFC00CEC /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB08_DATA3 0xFFC00D0C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB09_DATA3 0xFFC00D2C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB10_DATA3 0xFFC00D4C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB11_DATA3 0xFFC00D6C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB12_DATA3 0xFFC00D8C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB13_DATA3 0xFFC00DAC /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB14_DATA3 0xFFC00DCC /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB15_DATA3 0xFFC00DEC /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB16_DATA3 0xFFC00E0C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB17_DATA3 0xFFC00E2C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB18_DATA3 0xFFC00E4C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB19_DATA3 0xFFC00E6C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB20_DATA3 0xFFC00E8C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB21_DATA3 0xFFC00EAC /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB22_DATA3 0xFFC00ECC /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB23_DATA3 0xFFC00EEC /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB24_DATA3 0xFFC00F0C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB25_DATA3 0xFFC00F2C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB26_DATA3 0xFFC00F4C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB27_DATA3 0xFFC00F6C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB28_DATA3 0xFFC00F8C /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB29_DATA3 0xFFC00FAC /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB30_DATA3 0xFFC00FCC /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB31_DATA3 0xFFC00FEC /* CAN0 Mailbox Word 3 Register */ +#define CAN0_MB00_LENGTH 0xFFC00C10 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB01_LENGTH 0xFFC00C30 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB02_LENGTH 0xFFC00C50 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB03_LENGTH 0xFFC00C70 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB04_LENGTH 0xFFC00C90 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB05_LENGTH 0xFFC00CB0 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB06_LENGTH 0xFFC00CD0 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB07_LENGTH 0xFFC00CF0 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB08_LENGTH 0xFFC00D10 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB09_LENGTH 0xFFC00D30 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB10_LENGTH 0xFFC00D50 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB11_LENGTH 0xFFC00D70 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB12_LENGTH 0xFFC00D90 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB13_LENGTH 0xFFC00DB0 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB14_LENGTH 0xFFC00DD0 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB15_LENGTH 0xFFC00DF0 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB16_LENGTH 0xFFC00E10 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB17_LENGTH 0xFFC00E30 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB18_LENGTH 0xFFC00E50 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB19_LENGTH 0xFFC00E70 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB20_LENGTH 0xFFC00E90 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB21_LENGTH 0xFFC00EB0 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB22_LENGTH 0xFFC00ED0 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB23_LENGTH 0xFFC00EF0 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB24_LENGTH 0xFFC00F10 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB25_LENGTH 0xFFC00F30 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB26_LENGTH 0xFFC00F50 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB27_LENGTH 0xFFC00F70 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB28_LENGTH 0xFFC00F90 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB29_LENGTH 0xFFC00FB0 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB30_LENGTH 0xFFC00FD0 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB31_LENGTH 0xFFC00FF0 /* CAN0 Mailbox Word 4 Register */ +#define CAN0_MB00_TIMESTAMP 0xFFC00C14 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB01_TIMESTAMP 0xFFC00C34 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB02_TIMESTAMP 0xFFC00C54 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB03_TIMESTAMP 0xFFC00C74 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB04_TIMESTAMP 0xFFC00C94 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB05_TIMESTAMP 0xFFC00CB4 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB06_TIMESTAMP 0xFFC00CD4 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB07_TIMESTAMP 0xFFC00CF4 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB08_TIMESTAMP 0xFFC00D14 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB09_TIMESTAMP 0xFFC00D34 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB10_TIMESTAMP 0xFFC00D54 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB11_TIMESTAMP 0xFFC00D74 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB12_TIMESTAMP 0xFFC00D94 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB13_TIMESTAMP 0xFFC00DB4 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB14_TIMESTAMP 0xFFC00DD4 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB15_TIMESTAMP 0xFFC00DF4 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB16_TIMESTAMP 0xFFC00E14 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB17_TIMESTAMP 0xFFC00E34 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB18_TIMESTAMP 0xFFC00E54 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB19_TIMESTAMP 0xFFC00E74 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB20_TIMESTAMP 0xFFC00E94 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB21_TIMESTAMP 0xFFC00EB4 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB22_TIMESTAMP 0xFFC00ED4 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB23_TIMESTAMP 0xFFC00EF4 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB24_TIMESTAMP 0xFFC00F14 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB25_TIMESTAMP 0xFFC00F34 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB26_TIMESTAMP 0xFFC00F54 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB27_TIMESTAMP 0xFFC00F74 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB28_TIMESTAMP 0xFFC00F94 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB29_TIMESTAMP 0xFFC00FB4 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB30_TIMESTAMP 0xFFC00FD4 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB31_TIMESTAMP 0xFFC00FF4 /* CAN0 Mailbox Word 5 Register */ +#define CAN0_MB00_ID0 0xFFC00C18 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB01_ID0 0xFFC00C38 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB02_ID0 0xFFC00C58 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB03_ID0 0xFFC00C78 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB04_ID0 0xFFC00C98 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB05_ID0 0xFFC00CB8 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB06_ID0 0xFFC00CD8 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB07_ID0 0xFFC00CF8 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB08_ID0 0xFFC00D18 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB09_ID0 0xFFC00D38 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB10_ID0 0xFFC00D58 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB11_ID0 0xFFC00D78 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB12_ID0 0xFFC00D98 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB13_ID0 0xFFC00DB8 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB14_ID0 0xFFC00DD8 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB15_ID0 0xFFC00DF8 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB16_ID0 0xFFC00E18 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB17_ID0 0xFFC00E38 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB18_ID0 0xFFC00E58 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB19_ID0 0xFFC00E78 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB20_ID0 0xFFC00E98 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB21_ID0 0xFFC00EB8 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB22_ID0 0xFFC00ED8 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB23_ID0 0xFFC00EF8 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB24_ID0 0xFFC00F18 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB25_ID0 0xFFC00F38 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB26_ID0 0xFFC00F58 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB27_ID0 0xFFC00F78 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB28_ID0 0xFFC00F98 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB29_ID0 0xFFC00FB8 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB30_ID0 0xFFC00FD8 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB31_ID0 0xFFC00FF8 /* CAN0 Mailbox Word 6 Register */ +#define CAN0_MB00_ID1 0xFFC00C1C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB01_ID1 0xFFC00C3C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB02_ID1 0xFFC00C5C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB03_ID1 0xFFC00C7C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB04_ID1 0xFFC00C9C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB05_ID1 0xFFC00CBC /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB06_ID1 0xFFC00CDC /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB07_ID1 0xFFC00CFC /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB08_ID1 0xFFC00D1C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB09_ID1 0xFFC00D3C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB10_ID1 0xFFC00D5C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB11_ID1 0xFFC00D7C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB12_ID1 0xFFC00D9C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB13_ID1 0xFFC00DBC /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB14_ID1 0xFFC00DDC /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB15_ID1 0xFFC00DFC /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB16_ID1 0xFFC00E1C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB17_ID1 0xFFC00E3C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB18_ID1 0xFFC00E5C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB19_ID1 0xFFC00E7C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB20_ID1 0xFFC00E9C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB21_ID1 0xFFC00EBC /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB22_ID1 0xFFC00EDC /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB23_ID1 0xFFC00EFC /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB24_ID1 0xFFC00F1C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB25_ID1 0xFFC00F3C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB26_ID1 0xFFC00F5C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB27_ID1 0xFFC00F7C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB28_ID1 0xFFC00F9C /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB29_ID1 0xFFC00FBC /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB30_ID1 0xFFC00FDC /* CAN0 Mailbox Word 7 Register */ +#define CAN0_MB31_ID1 0xFFC00FFC /* CAN0 Mailbox Word 7 Register */ + +/* ========================= + LINK PORT Registers + ========================= */ +#define LP0_CTL 0xFFC01000 /* LP0 Control Register */ +#define LP0_STAT 0xFFC01004 /* LP0 Status Register */ +#define LP0_DIV 0xFFC01008 /* LP0 Clock Divider Value */ +#define LP0_CNT 0xFFC0100C /* LP0 Current Count Value of Clock Divider */ +#define LP0_TX 0xFFC01010 /* LP0 Transmit Buffer */ +#define LP0_RX 0xFFC01014 /* LP0 Receive Buffer */ +#define LP0_TXIN_SHDW 0xFFC01018 /* LP0 Shadow Input Transmit Buffer */ +#define LP0_TXOUT_SHDW 0xFFC0101C /* LP0 Shadow Output Transmit Buffer */ +#define LP1_CTL 0xFFC01100 /* LP1 Control Register */ +#define LP1_STAT 0xFFC01104 /* LP1 Status Register */ +#define LP1_DIV 0xFFC01108 /* LP1 Clock Divider Value */ +#define LP1_CNT 0xFFC0110C /* LP1 Current Count Value of Clock Divider */ +#define LP1_TX 0xFFC01110 /* LP1 Transmit Buffer */ +#define LP1_RX 0xFFC01114 /* LP1 Receive Buffer */ +#define LP1_TXIN_SHDW 0xFFC01118 /* LP1 Shadow Input Transmit Buffer */ +#define LP1_TXOUT_SHDW 0xFFC0111C /* LP1 Shadow Output Transmit Buffer */ +#define LP2_CTL 0xFFC01200 /* LP2 Control Register */ +#define LP2_STAT 0xFFC01204 /* LP2 Status Register */ +#define LP2_DIV 0xFFC01208 /* LP2 Clock Divider Value */ +#define LP2_CNT 0xFFC0120C /* LP2 Current Count Value of Clock Divider */ +#define LP2_TX 0xFFC01210 /* LP2 Transmit Buffer */ +#define LP2_RX 0xFFC01214 /* LP2 Receive Buffer */ +#define LP2_TXIN_SHDW 0xFFC01218 /* LP2 Shadow Input Transmit Buffer */ +#define LP2_TXOUT_SHDW 0xFFC0121C /* LP2 Shadow Output Transmit Buffer */ +#define LP3_CTL 0xFFC01300 /* LP3 Control Register */ +#define LP3_STAT 0xFFC01304 /* LP3 Status Register */ +#define LP3_DIV 0xFFC01308 /* LP3 Clock Divider Value */ +#define LP3_CNT 0xFFC0130C /* LP3 Current Count Value of Clock Divider */ +#define LP3_TX 0xFFC01310 /* LP3 Transmit Buffer */ +#define LP3_RX 0xFFC01314 /* LP3 Receive Buffer */ +#define LP3_TXIN_SHDW 0xFFC01318 /* LP3 Shadow Input Transmit Buffer */ +#define LP3_TXOUT_SHDW 0xFFC0131C /* LP3 Shadow Output Transmit Buffer */ + +/* ========================= + TIMER Registers + ========================= */ +#define TIMER_REVID 0xFFC01400 /* GPTIMER Timer IP Version ID */ +#define TIMER_RUN 0xFFC01404 /* GPTIMER Timer Run Register */ +#define TIMER_RUN_SET 0xFFC01408 /* GPTIMER Run Register Alias to Set */ +#define TIMER_RUN_CLR 0xFFC0140C /* GPTIMER Run Register Alias to Clear */ +#define TIMER_STOP_CFG 0xFFC01410 /* GPTIMER Stop Config Register */ +#define TIMER_STOP_CFG_SET 0xFFC01414 /* GPTIMER Stop Config Alias to Set */ +#define TIMER_STOP_CFG_CLR 0xFFC01418 /* GPTIMER Stop Config Alias to Clear */ +#define TIMER_DATA_IMSK 0xFFC0141C /* GPTIMER Data Interrupt Mask register */ +#define TIMER_STAT_IMSK 0xFFC01420 /* GPTIMER Status Interrupt Mask register */ +#define TIMER_TRG_MSK 0xFFC01424 /* GPTIMER Output Trigger Mask register */ +#define TIMER_TRG_IE 0xFFC01428 /* GPTIMER Slave Trigger Enable register */ +#define TIMER_DATA_ILAT 0xFFC0142C /* GPTIMER Data Interrupt Register */ +#define TIMER_STAT_ILAT 0xFFC01430 /* GPTIMER Status (Error) Interrupt Register */ +#define TIMER_ERR_TYPE 0xFFC01434 /* GPTIMER Register Indicating Type of Error */ +#define TIMER_BCAST_PER 0xFFC01438 /* GPTIMER Broadcast Period */ +#define TIMER_BCAST_WID 0xFFC0143C /* GPTIMER Broadcast Width */ +#define TIMER_BCAST_DLY 0xFFC01440 /* GPTIMER Broadcast Delay */ + +/* ========================= + TIMER0~7 + ========================= */ +#define TIMER0_CONFIG 0xFFC01460 /* TIMER0 Per Timer Config Register */ +#define TIMER0_COUNTER 0xFFC01464 /* TIMER0 Per Timer Counter Register */ +#define TIMER0_PERIOD 0xFFC01468 /* TIMER0 Per Timer Period Register */ +#define TIMER0_WIDTH 0xFFC0146C /* TIMER0 Per Timer Width Register */ +#define TIMER0_DELAY 0xFFC01470 /* TIMER0 Per Timer Delay Register */ + +#define TIMER1_CONFIG 0xFFC01480 /* TIMER1 Per Timer Config Register */ +#define TIMER1_COUNTER 0xFFC01484 /* TIMER1 Per Timer Counter Register */ +#define TIMER1_PERIOD 0xFFC01488 /* TIMER1 Per Timer Period Register */ +#define TIMER1_WIDTH 0xFFC0148C /* TIMER1 Per Timer Width Register */ +#define TIMER1_DELAY 0xFFC01490 /* TIMER1 Per Timer Delay Register */ + +#define TIMER2_CONFIG 0xFFC014A0 /* TIMER2 Per Timer Config Register */ +#define TIMER2_COUNTER 0xFFC014A4 /* TIMER2 Per Timer Counter Register */ +#define TIMER2_PERIOD 0xFFC014A8 /* TIMER2 Per Timer Period Register */ +#define TIMER2_WIDTH 0xFFC014AC /* TIMER2 Per Timer Width Register */ +#define TIMER2_DELAY 0xFFC014B0 /* TIMER2 Per Timer Delay Register */ + +#define TIMER3_CONFIG 0xFFC014C0 /* TIMER3 Per Timer Config Register */ +#define TIMER3_COUNTER 0xFFC014C4 /* TIMER3 Per Timer Counter Register */ +#define TIMER3_PERIOD 0xFFC014C8 /* TIMER3 Per Timer Period Register */ +#define TIMER3_WIDTH 0xFFC014CC /* TIMER3 Per Timer Width Register */ +#define TIMER3_DELAY 0xFFC014D0 /* TIMER3 Per Timer Delay Register */ + +#define TIMER4_CONFIG 0xFFC014E0 /* TIMER4 Per Timer Config Register */ +#define TIMER4_COUNTER 0xFFC014E4 /* TIMER4 Per Timer Counter Register */ +#define TIMER4_PERIOD 0xFFC014E8 /* TIMER4 Per Timer Period Register */ +#define TIMER4_WIDTH 0xFFC014EC /* TIMER4 Per Timer Width Register */ +#define TIMER4_DELAY 0xFFC014F0 /* TIMER4 Per Timer Delay Register */ + +#define TIMER5_CONFIG 0xFFC01500 /* TIMER5 Per Timer Config Register */ +#define TIMER5_COUNTER 0xFFC01504 /* TIMER5 Per Timer Counter Register */ +#define TIMER5_PERIOD 0xFFC01508 /* TIMER5 Per Timer Period Register */ +#define TIMER5_WIDTH 0xFFC0150C /* TIMER5 Per Timer Width Register */ +#define TIMER5_DELAY 0xFFC01510 /* TIMER5 Per Timer Delay Register */ + +#define TIMER6_CONFIG 0xFFC01520 /* TIMER6 Per Timer Config Register */ +#define TIMER6_COUNTER 0xFFC01524 /* TIMER6 Per Timer Counter Register */ +#define TIMER6_PERIOD 0xFFC01528 /* TIMER6 Per Timer Period Register */ +#define TIMER6_WIDTH 0xFFC0152C /* TIMER6 Per Timer Width Register */ +#define TIMER6_DELAY 0xFFC01530 /* TIMER6 Per Timer Delay Register */ + +#define TIMER7_CONFIG 0xFFC01540 /* TIMER7 Per Timer Config Register */ +#define TIMER7_COUNTER 0xFFC01544 /* TIMER7 Per Timer Counter Register */ +#define TIMER7_PERIOD 0xFFC01548 /* TIMER7 Per Timer Period Register */ +#define TIMER7_WIDTH 0xFFC0154C /* TIMER7 Per Timer Width Register */ +#define TIMER7_DELAY 0xFFC01550 /* TIMER7 Per Timer Delay Register */ + +/* ========================= + CRC Registers + ========================= */ + +/* ========================= + CRC0 + ========================= */ +#define REG_CRC0_CTL 0xFFC01C00 /* CRC0 Control Register */ +#define REG_CRC0_DCNT 0xFFC01C04 /* CRC0 Data Word Count Register */ +#define REG_CRC0_DCNTRLD 0xFFC01C08 /* CRC0 Data Word Count Reload Register */ +#define REG_CRC0_COMP 0xFFC01C14 /* CRC0 DATA Compare Register */ +#define REG_CRC0_FILLVAL 0xFFC01C18 /* CRC0 Fill Value Register */ +#define REG_CRC0_DFIFO 0xFFC01C1C /* CRC0 DATA FIFO Register */ +#define REG_CRC0_INEN 0xFFC01C20 /* CRC0 Interrupt Enable Register */ +#define REG_CRC0_INEN_SET 0xFFC01C24 /* CRC0 Interrupt Enable Set Register */ +#define REG_CRC0_INEN_CLR 0xFFC01C28 /* CRC0 Interrupt Enable Clear Register */ +#define REG_CRC0_POLY 0xFFC01C2C /* CRC0 Polynomial Register */ +#define REG_CRC0_STAT 0xFFC01C40 /* CRC0 Status Register */ +#define REG_CRC0_DCNTCAP 0xFFC01C44 /* CRC0 DATA Count Capture Register */ +#define REG_CRC0_RESULT_FIN 0xFFC01C4C /* CRC0 Final CRC Result Register */ +#define REG_CRC0_RESULT_CUR 0xFFC01C50 /* CRC0 Current CRC Result Register */ +#define REG_CRC0_REVID 0xFFC01C60 /* CRC0 Revision ID Register */ + +/* ========================= + CRC1 + ========================= */ +#define REG_CRC1_CTL 0xFFC01D00 /* CRC1 Control Register */ +#define REG_CRC1_DCNT 0xFFC01D04 /* CRC1 Data Word Count Register */ +#define REG_CRC1_DCNTRLD 0xFFC01D08 /* CRC1 Data Word Count Reload Register */ +#define REG_CRC1_COMP 0xFFC01D14 /* CRC1 DATA Compare Register */ +#define REG_CRC1_FILLVAL 0xFFC01D18 /* CRC1 Fill Value Register */ +#define REG_CRC1_DFIFO 0xFFC01D1C /* CRC1 DATA FIFO Register */ +#define REG_CRC1_INEN 0xFFC01D20 /* CRC1 Interrupt Enable Register */ +#define REG_CRC1_INEN_SET 0xFFC01D24 /* CRC1 Interrupt Enable Set Register */ +#define REG_CRC1_INEN_CLR 0xFFC01D28 /* CRC1 Interrupt Enable Clear Register */ +#define REG_CRC1_POLY 0xFFC01D2C /* CRC1 Polynomial Register */ +#define REG_CRC1_STAT 0xFFC01D40 /* CRC1 Status Register */ +#define REG_CRC1_DCNTCAP 0xFFC01D44 /* CRC1 DATA Count Capture Register */ +#define REG_CRC1_RESULT_FIN 0xFFC01D4C /* CRC1 Final CRC Result Register */ +#define REG_CRC1_RESULT_CUR 0xFFC01D50 /* CRC1 Current CRC Result Register */ +#define REG_CRC1_REVID 0xFFC01D60 /* CRC1 Revision ID Register */ + +/* ========================= + TWI Registers + ========================= */ + +/* ========================= + TWI0 + ========================= */ +#define TWI0_CLKDIV 0xFFC01E00 /* TWI0 SCL Clock Divider */ +#define TWI0_CONTROL 0xFFC01E04 /* TWI0 Control Register */ +#define TWI0_SLAVE_CTL 0xFFC01E08 /* TWI0 Slave Mode Control Register */ +#define TWI0_SLAVE_STAT 0xFFC01E0C /* TWI0 Slave Mode Status Register */ +#define TWI0_SLAVE_ADDR 0xFFC01E10 /* TWI0 Slave Mode Address Register */ +#define TWI0_MASTER_CTL 0xFFC01E14 /* TWI0 Master Mode Control Registers */ +#define TWI0_MASTER_STAT 0xFFC01E18 /* TWI0 Master Mode Status Register */ +#define TWI0_MASTER_ADDR 0xFFC01E1C /* TWI0 Master Mode Address Register */ +#define TWI0_INT_STAT 0xFFC01E20 /* TWI0 Interrupt Status Register */ +#define TWI0_INT_MASK 0xFFC01E24 /* TWI0 Interrupt Mask Register */ +#define TWI0_FIFO_CTL 0xFFC01E28 /* TWI0 FIFO Control Register */ +#define TWI0_FIFO_STAT 0xFFC01E2C /* TWI0 FIFO Status Register */ +#define TWI0_XMT_DATA8 0xFFC01E80 /* TWI0 FIFO Transmit Data Single-Byte Register */ +#define TWI0_XMT_DATA16 0xFFC01E84 /* TWI0 FIFO Transmit Data Double-Byte Register */ +#define TWI0_RCV_DATA8 0xFFC01E88 /* TWI0 FIFO Transmit Data Single-Byte Register */ +#define TWI0_RCV_DATA16 0xFFC01E8C /* TWI0 FIFO Transmit Data Double-Byte Register */ + +/* ========================= + TWI1 + ========================= */ +#define TWI1_CLKDIV 0xFFC01F00 /* TWI1 SCL Clock Divider */ +#define TWI1_CONTROL 0xFFC01F04 /* TWI1 Control Register */ +#define TWI1_SLAVE_CTL 0xFFC01F08 /* TWI1 Slave Mode Control Register */ +#define TWI1_SLAVE_STAT 0xFFC01F0C /* TWI1 Slave Mode Status Register */ +#define TWI1_SLAVE_ADDR 0xFFC01F10 /* TWI1 Slave Mode Address Register */ +#define TWI1_MASTER_CTL 0xFFC01F14 /* TWI1 Master Mode Control Registers */ +#define TWI1_MASTER_STAT 0xFFC01F18 /* TWI1 Master Mode Status Register */ +#define TWI1_MASTER_ADDR 0xFFC01F1C /* TWI1 Master Mode Address Register */ +#define TWI1_INT_STAT 0xFFC01F20 /* TWI1 Interrupt Status Register */ +#define TWI1_INT_MASK 0xFFC01F24 /* TWI1 Interrupt Mask Register */ +#define TWI1_FIFO_CTL 0xFFC01F28 /* TWI1 FIFO Control Register */ +#define TWI1_FIFO_STAT 0xFFC01F2C /* TWI1 FIFO Status Register */ +#define TWI1_XMT_DATA8 0xFFC01F80 /* TWI1 FIFO Transmit Data Single-Byte Register */ +#define TWI1_XMT_DATA16 0xFFC01F84 /* TWI1 FIFO Transmit Data Double-Byte Register */ +#define TWI1_RCV_DATA8 0xFFC01F88 /* TWI1 FIFO Transmit Data Single-Byte Register */ +#define TWI1_RCV_DATA16 0xFFC01F8C /* TWI1 FIFO Transmit Data Double-Byte Register */ + + +/* ========================= + UART Registers + ========================= */ + +/* ========================= + UART0 + ========================= */ +#define UART0_REVID 0xFFC02000 /* UART0 Revision ID Register */ +#define UART0_CTL 0xFFC02004 /* UART0 Control Register */ +#define UART0_STAT 0xFFC02008 /* UART0 Status Register */ +#define UART0_SCR 0xFFC0200C /* UART0 Scratch Register */ +#define UART0_CLK 0xFFC02010 /* UART0 Clock Rate Register */ +#define UART0_IER 0xFFC02014 /* UART0 Interrupt Mask Register */ +#define UART0_IER_SET 0xFFC02018 /* UART0 Interrupt Mask Set Register */ +#define UART0_IER_CLR 0xFFC0201C /* UART0 Interrupt Mask Clear Register */ +#define UART0_RBR 0xFFC02020 /* UART0 Receive Buffer Register */ +#define UART0_THR 0xFFC02024 /* UART0 Transmit Hold Register */ +#define UART0_TAIP 0xFFC02028 /* UART0 Transmit Address/Insert Pulse Register */ +#define UART0_TSR 0xFFC0202C /* UART0 Transmit Shift Register */ +#define UART0_RSR 0xFFC02030 /* UART0 Receive Shift Register */ +#define UART0_TXDIV 0xFFC02034 /* UART0 Transmit Clock Devider Register */ +#define UART0_RXDIV 0xFFC02038 /* UART0 Receive Clock Devider Register */ + +/* ========================= + UART1 + ========================= */ +#define UART1_REVID 0xFFC02400 /* UART1 Revision ID Register */ +#define UART1_CTL 0xFFC02404 /* UART1 Control Register */ +#define UART1_STAT 0xFFC02408 /* UART1 Status Register */ +#define UART1_SCR 0xFFC0240C /* UART1 Scratch Register */ +#define UART1_CLK 0xFFC02410 /* UART1 Clock Rate Register */ +#define UART1_IER 0xFFC02414 /* UART1 Interrupt Mask Register */ +#define UART1_IER_SET 0xFFC02418 /* UART1 Interrupt Mask Set Register */ +#define UART1_IER_CLR 0xFFC0241C /* UART1 Interrupt Mask Clear Register */ +#define UART1_RBR 0xFFC02420 /* UART1 Receive Buffer Register */ +#define UART1_THR 0xFFC02424 /* UART1 Transmit Hold Register */ +#define UART1_TAIP 0xFFC02428 /* UART1 Transmit Address/Insert Pulse Register */ +#define UART1_TSR 0xFFC0242C /* UART1 Transmit Shift Register */ +#define UART1_RSR 0xFFC02430 /* UART1 Receive Shift Register */ +#define UART1_TXDIV 0xFFC02434 /* UART1 Transmit Clock Devider Register */ +#define UART1_RXDIV 0xFFC02438 /* UART1 Receive Clock Devider Register */ + + +/* ========================= + PORT Registers + ========================= */ + +/* ========================= + PORTA + ========================= */ +#define PORTA_FER 0xFFC03000 /* PORTA Port x Function Enable Register */ +#define PORTA_FER_SET 0xFFC03004 /* PORTA Port x Function Enable Set Register */ +#define PORTA_FER_CLEAR 0xFFC03008 /* PORTA Port x Function Enable Clear Register */ +#define PORTA_DATA 0xFFC0300C /* PORTA Port x GPIO Data Register */ +#define PORTA_DATA_SET 0xFFC03010 /* PORTA Port x GPIO Data Set Register */ +#define PORTA_DATA_CLEAR 0xFFC03014 /* PORTA Port x GPIO Data Clear Register */ +#define PORTA_DIR 0xFFC03018 /* PORTA Port x GPIO Direction Register */ +#define PORTA_DIR_SET 0xFFC0301C /* PORTA Port x GPIO Direction Set Register */ +#define PORTA_DIR_CLEAR 0xFFC03020 /* PORTA Port x GPIO Direction Clear Register */ +#define PORTA_INEN 0xFFC03024 /* PORTA Port x GPIO Input Enable Register */ +#define PORTA_INEN_SET 0xFFC03028 /* PORTA Port x GPIO Input Enable Set Register */ +#define PORTA_INEN_CLEAR 0xFFC0302C /* PORTA Port x GPIO Input Enable Clear Register */ +#define PORTA_MUX 0xFFC03030 /* PORTA Port x Multiplexer Control Register */ +#define PORTA_DATA_TGL 0xFFC03034 /* PORTA Port x GPIO Input Enable Toggle Register */ +#define PORTA_POL 0xFFC03038 /* PORTA Port x GPIO Programming Inversion Register */ +#define PORTA_POL_SET 0xFFC0303C /* PORTA Port x GPIO Programming Inversion Set Register */ +#define PORTA_POL_CLEAR 0xFFC03040 /* PORTA Port x GPIO Programming Inversion Clear Register */ +#define PORTA_LOCK 0xFFC03044 /* PORTA Port x GPIO Lock Register */ +#define PORTA_REVID 0xFFC0307C /* PORTA Port x GPIO Revision ID */ + +/* ========================= + PORTB + ========================= */ +#define PORTB_FER 0xFFC03080 /* PORTB Port x Function Enable Register */ +#define PORTB_FER_SET 0xFFC03084 /* PORTB Port x Function Enable Set Register */ +#define PORTB_FER_CLEAR 0xFFC03088 /* PORTB Port x Function Enable Clear Register */ +#define PORTB_DATA 0xFFC0308C /* PORTB Port x GPIO Data Register */ +#define PORTB_DATA_SET 0xFFC03090 /* PORTB Port x GPIO Data Set Register */ +#define PORTB_DATA_CLEAR 0xFFC03094 /* PORTB Port x GPIO Data Clear Register */ +#define PORTB_DIR 0xFFC03098 /* PORTB Port x GPIO Direction Register */ +#define PORTB_DIR_SET 0xFFC0309C /* PORTB Port x GPIO Direction Set Register */ +#define PORTB_DIR_CLEAR 0xFFC030A0 /* PORTB Port x GPIO Direction Clear Register */ +#define PORTB_INEN 0xFFC030A4 /* PORTB Port x GPIO Input Enable Register */ +#define PORTB_INEN_SET 0xFFC030A8 /* PORTB Port x GPIO Input Enable Set Register */ +#define PORTB_INEN_CLEAR 0xFFC030AC /* PORTB Port x GPIO Input Enable Clear Register */ +#define PORTB_MUX 0xFFC030B0 /* PORTB Port x Multiplexer Control Register */ +#define PORTB_DATA_TGL 0xFFC030B4 /* PORTB Port x GPIO Input Enable Toggle Register */ +#define PORTB_POL 0xFFC030B8 /* PORTB Port x GPIO Programming Inversion Register */ +#define PORTB_POL_SET 0xFFC030BC /* PORTB Port x GPIO Programming Inversion Set Register */ +#define PORTB_POL_CLEAR 0xFFC030C0 /* PORTB Port x GPIO Programming Inversion Clear Register */ +#define PORTB_LOCK 0xFFC030C4 /* PORTB Port x GPIO Lock Register */ +#define PORTB_REVID 0xFFC030FC /* PORTB Port x GPIO Revision ID */ + +/* ========================= + PORTC + ========================= */ +#define PORTC_FER 0xFFC03100 /* PORTC Port x Function Enable Register */ +#define PORTC_FER_SET 0xFFC03104 /* PORTC Port x Function Enable Set Register */ +#define PORTC_FER_CLEAR 0xFFC03108 /* PORTC Port x Function Enable Clear Register */ +#define PORTC_DATA 0xFFC0310C /* PORTC Port x GPIO Data Register */ +#define PORTC_DATA_SET 0xFFC03110 /* PORTC Port x GPIO Data Set Register */ +#define PORTC_DATA_CLEAR 0xFFC03114 /* PORTC Port x GPIO Data Clear Register */ +#define PORTC_DIR 0xFFC03118 /* PORTC Port x GPIO Direction Register */ +#define PORTC_DIR_SET 0xFFC0311C /* PORTC Port x GPIO Direction Set Register */ +#define PORTC_DIR_CLEAR 0xFFC03120 /* PORTC Port x GPIO Direction Clear Register */ +#define PORTC_INEN 0xFFC03124 /* PORTC Port x GPIO Input Enable Register */ +#define PORTC_INEN_SET 0xFFC03128 /* PORTC Port x GPIO Input Enable Set Register */ +#define PORTC_INEN_CLEAR 0xFFC0312C /* PORTC Port x GPIO Input Enable Clear Register */ +#define PORTC_MUX 0xFFC03130 /* PORTC Port x Multiplexer Control Register */ +#define PORTC_DATA_TGL 0xFFC03134 /* PORTC Port x GPIO Input Enable Toggle Register */ +#define PORTC_POL 0xFFC03138 /* PORTC Port x GPIO Programming Inversion Register */ +#define PORTC_POL_SET 0xFFC0313C /* PORTC Port x GPIO Programming Inversion Set Register */ +#define PORTC_POL_CLEAR 0xFFC03140 /* PORTC Port x GPIO Programming Inversion Clear Register */ +#define PORTC_LOCK 0xFFC03144 /* PORTC Port x GPIO Lock Register */ +#define PORTC_REVID 0xFFC0317C /* PORTC Port x GPIO Revision ID */ + +/* ========================= + PORTD + ========================= */ +#define PORTD_FER 0xFFC03180 /* PORTD Port x Function Enable Register */ +#define PORTD_FER_SET 0xFFC03184 /* PORTD Port x Function Enable Set Register */ +#define PORTD_FER_CLEAR 0xFFC03188 /* PORTD Port x Function Enable Clear Register */ +#define PORTD_DATA 0xFFC0318C /* PORTD Port x GPIO Data Register */ +#define PORTD_DATA_SET 0xFFC03190 /* PORTD Port x GPIO Data Set Register */ +#define PORTD_DATA_CLEAR 0xFFC03194 /* PORTD Port x GPIO Data Clear Register */ +#define PORTD_DIR 0xFFC03198 /* PORTD Port x GPIO Direction Register */ +#define PORTD_DIR_SET 0xFFC0319C /* PORTD Port x GPIO Direction Set Register */ +#define PORTD_DIR_CLEAR 0xFFC031A0 /* PORTD Port x GPIO Direction Clear Register */ +#define PORTD_INEN 0xFFC031A4 /* PORTD Port x GPIO Input Enable Register */ +#define PORTD_INEN_SET 0xFFC031A8 /* PORTD Port x GPIO Input Enable Set Register */ +#define PORTD_INEN_CLEAR 0xFFC031AC /* PORTD Port x GPIO Input Enable Clear Register */ +#define PORTD_MUX 0xFFC031B0 /* PORTD Port x Multiplexer Control Register */ +#define PORTD_DATA_TGL 0xFFC031B4 /* PORTD Port x GPIO Input Enable Toggle Register */ +#define PORTD_POL 0xFFC031B8 /* PORTD Port x GPIO Programming Inversion Register */ +#define PORTD_POL_SET 0xFFC031BC /* PORTD Port x GPIO Programming Inversion Set Register */ +#define PORTD_POL_CLEAR 0xFFC031C0 /* PORTD Port x GPIO Programming Inversion Clear Register */ +#define PORTD_LOCK 0xFFC031C4 /* PORTD Port x GPIO Lock Register */ +#define PORTD_REVID 0xFFC031FC /* PORTD Port x GPIO Revision ID */ + +/* ========================= + PORTE + ========================= */ +#define PORTE_FER 0xFFC03200 /* PORTE Port x Function Enable Register */ +#define PORTE_FER_SET 0xFFC03204 /* PORTE Port x Function Enable Set Register */ +#define PORTE_FER_CLEAR 0xFFC03208 /* PORTE Port x Function Enable Clear Register */ +#define PORTE_DATA 0xFFC0320C /* PORTE Port x GPIO Data Register */ +#define PORTE_DATA_SET 0xFFC03210 /* PORTE Port x GPIO Data Set Register */ +#define PORTE_DATA_CLEAR 0xFFC03214 /* PORTE Port x GPIO Data Clear Register */ +#define PORTE_DIR 0xFFC03218 /* PORTE Port x GPIO Direction Register */ +#define PORTE_DIR_SET 0xFFC0321C /* PORTE Port x GPIO Direction Set Register */ +#define PORTE_DIR_CLEAR 0xFFC03220 /* PORTE Port x GPIO Direction Clear Register */ +#define PORTE_INEN 0xFFC03224 /* PORTE Port x GPIO Input Enable Register */ +#define PORTE_INEN_SET 0xFFC03228 /* PORTE Port x GPIO Input Enable Set Register */ +#define PORTE_INEN_CLEAR 0xFFC0322C /* PORTE Port x GPIO Input Enable Clear Register */ +#define PORTE_MUX 0xFFC03230 /* PORTE Port x Multiplexer Control Register */ +#define PORTE_DATA_TGL 0xFFC03234 /* PORTE Port x GPIO Input Enable Toggle Register */ +#define PORTE_POL 0xFFC03238 /* PORTE Port x GPIO Programming Inversion Register */ +#define PORTE_POL_SET 0xFFC0323C /* PORTE Port x GPIO Programming Inversion Set Register */ +#define PORTE_POL_CLEAR 0xFFC03240 /* PORTE Port x GPIO Programming Inversion Clear Register */ +#define PORTE_LOCK 0xFFC03244 /* PORTE Port x GPIO Lock Register */ +#define PORTE_REVID 0xFFC0327C /* PORTE Port x GPIO Revision ID */ + +/* ========================= + PORTF + ========================= */ +#define PORTF_FER 0xFFC03280 /* PORTF Port x Function Enable Register */ +#define PORTF_FER_SET 0xFFC03284 /* PORTF Port x Function Enable Set Register */ +#define PORTF_FER_CLEAR 0xFFC03288 /* PORTF Port x Function Enable Clear Register */ +#define PORTF_DATA 0xFFC0328C /* PORTF Port x GPIO Data Register */ +#define PORTF_DATA_SET 0xFFC03290 /* PORTF Port x GPIO Data Set Register */ +#define PORTF_DATA_CLEAR 0xFFC03294 /* PORTF Port x GPIO Data Clear Register */ +#define PORTF_DIR 0xFFC03298 /* PORTF Port x GPIO Direction Register */ +#define PORTF_DIR_SET 0xFFC0329C /* PORTF Port x GPIO Direction Set Register */ +#define PORTF_DIR_CLEAR 0xFFC032A0 /* PORTF Port x GPIO Direction Clear Register */ +#define PORTF_INEN 0xFFC032A4 /* PORTF Port x GPIO Input Enable Register */ +#define PORTF_INEN_SET 0xFFC032A8 /* PORTF Port x GPIO Input Enable Set Register */ +#define PORTF_INEN_CLEAR 0xFFC032AC /* PORTF Port x GPIO Input Enable Clear Register */ +#define PORTF_MUX 0xFFC032B0 /* PORTF Port x Multiplexer Control Register */ +#define PORTF_DATA_TGL 0xFFC032B4 /* PORTF Port x GPIO Input Enable Toggle Register */ +#define PORTF_POL 0xFFC032B8 /* PORTF Port x GPIO Programming Inversion Register */ +#define PORTF_POL_SET 0xFFC032BC /* PORTF Port x GPIO Programming Inversion Set Register */ +#define PORTF_POL_CLEAR 0xFFC032C0 /* PORTF Port x GPIO Programming Inversion Clear Register */ +#define PORTF_LOCK 0xFFC032C4 /* PORTF Port x GPIO Lock Register */ +#define PORTF_REVID 0xFFC032FC /* PORTF Port x GPIO Revision ID */ + +/* ========================= + PORTG + ========================= */ +#define PORTG_FER 0xFFC03300 /* PORTG Port x Function Enable Register */ +#define PORTG_FER_SET 0xFFC03304 /* PORTG Port x Function Enable Set Register */ +#define PORTG_FER_CLEAR 0xFFC03308 /* PORTG Port x Function Enable Clear Register */ +#define PORTG_DATA 0xFFC0330C /* PORTG Port x GPIO Data Register */ +#define PORTG_DATA_SET 0xFFC03310 /* PORTG Port x GPIO Data Set Register */ +#define PORTG_DATA_CLEAR 0xFFC03314 /* PORTG Port x GPIO Data Clear Register */ +#define PORTG_DIR 0xFFC03318 /* PORTG Port x GPIO Direction Register */ +#define PORTG_DIR_SET 0xFFC0331C /* PORTG Port x GPIO Direction Set Register */ +#define PORTG_DIR_CLEAR 0xFFC03320 /* PORTG Port x GPIO Direction Clear Register */ +#define PORTG_INEN 0xFFC03324 /* PORTG Port x GPIO Input Enable Register */ +#define PORTG_INEN_SET 0xFFC03328 /* PORTG Port x GPIO Input Enable Set Register */ +#define PORTG_INEN_CLEAR 0xFFC0332C /* PORTG Port x GPIO Input Enable Clear Register */ +#define PORTG_MUX 0xFFC03330 /* PORTG Port x Multiplexer Control Register */ +#define PORTG_DATA_TGL 0xFFC03334 /* PORTG Port x GPIO Input Enable Toggle Register */ +#define PORTG_POL 0xFFC03338 /* PORTG Port x GPIO Programming Inversion Register */ +#define PORTG_POL_SET 0xFFC0333C /* PORTG Port x GPIO Programming Inversion Set Register */ +#define PORTG_POL_CLEAR 0xFFC03340 /* PORTG Port x GPIO Programming Inversion Clear Register */ +#define PORTG_LOCK 0xFFC03344 /* PORTG Port x GPIO Lock Register */ +#define PORTG_REVID 0xFFC0337C /* PORTG Port x GPIO Revision ID */ + + +/* ========================= + PINT Registers + ========================= */ + +/* ========================= + PINT0 + ========================= */ +#define PINT0_MASK_SET 0xFFC04000 /* PINT0 Pint Mask Set Register */ +#define PINT0_MASK_CLEAR 0xFFC04004 /* PINT0 Pint Mask Clear Register */ +#define PINT0_REQUEST 0xFFC04008 /* PINT0 Pint Request Register */ +#define PINT0_ASSIGN 0xFFC0400C /* PINT0 Pint Assign Register */ +#define PINT0_EDGE_SET 0xFFC04010 /* PINT0 Pint Edge Set Register */ +#define PINT0_EDGE_CLEAR 0xFFC04014 /* PINT0 Pint Edge Clear Register */ +#define PINT0_INVERT_SET 0xFFC04018 /* PINT0 Pint Invert Set Register */ +#define PINT0_INVERT_CLEAR 0xFFC0401C /* PINT0 Pint Invert Clear Register */ +#define PINT0_PINSTATE 0xFFC04020 /* PINT0 Pint Pinstate Register */ +#define PINT0_LATCH 0xFFC04024 /* PINT0 Pint Latch Register */ + +/* ========================= + PINT1 + ========================= */ +#define PINT1_MASK_SET 0xFFC04100 /* PINT1 Pint Mask Set Register */ +#define PINT1_MASK_CLEAR 0xFFC04104 /* PINT1 Pint Mask Clear Register */ +#define PINT1_REQUEST 0xFFC04108 /* PINT1 Pint Request Register */ +#define PINT1_ASSIGN 0xFFC0410C /* PINT1 Pint Assign Register */ +#define PINT1_EDGE_SET 0xFFC04110 /* PINT1 Pint Edge Set Register */ +#define PINT1_EDGE_CLEAR 0xFFC04114 /* PINT1 Pint Edge Clear Register */ +#define PINT1_INVERT_SET 0xFFC04118 /* PINT1 Pint Invert Set Register */ +#define PINT1_INVERT_CLEAR 0xFFC0411C /* PINT1 Pint Invert Clear Register */ +#define PINT1_PINSTATE 0xFFC04120 /* PINT1 Pint Pinstate Register */ +#define PINT1_LATCH 0xFFC04124 /* PINT1 Pint Latch Register */ + +/* ========================= + PINT2 + ========================= */ +#define PINT2_MASK_SET 0xFFC04200 /* PINT2 Pint Mask Set Register */ +#define PINT2_MASK_CLEAR 0xFFC04204 /* PINT2 Pint Mask Clear Register */ +#define PINT2_REQUEST 0xFFC04208 /* PINT2 Pint Request Register */ +#define PINT2_ASSIGN 0xFFC0420C /* PINT2 Pint Assign Register */ +#define PINT2_EDGE_SET 0xFFC04210 /* PINT2 Pint Edge Set Register */ +#define PINT2_EDGE_CLEAR 0xFFC04214 /* PINT2 Pint Edge Clear Register */ +#define PINT2_INVERT_SET 0xFFC04218 /* PINT2 Pint Invert Set Register */ +#define PINT2_INVERT_CLEAR 0xFFC0421C /* PINT2 Pint Invert Clear Register */ +#define PINT2_PINSTATE 0xFFC04220 /* PINT2 Pint Pinstate Register */ +#define PINT2_LATCH 0xFFC04224 /* PINT2 Pint Latch Register */ + +/* ========================= + PINT3 + ========================= */ +#define PINT3_MASK_SET 0xFFC04300 /* PINT3 Pint Mask Set Register */ +#define PINT3_MASK_CLEAR 0xFFC04304 /* PINT3 Pint Mask Clear Register */ +#define PINT3_REQUEST 0xFFC04308 /* PINT3 Pint Request Register */ +#define PINT3_ASSIGN 0xFFC0430C /* PINT3 Pint Assign Register */ +#define PINT3_EDGE_SET 0xFFC04310 /* PINT3 Pint Edge Set Register */ +#define PINT3_EDGE_CLEAR 0xFFC04314 /* PINT3 Pint Edge Clear Register */ +#define PINT3_INVERT_SET 0xFFC04318 /* PINT3 Pint Invert Set Register */ +#define PINT3_INVERT_CLEAR 0xFFC0431C /* PINT3 Pint Invert Clear Register */ +#define PINT3_PINSTATE 0xFFC04320 /* PINT3 Pint Pinstate Register */ +#define PINT3_LATCH 0xFFC04324 /* PINT3 Pint Latch Register */ + +/* ========================= + PINT4 + ========================= */ +#define PINT4_MASK_SET 0xFFC04400 /* PINT4 Pint Mask Set Register */ +#define PINT4_MASK_CLEAR 0xFFC04404 /* PINT4 Pint Mask Clear Register */ +#define PINT4_REQUEST 0xFFC04408 /* PINT4 Pint Request Register */ +#define PINT4_ASSIGN 0xFFC0440C /* PINT4 Pint Assign Register */ +#define PINT4_EDGE_SET 0xFFC04410 /* PINT4 Pint Edge Set Register */ +#define PINT4_EDGE_CLEAR 0xFFC04414 /* PINT4 Pint Edge Clear Register */ +#define PINT4_INVERT_SET 0xFFC04418 /* PINT4 Pint Invert Set Register */ +#define PINT4_INVERT_CLEAR 0xFFC0441C /* PINT4 Pint Invert Clear Register */ +#define PINT4_PINSTATE 0xFFC04420 /* PINT4 Pint Pinstate Register */ +#define PINT4_LATCH 0xFFC04424 /* PINT4 Pint Latch Register */ + +/* ========================= + PINT5 + ========================= */ +#define PINT5_MASK_SET 0xFFC04500 /* PINT5 Pint Mask Set Register */ +#define PINT5_MASK_CLEAR 0xFFC04504 /* PINT5 Pint Mask Clear Register */ +#define PINT5_REQUEST 0xFFC04508 /* PINT5 Pint Request Register */ +#define PINT5_ASSIGN 0xFFC0450C /* PINT5 Pint Assign Register */ +#define PINT5_EDGE_SET 0xFFC04510 /* PINT5 Pint Edge Set Register */ +#define PINT5_EDGE_CLEAR 0xFFC04514 /* PINT5 Pint Edge Clear Register */ +#define PINT5_INVERT_SET 0xFFC04518 /* PINT5 Pint Invert Set Register */ +#define PINT5_INVERT_CLEAR 0xFFC0451C /* PINT5 Pint Invert Clear Register */ +#define PINT5_PINSTATE 0xFFC04520 /* PINT5 Pint Pinstate Register */ +#define PINT5_LATCH 0xFFC04524 /* PINT5 Pint Latch Register */ + + +/* ========================= + SMC Registers + ========================= */ + +/* ========================= + SMC0 + ========================= */ +#define SMC_GCTL 0xFFC16004 /* SMC0 SMC Control Register */ +#define SMC_GSTAT 0xFFC16008 /* SMC0 SMC Status Register */ +#define SMC_B0CTL 0xFFC1600C /* SMC0 SMC Bank0 Control Register */ +#define SMC_B0TIM 0xFFC16010 /* SMC0 SMC Bank0 Timing Register */ +#define SMC_B0ETIM 0xFFC16014 /* SMC0 SMC Bank0 Extended Timing Register */ +#define SMC_B1CTL 0xFFC1601C /* SMC0 SMC BANK1 Control Register */ +#define SMC_B1TIM 0xFFC16020 /* SMC0 SMC BANK1 Timing Register */ +#define SMC_B1ETIM 0xFFC16024 /* SMC0 SMC BANK1 Extended Timing Register */ +#define SMC_B2CTL 0xFFC1602C /* SMC0 SMC BANK2 Control Register */ +#define SMC_B2TIM 0xFFC16030 /* SMC0 SMC BANK2 Timing Register */ +#define SMC_B2ETIM 0xFFC16034 /* SMC0 SMC BANK2 Extended Timing Register */ +#define SMC_B3CTL 0xFFC1603C /* SMC0 SMC BANK3 Control Register */ +#define SMC_B3TIM 0xFFC16040 /* SMC0 SMC BANK3 Timing Register */ +#define SMC_B3ETIM 0xFFC16044 /* SMC0 SMC BANK3 Extended Timing Register */ + + +/* ========================= + WDOG Registers + ========================= */ + +/* ========================= + WDOG0 + ========================= */ +#define WDOG0_CTL 0xFFC17000 /* WDOG0 Control Register */ +#define WDOG0_CNT 0xFFC17004 /* WDOG0 Count Register */ +#define WDOG0_STAT 0xFFC17008 /* WDOG0 Watchdog Timer Status Register */ +#define WDOG_CTL WDOG0_CTL +#define WDOG_CNT WDOG0_CNT +#define WDOG_STAT WDOG0_STAT + +/* ========================= + WDOG1 + ========================= */ +#define WDOG1_CTL 0xFFC17800 /* WDOG1 Control Register */ +#define WDOG1_CNT 0xFFC17804 /* WDOG1 Count Register */ +#define WDOG1_STAT 0xFFC17808 /* WDOG1 Watchdog Timer Status Register */ + + +/* ========================= + SDU Registers + ========================= */ + +/* ========================= + SDU0 + ========================= */ +#define SDU0_IDCODE 0xFFC1F020 /* SDU0 ID Code Register */ +#define SDU0_CTL 0xFFC1F050 /* SDU0 Control Register */ +#define SDU0_STAT 0xFFC1F054 /* SDU0 Status Register */ +#define SDU0_MACCTL 0xFFC1F058 /* SDU0 Memory Access Control Register */ +#define SDU0_MACADDR 0xFFC1F05C /* SDU0 Memory Access Address Register */ +#define SDU0_MACDATA 0xFFC1F060 /* SDU0 Memory Access Data Register */ +#define SDU0_DMARD 0xFFC1F064 /* SDU0 DMA Read Data Register */ +#define SDU0_DMAWD 0xFFC1F068 /* SDU0 DMA Write Data Register */ +#define SDU0_MSG 0xFFC1F080 /* SDU0 Message Register */ +#define SDU0_MSG_SET 0xFFC1F084 /* SDU0 Message Set Register */ +#define SDU0_MSG_CLR 0xFFC1F088 /* SDU0 Message Clear Register */ +#define SDU0_GHLT 0xFFC1F08C /* SDU0 Group Halt Register */ + + +/* ========================= + EMAC Registers + ========================= */ +/* ========================= + EMAC0 + ========================= */ +#define EMAC0_MACCFG 0xFFC20000 /* EMAC0 MAC Configuration Register */ +#define EMAC0_MACFRMFILT 0xFFC20004 /* EMAC0 Filter Register for filtering Received Frames */ +#define EMAC0_HASHTBL_HI 0xFFC20008 /* EMAC0 Contains the Upper 32 bits of the hash table */ +#define EMAC0_HASHTBL_LO 0xFFC2000C /* EMAC0 Contains the lower 32 bits of the hash table */ +#define EMAC0_GMII_ADDR 0xFFC20010 /* EMAC0 Management Address Register */ +#define EMAC0_GMII_DATA 0xFFC20014 /* EMAC0 Management Data Register */ +#define EMAC0_FLOWCTL 0xFFC20018 /* EMAC0 MAC FLow Control Register */ +#define EMAC0_VLANTAG 0xFFC2001C /* EMAC0 VLAN Tag Register */ +#define EMAC0_VER 0xFFC20020 /* EMAC0 EMAC Version Register */ +#define EMAC0_DBG 0xFFC20024 /* EMAC0 EMAC Debug Register */ +#define EMAC0_RMTWKUP 0xFFC20028 /* EMAC0 Remote wake up frame register */ +#define EMAC0_PMT_CTLSTAT 0xFFC2002C /* EMAC0 PMT Control and Status Register */ +#define EMAC0_ISTAT 0xFFC20038 /* EMAC0 EMAC Interrupt Status Register */ +#define EMAC0_IMSK 0xFFC2003C /* EMAC0 EMAC Interrupt Mask Register */ +#define EMAC0_ADDR0_HI 0xFFC20040 /* EMAC0 EMAC Address0 High Register */ +#define EMAC0_ADDR0_LO 0xFFC20044 /* EMAC0 EMAC Address0 Low Register */ +#define EMAC0_MMC_CTL 0xFFC20100 /* EMAC0 MMC Control Register */ +#define EMAC0_MMC_RXINT 0xFFC20104 /* EMAC0 MMC RX Interrupt Register */ +#define EMAC0_MMC_TXINT 0xFFC20108 /* EMAC0 MMC TX Interrupt Register */ +#define EMAC0_MMC_RXIMSK 0xFFC2010C /* EMAC0 MMC RX Interrupt Mask Register */ +#define EMAC0_MMC_TXIMSK 0xFFC20110 /* EMAC0 MMC TX Interrupt Mask Register */ +#define EMAC0_TXOCTCNT_GB 0xFFC20114 /* EMAC0 Num bytes transmitted exclusive of preamble */ +#define EMAC0_TXFRMCNT_GB 0xFFC20118 /* EMAC0 Num frames transmitted exclusive of retired */ +#define EMAC0_TXBCASTFRM_G 0xFFC2011C /* EMAC0 Number of good broadcast frames transmitted. */ +#define EMAC0_TXMCASTFRM_G 0xFFC20120 /* EMAC0 Number of good multicast frames transmitted. */ +#define EMAC0_TX64_GB 0xFFC20124 /* EMAC0 Number of 64 byte length frames */ +#define EMAC0_TX65TO127_GB 0xFFC20128 /* EMAC0 Number of frames of length b/w 65-127 (inclusive) bytes */ +#define EMAC0_TX128TO255_GB 0xFFC2012C /* EMAC0 Number of frames of length b/w 128-255 (inclusive) bytes */ +#define EMAC0_TX256TO511_GB 0xFFC20130 /* EMAC0 Number of frames of length b/w 256-511 (inclusive) bytes */ +#define EMAC0_TX512TO1023_GB 0xFFC20134 /* EMAC0 Number of frames of length b/w 512-1023 (inclusive) bytes */ +#define EMAC0_TX1024TOMAX_GB 0xFFC20138 /* EMAC0 Number of frames of length b/w 1024-max (inclusive) bytes */ +#define EMAC0_TXUCASTFRM_GB 0xFFC2013C /* EMAC0 Number of good and bad unicast frames transmitted */ +#define EMAC0_TXMCASTFRM_GB 0xFFC20140 /* EMAC0 Number of good and bad multicast frames transmitted */ +#define EMAC0_TXBCASTFRM_GB 0xFFC20144 /* EMAC0 Number of good and bad broadcast frames transmitted */ +#define EMAC0_TXUNDR_ERR 0xFFC20148 /* EMAC0 Number of frames aborted due to frame underflow error */ +#define EMAC0_TXSNGCOL_G 0xFFC2014C /* EMAC0 Number of transmitted frames after single collision */ +#define EMAC0_TXMULTCOL_G 0xFFC20150 /* EMAC0 Number of transmitted frames with more than one collision */ +#define EMAC0_TXDEFERRED 0xFFC20154 /* EMAC0 Number of transmitted frames after deferral */ +#define EMAC0_TXLATECOL 0xFFC20158 /* EMAC0 Number of frames aborted due to late collision error */ +#define EMAC0_TXEXCESSCOL 0xFFC2015C /* EMAC0 Number of aborted frames due to excessive collisions */ +#define EMAC0_TXCARR_ERR 0xFFC20160 /* EMAC0 Number of aborted frames due to carrier sense error */ +#define EMAC0_TXOCTCNT_G 0xFFC20164 /* EMAC0 Number of bytes transmitted in good frames only */ +#define EMAC0_TXFRMCNT_G 0xFFC20168 /* EMAC0 Number of good frames transmitted. */ +#define EMAC0_TXEXCESSDEF 0xFFC2016C /* EMAC0 Number of frames aborted due to excessive deferral */ +#define EMAC0_TXPAUSEFRM 0xFFC20170 /* EMAC0 Number of good PAUSE frames transmitted. */ +#define EMAC0_TXVLANFRM_G 0xFFC20174 /* EMAC0 Number of VLAN frames transmitted */ +#define EMAC0_RXFRMCNT_GB 0xFFC20180 /* EMAC0 Number of good and bad frames received. */ +#define EMAC0_RXOCTCNT_GB 0xFFC20184 /* EMAC0 Number of bytes received in good and bad frames */ +#define EMAC0_RXOCTCNT_G 0xFFC20188 /* EMAC0 Number of bytes received only in good frames */ +#define EMAC0_RXBCASTFRM_G 0xFFC2018C /* EMAC0 Number of good broadcast frames received. */ +#define EMAC0_RXMCASTFRM_G 0xFFC20190 /* EMAC0 Number of good multicast frames received */ +#define EMAC0_RXCRC_ERR 0xFFC20194 /* EMAC0 Number of frames received with CRC error */ +#define EMAC0_RXALIGN_ERR 0xFFC20198 /* EMAC0 Number of frames with alignment error */ +#define EMAC0_RXRUNT_ERR 0xFFC2019C /* EMAC0 Number of frames received with runt error. */ +#define EMAC0_RXJAB_ERR 0xFFC201A0 /* EMAC0 Number of frames received with length greater than 1518 */ +#define EMAC0_RXUSIZE_G 0xFFC201A4 /* EMAC0 Number of frames received with length 64 */ +#define EMAC0_RXOSIZE_G 0xFFC201A8 /* EMAC0 Number of frames received with length greater than maxium */ +#define EMAC0_RX64_GB 0xFFC201AC /* EMAC0 Number of good and bad frames of lengh 64 bytes */ +#define EMAC0_RX65TO127_GB 0xFFC201B0 /* EMAC0 Number of good and bad frame between 64-127(inclusive) */ +#define EMAC0_RX128TO255_GB 0xFFC201B4 /* EMAC0 Number of good and bad frames received with length between 128 and 255 (inclusive) bytes, exclusive of preamble. */ +#define EMAC0_RX256TO511_GB 0xFFC201B8 /* EMAC0 Number of good and bad frames between 256-511(inclusive) */ +#define EMAC0_RX512TO1023_GB 0xFFC201BC /* EMAC0 Number of good and bad frames received between 512-1023 */ +#define EMAC0_RX1024TOMAX_GB 0xFFC201C0 /* EMAC0 Number of frames received between 1024 and maxsize */ +#define EMAC0_RXUCASTFRM_G 0xFFC201C4 /* EMAC0 Number of good unicast frames received. */ +#define EMAC0_RXLEN_ERR 0xFFC201C8 /* EMAC0 Number of frames received with length error */ +#define EMAC0_RXOORTYPE 0xFFC201CC /* EMAC0 Number of frames with length not equal to valid frame size */ +#define EMAC0_RXPAUSEFRM 0xFFC201D0 /* EMAC0 Number of good and valid PAUSE frames received. */ +#define EMAC0_RXFIFO_OVF 0xFFC201D4 /* EMAC0 Number of missed received frames due to FIFO overflow. This counter is not present in the GMAC-CORE configuration. */ +#define EMAC0_RXVLANFRM_GB 0xFFC201D8 /* EMAC0 Number of good and bad VLAN frames received. */ +#define EMAC0_RXWDOG_ERR 0xFFC201DC /* EMAC0 Frames received with error due to watchdog timeout */ +#define EMAC0_IPC_RXIMSK 0xFFC20200 /* EMAC0 MMC IPC RX Interrupt Mask Register */ +#define EMAC0_IPC_RXINT 0xFFC20208 /* EMAC0 MMC IPC RX Interrupt Register */ +#define EMAC0_RXIPV4_GD_FRM 0xFFC20210 /* EMAC0 Number of good IPv4 datagrams */ +#define EMAC0_RXIPV4_HDR_ERR_FRM 0xFFC20214 /* EMAC0 Number of IPv4 datagrams with header errors */ +#define EMAC0_RXIPV4_NOPAY_FRM 0xFFC20218 /* EMAC0 Number of IPv4 datagrams without checksum */ +#define EMAC0_RXIPV4_FRAG_FRM 0xFFC2021C /* EMAC0 Number of good IPv4 datagrams with fragmentation */ +#define EMAC0_RXIPV4_UDSBL_FRM 0xFFC20220 /* EMAC0 Number of IPv4 UDP datagrams with disabled checksum */ +#define EMAC0_RXIPV6_GD_FRM 0xFFC20224 /* EMAC0 Number of IPv4 datagrams with TCP/UDP/ICMP payloads */ +#define EMAC0_RXIPV6_HDR_ERR_FRM 0xFFC20228 /* EMAC0 Number of IPv6 datagrams with header errors */ +#define EMAC0_RXIPV6_NOPAY_FRM 0xFFC2022C /* EMAC0 Number of IPv6 datagrams with no TCP/UDP/ICMP payload */ +#define EMAC0_RXUDP_GD_FRM 0xFFC20230 /* EMAC0 Number of good IP datagrames with good UDP payload */ +#define EMAC0_RXUDP_ERR_FRM 0xFFC20234 /* EMAC0 Number of good IP datagrams with UDP checksum errors */ +#define EMAC0_RXTCP_GD_FRM 0xFFC20238 /* EMAC0 Number of good IP datagrams with a good TCP payload */ +#define EMAC0_RXTCP_ERR_FRM 0xFFC2023C /* EMAC0 Number of good IP datagrams with TCP checksum errors */ +#define EMAC0_RXICMP_GD_FRM 0xFFC20240 /* EMAC0 Number of good IP datagrams with a good ICMP payload */ +#define EMAC0_RXICMP_ERR_FRM 0xFFC20244 /* EMAC0 Number of good IP datagrams with ICMP checksum errors */ +#define EMAC0_RXIPV4_GD_OCT 0xFFC20250 /* EMAC0 Bytes received in IPv4 datagrams including tcp,udp or icmp */ +#define EMAC0_RXIPV4_HDR_ERR_OCT 0xFFC20254 /* EMAC0 Bytes received in IPv4 datagrams with header errors */ +#define EMAC0_RXIPV4_NOPAY_OCT 0xFFC20258 /* EMAC0 Bytes received in IPv4 datagrams without tcp,udp,icmp load */ +#define EMAC0_RXIPV4_FRAG_OCT 0xFFC2025C /* EMAC0 Bytes received in fragmented IPv4 datagrams */ +#define EMAC0_RXIPV4_UDSBL_OCT 0xFFC20260 /* EMAC0 Bytes received in UDP segment with checksum disabled */ +#define EMAC0_RXIPV6_GD_OCT 0xFFC20264 /* EMAC0 Bytes received in good IPv6 including tcp,udp or icmp load */ +#define EMAC0_RXIPV6_HDR_ERR_OCT 0xFFC20268 /* EMAC0 Number of bytes received in IPv6 with header errors */ +#define EMAC0_RXIPV6_NOPAY_OCT 0xFFC2026C /* EMAC0 Bytes received in IPv6 without tcp,udp or icmp load */ +#define EMAC0_RXUDP_GD_OCT 0xFFC20270 /* EMAC0 Number of bytes received in good UDP segments */ +#define EMAC0_RXUDP_ERR_OCT 0xFFC20274 /* EMAC0 Number of bytes received in UDP segment with checksum err */ +#define EMAC0_RXTCP_GD_OCT 0xFFC20278 /* EMAC0 Number of bytes received in a good TCP segment */ +#define EMAC0_RXTCP_ERR_OCT 0xFFC2027C /* EMAC0 Number of bytes received in TCP segment with checksum err */ +#define EMAC0_RXICMP_GD_OCT 0xFFC20280 /* EMAC0 Number of bytes received in a good ICMP segment */ +#define EMAC0_RXICMP_ERR_OCT 0xFFC20284 /* EMAC0 Bytes received in an ICMP segment with checksum errors */ +#define EMAC0_TM_CTL 0xFFC20700 /* EMAC0 EMAC Time Stamp Control Register */ +#define EMAC0_TM_SUBSEC 0xFFC20704 /* EMAC0 EMAC Time Stamp Sub Second Increment */ +#define EMAC0_TM_SEC 0xFFC20708 /* EMAC0 EMAC Time Stamp Second Register */ +#define EMAC0_TM_NSEC 0xFFC2070C /* EMAC0 EMAC Time Stamp Nano Second Register */ +#define EMAC0_TM_SECUPDT 0xFFC20710 /* EMAC0 EMAC Time Stamp Seconds Update */ +#define EMAC0_TM_NSECUPDT 0xFFC20714 /* EMAC0 EMAC Time Stamp Nano Seconds Update */ +#define EMAC0_TM_ADDEND 0xFFC20718 /* EMAC0 EMAC Time Stamp Addend Register */ +#define EMAC0_TM_TGTM 0xFFC2071C /* EMAC0 EMAC Time Stamp Target Time Sec. */ +#define EMAC0_TM_NTGTM 0xFFC20720 /* EMAC0 EMAC Time Stamp Target Time Nanosec. */ +#define EMAC0_TM_HISEC 0xFFC20724 /* EMAC0 EMAC Time Stamp High Second Register */ +#define EMAC0_TM_STMPSTAT 0xFFC20728 /* EMAC0 EMAC Time Stamp Status Register */ +#define EMAC0_TM_PPSCTL 0xFFC2072C /* EMAC0 EMAC PPS Control Register */ +#define EMAC0_TM_AUXSTMP_NSEC 0xFFC20730 /* EMAC0 EMAC Auxillary Time Stamp Nano Register */ +#define EMAC0_TM_AUXSTMP_SEC 0xFFC20734 /* EMAC0 EMAC Auxillary Time Stamp Sec Register */ +#define EMAC0_DMA_BUSMODE 0xFFC21000 /* EMAC0 Bus Operating Modes for EMAC DMA */ +#define EMAC0_DMA_TXPOLL 0xFFC21004 /* EMAC0 TX DMA Poll demand register */ +#define EMAC0_DMA_RXPOLL 0xFFC21008 /* EMAC0 RX DMA Poll demand register */ +#define EMAC0_DMA_RXDSC_ADDR 0xFFC2100C /* EMAC0 RX Descriptor List Address */ +#define EMAC0_DMA_TXDSC_ADDR 0xFFC21010 /* EMAC0 TX Descriptor List Address */ +#define EMAC0_DMA_STAT 0xFFC21014 /* EMAC0 DMA Status Register */ +#define EMAC0_DMA_OPMODE 0xFFC21018 /* EMAC0 DMA Operation Mode Register */ +#define EMAC0_DMA_IEN 0xFFC2101C /* EMAC0 DMA Interrupt Enable Register */ +#define EMAC0_DMA_MISS_FRM 0xFFC21020 /* EMAC0 DMA missed frame and buffer overflow counter */ +#define EMAC0_DMA_RXIWDOG 0xFFC21024 /* EMAC0 DMA RX Interrupt Watch Dog timer */ +#define EMAC0_DMA_BMMODE 0xFFC21028 /* EMAC0 AXI Bus Mode Register */ +#define EMAC0_DMA_BMSTAT 0xFFC2102C /* EMAC0 AXI Status Register */ +#define EMAC0_DMA_TXDSC_CUR 0xFFC21048 /* EMAC0 TX current descriptor register */ +#define EMAC0_DMA_RXDSC_CUR 0xFFC2104C /* EMAC0 RX current descriptor register */ +#define EMAC0_DMA_TXBUF_CUR 0xFFC21050 /* EMAC0 TX current buffer pointer register */ +#define EMAC0_DMA_RXBUF_CUR 0xFFC21054 /* EMAC0 RX current buffer pointer register */ +#define EMAC0_HWFEAT 0xFFC21058 /* EMAC0 Hardware Feature Register */ + +/* ========================= + EMAC1 + ========================= */ +#define EMAC1_MACCFG 0xFFC22000 /* EMAC1 MAC Configuration Register */ +#define EMAC1_MACFRMFILT 0xFFC22004 /* EMAC1 Filter Register for filtering Received Frames */ +#define EMAC1_HASHTBL_HI 0xFFC22008 /* EMAC1 Contains the Upper 32 bits of the hash table */ +#define EMAC1_HASHTBL_LO 0xFFC2200C /* EMAC1 Contains the lower 32 bits of the hash table */ +#define EMAC1_GMII_ADDR 0xFFC22010 /* EMAC1 Management Address Register */ +#define EMAC1_GMII_DATA 0xFFC22014 /* EMAC1 Management Data Register */ +#define EMAC1_FLOWCTL 0xFFC22018 /* EMAC1 MAC FLow Control Register */ +#define EMAC1_VLANTAG 0xFFC2201C /* EMAC1 VLAN Tag Register */ +#define EMAC1_VER 0xFFC22020 /* EMAC1 EMAC Version Register */ +#define EMAC1_DBG 0xFFC22024 /* EMAC1 EMAC Debug Register */ +#define EMAC1_RMTWKUP 0xFFC22028 /* EMAC1 Remote wake up frame register */ +#define EMAC1_PMT_CTLSTAT 0xFFC2202C /* EMAC1 PMT Control and Status Register */ +#define EMAC1_ISTAT 0xFFC22038 /* EMAC1 EMAC Interrupt Status Register */ +#define EMAC1_IMSK 0xFFC2203C /* EMAC1 EMAC Interrupt Mask Register */ +#define EMAC1_ADDR0_HI 0xFFC22040 /* EMAC1 EMAC Address0 High Register */ +#define EMAC1_ADDR0_LO 0xFFC22044 /* EMAC1 EMAC Address0 Low Register */ +#define EMAC1_MMC_CTL 0xFFC22100 /* EMAC1 MMC Control Register */ +#define EMAC1_MMC_RXINT 0xFFC22104 /* EMAC1 MMC RX Interrupt Register */ +#define EMAC1_MMC_TXINT 0xFFC22108 /* EMAC1 MMC TX Interrupt Register */ +#define EMAC1_MMC_RXIMSK 0xFFC2210C /* EMAC1 MMC RX Interrupt Mask Register */ +#define EMAC1_MMC_TXIMSK 0xFFC22110 /* EMAC1 MMC TX Interrupt Mask Register */ +#define EMAC1_TXOCTCNT_GB 0xFFC22114 /* EMAC1 Num bytes transmitted exclusive of preamble */ +#define EMAC1_TXFRMCNT_GB 0xFFC22118 /* EMAC1 Num frames transmitted exclusive of retired */ +#define EMAC1_TXBCASTFRM_G 0xFFC2211C /* EMAC1 Number of good broadcast frames transmitted. */ +#define EMAC1_TXMCASTFRM_G 0xFFC22120 /* EMAC1 Number of good multicast frames transmitted. */ +#define EMAC1_TX64_GB 0xFFC22124 /* EMAC1 Number of 64 byte length frames */ +#define EMAC1_TX65TO127_GB 0xFFC22128 /* EMAC1 Number of frames of length b/w 65-127 (inclusive) bytes */ +#define EMAC1_TX128TO255_GB 0xFFC2212C /* EMAC1 Number of frames of length b/w 128-255 (inclusive) bytes */ +#define EMAC1_TX256TO511_GB 0xFFC22130 /* EMAC1 Number of frames of length b/w 256-511 (inclusive) bytes */ +#define EMAC1_TX512TO1023_GB 0xFFC22134 /* EMAC1 Number of frames of length b/w 512-1023 (inclusive) bytes */ +#define EMAC1_TX1024TOMAX_GB 0xFFC22138 /* EMAC1 Number of frames of length b/w 1024-max (inclusive) bytes */ +#define EMAC1_TXUCASTFRM_GB 0xFFC2213C /* EMAC1 Number of good and bad unicast frames transmitted */ +#define EMAC1_TXMCASTFRM_GB 0xFFC22140 /* EMAC1 Number of good and bad multicast frames transmitted */ +#define EMAC1_TXBCASTFRM_GB 0xFFC22144 /* EMAC1 Number of good and bad broadcast frames transmitted */ +#define EMAC1_TXUNDR_ERR 0xFFC22148 /* EMAC1 Number of frames aborted due to frame underflow error */ +#define EMAC1_TXSNGCOL_G 0xFFC2214C /* EMAC1 Number of transmitted frames after single collision */ +#define EMAC1_TXMULTCOL_G 0xFFC22150 /* EMAC1 Number of transmitted frames with more than one collision */ +#define EMAC1_TXDEFERRED 0xFFC22154 /* EMAC1 Number of transmitted frames after deferral */ +#define EMAC1_TXLATECOL 0xFFC22158 /* EMAC1 Number of frames aborted due to late collision error */ +#define EMAC1_TXEXCESSCOL 0xFFC2215C /* EMAC1 Number of aborted frames due to excessive collisions */ +#define EMAC1_TXCARR_ERR 0xFFC22160 /* EMAC1 Number of aborted frames due to carrier sense error */ +#define EMAC1_TXOCTCNT_G 0xFFC22164 /* EMAC1 Number of bytes transmitted in good frames only */ +#define EMAC1_TXFRMCNT_G 0xFFC22168 /* EMAC1 Number of good frames transmitted. */ +#define EMAC1_TXEXCESSDEF 0xFFC2216C /* EMAC1 Number of frames aborted due to excessive deferral */ +#define EMAC1_TXPAUSEFRM 0xFFC22170 /* EMAC1 Number of good PAUSE frames transmitted. */ +#define EMAC1_TXVLANFRM_G 0xFFC22174 /* EMAC1 Number of VLAN frames transmitted */ +#define EMAC1_RXFRMCNT_GB 0xFFC22180 /* EMAC1 Number of good and bad frames received. */ +#define EMAC1_RXOCTCNT_GB 0xFFC22184 /* EMAC1 Number of bytes received in good and bad frames */ +#define EMAC1_RXOCTCNT_G 0xFFC22188 /* EMAC1 Number of bytes received only in good frames */ +#define EMAC1_RXBCASTFRM_G 0xFFC2218C /* EMAC1 Number of good broadcast frames received. */ +#define EMAC1_RXMCASTFRM_G 0xFFC22190 /* EMAC1 Number of good multicast frames received */ +#define EMAC1_RXCRC_ERR 0xFFC22194 /* EMAC1 Number of frames received with CRC error */ +#define EMAC1_RXALIGN_ERR 0xFFC22198 /* EMAC1 Number of frames with alignment error */ +#define EMAC1_RXRUNT_ERR 0xFFC2219C /* EMAC1 Number of frames received with runt error. */ +#define EMAC1_RXJAB_ERR 0xFFC221A0 /* EMAC1 Number of frames received with length greater than 1518 */ +#define EMAC1_RXUSIZE_G 0xFFC221A4 /* EMAC1 Number of frames received with length 64 */ +#define EMAC1_RXOSIZE_G 0xFFC221A8 /* EMAC1 Number of frames received with length greater than maxium */ +#define EMAC1_RX64_GB 0xFFC221AC /* EMAC1 Number of good and bad frames of lengh 64 bytes */ +#define EMAC1_RX65TO127_GB 0xFFC221B0 /* EMAC1 Number of good and bad frame between 64-127(inclusive) */ +#define EMAC1_RX128TO255_GB 0xFFC221B4 /* EMAC1 Number of good and bad frames received with length between 128 and 255 (inclusive) bytes, exclusive of preamble. */ +#define EMAC1_RX256TO511_GB 0xFFC221B8 /* EMAC1 Number of good and bad frames between 256-511(inclusive) */ +#define EMAC1_RX512TO1023_GB 0xFFC221BC /* EMAC1 Number of good and bad frames received between 512-1023 */ +#define EMAC1_RX1024TOMAX_GB 0xFFC221C0 /* EMAC1 Number of frames received between 1024 and maxsize */ +#define EMAC1_RXUCASTFRM_G 0xFFC221C4 /* EMAC1 Number of good unicast frames received. */ +#define EMAC1_RXLEN_ERR 0xFFC221C8 /* EMAC1 Number of frames received with length error */ +#define EMAC1_RXOORTYPE 0xFFC221CC /* EMAC1 Number of frames with length not equal to valid frame size */ +#define EMAC1_RXPAUSEFRM 0xFFC221D0 /* EMAC1 Number of good and valid PAUSE frames received. */ +#define EMAC1_RXFIFO_OVF 0xFFC221D4 /* EMAC1 Number of missed received frames due to FIFO overflow. This counter is not present in the GMAC-CORE configuration. */ +#define EMAC1_RXVLANFRM_GB 0xFFC221D8 /* EMAC1 Number of good and bad VLAN frames received. */ +#define EMAC1_RXWDOG_ERR 0xFFC221DC /* EMAC1 Frames received with error due to watchdog timeout */ +#define EMAC1_IPC_RXIMSK 0xFFC22200 /* EMAC1 MMC IPC RX Interrupt Mask Register */ +#define EMAC1_IPC_RXINT 0xFFC22208 /* EMAC1 MMC IPC RX Interrupt Register */ +#define EMAC1_RXIPV4_GD_FRM 0xFFC22210 /* EMAC1 Number of good IPv4 datagrams */ +#define EMAC1_RXIPV4_HDR_ERR_FRM 0xFFC22214 /* EMAC1 Number of IPv4 datagrams with header errors */ +#define EMAC1_RXIPV4_NOPAY_FRM 0xFFC22218 /* EMAC1 Number of IPv4 datagrams without checksum */ +#define EMAC1_RXIPV4_FRAG_FRM 0xFFC2221C /* EMAC1 Number of good IPv4 datagrams with fragmentation */ +#define EMAC1_RXIPV4_UDSBL_FRM 0xFFC22220 /* EMAC1 Number of IPv4 UDP datagrams with disabled checksum */ +#define EMAC1_RXIPV6_GD_FRM 0xFFC22224 /* EMAC1 Number of IPv4 datagrams with TCP/UDP/ICMP payloads */ +#define EMAC1_RXIPV6_HDR_ERR_FRM 0xFFC22228 /* EMAC1 Number of IPv6 datagrams with header errors */ +#define EMAC1_RXIPV6_NOPAY_FRM 0xFFC2222C /* EMAC1 Number of IPv6 datagrams with no TCP/UDP/ICMP payload */ +#define EMAC1_RXUDP_GD_FRM 0xFFC22230 /* EMAC1 Number of good IP datagrames with good UDP payload */ +#define EMAC1_RXUDP_ERR_FRM 0xFFC22234 /* EMAC1 Number of good IP datagrams with UDP checksum errors */ +#define EMAC1_RXTCP_GD_FRM 0xFFC22238 /* EMAC1 Number of good IP datagrams with a good TCP payload */ +#define EMAC1_RXTCP_ERR_FRM 0xFFC2223C /* EMAC1 Number of good IP datagrams with TCP checksum errors */ +#define EMAC1_RXICMP_GD_FRM 0xFFC22240 /* EMAC1 Number of good IP datagrams with a good ICMP payload */ +#define EMAC1_RXICMP_ERR_FRM 0xFFC22244 /* EMAC1 Number of good IP datagrams with ICMP checksum errors */ +#define EMAC1_RXIPV4_GD_OCT 0xFFC22250 /* EMAC1 Bytes received in IPv4 datagrams including tcp,udp or icmp */ +#define EMAC1_RXIPV4_HDR_ERR_OCT 0xFFC22254 /* EMAC1 Bytes received in IPv4 datagrams with header errors */ +#define EMAC1_RXIPV4_NOPAY_OCT 0xFFC22258 /* EMAC1 Bytes received in IPv4 datagrams without tcp,udp,icmp load */ +#define EMAC1_RXIPV4_FRAG_OCT 0xFFC2225C /* EMAC1 Bytes received in fragmented IPv4 datagrams */ +#define EMAC1_RXIPV4_UDSBL_OCT 0xFFC22260 /* EMAC1 Bytes received in UDP segment with checksum disabled */ +#define EMAC1_RXIPV6_GD_OCT 0xFFC22264 /* EMAC1 Bytes received in good IPv6 including tcp,udp or icmp load */ +#define EMAC1_RXIPV6_HDR_ERR_OCT 0xFFC22268 /* EMAC1 Number of bytes received in IPv6 with header errors */ +#define EMAC1_RXIPV6_NOPAY_OCT 0xFFC2226C /* EMAC1 Bytes received in IPv6 without tcp,udp or icmp load */ +#define EMAC1_RXUDP_GD_OCT 0xFFC22270 /* EMAC1 Number of bytes received in good UDP segments */ +#define EMAC1_RXUDP_ERR_OCT 0xFFC22274 /* EMAC1 Number of bytes received in UDP segment with checksum err */ +#define EMAC1_RXTCP_GD_OCT 0xFFC22278 /* EMAC1 Number of bytes received in a good TCP segment */ +#define EMAC1_RXTCP_ERR_OCT 0xFFC2227C /* EMAC1 Number of bytes received in TCP segment with checksum err */ +#define EMAC1_RXICMP_GD_OCT 0xFFC22280 /* EMAC1 Number of bytes received in a good ICMP segment */ +#define EMAC1_RXICMP_ERR_OCT 0xFFC22284 /* EMAC1 Bytes received in an ICMP segment with checksum errors */ +#define EMAC1_TM_CTL 0xFFC22700 /* EMAC1 EMAC Time Stamp Control Register */ +#define EMAC1_TM_SUBSEC 0xFFC22704 /* EMAC1 EMAC Time Stamp Sub Second Increment */ +#define EMAC1_TM_SEC 0xFFC22708 /* EMAC1 EMAC Time Stamp Second Register */ +#define EMAC1_TM_NSEC 0xFFC2270C /* EMAC1 EMAC Time Stamp Nano Second Register */ +#define EMAC1_TM_SECUPDT 0xFFC22710 /* EMAC1 EMAC Time Stamp Seconds Update */ +#define EMAC1_TM_NSECUPDT 0xFFC22714 /* EMAC1 EMAC Time Stamp Nano Seconds Update */ +#define EMAC1_TM_ADDEND 0xFFC22718 /* EMAC1 EMAC Time Stamp Addend Register */ +#define EMAC1_TM_TGTM 0xFFC2271C /* EMAC1 EMAC Time Stamp Target Time Sec. */ +#define EMAC1_TM_NTGTM 0xFFC22720 /* EMAC1 EMAC Time Stamp Target Time Nanosec. */ +#define EMAC1_TM_HISEC 0xFFC22724 /* EMAC1 EMAC Time Stamp High Second Register */ +#define EMAC1_TM_STMPSTAT 0xFFC22728 /* EMAC1 EMAC Time Stamp Status Register */ +#define EMAC1_TM_PPSCTL 0xFFC2272C /* EMAC1 EMAC PPS Control Register */ +#define EMAC1_TM_AUXSTMP_NSEC 0xFFC22730 /* EMAC1 EMAC Auxillary Time Stamp Nano Register */ +#define EMAC1_TM_AUXSTMP_SEC 0xFFC22734 /* EMAC1 EMAC Auxillary Time Stamp Sec Register */ +#define EMAC1_DMA_BUSMODE 0xFFC23000 /* EMAC1 Bus Operating Modes for EMAC DMA */ +#define EMAC1_DMA_TXPOLL 0xFFC23004 /* EMAC1 TX DMA Poll demand register */ +#define EMAC1_DMA_RXPOLL 0xFFC23008 /* EMAC1 RX DMA Poll demand register */ +#define EMAC1_DMA_RXDSC_ADDR 0xFFC2300C /* EMAC1 RX Descriptor List Address */ +#define EMAC1_DMA_TXDSC_ADDR 0xFFC23010 /* EMAC1 TX Descriptor List Address */ +#define EMAC1_DMA_STAT 0xFFC23014 /* EMAC1 DMA Status Register */ +#define EMAC1_DMA_OPMODE 0xFFC23018 /* EMAC1 DMA Operation Mode Register */ +#define EMAC1_DMA_IEN 0xFFC2301C /* EMAC1 DMA Interrupt Enable Register */ +#define EMAC1_DMA_MISS_FRM 0xFFC23020 /* EMAC1 DMA missed frame and buffer overflow counter */ +#define EMAC1_DMA_RXIWDOG 0xFFC23024 /* EMAC1 DMA RX Interrupt Watch Dog timer */ +#define EMAC1_DMA_BMMODE 0xFFC23028 /* EMAC1 AXI Bus Mode Register */ +#define EMAC1_DMA_BMSTAT 0xFFC2302C /* EMAC1 AXI Status Register */ +#define EMAC1_DMA_TXDSC_CUR 0xFFC23048 /* EMAC1 TX current descriptor register */ +#define EMAC1_DMA_RXDSC_CUR 0xFFC2304C /* EMAC1 RX current descriptor register */ +#define EMAC1_DMA_TXBUF_CUR 0xFFC23050 /* EMAC1 TX current buffer pointer register */ +#define EMAC1_DMA_RXBUF_CUR 0xFFC23054 /* EMAC1 RX current buffer pointer register */ +#define EMAC1_HWFEAT 0xFFC23058 /* EMAC1 Hardware Feature Register */ + + +/* ========================= + SPI Registers + ========================= */ + +/* ========================= + SPI0 + ========================= */ +#define SPI0_REGBASE 0xFFC40400 +#define SPI0_CTL 0xFFC40404 /* SPI0 Control Register */ +#define SPI0_RXCTL 0xFFC40408 /* SPI0 RX Control Register */ +#define SPI0_TXCTL 0xFFC4040C /* SPI0 TX Control Register */ +#define SPI0_CLK 0xFFC40410 /* SPI0 Clock Rate Register */ +#define SPI0_DLY 0xFFC40414 /* SPI0 Delay Register */ +#define SPI0_SLVSEL 0xFFC40418 /* SPI0 Slave Select Register */ +#define SPI0_RWC 0xFFC4041C /* SPI0 Received Word-Count Register */ +#define SPI0_RWCR 0xFFC40420 /* SPI0 Received Word-Count Reload Register */ +#define SPI0_TWC 0xFFC40424 /* SPI0 Transmitted Word-Count Register */ +#define SPI0_TWCR 0xFFC40428 /* SPI0 Transmitted Word-Count Reload Register */ +#define SPI0_IMSK 0xFFC40430 /* SPI0 Interrupt Mask Register */ +#define SPI0_IMSK_CLR 0xFFC40434 /* SPI0 Interrupt Mask Clear Register */ +#define SPI0_IMSK_SET 0xFFC40438 /* SPI0 Interrupt Mask Set Register */ +#define SPI0_STAT 0xFFC40440 /* SPI0 Status Register */ +#define SPI0_ILAT 0xFFC40444 /* SPI0 Masked Interrupt Condition Register */ +#define SPI0_ILAT_CLR 0xFFC40448 /* SPI0 Masked Interrupt Clear Register */ +#define SPI0_RFIFO 0xFFC40450 /* SPI0 Receive FIFO Data Register */ +#define SPI0_TFIFO 0xFFC40458 /* SPI0 Transmit FIFO Data Register */ + +/* ========================= + SPI1 + ========================= */ +#define SPI1_REGBASE 0xFFC40500 +#define SPI1_CTL 0xFFC40504 /* SPI1 Control Register */ +#define SPI1_RXCTL 0xFFC40508 /* SPI1 RX Control Register */ +#define SPI1_TXCTL 0xFFC4050C /* SPI1 TX Control Register */ +#define SPI1_CLK 0xFFC40510 /* SPI1 Clock Rate Register */ +#define SPI1_DLY 0xFFC40514 /* SPI1 Delay Register */ +#define SPI1_SLVSEL 0xFFC40518 /* SPI1 Slave Select Register */ +#define SPI1_RWC 0xFFC4051C /* SPI1 Received Word-Count Register */ +#define SPI1_RWCR 0xFFC40520 /* SPI1 Received Word-Count Reload Register */ +#define SPI1_TWC 0xFFC40524 /* SPI1 Transmitted Word-Count Register */ +#define SPI1_TWCR 0xFFC40528 /* SPI1 Transmitted Word-Count Reload Register */ +#define SPI1_IMSK 0xFFC40530 /* SPI1 Interrupt Mask Register */ +#define SPI1_IMSK_CLR 0xFFC40534 /* SPI1 Interrupt Mask Clear Register */ +#define SPI1_IMSK_SET 0xFFC40538 /* SPI1 Interrupt Mask Set Register */ +#define SPI1_STAT 0xFFC40540 /* SPI1 Status Register */ +#define SPI1_ILAT 0xFFC40544 /* SPI1 Masked Interrupt Condition Register */ +#define SPI1_ILAT_CLR 0xFFC40548 /* SPI1 Masked Interrupt Clear Register */ +#define SPI1_RFIFO 0xFFC40550 /* SPI1 Receive FIFO Data Register */ +#define SPI1_TFIFO 0xFFC40558 /* SPI1 Transmit FIFO Data Register */ + +/* ========================= + SPORT Registers + ========================= */ + +/* ========================= + SPORT0 + ========================= */ +#define SPORT0_CTL_A 0xFFC40000 /* SPORT0 'A' Control Register */ +#define SPORT0_DIV_A 0xFFC40004 /* SPORT0 'A' Clock and FS Divide Register */ +#define SPORT0_MCTL_A 0xFFC40008 /* SPORT0 'A' Multichannel Control Register */ +#define SPORT0_CS0_A 0xFFC4000C /* SPORT0 'A' Multichannel Select Register (Channels 0-31) */ +#define SPORT0_CS1_A 0xFFC40010 /* SPORT0 'A' Multichannel Select Register (Channels 32-63) */ +#define SPORT0_CS2_A 0xFFC40014 /* SPORT0 'A' Multichannel Select Register (Channels 64-95) */ +#define SPORT0_CS3_A 0xFFC40018 /* SPORT0 'A' Multichannel Select Register (Channels 96-127) */ +#define SPORT0_CNT_A 0xFFC4001C /* SPORT0 'A' Frame Sync And Clock Divisor Current Count */ +#define SPORT0_ERR_A 0xFFC40020 /* SPORT0 'A' Error Register */ +#define SPORT0_MSTAT_A 0xFFC40024 /* SPORT0 'A' Multichannel Mode Status Register */ +#define SPORT0_CTL2_A 0xFFC40028 /* SPORT0 'A' Control Register 2 */ +#define SPORT0_TXPRI_A 0xFFC40040 /* SPORT0 'A' Primary Channel Transmit Buffer Register */ +#define SPORT0_RXPRI_A 0xFFC40044 /* SPORT0 'A' Primary Channel Receive Buffer Register */ +#define SPORT0_TXSEC_A 0xFFC40048 /* SPORT0 'A' Secondary Channel Transmit Buffer Register */ +#define SPORT0_RXSEC_A 0xFFC4004C /* SPORT0 'A' Secondary Channel Receive Buffer Register */ +#define SPORT0_CTL_B 0xFFC40080 /* SPORT0 'B' Control Register */ +#define SPORT0_DIV_B 0xFFC40084 /* SPORT0 'B' Clock and FS Divide Register */ +#define SPORT0_MCTL_B 0xFFC40088 /* SPORT0 'B' Multichannel Control Register */ +#define SPORT0_CS0_B 0xFFC4008C /* SPORT0 'B' Multichannel Select Register (Channels 0-31) */ +#define SPORT0_CS1_B 0xFFC40090 /* SPORT0 'B' Multichannel Select Register (Channels 32-63) */ +#define SPORT0_CS2_B 0xFFC40094 /* SPORT0 'B' Multichannel Select Register (Channels 64-95) */ +#define SPORT0_CS3_B 0xFFC40098 /* SPORT0 'B' Multichannel Select Register (Channels 96-127) */ +#define SPORT0_CNT_B 0xFFC4009C /* SPORT0 'B' Frame Sync And Clock Divisor Current Count */ +#define SPORT0_ERR_B 0xFFC400A0 /* SPORT0 'B' Error Register */ +#define SPORT0_MSTAT_B 0xFFC400A4 /* SPORT0 'B' Multichannel Mode Status Register */ +#define SPORT0_CTL2_B 0xFFC400A8 /* SPORT0 'B' Control Register 2 */ +#define SPORT0_TXPRI_B 0xFFC400C0 /* SPORT0 'B' Primary Channel Transmit Buffer Register */ +#define SPORT0_RXPRI_B 0xFFC400C4 /* SPORT0 'B' Primary Channel Receive Buffer Register */ +#define SPORT0_TXSEC_B 0xFFC400C8 /* SPORT0 'B' Secondary Channel Transmit Buffer Register */ +#define SPORT0_RXSEC_B 0xFFC400CC /* SPORT0 'B' Secondary Channel Receive Buffer Register */ + +/* ========================= + SPORT1 + ========================= */ +#define SPORT1_CTL_A 0xFFC40100 /* SPORT1 'A' Control Register */ +#define SPORT1_DIV_A 0xFFC40104 /* SPORT1 'A' Clock and FS Divide Register */ +#define SPORT1_MCTL_A 0xFFC40108 /* SPORT1 'A' Multichannel Control Register */ +#define SPORT1_CS0_A 0xFFC4010C /* SPORT1 'A' Multichannel Select Register (Channels 0-31) */ +#define SPORT1_CS1_A 0xFFC40110 /* SPORT1 'A' Multichannel Select Register (Channels 32-63) */ +#define SPORT1_CS2_A 0xFFC40114 /* SPORT1 'A' Multichannel Select Register (Channels 64-95) */ +#define SPORT1_CS3_A 0xFFC40118 /* SPORT1 'A' Multichannel Select Register (Channels 96-127) */ +#define SPORT1_CNT_A 0xFFC4011C /* SPORT1 'A' Frame Sync And Clock Divisor Current Count */ +#define SPORT1_ERR_A 0xFFC40120 /* SPORT1 'A' Error Register */ +#define SPORT1_MSTAT_A 0xFFC40124 /* SPORT1 'A' Multichannel Mode Status Register */ +#define SPORT1_CTL2_A 0xFFC40128 /* SPORT1 'A' Control Register 2 */ +#define SPORT1_TXPRI_A 0xFFC40140 /* SPORT1 'A' Primary Channel Transmit Buffer Register */ +#define SPORT1_RXPRI_A 0xFFC40144 /* SPORT1 'A' Primary Channel Receive Buffer Register */ +#define SPORT1_TXSEC_A 0xFFC40148 /* SPORT1 'A' Secondary Channel Transmit Buffer Register */ +#define SPORT1_RXSEC_A 0xFFC4014C /* SPORT1 'A' Secondary Channel Receive Buffer Register */ +#define SPORT1_CTL_B 0xFFC40180 /* SPORT1 'B' Control Register */ +#define SPORT1_DIV_B 0xFFC40184 /* SPORT1 'B' Clock and FS Divide Register */ +#define SPORT1_MCTL_B 0xFFC40188 /* SPORT1 'B' Multichannel Control Register */ +#define SPORT1_CS0_B 0xFFC4018C /* SPORT1 'B' Multichannel Select Register (Channels 0-31) */ +#define SPORT1_CS1_B 0xFFC40190 /* SPORT1 'B' Multichannel Select Register (Channels 32-63) */ +#define SPORT1_CS2_B 0xFFC40194 /* SPORT1 'B' Multichannel Select Register (Channels 64-95) */ +#define SPORT1_CS3_B 0xFFC40198 /* SPORT1 'B' Multichannel Select Register (Channels 96-127) */ +#define SPORT1_CNT_B 0xFFC4019C /* SPORT1 'B' Frame Sync And Clock Divisor Current Count */ +#define SPORT1_ERR_B 0xFFC401A0 /* SPORT1 'B' Error Register */ +#define SPORT1_MSTAT_B 0xFFC401A4 /* SPORT1 'B' Multichannel Mode Status Register */ +#define SPORT1_CTL2_B 0xFFC401A8 /* SPORT1 'B' Control Register 2 */ +#define SPORT1_TXPRI_B 0xFFC401C0 /* SPORT1 'B' Primary Channel Transmit Buffer Register */ +#define SPORT1_RXPRI_B 0xFFC401C4 /* SPORT1 'B' Primary Channel Receive Buffer Register */ +#define SPORT1_TXSEC_B 0xFFC401C8 /* SPORT1 'B' Secondary Channel Transmit Buffer Register */ +#define SPORT1_RXSEC_B 0xFFC401CC /* SPORT1 'B' Secondary Channel Receive Buffer Register */ + +/* ========================= + SPORT2 + ========================= */ +#define SPORT2_CTL_A 0xFFC40200 /* SPORT2 'A' Control Register */ +#define SPORT2_DIV_A 0xFFC40204 /* SPORT2 'A' Clock and FS Divide Register */ +#define SPORT2_MCTL_A 0xFFC40208 /* SPORT2 'A' Multichannel Control Register */ +#define SPORT2_CS0_A 0xFFC4020C /* SPORT2 'A' Multichannel Select Register (Channels 0-31) */ +#define SPORT2_CS1_A 0xFFC40210 /* SPORT2 'A' Multichannel Select Register (Channels 32-63) */ +#define SPORT2_CS2_A 0xFFC40214 /* SPORT2 'A' Multichannel Select Register (Channels 64-95) */ +#define SPORT2_CS3_A 0xFFC40218 /* SPORT2 'A' Multichannel Select Register (Channels 96-127) */ +#define SPORT2_CNT_A 0xFFC4021C /* SPORT2 'A' Frame Sync And Clock Divisor Current Count */ +#define SPORT2_ERR_A 0xFFC40220 /* SPORT2 'A' Error Register */ +#define SPORT2_MSTAT_A 0xFFC40224 /* SPORT2 'A' Multichannel Mode Status Register */ +#define SPORT2_CTL2_A 0xFFC40228 /* SPORT2 'A' Control Register 2 */ +#define SPORT2_TXPRI_A 0xFFC40240 /* SPORT2 'A' Primary Channel Transmit Buffer Register */ +#define SPORT2_RXPRI_A 0xFFC40244 /* SPORT2 'A' Primary Channel Receive Buffer Register */ +#define SPORT2_TXSEC_A 0xFFC40248 /* SPORT2 'A' Secondary Channel Transmit Buffer Register */ +#define SPORT2_RXSEC_A 0xFFC4024C /* SPORT2 'A' Secondary Channel Receive Buffer Register */ +#define SPORT2_CTL_B 0xFFC40280 /* SPORT2 'B' Control Register */ +#define SPORT2_DIV_B 0xFFC40284 /* SPORT2 'B' Clock and FS Divide Register */ +#define SPORT2_MCTL_B 0xFFC40288 /* SPORT2 'B' Multichannel Control Register */ +#define SPORT2_CS0_B 0xFFC4028C /* SPORT2 'B' Multichannel Select Register (Channels 0-31) */ +#define SPORT2_CS1_B 0xFFC40290 /* SPORT2 'B' Multichannel Select Register (Channels 32-63) */ +#define SPORT2_CS2_B 0xFFC40294 /* SPORT2 'B' Multichannel Select Register (Channels 64-95) */ +#define SPORT2_CS3_B 0xFFC40298 /* SPORT2 'B' Multichannel Select Register (Channels 96-127) */ +#define SPORT2_CNT_B 0xFFC4029C /* SPORT2 'B' Frame Sync And Clock Divisor Current Count */ +#define SPORT2_ERR_B 0xFFC402A0 /* SPORT2 'B' Error Register */ +#define SPORT2_MSTAT_B 0xFFC402A4 /* SPORT2 'B' Multichannel Mode Status Register */ +#define SPORT2_CTL2_B 0xFFC402A8 /* SPORT2 'B' Control Register 2 */ +#define SPORT2_TXPRI_B 0xFFC402C0 /* SPORT2 'B' Primary Channel Transmit Buffer Register */ +#define SPORT2_RXPRI_B 0xFFC402C4 /* SPORT2 'B' Primary Channel Receive Buffer Register */ +#define SPORT2_TXSEC_B 0xFFC402C8 /* SPORT2 'B' Secondary Channel Transmit Buffer Register */ +#define SPORT2_RXSEC_B 0xFFC402CC /* SPORT2 'B' Secondary Channel Receive Buffer Register */ + +/* ========================= + EPPI Registers + ========================= */ + +/* ========================= + EPPI0 + ========================= */ +#define EPPI0_STAT 0xFFC18000 /* EPPI0 Status Register */ +#define EPPI0_HCNT 0xFFC18004 /* EPPI0 Horizontal Transfer Count Register */ +#define EPPI0_HDLY 0xFFC18008 /* EPPI0 Horizontal Delay Count Register */ +#define EPPI0_VCNT 0xFFC1800C /* EPPI0 Vertical Transfer Count Register */ +#define EPPI0_VDLY 0xFFC18010 /* EPPI0 Vertical Delay Count Register */ +#define EPPI0_FRAME 0xFFC18014 /* EPPI0 Lines Per Frame Register */ +#define EPPI0_LINE 0xFFC18018 /* EPPI0 Samples Per Line Register */ +#define EPPI0_CLKDIV 0xFFC1801C /* EPPI0 Clock Divide Register */ +#define EPPI0_CTL 0xFFC18020 /* EPPI0 Control Register */ +#define EPPI0_FS1_WLHB 0xFFC18024 /* EPPI0 FS1 Width Register / EPPI Horizontal Blanking Samples Per Line Register */ +#define EPPI0_FS1_PASPL 0xFFC18028 /* EPPI0 FS1 Period Register / EPPI Active Samples Per Line Register */ +#define EPPI0_FS2_WLVB 0xFFC1802C /* EPPI0 FS2 Width Register / EPPI Lines Of Vertical Blanking Register */ +#define EPPI0_FS2_PALPF 0xFFC18030 /* EPPI0 FS2 Period Register / EPPI Active Lines Per Field Register */ +#define EPPI0_IMSK 0xFFC18034 /* EPPI0 Interrupt Mask Register */ +#define EPPI0_ODDCLIP 0xFFC1803C /* EPPI0 Clipping Register for ODD (Chroma) Data */ +#define EPPI0_EVENCLIP 0xFFC18040 /* EPPI0 Clipping Register for EVEN (Luma) Data */ +#define EPPI0_FS1_DLY 0xFFC18044 /* EPPI0 Frame Sync 1 Delay Value */ +#define EPPI0_FS2_DLY 0xFFC18048 /* EPPI0 Frame Sync 2 Delay Value */ +#define EPPI0_CTL2 0xFFC1804C /* EPPI0 Control Register 2 */ + +/* ========================= + EPPI1 + ========================= */ +#define EPPI1_STAT 0xFFC18400 /* EPPI1 Status Register */ +#define EPPI1_HCNT 0xFFC18404 /* EPPI1 Horizontal Transfer Count Register */ +#define EPPI1_HDLY 0xFFC18408 /* EPPI1 Horizontal Delay Count Register */ +#define EPPI1_VCNT 0xFFC1840C /* EPPI1 Vertical Transfer Count Register */ +#define EPPI1_VDLY 0xFFC18410 /* EPPI1 Vertical Delay Count Register */ +#define EPPI1_FRAME 0xFFC18414 /* EPPI1 Lines Per Frame Register */ +#define EPPI1_LINE 0xFFC18418 /* EPPI1 Samples Per Line Register */ +#define EPPI1_CLKDIV 0xFFC1841C /* EPPI1 Clock Divide Register */ +#define EPPI1_CTL 0xFFC18420 /* EPPI1 Control Register */ +#define EPPI1_FS1_WLHB 0xFFC18424 /* EPPI1 FS1 Width Register / EPPI Horizontal Blanking Samples Per Line Register */ +#define EPPI1_FS1_PASPL 0xFFC18428 /* EPPI1 FS1 Period Register / EPPI Active Samples Per Line Register */ +#define EPPI1_FS2_WLVB 0xFFC1842C /* EPPI1 FS2 Width Register / EPPI Lines Of Vertical Blanking Register */ +#define EPPI1_FS2_PALPF 0xFFC18430 /* EPPI1 FS2 Period Register / EPPI Active Lines Per Field Register */ +#define EPPI1_IMSK 0xFFC18434 /* EPPI1 Interrupt Mask Register */ +#define EPPI1_ODDCLIP 0xFFC1843C /* EPPI1 Clipping Register for ODD (Chroma) Data */ +#define EPPI1_EVENCLIP 0xFFC18440 /* EPPI1 Clipping Register for EVEN (Luma) Data */ +#define EPPI1_FS1_DLY 0xFFC18444 /* EPPI1 Frame Sync 1 Delay Value */ +#define EPPI1_FS2_DLY 0xFFC18448 /* EPPI1 Frame Sync 2 Delay Value */ +#define EPPI1_CTL2 0xFFC1844C /* EPPI1 Control Register 2 */ + +/* ========================= + EPPI2 + ========================= */ +#define EPPI2_STAT 0xFFC18800 /* EPPI2 Status Register */ +#define EPPI2_HCNT 0xFFC18804 /* EPPI2 Horizontal Transfer Count Register */ +#define EPPI2_HDLY 0xFFC18808 /* EPPI2 Horizontal Delay Count Register */ +#define EPPI2_VCNT 0xFFC1880C /* EPPI2 Vertical Transfer Count Register */ +#define EPPI2_VDLY 0xFFC18810 /* EPPI2 Vertical Delay Count Register */ +#define EPPI2_FRAME 0xFFC18814 /* EPPI2 Lines Per Frame Register */ +#define EPPI2_LINE 0xFFC18818 /* EPPI2 Samples Per Line Register */ +#define EPPI2_CLKDIV 0xFFC1881C /* EPPI2 Clock Divide Register */ +#define EPPI2_CTL 0xFFC18820 /* EPPI2 Control Register */ +#define EPPI2_FS1_WLHB 0xFFC18824 /* EPPI2 FS1 Width Register / EPPI Horizontal Blanking Samples Per Line Register */ +#define EPPI2_FS1_PASPL 0xFFC18828 /* EPPI2 FS1 Period Register / EPPI Active Samples Per Line Register */ +#define EPPI2_FS2_WLVB 0xFFC1882C /* EPPI2 FS2 Width Register / EPPI Lines Of Vertical Blanking Register */ +#define EPPI2_FS2_PALPF 0xFFC18830 /* EPPI2 FS2 Period Register / EPPI Active Lines Per Field Register */ +#define EPPI2_IMSK 0xFFC18834 /* EPPI2 Interrupt Mask Register */ +#define EPPI2_ODDCLIP 0xFFC1883C /* EPPI2 Clipping Register for ODD (Chroma) Data */ +#define EPPI2_EVENCLIP 0xFFC18840 /* EPPI2 Clipping Register for EVEN (Luma) Data */ +#define EPPI2_FS1_DLY 0xFFC18844 /* EPPI2 Frame Sync 1 Delay Value */ +#define EPPI2_FS2_DLY 0xFFC18848 /* EPPI2 Frame Sync 2 Delay Value */ +#define EPPI2_CTL2 0xFFC1884C /* EPPI2 Control Register 2 */ + + + +/* ========================= + DDE Registers + ========================= */ + +/* ========================= + DMA0 + ========================= */ +#define DMA0_NEXT_DESC_PTR 0xFFC41000 /* DMA0 Pointer to Next Initial Descriptor */ +#define DMA0_START_ADDR 0xFFC41004 /* DMA0 Start Address of Current Buffer */ +#define DMA0_CONFIG 0xFFC41008 /* DMA0 Configuration Register */ +#define DMA0_X_COUNT 0xFFC4100C /* DMA0 Inner Loop Count Start Value */ +#define DMA0_X_MODIFY 0xFFC41010 /* DMA0 Inner Loop Address Increment */ +#define DMA0_Y_COUNT 0xFFC41014 /* DMA0 Outer Loop Count Start Value (2D only) */ +#define DMA0_Y_MODIFY 0xFFC41018 /* DMA0 Outer Loop Address Increment (2D only) */ +#define DMA0_CURR_DESC_PTR 0xFFC41024 /* DMA0 Current Descriptor Pointer */ +#define DMA0_PREV_DESC_PTR 0xFFC41028 /* DMA0 Previous Initial Descriptor Pointer */ +#define DMA0_CURR_ADDR 0xFFC4102C /* DMA0 Current Address */ +#define DMA0_IRQ_STATUS 0xFFC41030 /* DMA0 Status Register */ +#define DMA0_CURR_X_COUNT 0xFFC41034 /* DMA0 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA0_CURR_Y_COUNT 0xFFC41038 /* DMA0 Current Row Count (2D only) */ +#define DMA0_BWL_COUNT 0xFFC41040 /* DMA0 Bandwidth Limit Count */ +#define DMA0_CURR_BWL_COUNT 0xFFC41044 /* DMA0 Bandwidth Limit Count Current */ +#define DMA0_BWM_COUNT 0xFFC41048 /* DMA0 Bandwidth Monitor Count */ +#define DMA0_CURR_BWM_COUNT 0xFFC4104C /* DMA0 Bandwidth Monitor Count Current */ + +/* ========================= + DMA1 + ========================= */ +#define DMA1_NEXT_DESC_PTR 0xFFC41080 /* DMA1 Pointer to Next Initial Descriptor */ +#define DMA1_START_ADDR 0xFFC41084 /* DMA1 Start Address of Current Buffer */ +#define DMA1_CONFIG 0xFFC41088 /* DMA1 Configuration Register */ +#define DMA1_X_COUNT 0xFFC4108C /* DMA1 Inner Loop Count Start Value */ +#define DMA1_X_MODIFY 0xFFC41090 /* DMA1 Inner Loop Address Increment */ +#define DMA1_Y_COUNT 0xFFC41094 /* DMA1 Outer Loop Count Start Value (2D only) */ +#define DMA1_Y_MODIFY 0xFFC41098 /* DMA1 Outer Loop Address Increment (2D only) */ +#define DMA1_CURR_DESC_PTR 0xFFC410A4 /* DMA1 Current Descriptor Pointer */ +#define DMA1_PREV_DESC_PTR 0xFFC410A8 /* DMA1 Previous Initial Descriptor Pointer */ +#define DMA1_CURR_ADDR 0xFFC410AC /* DMA1 Current Address */ +#define DMA1_IRQ_STATUS 0xFFC410B0 /* DMA1 Status Register */ +#define DMA1_CURR_X_COUNT 0xFFC410B4 /* DMA1 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA1_CURR_Y_COUNT 0xFFC410B8 /* DMA1 Current Row Count (2D only) */ +#define DMA1_BWL_COUNT 0xFFC410C0 /* DMA1 Bandwidth Limit Count */ +#define DMA1_CURR_BWL_COUNT 0xFFC410C4 /* DMA1 Bandwidth Limit Count Current */ +#define DMA1_BWM_COUNT 0xFFC410C8 /* DMA1 Bandwidth Monitor Count */ +#define DMA1_CURR_BWM_COUNT 0xFFC410CC /* DMA1 Bandwidth Monitor Count Current */ + +/* ========================= + DMA2 + ========================= */ +#define DMA2_NEXT_DESC_PTR 0xFFC41100 /* DMA2 Pointer to Next Initial Descriptor */ +#define DMA2_START_ADDR 0xFFC41104 /* DMA2 Start Address of Current Buffer */ +#define DMA2_CONFIG 0xFFC41108 /* DMA2 Configuration Register */ +#define DMA2_X_COUNT 0xFFC4110C /* DMA2 Inner Loop Count Start Value */ +#define DMA2_X_MODIFY 0xFFC41110 /* DMA2 Inner Loop Address Increment */ +#define DMA2_Y_COUNT 0xFFC41114 /* DMA2 Outer Loop Count Start Value (2D only) */ +#define DMA2_Y_MODIFY 0xFFC41118 /* DMA2 Outer Loop Address Increment (2D only) */ +#define DMA2_CURR_DESC_PTR 0xFFC41124 /* DMA2 Current Descriptor Pointer */ +#define DMA2_PREV_DESC_PTR 0xFFC41128 /* DMA2 Previous Initial Descriptor Pointer */ +#define DMA2_CURR_ADDR 0xFFC4112C /* DMA2 Current Address */ +#define DMA2_IRQ_STATUS 0xFFC41130 /* DMA2 Status Register */ +#define DMA2_CURR_X_COUNT 0xFFC41134 /* DMA2 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA2_CURR_Y_COUNT 0xFFC41138 /* DMA2 Current Row Count (2D only) */ +#define DMA2_BWL_COUNT 0xFFC41140 /* DMA2 Bandwidth Limit Count */ +#define DMA2_CURR_BWL_COUNT 0xFFC41144 /* DMA2 Bandwidth Limit Count Current */ +#define DMA2_BWM_COUNT 0xFFC41148 /* DMA2 Bandwidth Monitor Count */ +#define DMA2_CURR_BWM_COUNT 0xFFC4114C /* DMA2 Bandwidth Monitor Count Current */ + +/* ========================= + DMA3 + ========================= */ +#define DMA3_NEXT_DESC_PTR 0xFFC41180 /* DMA3 Pointer to Next Initial Descriptor */ +#define DMA3_START_ADDR 0xFFC41184 /* DMA3 Start Address of Current Buffer */ +#define DMA3_CONFIG 0xFFC41188 /* DMA3 Configuration Register */ +#define DMA3_X_COUNT 0xFFC4118C /* DMA3 Inner Loop Count Start Value */ +#define DMA3_X_MODIFY 0xFFC41190 /* DMA3 Inner Loop Address Increment */ +#define DMA3_Y_COUNT 0xFFC41194 /* DMA3 Outer Loop Count Start Value (2D only) */ +#define DMA3_Y_MODIFY 0xFFC41198 /* DMA3 Outer Loop Address Increment (2D only) */ +#define DMA3_CURR_DESC_PTR 0xFFC411A4 /* DMA3 Current Descriptor Pointer */ +#define DMA3_PREV_DESC_PTR 0xFFC411A8 /* DMA3 Previous Initial Descriptor Pointer */ +#define DMA3_CURR_ADDR 0xFFC411AC /* DMA3 Current Address */ +#define DMA3_IRQ_STATUS 0xFFC411B0 /* DMA3 Status Register */ +#define DMA3_CURR_X_COUNT 0xFFC411B4 /* DMA3 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA3_CURR_Y_COUNT 0xFFC411B8 /* DMA3 Current Row Count (2D only) */ +#define DMA3_BWL_COUNT 0xFFC411C0 /* DMA3 Bandwidth Limit Count */ +#define DMA3_CURR_BWL_COUNT 0xFFC411C4 /* DMA3 Bandwidth Limit Count Current */ +#define DMA3_BWM_COUNT 0xFFC411C8 /* DMA3 Bandwidth Monitor Count */ +#define DMA3_CURR_BWM_COUNT 0xFFC411CC /* DMA3 Bandwidth Monitor Count Current */ + +/* ========================= + DMA4 + ========================= */ +#define DMA4_NEXT_DESC_PTR 0xFFC41200 /* DMA4 Pointer to Next Initial Descriptor */ +#define DMA4_START_ADDR 0xFFC41204 /* DMA4 Start Address of Current Buffer */ +#define DMA4_CONFIG 0xFFC41208 /* DMA4 Configuration Register */ +#define DMA4_X_COUNT 0xFFC4120C /* DMA4 Inner Loop Count Start Value */ +#define DMA4_X_MODIFY 0xFFC41210 /* DMA4 Inner Loop Address Increment */ +#define DMA4_Y_COUNT 0xFFC41214 /* DMA4 Outer Loop Count Start Value (2D only) */ +#define DMA4_Y_MODIFY 0xFFC41218 /* DMA4 Outer Loop Address Increment (2D only) */ +#define DMA4_CURR_DESC_PTR 0xFFC41224 /* DMA4 Current Descriptor Pointer */ +#define DMA4_PREV_DESC_PTR 0xFFC41228 /* DMA4 Previous Initial Descriptor Pointer */ +#define DMA4_CURR_ADDR 0xFFC4122C /* DMA4 Current Address */ +#define DMA4_IRQ_STATUS 0xFFC41230 /* DMA4 Status Register */ +#define DMA4_CURR_X_COUNT 0xFFC41234 /* DMA4 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA4_CURR_Y_COUNT 0xFFC41238 /* DMA4 Current Row Count (2D only) */ +#define DMA4_BWL_COUNT 0xFFC41240 /* DMA4 Bandwidth Limit Count */ +#define DMA4_CURR_BWL_COUNT 0xFFC41244 /* DMA4 Bandwidth Limit Count Current */ +#define DMA4_BWM_COUNT 0xFFC41248 /* DMA4 Bandwidth Monitor Count */ +#define DMA4_CURR_BWM_COUNT 0xFFC4124C /* DMA4 Bandwidth Monitor Count Current */ + +/* ========================= + DMA5 + ========================= */ +#define DMA5_NEXT_DESC_PTR 0xFFC41280 /* DMA5 Pointer to Next Initial Descriptor */ +#define DMA5_START_ADDR 0xFFC41284 /* DMA5 Start Address of Current Buffer */ +#define DMA5_CONFIG 0xFFC41288 /* DMA5 Configuration Register */ +#define DMA5_X_COUNT 0xFFC4128C /* DMA5 Inner Loop Count Start Value */ +#define DMA5_X_MODIFY 0xFFC41290 /* DMA5 Inner Loop Address Increment */ +#define DMA5_Y_COUNT 0xFFC41294 /* DMA5 Outer Loop Count Start Value (2D only) */ +#define DMA5_Y_MODIFY 0xFFC41298 /* DMA5 Outer Loop Address Increment (2D only) */ +#define DMA5_CURR_DESC_PTR 0xFFC412A4 /* DMA5 Current Descriptor Pointer */ +#define DMA5_PREV_DESC_PTR 0xFFC412A8 /* DMA5 Previous Initial Descriptor Pointer */ +#define DMA5_CURR_ADDR 0xFFC412AC /* DMA5 Current Address */ +#define DMA5_IRQ_STATUS 0xFFC412B0 /* DMA5 Status Register */ +#define DMA5_CURR_X_COUNT 0xFFC412B4 /* DMA5 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA5_CURR_Y_COUNT 0xFFC412B8 /* DMA5 Current Row Count (2D only) */ +#define DMA5_BWL_COUNT 0xFFC412C0 /* DMA5 Bandwidth Limit Count */ +#define DMA5_CURR_BWL_COUNT 0xFFC412C4 /* DMA5 Bandwidth Limit Count Current */ +#define DMA5_BWM_COUNT 0xFFC412C8 /* DMA5 Bandwidth Monitor Count */ +#define DMA5_CURR_BWM_COUNT 0xFFC412CC /* DMA5 Bandwidth Monitor Count Current */ + +/* ========================= + DMA6 + ========================= */ +#define DMA6_NEXT_DESC_PTR 0xFFC41300 /* DMA6 Pointer to Next Initial Descriptor */ +#define DMA6_START_ADDR 0xFFC41304 /* DMA6 Start Address of Current Buffer */ +#define DMA6_CONFIG 0xFFC41308 /* DMA6 Configuration Register */ +#define DMA6_X_COUNT 0xFFC4130C /* DMA6 Inner Loop Count Start Value */ +#define DMA6_X_MODIFY 0xFFC41310 /* DMA6 Inner Loop Address Increment */ +#define DMA6_Y_COUNT 0xFFC41314 /* DMA6 Outer Loop Count Start Value (2D only) */ +#define DMA6_Y_MODIFY 0xFFC41318 /* DMA6 Outer Loop Address Increment (2D only) */ +#define DMA6_CURR_DESC_PTR 0xFFC41324 /* DMA6 Current Descriptor Pointer */ +#define DMA6_PREV_DESC_PTR 0xFFC41328 /* DMA6 Previous Initial Descriptor Pointer */ +#define DMA6_CURR_ADDR 0xFFC4132C /* DMA6 Current Address */ +#define DMA6_IRQ_STATUS 0xFFC41330 /* DMA6 Status Register */ +#define DMA6_CURR_X_COUNT 0xFFC41334 /* DMA6 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA6_CURR_Y_COUNT 0xFFC41338 /* DMA6 Current Row Count (2D only) */ +#define DMA6_BWL_COUNT 0xFFC41340 /* DMA6 Bandwidth Limit Count */ +#define DMA6_CURR_BWL_COUNT 0xFFC41344 /* DMA6 Bandwidth Limit Count Current */ +#define DMA6_BWM_COUNT 0xFFC41348 /* DMA6 Bandwidth Monitor Count */ +#define DMA6_CURR_BWM_COUNT 0xFFC4134C /* DMA6 Bandwidth Monitor Count Current */ + +/* ========================= + DMA7 + ========================= */ +#define DMA7_NEXT_DESC_PTR 0xFFC41380 /* DMA7 Pointer to Next Initial Descriptor */ +#define DMA7_START_ADDR 0xFFC41384 /* DMA7 Start Address of Current Buffer */ +#define DMA7_CONFIG 0xFFC41388 /* DMA7 Configuration Register */ +#define DMA7_X_COUNT 0xFFC4138C /* DMA7 Inner Loop Count Start Value */ +#define DMA7_X_MODIFY 0xFFC41390 /* DMA7 Inner Loop Address Increment */ +#define DMA7_Y_COUNT 0xFFC41394 /* DMA7 Outer Loop Count Start Value (2D only) */ +#define DMA7_Y_MODIFY 0xFFC41398 /* DMA7 Outer Loop Address Increment (2D only) */ +#define DMA7_CURR_DESC_PTR 0xFFC413A4 /* DMA7 Current Descriptor Pointer */ +#define DMA7_PREV_DESC_PTR 0xFFC413A8 /* DMA7 Previous Initial Descriptor Pointer */ +#define DMA7_CURR_ADDR 0xFFC413AC /* DMA7 Current Address */ +#define DMA7_IRQ_STATUS 0xFFC413B0 /* DMA7 Status Register */ +#define DMA7_CURR_X_COUNT 0xFFC413B4 /* DMA7 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA7_CURR_Y_COUNT 0xFFC413B8 /* DMA7 Current Row Count (2D only) */ +#define DMA7_BWL_COUNT 0xFFC413C0 /* DMA7 Bandwidth Limit Count */ +#define DMA7_CURR_BWL_COUNT 0xFFC413C4 /* DMA7 Bandwidth Limit Count Current */ +#define DMA7_BWM_COUNT 0xFFC413C8 /* DMA7 Bandwidth Monitor Count */ +#define DMA7_CURR_BWM_COUNT 0xFFC413CC /* DMA7 Bandwidth Monitor Count Current */ + +/* ========================= + DMA8 + ========================= */ +#define DMA8_NEXT_DESC_PTR 0xFFC41400 /* DMA8 Pointer to Next Initial Descriptor */ +#define DMA8_START_ADDR 0xFFC41404 /* DMA8 Start Address of Current Buffer */ +#define DMA8_CONFIG 0xFFC41408 /* DMA8 Configuration Register */ +#define DMA8_X_COUNT 0xFFC4140C /* DMA8 Inner Loop Count Start Value */ +#define DMA8_X_MODIFY 0xFFC41410 /* DMA8 Inner Loop Address Increment */ +#define DMA8_Y_COUNT 0xFFC41414 /* DMA8 Outer Loop Count Start Value (2D only) */ +#define DMA8_Y_MODIFY 0xFFC41418 /* DMA8 Outer Loop Address Increment (2D only) */ +#define DMA8_CURR_DESC_PTR 0xFFC41424 /* DMA8 Current Descriptor Pointer */ +#define DMA8_PREV_DESC_PTR 0xFFC41428 /* DMA8 Previous Initial Descriptor Pointer */ +#define DMA8_CURR_ADDR 0xFFC4142C /* DMA8 Current Address */ +#define DMA8_IRQ_STATUS 0xFFC41430 /* DMA8 Status Register */ +#define DMA8_CURR_X_COUNT 0xFFC41434 /* DMA8 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA8_CURR_Y_COUNT 0xFFC41438 /* DMA8 Current Row Count (2D only) */ +#define DMA8_BWL_COUNT 0xFFC41440 /* DMA8 Bandwidth Limit Count */ +#define DMA8_CURR_BWL_COUNT 0xFFC41444 /* DMA8 Bandwidth Limit Count Current */ +#define DMA8_BWM_COUNT 0xFFC41448 /* DMA8 Bandwidth Monitor Count */ +#define DMA8_CURR_BWM_COUNT 0xFFC4144C /* DMA8 Bandwidth Monitor Count Current */ + +/* ========================= + DMA9 + ========================= */ +#define DMA9_NEXT_DESC_PTR 0xFFC41480 /* DMA9 Pointer to Next Initial Descriptor */ +#define DMA9_START_ADDR 0xFFC41484 /* DMA9 Start Address of Current Buffer */ +#define DMA9_CONFIG 0xFFC41488 /* DMA9 Configuration Register */ +#define DMA9_X_COUNT 0xFFC4148C /* DMA9 Inner Loop Count Start Value */ +#define DMA9_X_MODIFY 0xFFC41490 /* DMA9 Inner Loop Address Increment */ +#define DMA9_Y_COUNT 0xFFC41494 /* DMA9 Outer Loop Count Start Value (2D only) */ +#define DMA9_Y_MODIFY 0xFFC41498 /* DMA9 Outer Loop Address Increment (2D only) */ +#define DMA9_CURR_DESC_PTR 0xFFC414A4 /* DMA9 Current Descriptor Pointer */ +#define DMA9_PREV_DESC_PTR 0xFFC414A8 /* DMA9 Previous Initial Descriptor Pointer */ +#define DMA9_CURR_ADDR 0xFFC414AC /* DMA9 Current Address */ +#define DMA9_IRQ_STATUS 0xFFC414B0 /* DMA9 Status Register */ +#define DMA9_CURR_X_COUNT 0xFFC414B4 /* DMA9 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA9_CURR_Y_COUNT 0xFFC414B8 /* DMA9 Current Row Count (2D only) */ +#define DMA9_BWL_COUNT 0xFFC414C0 /* DMA9 Bandwidth Limit Count */ +#define DMA9_CURR_BWL_COUNT 0xFFC414C4 /* DMA9 Bandwidth Limit Count Current */ +#define DMA9_BWM_COUNT 0xFFC414C8 /* DMA9 Bandwidth Monitor Count */ +#define DMA9_CURR_BWM_COUNT 0xFFC414CC /* DMA9 Bandwidth Monitor Count Current */ + +/* ========================= + DMA10 + ========================= */ +#define DMA10_NEXT_DESC_PTR 0xFFC05000 /* DMA10 Pointer to Next Initial Descriptor */ +#define DMA10_START_ADDR 0xFFC05004 /* DMA10 Start Address of Current Buffer */ +#define DMA10_CONFIG 0xFFC05008 /* DMA10 Configuration Register */ +#define DMA10_X_COUNT 0xFFC0500C /* DMA10 Inner Loop Count Start Value */ +#define DMA10_X_MODIFY 0xFFC05010 /* DMA10 Inner Loop Address Increment */ +#define DMA10_Y_COUNT 0xFFC05014 /* DMA10 Outer Loop Count Start Value (2D only) */ +#define DMA10_Y_MODIFY 0xFFC05018 /* DMA10 Outer Loop Address Increment (2D only) */ +#define DMA10_CURR_DESC_PTR 0xFFC05024 /* DMA10 Current Descriptor Pointer */ +#define DMA10_PREV_DESC_PTR 0xFFC05028 /* DMA10 Previous Initial Descriptor Pointer */ +#define DMA10_CURR_ADDR 0xFFC0502C /* DMA10 Current Address */ +#define DMA10_IRQ_STATUS 0xFFC05030 /* DMA10 Status Register */ +#define DMA10_CURR_X_COUNT 0xFFC05034 /* DMA10 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA10_CURR_Y_COUNT 0xFFC05038 /* DMA10 Current Row Count (2D only) */ +#define DMA10_BWL_COUNT 0xFFC05040 /* DMA10 Bandwidth Limit Count */ +#define DMA10_CURR_BWL_COUNT 0xFFC05044 /* DMA10 Bandwidth Limit Count Current */ +#define DMA10_BWM_COUNT 0xFFC05048 /* DMA10 Bandwidth Monitor Count */ +#define DMA10_CURR_BWM_COUNT 0xFFC0504C /* DMA10 Bandwidth Monitor Count Current */ + +/* ========================= + DMA11 + ========================= */ +#define DMA11_NEXT_DESC_PTR 0xFFC05080 /* DMA11 Pointer to Next Initial Descriptor */ +#define DMA11_START_ADDR 0xFFC05084 /* DMA11 Start Address of Current Buffer */ +#define DMA11_CONFIG 0xFFC05088 /* DMA11 Configuration Register */ +#define DMA11_X_COUNT 0xFFC0508C /* DMA11 Inner Loop Count Start Value */ +#define DMA11_X_MODIFY 0xFFC05090 /* DMA11 Inner Loop Address Increment */ +#define DMA11_Y_COUNT 0xFFC05094 /* DMA11 Outer Loop Count Start Value (2D only) */ +#define DMA11_Y_MODIFY 0xFFC05098 /* DMA11 Outer Loop Address Increment (2D only) */ +#define DMA11_CURR_DESC_PTR 0xFFC050A4 /* DMA11 Current Descriptor Pointer */ +#define DMA11_PREV_DESC_PTR 0xFFC050A8 /* DMA11 Previous Initial Descriptor Pointer */ +#define DMA11_CURR_ADDR 0xFFC050AC /* DMA11 Current Address */ +#define DMA11_IRQ_STATUS 0xFFC050B0 /* DMA11 Status Register */ +#define DMA11_CURR_X_COUNT 0xFFC050B4 /* DMA11 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA11_CURR_Y_COUNT 0xFFC050B8 /* DMA11 Current Row Count (2D only) */ +#define DMA11_BWL_COUNT 0xFFC050C0 /* DMA11 Bandwidth Limit Count */ +#define DMA11_CURR_BWL_COUNT 0xFFC050C4 /* DMA11 Bandwidth Limit Count Current */ +#define DMA11_BWM_COUNT 0xFFC050C8 /* DMA11 Bandwidth Monitor Count */ +#define DMA11_CURR_BWM_COUNT 0xFFC050CC /* DMA11 Bandwidth Monitor Count Current */ + +/* ========================= + DMA12 + ========================= */ +#define DMA12_NEXT_DESC_PTR 0xFFC05100 /* DMA12 Pointer to Next Initial Descriptor */ +#define DMA12_START_ADDR 0xFFC05104 /* DMA12 Start Address of Current Buffer */ +#define DMA12_CONFIG 0xFFC05108 /* DMA12 Configuration Register */ +#define DMA12_X_COUNT 0xFFC0510C /* DMA12 Inner Loop Count Start Value */ +#define DMA12_X_MODIFY 0xFFC05110 /* DMA12 Inner Loop Address Increment */ +#define DMA12_Y_COUNT 0xFFC05114 /* DMA12 Outer Loop Count Start Value (2D only) */ +#define DMA12_Y_MODIFY 0xFFC05118 /* DMA12 Outer Loop Address Increment (2D only) */ +#define DMA12_CURR_DESC_PTR 0xFFC05124 /* DMA12 Current Descriptor Pointer */ +#define DMA12_PREV_DESC_PTR 0xFFC05128 /* DMA12 Previous Initial Descriptor Pointer */ +#define DMA12_CURR_ADDR 0xFFC0512C /* DMA12 Current Address */ +#define DMA12_IRQ_STATUS 0xFFC05130 /* DMA12 Status Register */ +#define DMA12_CURR_X_COUNT 0xFFC05134 /* DMA12 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA12_CURR_Y_COUNT 0xFFC05138 /* DMA12 Current Row Count (2D only) */ +#define DMA12_BWL_COUNT 0xFFC05140 /* DMA12 Bandwidth Limit Count */ +#define DMA12_CURR_BWL_COUNT 0xFFC05144 /* DMA12 Bandwidth Limit Count Current */ +#define DMA12_BWM_COUNT 0xFFC05148 /* DMA12 Bandwidth Monitor Count */ +#define DMA12_CURR_BWM_COUNT 0xFFC0514C /* DMA12 Bandwidth Monitor Count Current */ + +/* ========================= + DMA13 + ========================= */ +#define DMA13_NEXT_DESC_PTR 0xFFC07000 /* DMA13 Pointer to Next Initial Descriptor */ +#define DMA13_START_ADDR 0xFFC07004 /* DMA13 Start Address of Current Buffer */ +#define DMA13_CONFIG 0xFFC07008 /* DMA13 Configuration Register */ +#define DMA13_X_COUNT 0xFFC0700C /* DMA13 Inner Loop Count Start Value */ +#define DMA13_X_MODIFY 0xFFC07010 /* DMA13 Inner Loop Address Increment */ +#define DMA13_Y_COUNT 0xFFC07014 /* DMA13 Outer Loop Count Start Value (2D only) */ +#define DMA13_Y_MODIFY 0xFFC07018 /* DMA13 Outer Loop Address Increment (2D only) */ +#define DMA13_CURR_DESC_PTR 0xFFC07024 /* DMA13 Current Descriptor Pointer */ +#define DMA13_PREV_DESC_PTR 0xFFC07028 /* DMA13 Previous Initial Descriptor Pointer */ +#define DMA13_CURR_ADDR 0xFFC0702C /* DMA13 Current Address */ +#define DMA13_IRQ_STATUS 0xFFC07030 /* DMA13 Status Register */ +#define DMA13_CURR_X_COUNT 0xFFC07034 /* DMA13 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA13_CURR_Y_COUNT 0xFFC07038 /* DMA13 Current Row Count (2D only) */ +#define DMA13_BWL_COUNT 0xFFC07040 /* DMA13 Bandwidth Limit Count */ +#define DMA13_CURR_BWL_COUNT 0xFFC07044 /* DMA13 Bandwidth Limit Count Current */ +#define DMA13_BWM_COUNT 0xFFC07048 /* DMA13 Bandwidth Monitor Count */ +#define DMA13_CURR_BWM_COUNT 0xFFC0704C /* DMA13 Bandwidth Monitor Count Current */ + +/* ========================= + DMA14 + ========================= */ +#define DMA14_NEXT_DESC_PTR 0xFFC07080 /* DMA14 Pointer to Next Initial Descriptor */ +#define DMA14_START_ADDR 0xFFC07084 /* DMA14 Start Address of Current Buffer */ +#define DMA14_CONFIG 0xFFC07088 /* DMA14 Configuration Register */ +#define DMA14_X_COUNT 0xFFC0708C /* DMA14 Inner Loop Count Start Value */ +#define DMA14_X_MODIFY 0xFFC07090 /* DMA14 Inner Loop Address Increment */ +#define DMA14_Y_COUNT 0xFFC07094 /* DMA14 Outer Loop Count Start Value (2D only) */ +#define DMA14_Y_MODIFY 0xFFC07098 /* DMA14 Outer Loop Address Increment (2D only) */ +#define DMA14_CURR_DESC_PTR 0xFFC070A4 /* DMA14 Current Descriptor Pointer */ +#define DMA14_PREV_DESC_PTR 0xFFC070A8 /* DMA14 Previous Initial Descriptor Pointer */ +#define DMA14_CURR_ADDR 0xFFC070AC /* DMA14 Current Address */ +#define DMA14_IRQ_STATUS 0xFFC070B0 /* DMA14 Status Register */ +#define DMA14_CURR_X_COUNT 0xFFC070B4 /* DMA14 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA14_CURR_Y_COUNT 0xFFC070B8 /* DMA14 Current Row Count (2D only) */ +#define DMA14_BWL_COUNT 0xFFC070C0 /* DMA14 Bandwidth Limit Count */ +#define DMA14_CURR_BWL_COUNT 0xFFC070C4 /* DMA14 Bandwidth Limit Count Current */ +#define DMA14_BWM_COUNT 0xFFC070C8 /* DMA14 Bandwidth Monitor Count */ +#define DMA14_CURR_BWM_COUNT 0xFFC070CC /* DMA14 Bandwidth Monitor Count Current */ + +/* ========================= + DMA15 + ========================= */ +#define DMA15_NEXT_DESC_PTR 0xFFC07100 /* DMA15 Pointer to Next Initial Descriptor */ +#define DMA15_START_ADDR 0xFFC07104 /* DMA15 Start Address of Current Buffer */ +#define DMA15_CONFIG 0xFFC07108 /* DMA15 Configuration Register */ +#define DMA15_X_COUNT 0xFFC0710C /* DMA15 Inner Loop Count Start Value */ +#define DMA15_X_MODIFY 0xFFC07110 /* DMA15 Inner Loop Address Increment */ +#define DMA15_Y_COUNT 0xFFC07114 /* DMA15 Outer Loop Count Start Value (2D only) */ +#define DMA15_Y_MODIFY 0xFFC07118 /* DMA15 Outer Loop Address Increment (2D only) */ +#define DMA15_CURR_DESC_PTR 0xFFC07124 /* DMA15 Current Descriptor Pointer */ +#define DMA15_PREV_DESC_PTR 0xFFC07128 /* DMA15 Previous Initial Descriptor Pointer */ +#define DMA15_CURR_ADDR 0xFFC0712C /* DMA15 Current Address */ +#define DMA15_IRQ_STATUS 0xFFC07130 /* DMA15 Status Register */ +#define DMA15_CURR_X_COUNT 0xFFC07134 /* DMA15 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA15_CURR_Y_COUNT 0xFFC07138 /* DMA15 Current Row Count (2D only) */ +#define DMA15_BWL_COUNT 0xFFC07140 /* DMA15 Bandwidth Limit Count */ +#define DMA15_CURR_BWL_COUNT 0xFFC07144 /* DMA15 Bandwidth Limit Count Current */ +#define DMA15_BWM_COUNT 0xFFC07148 /* DMA15 Bandwidth Monitor Count */ +#define DMA15_CURR_BWM_COUNT 0xFFC0714C /* DMA15 Bandwidth Monitor Count Current */ + +/* ========================= + DMA16 + ========================= */ +#define DMA16_NEXT_DESC_PTR 0xFFC07180 /* DMA16 Pointer to Next Initial Descriptor */ +#define DMA16_START_ADDR 0xFFC07184 /* DMA16 Start Address of Current Buffer */ +#define DMA16_CONFIG 0xFFC07188 /* DMA16 Configuration Register */ +#define DMA16_X_COUNT 0xFFC0718C /* DMA16 Inner Loop Count Start Value */ +#define DMA16_X_MODIFY 0xFFC07190 /* DMA16 Inner Loop Address Increment */ +#define DMA16_Y_COUNT 0xFFC07194 /* DMA16 Outer Loop Count Start Value (2D only) */ +#define DMA16_Y_MODIFY 0xFFC07198 /* DMA16 Outer Loop Address Increment (2D only) */ +#define DMA16_CURR_DESC_PTR 0xFFC071A4 /* DMA16 Current Descriptor Pointer */ +#define DMA16_PREV_DESC_PTR 0xFFC071A8 /* DMA16 Previous Initial Descriptor Pointer */ +#define DMA16_CURR_ADDR 0xFFC071AC /* DMA16 Current Address */ +#define DMA16_IRQ_STATUS 0xFFC071B0 /* DMA16 Status Register */ +#define DMA16_CURR_X_COUNT 0xFFC071B4 /* DMA16 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA16_CURR_Y_COUNT 0xFFC071B8 /* DMA16 Current Row Count (2D only) */ +#define DMA16_BWL_COUNT 0xFFC071C0 /* DMA16 Bandwidth Limit Count */ +#define DMA16_CURR_BWL_COUNT 0xFFC071C4 /* DMA16 Bandwidth Limit Count Current */ +#define DMA16_BWM_COUNT 0xFFC071C8 /* DMA16 Bandwidth Monitor Count */ +#define DMA16_CURR_BWM_COUNT 0xFFC071CC /* DMA16 Bandwidth Monitor Count Current */ + +/* ========================= + DMA17 + ========================= */ +#define DMA17_NEXT_DESC_PTR 0xFFC07200 /* DMA17 Pointer to Next Initial Descriptor */ +#define DMA17_START_ADDR 0xFFC07204 /* DMA17 Start Address of Current Buffer */ +#define DMA17_CONFIG 0xFFC07208 /* DMA17 Configuration Register */ +#define DMA17_X_COUNT 0xFFC0720C /* DMA17 Inner Loop Count Start Value */ +#define DMA17_X_MODIFY 0xFFC07210 /* DMA17 Inner Loop Address Increment */ +#define DMA17_Y_COUNT 0xFFC07214 /* DMA17 Outer Loop Count Start Value (2D only) */ +#define DMA17_Y_MODIFY 0xFFC07218 /* DMA17 Outer Loop Address Increment (2D only) */ +#define DMA17_CURR_DESC_PTR 0xFFC07224 /* DMA17 Current Descriptor Pointer */ +#define DMA17_PREV_DESC_PTR 0xFFC07228 /* DMA17 Previous Initial Descriptor Pointer */ +#define DMA17_CURR_ADDR 0xFFC0722C /* DMA17 Current Address */ +#define DMA17_IRQ_STATUS 0xFFC07230 /* DMA17 Status Register */ +#define DMA17_CURR_X_COUNT 0xFFC07234 /* DMA17 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA17_CURR_Y_COUNT 0xFFC07238 /* DMA17 Current Row Count (2D only) */ +#define DMA17_BWL_COUNT 0xFFC07240 /* DMA17 Bandwidth Limit Count */ +#define DMA17_CURR_BWL_COUNT 0xFFC07244 /* DMA17 Bandwidth Limit Count Current */ +#define DMA17_BWM_COUNT 0xFFC07248 /* DMA17 Bandwidth Monitor Count */ +#define DMA17_CURR_BWM_COUNT 0xFFC0724C /* DMA17 Bandwidth Monitor Count Current */ + +/* ========================= + DMA18 + ========================= */ +#define DMA18_NEXT_DESC_PTR 0xFFC07280 /* DMA18 Pointer to Next Initial Descriptor */ +#define DMA18_START_ADDR 0xFFC07284 /* DMA18 Start Address of Current Buffer */ +#define DMA18_CONFIG 0xFFC07288 /* DMA18 Configuration Register */ +#define DMA18_X_COUNT 0xFFC0728C /* DMA18 Inner Loop Count Start Value */ +#define DMA18_X_MODIFY 0xFFC07290 /* DMA18 Inner Loop Address Increment */ +#define DMA18_Y_COUNT 0xFFC07294 /* DMA18 Outer Loop Count Start Value (2D only) */ +#define DMA18_Y_MODIFY 0xFFC07298 /* DMA18 Outer Loop Address Increment (2D only) */ +#define DMA18_CURR_DESC_PTR 0xFFC072A4 /* DMA18 Current Descriptor Pointer */ +#define DMA18_PREV_DESC_PTR 0xFFC072A8 /* DMA18 Previous Initial Descriptor Pointer */ +#define DMA18_CURR_ADDR 0xFFC072AC /* DMA18 Current Address */ +#define DMA18_IRQ_STATUS 0xFFC072B0 /* DMA18 Status Register */ +#define DMA18_CURR_X_COUNT 0xFFC072B4 /* DMA18 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA18_CURR_Y_COUNT 0xFFC072B8 /* DMA18 Current Row Count (2D only) */ +#define DMA18_BWL_COUNT 0xFFC072C0 /* DMA18 Bandwidth Limit Count */ +#define DMA18_CURR_BWL_COUNT 0xFFC072C4 /* DMA18 Bandwidth Limit Count Current */ +#define DMA18_BWM_COUNT 0xFFC072C8 /* DMA18 Bandwidth Monitor Count */ +#define DMA18_CURR_BWM_COUNT 0xFFC072CC /* DMA18 Bandwidth Monitor Count Current */ + +/* ========================= + DMA19 + ========================= */ +#define DMA19_NEXT_DESC_PTR 0xFFC07300 /* DMA19 Pointer to Next Initial Descriptor */ +#define DMA19_START_ADDR 0xFFC07304 /* DMA19 Start Address of Current Buffer */ +#define DMA19_CONFIG 0xFFC07308 /* DMA19 Configuration Register */ +#define DMA19_X_COUNT 0xFFC0730C /* DMA19 Inner Loop Count Start Value */ +#define DMA19_X_MODIFY 0xFFC07310 /* DMA19 Inner Loop Address Increment */ +#define DMA19_Y_COUNT 0xFFC07314 /* DMA19 Outer Loop Count Start Value (2D only) */ +#define DMA19_Y_MODIFY 0xFFC07318 /* DMA19 Outer Loop Address Increment (2D only) */ +#define DMA19_CURR_DESC_PTR 0xFFC07324 /* DMA19 Current Descriptor Pointer */ +#define DMA19_PREV_DESC_PTR 0xFFC07328 /* DMA19 Previous Initial Descriptor Pointer */ +#define DMA19_CURR_ADDR 0xFFC0732C /* DMA19 Current Address */ +#define DMA19_IRQ_STATUS 0xFFC07330 /* DMA19 Status Register */ +#define DMA19_CURR_X_COUNT 0xFFC07334 /* DMA19 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA19_CURR_Y_COUNT 0xFFC07338 /* DMA19 Current Row Count (2D only) */ +#define DMA19_BWL_COUNT 0xFFC07340 /* DMA19 Bandwidth Limit Count */ +#define DMA19_CURR_BWL_COUNT 0xFFC07344 /* DMA19 Bandwidth Limit Count Current */ +#define DMA19_BWM_COUNT 0xFFC07348 /* DMA19 Bandwidth Monitor Count */ +#define DMA19_CURR_BWM_COUNT 0xFFC0734C /* DMA19 Bandwidth Monitor Count Current */ + +/* ========================= + DMA20 + ========================= */ +#define DMA20_NEXT_DESC_PTR 0xFFC07380 /* DMA20 Pointer to Next Initial Descriptor */ +#define DMA20_START_ADDR 0xFFC07384 /* DMA20 Start Address of Current Buffer */ +#define DMA20_CONFIG 0xFFC07388 /* DMA20 Configuration Register */ +#define DMA20_X_COUNT 0xFFC0738C /* DMA20 Inner Loop Count Start Value */ +#define DMA20_X_MODIFY 0xFFC07390 /* DMA20 Inner Loop Address Increment */ +#define DMA20_Y_COUNT 0xFFC07394 /* DMA20 Outer Loop Count Start Value (2D only) */ +#define DMA20_Y_MODIFY 0xFFC07398 /* DMA20 Outer Loop Address Increment (2D only) */ +#define DMA20_CURR_DESC_PTR 0xFFC073A4 /* DMA20 Current Descriptor Pointer */ +#define DMA20_PREV_DESC_PTR 0xFFC073A8 /* DMA20 Previous Initial Descriptor Pointer */ +#define DMA20_CURR_ADDR 0xFFC073AC /* DMA20 Current Address */ +#define DMA20_IRQ_STATUS 0xFFC073B0 /* DMA20 Status Register */ +#define DMA20_CURR_X_COUNT 0xFFC073B4 /* DMA20 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA20_CURR_Y_COUNT 0xFFC073B8 /* DMA20 Current Row Count (2D only) */ +#define DMA20_BWL_COUNT 0xFFC073C0 /* DMA20 Bandwidth Limit Count */ +#define DMA20_CURR_BWL_COUNT 0xFFC073C4 /* DMA20 Bandwidth Limit Count Current */ +#define DMA20_BWM_COUNT 0xFFC073C8 /* DMA20 Bandwidth Monitor Count */ +#define DMA20_CURR_BWM_COUNT 0xFFC073CC /* DMA20 Bandwidth Monitor Count Current */ + +/* ========================= + DMA21 + ========================= */ +#define DMA21_NEXT_DESC_PTR 0xFFC09000 /* DMA21 Pointer to Next Initial Descriptor */ +#define DMA21_START_ADDR 0xFFC09004 /* DMA21 Start Address of Current Buffer */ +#define DMA21_CONFIG 0xFFC09008 /* DMA21 Configuration Register */ +#define DMA21_X_COUNT 0xFFC0900C /* DMA21 Inner Loop Count Start Value */ +#define DMA21_X_MODIFY 0xFFC09010 /* DMA21 Inner Loop Address Increment */ +#define DMA21_Y_COUNT 0xFFC09014 /* DMA21 Outer Loop Count Start Value (2D only) */ +#define DMA21_Y_MODIFY 0xFFC09018 /* DMA21 Outer Loop Address Increment (2D only) */ +#define DMA21_CURR_DESC_PTR 0xFFC09024 /* DMA21 Current Descriptor Pointer */ +#define DMA21_PREV_DESC_PTR 0xFFC09028 /* DMA21 Previous Initial Descriptor Pointer */ +#define DMA21_CURR_ADDR 0xFFC0902C /* DMA21 Current Address */ +#define DMA21_IRQ_STATUS 0xFFC09030 /* DMA21 Status Register */ +#define DMA21_CURR_X_COUNT 0xFFC09034 /* DMA21 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA21_CURR_Y_COUNT 0xFFC09038 /* DMA21 Current Row Count (2D only) */ +#define DMA21_BWL_COUNT 0xFFC09040 /* DMA21 Bandwidth Limit Count */ +#define DMA21_CURR_BWL_COUNT 0xFFC09044 /* DMA21 Bandwidth Limit Count Current */ +#define DMA21_BWM_COUNT 0xFFC09048 /* DMA21 Bandwidth Monitor Count */ +#define DMA21_CURR_BWM_COUNT 0xFFC0904C /* DMA21 Bandwidth Monitor Count Current */ + +/* ========================= + DMA22 + ========================= */ +#define DMA22_NEXT_DESC_PTR 0xFFC09080 /* DMA22 Pointer to Next Initial Descriptor */ +#define DMA22_START_ADDR 0xFFC09084 /* DMA22 Start Address of Current Buffer */ +#define DMA22_CONFIG 0xFFC09088 /* DMA22 Configuration Register */ +#define DMA22_X_COUNT 0xFFC0908C /* DMA22 Inner Loop Count Start Value */ +#define DMA22_X_MODIFY 0xFFC09090 /* DMA22 Inner Loop Address Increment */ +#define DMA22_Y_COUNT 0xFFC09094 /* DMA22 Outer Loop Count Start Value (2D only) */ +#define DMA22_Y_MODIFY 0xFFC09098 /* DMA22 Outer Loop Address Increment (2D only) */ +#define DMA22_CURR_DESC_PTR 0xFFC090A4 /* DMA22 Current Descriptor Pointer */ +#define DMA22_PREV_DESC_PTR 0xFFC090A8 /* DMA22 Previous Initial Descriptor Pointer */ +#define DMA22_CURR_ADDR 0xFFC090AC /* DMA22 Current Address */ +#define DMA22_IRQ_STATUS 0xFFC090B0 /* DMA22 Status Register */ +#define DMA22_CURR_X_COUNT 0xFFC090B4 /* DMA22 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA22_CURR_Y_COUNT 0xFFC090B8 /* DMA22 Current Row Count (2D only) */ +#define DMA22_BWL_COUNT 0xFFC090C0 /* DMA22 Bandwidth Limit Count */ +#define DMA22_CURR_BWL_COUNT 0xFFC090C4 /* DMA22 Bandwidth Limit Count Current */ +#define DMA22_BWM_COUNT 0xFFC090C8 /* DMA22 Bandwidth Monitor Count */ +#define DMA22_CURR_BWM_COUNT 0xFFC090CC /* DMA22 Bandwidth Monitor Count Current */ + +/* ========================= + DMA23 + ========================= */ +#define DMA23_NEXT_DESC_PTR 0xFFC09100 /* DMA23 Pointer to Next Initial Descriptor */ +#define DMA23_START_ADDR 0xFFC09104 /* DMA23 Start Address of Current Buffer */ +#define DMA23_CONFIG 0xFFC09108 /* DMA23 Configuration Register */ +#define DMA23_X_COUNT 0xFFC0910C /* DMA23 Inner Loop Count Start Value */ +#define DMA23_X_MODIFY 0xFFC09110 /* DMA23 Inner Loop Address Increment */ +#define DMA23_Y_COUNT 0xFFC09114 /* DMA23 Outer Loop Count Start Value (2D only) */ +#define DMA23_Y_MODIFY 0xFFC09118 /* DMA23 Outer Loop Address Increment (2D only) */ +#define DMA23_CURR_DESC_PTR 0xFFC09124 /* DMA23 Current Descriptor Pointer */ +#define DMA23_PREV_DESC_PTR 0xFFC09128 /* DMA23 Previous Initial Descriptor Pointer */ +#define DMA23_CURR_ADDR 0xFFC0912C /* DMA23 Current Address */ +#define DMA23_IRQ_STATUS 0xFFC09130 /* DMA23 Status Register */ +#define DMA23_CURR_X_COUNT 0xFFC09134 /* DMA23 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA23_CURR_Y_COUNT 0xFFC09138 /* DMA23 Current Row Count (2D only) */ +#define DMA23_BWL_COUNT 0xFFC09140 /* DMA23 Bandwidth Limit Count */ +#define DMA23_CURR_BWL_COUNT 0xFFC09144 /* DMA23 Bandwidth Limit Count Current */ +#define DMA23_BWM_COUNT 0xFFC09148 /* DMA23 Bandwidth Monitor Count */ +#define DMA23_CURR_BWM_COUNT 0xFFC0914C /* DMA23 Bandwidth Monitor Count Current */ + +/* ========================= + DMA24 + ========================= */ +#define DMA24_NEXT_DESC_PTR 0xFFC09180 /* DMA24 Pointer to Next Initial Descriptor */ +#define DMA24_START_ADDR 0xFFC09184 /* DMA24 Start Address of Current Buffer */ +#define DMA24_CONFIG 0xFFC09188 /* DMA24 Configuration Register */ +#define DMA24_X_COUNT 0xFFC0918C /* DMA24 Inner Loop Count Start Value */ +#define DMA24_X_MODIFY 0xFFC09190 /* DMA24 Inner Loop Address Increment */ +#define DMA24_Y_COUNT 0xFFC09194 /* DMA24 Outer Loop Count Start Value (2D only) */ +#define DMA24_Y_MODIFY 0xFFC09198 /* DMA24 Outer Loop Address Increment (2D only) */ +#define DMA24_CURR_DESC_PTR 0xFFC091A4 /* DMA24 Current Descriptor Pointer */ +#define DMA24_PREV_DESC_PTR 0xFFC091A8 /* DMA24 Previous Initial Descriptor Pointer */ +#define DMA24_CURR_ADDR 0xFFC091AC /* DMA24 Current Address */ +#define DMA24_IRQ_STATUS 0xFFC091B0 /* DMA24 Status Register */ +#define DMA24_CURR_X_COUNT 0xFFC091B4 /* DMA24 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA24_CURR_Y_COUNT 0xFFC091B8 /* DMA24 Current Row Count (2D only) */ +#define DMA24_BWL_COUNT 0xFFC091C0 /* DMA24 Bandwidth Limit Count */ +#define DMA24_CURR_BWL_COUNT 0xFFC091C4 /* DMA24 Bandwidth Limit Count Current */ +#define DMA24_BWM_COUNT 0xFFC091C8 /* DMA24 Bandwidth Monitor Count */ +#define DMA24_CURR_BWM_COUNT 0xFFC091CC /* DMA24 Bandwidth Monitor Count Current */ + +/* ========================= + DMA25 + ========================= */ +#define DMA25_NEXT_DESC_PTR 0xFFC09200 /* DMA25 Pointer to Next Initial Descriptor */ +#define DMA25_START_ADDR 0xFFC09204 /* DMA25 Start Address of Current Buffer */ +#define DMA25_CONFIG 0xFFC09208 /* DMA25 Configuration Register */ +#define DMA25_X_COUNT 0xFFC0920C /* DMA25 Inner Loop Count Start Value */ +#define DMA25_X_MODIFY 0xFFC09210 /* DMA25 Inner Loop Address Increment */ +#define DMA25_Y_COUNT 0xFFC09214 /* DMA25 Outer Loop Count Start Value (2D only) */ +#define DMA25_Y_MODIFY 0xFFC09218 /* DMA25 Outer Loop Address Increment (2D only) */ +#define DMA25_CURR_DESC_PTR 0xFFC09224 /* DMA25 Current Descriptor Pointer */ +#define DMA25_PREV_DESC_PTR 0xFFC09228 /* DMA25 Previous Initial Descriptor Pointer */ +#define DMA25_CURR_ADDR 0xFFC0922C /* DMA25 Current Address */ +#define DMA25_IRQ_STATUS 0xFFC09230 /* DMA25 Status Register */ +#define DMA25_CURR_X_COUNT 0xFFC09234 /* DMA25 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA25_CURR_Y_COUNT 0xFFC09238 /* DMA25 Current Row Count (2D only) */ +#define DMA25_BWL_COUNT 0xFFC09240 /* DMA25 Bandwidth Limit Count */ +#define DMA25_CURR_BWL_COUNT 0xFFC09244 /* DMA25 Bandwidth Limit Count Current */ +#define DMA25_BWM_COUNT 0xFFC09248 /* DMA25 Bandwidth Monitor Count */ +#define DMA25_CURR_BWM_COUNT 0xFFC0924C /* DMA25 Bandwidth Monitor Count Current */ + +/* ========================= + DMA26 + ========================= */ +#define DMA26_NEXT_DESC_PTR 0xFFC09280 /* DMA26 Pointer to Next Initial Descriptor */ +#define DMA26_START_ADDR 0xFFC09284 /* DMA26 Start Address of Current Buffer */ +#define DMA26_CONFIG 0xFFC09288 /* DMA26 Configuration Register */ +#define DMA26_X_COUNT 0xFFC0928C /* DMA26 Inner Loop Count Start Value */ +#define DMA26_X_MODIFY 0xFFC09290 /* DMA26 Inner Loop Address Increment */ +#define DMA26_Y_COUNT 0xFFC09294 /* DMA26 Outer Loop Count Start Value (2D only) */ +#define DMA26_Y_MODIFY 0xFFC09298 /* DMA26 Outer Loop Address Increment (2D only) */ +#define DMA26_CURR_DESC_PTR 0xFFC092A4 /* DMA26 Current Descriptor Pointer */ +#define DMA26_PREV_DESC_PTR 0xFFC092A8 /* DMA26 Previous Initial Descriptor Pointer */ +#define DMA26_CURR_ADDR 0xFFC092AC /* DMA26 Current Address */ +#define DMA26_IRQ_STATUS 0xFFC092B0 /* DMA26 Status Register */ +#define DMA26_CURR_X_COUNT 0xFFC092B4 /* DMA26 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA26_CURR_Y_COUNT 0xFFC092B8 /* DMA26 Current Row Count (2D only) */ +#define DMA26_BWL_COUNT 0xFFC092C0 /* DMA26 Bandwidth Limit Count */ +#define DMA26_CURR_BWL_COUNT 0xFFC092C4 /* DMA26 Bandwidth Limit Count Current */ +#define DMA26_BWM_COUNT 0xFFC092C8 /* DMA26 Bandwidth Monitor Count */ +#define DMA26_CURR_BWM_COUNT 0xFFC092CC /* DMA26 Bandwidth Monitor Count Current */ + +/* ========================= + DMA27 + ========================= */ +#define DMA27_NEXT_DESC_PTR 0xFFC09300 /* DMA27 Pointer to Next Initial Descriptor */ +#define DMA27_START_ADDR 0xFFC09304 /* DMA27 Start Address of Current Buffer */ +#define DMA27_CONFIG 0xFFC09308 /* DMA27 Configuration Register */ +#define DMA27_X_COUNT 0xFFC0930C /* DMA27 Inner Loop Count Start Value */ +#define DMA27_X_MODIFY 0xFFC09310 /* DMA27 Inner Loop Address Increment */ +#define DMA27_Y_COUNT 0xFFC09314 /* DMA27 Outer Loop Count Start Value (2D only) */ +#define DMA27_Y_MODIFY 0xFFC09318 /* DMA27 Outer Loop Address Increment (2D only) */ +#define DMA27_CURR_DESC_PTR 0xFFC09324 /* DMA27 Current Descriptor Pointer */ +#define DMA27_PREV_DESC_PTR 0xFFC09328 /* DMA27 Previous Initial Descriptor Pointer */ +#define DMA27_CURR_ADDR 0xFFC0932C /* DMA27 Current Address */ +#define DMA27_IRQ_STATUS 0xFFC09330 /* DMA27 Status Register */ +#define DMA27_CURR_X_COUNT 0xFFC09334 /* DMA27 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA27_CURR_Y_COUNT 0xFFC09338 /* DMA27 Current Row Count (2D only) */ +#define DMA27_BWL_COUNT 0xFFC09340 /* DMA27 Bandwidth Limit Count */ +#define DMA27_CURR_BWL_COUNT 0xFFC09344 /* DMA27 Bandwidth Limit Count Current */ +#define DMA27_BWM_COUNT 0xFFC09348 /* DMA27 Bandwidth Monitor Count */ +#define DMA27_CURR_BWM_COUNT 0xFFC0934C /* DMA27 Bandwidth Monitor Count Current */ + +/* ========================= + DMA28 + ========================= */ +#define DMA28_NEXT_DESC_PTR 0xFFC09380 /* DMA28 Pointer to Next Initial Descriptor */ +#define DMA28_START_ADDR 0xFFC09384 /* DMA28 Start Address of Current Buffer */ +#define DMA28_CONFIG 0xFFC09388 /* DMA28 Configuration Register */ +#define DMA28_X_COUNT 0xFFC0938C /* DMA28 Inner Loop Count Start Value */ +#define DMA28_X_MODIFY 0xFFC09390 /* DMA28 Inner Loop Address Increment */ +#define DMA28_Y_COUNT 0xFFC09394 /* DMA28 Outer Loop Count Start Value (2D only) */ +#define DMA28_Y_MODIFY 0xFFC09398 /* DMA28 Outer Loop Address Increment (2D only) */ +#define DMA28_CURR_DESC_PTR 0xFFC093A4 /* DMA28 Current Descriptor Pointer */ +#define DMA28_PREV_DESC_PTR 0xFFC093A8 /* DMA28 Previous Initial Descriptor Pointer */ +#define DMA28_CURR_ADDR 0xFFC093AC /* DMA28 Current Address */ +#define DMA28_IRQ_STATUS 0xFFC093B0 /* DMA28 Status Register */ +#define DMA28_CURR_X_COUNT 0xFFC093B4 /* DMA28 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA28_CURR_Y_COUNT 0xFFC093B8 /* DMA28 Current Row Count (2D only) */ +#define DMA28_BWL_COUNT 0xFFC093C0 /* DMA28 Bandwidth Limit Count */ +#define DMA28_CURR_BWL_COUNT 0xFFC093C4 /* DMA28 Bandwidth Limit Count Current */ +#define DMA28_BWM_COUNT 0xFFC093C8 /* DMA28 Bandwidth Monitor Count */ +#define DMA28_CURR_BWM_COUNT 0xFFC093CC /* DMA28 Bandwidth Monitor Count Current */ + +/* ========================= + DMA29 + ========================= */ +#define DMA29_NEXT_DESC_PTR 0xFFC0B000 /* DMA29 Pointer to Next Initial Descriptor */ +#define DMA29_START_ADDR 0xFFC0B004 /* DMA29 Start Address of Current Buffer */ +#define DMA29_CONFIG 0xFFC0B008 /* DMA29 Configuration Register */ +#define DMA29_X_COUNT 0xFFC0B00C /* DMA29 Inner Loop Count Start Value */ +#define DMA29_X_MODIFY 0xFFC0B010 /* DMA29 Inner Loop Address Increment */ +#define DMA29_Y_COUNT 0xFFC0B014 /* DMA29 Outer Loop Count Start Value (2D only) */ +#define DMA29_Y_MODIFY 0xFFC0B018 /* DMA29 Outer Loop Address Increment (2D only) */ +#define DMA29_CURR_DESC_PTR 0xFFC0B024 /* DMA29 Current Descriptor Pointer */ +#define DMA29_PREV_DESC_PTR 0xFFC0B028 /* DMA29 Previous Initial Descriptor Pointer */ +#define DMA29_CURR_ADDR 0xFFC0B02C /* DMA29 Current Address */ +#define DMA29_IRQ_STATUS 0xFFC0B030 /* DMA29 Status Register */ +#define DMA29_CURR_X_COUNT 0xFFC0B034 /* DMA29 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA29_CURR_Y_COUNT 0xFFC0B038 /* DMA29 Current Row Count (2D only) */ +#define DMA29_BWL_COUNT 0xFFC0B040 /* DMA29 Bandwidth Limit Count */ +#define DMA29_CURR_BWL_COUNT 0xFFC0B044 /* DMA29 Bandwidth Limit Count Current */ +#define DMA29_BWM_COUNT 0xFFC0B048 /* DMA29 Bandwidth Monitor Count */ +#define DMA29_CURR_BWM_COUNT 0xFFC0B04C /* DMA29 Bandwidth Monitor Count Current */ + +/* ========================= + DMA30 + ========================= */ +#define DMA30_NEXT_DESC_PTR 0xFFC0B080 /* DMA30 Pointer to Next Initial Descriptor */ +#define DMA30_START_ADDR 0xFFC0B084 /* DMA30 Start Address of Current Buffer */ +#define DMA30_CONFIG 0xFFC0B088 /* DMA30 Configuration Register */ +#define DMA30_X_COUNT 0xFFC0B08C /* DMA30 Inner Loop Count Start Value */ +#define DMA30_X_MODIFY 0xFFC0B090 /* DMA30 Inner Loop Address Increment */ +#define DMA30_Y_COUNT 0xFFC0B094 /* DMA30 Outer Loop Count Start Value (2D only) */ +#define DMA30_Y_MODIFY 0xFFC0B098 /* DMA30 Outer Loop Address Increment (2D only) */ +#define DMA30_CURR_DESC_PTR 0xFFC0B0A4 /* DMA30 Current Descriptor Pointer */ +#define DMA30_PREV_DESC_PTR 0xFFC0B0A8 /* DMA30 Previous Initial Descriptor Pointer */ +#define DMA30_CURR_ADDR 0xFFC0B0AC /* DMA30 Current Address */ +#define DMA30_IRQ_STATUS 0xFFC0B0B0 /* DMA30 Status Register */ +#define DMA30_CURR_X_COUNT 0xFFC0B0B4 /* DMA30 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA30_CURR_Y_COUNT 0xFFC0B0B8 /* DMA30 Current Row Count (2D only) */ +#define DMA30_BWL_COUNT 0xFFC0B0C0 /* DMA30 Bandwidth Limit Count */ +#define DMA30_CURR_BWL_COUNT 0xFFC0B0C4 /* DMA30 Bandwidth Limit Count Current */ +#define DMA30_BWM_COUNT 0xFFC0B0C8 /* DMA30 Bandwidth Monitor Count */ +#define DMA30_CURR_BWM_COUNT 0xFFC0B0CC /* DMA30 Bandwidth Monitor Count Current */ + +/* ========================= + DMA31 + ========================= */ +#define DMA31_NEXT_DESC_PTR 0xFFC0B100 /* DMA31 Pointer to Next Initial Descriptor */ +#define DMA31_START_ADDR 0xFFC0B104 /* DMA31 Start Address of Current Buffer */ +#define DMA31_CONFIG 0xFFC0B108 /* DMA31 Configuration Register */ +#define DMA31_X_COUNT 0xFFC0B10C /* DMA31 Inner Loop Count Start Value */ +#define DMA31_X_MODIFY 0xFFC0B110 /* DMA31 Inner Loop Address Increment */ +#define DMA31_Y_COUNT 0xFFC0B114 /* DMA31 Outer Loop Count Start Value (2D only) */ +#define DMA31_Y_MODIFY 0xFFC0B118 /* DMA31 Outer Loop Address Increment (2D only) */ +#define DMA31_CURR_DESC_PTR 0xFFC0B124 /* DMA31 Current Descriptor Pointer */ +#define DMA31_PREV_DESC_PTR 0xFFC0B128 /* DMA31 Previous Initial Descriptor Pointer */ +#define DMA31_CURR_ADDR 0xFFC0B12C /* DMA31 Current Address */ +#define DMA31_IRQ_STATUS 0xFFC0B130 /* DMA31 Status Register */ +#define DMA31_CURR_X_COUNT 0xFFC0B134 /* DMA31 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA31_CURR_Y_COUNT 0xFFC0B138 /* DMA31 Current Row Count (2D only) */ +#define DMA31_BWL_COUNT 0xFFC0B140 /* DMA31 Bandwidth Limit Count */ +#define DMA31_CURR_BWL_COUNT 0xFFC0B144 /* DMA31 Bandwidth Limit Count Current */ +#define DMA31_BWM_COUNT 0xFFC0B148 /* DMA31 Bandwidth Monitor Count */ +#define DMA31_CURR_BWM_COUNT 0xFFC0B14C /* DMA31 Bandwidth Monitor Count Current */ + +/* ========================= + DMA32 + ========================= */ +#define DMA32_NEXT_DESC_PTR 0xFFC0B180 /* DMA32 Pointer to Next Initial Descriptor */ +#define DMA32_START_ADDR 0xFFC0B184 /* DMA32 Start Address of Current Buffer */ +#define DMA32_CONFIG 0xFFC0B188 /* DMA32 Configuration Register */ +#define DMA32_X_COUNT 0xFFC0B18C /* DMA32 Inner Loop Count Start Value */ +#define DMA32_X_MODIFY 0xFFC0B190 /* DMA32 Inner Loop Address Increment */ +#define DMA32_Y_COUNT 0xFFC0B194 /* DMA32 Outer Loop Count Start Value (2D only) */ +#define DMA32_Y_MODIFY 0xFFC0B198 /* DMA32 Outer Loop Address Increment (2D only) */ +#define DMA32_CURR_DESC_PTR 0xFFC0B1A4 /* DMA32 Current Descriptor Pointer */ +#define DMA32_PREV_DESC_PTR 0xFFC0B1A8 /* DMA32 Previous Initial Descriptor Pointer */ +#define DMA32_CURR_ADDR 0xFFC0B1AC /* DMA32 Current Address */ +#define DMA32_IRQ_STATUS 0xFFC0B1B0 /* DMA32 Status Register */ +#define DMA32_CURR_X_COUNT 0xFFC0B1B4 /* DMA32 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA32_CURR_Y_COUNT 0xFFC0B1B8 /* DMA32 Current Row Count (2D only) */ +#define DMA32_BWL_COUNT 0xFFC0B1C0 /* DMA32 Bandwidth Limit Count */ +#define DMA32_CURR_BWL_COUNT 0xFFC0B1C4 /* DMA32 Bandwidth Limit Count Current */ +#define DMA32_BWM_COUNT 0xFFC0B1C8 /* DMA32 Bandwidth Monitor Count */ +#define DMA32_CURR_BWM_COUNT 0xFFC0B1CC /* DMA32 Bandwidth Monitor Count Current */ + +/* ========================= + DMA33 + ========================= */ +#define DMA33_NEXT_DESC_PTR 0xFFC0D000 /* DMA33 Pointer to Next Initial Descriptor */ +#define DMA33_START_ADDR 0xFFC0D004 /* DMA33 Start Address of Current Buffer */ +#define DMA33_CONFIG 0xFFC0D008 /* DMA33 Configuration Register */ +#define DMA33_X_COUNT 0xFFC0D00C /* DMA33 Inner Loop Count Start Value */ +#define DMA33_X_MODIFY 0xFFC0D010 /* DMA33 Inner Loop Address Increment */ +#define DMA33_Y_COUNT 0xFFC0D014 /* DMA33 Outer Loop Count Start Value (2D only) */ +#define DMA33_Y_MODIFY 0xFFC0D018 /* DMA33 Outer Loop Address Increment (2D only) */ +#define DMA33_CURR_DESC_PTR 0xFFC0D024 /* DMA33 Current Descriptor Pointer */ +#define DMA33_PREV_DESC_PTR 0xFFC0D028 /* DMA33 Previous Initial Descriptor Pointer */ +#define DMA33_CURR_ADDR 0xFFC0D02C /* DMA33 Current Address */ +#define DMA33_IRQ_STATUS 0xFFC0D030 /* DMA33 Status Register */ +#define DMA33_CURR_X_COUNT 0xFFC0D034 /* DMA33 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA33_CURR_Y_COUNT 0xFFC0D038 /* DMA33 Current Row Count (2D only) */ +#define DMA33_BWL_COUNT 0xFFC0D040 /* DMA33 Bandwidth Limit Count */ +#define DMA33_CURR_BWL_COUNT 0xFFC0D044 /* DMA33 Bandwidth Limit Count Current */ +#define DMA33_BWM_COUNT 0xFFC0D048 /* DMA33 Bandwidth Monitor Count */ +#define DMA33_CURR_BWM_COUNT 0xFFC0D04C /* DMA33 Bandwidth Monitor Count Current */ + +/* ========================= + DMA34 + ========================= */ +#define DMA34_NEXT_DESC_PTR 0xFFC0D080 /* DMA34 Pointer to Next Initial Descriptor */ +#define DMA34_START_ADDR 0xFFC0D084 /* DMA34 Start Address of Current Buffer */ +#define DMA34_CONFIG 0xFFC0D088 /* DMA34 Configuration Register */ +#define DMA34_X_COUNT 0xFFC0D08C /* DMA34 Inner Loop Count Start Value */ +#define DMA34_X_MODIFY 0xFFC0D090 /* DMA34 Inner Loop Address Increment */ +#define DMA34_Y_COUNT 0xFFC0D094 /* DMA34 Outer Loop Count Start Value (2D only) */ +#define DMA34_Y_MODIFY 0xFFC0D098 /* DMA34 Outer Loop Address Increment (2D only) */ +#define DMA34_CURR_DESC_PTR 0xFFC0D0A4 /* DMA34 Current Descriptor Pointer */ +#define DMA34_PREV_DESC_PTR 0xFFC0D0A8 /* DMA34 Previous Initial Descriptor Pointer */ +#define DMA34_CURR_ADDR 0xFFC0D0AC /* DMA34 Current Address */ +#define DMA34_IRQ_STATUS 0xFFC0D0B0 /* DMA34 Status Register */ +#define DMA34_CURR_X_COUNT 0xFFC0D0B4 /* DMA34 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA34_CURR_Y_COUNT 0xFFC0D0B8 /* DMA34 Current Row Count (2D only) */ +#define DMA34_BWL_COUNT 0xFFC0D0C0 /* DMA34 Bandwidth Limit Count */ +#define DMA34_CURR_BWL_COUNT 0xFFC0D0C4 /* DMA34 Bandwidth Limit Count Current */ +#define DMA34_BWM_COUNT 0xFFC0D0C8 /* DMA34 Bandwidth Monitor Count */ +#define DMA34_CURR_BWM_COUNT 0xFFC0D0CC /* DMA34 Bandwidth Monitor Count Current */ + +/* ========================= + DMA35 + ========================= */ +#define DMA35_NEXT_DESC_PTR 0xFFC10000 /* DMA35 Pointer to Next Initial Descriptor */ +#define DMA35_START_ADDR 0xFFC10004 /* DMA35 Start Address of Current Buffer */ +#define DMA35_CONFIG 0xFFC10008 /* DMA35 Configuration Register */ +#define DMA35_X_COUNT 0xFFC1000C /* DMA35 Inner Loop Count Start Value */ +#define DMA35_X_MODIFY 0xFFC10010 /* DMA35 Inner Loop Address Increment */ +#define DMA35_Y_COUNT 0xFFC10014 /* DMA35 Outer Loop Count Start Value (2D only) */ +#define DMA35_Y_MODIFY 0xFFC10018 /* DMA35 Outer Loop Address Increment (2D only) */ +#define DMA35_CURR_DESC_PTR 0xFFC10024 /* DMA35 Current Descriptor Pointer */ +#define DMA35_PREV_DESC_PTR 0xFFC10028 /* DMA35 Previous Initial Descriptor Pointer */ +#define DMA35_CURR_ADDR 0xFFC1002C /* DMA35 Current Address */ +#define DMA35_IRQ_STATUS 0xFFC10030 /* DMA35 Status Register */ +#define DMA35_CURR_X_COUNT 0xFFC10034 /* DMA35 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA35_CURR_Y_COUNT 0xFFC10038 /* DMA35 Current Row Count (2D only) */ +#define DMA35_BWL_COUNT 0xFFC10040 /* DMA35 Bandwidth Limit Count */ +#define DMA35_CURR_BWL_COUNT 0xFFC10044 /* DMA35 Bandwidth Limit Count Current */ +#define DMA35_BWM_COUNT 0xFFC10048 /* DMA35 Bandwidth Monitor Count */ +#define DMA35_CURR_BWM_COUNT 0xFFC1004C /* DMA35 Bandwidth Monitor Count Current */ + +/* ========================= + DMA36 + ========================= */ +#define DMA36_NEXT_DESC_PTR 0xFFC10080 /* DMA36 Pointer to Next Initial Descriptor */ +#define DMA36_START_ADDR 0xFFC10084 /* DMA36 Start Address of Current Buffer */ +#define DMA36_CONFIG 0xFFC10088 /* DMA36 Configuration Register */ +#define DMA36_X_COUNT 0xFFC1008C /* DMA36 Inner Loop Count Start Value */ +#define DMA36_X_MODIFY 0xFFC10090 /* DMA36 Inner Loop Address Increment */ +#define DMA36_Y_COUNT 0xFFC10094 /* DMA36 Outer Loop Count Start Value (2D only) */ +#define DMA36_Y_MODIFY 0xFFC10098 /* DMA36 Outer Loop Address Increment (2D only) */ +#define DMA36_CURR_DESC_PTR 0xFFC100A4 /* DMA36 Current Descriptor Pointer */ +#define DMA36_PREV_DESC_PTR 0xFFC100A8 /* DMA36 Previous Initial Descriptor Pointer */ +#define DMA36_CURR_ADDR 0xFFC100AC /* DMA36 Current Address */ +#define DMA36_IRQ_STATUS 0xFFC100B0 /* DMA36 Status Register */ +#define DMA36_CURR_X_COUNT 0xFFC100B4 /* DMA36 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA36_CURR_Y_COUNT 0xFFC100B8 /* DMA36 Current Row Count (2D only) */ +#define DMA36_BWL_COUNT 0xFFC100C0 /* DMA36 Bandwidth Limit Count */ +#define DMA36_CURR_BWL_COUNT 0xFFC100C4 /* DMA36 Bandwidth Limit Count Current */ +#define DMA36_BWM_COUNT 0xFFC100C8 /* DMA36 Bandwidth Monitor Count */ +#define DMA36_CURR_BWM_COUNT 0xFFC100CC /* DMA36 Bandwidth Monitor Count Current */ + +/* ========================= + DMA37 + ========================= */ +#define DMA37_NEXT_DESC_PTR 0xFFC10100 /* DMA37 Pointer to Next Initial Descriptor */ +#define DMA37_START_ADDR 0xFFC10104 /* DMA37 Start Address of Current Buffer */ +#define DMA37_CONFIG 0xFFC10108 /* DMA37 Configuration Register */ +#define DMA37_X_COUNT 0xFFC1010C /* DMA37 Inner Loop Count Start Value */ +#define DMA37_X_MODIFY 0xFFC10110 /* DMA37 Inner Loop Address Increment */ +#define DMA37_Y_COUNT 0xFFC10114 /* DMA37 Outer Loop Count Start Value (2D only) */ +#define DMA37_Y_MODIFY 0xFFC10118 /* DMA37 Outer Loop Address Increment (2D only) */ +#define DMA37_CURR_DESC_PTR 0xFFC10124 /* DMA37 Current Descriptor Pointer */ +#define DMA37_PREV_DESC_PTR 0xFFC10128 /* DMA37 Previous Initial Descriptor Pointer */ +#define DMA37_CURR_ADDR 0xFFC1012C /* DMA37 Current Address */ +#define DMA37_IRQ_STATUS 0xFFC10130 /* DMA37 Status Register */ +#define DMA37_CURR_X_COUNT 0xFFC10134 /* DMA37 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA37_CURR_Y_COUNT 0xFFC10138 /* DMA37 Current Row Count (2D only) */ +#define DMA37_BWL_COUNT 0xFFC10140 /* DMA37 Bandwidth Limit Count */ +#define DMA37_CURR_BWL_COUNT 0xFFC10144 /* DMA37 Bandwidth Limit Count Current */ +#define DMA37_BWM_COUNT 0xFFC10148 /* DMA37 Bandwidth Monitor Count */ +#define DMA37_CURR_BWM_COUNT 0xFFC1014C /* DMA37 Bandwidth Monitor Count Current */ + +/* ========================= + DMA38 + ========================= */ +#define DMA38_NEXT_DESC_PTR 0xFFC12000 /* DMA38 Pointer to Next Initial Descriptor */ +#define DMA38_START_ADDR 0xFFC12004 /* DMA38 Start Address of Current Buffer */ +#define DMA38_CONFIG 0xFFC12008 /* DMA38 Configuration Register */ +#define DMA38_X_COUNT 0xFFC1200C /* DMA38 Inner Loop Count Start Value */ +#define DMA38_X_MODIFY 0xFFC12010 /* DMA38 Inner Loop Address Increment */ +#define DMA38_Y_COUNT 0xFFC12014 /* DMA38 Outer Loop Count Start Value (2D only) */ +#define DMA38_Y_MODIFY 0xFFC12018 /* DMA38 Outer Loop Address Increment (2D only) */ +#define DMA38_CURR_DESC_PTR 0xFFC12024 /* DMA38 Current Descriptor Pointer */ +#define DMA38_PREV_DESC_PTR 0xFFC12028 /* DMA38 Previous Initial Descriptor Pointer */ +#define DMA38_CURR_ADDR 0xFFC1202C /* DMA38 Current Address */ +#define DMA38_IRQ_STATUS 0xFFC12030 /* DMA38 Status Register */ +#define DMA38_CURR_X_COUNT 0xFFC12034 /* DMA38 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA38_CURR_Y_COUNT 0xFFC12038 /* DMA38 Current Row Count (2D only) */ +#define DMA38_BWL_COUNT 0xFFC12040 /* DMA38 Bandwidth Limit Count */ +#define DMA38_CURR_BWL_COUNT 0xFFC12044 /* DMA38 Bandwidth Limit Count Current */ +#define DMA38_BWM_COUNT 0xFFC12048 /* DMA38 Bandwidth Monitor Count */ +#define DMA38_CURR_BWM_COUNT 0xFFC1204C /* DMA38 Bandwidth Monitor Count Current */ + +/* ========================= + DMA39 + ========================= */ +#define DMA39_NEXT_DESC_PTR 0xFFC12080 /* DMA39 Pointer to Next Initial Descriptor */ +#define DMA39_START_ADDR 0xFFC12084 /* DMA39 Start Address of Current Buffer */ +#define DMA39_CONFIG 0xFFC12088 /* DMA39 Configuration Register */ +#define DMA39_X_COUNT 0xFFC1208C /* DMA39 Inner Loop Count Start Value */ +#define DMA39_X_MODIFY 0xFFC12090 /* DMA39 Inner Loop Address Increment */ +#define DMA39_Y_COUNT 0xFFC12094 /* DMA39 Outer Loop Count Start Value (2D only) */ +#define DMA39_Y_MODIFY 0xFFC12098 /* DMA39 Outer Loop Address Increment (2D only) */ +#define DMA39_CURR_DESC_PTR 0xFFC120A4 /* DMA39 Current Descriptor Pointer */ +#define DMA39_PREV_DESC_PTR 0xFFC120A8 /* DMA39 Previous Initial Descriptor Pointer */ +#define DMA39_CURR_ADDR 0xFFC120AC /* DMA39 Current Address */ +#define DMA39_IRQ_STATUS 0xFFC120B0 /* DMA39 Status Register */ +#define DMA39_CURR_X_COUNT 0xFFC120B4 /* DMA39 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA39_CURR_Y_COUNT 0xFFC120B8 /* DMA39 Current Row Count (2D only) */ +#define DMA39_BWL_COUNT 0xFFC120C0 /* DMA39 Bandwidth Limit Count */ +#define DMA39_CURR_BWL_COUNT 0xFFC120C4 /* DMA39 Bandwidth Limit Count Current */ +#define DMA39_BWM_COUNT 0xFFC120C8 /* DMA39 Bandwidth Monitor Count */ +#define DMA39_CURR_BWM_COUNT 0xFFC120CC /* DMA39 Bandwidth Monitor Count Current */ + +/* ========================= + DMA40 + ========================= */ +#define DMA40_NEXT_DESC_PTR 0xFFC12100 /* DMA40 Pointer to Next Initial Descriptor */ +#define DMA40_START_ADDR 0xFFC12104 /* DMA40 Start Address of Current Buffer */ +#define DMA40_CONFIG 0xFFC12108 /* DMA40 Configuration Register */ +#define DMA40_X_COUNT 0xFFC1210C /* DMA40 Inner Loop Count Start Value */ +#define DMA40_X_MODIFY 0xFFC12110 /* DMA40 Inner Loop Address Increment */ +#define DMA40_Y_COUNT 0xFFC12114 /* DMA40 Outer Loop Count Start Value (2D only) */ +#define DMA40_Y_MODIFY 0xFFC12118 /* DMA40 Outer Loop Address Increment (2D only) */ +#define DMA40_CURR_DESC_PTR 0xFFC12124 /* DMA40 Current Descriptor Pointer */ +#define DMA40_PREV_DESC_PTR 0xFFC12128 /* DMA40 Previous Initial Descriptor Pointer */ +#define DMA40_CURR_ADDR 0xFFC1212C /* DMA40 Current Address */ +#define DMA40_IRQ_STATUS 0xFFC12130 /* DMA40 Status Register */ +#define DMA40_CURR_X_COUNT 0xFFC12134 /* DMA40 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA40_CURR_Y_COUNT 0xFFC12138 /* DMA40 Current Row Count (2D only) */ +#define DMA40_BWL_COUNT 0xFFC12140 /* DMA40 Bandwidth Limit Count */ +#define DMA40_CURR_BWL_COUNT 0xFFC12144 /* DMA40 Bandwidth Limit Count Current */ +#define DMA40_BWM_COUNT 0xFFC12148 /* DMA40 Bandwidth Monitor Count */ +#define DMA40_CURR_BWM_COUNT 0xFFC1214C /* DMA40 Bandwidth Monitor Count Current */ + +/* ========================= + DMA41 + ========================= */ +#define DMA41_NEXT_DESC_PTR 0xFFC12180 /* DMA41 Pointer to Next Initial Descriptor */ +#define DMA41_START_ADDR 0xFFC12184 /* DMA41 Start Address of Current Buffer */ +#define DMA41_CONFIG 0xFFC12188 /* DMA41 Configuration Register */ +#define DMA41_X_COUNT 0xFFC1218C /* DMA41 Inner Loop Count Start Value */ +#define DMA41_X_MODIFY 0xFFC12190 /* DMA41 Inner Loop Address Increment */ +#define DMA41_Y_COUNT 0xFFC12194 /* DMA41 Outer Loop Count Start Value (2D only) */ +#define DMA41_Y_MODIFY 0xFFC12198 /* DMA41 Outer Loop Address Increment (2D only) */ +#define DMA41_CURR_DESC_PTR 0xFFC121A4 /* DMA41 Current Descriptor Pointer */ +#define DMA41_PREV_DESC_PTR 0xFFC121A8 /* DMA41 Previous Initial Descriptor Pointer */ +#define DMA41_CURR_ADDR 0xFFC121AC /* DMA41 Current Address */ +#define DMA41_IRQ_STATUS 0xFFC121B0 /* DMA41 Status Register */ +#define DMA41_CURR_X_COUNT 0xFFC121B4 /* DMA41 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA41_CURR_Y_COUNT 0xFFC121B8 /* DMA41 Current Row Count (2D only) */ +#define DMA41_BWL_COUNT 0xFFC121C0 /* DMA41 Bandwidth Limit Count */ +#define DMA41_CURR_BWL_COUNT 0xFFC121C4 /* DMA41 Bandwidth Limit Count Current */ +#define DMA41_BWM_COUNT 0xFFC121C8 /* DMA41 Bandwidth Monitor Count */ +#define DMA41_CURR_BWM_COUNT 0xFFC121CC /* DMA41 Bandwidth Monitor Count Current */ + +/* ========================= + DMA42 + ========================= */ +#define DMA42_NEXT_DESC_PTR 0xFFC14000 /* DMA42 Pointer to Next Initial Descriptor */ +#define DMA42_START_ADDR 0xFFC14004 /* DMA42 Start Address of Current Buffer */ +#define DMA42_CONFIG 0xFFC14008 /* DMA42 Configuration Register */ +#define DMA42_X_COUNT 0xFFC1400C /* DMA42 Inner Loop Count Start Value */ +#define DMA42_X_MODIFY 0xFFC14010 /* DMA42 Inner Loop Address Increment */ +#define DMA42_Y_COUNT 0xFFC14014 /* DMA42 Outer Loop Count Start Value (2D only) */ +#define DMA42_Y_MODIFY 0xFFC14018 /* DMA42 Outer Loop Address Increment (2D only) */ +#define DMA42_CURR_DESC_PTR 0xFFC14024 /* DMA42 Current Descriptor Pointer */ +#define DMA42_PREV_DESC_PTR 0xFFC14028 /* DMA42 Previous Initial Descriptor Pointer */ +#define DMA42_CURR_ADDR 0xFFC1402C /* DMA42 Current Address */ +#define DMA42_IRQ_STATUS 0xFFC14030 /* DMA42 Status Register */ +#define DMA42_CURR_X_COUNT 0xFFC14034 /* DMA42 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA42_CURR_Y_COUNT 0xFFC14038 /* DMA42 Current Row Count (2D only) */ +#define DMA42_BWL_COUNT 0xFFC14040 /* DMA42 Bandwidth Limit Count */ +#define DMA42_CURR_BWL_COUNT 0xFFC14044 /* DMA42 Bandwidth Limit Count Current */ +#define DMA42_BWM_COUNT 0xFFC14048 /* DMA42 Bandwidth Monitor Count */ +#define DMA42_CURR_BWM_COUNT 0xFFC1404C /* DMA42 Bandwidth Monitor Count Current */ + +/* ========================= + DMA43 + ========================= */ +#define DMA43_NEXT_DESC_PTR 0xFFC14080 /* DMA43 Pointer to Next Initial Descriptor */ +#define DMA43_START_ADDR 0xFFC14084 /* DMA43 Start Address of Current Buffer */ +#define DMA43_CONFIG 0xFFC14088 /* DMA43 Configuration Register */ +#define DMA43_X_COUNT 0xFFC1408C /* DMA43 Inner Loop Count Start Value */ +#define DMA43_X_MODIFY 0xFFC14090 /* DMA43 Inner Loop Address Increment */ +#define DMA43_Y_COUNT 0xFFC14094 /* DMA43 Outer Loop Count Start Value (2D only) */ +#define DMA43_Y_MODIFY 0xFFC14098 /* DMA43 Outer Loop Address Increment (2D only) */ +#define DMA43_CURR_DESC_PTR 0xFFC140A4 /* DMA43 Current Descriptor Pointer */ +#define DMA43_PREV_DESC_PTR 0xFFC140A8 /* DMA43 Previous Initial Descriptor Pointer */ +#define DMA43_CURR_ADDR 0xFFC140AC /* DMA43 Current Address */ +#define DMA43_IRQ_STATUS 0xFFC140B0 /* DMA43 Status Register */ +#define DMA43_CURR_X_COUNT 0xFFC140B4 /* DMA43 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA43_CURR_Y_COUNT 0xFFC140B8 /* DMA43 Current Row Count (2D only) */ +#define DMA43_BWL_COUNT 0xFFC140C0 /* DMA43 Bandwidth Limit Count */ +#define DMA43_CURR_BWL_COUNT 0xFFC140C4 /* DMA43 Bandwidth Limit Count Current */ +#define DMA43_BWM_COUNT 0xFFC140C8 /* DMA43 Bandwidth Monitor Count */ +#define DMA43_CURR_BWM_COUNT 0xFFC140CC /* DMA43 Bandwidth Monitor Count Current */ + +/* ========================= + DMA44 + ========================= */ +#define DMA44_NEXT_DESC_PTR 0xFFC14100 /* DMA44 Pointer to Next Initial Descriptor */ +#define DMA44_START_ADDR 0xFFC14104 /* DMA44 Start Address of Current Buffer */ +#define DMA44_CONFIG 0xFFC14108 /* DMA44 Configuration Register */ +#define DMA44_X_COUNT 0xFFC1410C /* DMA44 Inner Loop Count Start Value */ +#define DMA44_X_MODIFY 0xFFC14110 /* DMA44 Inner Loop Address Increment */ +#define DMA44_Y_COUNT 0xFFC14114 /* DMA44 Outer Loop Count Start Value (2D only) */ +#define DMA44_Y_MODIFY 0xFFC14118 /* DMA44 Outer Loop Address Increment (2D only) */ +#define DMA44_CURR_DESC_PTR 0xFFC14124 /* DMA44 Current Descriptor Pointer */ +#define DMA44_PREV_DESC_PTR 0xFFC14128 /* DMA44 Previous Initial Descriptor Pointer */ +#define DMA44_CURR_ADDR 0xFFC1412C /* DMA44 Current Address */ +#define DMA44_IRQ_STATUS 0xFFC14130 /* DMA44 Status Register */ +#define DMA44_CURR_X_COUNT 0xFFC14134 /* DMA44 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA44_CURR_Y_COUNT 0xFFC14138 /* DMA44 Current Row Count (2D only) */ +#define DMA44_BWL_COUNT 0xFFC14140 /* DMA44 Bandwidth Limit Count */ +#define DMA44_CURR_BWL_COUNT 0xFFC14144 /* DMA44 Bandwidth Limit Count Current */ +#define DMA44_BWM_COUNT 0xFFC14148 /* DMA44 Bandwidth Monitor Count */ +#define DMA44_CURR_BWM_COUNT 0xFFC1414C /* DMA44 Bandwidth Monitor Count Current */ + +/* ========================= + DMA45 + ========================= */ +#define DMA45_NEXT_DESC_PTR 0xFFC14180 /* DMA45 Pointer to Next Initial Descriptor */ +#define DMA45_START_ADDR 0xFFC14184 /* DMA45 Start Address of Current Buffer */ +#define DMA45_CONFIG 0xFFC14188 /* DMA45 Configuration Register */ +#define DMA45_X_COUNT 0xFFC1418C /* DMA45 Inner Loop Count Start Value */ +#define DMA45_X_MODIFY 0xFFC14190 /* DMA45 Inner Loop Address Increment */ +#define DMA45_Y_COUNT 0xFFC14194 /* DMA45 Outer Loop Count Start Value (2D only) */ +#define DMA45_Y_MODIFY 0xFFC14198 /* DMA45 Outer Loop Address Increment (2D only) */ +#define DMA45_CURR_DESC_PTR 0xFFC141A4 /* DMA45 Current Descriptor Pointer */ +#define DMA45_PREV_DESC_PTR 0xFFC141A8 /* DMA45 Previous Initial Descriptor Pointer */ +#define DMA45_CURR_ADDR 0xFFC141AC /* DMA45 Current Address */ +#define DMA45_IRQ_STATUS 0xFFC141B0 /* DMA45 Status Register */ +#define DMA45_CURR_X_COUNT 0xFFC141B4 /* DMA45 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA45_CURR_Y_COUNT 0xFFC141B8 /* DMA45 Current Row Count (2D only) */ +#define DMA45_BWL_COUNT 0xFFC141C0 /* DMA45 Bandwidth Limit Count */ +#define DMA45_CURR_BWL_COUNT 0xFFC141C4 /* DMA45 Bandwidth Limit Count Current */ +#define DMA45_BWM_COUNT 0xFFC141C8 /* DMA45 Bandwidth Monitor Count */ +#define DMA45_CURR_BWM_COUNT 0xFFC141CC /* DMA45 Bandwidth Monitor Count Current */ + +/* ========================= + DMA46 + ========================= */ +#define DMA46_NEXT_DESC_PTR 0xFFC14200 /* DMA46 Pointer to Next Initial Descriptor */ +#define DMA46_START_ADDR 0xFFC14204 /* DMA46 Start Address of Current Buffer */ +#define DMA46_CONFIG 0xFFC14208 /* DMA46 Configuration Register */ +#define DMA46_X_COUNT 0xFFC1420C /* DMA46 Inner Loop Count Start Value */ +#define DMA46_X_MODIFY 0xFFC14210 /* DMA46 Inner Loop Address Increment */ +#define DMA46_Y_COUNT 0xFFC14214 /* DMA46 Outer Loop Count Start Value (2D only) */ +#define DMA46_Y_MODIFY 0xFFC14218 /* DMA46 Outer Loop Address Increment (2D only) */ +#define DMA46_CURR_DESC_PTR 0xFFC14224 /* DMA46 Current Descriptor Pointer */ +#define DMA46_PREV_DESC_PTR 0xFFC14228 /* DMA46 Previous Initial Descriptor Pointer */ +#define DMA46_CURR_ADDR 0xFFC1422C /* DMA46 Current Address */ +#define DMA46_IRQ_STATUS 0xFFC14230 /* DMA46 Status Register */ +#define DMA46_CURR_X_COUNT 0xFFC14234 /* DMA46 Current Count(1D) or intra-row XCNT (2D) */ +#define DMA46_CURR_Y_COUNT 0xFFC14238 /* DMA46 Current Row Count (2D only) */ +#define DMA46_BWL_COUNT 0xFFC14240 /* DMA46 Bandwidth Limit Count */ +#define DMA46_CURR_BWL_COUNT 0xFFC14244 /* DMA46 Bandwidth Limit Count Current */ +#define DMA46_BWM_COUNT 0xFFC14248 /* DMA46 Bandwidth Monitor Count */ +#define DMA46_CURR_BWM_COUNT 0xFFC1424C /* DMA46 Bandwidth Monitor Count Current */ + + +/******************************************************************************** + DMA Alias Definitions + ********************************************************************************/ +#define MDMA0_DEST_CRC0_NEXT_DESC_PTR (DMA22_NEXT_DESC_PTR) +#define MDMA0_DEST_CRC0_START_ADDR (DMA22_START_ADDR) +#define MDMA0_DEST_CRC0_CONFIG (DMA22_CONFIG) +#define MDMA0_DEST_CRC0_X_COUNT (DMA22_X_COUNT) +#define MDMA0_DEST_CRC0_X_MODIFY (DMA22_X_MODIFY) +#define MDMA0_DEST_CRC0_Y_COUNT (DMA22_Y_COUNT) +#define MDMA0_DEST_CRC0_Y_MODIFY (DMA22_Y_MODIFY) +#define MDMA0_DEST_CRC0_CURR_DESC_PTR (DMA22_CURR_DESC_PTR) +#define MDMA0_DEST_CRC0_PREV_DESC_PTR (DMA22_PREV_DESC_PTR) +#define MDMA0_DEST_CRC0_CURR_ADDR (DMA22_CURR_ADDR) +#define MDMA0_DEST_CRC0_IRQ_STATUS (DMA22_IRQ_STATUS) +#define MDMA0_DEST_CRC0_CURR_X_COUNT (DMA22_CURR_X_COUNT) +#define MDMA0_DEST_CRC0_CURR_Y_COUNT (DMA22_CURR_Y_COUNT) +#define MDMA0_DEST_CRC0_BWL_COUNT (DMA22_BWL_COUNT) +#define MDMA0_DEST_CRC0_CURR_BWL_COUNT (DMA22_CURR_BWL_COUNT) +#define MDMA0_DEST_CRC0_BWM_COUNT (DMA22_BWM_COUNT) +#define MDMA0_DEST_CRC0_CURR_BWM_COUNT (DMA22_CURR_BWM_COUNT) +#define MDMA0_SRC_CRC0_NEXT_DESC_PTR (DMA21_NEXT_DESC_PTR) +#define MDMA0_SRC_CRC0_START_ADDR (DMA21_START_ADDR) +#define MDMA0_SRC_CRC0_CONFIG (DMA21_CONFIG) +#define MDMA0_SRC_CRC0_X_COUNT (DMA21_X_COUNT) +#define MDMA0_SRC_CRC0_X_MODIFY (DMA21_X_MODIFY) +#define MDMA0_SRC_CRC0_Y_COUNT (DMA21_Y_COUNT) +#define MDMA0_SRC_CRC0_Y_MODIFY (DMA21_Y_MODIFY) +#define MDMA0_SRC_CRC0_CURR_DESC_PTR (DMA21_CURR_DESC_PTR) +#define MDMA0_SRC_CRC0_PREV_DESC_PTR (DMA21_PREV_DESC_PTR) +#define MDMA0_SRC_CRC0_CURR_ADDR (DMA21_CURR_ADDR) +#define MDMA0_SRC_CRC0_IRQ_STATUS (DMA21_IRQ_STATUS) +#define MDMA0_SRC_CRC0_CURR_X_COUNT (DMA21_CURR_X_COUNT) +#define MDMA0_SRC_CRC0_CURR_Y_COUNT (DMA21_CURR_Y_COUNT) +#define MDMA0_SRC_CRC0_BWL_COUNT (DMA21_BWL_COUNT) +#define MDMA0_SRC_CRC0_CURR_BWL_COUNT (DMA21_CURR_BWL_COUNT) +#define MDMA0_SRC_CRC0_BWM_COUNT (DMA21_BWM_COUNT) +#define MDMA0_SRC_CRC0_CURR_BWM_COUNT (DMA21_CURR_BWM_COUNT) +#define MDMA1_DEST_CRC1_NEXT_DESC_PTR (DMA24_NEXT_DESC_PTR) +#define MDMA1_DEST_CRC1_START_ADDR (DMA24_START_ADDR) +#define MDMA1_DEST_CRC1_CONFIG (DMA24_CONFIG) +#define MDMA1_DEST_CRC1_X_COUNT (DMA24_X_COUNT) +#define MDMA1_DEST_CRC1_X_MODIFY (DMA24_X_MODIFY) +#define MDMA1_DEST_CRC1_Y_COUNT (DMA24_Y_COUNT) +#define MDMA1_DEST_CRC1_Y_MODIFY (DMA24_Y_MODIFY) +#define MDMA1_DEST_CRC1_CURR_DESC_PTR (DMA24_CURR_DESC_PTR) +#define MDMA1_DEST_CRC1_PREV_DESC_PTR (DMA24_PREV_DESC_PTR) +#define MDMA1_DEST_CRC1_CURR_ADDR (DMA24_CURR_ADDR) +#define MDMA1_DEST_CRC1_IRQ_STATUS (DMA24_IRQ_STATUS) +#define MDMA1_DEST_CRC1_CURR_X_COUNT (DMA24_CURR_X_COUNT) +#define MDMA1_DEST_CRC1_CURR_Y_COUNT (DMA24_CURR_Y_COUNT) +#define MDMA1_DEST_CRC1_BWL_COUNT (DMA24_BWL_COUNT) +#define MDMA1_DEST_CRC1_CURR_BWL_COUNT (DMA24_CURR_BWL_COUNT) +#define MDMA1_DEST_CRC1_BWM_COUNT (DMA24_BWM_COUNT) +#define MDMA1_DEST_CRC1_CURR_BWM_COUNT (DMA24_CURR_BWM_COUNT) +#define MDMA1_SRC_CRC1_NEXT_DESC_PTR (DMA23_NEXT_DESC_PTR) +#define MDMA1_SRC_CRC1_START_ADDR (DMA23_START_ADDR) +#define MDMA1_SRC_CRC1_CONFIG (DMA23_CONFIG) +#define MDMA1_SRC_CRC1_X_COUNT (DMA23_X_COUNT) +#define MDMA1_SRC_CRC1_X_MODIFY (DMA23_X_MODIFY) +#define MDMA1_SRC_CRC1_Y_COUNT (DMA23_Y_COUNT) +#define MDMA1_SRC_CRC1_Y_MODIFY (DMA23_Y_MODIFY) +#define MDMA1_SRC_CRC1_CURR_DESC_PTR (DMA23_CURR_DESC_PTR) +#define MDMA1_SRC_CRC1_PREV_DESC_PTR (DMA23_PREV_DESC_PTR) +#define MDMA1_SRC_CRC1_CURR_ADDR (DMA23_CURR_ADDR) +#define MDMA1_SRC_CRC1_IRQ_STATUS (DMA23_IRQ_STATUS) +#define MDMA1_SRC_CRC1_CURR_X_COUNT (DMA23_CURR_X_COUNT) +#define MDMA1_SRC_CRC1_CURR_Y_COUNT (DMA23_CURR_Y_COUNT) +#define MDMA1_SRC_CRC1_BWL_COUNT (DMA23_BWL_COUNT) +#define MDMA1_SRC_CRC1_CURR_BWL_COUNT (DMA23_CURR_BWL_COUNT) +#define MDMA1_SRC_CRC1_BWM_COUNT (DMA23_BWM_COUNT) +#define MDMA1_SRC_CRC1_CURR_BWM_COUNT (DMA23_CURR_BWM_COUNT) +#define MDMA2_DEST_NEXT_DESC_PTR (DMA26_NEXT_DESC_PTR) +#define MDMA2_DEST_START_ADDR (DMA26_START_ADDR) +#define MDMA2_DEST_CONFIG (DMA26_CONFIG) +#define MDMA2_DEST_X_COUNT (DMA26_X_COUNT) +#define MDMA2_DEST_X_MODIFY (DMA26_X_MODIFY) +#define MDMA2_DEST_Y_COUNT (DMA26_Y_COUNT) +#define MDMA2_DEST_Y_MODIFY (DMA26_Y_MODIFY) +#define MDMA2_DEST_CURR_DESC_PTR (DMA26_CURR_DESC_PTR) +#define MDMA2_DEST_PREV_DESC_PTR (DMA26_PREV_DESC_PTR) +#define MDMA2_DEST_CURR_ADDR (DMA26_CURR_ADDR) +#define MDMA2_DEST_IRQ_STATUS (DMA26_IRQ_STATUS) +#define MDMA2_DEST_CURR_X_COUNT (DMA26_CURR_X_COUNT) +#define MDMA2_DEST_CURR_Y_COUNT (DMA26_CURR_Y_COUNT) +#define MDMA2_DEST_BWL_COUNT (DMA26_BWL_COUNT) +#define MDMA2_DEST_CURR_BWL_COUNT (DMA26_CURR_BWL_COUNT) +#define MDMA2_DEST_BWM_COUNT (DMA26_BWM_COUNT) +#define MDMA2_DEST_CURR_BWM_COUNT (DMA26_CURR_BWM_COUNT) +#define MDMA2_SRC_NEXT_DESC_PTR (DMA25_NEXT_DESC_PTR) +#define MDMA2_SRC_START_ADDR (DMA25_START_ADDR) +#define MDMA2_SRC_CONFIG (DMA25_CONFIG) +#define MDMA2_SRC_X_COUNT (DMA25_X_COUNT) +#define MDMA2_SRC_X_MODIFY (DMA25_X_MODIFY) +#define MDMA2_SRC_Y_COUNT (DMA25_Y_COUNT) +#define MDMA2_SRC_Y_MODIFY (DMA25_Y_MODIFY) +#define MDMA2_SRC_CURR_DESC_PTR (DMA25_CURR_DESC_PTR) +#define MDMA2_SRC_PREV_DESC_PTR (DMA25_PREV_DESC_PTR) +#define MDMA2_SRC_CURR_ADDR (DMA25_CURR_ADDR) +#define MDMA2_SRC_IRQ_STATUS (DMA25_IRQ_STATUS) +#define MDMA2_SRC_CURR_X_COUNT (DMA25_CURR_X_COUNT) +#define MDMA2_SRC_CURR_Y_COUNT (DMA25_CURR_Y_COUNT) +#define MDMA2_SRC_BWL_COUNT (DMA25_BWL_COUNT) +#define MDMA2_SRC_CURR_BWL_COUNT (DMA25_CURR_BWL_COUNT) +#define MDMA2_SRC_BWM_COUNT (DMA25_BWM_COUNT) +#define MDMA2_SRC_CURR_BWM_COUNT (DMA25_CURR_BWM_COUNT) +#define MDMA3_DEST_NEXT_DESC_PTR (DMA28_NEXT_DESC_PTR) +#define MDMA3_DEST_START_ADDR (DMA28_START_ADDR) +#define MDMA3_DEST_CONFIG (DMA28_CONFIG) +#define MDMA3_DEST_X_COUNT (DMA28_X_COUNT) +#define MDMA3_DEST_X_MODIFY (DMA28_X_MODIFY) +#define MDMA3_DEST_Y_COUNT (DMA28_Y_COUNT) +#define MDMA3_DEST_Y_MODIFY (DMA28_Y_MODIFY) +#define MDMA3_DEST_CURR_DESC_PTR (DMA28_CURR_DESC_PTR) +#define MDMA3_DEST_PREV_DESC_PTR (DMA28_PREV_DESC_PTR) +#define MDMA3_DEST_CURR_ADDR (DMA28_CURR_ADDR) +#define MDMA3_DEST_IRQ_STATUS (DMA28_IRQ_STATUS) +#define MDMA3_DEST_CURR_X_COUNT (DMA28_CURR_X_COUNT) +#define MDMA3_DEST_CURR_Y_COUNT (DMA28_CURR_Y_COUNT) +#define MDMA3_DEST_BWL_COUNT (DMA28_BWL_COUNT) +#define MDMA3_DEST_CURR_BWL_COUNT (DMA28_CURR_BWL_COUNT) +#define MDMA3_DEST_BWM_COUNT (DMA28_BWM_COUNT) +#define MDMA3_DEST_CURR_BWM_COUNT (DMA28_CURR_BWM_COUNT) +#define MDMA3_SRC_NEXT_DESC_PTR (DMA27_NEXT_DESC_PTR) +#define MDMA3_SRC_START_ADDR (DMA27_START_ADDR) +#define MDMA3_SRC_CONFIG (DMA27_CONFIG) +#define MDMA3_SRC_X_COUNT (DMA27_X_COUNT) +#define MDMA3_SRC_X_MODIFY (DMA27_X_MODIFY) +#define MDMA3_SRC_Y_COUNT (DMA27_Y_COUNT) +#define MDMA3_SRC_Y_MODIFY (DMA27_Y_MODIFY) +#define MDMA3_SRC_CURR_DESC_PTR (DMA27_CURR_DESC_PTR) +#define MDMA3_SRC_PREV_DESC_PTR (DMA27_PREV_DESC_PTR) +#define MDMA3_SRC_CURR_ADDR (DMA27_CURR_ADDR) +#define MDMA3_SRC_IRQ_STATUS (DMA27_IRQ_STATUS) +#define MDMA3_SRC_CURR_X_COUNT (DMA27_CURR_X_COUNT) +#define MDMA3_SRC_CURR_Y_COUNT (DMA27_CURR_Y_COUNT) +#define MDMA3_SRC_BWL_COUNT (DMA27_BWL_COUNT) +#define MDMA3_SRC_CURR_BWL_COUNT (DMA27_CURR_BWL_COUNT) +#define MDMA3_SRC_BWM_COUNT (DMA27_BWM_COUNT) +#define MDMA3_SRC_CURR_BWM_COUNT (DMA27_CURR_BWM_COUNT) + + +/* ========================= + DMC Registers + ========================= */ + +/* ========================= + DMC0 + ========================= */ +#define DMC0_ID 0xFFC80000 /* DMC0 Identification Register */ +#define DMC0_CTL 0xFFC80004 /* DMC0 Control Register */ +#define DMC0_STAT 0xFFC80008 /* DMC0 Status Register */ +#define DMC0_EFFCTL 0xFFC8000C /* DMC0 Efficiency Controller */ +#define DMC0_PRIO 0xFFC80010 /* DMC0 Priority ID Register */ +#define DMC0_PRIOMSK 0xFFC80014 /* DMC0 Priority ID Mask */ +#define DMC0_CFG 0xFFC80040 /* DMC0 SDRAM Configuration */ +#define DMC0_TR0 0xFFC80044 /* DMC0 Timing Register 0 */ +#define DMC0_TR1 0xFFC80048 /* DMC0 Timing Register 1 */ +#define DMC0_TR2 0xFFC8004C /* DMC0 Timing Register 2 */ +#define DMC0_MSK 0xFFC8005C /* DMC0 Mode Register Mask */ +#define DMC0_MR 0xFFC80060 /* DMC0 Mode Shadow register */ +#define DMC0_EMR1 0xFFC80064 /* DMC0 EMR1 Shadow Register */ +#define DMC0_EMR2 0xFFC80068 /* DMC0 EMR2 Shadow Register */ +#define DMC0_EMR3 0xFFC8006C /* DMC0 EMR3 Shadow Register */ +#define DMC0_DLLCTL 0xFFC80080 /* DMC0 DLL Control Register */ +#define DMC0_PADCTL 0xFFC800C0 /* DMC0 PAD Control Register 0 */ + +#define DEVSZ_64 0x000 /* DMC External Bank Size = 64Mbit */ +#define DEVSZ_128 0x100 /* DMC External Bank Size = 128Mbit */ +#define DEVSZ_256 0x200 /* DMC External Bank Size = 256Mbit */ +#define DEVSZ_512 0x300 /* DMC External Bank Size = 512Mbit */ +#define DEVSZ_1G 0x400 /* DMC External Bank Size = 1Gbit */ +#define DEVSZ_2G 0x500 /* DMC External Bank Size = 2Gbit */ + + +/* ========================= + L2CTL Registers + ========================= */ + +/* ========================= + L2CTL0 + ========================= */ +#define L2CTL0_CTL 0xFFCA3000 /* L2CTL0 L2 Control Register */ +#define L2CTL0_ACTL_C0 0xFFCA3004 /* L2CTL0 L2 Core 0 Access Control Register */ +#define L2CTL0_ACTL_C1 0xFFCA3008 /* L2CTL0 L2 Core 1 Access Control Register */ +#define L2CTL0_ACTL_SYS 0xFFCA300C /* L2CTL0 L2 System Access Control Register */ +#define L2CTL0_STAT 0xFFCA3010 /* L2CTL0 L2 Status Register */ +#define L2CTL0_RPCR 0xFFCA3014 /* L2CTL0 L2 Read Priority Count Register */ +#define L2CTL0_WPCR 0xFFCA3018 /* L2CTL0 L2 Write Priority Count Register */ +#define L2CTL0_RFA 0xFFCA3024 /* L2CTL0 L2 Refresh Address Regsiter */ +#define L2CTL0_ERRADDR0 0xFFCA3040 /* L2CTL0 L2 Bank 0 ECC Error Address Register */ +#define L2CTL0_ERRADDR1 0xFFCA3044 /* L2CTL0 L2 Bank 1 ECC Error Address Register */ +#define L2CTL0_ERRADDR2 0xFFCA3048 /* L2CTL0 L2 Bank 2 ECC Error Address Register */ +#define L2CTL0_ERRADDR3 0xFFCA304C /* L2CTL0 L2 Bank 3 ECC Error Address Register */ +#define L2CTL0_ERRADDR4 0xFFCA3050 /* L2CTL0 L2 Bank 4 ECC Error Address Register */ +#define L2CTL0_ERRADDR5 0xFFCA3054 /* L2CTL0 L2 Bank 5 ECC Error Address Register */ +#define L2CTL0_ERRADDR6 0xFFCA3058 /* L2CTL0 L2 Bank 6 ECC Error Address Register */ +#define L2CTL0_ERRADDR7 0xFFCA305C /* L2CTL0 L2 Bank 7 ECC Error Address Register */ +#define L2CTL0_ET0 0xFFCA3080 /* L2CTL0 L2 AXI Error 0 Type Register */ +#define L2CTL0_EADDR0 0xFFCA3084 /* L2CTL0 L2 AXI Error 0 Address Register */ +#define L2CTL0_ET1 0xFFCA3088 /* L2CTL0 L2 AXI Error 1 Type Register */ +#define L2CTL0_EADDR1 0xFFCA308C /* L2CTL0 L2 AXI Error 1 Address Register */ + + +/* ========================= + SEC Registers + ========================= */ +/* ------------------------------------------------------------------------------------------------------------------------ + SEC Core Interface (SCI) Register Definitions + ------------------------------------------------------------------------------------------------------------------------ */ + +#define SEC_SCI_BASE 0xFFCA4400 +#define SEC_SCI_OFF 0x40 +#define SEC_CCTL 0x0 /* SEC Core Control Register n */ +#define SEC_CSTAT 0x4 /* SEC Core Status Register n */ +#define SEC_CPND 0x8 /* SEC Core Pending IRQ Register n */ +#define SEC_CACT 0xC /* SEC Core Active IRQ Register n */ +#define SEC_CPMSK 0x10 /* SEC Core IRQ Priority Mask Register n */ +#define SEC_CGMSK 0x14 /* SEC Core IRQ Group Mask Register n */ +#define SEC_CPLVL 0x18 /* SEC Core IRQ Priority Level Register n */ +#define SEC_CSID 0x1C /* SEC Core IRQ Source ID Register n */ + +#define bfin_read_SEC_SCI(n, reg) bfin_read32(SEC_SCI_BASE + (n) * SEC_SCI_OFF + reg) +#define bfin_write_SEC_SCI(n, reg, val) \ + bfin_write32(SEC_SCI_BASE + (n) * SEC_SCI_OFF + reg, val) + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC Fault Management Interface (SFI) Register Definitions + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_FCTL 0xFFCA4010 /* SEC Fault Control Register */ +#define SEC_FSTAT 0xFFCA4014 /* SEC Fault Status Register */ +#define SEC_FSID 0xFFCA4018 /* SEC Fault Source ID Register */ +#define SEC_FEND 0xFFCA401C /* SEC Fault End Register */ +#define SEC_FDLY 0xFFCA4020 /* SEC Fault Delay Register */ +#define SEC_FDLY_CUR 0xFFCA4024 /* SEC Fault Delay Current Register */ +#define SEC_FSRDLY 0xFFCA4028 /* SEC Fault System Reset Delay Register */ +#define SEC_FSRDLY_CUR 0xFFCA402C /* SEC Fault System Reset Delay Current Register */ +#define SEC_FCOPP 0xFFCA4030 /* SEC Fault COP Period Register */ +#define SEC_FCOPP_CUR 0xFFCA4034 /* SEC Fault COP Period Current Register */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC Global Register Definitions + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_GCTL 0xFFCA4000 /* SEC Global Control Register */ +#define SEC_GSTAT 0xFFCA4004 /* SEC Global Status Register */ +#define SEC_RAISE 0xFFCA4008 /* SEC Global Raise Register */ +#define SEC_END 0xFFCA400C /* SEC Global End Register */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC Source Interface (SSI) Register Definitions + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_SCTL0 0xFFCA4800 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL1 0xFFCA4808 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL2 0xFFCA4810 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL3 0xFFCA4818 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL4 0xFFCA4820 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL5 0xFFCA4828 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL6 0xFFCA4830 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL7 0xFFCA4838 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL8 0xFFCA4840 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL9 0xFFCA4848 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL10 0xFFCA4850 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL11 0xFFCA4858 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL12 0xFFCA4860 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL13 0xFFCA4868 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL14 0xFFCA4870 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL15 0xFFCA4878 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL16 0xFFCA4880 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL17 0xFFCA4888 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL18 0xFFCA4890 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL19 0xFFCA4898 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL20 0xFFCA48A0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL21 0xFFCA48A8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL22 0xFFCA48B0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL23 0xFFCA48B8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL24 0xFFCA48C0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL25 0xFFCA48C8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL26 0xFFCA48D0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL27 0xFFCA48D8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL28 0xFFCA48E0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL29 0xFFCA48E8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL30 0xFFCA48F0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL31 0xFFCA48F8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL32 0xFFCA4900 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL33 0xFFCA4908 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL34 0xFFCA4910 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL35 0xFFCA4918 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL36 0xFFCA4920 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL37 0xFFCA4928 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL38 0xFFCA4930 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL39 0xFFCA4938 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL40 0xFFCA4940 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL41 0xFFCA4948 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL42 0xFFCA4950 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL43 0xFFCA4958 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL44 0xFFCA4960 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL45 0xFFCA4968 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL46 0xFFCA4970 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL47 0xFFCA4978 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL48 0xFFCA4980 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL49 0xFFCA4988 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL50 0xFFCA4990 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL51 0xFFCA4998 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL52 0xFFCA49A0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL53 0xFFCA49A8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL54 0xFFCA49B0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL55 0xFFCA49B8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL56 0xFFCA49C0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL57 0xFFCA49C8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL58 0xFFCA49D0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL59 0xFFCA49D8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL60 0xFFCA49E0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL61 0xFFCA49E8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL62 0xFFCA49F0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL63 0xFFCA49F8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL64 0xFFCA4A00 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL65 0xFFCA4A08 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL66 0xFFCA4A10 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL67 0xFFCA4A18 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL68 0xFFCA4A20 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL69 0xFFCA4A28 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL70 0xFFCA4A30 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL71 0xFFCA4A38 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL72 0xFFCA4A40 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL73 0xFFCA4A48 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL74 0xFFCA4A50 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL75 0xFFCA4A58 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL76 0xFFCA4A60 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL77 0xFFCA4A68 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL78 0xFFCA4A70 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL79 0xFFCA4A78 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL80 0xFFCA4A80 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL81 0xFFCA4A88 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL82 0xFFCA4A90 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL83 0xFFCA4A98 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL84 0xFFCA4AA0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL85 0xFFCA4AA8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL86 0xFFCA4AB0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL87 0xFFCA4AB8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL88 0xFFCA4AC0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL89 0xFFCA4AC8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL90 0xFFCA4AD0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL91 0xFFCA4AD8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL92 0xFFCA4AE0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL93 0xFFCA4AE8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL94 0xFFCA4AF0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL95 0xFFCA4AF8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL96 0xFFCA4B00 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL97 0xFFCA4B08 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL98 0xFFCA4B10 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL99 0xFFCA4B18 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL100 0xFFCA4B20 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL101 0xFFCA4B28 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL102 0xFFCA4B30 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL103 0xFFCA4B38 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL104 0xFFCA4B40 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL105 0xFFCA4B48 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL106 0xFFCA4B50 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL107 0xFFCA4B58 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL108 0xFFCA4B60 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL109 0xFFCA4B68 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL110 0xFFCA4B70 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL111 0xFFCA4B78 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL112 0xFFCA4B80 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL113 0xFFCA4B88 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL114 0xFFCA4B90 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL115 0xFFCA4B98 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL116 0xFFCA4BA0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL117 0xFFCA4BA8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL118 0xFFCA4BB0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL119 0xFFCA4BB8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL120 0xFFCA4BC0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL121 0xFFCA4BC8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL122 0xFFCA4BD0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL123 0xFFCA4BD8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL124 0xFFCA4BE0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL125 0xFFCA4BE8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL126 0xFFCA4BF0 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL127 0xFFCA4BF8 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL128 0xFFCA4C00 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL129 0xFFCA4C08 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL130 0xFFCA4C10 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL131 0xFFCA4C18 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL132 0xFFCA4C20 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL133 0xFFCA4C28 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL134 0xFFCA4C30 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL135 0xFFCA4C38 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL136 0xFFCA4C40 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL137 0xFFCA4C48 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL138 0xFFCA4C50 /* SEC IRQ Source Control Register n */ +#define SEC_SCTL139 0xFFCA4C58 /* SEC IRQ Source Control Register n */ +#define SEC_SSTAT0 0xFFCA4804 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT1 0xFFCA480C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT2 0xFFCA4814 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT3 0xFFCA481C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT4 0xFFCA4824 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT5 0xFFCA482C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT6 0xFFCA4834 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT7 0xFFCA483C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT8 0xFFCA4844 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT9 0xFFCA484C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT10 0xFFCA4854 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT11 0xFFCA485C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT12 0xFFCA4864 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT13 0xFFCA486C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT14 0xFFCA4874 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT15 0xFFCA487C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT16 0xFFCA4884 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT17 0xFFCA488C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT18 0xFFCA4894 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT19 0xFFCA489C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT20 0xFFCA48A4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT21 0xFFCA48AC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT22 0xFFCA48B4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT23 0xFFCA48BC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT24 0xFFCA48C4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT25 0xFFCA48CC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT26 0xFFCA48D4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT27 0xFFCA48DC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT28 0xFFCA48E4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT29 0xFFCA48EC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT30 0xFFCA48F4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT31 0xFFCA48FC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT32 0xFFCA4904 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT33 0xFFCA490C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT34 0xFFCA4914 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT35 0xFFCA491C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT36 0xFFCA4924 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT37 0xFFCA492C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT38 0xFFCA4934 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT39 0xFFCA493C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT40 0xFFCA4944 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT41 0xFFCA494C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT42 0xFFCA4954 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT43 0xFFCA495C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT44 0xFFCA4964 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT45 0xFFCA496C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT46 0xFFCA4974 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT47 0xFFCA497C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT48 0xFFCA4984 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT49 0xFFCA498C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT50 0xFFCA4994 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT51 0xFFCA499C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT52 0xFFCA49A4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT53 0xFFCA49AC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT54 0xFFCA49B4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT55 0xFFCA49BC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT56 0xFFCA49C4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT57 0xFFCA49CC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT58 0xFFCA49D4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT59 0xFFCA49DC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT60 0xFFCA49E4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT61 0xFFCA49EC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT62 0xFFCA49F4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT63 0xFFCA49FC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT64 0xFFCA4A04 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT65 0xFFCA4A0C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT66 0xFFCA4A14 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT67 0xFFCA4A1C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT68 0xFFCA4A24 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT69 0xFFCA4A2C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT70 0xFFCA4A34 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT71 0xFFCA4A3C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT72 0xFFCA4A44 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT73 0xFFCA4A4C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT74 0xFFCA4A54 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT75 0xFFCA4A5C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT76 0xFFCA4A64 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT77 0xFFCA4A6C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT78 0xFFCA4A74 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT79 0xFFCA4A7C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT80 0xFFCA4A84 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT81 0xFFCA4A8C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT82 0xFFCA4A94 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT83 0xFFCA4A9C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT84 0xFFCA4AA4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT85 0xFFCA4AAC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT86 0xFFCA4AB4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT87 0xFFCA4ABC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT88 0xFFCA4AC4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT89 0xFFCA4ACC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT90 0xFFCA4AD4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT91 0xFFCA4ADC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT92 0xFFCA4AE4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT93 0xFFCA4AEC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT94 0xFFCA4AF4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT95 0xFFCA4AFC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT96 0xFFCA4B04 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT97 0xFFCA4B0C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT98 0xFFCA4B14 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT99 0xFFCA4B1C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT100 0xFFCA4B24 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT101 0xFFCA4B2C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT102 0xFFCA4B34 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT103 0xFFCA4B3C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT104 0xFFCA4B44 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT105 0xFFCA4B4C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT106 0xFFCA4B54 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT107 0xFFCA4B5C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT108 0xFFCA4B64 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT109 0xFFCA4B6C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT110 0xFFCA4B74 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT111 0xFFCA4B7C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT112 0xFFCA4B84 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT113 0xFFCA4B8C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT114 0xFFCA4B94 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT115 0xFFCA4B9C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT116 0xFFCA4BA4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT117 0xFFCA4BAC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT118 0xFFCA4BB4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT119 0xFFCA4BBC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT120 0xFFCA4BC4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT121 0xFFCA4BCC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT122 0xFFCA4BD4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT123 0xFFCA4BDC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT124 0xFFCA4BE4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT125 0xFFCA4BEC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT126 0xFFCA4BF4 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT127 0xFFCA4BFC /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT128 0xFFCA4C04 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT129 0xFFCA4C0C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT130 0xFFCA4C14 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT131 0xFFCA4C1C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT132 0xFFCA4C24 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT133 0xFFCA4C2C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT134 0xFFCA4C34 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT135 0xFFCA4C3C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT136 0xFFCA4C44 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT137 0xFFCA4C4C /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT138 0xFFCA4C54 /* SEC IRQ Source Status Register n */ +#define SEC_SSTAT139 0xFFCA4C5C /* SEC IRQ Source Status Register n */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_CCTL Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_CCTL_LOCK 0x80000000 /* LOCK: Lock */ +#define SEC_CCTL_NMI_EN 0x00010000 /* NMIEN: Enable */ +#define SEC_CCTL_WAITIDLE 0x00001000 /* WFI: Wait for Idle */ +#define SEC_CCTL_RESET 0x00000002 /* RESET: Reset */ +#define SEC_CCTL_EN 0x00000001 /* EN: Enable */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_CSTAT Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_CSTAT_NMI 0x00010000 /* NMI Status */ +#define SEC_CSTAT_WAITING 0x00001000 /* WFI: Waiting */ +#define SEC_CSTAT_VALID_SID 0x00000400 /* SIDV: Valid */ +#define SEC_CSTAT_VALID_ACT 0x00000200 /* ACTV: Valid */ +#define SEC_CSTAT_VALID_PND 0x00000100 /* PNDV: Valid */ +#define SEC_CSTAT_ERRC 0x00000030 /* Error Cause */ +#define SEC_CSTAT_ACKERR 0x00000010 /* ERRC: Acknowledge Error */ +#define SEC_CSTAT_ERR 0x00000002 /* ERR: Error Occurred */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_CPND Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_CPND_PRIO 0x0000FF00 /* Highest Pending IRQ Priority */ +#define SEC_CPND_SID 0x000000FF /* Highest Pending IRQ Source ID */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_CACT Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_CACT_PRIO 0x0000FF00 /* Highest Active IRQ Priority */ +#define SEC_CACT_SID 0x000000FF /* Highest Active IRQ Source ID */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_CPMSK Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_CPMSK_LOCK 0x80000000 /* LOCK: Lock */ +#define SEC_CPMSK_PRIO 0x000000FF /* IRQ Priority Mask */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_CGMSK Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_CGMSK_LOCK 0x80000000 /* LOCK: Lock */ +#define SEC_CGMSK_MASK 0x00000100 /* UGRP: Mask Ungrouped Sources */ +#define SEC_CGMSK_GRP 0x0000000F /* Grouped Mask */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_CPLVL Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_CPLVL_LOCK 0x80000000 /* LOCK: Lock */ +#define SEC_CPLVL_PLVL 0x00000007 /* Priority Levels */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_CSID Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_CSID_SID 0x000000FF /* Source ID */ + + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_FCTL Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_FCTL_LOCK 0x80000000 /* LOCK: Lock */ +#define SEC_FCTL_FLTPND_MODE 0x00002000 /* TES: Fault Pending Mode */ +#define SEC_FCTL_COP_MODE 0x00001000 /* CMS: COP Mode */ +#define SEC_FCTL_FLTIN_EN 0x00000080 /* FIEN: Enable */ +#define SEC_FCTL_SYSRST_EN 0x00000040 /* SREN: Enable */ +#define SEC_FCTL_TRGOUT_EN 0x00000020 /* TOEN: Enable */ +#define SEC_FCTL_FLTOUT_EN 0x00000010 /* FOEN: Enable */ +#define SEC_FCTL_RESET 0x00000002 /* RESET: Reset */ +#define SEC_FCTL_EN 0x00000001 /* EN: Enable */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_FSTAT Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_FSTAT_NXTFLT 0x00000400 /* NPND: Pending */ +#define SEC_FSTAT_FLTACT 0x00000200 /* ACT: Active Fault */ +#define SEC_FSTAT_FLTPND 0x00000100 /* PND: Pending */ +#define SEC_FSTAT_ERRC 0x00000030 /* Error Cause */ +#define SEC_FSTAT_ENDERR 0x00000020 /* ERRC: End Error */ +#define SEC_FSTAT_ERR 0x00000002 /* ERR: Error Occurred */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_FSID Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_FSID_SRC_EXTFLT 0x00010000 /* FEXT: Fault External */ +#define SEC_FSID_SID 0x000000FF /* Source ID */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_FEND Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_FEND_END_EXTFLT 0x00010000 /* FEXT: Fault External */ +#define SEC_FEND_SID 0x000000FF /* Source ID */ + + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_GCTL Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_GCTL_LOCK 0x80000000 /* Lock */ +#define SEC_GCTL_RESET 0x00000002 /* Reset */ +#define SEC_GCTL_EN 0x00000001 /* Enable */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_GSTAT Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_GSTAT_LWERR 0x80000000 /* LWERR: Error Occurred */ +#define SEC_GSTAT_ADRERR 0x40000000 /* ADRERR: Error Occurred */ +#define SEC_GSTAT_SID 0x00FF0000 /* Source ID for SSI Error */ +#define SEC_GSTAT_SCI 0x00000F00 /* SCI ID for SCI Error */ +#define SEC_GSTAT_ERRC 0x00000030 /* Error Cause */ +#define SEC_GSTAT_SCIERR 0x00000010 /* ERRC: SCI Error */ +#define SEC_GSTAT_SSIERR 0x00000020 /* ERRC: SSI Error */ +#define SEC_GSTAT_ERR 0x00000002 /* ERR: Error Occurred */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_RAISE Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_RAISE_SID 0x000000FF /* Source ID IRQ Set to Pending */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_END Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_END_SID 0x000000FF /* Source ID IRQ to End */ + + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_SCTL Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_SCTL_LOCK 0x80000000 /* Lock */ +#define SEC_SCTL_CTG 0x0F000000 /* Core Target Select */ +#define SEC_SCTL_GRP 0x000F0000 /* Group Select */ +#define SEC_SCTL_PRIO 0x0000FF00 /* Priority Level Select */ +#define SEC_SCTL_ERR_EN 0x00000010 /* ERREN: Enable */ +#define SEC_SCTL_EDGE 0x00000008 /* ES: Edge Sensitive */ +#define SEC_SCTL_SRC_EN 0x00000004 /* SEN: Enable */ +#define SEC_SCTL_FAULT_EN 0x00000002 /* FEN: Enable */ +#define SEC_SCTL_INT_EN 0x00000001 /* IEN: Enable */ + +/* ------------------------------------------------------------------------------------------------------------------------ + SEC_SSTAT Pos/Masks Description + ------------------------------------------------------------------------------------------------------------------------ */ +#define SEC_SSTAT_CHID 0x00FF0000 /* Channel ID */ +#define SEC_SSTAT_ACTIVE_SRC 0x00000200 /* ACT: Active Source */ +#define SEC_SSTAT_PENDING 0x00000100 /* PND: Pending */ +#define SEC_SSTAT_ERRC 0x00000030 /* Error Cause */ +#define SEC_SSTAT_ENDERR 0x00000020 /* ERRC: End Error */ +#define SEC_SSTAT_ERR 0x00000002 /* Error */ + + +/* ========================= + RCU Registers + ========================= */ + +/* ========================= + RCU0 + ========================= */ +#define RCU0_CTL 0xFFCA6000 /* RCU0 Control Register */ +#define RCU0_STAT 0xFFCA6004 /* RCU0 Status Register */ +#define RCU0_CRCTL 0xFFCA6008 /* RCU0 Core Reset Control Register */ +#define RCU0_CRSTAT 0xFFCA600C /* RCU0 Core Reset Status Register */ +#define RCU0_SIDIS 0xFFCA6010 /* RCU0 System Interface Disable Register */ +#define RCU0_SISTAT 0xFFCA6014 /* RCU0 System Interface Status Register */ +#define RCU0_SVECT_LCK 0xFFCA6018 /* RCU0 SVECT Lock Register */ +#define RCU0_BCODE 0xFFCA601C /* RCU0 Boot Code Register */ +#define RCU0_SVECT0 0xFFCA6020 /* RCU0 Software Vector Register n */ +#define RCU0_SVECT1 0xFFCA6024 /* RCU0 Software Vector Register n */ + + +/* ========================= + CGU0 + ========================= */ +#define CGU0_CTL 0xFFCA8000 /* CGU0 Control Register */ +#define CGU0_STAT 0xFFCA8004 /* CGU0 Status Register */ +#define CGU0_DIV 0xFFCA8008 /* CGU0 Divisor Register */ +#define CGU0_CLKOUTSEL 0xFFCA800C /* CGU0 CLKOUT Select Register */ + + +/* ========================= + DPM Registers + ========================= */ + +/* ========================= + DPM0 + ========================= */ +#define DPM0_CTL 0xFFCA9000 /* DPM0 Control Register */ +#define DPM0_STAT 0xFFCA9004 /* DPM0 Status Register */ +#define DPM0_CCBF_DIS 0xFFCA9008 /* DPM0 Core Clock Buffer Disable Register */ +#define DPM0_CCBF_EN 0xFFCA900C /* DPM0 Core Clock Buffer Enable Register */ +#define DPM0_CCBF_STAT 0xFFCA9010 /* DPM0 Core Clock Buffer Status Register */ +#define DPM0_CCBF_STAT_STKY 0xFFCA9014 /* DPM0 Core Clock Buffer Status Sticky Register */ +#define DPM0_SCBF_DIS 0xFFCA9018 /* DPM0 System Clock Buffer Disable Register */ +#define DPM0_WAKE_EN 0xFFCA901C /* DPM0 Wakeup Enable Register */ +#define DPM0_WAKE_POL 0xFFCA9020 /* DPM0 Wakeup Polarity Register */ +#define DPM0_WAKE_STAT 0xFFCA9024 /* DPM0 Wakeup Status Register */ +#define DPM0_HIB_DIS 0xFFCA9028 /* DPM0 Hibernate Disable Register */ +#define DPM0_PGCNTR 0xFFCA902C /* DPM0 Power Good Counter Register */ +#define DPM0_RESTORE0 0xFFCA9030 /* DPM0 Restore Register */ +#define DPM0_RESTORE1 0xFFCA9034 /* DPM0 Restore Register */ +#define DPM0_RESTORE2 0xFFCA9038 /* DPM0 Restore Register */ +#define DPM0_RESTORE3 0xFFCA903C /* DPM0 Restore Register */ +#define DPM0_RESTORE4 0xFFCA9040 /* DPM0 Restore Register */ +#define DPM0_RESTORE5 0xFFCA9044 /* DPM0 Restore Register */ +#define DPM0_RESTORE6 0xFFCA9048 /* DPM0 Restore Register */ +#define DPM0_RESTORE7 0xFFCA904C /* DPM0 Restore Register */ +#define DPM0_RESTORE8 0xFFCA9050 /* DPM0 Restore Register */ +#define DPM0_RESTORE9 0xFFCA9054 /* DPM0 Restore Register */ +#define DPM0_RESTORE10 0xFFCA9058 /* DPM0 Restore Register */ +#define DPM0_RESTORE11 0xFFCA905C /* DPM0 Restore Register */ +#define DPM0_RESTORE12 0xFFCA9060 /* DPM0 Restore Register */ +#define DPM0_RESTORE13 0xFFCA9064 /* DPM0 Restore Register */ +#define DPM0_RESTORE14 0xFFCA9068 /* DPM0 Restore Register */ +#define DPM0_RESTORE15 0xFFCA906C /* DPM0 Restore Register */ + + +/* ========================= + DBG Registers + ========================= */ + +/* USB register */ +#define USB_FADDR 0xFFCC1000 /* USB Device Address in Peripheral Mode */ +#define USB_POWER 0xFFCC1001 /* USB Power and Device Control */ +#define USB_INTRTX 0xFFCC1002 /* USB Transmit Interrupt */ +#define USB_INTRRX 0xFFCC1004 /* USB Receive Interrupts */ +#define USB_INTRTXE 0xFFCC1006 /* USB Transmit Interrupt Enable */ +#define USB_INTRRXE 0xFFCC1008 /* USB Receive Interrupt Enable */ +#define USB_INTRUSB 0xFFCC100A /* USB USB Interrupts */ +#define USB_INTRUSBE 0xFFCC100B /* USB USB Interrupt Enable */ +#define USB_FRAME 0xFFCC100C /* USB Frame Number */ +#define USB_INDEX 0xFFCC100E /* USB Index */ +#define USB_TESTMODE 0xFFCC100F /* USB Testmodes */ +#define USB_EPI_TXMAXP0 0xFFCC1010 /* USB Transmit Maximum Packet Length */ +#define USB_EP_NI0_TXMAXP 0xFFCC1010 +#define USB_EP0I_CSR0_H 0xFFCC1012 /* USB Config and Status EP0 */ +#define USB_EPI_TXCSR0_H 0xFFCC1012 /* USB Transmit Configuration and Status */ +#define USB_EP0I_CSR0_P 0xFFCC1012 /* USB Config and Status EP0 */ +#define USB_EPI_TXCSR0_P 0xFFCC1012 /* USB Transmit Configuration and Status */ +#define USB_EPI_RXMAXP0 0xFFCC1014 /* USB Receive Maximum Packet Length */ +#define USB_EPI_RXCSR0_H 0xFFCC1016 /* USB Receive Configuration and Status Register */ +#define USB_EPI_RXCSR0_P 0xFFCC1016 /* USB Receive Configuration and Status Register */ +#define USB_EP0I_CNT0 0xFFCC1018 /* USB Number of Received Bytes for Endpoint 0 */ +#define USB_EPI_RXCNT0 0xFFCC1018 /* USB Number of Byte Received */ +#define USB_EP0I_TYPE0 0xFFCC101A /* USB Speed for Endpoint 0 */ +#define USB_EPI_TXTYPE0 0xFFCC101A /* USB Transmit Type */ +#define USB_EP0I_NAKLIMIT0 0xFFCC101B /* USB NAK Response Timeout for Endpoint 0 */ +#define USB_EPI_TXINTERVAL0 0xFFCC101B /* USB Transmit Polling Interval */ +#define USB_EPI_RXTYPE0 0xFFCC101C /* USB Receive Type */ +#define USB_EPI_RXINTERVAL0 0xFFCC101D /* USB Receive Polling Interval */ +#define USB_EP0I_CFGDATA0 0xFFCC101F /* USB Configuration Information */ +#define USB_FIFOB0 0xFFCC1020 /* USB FIFO Data */ +#define USB_FIFOB1 0xFFCC1024 /* USB FIFO Data */ +#define USB_FIFOB2 0xFFCC1028 /* USB FIFO Data */ +#define USB_FIFOB3 0xFFCC102C /* USB FIFO Data */ +#define USB_FIFOB4 0xFFCC1030 /* USB FIFO Data */ +#define USB_FIFOB5 0xFFCC1034 /* USB FIFO Data */ +#define USB_FIFOB6 0xFFCC1038 /* USB FIFO Data */ +#define USB_FIFOB7 0xFFCC103C /* USB FIFO Data */ +#define USB_FIFOB8 0xFFCC1040 /* USB FIFO Data */ +#define USB_FIFOB9 0xFFCC1044 /* USB FIFO Data */ +#define USB_FIFOB10 0xFFCC1048 /* USB FIFO Data */ +#define USB_FIFOB11 0xFFCC104C /* USB FIFO Data */ +#define USB_FIFOH0 0xFFCC1020 /* USB FIFO Data */ +#define USB_FIFOH1 0xFFCC1024 /* USB FIFO Data */ +#define USB_FIFOH2 0xFFCC1028 /* USB FIFO Data */ +#define USB_FIFOH3 0xFFCC102C /* USB FIFO Data */ +#define USB_FIFOH4 0xFFCC1030 /* USB FIFO Data */ +#define USB_FIFOH5 0xFFCC1034 /* USB FIFO Data */ +#define USB_FIFOH6 0xFFCC1038 /* USB FIFO Data */ +#define USB_FIFOH7 0xFFCC103C /* USB FIFO Data */ +#define USB_FIFOH8 0xFFCC1040 /* USB FIFO Data */ +#define USB_FIFOH9 0xFFCC1044 /* USB FIFO Data */ +#define USB_FIFOH10 0xFFCC1048 /* USB FIFO Data */ +#define USB_FIFOH11 0xFFCC104C /* USB FIFO Data */ +#define USB_FIFO0 0xFFCC1020 /* USB FIFO Data */ +#define USB_EP0_FIFO 0xFFCC1020 +#define USB_FIFO1 0xFFCC1024 /* USB FIFO Data */ +#define USB_FIFO2 0xFFCC1028 /* USB FIFO Data */ +#define USB_FIFO3 0xFFCC102C /* USB FIFO Data */ +#define USB_FIFO4 0xFFCC1030 /* USB FIFO Data */ +#define USB_FIFO5 0xFFCC1034 /* USB FIFO Data */ +#define USB_FIFO6 0xFFCC1038 /* USB FIFO Data */ +#define USB_FIFO7 0xFFCC103C /* USB FIFO Data */ +#define USB_FIFO8 0xFFCC1040 /* USB FIFO Data */ +#define USB_FIFO9 0xFFCC1044 /* USB FIFO Data */ +#define USB_FIFO10 0xFFCC1048 /* USB FIFO Data */ +#define USB_FIFO11 0xFFCC104C /* USB FIFO Data */ +#define USB_OTG_DEV_CTL 0xFFCC1060 /* USB Device Control */ +#define USB_TXFIFOSZ 0xFFCC1062 /* USB Transmit FIFO Size */ +#define USB_RXFIFOSZ 0xFFCC1063 /* USB Receive FIFO Size */ +#define USB_TXFIFOADDR 0xFFCC1064 /* USB Transmit FIFO Address */ +#define USB_RXFIFOADDR 0xFFCC1066 /* USB Receive FIFO Address */ +#define USB_VENDSTAT 0xFFCC1068 /* USB Vendor Status */ +#define USB_HWVERS 0xFFCC106C /* USB Hardware Version */ +#define USB_EPINFO 0xFFCC1078 /* USB Endpoint Info */ +#define USB_RAMINFO 0xFFCC1079 /* USB Ram Information */ +#define USB_LINKINFO 0xFFCC107A /* USB Programmable Delay Values */ +#define USB_VPLEN 0xFFCC107B /* USB VBus Pulse Duration */ +#define USB_HS_EOF1 0xFFCC107C /* USB High Speed End of Frame Remaining */ +#define USB_FS_EOF1 0xFFCC107D /* USB Full Speed End of Frame Remaining */ +#define USB_LS_EOF1 0xFFCC107E /* USB Low Speed End of Frame Remaining */ +#define USB_SOFT_RST 0xFFCC107F /* USB Software Reset */ +#define USB_TXFUNCADDR0 0xFFCC1080 /* USB Transmit Function Address */ +#define USB_TXFUNCADDR1 0xFFCC1088 /* USB Transmit Function Address */ +#define USB_TXFUNCADDR2 0xFFCC1090 /* USB Transmit Function Address */ +#define USB_TXFUNCADDR3 0xFFCC1098 /* USB Transmit Function Address */ +#define USB_TXFUNCADDR4 0xFFCC10A0 /* USB Transmit Function Address */ +#define USB_TXFUNCADDR5 0xFFCC10A8 /* USB Transmit Function Address */ +#define USB_TXFUNCADDR6 0xFFCC10B0 /* USB Transmit Function Address */ +#define USB_TXFUNCADDR7 0xFFCC10B8 /* USB Transmit Function Address */ +#define USB_TXFUNCADDR8 0xFFCC10C0 /* USB Transmit Function Address */ +#define USB_TXFUNCADDR9 0xFFCC10C8 /* USB Transmit Function Address */ +#define USB_TXFUNCADDR10 0xFFCC10D0 /* USB Transmit Function Address */ +#define USB_TXFUNCADDR11 0xFFCC10D8 /* USB Transmit Function Address */ +#define USB_TXHUBADDR0 0xFFCC1082 /* USB Transmit Hub Address */ +#define USB_TXHUBADDR1 0xFFCC108A /* USB Transmit Hub Address */ +#define USB_TXHUBADDR2 0xFFCC1092 /* USB Transmit Hub Address */ +#define USB_TXHUBADDR3 0xFFCC109A /* USB Transmit Hub Address */ +#define USB_TXHUBADDR4 0xFFCC10A2 /* USB Transmit Hub Address */ +#define USB_TXHUBADDR5 0xFFCC10AA /* USB Transmit Hub Address */ +#define USB_TXHUBADDR6 0xFFCC10B2 /* USB Transmit Hub Address */ +#define USB_TXHUBADDR7 0xFFCC10BA /* USB Transmit Hub Address */ +#define USB_TXHUBADDR8 0xFFCC10C2 /* USB Transmit Hub Address */ +#define USB_TXHUBADDR9 0xFFCC10CA /* USB Transmit Hub Address */ +#define USB_TXHUBADDR10 0xFFCC10D2 /* USB Transmit Hub Address */ +#define USB_TXHUBADDR11 0xFFCC10DA /* USB Transmit Hub Address */ +#define USB_TXHUBPORT0 0xFFCC1083 /* USB Transmit Hub Port */ +#define USB_TXHUBPORT1 0xFFCC108B /* USB Transmit Hub Port */ +#define USB_TXHUBPORT2 0xFFCC1093 /* USB Transmit Hub Port */ +#define USB_TXHUBPORT3 0xFFCC109B /* USB Transmit Hub Port */ +#define USB_TXHUBPORT4 0xFFCC10A3 /* USB Transmit Hub Port */ +#define USB_TXHUBPORT5 0xFFCC10AB /* USB Transmit Hub Port */ +#define USB_TXHUBPORT6 0xFFCC10B3 /* USB Transmit Hub Port */ +#define USB_TXHUBPORT7 0xFFCC10BB /* USB Transmit Hub Port */ +#define USB_TXHUBPORT8 0xFFCC10C3 /* USB Transmit Hub Port */ +#define USB_TXHUBPORT9 0xFFCC10CB /* USB Transmit Hub Port */ +#define USB_TXHUBPORT10 0xFFCC10D3 /* USB Transmit Hub Port */ +#define USB_TXHUBPORT11 0xFFCC10DB /* USB Transmit Hub Port */ +#define USB_RXFUNCADDR0 0xFFCC1084 /* USB Receive Function Address */ +#define USB_RXFUNCADDR1 0xFFCC108C /* USB Receive Function Address */ +#define USB_RXFUNCADDR2 0xFFCC1094 /* USB Receive Function Address */ +#define USB_RXFUNCADDR3 0xFFCC109C /* USB Receive Function Address */ +#define USB_RXFUNCADDR4 0xFFCC10A4 /* USB Receive Function Address */ +#define USB_RXFUNCADDR5 0xFFCC10AC /* USB Receive Function Address */ +#define USB_RXFUNCADDR6 0xFFCC10B4 /* USB Receive Function Address */ +#define USB_RXFUNCADDR7 0xFFCC10BC /* USB Receive Function Address */ +#define USB_RXFUNCADDR8 0xFFCC10C4 /* USB Receive Function Address */ +#define USB_RXFUNCADDR9 0xFFCC10CC /* USB Receive Function Address */ +#define USB_RXFUNCADDR10 0xFFCC10D4 /* USB Receive Function Address */ +#define USB_RXFUNCADDR11 0xFFCC10DC /* USB Receive Function Address */ +#define USB_RXHUBADDR0 0xFFCC1086 /* USB Receive Hub Address */ +#define USB_RXHUBADDR1 0xFFCC108E /* USB Receive Hub Address */ +#define USB_RXHUBADDR2 0xFFCC1096 /* USB Receive Hub Address */ +#define USB_RXHUBADDR3 0xFFCC109E /* USB Receive Hub Address */ +#define USB_RXHUBADDR4 0xFFCC10A6 /* USB Receive Hub Address */ +#define USB_RXHUBADDR5 0xFFCC10AE /* USB Receive Hub Address */ +#define USB_RXHUBADDR6 0xFFCC10B6 /* USB Receive Hub Address */ +#define USB_RXHUBADDR7 0xFFCC10BE /* USB Receive Hub Address */ +#define USB_RXHUBADDR8 0xFFCC10C6 /* USB Receive Hub Address */ +#define USB_RXHUBADDR9 0xFFCC10CE /* USB Receive Hub Address */ +#define USB_RXHUBADDR10 0xFFCC10D6 /* USB Receive Hub Address */ +#define USB_RXHUBADDR11 0xFFCC10DE /* USB Receive Hub Address */ +#define USB_RXHUBPORT0 0xFFCC1087 /* USB Receive Hub Port */ +#define USB_RXHUBPORT1 0xFFCC108F /* USB Receive Hub Port */ +#define USB_RXHUBPORT2 0xFFCC1097 /* USB Receive Hub Port */ +#define USB_RXHUBPORT3 0xFFCC109F /* USB Receive Hub Port */ +#define USB_RXHUBPORT4 0xFFCC10A7 /* USB Receive Hub Port */ +#define USB_RXHUBPORT5 0xFFCC10AF /* USB Receive Hub Port */ +#define USB_RXHUBPORT6 0xFFCC10B7 /* USB Receive Hub Port */ +#define USB_RXHUBPORT7 0xFFCC10BF /* USB Receive Hub Port */ +#define USB_RXHUBPORT8 0xFFCC10C7 /* USB Receive Hub Port */ +#define USB_RXHUBPORT9 0xFFCC10CF /* USB Receive Hub Port */ +#define USB_RXHUBPORT10 0xFFCC10D7 /* USB Receive Hub Port */ +#define USB_RXHUBPORT11 0xFFCC10DF /* USB Receive Hub Port */ +#define USB_EP0_CSR0_H 0xFFCC1102 /* USB Config and Status EP0 */ +#define USB_EP0_CSR0_P 0xFFCC1102 /* USB Config and Status EP0 */ +#define USB_EP0_CNT0 0xFFCC1108 /* USB Number of Received Bytes for Endpoint 0 */ +#define USB_EP0_TYPE0 0xFFCC110A /* USB Speed for Endpoint 0 */ +#define USB_EP0_NAKLIMIT0 0xFFCC110B /* USB NAK Response Timeout for Endpoint 0 */ +#define USB_EP0_CFGDATA0 0xFFCC110F /* USB Configuration Information */ +#define USB_EP_TXMAXP0 0xFFCC1110 /* USB Transmit Maximum Packet Length */ +#define USB_EP_TXMAXP1 0xFFCC1120 /* USB Transmit Maximum Packet Length */ +#define USB_EP_TXMAXP2 0xFFCC1130 /* USB Transmit Maximum Packet Length */ +#define USB_EP_TXMAXP3 0xFFCC1140 /* USB Transmit Maximum Packet Length */ +#define USB_EP_TXMAXP4 0xFFCC1150 /* USB Transmit Maximum Packet Length */ +#define USB_EP_TXMAXP5 0xFFCC1160 /* USB Transmit Maximum Packet Length */ +#define USB_EP_TXMAXP6 0xFFCC1170 /* USB Transmit Maximum Packet Length */ +#define USB_EP_TXMAXP7 0xFFCC1180 /* USB Transmit Maximum Packet Length */ +#define USB_EP_TXMAXP8 0xFFCC1190 /* USB Transmit Maximum Packet Length */ +#define USB_EP_TXMAXP9 0xFFCC11A0 /* USB Transmit Maximum Packet Length */ +#define USB_EP_TXMAXP10 0xFFCC11B0 /* USB Transmit Maximum Packet Length */ +#define USB_EP_TXCSR0_H 0xFFCC1112 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR1_H 0xFFCC1122 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR2_H 0xFFCC1132 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR3_H 0xFFCC1142 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR4_H 0xFFCC1152 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR5_H 0xFFCC1162 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR6_H 0xFFCC1172 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR7_H 0xFFCC1182 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR8_H 0xFFCC1192 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR9_H 0xFFCC11A2 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR10_H 0xFFCC11B2 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR0_P 0xFFCC1112 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR1_P 0xFFCC1122 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR2_P 0xFFCC1132 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR3_P 0xFFCC1142 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR4_P 0xFFCC1152 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR5_P 0xFFCC1162 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR6_P 0xFFCC1172 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR7_P 0xFFCC1182 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR8_P 0xFFCC1192 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR9_P 0xFFCC11A2 /* USB Transmit Configuration and Status */ +#define USB_EP_TXCSR10_P 0xFFCC11B2 /* USB Transmit Configuration and Status */ +#define USB_EP_RXMAXP0 0xFFCC1114 /* USB Receive Maximum Packet Length */ +#define USB_EP_RXMAXP1 0xFFCC1124 /* USB Receive Maximum Packet Length */ +#define USB_EP_RXMAXP2 0xFFCC1134 /* USB Receive Maximum Packet Length */ +#define USB_EP_RXMAXP3 0xFFCC1144 /* USB Receive Maximum Packet Length */ +#define USB_EP_RXMAXP4 0xFFCC1154 /* USB Receive Maximum Packet Length */ +#define USB_EP_RXMAXP5 0xFFCC1164 /* USB Receive Maximum Packet Length */ +#define USB_EP_RXMAXP6 0xFFCC1174 /* USB Receive Maximum Packet Length */ +#define USB_EP_RXMAXP7 0xFFCC1184 /* USB Receive Maximum Packet Length */ +#define USB_EP_RXMAXP8 0xFFCC1194 /* USB Receive Maximum Packet Length */ +#define USB_EP_RXMAXP9 0xFFCC11A4 /* USB Receive Maximum Packet Length */ +#define USB_EP_RXMAXP10 0xFFCC11B4 /* USB Receive Maximum Packet Length */ +#define USB_EP_RXCSR0_H 0xFFCC1116 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR1_H 0xFFCC1126 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR2_H 0xFFCC1136 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR3_H 0xFFCC1146 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR4_H 0xFFCC1156 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR5_H 0xFFCC1166 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR6_H 0xFFCC1176 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR7_H 0xFFCC1186 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR8_H 0xFFCC1196 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR9_H 0xFFCC11A6 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR10_H 0xFFCC11B6 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR0_P 0xFFCC1116 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR1_P 0xFFCC1126 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR2_P 0xFFCC1136 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR3_P 0xFFCC1146 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR4_P 0xFFCC1156 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR5_P 0xFFCC1166 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR6_P 0xFFCC1176 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR7_P 0xFFCC1186 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR8_P 0xFFCC1196 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR9_P 0xFFCC11A6 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCSR10_P 0xFFCC11B6 /* USB Receive Configuration and Status Register */ +#define USB_EP_RXCNT0 0xFFCC1118 /* USB Number of Byte Received */ +#define USB_EP_RXCNT1 0xFFCC1128 /* USB Number of Byte Received */ +#define USB_EP_RXCNT2 0xFFCC1138 /* USB Number of Byte Received */ +#define USB_EP_RXCNT3 0xFFCC1148 /* USB Number of Byte Received */ +#define USB_EP_RXCNT4 0xFFCC1158 /* USB Number of Byte Received */ +#define USB_EP_RXCNT5 0xFFCC1168 /* USB Number of Byte Received */ +#define USB_EP_RXCNT6 0xFFCC1178 /* USB Number of Byte Received */ +#define USB_EP_RXCNT7 0xFFCC1188 /* USB Number of Byte Received */ +#define USB_EP_RXCNT8 0xFFCC1198 /* USB Number of Byte Received */ +#define USB_EP_RXCNT9 0xFFCC11A8 /* USB Number of Byte Received */ +#define USB_EP_RXCNT10 0xFFCC11B8 /* USB Number of Byte Received */ +#define USB_EP_TXTYPE0 0xFFCC111A /* USB Transmit Type */ +#define USB_EP_TXTYPE1 0xFFCC112A /* USB Transmit Type */ +#define USB_EP_TXTYPE2 0xFFCC113A /* USB Transmit Type */ +#define USB_EP_TXTYPE3 0xFFCC114A /* USB Transmit Type */ +#define USB_EP_TXTYPE4 0xFFCC115A /* USB Transmit Type */ +#define USB_EP_TXTYPE5 0xFFCC116A /* USB Transmit Type */ +#define USB_EP_TXTYPE6 0xFFCC117A /* USB Transmit Type */ +#define USB_EP_TXTYPE7 0xFFCC118A /* USB Transmit Type */ +#define USB_EP_TXTYPE8 0xFFCC119A /* USB Transmit Type */ +#define USB_EP_TXTYPE9 0xFFCC11AA /* USB Transmit Type */ +#define USB_EP_TXTYPE10 0xFFCC11BA /* USB Transmit Type */ +#define USB_EP_TXINTERVAL0 0xFFCC111B /* USB Transmit Polling Interval */ +#define USB_EP_TXINTERVAL1 0xFFCC112B /* USB Transmit Polling Interval */ +#define USB_EP_TXINTERVAL2 0xFFCC113B /* USB Transmit Polling Interval */ +#define USB_EP_TXINTERVAL3 0xFFCC114B /* USB Transmit Polling Interval */ +#define USB_EP_TXINTERVAL4 0xFFCC115B /* USB Transmit Polling Interval */ +#define USB_EP_TXINTERVAL5 0xFFCC116B /* USB Transmit Polling Interval */ +#define USB_EP_TXINTERVAL6 0xFFCC117B /* USB Transmit Polling Interval */ +#define USB_EP_TXINTERVAL7 0xFFCC118B /* USB Transmit Polling Interval */ +#define USB_EP_TXINTERVAL8 0xFFCC119B /* USB Transmit Polling Interval */ +#define USB_EP_TXINTERVAL9 0xFFCC11AB /* USB Transmit Polling Interval */ +#define USB_EP_TXINTERVAL10 0xFFCC11BB /* USB Transmit Polling Interval */ +#define USB_EP_RXTYPE0 0xFFCC111C /* USB Receive Type */ +#define USB_EP_RXTYPE1 0xFFCC112C /* USB Receive Type */ +#define USB_EP_RXTYPE2 0xFFCC113C /* USB Receive Type */ +#define USB_EP_RXTYPE3 0xFFCC114C /* USB Receive Type */ +#define USB_EP_RXTYPE4 0xFFCC115C /* USB Receive Type */ +#define USB_EP_RXTYPE5 0xFFCC116C /* USB Receive Type */ +#define USB_EP_RXTYPE6 0xFFCC117C /* USB Receive Type */ +#define USB_EP_RXTYPE7 0xFFCC118C /* USB Receive Type */ +#define USB_EP_RXTYPE8 0xFFCC119C /* USB Receive Type */ +#define USB_EP_RXTYPE9 0xFFCC11AC /* USB Receive Type */ +#define USB_EP_RXTYPE10 0xFFCC11BC /* USB Receive Type */ +#define USB_EP_RXINTERVAL0 0xFFCC111D /* USB Receive Polling Interval */ +#define USB_EP_RXINTERVAL1 0xFFCC112D /* USB Receive Polling Interval */ +#define USB_EP_RXINTERVAL2 0xFFCC113D /* USB Receive Polling Interval */ +#define USB_EP_RXINTERVAL3 0xFFCC114D /* USB Receive Polling Interval */ +#define USB_EP_RXINTERVAL4 0xFFCC115D /* USB Receive Polling Interval */ +#define USB_EP_RXINTERVAL5 0xFFCC116D /* USB Receive Polling Interval */ +#define USB_EP_RXINTERVAL6 0xFFCC117D /* USB Receive Polling Interval */ +#define USB_EP_RXINTERVAL7 0xFFCC118D /* USB Receive Polling Interval */ +#define USB_EP_RXINTERVAL8 0xFFCC119D /* USB Receive Polling Interval */ +#define USB_EP_RXINTERVAL9 0xFFCC11AD /* USB Receive Polling Interval */ +#define USB_EP_RXINTERVAL10 0xFFCC11BD /* USB Receive Polling Interval */ +#define USB_DMA_IRQ 0xFFCC1200 /* USB Interrupt Register */ +#define USB_DMA_CTL0 0xFFCC1204 /* USB DMA Control */ +#define USB_DMA_CTL1 0xFFCC1214 /* USB DMA Control */ +#define USB_DMA_CTL2 0xFFCC1224 /* USB DMA Control */ +#define USB_DMA_CTL3 0xFFCC1234 /* USB DMA Control */ +#define USB_DMA_CTL4 0xFFCC1244 /* USB DMA Control */ +#define USB_DMA_CTL5 0xFFCC1254 /* USB DMA Control */ +#define USB_DMA_CTL6 0xFFCC1264 /* USB DMA Control */ +#define USB_DMA_CTL7 0xFFCC1274 /* USB DMA Control */ +#define USB_DMA_ADDR0 0xFFCC1208 /* USB DMA Address */ +#define USB_DMA_ADDR1 0xFFCC1218 /* USB DMA Address */ +#define USB_DMA_ADDR2 0xFFCC1228 /* USB DMA Address */ +#define USB_DMA_ADDR3 0xFFCC1238 /* USB DMA Address */ +#define USB_DMA_ADDR4 0xFFCC1248 /* USB DMA Address */ +#define USB_DMA_ADDR5 0xFFCC1258 /* USB DMA Address */ +#define USB_DMA_ADDR6 0xFFCC1268 /* USB DMA Address */ +#define USB_DMA_ADDR7 0xFFCC1278 /* USB DMA Address */ +#define USB_DMA_CNT0 0xFFCC120C /* USB DMA Count */ +#define USB_DMA_CNT1 0xFFCC121C /* USB DMA Count */ +#define USB_DMA_CNT2 0xFFCC122C /* USB DMA Count */ +#define USB_DMA_CNT3 0xFFCC123C /* USB DMA Count */ +#define USB_DMA_CNT4 0xFFCC124C /* USB DMA Count */ +#define USB_DMA_CNT5 0xFFCC125C /* USB DMA Count */ +#define USB_DMA_CNT6 0xFFCC126C /* USB DMA Count */ +#define USB_DMA_CNT7 0xFFCC127C /* USB DMA Count */ +#define USB_RQPKTCNT0 0xFFCC1300 /* USB Request Packet Count */ +#define USB_RQPKTCNT1 0xFFCC1304 /* USB Request Packet Count */ +#define USB_RQPKTCNT2 0xFFCC1308 /* USB Request Packet Count */ +#define USB_RQPKTCNT3 0xFFCC130C /* USB Request Packet Count */ +#define USB_RQPKTCNT4 0xFFCC1310 /* USB Request Packet Count */ +#define USB_RQPKTCNT5 0xFFCC1314 /* USB Request Packet Count */ +#define USB_RQPKTCNT6 0xFFCC1318 /* USB Request Packet Count */ +#define USB_RQPKTCNT7 0xFFCC131C /* USB Request Packet Count */ +#define USB_RQPKTCNT8 0xFFCC1320 /* USB Request Packet Count */ +#define USB_RQPKTCNT9 0xFFCC1324 /* USB Request Packet Count */ +#define USB_RQPKTCNT10 0xFFCC1328 /* USB Request Packet Count */ +#define USB_CT_UCH 0xFFCC1344 /* USB Chirp Timeout */ +#define USB_CT_HHSRTN 0xFFCC1346 /* USB High Speed Resume Return to Normal */ +#define USB_CT_HSBT 0xFFCC1348 /* USB High Speed Timeout */ +#define USB_LPM_ATTR 0xFFCC1360 /* USB LPM Attribute */ +#define USB_LPM_CTL 0xFFCC1362 /* USB LPM Control */ +#define USB_LPM_IEN 0xFFCC1363 /* USB LPM Interrupt Enable */ +#define USB_LPM_IRQ 0xFFCC1364 /* USB LPM Interrupt */ +#define USB_LPM_FADDR 0xFFCC1365 /* USB LPM Function Address */ +#define USB_VBUS_CTL 0xFFCC1380 /* USB VBus Control */ +#define USB_BAT_CHG 0xFFCC1381 /* USB Battery Charging */ +#define USB_PHY_CTL 0xFFCC1394 /* USB PHY Control */ +#define USB_TESTCTL 0xFFCC1397 /* USB Test Control */ +#define USB_PLL_OSC 0xFFCC1398 /* USB PLL and Oscillator Control */ + + + +/* ========================= + CHIPID + ========================= */ + +#define CHIPID 0xffc00014 +/* CHIPID Masks */ +#define CHIPID_VERSION 0xF0000000 +#define CHIPID_FAMILY 0x0FFFF000 +#define CHIPID_MANUFACTURE 0x00000FFE + + +#endif /* _DEF_BF60X_H */
diff --git a/arch/blackfin/mach-bf609/include/mach/dma.h b/arch/blackfin/mach-bf609/include/mach/dma.h new file mode 100644 index 0000000..872d141 --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/dma.h
@@ -0,0 +1,116 @@ +/* mach/dma.h - arch-specific DMA defines + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef _MACH_DMA_H_ +#define _MACH_DMA_H_ + +#define CH_SPORT0_TX 0 +#define CH_SPORT0_RX 1 +#define CH_SPORT1_TX 2 +#define CH_SPORT1_RX 3 +#define CH_SPORT2_TX 4 +#define CH_SPORT2_RX 5 +#define CH_SPI0_TX 6 +#define CH_SPI0_RX 7 +#define CH_SPI1_TX 8 +#define CH_SPI1_RX 9 +#define CH_RSI 10 +#define CH_SDU 11 +#define CH_LP0 13 +#define CH_LP1 14 +#define CH_LP2 15 +#define CH_LP3 16 +#define CH_UART0_TX 17 +#define CH_UART0_RX 18 +#define CH_UART1_TX 19 +#define CH_UART1_RX 20 +#define CH_MEM_STREAM0_SRC_CRC0 21 +#define CH_MEM_STREAM0_SRC CH_MEM_STREAM0_SRC_CRC0 +#define CH_MEM_STREAM0_DEST_CRC0 22 +#define CH_MEM_STREAM0_DEST CH_MEM_STREAM0_DEST_CRC0 +#define CH_MEM_STREAM1_SRC_CRC1 23 +#define CH_MEM_STREAM1_SRC CH_MEM_STREAM1_SRC_CRC1 +#define CH_MEM_STREAM1_DEST_CRC1 24 +#define CH_MEM_STREAM1_DEST CH_MEM_STREAM1_DEST_CRC1 +#define CH_MEM_STREAM2_SRC 25 +#define CH_MEM_STREAM2_DEST 26 +#define CH_MEM_STREAM3_SRC 27 +#define CH_MEM_STREAM3_DEST 28 +#define CH_EPPI0_CH0 29 +#define CH_EPPI0_CH1 30 +#define CH_EPPI1_CH0 31 +#define CH_EPPI1_CH1 32 +#define CH_EPPI2_CH0 33 +#define CH_EPPI2_CH1 34 +#define CH_PIXC_CH0 35 +#define CH_PIXC_CH1 36 +#define CH_PIXC_CH2 37 +#define CH_PVP_CPDOB 38 +#define CH_PVP_CPDOC 39 +#define CH_PVP_CPSTAT 40 +#define CH_PVP_CPCI 41 +#define CH_PVP_MPDO 42 +#define CH_PVP_MPDI 43 +#define CH_PVP_MPSTAT 44 +#define CH_PVP_MPCI 45 +#define CH_PVP_CPDOA 46 + +#define MAX_DMA_CHANNELS 47 +#define MAX_DMA_SUSPEND_CHANNELS 0 +#define DMA_MMR_SIZE_32 + +#define bfin_read_MDMA_S0_CONFIG bfin_read_MDMA0_SRC_CRC0_CONFIG +#define bfin_write_MDMA_S0_CONFIG bfin_write_MDMA0_SRC_CRC0_CONFIG +#define bfin_read_MDMA_S0_IRQ_STATUS bfin_read_MDMA0_SRC_CRC0_IRQ_STATUS +#define bfin_write_MDMA_S0_IRQ_STATUS bfin_write_MDMA0_SRC_CRC0_IRQ_STATUS +#define bfin_write_MDMA_S0_START_ADDR bfin_write_MDMA0_SRC_CRC0_START_ADDR +#define bfin_write_MDMA_S0_X_COUNT bfin_write_MDMA0_SRC_CRC0_X_COUNT +#define bfin_write_MDMA_S0_X_MODIFY bfin_write_MDMA0_SRC_CRC0_X_MODIFY +#define bfin_write_MDMA_S0_Y_COUNT bfin_write_MDMA0_SRC_CRC0_Y_COUNT +#define bfin_write_MDMA_S0_Y_MODIFY bfin_write_MDMA0_SRC_CRC0_Y_MODIFY +#define bfin_read_MDMA_D0_CONFIG bfin_read_MDMA0_DEST_CRC0_CONFIG +#define bfin_write_MDMA_D0_CONFIG bfin_write_MDMA0_DEST_CRC0_CONFIG +#define bfin_read_MDMA_D0_IRQ_STATUS bfin_read_MDMA0_DEST_CRC0_IRQ_STATUS +#define bfin_write_MDMA_D0_IRQ_STATUS bfin_write_MDMA0_DEST_CRC0_IRQ_STATUS +#define bfin_write_MDMA_D0_START_ADDR bfin_write_MDMA0_DEST_CRC0_START_ADDR +#define bfin_write_MDMA_D0_X_COUNT bfin_write_MDMA0_DEST_CRC0_X_COUNT +#define bfin_write_MDMA_D0_X_MODIFY bfin_write_MDMA0_DEST_CRC0_X_MODIFY +#define bfin_write_MDMA_D0_Y_COUNT bfin_write_MDMA0_DEST_CRC0_Y_COUNT +#define bfin_write_MDMA_D0_Y_MODIFY bfin_write_MDMA0_DEST_CRC0_Y_MODIFY + +#define bfin_read_MDMA_S1_CONFIG bfin_read_MDMA1_SRC_CRC1_CONFIG +#define bfin_write_MDMA_S1_CONFIG bfin_write_MDMA1_SRC_CRC1_CONFIG +#define bfin_read_MDMA_D1_CONFIG bfin_read_MDMA1_DEST_CRC1_CONFIG +#define bfin_write_MDMA_D1_CONFIG bfin_write_MDMA1_DEST_CRC1_CONFIG +#define bfin_read_MDMA_D1_IRQ_STATUS bfin_read_MDMA1_DEST_CRC1_IRQ_STATUS +#define bfin_write_MDMA_D1_IRQ_STATUS bfin_write_MDMA1_DEST_CRC1_IRQ_STATUS + +#define bfin_read_MDMA_S3_CONFIG bfin_read_MDMA3_SRC_CONFIG +#define bfin_write_MDMA_S3_CONFIG bfin_write_MDMA3_SRC_CONFIG +#define bfin_read_MDMA_S3_IRQ_STATUS bfin_read_MDMA3_SRC_IRQ_STATUS +#define bfin_write_MDMA_S3_IRQ_STATUS bfin_write_MDMA3_SRC_IRQ_STATUS +#define bfin_write_MDMA_S3_START_ADDR bfin_write_MDMA3_SRC_START_ADDR +#define bfin_write_MDMA_S3_X_COUNT bfin_write_MDMA3_SRC_X_COUNT +#define bfin_write_MDMA_S3_X_MODIFY bfin_write_MDMA3_SRC_X_MODIFY +#define bfin_write_MDMA_S3_Y_COUNT bfin_write_MDMA3_SRC_Y_COUNT +#define bfin_write_MDMA_S3_Y_MODIFY bfin_write_MDMA3_SRC_Y_MODIFY +#define bfin_read_MDMA_D3_CONFIG bfin_read_MDMA3_DEST_CONFIG +#define bfin_write_MDMA_D3_CONFIG bfin_write_MDMA3_DEST_CONFIG +#define bfin_read_MDMA_D3_IRQ_STATUS bfin_read_MDMA3_DEST_IRQ_STATUS +#define bfin_write_MDMA_D3_IRQ_STATUS bfin_write_MDMA3_DEST_IRQ_STATUS +#define bfin_write_MDMA_D3_START_ADDR bfin_write_MDMA3_DEST_START_ADDR +#define bfin_write_MDMA_D3_X_COUNT bfin_write_MDMA3_DEST_X_COUNT +#define bfin_write_MDMA_D3_X_MODIFY bfin_write_MDMA3_DEST_X_MODIFY +#define bfin_write_MDMA_D3_Y_COUNT bfin_write_MDMA3_DEST_Y_COUNT +#define bfin_write_MDMA_D3_Y_MODIFY bfin_write_MDMA3_DEST_Y_MODIFY + +#define MDMA_S0_NEXT_DESC_PTR MDMA0_SRC_CRC0_NEXT_DESC_PTR +#define MDMA_D0_NEXT_DESC_PTR MDMA0_DEST_CRC0_NEXT_DESC_PTR +#define MDMA_S1_NEXT_DESC_PTR MDMA1_SRC_CRC1_NEXT_DESC_PTR +#define MDMA_D1_NEXT_DESC_PTR MDMA1_DEST_CRC1_NEXT_DESC_PTR + +#endif
diff --git a/arch/blackfin/mach-bf609/include/mach/gpio.h b/arch/blackfin/mach-bf609/include/mach/gpio.h new file mode 100644 index 0000000..127586b --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/gpio.h
@@ -0,0 +1,171 @@ +/* + * Copyright 2007-2009 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + +#ifndef _MACH_GPIO_H_ +#define _MACH_GPIO_H_ + +#define MAX_BLACKFIN_GPIOS 112 + +#define GPIO_PA0 0 +#define GPIO_PA1 1 +#define GPIO_PA2 2 +#define GPIO_PA3 3 +#define GPIO_PA4 4 +#define GPIO_PA5 5 +#define GPIO_PA6 6 +#define GPIO_PA7 7 +#define GPIO_PA8 8 +#define GPIO_PA9 9 +#define GPIO_PA10 10 +#define GPIO_PA11 11 +#define GPIO_PA12 12 +#define GPIO_PA13 13 +#define GPIO_PA14 14 +#define GPIO_PA15 15 +#define GPIO_PB0 16 +#define GPIO_PB1 17 +#define GPIO_PB2 18 +#define GPIO_PB3 19 +#define GPIO_PB4 20 +#define GPIO_PB5 21 +#define GPIO_PB6 22 +#define GPIO_PB7 23 +#define GPIO_PB8 24 +#define GPIO_PB9 25 +#define GPIO_PB10 26 +#define GPIO_PB11 27 +#define GPIO_PB12 28 +#define GPIO_PB13 29 +#define GPIO_PB14 30 +#define GPIO_PB15 31 +#define GPIO_PC0 32 +#define GPIO_PC1 33 +#define GPIO_PC2 34 +#define GPIO_PC3 35 +#define GPIO_PC4 36 +#define GPIO_PC5 37 +#define GPIO_PC6 38 +#define GPIO_PC7 39 +#define GPIO_PC8 40 +#define GPIO_PC9 41 +#define GPIO_PC10 42 +#define GPIO_PC11 43 +#define GPIO_PC12 44 +#define GPIO_PC13 45 +#define GPIO_PC14 46 +#define GPIO_PC15 47 +#define GPIO_PD0 48 +#define GPIO_PD1 49 +#define GPIO_PD2 50 +#define GPIO_PD3 51 +#define GPIO_PD4 52 +#define GPIO_PD5 53 +#define GPIO_PD6 54 +#define GPIO_PD7 55 +#define GPIO_PD8 56 +#define GPIO_PD9 57 +#define GPIO_PD10 58 +#define GPIO_PD11 59 +#define GPIO_PD12 60 +#define GPIO_PD13 61 +#define GPIO_PD14 62 +#define GPIO_PD15 63 +#define GPIO_PE0 64 +#define GPIO_PE1 65 +#define GPIO_PE2 66 +#define GPIO_PE3 67 +#define GPIO_PE4 68 +#define GPIO_PE5 69 +#define GPIO_PE6 70 +#define GPIO_PE7 71 +#define GPIO_PE8 72 +#define GPIO_PE9 73 +#define GPIO_PE10 74 +#define GPIO_PE11 75 +#define GPIO_PE12 76 +#define GPIO_PE13 77 +#define GPIO_PE14 78 +#define GPIO_PE15 79 +#define GPIO_PF0 80 +#define GPIO_PF1 81 +#define GPIO_PF2 82 +#define GPIO_PF3 83 +#define GPIO_PF4 84 +#define GPIO_PF5 85 +#define GPIO_PF6 86 +#define GPIO_PF7 87 +#define GPIO_PF8 88 +#define GPIO_PF9 89 +#define GPIO_PF10 90 +#define GPIO_PF11 91 +#define GPIO_PF12 92 +#define GPIO_PF13 93 +#define GPIO_PF14 94 +#define GPIO_PF15 95 +#define GPIO_PG0 96 +#define GPIO_PG1 97 +#define GPIO_PG2 98 +#define GPIO_PG3 99 +#define GPIO_PG4 100 +#define GPIO_PG5 101 +#define GPIO_PG6 102 +#define GPIO_PG7 103 +#define GPIO_PG8 104 +#define GPIO_PG9 105 +#define GPIO_PG10 106 +#define GPIO_PG11 107 +#define GPIO_PG12 108 +#define GPIO_PG13 109 +#define GPIO_PG14 110 +#define GPIO_PG15 111 + + +#define BFIN_GPIO_PINT 1 + + +#ifndef __ASSEMBLY__ + +struct gpio_port_t { + unsigned long port_fer; + unsigned long port_fer_set; + unsigned long port_fer_clear; + unsigned long data; + unsigned long data_set; + unsigned long data_clear; + unsigned long dir; + unsigned long dir_set; + unsigned long dir_clear; + unsigned long inen; + unsigned long inen_set; + unsigned long inen_clear; + unsigned long port_mux; + unsigned long toggle; + unsigned long polar; + unsigned long polar_set; + unsigned long polar_clear; + unsigned long lock; + unsigned long spare; + unsigned long revid; +}; + +struct gpio_port_s { + unsigned short fer; + unsigned short data; + unsigned short dir; + unsigned short inen; + unsigned int mux; +}; + +#endif + +#include <mach-common/ports-a.h> +#include <mach-common/ports-b.h> +#include <mach-common/ports-c.h> +#include <mach-common/ports-d.h> +#include <mach-common/ports-e.h> +#include <mach-common/ports-f.h> +#include <mach-common/ports-g.h> + +#endif /* _MACH_GPIO_H_ */
diff --git a/arch/blackfin/mach-bf609/include/mach/irq.h b/arch/blackfin/mach-bf609/include/mach/irq.h new file mode 100644 index 0000000..0004552 --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/irq.h
@@ -0,0 +1,318 @@ +/* + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef _BF60x_IRQ_H_ +#define _BF60x_IRQ_H_ + +#include <mach-common/irq.h> + +#undef BFIN_IRQ +#define BFIN_IRQ(x) ((x) + IVG15) + +#define NR_PERI_INTS (5 * 32) + +#define IRQ_SEC_ERR BFIN_IRQ(0) /* SEC Error */ +#define IRQ_CGU_EVT BFIN_IRQ(1) /* CGU Event */ +#define IRQ_WATCH0 BFIN_IRQ(2) /* Watchdog0 Interrupt */ +#define IRQ_WATCH1 BFIN_IRQ(3) /* Watchdog1 Interrupt */ +#define IRQ_L2CTL0_ECC_ERR BFIN_IRQ(4) /* L2 ECC Error */ +#define IRQ_L2CTL0_ECC_WARN BFIN_IRQ(5) /* L2 ECC Waring */ +#define IRQ_C0_DBL_FAULT BFIN_IRQ(6) /* Core 0 Double Fault */ +#define IRQ_C1_DBL_FAULT BFIN_IRQ(7) /* Core 1 Double Fault */ +#define IRQ_C0_HW_ERR BFIN_IRQ(8) /* Core 0 Hardware Error */ +#define IRQ_C1_HW_ERR BFIN_IRQ(9) /* Core 1 Hardware Error */ +#define IRQ_C0_NMI_L1_PARITY_ERR BFIN_IRQ(10) /* Core 0 Unhandled NMI or L1 Memory Parity Error */ +#define IRQ_C1_NMI_L1_PARITY_ERR BFIN_IRQ(11) /* Core 1 Unhandled NMI or L1 Memory Parity Error */ +#define CORE_IRQS (IRQ_C1_NMI_L1_PARITY_ERR + 1) + +#define IRQ_TIMER0 BFIN_IRQ(12) /* Timer 0 Interrupt */ +#define IRQ_TIMER1 BFIN_IRQ(13) /* Timer 1 Interrupt */ +#define IRQ_TIMER2 BFIN_IRQ(14) /* Timer 2 Interrupt */ +#define IRQ_TIMER3 BFIN_IRQ(15) /* Timer 3 Interrupt */ +#define IRQ_TIMER4 BFIN_IRQ(16) /* Timer 4 Interrupt */ +#define IRQ_TIMER5 BFIN_IRQ(17) /* Timer 5 Interrupt */ +#define IRQ_TIMER6 BFIN_IRQ(18) /* Timer 6 Interrupt */ +#define IRQ_TIMER7 BFIN_IRQ(19) /* Timer 7 Interrupt */ +#define IRQ_TIMER_STAT BFIN_IRQ(20) /* Timer Block Status */ +#define IRQ_PINT0 BFIN_IRQ(21) /* PINT0 Interrupt */ +#define IRQ_PINT1 BFIN_IRQ(22) /* PINT1 Interrupt */ +#define IRQ_PINT2 BFIN_IRQ(23) /* PINT2 Interrupt */ +#define IRQ_PINT3 BFIN_IRQ(24) /* PINT3 Interrupt */ +#define IRQ_PINT4 BFIN_IRQ(25) /* PINT4 Interrupt */ +#define IRQ_PINT5 BFIN_IRQ(26) /* PINT5 Interrupt */ +#define IRQ_CNT BFIN_IRQ(27) /* CNT Interrupt */ +#define IRQ_PWM0_TRIP BFIN_IRQ(28) /* PWM0 Trip Interrupt */ +#define IRQ_PWM0_SYNC BFIN_IRQ(29) /* PWM0 Sync Interrupt */ +#define IRQ_PWM1_TRIP BFIN_IRQ(30) /* PWM1 Trip Interrupt */ +#define IRQ_PWM1_SYNC BFIN_IRQ(31) /* PWM1 Sync Interrupt */ +#define IRQ_TWI0 BFIN_IRQ(32) /* TWI0 Interrupt */ +#define IRQ_TWI1 BFIN_IRQ(33) /* TWI1 Interrupt */ +#define IRQ_SOFT0 BFIN_IRQ(34) /* Software-Driven Interrupt 0 */ +#define IRQ_SOFT1 BFIN_IRQ(35) /* Software-Driven Interrupt 1 */ +#define IRQ_SOFT2 BFIN_IRQ(36) /* Software-Driven Interrupt 2 */ +#define IRQ_SOFT3 BFIN_IRQ(37) /* Software-Driven Interrupt 3 */ +#define IRQ_ACM_EVT_MISS BFIN_IRQ(38) /* ACM Event Miss */ +#define IRQ_ACM_EVT_COMPLETE BFIN_IRQ(39) /* ACM Event Complete */ +#define IRQ_CAN0_RX BFIN_IRQ(40) /* CAN0 Receive Interrupt */ +#define IRQ_CAN0_TX BFIN_IRQ(41) /* CAN0 Transmit Interrupt */ +#define IRQ_CAN0_STAT BFIN_IRQ(42) /* CAN0 Status */ +#define IRQ_SPORT0_TX BFIN_IRQ(43) /* SPORT0 TX Interrupt (DMA0) */ +#define IRQ_SPORT0_TX_STAT BFIN_IRQ(44) /* SPORT0 TX Status Interrupt */ +#define IRQ_SPORT0_RX BFIN_IRQ(45) /* SPORT0 RX Interrupt (DMA1) */ +#define IRQ_SPORT0_RX_STAT BFIN_IRQ(46) /* SPORT0 RX Status Interrupt */ +#define IRQ_SPORT1_TX BFIN_IRQ(47) /* SPORT1 TX Interrupt (DMA2) */ +#define IRQ_SPORT1_TX_STAT BFIN_IRQ(48) /* SPORT1 TX Status Interrupt */ +#define IRQ_SPORT1_RX BFIN_IRQ(49) /* SPORT1 RX Interrupt (DMA3) */ +#define IRQ_SPORT1_RX_STAT BFIN_IRQ(50) /* SPORT1 RX Status Interrupt */ +#define IRQ_SPORT2_TX BFIN_IRQ(51) /* SPORT2 TX Interrupt (DMA4) */ +#define IRQ_SPORT2_TX_STAT BFIN_IRQ(52) /* SPORT2 TX Status Interrupt */ +#define IRQ_SPORT2_RX BFIN_IRQ(53) /* SPORT2 RX Interrupt (DMA5) */ +#define IRQ_SPORT2_RX_STAT BFIN_IRQ(54) /* SPORT2 RX Status Interrupt */ +#define IRQ_SPI0_TX BFIN_IRQ(55) /* SPI0 TX Interrupt (DMA6) */ +#define IRQ_SPI0_RX BFIN_IRQ(56) /* SPI0 RX Interrupt (DMA7) */ +#define IRQ_SPI0_STAT BFIN_IRQ(57) /* SPI0 Status Interrupt */ +#define IRQ_SPI1_TX BFIN_IRQ(58) /* SPI1 TX Interrupt (DMA8) */ +#define IRQ_SPI1_RX BFIN_IRQ(59) /* SPI1 RX Interrupt (DMA9) */ +#define IRQ_SPI1_STAT BFIN_IRQ(60) /* SPI1 Status Interrupt */ +#define IRQ_RSI BFIN_IRQ(61) /* RSI (DMA10) Interrupt */ +#define IRQ_RSI_INT0 BFIN_IRQ(62) /* RSI Interrupt0 */ +#define IRQ_RSI_INT1 BFIN_IRQ(63) /* RSI Interrupt1 */ +#define IRQ_SDU BFIN_IRQ(64) /* DMA11 Data (SDU) */ +/* -- RESERVED -- 65 DMA12 Data (Reserved) */ +/* -- RESERVED -- 66 Reserved */ +/* -- RESERVED -- 67 Reserved */ +#define IRQ_EMAC0_STAT BFIN_IRQ(68) /* EMAC0 Status */ +/* -- RESERVED -- 69 EMAC0 Power (Reserved) */ +#define IRQ_EMAC1_STAT BFIN_IRQ(70) /* EMAC1 Status */ +/* -- RESERVED -- 71 EMAC1 Power (Reserved) */ +#define IRQ_LP0 BFIN_IRQ(72) /* DMA13 Data (Link Port 0) */ +#define IRQ_LP0_STAT BFIN_IRQ(73) /* Link Port 0 Status */ +#define IRQ_LP1 BFIN_IRQ(74) /* DMA14 Data (Link Port 1) */ +#define IRQ_LP1_STAT BFIN_IRQ(75) /* Link Port 1 Status */ +#define IRQ_LP2 BFIN_IRQ(76) /* DMA15 Data (Link Port 2) */ +#define IRQ_LP2_STAT BFIN_IRQ(77) /* Link Port 2 Status */ +#define IRQ_LP3 BFIN_IRQ(78) /* DMA16 Data(Link Port 3) */ +#define IRQ_LP3_STAT BFIN_IRQ(79) /* Link Port 3 Status */ +#define IRQ_UART0_TX BFIN_IRQ(80) /* UART0 TX Interrupt (DMA17) */ +#define IRQ_UART0_RX BFIN_IRQ(81) /* UART0 RX Interrupt (DMA18) */ +#define IRQ_UART0_STAT BFIN_IRQ(82) /* UART0 Status(Error) Interrupt */ +#define IRQ_UART1_TX BFIN_IRQ(83) /* UART1 TX Interrupt (DMA19) */ +#define IRQ_UART1_RX BFIN_IRQ(84) /* UART1 RX Interrupt (DMA20) */ +#define IRQ_UART1_STAT BFIN_IRQ(85) /* UART1 Status(Error) Interrupt */ +#define IRQ_MDMA0_SRC_CRC0 BFIN_IRQ(86) /* DMA21 Data (MDMA Stream 0 Source/CRC0 Input Channel) */ +#define IRQ_MDMA0_DEST_CRC0 BFIN_IRQ(87) /* DMA22 Data (MDMA Stream 0 Destination/CRC0 Output Channel) */ +#define IRQ_MDMAS0 IRQ_MDMA0_DEST_CRC0 +#define IRQ_CRC0_DCNTEXP BFIN_IRQ(88) /* CRC0 DATACOUNT Expiration */ +#define IRQ_CRC0_ERR BFIN_IRQ(89) /* CRC0 Error */ +#define IRQ_MDMA1_SRC_CRC1 BFIN_IRQ(90) /* DMA23 Data (MDMA Stream 1 Source/CRC1 Input Channel) */ +#define IRQ_MDMA1_DEST_CRC1 BFIN_IRQ(91) /* DMA24 Data (MDMA Stream 1 Destination/CRC1 Output Channel) */ +#define IRQ_MDMAS1 IRQ_MDMA1_DEST_CRC1 +#define IRQ_CRC1_DCNTEXP BFIN_IRQ(92) /* CRC1 DATACOUNT Expiration */ +#define IRQ_CRC1_ERR BFIN_IRQ(93) /* CRC1 Error */ +#define IRQ_MDMA2_SRC BFIN_IRQ(94) /* DMA25 Data (MDMA Stream 2 Source Channel) */ +#define IRQ_MDMA2_DEST BFIN_IRQ(95) /* DMA26 Data (MDMA Stream 2 Destination Channel) */ +#define IRQ_MDMAS2 IRQ_MDMA2_DEST +#define IRQ_MDMA3_SRC BFIN_IRQ(96) /* DMA27 Data (MDMA Stream 3 Source Channel) */ +#define IRQ_MDMA3_DEST BFIN_IRQ(97) /* DMA28 Data (MDMA Stream 3 Destination Channel) */ +#define IRQ_MDMAS3 IRQ_MDMA3_DEST +#define IRQ_EPPI0_CH0 BFIN_IRQ(98) /* DMA29 Data (EPPI0 Channel 0) */ +#define IRQ_EPPI0_CH1 BFIN_IRQ(99) /* DMA30 Data (EPPI0 Channel 1) */ +#define IRQ_EPPI0_STAT BFIN_IRQ(100) /* EPPI0 Status */ +#define IRQ_EPPI2_CH0 BFIN_IRQ(101) /* DMA31 Data (EPPI2 Channel 0) */ +#define IRQ_EPPI2_CH1 BFIN_IRQ(102) /* DMA32 Data (EPPI2 Channel 1) */ +#define IRQ_EPPI2_STAT BFIN_IRQ(103) /* EPPI2 Status */ +#define IRQ_EPPI1_CH0 BFIN_IRQ(104) /* DMA33 Data (EPPI1 Channel 0) */ +#define IRQ_EPPI1_CH1 BFIN_IRQ(105) /* DMA34 Data (EPPI1 Channel 1) */ +#define IRQ_EPPI1_STAT BFIN_IRQ(106) /* EPPI1 Status */ +#define IRQ_PIXC_CH0 BFIN_IRQ(107) /* DMA35 Data (PIXC Channel 0) */ +#define IRQ_PIXC_CH1 BFIN_IRQ(108) /* DMA36 Data (PIXC Channel 1) */ +#define IRQ_PIXC_CH2 BFIN_IRQ(109) /* DMA37 Data (PIXC Channel 2) */ +#define IRQ_PIXC_STAT BFIN_IRQ(110) /* PIXC Status */ +#define IRQ_PVP_CPDOB BFIN_IRQ(111) /* DMA38 Data (PVP0 Camera Pipe Data Out B) */ +#define IRQ_PVP_CPDOC BFIN_IRQ(112) /* DMA39 Data (PVP0 Camera Pipe Data Out C) */ +#define IRQ_PVP_CPSTAT BFIN_IRQ(113) /* DMA40 Data (PVP0 Camera Pipe Status Out) */ +#define IRQ_PVP_CPCI BFIN_IRQ(114) /* DMA41 Data (PVP0 Camera Pipe Control In) */ +#define IRQ_PVP_STAT0 BFIN_IRQ(115) /* PVP0 Status 0 */ +#define IRQ_PVP_MPDO BFIN_IRQ(116) /* DMA42 Data (PVP0 Memory Pipe Data Out) */ +#define IRQ_PVP_MPDI BFIN_IRQ(117) /* DMA43 Data (PVP0 Memory Pipe Data In) */ +#define IRQ_PVP_MPSTAT BFIN_IRQ(118) /* DMA44 Data (PVP0 Memory Pipe Status Out) */ +#define IRQ_PVP_MPCI BFIN_IRQ(119) /* DMA45 Data (PVP0 Memory Pipe Control In) */ +#define IRQ_PVP_CPDOA BFIN_IRQ(120) /* DMA46 Data (PVP0 Camera Pipe Data Out A) */ +#define IRQ_PVP_STAT1 BFIN_IRQ(121) /* PVP0 Status 1 */ +#define IRQ_USB_STAT BFIN_IRQ(122) /* USB Status Interrupt */ +#define IRQ_USB_DMA BFIN_IRQ(123) /* USB DMA Interrupt */ +#define IRQ_TRU_INT0 BFIN_IRQ(124) /* TRU0 Interrupt 0 */ +#define IRQ_TRU_INT1 BFIN_IRQ(125) /* TRU0 Interrupt 1 */ +#define IRQ_TRU_INT2 BFIN_IRQ(126) /* TRU0 Interrupt 2 */ +#define IRQ_TRU_INT3 BFIN_IRQ(127) /* TRU0 Interrupt 3 */ +#define IRQ_DMAC0_ERROR BFIN_IRQ(128) /* DMAC0 Status Interrupt */ +#define IRQ_CGU0_ERROR BFIN_IRQ(129) /* CGU0 Error */ +/* -- RESERVED -- 130 Reserved */ +#define IRQ_DPM BFIN_IRQ(131) /* DPM0 Event */ +/* -- RESERVED -- 132 Reserved */ +#define IRQ_SWU0 BFIN_IRQ(133) /* SWU0 */ +#define IRQ_SWU1 BFIN_IRQ(134) /* SWU1 */ +#define IRQ_SWU2 BFIN_IRQ(135) /* SWU2 */ +#define IRQ_SWU3 BFIN_IRQ(136) /* SWU3 */ +#define IRQ_SWU4 BFIN_IRQ(137) /* SWU4 */ +#define IRQ_SWU5 BFIN_IRQ(138) /* SWU5 */ +#define IRQ_SWU6 BFIN_IRQ(139) /* SWU6 */ + +#define SYS_IRQS IRQ_SWU6 + +#define BFIN_PA_IRQ(x) ((x) + SYS_IRQS + 1) +#define IRQ_PA0 BFIN_PA_IRQ(0) +#define IRQ_PA1 BFIN_PA_IRQ(1) +#define IRQ_PA2 BFIN_PA_IRQ(2) +#define IRQ_PA3 BFIN_PA_IRQ(3) +#define IRQ_PA4 BFIN_PA_IRQ(4) +#define IRQ_PA5 BFIN_PA_IRQ(5) +#define IRQ_PA6 BFIN_PA_IRQ(6) +#define IRQ_PA7 BFIN_PA_IRQ(7) +#define IRQ_PA8 BFIN_PA_IRQ(8) +#define IRQ_PA9 BFIN_PA_IRQ(9) +#define IRQ_PA10 BFIN_PA_IRQ(10) +#define IRQ_PA11 BFIN_PA_IRQ(11) +#define IRQ_PA12 BFIN_PA_IRQ(12) +#define IRQ_PA13 BFIN_PA_IRQ(13) +#define IRQ_PA14 BFIN_PA_IRQ(14) +#define IRQ_PA15 BFIN_PA_IRQ(15) + +#define BFIN_PB_IRQ(x) ((x) + IRQ_PA15 + 1) +#define IRQ_PB0 BFIN_PB_IRQ(0) +#define IRQ_PB1 BFIN_PB_IRQ(1) +#define IRQ_PB2 BFIN_PB_IRQ(2) +#define IRQ_PB3 BFIN_PB_IRQ(3) +#define IRQ_PB4 BFIN_PB_IRQ(4) +#define IRQ_PB5 BFIN_PB_IRQ(5) +#define IRQ_PB6 BFIN_PB_IRQ(6) +#define IRQ_PB7 BFIN_PB_IRQ(7) +#define IRQ_PB8 BFIN_PB_IRQ(8) +#define IRQ_PB9 BFIN_PB_IRQ(9) +#define IRQ_PB10 BFIN_PB_IRQ(10) +#define IRQ_PB11 BFIN_PB_IRQ(11) +#define IRQ_PB12 BFIN_PB_IRQ(12) +#define IRQ_PB13 BFIN_PB_IRQ(13) +#define IRQ_PB14 BFIN_PB_IRQ(14) +#define IRQ_PB15 BFIN_PB_IRQ(15) /* N/A */ + +#define BFIN_PC_IRQ(x) ((x) + IRQ_PB15 + 1) +#define IRQ_PC0 BFIN_PC_IRQ(0) +#define IRQ_PC1 BFIN_PC_IRQ(1) +#define IRQ_PC2 BFIN_PC_IRQ(2) +#define IRQ_PC3 BFIN_PC_IRQ(3) +#define IRQ_PC4 BFIN_PC_IRQ(4) +#define IRQ_PC5 BFIN_PC_IRQ(5) +#define IRQ_PC6 BFIN_PC_IRQ(6) +#define IRQ_PC7 BFIN_PC_IRQ(7) +#define IRQ_PC8 BFIN_PC_IRQ(8) +#define IRQ_PC9 BFIN_PC_IRQ(9) +#define IRQ_PC10 BFIN_PC_IRQ(10) +#define IRQ_PC11 BFIN_PC_IRQ(11) +#define IRQ_PC12 BFIN_PC_IRQ(12) +#define IRQ_PC13 BFIN_PC_IRQ(13) +#define IRQ_PC14 BFIN_PC_IRQ(14) /* N/A */ +#define IRQ_PC15 BFIN_PC_IRQ(15) /* N/A */ + +#define BFIN_PD_IRQ(x) ((x) + IRQ_PC15 + 1) +#define IRQ_PD0 BFIN_PD_IRQ(0) +#define IRQ_PD1 BFIN_PD_IRQ(1) +#define IRQ_PD2 BFIN_PD_IRQ(2) +#define IRQ_PD3 BFIN_PD_IRQ(3) +#define IRQ_PD4 BFIN_PD_IRQ(4) +#define IRQ_PD5 BFIN_PD_IRQ(5) +#define IRQ_PD6 BFIN_PD_IRQ(6) +#define IRQ_PD7 BFIN_PD_IRQ(7) +#define IRQ_PD8 BFIN_PD_IRQ(8) +#define IRQ_PD9 BFIN_PD_IRQ(9) +#define IRQ_PD10 BFIN_PD_IRQ(10) +#define IRQ_PD11 BFIN_PD_IRQ(11) +#define IRQ_PD12 BFIN_PD_IRQ(12) +#define IRQ_PD13 BFIN_PD_IRQ(13) +#define IRQ_PD14 BFIN_PD_IRQ(14) +#define IRQ_PD15 BFIN_PD_IRQ(15) + +#define BFIN_PE_IRQ(x) ((x) + IRQ_PD15 + 1) +#define IRQ_PE0 BFIN_PE_IRQ(0) +#define IRQ_PE1 BFIN_PE_IRQ(1) +#define IRQ_PE2 BFIN_PE_IRQ(2) +#define IRQ_PE3 BFIN_PE_IRQ(3) +#define IRQ_PE4 BFIN_PE_IRQ(4) +#define IRQ_PE5 BFIN_PE_IRQ(5) +#define IRQ_PE6 BFIN_PE_IRQ(6) +#define IRQ_PE7 BFIN_PE_IRQ(7) +#define IRQ_PE8 BFIN_PE_IRQ(8) +#define IRQ_PE9 BFIN_PE_IRQ(9) +#define IRQ_PE10 BFIN_PE_IRQ(10) +#define IRQ_PE11 BFIN_PE_IRQ(11) +#define IRQ_PE12 BFIN_PE_IRQ(12) +#define IRQ_PE13 BFIN_PE_IRQ(13) +#define IRQ_PE14 BFIN_PE_IRQ(14) +#define IRQ_PE15 BFIN_PE_IRQ(15) + +#define BFIN_PF_IRQ(x) ((x) + IRQ_PE15 + 1) +#define IRQ_PF0 BFIN_PF_IRQ(0) +#define IRQ_PF1 BFIN_PF_IRQ(1) +#define IRQ_PF2 BFIN_PF_IRQ(2) +#define IRQ_PF3 BFIN_PF_IRQ(3) +#define IRQ_PF4 BFIN_PF_IRQ(4) +#define IRQ_PF5 BFIN_PF_IRQ(5) +#define IRQ_PF6 BFIN_PF_IRQ(6) +#define IRQ_PF7 BFIN_PF_IRQ(7) +#define IRQ_PF8 BFIN_PF_IRQ(8) +#define IRQ_PF9 BFIN_PF_IRQ(9) +#define IRQ_PF10 BFIN_PF_IRQ(10) +#define IRQ_PF11 BFIN_PF_IRQ(11) +#define IRQ_PF12 BFIN_PF_IRQ(12) +#define IRQ_PF13 BFIN_PF_IRQ(13) +#define IRQ_PF14 BFIN_PF_IRQ(14) +#define IRQ_PF15 BFIN_PF_IRQ(15) + +#define BFIN_PG_IRQ(x) ((x) + IRQ_PF15 + 1) +#define IRQ_PG0 BFIN_PG_IRQ(0) +#define IRQ_PG1 BFIN_PG_IRQ(1) +#define IRQ_PG2 BFIN_PG_IRQ(2) +#define IRQ_PG3 BFIN_PG_IRQ(3) +#define IRQ_PG4 BFIN_PG_IRQ(4) +#define IRQ_PG5 BFIN_PG_IRQ(5) +#define IRQ_PG6 BFIN_PG_IRQ(6) +#define IRQ_PG7 BFIN_PG_IRQ(7) +#define IRQ_PG8 BFIN_PG_IRQ(8) +#define IRQ_PG9 BFIN_PG_IRQ(9) +#define IRQ_PG10 BFIN_PG_IRQ(10) +#define IRQ_PG11 BFIN_PG_IRQ(11) +#define IRQ_PG12 BFIN_PG_IRQ(12) +#define IRQ_PG13 BFIN_PG_IRQ(13) +#define IRQ_PG14 BFIN_PG_IRQ(14) +#define IRQ_PG15 BFIN_PG_IRQ(15) + +#define GPIO_IRQ_BASE IRQ_PA0 + +#define NR_MACH_IRQS (IRQ_PG15 + 1) + +#ifndef __ASSEMBLY__ +#include <linux/types.h> + +/* + * bfin pint registers layout + */ +struct bfin_pint_regs { + u32 mask_set; + u32 mask_clear; + u32 request; + u32 assign; + u32 edge_set; + u32 edge_clear; + u32 invert_set; + u32 invert_clear; + u32 pinstate; + u32 latch; + u32 __pad0[2]; +}; + +#endif + +#endif
diff --git a/arch/blackfin/mach-bf609/include/mach/mem_map.h b/arch/blackfin/mach-bf609/include/mach/mem_map.h new file mode 100644 index 0000000..20b65bf --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/mem_map.h
@@ -0,0 +1,86 @@ +/* + * BF60x memory map + * + * Copyright 2011 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + +#ifndef __BFIN_MACH_MEM_MAP_H__ +#define __BFIN_MACH_MEM_MAP_H__ + +#ifndef __BFIN_MEM_MAP_H__ +# error "do not include mach/mem_map.h directly -- use asm/mem_map.h" +#endif + +/* Async Memory Banks */ +#define ASYNC_BANK3_BASE 0xBC000000 /* Async Bank 3 */ +#define ASYNC_BANK3_SIZE 0x04000000 /* 64M */ +#define ASYNC_BANK2_BASE 0xB8000000 /* Async Bank 2 */ +#define ASYNC_BANK2_SIZE 0x04000000 /* 64M */ +#define ASYNC_BANK1_BASE 0xB4000000 /* Async Bank 1 */ +#define ASYNC_BANK1_SIZE 0x04000000 /* 64M */ +#define ASYNC_BANK0_BASE 0xB0000000 /* Async Bank 0 */ +#define ASYNC_BANK0_SIZE 0x04000000 /* 64M */ + +/* Boot ROM Memory */ + +#define BOOT_ROM_START 0xC8000000 +#define BOOT_ROM_LENGTH 0x8000 + +/* Level 1 Memory */ + +/* Memory Map for ADSP-BF60x processors */ +#ifdef CONFIG_BFIN_ICACHE +#define BFIN_ICACHESIZE (16*1024) +#define L1_CODE_LENGTH 0x10000 +#else +#define BFIN_ICACHESIZE (0*1024) +#define L1_CODE_LENGTH 0x14000 +#endif + +#define L1_CODE_START 0xFFA00000 +#define L1_DATA_A_START 0xFF800000 +#define L1_DATA_B_START 0xFF900000 + + +#define COREA_L1_SCRATCH_START 0xFFB00000 +#define COREB_L1_SCRATCH_START 0xFF700000 + +#define COREB_L1_CODE_START 0xFF600000 +#define COREB_L1_DATA_A_START 0xFF400000 +#define COREB_L1_DATA_B_START 0xFF500000 + +#define COREB_L1_CODE_LENGTH 0x14000 +#define COREB_L1_DATA_A_LENGTH 0x8000 +#define COREB_L1_DATA_B_LENGTH 0x8000 + + +#ifdef CONFIG_BFIN_DCACHE + +#ifdef CONFIG_BFIN_DCACHE_BANKA +#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x8000 - 0x4000) +#define L1_DATA_B_LENGTH 0x8000 +#define BFIN_DCACHESIZE (16*1024) +#define BFIN_DSUPBANKS 1 +#else +#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x8000 - 0x4000) +#define L1_DATA_B_LENGTH (0x8000 - 0x4000) +#define BFIN_DCACHESIZE (32*1024) +#define BFIN_DSUPBANKS 2 +#endif + +#else +#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH 0x8000 +#define L1_DATA_B_LENGTH 0x8000 +#define BFIN_DCACHESIZE (0*1024) +#define BFIN_DSUPBANKS 0 +#endif /*CONFIG_BFIN_DCACHE*/ + +/* Level 2 Memory */ +#define L2_START 0xC8080000 +#define L2_LENGTH 0x40000 + +#endif
diff --git a/arch/blackfin/mach-bf609/include/mach/pll.h b/arch/blackfin/mach-bf609/include/mach/pll.h new file mode 100644 index 0000000..1857a4a --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/pll.h
@@ -0,0 +1 @@ +/* #include <mach-common/pll.h> */
diff --git a/arch/blackfin/mach-bf609/include/mach/pm.h b/arch/blackfin/mach-bf609/include/mach/pm.h new file mode 100644 index 0000000..036d9bdc8 --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/pm.h
@@ -0,0 +1,21 @@ +/* + * Blackfin bf609 power management + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 + */ + +#ifndef __MACH_BF609_PM_H__ +#define __MACH_BF609_PM_H__ + +#include <linux/suspend.h> + +int bfin609_pm_enter(suspend_state_t state); +int bf609_pm_prepare(void); +void bf609_pm_finish(void); + +void bf609_hibernate(void); +void bfin_sec_raise_irq(unsigned int sid); +void coreb_enable(void); +#endif
diff --git a/arch/blackfin/mach-bf609/include/mach/portmux.h b/arch/blackfin/mach-bf609/include/mach/portmux.h new file mode 100644 index 0000000..2e1a51c --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/portmux.h
@@ -0,0 +1,347 @@ +/* + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later + */ + +#ifndef _MACH_PORTMUX_H_ +#define _MACH_PORTMUX_H_ + +#define MAX_RESOURCES MAX_BLACKFIN_GPIOS + +/* EMAC RMII Port Mux */ +#define P_MII0_MDC (P_DEFINED | P_IDENT(GPIO_PC6) | P_FUNCT(0)) +#define P_MII0_MDIO (P_DEFINED | P_IDENT(GPIO_PC7) | P_FUNCT(0)) +#define P_MII0_ETxD0 (P_DEFINED | P_IDENT(GPIO_PC2) | P_FUNCT(0)) +#define P_MII0_ERxD0 (P_DEFINED | P_IDENT(GPIO_PC0) | P_FUNCT(0)) +#define P_MII0_ETxD1 (P_DEFINED | P_IDENT(GPIO_PC3) | P_FUNCT(0)) +#define P_MII0_ERxD1 (P_DEFINED | P_IDENT(GPIO_PC1) | P_FUNCT(0)) +#define P_MII0_ETxEN (P_DEFINED | P_IDENT(GPIO_PB13) | P_FUNCT(0)) +#define P_MII0_PHYINT (P_DEFINED | P_IDENT(GPIO_PD6) | P_FUNCT(0)) +#define P_MII0_CRS (P_DEFINED | P_IDENT(GPIO_PC5) | P_FUNCT(0)) +#define P_MII0_ERxER (P_DEFINED | P_IDENT(GPIO_PC4) | P_FUNCT(0)) +#define P_MII0_TxCLK (P_DEFINED | P_IDENT(GPIO_PB14) | P_FUNCT(0)) + +#define P_RMII0 {\ + P_MII0_ETxD0, \ + P_MII0_ETxD1, \ + P_MII0_ETxEN, \ + P_MII0_ERxD0, \ + P_MII0_ERxD1, \ + P_MII0_ERxER, \ + P_MII0_TxCLK, \ + P_MII0_PHYINT, \ + P_MII0_CRS, \ + P_MII0_MDC, \ + P_MII0_MDIO, 0} + +#define P_MII1_MDC (P_DEFINED | P_IDENT(GPIO_PE10) | P_FUNCT(0)) +#define P_MII1_MDIO (P_DEFINED | P_IDENT(GPIO_PE11) | P_FUNCT(0)) +#define P_MII1_ETxD0 (P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(0)) +#define P_MII1_ERxD0 (P_DEFINED | P_IDENT(GPIO_PG0) | P_FUNCT(0)) +#define P_MII1_ETxD1 (P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(0)) +#define P_MII1_ERxD1 (P_DEFINED | P_IDENT(GPIO_PE15) | P_FUNCT(0)) +#define P_MII1_ETxEN (P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(0)) +#define P_MII1_PHYINT (P_DEFINED | P_IDENT(GPIO_PE12) | P_FUNCT(0)) +#define P_MII1_CRS (P_DEFINED | P_IDENT(GPIO_PE13) | P_FUNCT(0)) +#define P_MII1_ERxER (P_DEFINED | P_IDENT(GPIO_PE14) | P_FUNCT(0)) +#define P_MII1_TxCLK (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(0)) + +#define P_RMII1 {\ + P_MII1_ETxD0, \ + P_MII1_ETxD1, \ + P_MII1_ETxEN, \ + P_MII1_ERxD0, \ + P_MII1_ERxD1, \ + P_MII1_ERxER, \ + P_MII1_TxCLK, \ + P_MII1_PHYINT, \ + P_MII1_CRS, \ + P_MII1_MDC, \ + P_MII1_MDIO, 0} + +/* PPI Port Mux */ +#define P_PPI0_D0 (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(1)) +#define P_PPI0_D1 (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(1)) +#define P_PPI0_D2 (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(1)) +#define P_PPI0_D3 (P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(1)) +#define P_PPI0_D4 (P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(1)) +#define P_PPI0_D5 (P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(1)) +#define P_PPI0_D6 (P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(1)) +#define P_PPI0_D7 (P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(1)) +#define P_PPI0_D8 (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(1)) +#define P_PPI0_D9 (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(1)) +#define P_PPI0_D10 (P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(1)) +#define P_PPI0_D11 (P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(1)) +#define P_PPI0_D12 (P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(1)) +#define P_PPI0_D13 (P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(1)) +#define P_PPI0_D14 (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(1)) +#define P_PPI0_D15 (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(1)) +#define P_PPI0_D16 (P_DEFINED | P_IDENT(GPIO_PE3) | P_FUNCT(1)) +#define P_PPI0_D17 (P_DEFINED | P_IDENT(GPIO_PE4) | P_FUNCT(1)) +#define P_PPI0_D18 (P_DEFINED | P_IDENT(GPIO_PE0) | P_FUNCT(1)) +#define P_PPI0_D19 (P_DEFINED | P_IDENT(GPIO_PE1) | P_FUNCT(1)) +#define P_PPI0_D20 (P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(1)) +#define P_PPI0_D21 (P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(1)) +#define P_PPI0_D22 (P_DEFINED | P_IDENT(GPIO_PE2) | P_FUNCT(1)) +#define P_PPI0_D23 (P_DEFINED | P_IDENT(GPIO_PE5) | P_FUNCT(1)) +#define P_PPI0_CLK (P_DEFINED | P_IDENT(GPIO_PE9) | P_FUNCT(1)) +#define P_PPI0_FS1 (P_DEFINED | P_IDENT(GPIO_PE8) | P_FUNCT(1)) +#define P_PPI0_FS2 (P_DEFINED | P_IDENT(GPIO_PE7) | P_FUNCT(1)) +#define P_PPI0_FS3 (P_DEFINED | P_IDENT(GPIO_PE6) | P_FUNCT(1)) + +#define P_PPI1_D0 (P_DEFINED | P_IDENT(GPIO_PC0) | P_FUNCT(1)) +#define P_PPI1_D1 (P_DEFINED | P_IDENT(GPIO_PC1) | P_FUNCT(1)) +#define P_PPI1_D2 (P_DEFINED | P_IDENT(GPIO_PC2) | P_FUNCT(1)) +#define P_PPI1_D3 (P_DEFINED | P_IDENT(GPIO_PC3) | P_FUNCT(1)) +#define P_PPI1_D4 (P_DEFINED | P_IDENT(GPIO_PC4) | P_FUNCT(1)) +#define P_PPI1_D5 (P_DEFINED | P_IDENT(GPIO_PC5) | P_FUNCT(1)) +#define P_PPI1_D6 (P_DEFINED | P_IDENT(GPIO_PC6) | P_FUNCT(1)) +#define P_PPI1_D7 (P_DEFINED | P_IDENT(GPIO_PC7) | P_FUNCT(1)) +#define P_PPI1_D8 (P_DEFINED | P_IDENT(GPIO_PC8) | P_FUNCT(1)) +#define P_PPI1_D9 (P_DEFINED | P_IDENT(GPIO_PC9) | P_FUNCT(1)) +#define P_PPI1_D10 (P_DEFINED | P_IDENT(GPIO_PC10) | P_FUNCT(1)) +#define P_PPI1_D11 (P_DEFINED | P_IDENT(GPIO_PC11) | P_FUNCT(1)) +#define P_PPI1_D12 (P_DEFINED | P_IDENT(GPIO_PC12) | P_FUNCT(1)) +#define P_PPI1_D13 (P_DEFINED | P_IDENT(GPIO_PC13) | P_FUNCT(1)) +#define P_PPI1_D14 (P_DEFINED | P_IDENT(GPIO_PC14) | P_FUNCT(1)) +#define P_PPI1_D15 (P_DEFINED | P_IDENT(GPIO_PC15) | P_FUNCT(1)) +#define P_PPI1_D16 (P_DEFINED | P_IDENT(GPIO_PD0) | P_FUNCT(1)) +#define P_PPI1_D17 (P_DEFINED | P_IDENT(GPIO_PD1) | P_FUNCT(1)) +#define P_PPI1_CLK (P_DEFINED | P_IDENT(GPIO_PB14) | P_FUNCT(1)) +#define P_PPI1_FS1 (P_DEFINED | P_IDENT(GPIO_PB13) | P_FUNCT(1)) +#define P_PPI1_FS2 (P_DEFINED | P_IDENT(GPIO_PD6) | P_FUNCT(1)) +#define P_PPI1_FS3 (P_DEFINED | P_IDENT(GPIO_PB15) | P_FUNCT(1)) + +#define P_PPI2_D0 (P_DEFINED | P_IDENT(GPIO_PA0) | P_FUNCT(1)) +#define P_PPI2_D1 (P_DEFINED | P_IDENT(GPIO_PA1) | P_FUNCT(1)) +#define P_PPI2_D2 (P_DEFINED | P_IDENT(GPIO_PA2) | P_FUNCT(1)) +#define P_PPI2_D3 (P_DEFINED | P_IDENT(GPIO_PA3) | P_FUNCT(1)) +#define P_PPI2_D4 (P_DEFINED | P_IDENT(GPIO_PA4) | P_FUNCT(1)) +#define P_PPI2_D5 (P_DEFINED | P_IDENT(GPIO_PA5) | P_FUNCT(1)) +#define P_PPI2_D6 (P_DEFINED | P_IDENT(GPIO_PA6) | P_FUNCT(1)) +#define P_PPI2_D7 (P_DEFINED | P_IDENT(GPIO_PA7) | P_FUNCT(1)) +#define P_PPI2_D8 (P_DEFINED | P_IDENT(GPIO_PA8) | P_FUNCT(1)) +#define P_PPI2_D9 (P_DEFINED | P_IDENT(GPIO_PA9) | P_FUNCT(1)) +#define P_PPI2_D10 (P_DEFINED | P_IDENT(GPIO_PA10) | P_FUNCT(1)) +#define P_PPI2_D11 (P_DEFINED | P_IDENT(GPIO_PA11) | P_FUNCT(1)) +#define P_PPI2_D12 (P_DEFINED | P_IDENT(GPIO_PA12) | P_FUNCT(1)) +#define P_PPI2_D13 (P_DEFINED | P_IDENT(GPIO_PA13) | P_FUNCT(1)) +#define P_PPI2_D14 (P_DEFINED | P_IDENT(GPIO_PA14) | P_FUNCT(1)) +#define P_PPI2_D15 (P_DEFINED | P_IDENT(GPIO_PA15) | P_FUNCT(1)) +#define P_PPI2_D16 (P_DEFINED | P_IDENT(GPIO_PB7) | P_FUNCT(1)) +#define P_PPI2_D17 (P_DEFINED | P_IDENT(GPIO_PB8) | P_FUNCT(1)) +#define P_PPI2_CLK (P_DEFINED | P_IDENT(GPIO_PB0) | P_FUNCT(1)) +#define P_PPI2_FS1 (P_DEFINED | P_IDENT(GPIO_PB1) | P_FUNCT(1)) +#define P_PPI2_FS2 (P_DEFINED | P_IDENT(GPIO_PB2) | P_FUNCT(1)) +#define P_PPI2_FS3 (P_DEFINED | P_IDENT(GPIO_PB3) | P_FUNCT(1)) + +/* SPI Port Mux */ +#define P_SPI0_SS (P_DEFINED | P_IDENT(GPIO_PD11) | P_FUNCT(3)) +#define P_SPI0_SCK (P_DEFINED | P_IDENT(GPIO_PD4) | P_FUNCT(0)) +#define P_SPI0_MISO (P_DEFINED | P_IDENT(GPIO_PD2) | P_FUNCT(0)) +#define P_SPI0_MOSI (P_DEFINED | P_IDENT(GPIO_PD3) | P_FUNCT(0)) +#define P_SPI0_RDY (P_DEFINED | P_IDENT(GPIO_PD10) | P_FUNCT(0)) +#define P_SPI0_D2 (P_DEFINED | P_IDENT(GPIO_PD0) | P_FUNCT(0)) +#define P_SPI0_D3 (P_DEFINED | P_IDENT(GPIO_PD1) | P_FUNCT(0)) + +#define P_SPI0_SSEL1 (P_DEFINED | P_IDENT(GPIO_PD11) | P_FUNCT(0)) +#define P_SPI0_SSEL2 (P_DEFINED | P_IDENT(GPIO_PD1) | P_FUNCT(2)) +#define P_SPI0_SSEL3 (P_DEFINED | P_IDENT(GPIO_PD0) | P_FUNCT(2)) +#define P_SPI0_SSEL4 (P_DEFINED | P_IDENT(GPIO_PC15) | P_FUNCT(0)) +#define P_SPI0_SSEL5 (P_DEFINED | P_IDENT(GPIO_PD9) | P_FUNCT(0)) +#define P_SPI0_SSEL6 (P_DEFINED | P_IDENT(GPIO_PC13) | P_FUNCT(0)) +#define P_SPI0_SSEL7 (P_DEFINED | P_IDENT(GPIO_PC12) | P_FUNCT(0)) + +#define P_SPI1_SS (P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(3)) +#define P_SPI1_SCK (P_DEFINED | P_IDENT(GPIO_PD5) | P_FUNCT(0)) +#define P_SPI1_MISO (P_DEFINED | P_IDENT(GPIO_PD14) | P_FUNCT(0)) +#define P_SPI1_MOSI (P_DEFINED | P_IDENT(GPIO_PD13) | P_FUNCT(0)) +#define P_SPI1_RDY (P_DEFINED | P_IDENT(GPIO_PE2) | P_FUNCT(0)) +#define P_SPI1_D2 (P_DEFINED | P_IDENT(GPIO_PE1) | P_FUNCT(0)) +#define P_SPI1_D3 (P_DEFINED | P_IDENT(GPIO_PE0) | P_FUNCT(0)) + +#define P_SPI1_SSEL1 (P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(0)) +#define P_SPI1_SSEL2 (P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(2)) +#define P_SPI1_SSEL3 (P_DEFINED | P_IDENT(GPIO_PD10) | P_FUNCT(2)) +#define P_SPI1_SSEL4 (P_DEFINED | P_IDENT(GPIO_PD9) | P_FUNCT(2)) +#define P_SPI1_SSEL5 (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(0)) +#define P_SPI1_SSEL6 (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(0)) +#define P_SPI1_SSEL7 (P_DEFINED | P_IDENT(GPIO_PC14) | P_FUNCT(0)) + +#define GPIO_DEFAULT_BOOT_SPI_CS +#define P_DEFAULT_BOOT_SPI_CS + +/* CORE IDLE */ +#define P_IDLEA (P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(1)) +#define P_IDLEB (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(1)) +#define P_SLEEP (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(2)) + +/* UART Port Mux */ +#define P_UART0_TX (P_DEFINED | P_IDENT(GPIO_PD7) | P_FUNCT(1)) +#define P_UART0_RX (P_DEFINED | P_IDENT(GPIO_PD8) | P_FUNCT(1)) +#define P_UART0_RTS (P_DEFINED | P_IDENT(GPIO_PD9) | P_FUNCT(1)) +#define P_UART0_CTS (P_DEFINED | P_IDENT(GPIO_PD10) | P_FUNCT(1)) + +#define P_UART1_TX (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(0)) +#define P_UART1_RX (P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(0)) +#define P_UART1_RTS (P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(0)) +#define P_UART1_CTS (P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(0)) + +/* Timer */ +#define P_TMRCLK (P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(3)) +#define P_TMR0 (P_DEFINED | P_IDENT(GPIO_PE14) | P_FUNCT(2)) +#define P_TMR1 (P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(1)) +#define P_TMR2 (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(1)) +#define P_TMR3 (P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(1)) +#define P_TMR4 (P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(1)) +#define P_TMR5 (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(1)) +#define P_TMR6 (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(1)) +#define P_TMR7 (P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(1)) + +/* RSI */ +#define P_RSI_DATA0 (P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(2)) +#define P_RSI_DATA1 (P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(2)) +#define P_RSI_DATA2 (P_DEFINED | P_IDENT(GPIO_PG0) | P_FUNCT(2)) +#define P_RSI_DATA3 (P_DEFINED | P_IDENT(GPIO_PE15) | P_FUNCT(2)) +#define P_RSI_DATA4 (P_DEFINED | P_IDENT(GPIO_PE13) | P_FUNCT(2)) +#define P_RSI_DATA5 (P_DEFINED | P_IDENT(GPIO_PE12) | P_FUNCT(2)) +#define P_RSI_DATA6 (P_DEFINED | P_IDENT(GPIO_PE10) | P_FUNCT(2)) +#define P_RSI_DATA7 (P_DEFINED | P_IDENT(GPIO_PE11) | P_FUNCT(2)) +#define P_RSI_CMD (P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(1)) +#define P_RSI_CLK (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(1)) + +/* PTP */ +#define P_PTP0_PPS (P_DEFINED | P_IDENT(GPIO_PB15) | P_FUNCT(0)) +#define P_PTP0_CLKIN (P_DEFINED | P_IDENT(GPIO_PC13) | P_FUNCT(2)) +#define P_PTP0_AUXIN (P_DEFINED | P_IDENT(GPIO_PC11) | P_FUNCT(2)) + +#define P_PTP1_PPS (P_DEFINED | P_IDENT(GPIO_PC9) | P_FUNCT(0)) +#define P_PTP1_CLKIN (P_DEFINED | P_IDENT(GPIO_PC13) | P_FUNCT(2)) +#define P_PTP1_AUXIN (P_DEFINED | P_IDENT(GPIO_PC11) | P_FUNCT(2)) + +/* SMC Port Mux */ +#define P_A3 (P_DEFINED | P_IDENT(GPIO_PA0) | P_FUNCT(0)) +#define P_A4 (P_DEFINED | P_IDENT(GPIO_PA1) | P_FUNCT(0)) +#define P_A5 (P_DEFINED | P_IDENT(GPIO_PA2) | P_FUNCT(0)) +#define P_A6 (P_DEFINED | P_IDENT(GPIO_PA3) | P_FUNCT(0)) +#define P_A7 (P_DEFINED | P_IDENT(GPIO_PA4) | P_FUNCT(0)) +#define P_A8 (P_DEFINED | P_IDENT(GPIO_PA5) | P_FUNCT(0)) +#define P_A9 (P_DEFINED | P_IDENT(GPIO_PA6) | P_FUNCT(0)) +#define P_A10 (P_DEFINED | P_IDENT(GPIO_PA7) | P_FUNCT(0)) +#define P_A11 (P_DEFINED | P_IDENT(GPIO_PA8) | P_FUNCT(0)) +#define P_A12 (P_DEFINED | P_IDENT(GPIO_PA9) | P_FUNCT(0)) +#define P_A13 (P_DEFINED | P_IDENT(GPIO_PB2) | P_FUNCT(0)) +#define P_A14 (P_DEFINED | P_IDENT(GPIO_PA10) | P_FUNCT(0)) +#define P_A15 (P_DEFINED | P_IDENT(GPIO_PA11) | P_FUNCT(0)) +#define P_A16 (P_DEFINED | P_IDENT(GPIO_PB3) | P_FUNCT(0)) +#define P_A17 (P_DEFINED | P_IDENT(GPIO_PA12) | P_FUNCT(0)) +#define P_A18 (P_DEFINED | P_IDENT(GPIO_PA13) | P_FUNCT(0)) +#define P_A19 (P_DEFINED | P_IDENT(GPIO_PA14) | P_FUNCT(0)) +#define P_A20 (P_DEFINED | P_IDENT(GPIO_PA15) | P_FUNCT(0)) +#define P_A21 (P_DEFINED | P_IDENT(GPIO_PB6) | P_FUNCT(0)) +#define P_A22 (P_DEFINED | P_IDENT(GPIO_PB7) | P_FUNCT(0)) +#define P_A23 (P_DEFINED | P_IDENT(GPIO_PB8) | P_FUNCT(0)) +#define P_A24 (P_DEFINED | P_IDENT(GPIO_PB10) | P_FUNCT(0)) +#define P_A25 (P_DEFINED | P_IDENT(GPIO_PB11) | P_FUNCT(0)) +#define P_NORCK (P_DEFINED | P_IDENT(GPIO_PB0) | P_FUNCT(0)) + +#define P_AMS1 (P_DEFINED | P_IDENT(GPIO_PB1) | P_FUNCT(0)) +#define P_AMS2 (P_DEFINED | P_IDENT(GPIO_PB4) | P_FUNCT(0)) +#define P_AMS3 (P_DEFINED | P_IDENT(GPIO_PB5) | P_FUNCT(0)) + +/* CAN */ +#define P_CAN0_TX (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(2)) +#define P_CAN0_RX (P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(2)) + +/* SPORT */ +#define P_SPORT0_ACLK (P_DEFINED | P_IDENT(GPIO_PB5) | P_FUNCT(2)) +#define P_SPORT0_AFS (P_DEFINED | P_IDENT(GPIO_PB4) | P_FUNCT(2)) +#define P_SPORT0_AD0 (P_DEFINED | P_IDENT(GPIO_PB9) | P_FUNCT(2)) +#define P_SPORT0_AD1 (P_DEFINED | P_IDENT(GPIO_PB12) | P_FUNCT(2)) +#define P_SPORT0_ATDV (P_DEFINED | P_IDENT(GPIO_PB6) | P_FUNCT(1)) +#define P_SPORT0_BCLK (P_DEFINED | P_IDENT(GPIO_PB8) | P_FUNCT(2)) +#define P_SPORT0_BFS (P_DEFINED | P_IDENT(GPIO_PB7) | P_FUNCT(2)) +#define P_SPORT0_BD0 (P_DEFINED | P_IDENT(GPIO_PB11) | P_FUNCT(2)) +#define P_SPORT0_BD1 (P_DEFINED | P_IDENT(GPIO_PB10) | P_FUNCT(2)) +#define P_SPORT0_BTDV (P_DEFINED | P_IDENT(GPIO_PB12) | P_FUNCT(1)) + +#define P_SPORT1_ACLK (P_DEFINED | P_IDENT(GPIO_PE2) | P_FUNCT(2)) +#define P_SPORT1_AFS (P_DEFINED | P_IDENT(GPIO_PE5) | P_FUNCT(2)) +#define P_SPORT1_AD0 (P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(2)) +#define P_SPORT1_AD1 (P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(2)) +#define P_SPORT1_ATDV (P_DEFINED | P_IDENT(GPIO_PE6) | P_FUNCT(0)) +#define P_SPORT1_BCLK (P_DEFINED | P_IDENT(GPIO_PE4) | P_FUNCT(2)) +#define P_SPORT1_BFS (P_DEFINED | P_IDENT(GPIO_PE3) | P_FUNCT(2)) +#define P_SPORT1_BD0 (P_DEFINED | P_IDENT(GPIO_PE1) | P_FUNCT(2)) +#define P_SPORT1_BD1 (P_DEFINED | P_IDENT(GPIO_PE0) | P_FUNCT(2)) +#define P_SPORT1_BTDV (P_DEFINED | P_IDENT(GPIO_PE7) | P_FUNCT(0)) + +#define P_SPORT2_ACLK (P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(0)) +#define P_SPORT2_AFS (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0)) +#define P_SPORT2_AD0 (P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(0)) +#define P_SPORT2_AD1 (P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(0)) +#define P_SPORT2_ATDV (P_DEFINED | P_IDENT(GPIO_PE14) | P_FUNCT(1)) +#define P_SPORT2_BCLK (P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(1)) +#define P_SPORT2_BFS (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(0)) +#define P_SPORT2_BD0 (P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(0)) +#define P_SPORT2_BD1 (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(0)) +#define P_SPORT2_BTDV (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(2)) + +/* LINK PORT */ +#define P_LP0_CLK (P_DEFINED | P_IDENT(GPIO_PB0) | P_FUNCT(2)) +#define P_LP0_ACK (P_DEFINED | P_IDENT(GPIO_PB1) | P_FUNCT(2)) +#define P_LP0_D0 (P_DEFINED | P_IDENT(GPIO_PA0) | P_FUNCT(2)) +#define P_LP0_D1 (P_DEFINED | P_IDENT(GPIO_PA1) | P_FUNCT(2)) +#define P_LP0_D2 (P_DEFINED | P_IDENT(GPIO_PA2) | P_FUNCT(2)) +#define P_LP0_D3 (P_DEFINED | P_IDENT(GPIO_PA3) | P_FUNCT(2)) +#define P_LP0_D4 (P_DEFINED | P_IDENT(GPIO_PA4) | P_FUNCT(2)) +#define P_LP0_D5 (P_DEFINED | P_IDENT(GPIO_PA5) | P_FUNCT(2)) +#define P_LP0_D6 (P_DEFINED | P_IDENT(GPIO_PA6) | P_FUNCT(2)) +#define P_LP0_D7 (P_DEFINED | P_IDENT(GPIO_PA7) | P_FUNCT(2)) + +#define P_LP1_CLK (P_DEFINED | P_IDENT(GPIO_PB3) | P_FUNCT(2)) +#define P_LP1_ACK (P_DEFINED | P_IDENT(GPIO_PB2) | P_FUNCT(2)) +#define P_LP1_D0 (P_DEFINED | P_IDENT(GPIO_PA8) | P_FUNCT(2)) +#define P_LP1_D1 (P_DEFINED | P_IDENT(GPIO_PA9) | P_FUNCT(2)) +#define P_LP1_D2 (P_DEFINED | P_IDENT(GPIO_PA10) | P_FUNCT(2)) +#define P_LP1_D3 (P_DEFINED | P_IDENT(GPIO_PA11) | P_FUNCT(2)) +#define P_LP1_D4 (P_DEFINED | P_IDENT(GPIO_PA12) | P_FUNCT(2)) +#define P_LP1_D5 (P_DEFINED | P_IDENT(GPIO_PA13) | P_FUNCT(2)) +#define P_LP1_D6 (P_DEFINED | P_IDENT(GPIO_PA14) | P_FUNCT(2)) +#define P_LP1_D7 (P_DEFINED | P_IDENT(GPIO_PA15) | P_FUNCT(2)) + +#define P_LP2_CLK (P_DEFINED | P_IDENT(GPIO_PE6) | P_FUNCT(2)) +#define P_LP2_ACK (P_DEFINED | P_IDENT(GPIO_PE7) | P_FUNCT(2)) +#define P_LP2_D0 (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(2)) +#define P_LP2_D1 (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(2)) +#define P_LP2_D2 (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(2)) +#define P_LP2_D3 (P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(2)) +#define P_LP2_D4 (P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(2)) +#define P_LP2_D5 (P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(2)) +#define P_LP2_D6 (P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(2)) +#define P_LP2_D7 (P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(2)) + +#define P_LP3_CLK (P_DEFINED | P_IDENT(GPIO_PE9) | P_FUNCT(2)) +#define P_LP3_ACK (P_DEFINED | P_IDENT(GPIO_PE8) | P_FUNCT(2)) +#define P_LP3_D0 (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(2)) +#define P_LP3_D1 (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(2)) +#define P_LP3_D2 (P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(2)) +#define P_LP3_D3 (P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(2)) +#define P_LP3_D4 (P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(2)) +#define P_LP3_D5 (P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(2)) +#define P_LP3_D6 (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(2)) +#define P_LP3_D7 (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(2)) + +/* TWI */ +#define P_TWI0_SCL (P_DONTCARE) +#define P_TWI0_SDA (P_DONTCARE) +#define P_TWI1_SCL (P_DONTCARE) +#define P_TWI1_SDA (P_DONTCARE) + +/* Rotary Encoder */ +#define P_CNT_CZM (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(3)) +#define P_CNT_CUD (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(3)) +#define P_CNT_CDG (P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(3)) + +#endif /* _MACH_PORTMUX_H_ */
diff --git a/arch/blackfin/mach-bf609/pm.c b/arch/blackfin/mach-bf609/pm.c new file mode 100644 index 0000000..b76966eb --- /dev/null +++ b/arch/blackfin/mach-bf609/pm.c
@@ -0,0 +1,362 @@ +/* + * Blackfin bf609 power management + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 + */ + +#include <linux/suspend.h> +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/gpio.h> +#include <linux/irq.h> + +#include <linux/delay.h> + +#include <asm/dpmc.h> +#include <asm/pm.h> +#include <mach/pm.h> +#include <asm/blackfin.h> + +/***********************************************************/ +/* */ +/* Wakeup Actions for DPM_RESTORE */ +/* */ +/***********************************************************/ +#define BITP_ROM_WUA_CHKHDR 24 +#define BITP_ROM_WUA_DDRLOCK 7 +#define BITP_ROM_WUA_DDRDLLEN 6 +#define BITP_ROM_WUA_DDR 5 +#define BITP_ROM_WUA_CGU 4 +#define BITP_ROM_WUA_MEMBOOT 2 +#define BITP_ROM_WUA_EN 1 + +#define BITM_ROM_WUA_CHKHDR (0xFF000000) +#define ENUM_ROM_WUA_CHKHDR_AD 0xAD000000 + +#define BITM_ROM_WUA_DDRLOCK (0x00000080) +#define BITM_ROM_WUA_DDRDLLEN (0x00000040) +#define BITM_ROM_WUA_DDR (0x00000020) +#define BITM_ROM_WUA_CGU (0x00000010) +#define BITM_ROM_WUA_MEMBOOT (0x00000002) +#define BITM_ROM_WUA_EN (0x00000001) + +/***********************************************************/ +/* */ +/* Syscontrol */ +/* */ +/***********************************************************/ +#define BITP_ROM_SYSCTRL_CGU_LOCKINGEN 28 /* unlocks CGU_CTL register */ +#define BITP_ROM_SYSCTRL_WUA_OVERRIDE 24 +#define BITP_ROM_SYSCTRL_WUA_DDRDLLEN 20 /* Saves the DDR DLL and PADS registers to the DPM registers */ +#define BITP_ROM_SYSCTRL_WUA_DDR 19 /* Saves the DDR registers to the DPM registers */ +#define BITP_ROM_SYSCTRL_WUA_CGU 18 /* Saves the CGU registers into DPM registers */ +#define BITP_ROM_SYSCTRL_WUA_DPMWRITE 17 /* Saves the Syscontrol structure structure contents into DPM registers */ +#define BITP_ROM_SYSCTRL_WUA_EN 16 /* reads current PLL and DDR configuration into structure */ +#define BITP_ROM_SYSCTRL_DDR_WRITE 13 /* writes the DDR registers from Syscontrol structure for wakeup initialization of DDR */ +#define BITP_ROM_SYSCTRL_DDR_READ 12 /* Read the DDR registers into the Syscontrol structure for storing prior to hibernate */ +#define BITP_ROM_SYSCTRL_CGU_AUTODIS 11 /* Disables auto handling of UPDT and ALGN fields */ +#define BITP_ROM_SYSCTRL_CGU_CLKOUTSEL 7 /* access CGU_CLKOUTSEL register */ +#define BITP_ROM_SYSCTRL_CGU_DIV 6 /* access CGU_DIV register */ +#define BITP_ROM_SYSCTRL_CGU_STAT 5 /* access CGU_STAT register */ +#define BITP_ROM_SYSCTRL_CGU_CTL 4 /* access CGU_CTL register */ +#define BITP_ROM_SYSCTRL_CGU_RTNSTAT 2 /* Update structure STAT field upon error */ +#define BITP_ROM_SYSCTRL_WRITE 1 /* write registers */ +#define BITP_ROM_SYSCTRL_READ 0 /* read registers */ + +#define BITM_ROM_SYSCTRL_CGU_READ (0x00000001) /* Read CGU registers */ +#define BITM_ROM_SYSCTRL_CGU_WRITE (0x00000002) /* Write registers */ +#define BITM_ROM_SYSCTRL_CGU_RTNSTAT (0x00000004) /* Update structure STAT field upon error or after a write operation */ +#define BITM_ROM_SYSCTRL_CGU_CTL (0x00000010) /* Access CGU_CTL register */ +#define BITM_ROM_SYSCTRL_CGU_STAT (0x00000020) /* Access CGU_STAT register */ +#define BITM_ROM_SYSCTRL_CGU_DIV (0x00000040) /* Access CGU_DIV register */ +#define BITM_ROM_SYSCTRL_CGU_CLKOUTSEL (0x00000080) /* Access CGU_CLKOUTSEL register */ +#define BITM_ROM_SYSCTRL_CGU_AUTODIS (0x00000800) /* Disables auto handling of UPDT and ALGN fields */ +#define BITM_ROM_SYSCTRL_DDR_READ (0x00001000) /* Reads the contents of the DDR registers and stores them into the structure */ +#define BITM_ROM_SYSCTRL_DDR_WRITE (0x00002000) /* Writes the DDR registers from the structure, only really intented for wakeup functionality and not for full DDR configuration */ +#define BITM_ROM_SYSCTRL_WUA_EN (0x00010000) /* Wakeup entry or exit opertation enable */ +#define BITM_ROM_SYSCTRL_WUA_DPMWRITE (0x00020000) /* When set indicates a restore of the PLL and DDR is to be performed otherwise a save is required */ +#define BITM_ROM_SYSCTRL_WUA_CGU (0x00040000) /* Only applicable for a PLL and DDR save operation to the DPM, saves the current settings if cleared or the contents of the structure if set */ +#define BITM_ROM_SYSCTRL_WUA_DDR (0x00080000) /* Only applicable for a PLL and DDR save operation to the DPM, saves the current settings if cleared or the contents of the structure if set */ +#define BITM_ROM_SYSCTRL_WUA_DDRDLLEN (0x00100000) /* Enables saving/restoring of the DDR DLLCTL register */ +#define BITM_ROM_SYSCTRL_WUA_OVERRIDE (0x01000000) +#define BITM_ROM_SYSCTRL_CGU_LOCKINGEN (0x10000000) /* Unlocks the CGU_CTL register */ + + +/* Structures for the syscontrol() function */ +struct STRUCT_ROM_SYSCTRL { + uint32_t ulCGU_CTL; + uint32_t ulCGU_STAT; + uint32_t ulCGU_DIV; + uint32_t ulCGU_CLKOUTSEL; + uint32_t ulWUA_Flags; + uint32_t ulWUA_BootAddr; + uint32_t ulWUA_User; + uint32_t ulDDR_CTL; + uint32_t ulDDR_CFG; + uint32_t ulDDR_TR0; + uint32_t ulDDR_TR1; + uint32_t ulDDR_TR2; + uint32_t ulDDR_MR; + uint32_t ulDDR_EMR1; + uint32_t ulDDR_EMR2; + uint32_t ulDDR_PADCTL; + uint32_t ulDDR_DLLCTL; + uint32_t ulReserved; +}; + +struct bfin_pm_data { + uint32_t magic; + uint32_t resume_addr; + uint32_t sp; +}; + +struct bfin_pm_data bf609_pm_data; + +struct STRUCT_ROM_SYSCTRL configvalues; +uint32_t dactionflags; + +#define FUNC_ROM_SYSCONTROL 0xC8000080 +__attribute__((l1_data)) +static uint32_t (* const bfrom_SysControl)(uint32_t action_flags, struct STRUCT_ROM_SYSCTRL *settings, void *reserved) = (void *)FUNC_ROM_SYSCONTROL; + +__attribute__((l1_text)) +void bfin_cpu_suspend(void) +{ + __asm__ __volatile__( \ + ".align 8;" \ + "idle;" \ + : : \ + ); +} + +__attribute__((l1_text)) +void bfin_deepsleep(unsigned long mask) +{ + uint32_t dpm0_ctl; + + bfin_write32(DPM0_WAKE_EN, 0x10); + bfin_write32(DPM0_WAKE_POL, 0x10); + dpm0_ctl = 0x00000008; + bfin_write32(DPM0_CTL, dpm0_ctl); + SSYNC(); + __asm__ __volatile__( \ + ".align 8;" \ + "idle;" \ + : : \ + ); +#ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH + __asm__ __volatile__( + "R0 = 0;" + "CYCLES = R0;" + "CYCLES2 = R0;" + "R0 = SYSCFG;" + "BITSET(R0, 1);" + "SYSCFG = R0;" + : : : "R0" + ); +#endif + +} + +__attribute__((l1_text)) +void bf609_ddr_sr(void) +{ + uint32_t reg; + + reg = bfin_read_DMC0_CTL(); + reg |= 0x8; + bfin_write_DMC0_CTL(reg); + + while (!(bfin_read_DMC0_STAT() & 0x8)) + continue; +} + +__attribute__((l1_text)) +void bf609_ddr_sr_exit(void) +{ + uint32_t reg; + while (!(bfin_read_DMC0_STAT() & 0x1)) + continue; + + reg = bfin_read_DMC0_CTL(); + reg &= ~0x8; + bfin_write_DMC0_CTL(reg); + + while ((bfin_read_DMC0_STAT() & 0x8)) + continue; +} + +__attribute__((l1_text)) +void bfin_hibernate_syscontrol(void) +{ + configvalues.ulWUA_Flags = (0xAD000000 | BITM_ROM_WUA_EN + | BITM_ROM_WUA_CGU | BITM_ROM_WUA_DDR | BITM_ROM_WUA_DDRDLLEN); + + dactionflags = (BITM_ROM_SYSCTRL_WUA_EN + | BITM_ROM_SYSCTRL_WUA_DPMWRITE | BITM_ROM_SYSCTRL_WUA_CGU + | BITM_ROM_SYSCTRL_WUA_DDR | BITM_ROM_SYSCTRL_WUA_DDRDLLEN); + + bfrom_SysControl(dactionflags, &configvalues, NULL); + + bfin_write32(DPM0_RESTORE5, bfin_read32(DPM0_RESTORE5) | 4); +} + +#ifndef CONFIG_BF60x +# define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) +#else +# define SIC_SYSIRQ(irq) ((irq) - IVG15) +#endif +void bfin_hibernate(unsigned long mask) +{ + bfin_write32(DPM0_WAKE_EN, 0x10); + bfin_write32(DPM0_WAKE_POL, 0x10); + bfin_write32(DPM0_PGCNTR, 0x0000FFFF); + bfin_write32(DPM0_HIB_DIS, 0xFFFF); + + printk(KERN_DEBUG "hibernate: restore %x pgcnt %x\n", bfin_read32(DPM0_RESTORE0), bfin_read32(DPM0_PGCNTR)); + + bf609_hibernate(); +} + +void bf609_cpu_pm_enter(suspend_state_t state) +{ + int error; + unsigned long wakeup = 0; + unsigned long wakeup_pol = 0; + +#ifdef CONFIG_PM_BFIN_WAKE_PA15 + wakeup |= PA15WE; +# if CONFIG_PM_BFIN_WAKE_PA15_POL + wakeup_pol |= PA15WE; +# endif +#endif + +#ifdef CONFIG_PM_BFIN_WAKE_PB15 + wakeup |= PB15WE; +# if CONFIG_PM_BFIN_WAKE_PA15_POL + wakeup_pol |= PB15WE; +# endif +#endif + +#ifdef CONFIG_PM_BFIN_WAKE_PC15 + wakeup |= PC15WE; +# if CONFIG_PM_BFIN_WAKE_PC15_POL + wakeup_pol |= PC15WE; +# endif +#endif + +#ifdef CONFIG_PM_BFIN_WAKE_PD06 + wakeup |= PD06WE; +# if CONFIG_PM_BFIN_WAKE_PD06_POL + wakeup_pol |= PD06WE; +# endif +#endif + +#ifdef CONFIG_PM_BFIN_WAKE_PE12 + wakeup |= PE12WE; +# if CONFIG_PM_BFIN_WAKE_PE12_POL + wakeup_pol |= PE12WE; +# endif +#endif + +#ifdef CONFIG_PM_BFIN_WAKE_PG04 + wakeup |= PG04WE; +# if CONFIG_PM_BFIN_WAKE_PG04_POL + wakeup_pol |= PG04WE; +# endif +#endif + +#ifdef CONFIG_PM_BFIN_WAKE_PG13 + wakeup |= PG13WE; +# if CONFIG_PM_BFIN_WAKE_PG13_POL + wakeup_pol |= PG13WE; +# endif +#endif + +#ifdef CONFIG_PM_BFIN_WAKE_USB + wakeup |= USBWE; +# if CONFIG_PM_BFIN_WAKE_USB_POL + wakeup_pol |= USBWE; +# endif +#endif + + error = irq_set_irq_wake(255, 1); + if(error < 0) + printk(KERN_DEBUG "Unable to get irq wake\n"); + error = irq_set_irq_wake(231, 1); + if (error < 0) + printk(KERN_DEBUG "Unable to get irq wake\n"); + + if (state == PM_SUSPEND_STANDBY) + bfin_deepsleep(wakeup); + else { + bfin_hibernate(wakeup); + } +} + +int bf609_cpu_pm_prepare(void) +{ + return 0; +} + +void bf609_cpu_pm_finish(void) +{ + +} + +static struct bfin_cpu_pm_fns bf609_cpu_pm = { + .enter = bf609_cpu_pm_enter, + .prepare = bf609_cpu_pm_prepare, + .finish = bf609_cpu_pm_finish, +}; + +static irqreturn_t test_isr(int irq, void *dev_id) +{ + printk(KERN_DEBUG "gpio irq %d\n", irq); + return IRQ_HANDLED; +} + +static irqreturn_t dpm0_isr(int irq, void *dev_id) +{ + uint32_t wake_stat; + + wake_stat = bfin_read32(DPM0_WAKE_STAT); + printk(KERN_DEBUG "enter %s wake stat %08x\n", __func__, wake_stat); + + bfin_write32(DPM0_WAKE_STAT, wake_stat); + return IRQ_HANDLED; +} + +static int __init bf609_init_pm(void) +{ + int irq; + int error; + +#if CONFIG_PM_BFIN_WAKE_PE12 + irq = gpio_to_irq(GPIO_PE12); + if (irq < 0) { + error = irq; + printk(KERN_DEBUG "Unable to get irq number for GPIO %d, error %d\n", + GPIO_PE12, error); + } + + error = request_irq(irq, test_isr, IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND, "gpiope12", NULL); + if(error < 0) + printk(KERN_DEBUG "Unable to get irq\n"); +#endif + + error = request_irq(IRQ_CGU_EVT, dpm0_isr, IRQF_NO_SUSPEND, "cgu0 event", NULL); + if(error < 0) + printk(KERN_DEBUG "Unable to get irq\n"); + + error = request_irq(IRQ_DPM, dpm0_isr, IRQF_NO_SUSPEND, "dpm0 event", NULL); + if (error < 0) + printk(KERN_DEBUG "Unable to get irq\n"); + + bfin_cpu_pm = &bf609_cpu_pm; + return 0; +} + +late_initcall(bf609_init_pm);
diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile index ff299f2..75f0ba2 100644 --- a/arch/blackfin/mach-common/Makefile +++ b/arch/blackfin/mach-common/Makefile
@@ -6,7 +6,10 @@ cache.o cache-c.o entry.o head.o \ interrupt.o arch_checks.o ints-priority.o -obj-$(CONFIG_PM) += pm.o dpmc_modes.o +obj-$(CONFIG_PM) += pm.o +ifneq ($(CONFIG_BF60x),y) +obj-$(CONFIG_PM) += dpmc_modes.o +endif obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/blackfin/mach-common/clock.h b/arch/blackfin/mach-common/clock.h new file mode 100644 index 0000000..645ff46 --- /dev/null +++ b/arch/blackfin/mach-common/clock.h
@@ -0,0 +1,27 @@ +#ifndef __MACH_COMMON_CLKDEV_H +#define __MACH_COMMON_CLKDEV_H + +#include <linux/clk.h> + +struct clk_ops { + unsigned long (*get_rate)(struct clk *clk); + unsigned long (*round_rate)(struct clk *clk, unsigned long rate); + int (*set_rate)(struct clk *clk, unsigned long rate); + int (*enable)(struct clk *clk); + int (*disable)(struct clk *clk); +}; + +struct clk { + const char *name; + unsigned long rate; + spinlock_t lock; + u32 flags; + const struct clk_ops *ops; + const struct params *params; + void __iomem *reg; + u32 mask; + u32 shift; +}; + +#endif +
diff --git a/arch/blackfin/mach-common/clocks-init.c b/arch/blackfin/mach-common/clocks-init.c index d5cfe61..7ad2407 100644 --- a/arch/blackfin/mach-common/clocks-init.c +++ b/arch/blackfin/mach-common/clocks-init.c
@@ -15,10 +15,121 @@ #include <asm/mem_init.h> #include <asm/dpmc.h> +#ifdef CONFIG_BF60x +#define CSEL_P 0 +#define S0SEL_P 5 +#define SYSSEL_P 8 +#define S1SEL_P 13 +#define DSEL_P 16 +#define OSEL_P 22 +#define ALGN_P 29 +#define UPDT_P 30 +#define LOCK_P 31 + +#define CGU_CTL_VAL ((CONFIG_VCO_MULT << 8) | CLKIN_HALF) +#define CGU_DIV_VAL \ + ((CONFIG_CCLK_DIV << CSEL_P) | \ + (CONFIG_SCLK_DIV << SYSSEL_P) | \ + (CONFIG_SCLK0_DIV << S0SEL_P) | \ + (CONFIG_SCLK1_DIV << S1SEL_P) | \ + (CONFIG_DCLK_DIV << DSEL_P)) + +#define CONFIG_BFIN_DCLK (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_DCLK_DIV) / 1000000) +#if ((CONFIG_BFIN_DCLK != 125) && \ + (CONFIG_BFIN_DCLK != 133) && (CONFIG_BFIN_DCLK != 150) && \ + (CONFIG_BFIN_DCLK != 166) && (CONFIG_BFIN_DCLK != 200) && \ + (CONFIG_BFIN_DCLK != 225) && (CONFIG_BFIN_DCLK != 250)) +#error "DCLK must be in (125, 133, 150, 166, 200, 225, 250)MHz" +#endif +struct ddr_config { + u32 ddr_clk; + u32 dmc_ddrctl; + u32 dmc_ddrcfg; + u32 dmc_ddrtr0; + u32 dmc_ddrtr1; + u32 dmc_ddrtr2; + u32 dmc_ddrmr; + u32 dmc_ddrmr1; +}; + +struct ddr_config ddr_config_table[] __attribute__((section(".data_l1"))) = { + [0] = { + .ddr_clk = 125, + .dmc_ddrctl = 0x00000904, + .dmc_ddrcfg = 0x00000422, + .dmc_ddrtr0 = 0x20705212, + .dmc_ddrtr1 = 0x201003CF, + .dmc_ddrtr2 = 0x00320107, + .dmc_ddrmr = 0x00000422, + .dmc_ddrmr1 = 0x4, + }, + [1] = { + .ddr_clk = 133, + .dmc_ddrctl = 0x00000904, + .dmc_ddrcfg = 0x00000422, + .dmc_ddrtr0 = 0x20806313, + .dmc_ddrtr1 = 0x2013040D, + .dmc_ddrtr2 = 0x00320108, + .dmc_ddrmr = 0x00000632, + .dmc_ddrmr1 = 0x4, + }, + [2] = { + .ddr_clk = 150, + .dmc_ddrctl = 0x00000904, + .dmc_ddrcfg = 0x00000422, + .dmc_ddrtr0 = 0x20A07323, + .dmc_ddrtr1 = 0x20160492, + .dmc_ddrtr2 = 0x00320209, + .dmc_ddrmr = 0x00000632, + .dmc_ddrmr1 = 0x4, + }, + [3] = { + .ddr_clk = 166, + .dmc_ddrctl = 0x00000904, + .dmc_ddrcfg = 0x00000422, + .dmc_ddrtr0 = 0x20A07323, + .dmc_ddrtr1 = 0x2016050E, + .dmc_ddrtr2 = 0x00320209, + .dmc_ddrmr = 0x00000632, + .dmc_ddrmr1 = 0x4, + }, + [4] = { + .ddr_clk = 200, + .dmc_ddrctl = 0x00000904, + .dmc_ddrcfg = 0x00000422, + .dmc_ddrtr0 = 0x20a07323, + .dmc_ddrtr1 = 0x2016050f, + .dmc_ddrtr2 = 0x00320509, + .dmc_ddrmr = 0x00000632, + .dmc_ddrmr1 = 0x4, + }, + [5] = { + .ddr_clk = 225, + .dmc_ddrctl = 0x00000904, + .dmc_ddrcfg = 0x00000422, + .dmc_ddrtr0 = 0x20E0A424, + .dmc_ddrtr1 = 0x302006DB, + .dmc_ddrtr2 = 0x0032020D, + .dmc_ddrmr = 0x00000842, + .dmc_ddrmr1 = 0x4, + }, + [6] = { + .ddr_clk = 250, + .dmc_ddrctl = 0x00000904, + .dmc_ddrcfg = 0x00000422, + .dmc_ddrtr0 = 0x20E0A424, + .dmc_ddrtr1 = 0x3020079E, + .dmc_ddrtr2 = 0x0032020D, + .dmc_ddrmr = 0x00000842, + .dmc_ddrmr1 = 0x4, + }, +}; +#else #define SDGCTL_WIDTH (1 << 31) /* SDRAM external data path width */ #define PLL_CTL_VAL \ (((CONFIG_VCO_MULT & 63) << 9) | CLKIN_HALF | \ - (PLL_BYPASS << 8) | (ANOMALY_05000305 ? 0 : 0x8000)) + (PLL_BYPASS << 8) | (ANOMALY_05000305 ? 0 : 0x8000)) +#endif __attribute__((l1_text)) static void do_sync(void) @@ -33,6 +144,44 @@ * in the middle of reprogramming things, and that'll screw us up. * For example, any automatic DMAs left by U-Boot for splash screens. */ + +#ifdef CONFIG_BF60x + int i, dlldatacycle, dll_ctl; + bfin_write32(CGU0_DIV, CGU_DIV_VAL); + bfin_write32(CGU0_CTL, CGU_CTL_VAL); + while ((bfin_read32(CGU0_STAT) & 0x8) || !(bfin_read32(CGU0_STAT) & 0x4)) + continue; + + bfin_write32(CGU0_DIV, CGU_DIV_VAL | (1 << UPDT_P)); + while (bfin_read32(CGU0_STAT) & (1 << 3)) + continue; + + for (i = 0; i < 7; i++) { + if (ddr_config_table[i].ddr_clk == CONFIG_BFIN_DCLK) { + bfin_write_DDR0_CFG(ddr_config_table[i].dmc_ddrcfg); + bfin_write_DDR0_TR0(ddr_config_table[i].dmc_ddrtr0); + bfin_write_DDR0_TR1(ddr_config_table[i].dmc_ddrtr1); + bfin_write_DDR0_TR2(ddr_config_table[i].dmc_ddrtr2); + bfin_write_DDR0_MR(ddr_config_table[i].dmc_ddrmr); + bfin_write_DDR0_EMR1(ddr_config_table[i].dmc_ddrmr1); + bfin_write_DDR0_CTL(ddr_config_table[i].dmc_ddrctl); + break; + } + } + + do_sync(); + while (!(bfin_read_DDR0_STAT() & 0x4)) + continue; + + dlldatacycle = (bfin_read_DDR0_STAT() & 0x00f00000) >> 20; + dll_ctl = bfin_read_DDR0_DLLCTL(); + dll_ctl &= 0x0ff; + bfin_write_DDR0_DLLCTL(dll_ctl | (dlldatacycle << 8)); + + do_sync(); + while (!(bfin_read_DDR0_STAT() & 0x2000)) + continue; +#else size_t i; for (i = 0; i < MAX_DMA_CHANNELS; ++i) { struct dma_register *dma = dma_io_base_addr[i]; @@ -91,6 +240,8 @@ bfin_write_EBIU_DDRQUE(CONFIG_MEM_EBIU_DDRQUE); #endif #endif +#endif do_sync(); bfin_read16(0); + }
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c index 2e6eefd..6e87dc1 100644 --- a/arch/blackfin/mach-common/cpufreq.c +++ b/arch/blackfin/mach-common/cpufreq.c
@@ -10,6 +10,7 @@ #include <linux/module.h> #include <linux/types.h> #include <linux/init.h> +#include <linux/clk.h> #include <linux/cpufreq.h> #include <linux/fs.h> #include <linux/delay.h> @@ -17,6 +18,7 @@ #include <asm/time.h> #include <asm/dpmc.h> + /* this is the table of CCLK frequencies, in Hz */ /* .index is the entry in the auxiliary dpm_state_table[] */ static struct cpufreq_frequency_table bfin_freq_table[] = { @@ -67,12 +69,22 @@ #else min_cclk = sclk; #endif + +#ifndef CONFIG_BF60x csel = ((bfin_read_PLL_DIV() & CSEL) >> 4); +#else + csel = bfin_read32(CGU0_DIV) & 0x1F; +#endif for (index = 0; (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) { bfin_freq_table[index].frequency = cclk >> index; +#ifndef CONFIG_BF60x dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */ dpm_state_table[index].tscale = (TIME_SCALE / (1 << csel)) - 1; +#else + dpm_state_table[index].csel = csel; + dpm_state_table[index].tscale = TIME_SCALE >> index; +#endif pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n", bfin_freq_table[index].frequency, @@ -99,14 +111,34 @@ return get_cclk() / 1000; } +#ifdef CONFIG_BF60x +unsigned long cpu_set_cclk(int cpu, unsigned long new) +{ + struct clk *clk; + int ret; + + clk = clk_get(NULL, "CCLK"); + if (IS_ERR(clk)) + return -ENODEV; + + ret = clk_set_rate(clk, new); + clk_put(clk); + return ret; +} +#endif + static int bfin_target(struct cpufreq_policy *poli, unsigned int target_freq, unsigned int relation) { - unsigned int index, plldiv, cpu; +#ifndef CONFIG_BF60x + unsigned int plldiv; +#endif + unsigned int index, cpu; unsigned long flags, cclk_hz; struct cpufreq_freqs freqs; static unsigned long lpj_ref; static unsigned int lpj_ref_freq; + int ret = 0; #if defined(CONFIG_CYCLES_CLOCKSOURCE) cycles_t cycles; @@ -134,9 +166,17 @@ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); if (cpu == CPUFREQ_CPU) { flags = hard_local_irq_save(); +#ifndef CONFIG_BF60x plldiv = (bfin_read_PLL_DIV() & SSEL) | dpm_state_table[index].csel; bfin_write_PLL_DIV(plldiv); +#else + ret = cpu_set_cclk(cpu, freqs.new * 1000); + if (ret != 0) { + pr_debug("cpufreq set freq failed %d\n", ret); + break; + } +#endif on_each_cpu(bfin_adjust_core_timer, &index, 1); #if defined(CONFIG_CYCLES_CLOCKSOURCE) cycles = get_cycles(); @@ -161,7 +201,7 @@ } pr_debug("cpufreq: done\n"); - return 0; + return ret; } static int bfin_verify_speed(struct cpufreq_policy *policy) @@ -169,7 +209,7 @@ return cpufreq_frequency_table_verify(policy, bfin_freq_table); } -static int __init __bfin_cpu_init(struct cpufreq_policy *policy) +static int __bfin_cpu_init(struct cpufreq_policy *policy) { unsigned long cclk, sclk;
diff --git a/arch/blackfin/mach-common/dpmc_modes.S b/arch/blackfin/mach-common/dpmc_modes.S index 1c534d2..de99f3a 100644 --- a/arch/blackfin/mach-common/dpmc_modes.S +++ b/arch/blackfin/mach-common/dpmc_modes.S
@@ -10,7 +10,6 @@ #include <asm/dpmc.h> .section .l1.text - ENTRY(_sleep_mode) [--SP] = (R7:4, P5:3); [--SP] = RETS; @@ -43,6 +42,9 @@ BITCLR (R7, 5); w[p0] = R7.L; IDLE; + + bfin_init_pm_bench_cycles; + call _test_pll_locked; RETS = [SP++]; @@ -58,12 +60,13 @@ * * We accept just one argument -- the value to write to VR_CTL. */ + ENTRY(_hibernate_mode) /* Save/setup the regs we need early for minor pipeline optimization */ R4 = R0; + P3.H = hi(VR_CTL); P3.L = lo(VR_CTL); - /* Disable all wakeup sources */ R0 = IWR_DISABLE_ALL; R1 = IWR_DISABLE_ALL; @@ -74,6 +77,9 @@ /* Finally, we climb into our cave to hibernate */ W[P3] = R4.L; + + bfin_init_pm_bench_cycles; + CLI R2; IDLE; .Lforever: @@ -158,6 +164,8 @@ SSYNC; IDLE; + bfin_init_pm_bench_cycles; + call _test_pll_locked; P0.H = hi(PLL_DIV); @@ -276,327 +284,10 @@ ENDPROC(_test_pll_locked) .section .text - -#define PM_REG0 R7 -#define PM_REG1 R6 -#define PM_REG2 R5 -#define PM_REG3 R4 -#define PM_REG4 R3 -#define PM_REG5 R2 -#define PM_REG6 R1 -#define PM_REG7 R0 -#define PM_REG8 P5 -#define PM_REG9 P4 -#define PM_REG10 P3 -#define PM_REG11 P2 -#define PM_REG12 P1 -#define PM_REG13 P0 - -#define PM_REGSET0 R7:7 -#define PM_REGSET1 R7:6 -#define PM_REGSET2 R7:5 -#define PM_REGSET3 R7:4 -#define PM_REGSET4 R7:3 -#define PM_REGSET5 R7:2 -#define PM_REGSET6 R7:1 -#define PM_REGSET7 R7:0 -#define PM_REGSET8 R7:0, P5:5 -#define PM_REGSET9 R7:0, P5:4 -#define PM_REGSET10 R7:0, P5:3 -#define PM_REGSET11 R7:0, P5:2 -#define PM_REGSET12 R7:0, P5:1 -#define PM_REGSET13 R7:0, P5:0 - -#define _PM_PUSH(n, x, w, base) PM_REG##n = w[FP + ((x) - (base))]; -#define _PM_POP(n, x, w, base) w[FP + ((x) - (base))] = PM_REG##n; -#define PM_PUSH_SYNC(n) [--sp] = (PM_REGSET##n); -#define PM_POP_SYNC(n) (PM_REGSET##n) = [sp++]; -#define PM_PUSH(n, x) PM_REG##n = [FP++]; -#define PM_POP(n, x) [FP--] = PM_REG##n; -#define PM_CORE_PUSH(n, x) _PM_PUSH(n, x, , COREMMR_BASE) -#define PM_CORE_POP(n, x) _PM_POP(n, x, , COREMMR_BASE) -#define PM_SYS_PUSH(n, x) _PM_PUSH(n, x, , SYSMMR_BASE) -#define PM_SYS_POP(n, x) _PM_POP(n, x, , SYSMMR_BASE) -#define PM_SYS_PUSH16(n, x) _PM_PUSH(n, x, w, SYSMMR_BASE) -#define PM_SYS_POP16(n, x) _PM_POP(n, x, w, SYSMMR_BASE) - ENTRY(_do_hibernate) - /* - * Save the core regs early so we can blow them away when - * saving/restoring MMR states - */ - [--sp] = (R7:0, P5:0); - [--sp] = fp; - [--sp] = usp; - - [--sp] = i0; - [--sp] = i1; - [--sp] = i2; - [--sp] = i3; - - [--sp] = m0; - [--sp] = m1; - [--sp] = m2; - [--sp] = m3; - - [--sp] = l0; - [--sp] = l1; - [--sp] = l2; - [--sp] = l3; - - [--sp] = b0; - [--sp] = b1; - [--sp] = b2; - [--sp] = b3; - [--sp] = a0.x; - [--sp] = a0.w; - [--sp] = a1.x; - [--sp] = a1.w; - - [--sp] = LC0; - [--sp] = LC1; - [--sp] = LT0; - [--sp] = LT1; - [--sp] = LB0; - [--sp] = LB1; - - /* We can't push RETI directly as that'll change IPEND[4] */ - r7 = RETI; - [--sp] = RETS; - [--sp] = ASTAT; - [--sp] = CYCLES; - [--sp] = CYCLES2; - [--sp] = SYSCFG; - [--sp] = RETX; - [--sp] = SEQSTAT; - [--sp] = r7; - - /* Save first func arg in M3 */ - M3 = R0; - - /* Save system MMRs */ - FP.H = hi(SYSMMR_BASE); - FP.L = lo(SYSMMR_BASE); - -#ifdef SIC_IMASK0 - PM_SYS_PUSH(0, SIC_IMASK0) - PM_SYS_PUSH(1, SIC_IMASK1) -# ifdef SIC_IMASK2 - PM_SYS_PUSH(2, SIC_IMASK2) -# endif -#else - PM_SYS_PUSH(0, SIC_IMASK) -#endif -#ifdef SIC_IAR0 - PM_SYS_PUSH(3, SIC_IAR0) - PM_SYS_PUSH(4, SIC_IAR1) - PM_SYS_PUSH(5, SIC_IAR2) -#endif -#ifdef SIC_IAR3 - PM_SYS_PUSH(6, SIC_IAR3) -#endif -#ifdef SIC_IAR4 - PM_SYS_PUSH(7, SIC_IAR4) - PM_SYS_PUSH(8, SIC_IAR5) - PM_SYS_PUSH(9, SIC_IAR6) -#endif -#ifdef SIC_IAR7 - PM_SYS_PUSH(10, SIC_IAR7) -#endif -#ifdef SIC_IAR8 - PM_SYS_PUSH(11, SIC_IAR8) - PM_SYS_PUSH(12, SIC_IAR9) - PM_SYS_PUSH(13, SIC_IAR10) -#endif - PM_PUSH_SYNC(13) -#ifdef SIC_IAR11 - PM_SYS_PUSH(0, SIC_IAR11) -#endif - -#ifdef SIC_IWR - PM_SYS_PUSH(1, SIC_IWR) -#endif -#ifdef SIC_IWR0 - PM_SYS_PUSH(1, SIC_IWR0) -#endif -#ifdef SIC_IWR1 - PM_SYS_PUSH(2, SIC_IWR1) -#endif -#ifdef SIC_IWR2 - PM_SYS_PUSH(3, SIC_IWR2) -#endif - -#ifdef PINT0_ASSIGN - PM_SYS_PUSH(4, PINT0_MASK_SET) - PM_SYS_PUSH(5, PINT1_MASK_SET) - PM_SYS_PUSH(6, PINT2_MASK_SET) - PM_SYS_PUSH(7, PINT3_MASK_SET) - PM_SYS_PUSH(8, PINT0_ASSIGN) - PM_SYS_PUSH(9, PINT1_ASSIGN) - PM_SYS_PUSH(10, PINT2_ASSIGN) - PM_SYS_PUSH(11, PINT3_ASSIGN) - PM_SYS_PUSH(12, PINT0_INVERT_SET) - PM_SYS_PUSH(13, PINT1_INVERT_SET) - PM_PUSH_SYNC(13) - PM_SYS_PUSH(0, PINT2_INVERT_SET) - PM_SYS_PUSH(1, PINT3_INVERT_SET) - PM_SYS_PUSH(2, PINT0_EDGE_SET) - PM_SYS_PUSH(3, PINT1_EDGE_SET) - PM_SYS_PUSH(4, PINT2_EDGE_SET) - PM_SYS_PUSH(5, PINT3_EDGE_SET) -#endif - - PM_SYS_PUSH16(6, SYSCR) - - PM_SYS_PUSH16(7, EBIU_AMGCTL) - PM_SYS_PUSH(8, EBIU_AMBCTL0) - PM_SYS_PUSH(9, EBIU_AMBCTL1) -#ifdef EBIU_FCTL - PM_SYS_PUSH(10, EBIU_MBSCTL) - PM_SYS_PUSH(11, EBIU_MODE) - PM_SYS_PUSH(12, EBIU_FCTL) - PM_PUSH_SYNC(12) -#else - PM_PUSH_SYNC(9) -#endif - - /* Save Core MMRs */ - I0.H = hi(COREMMR_BASE); - I0.L = lo(COREMMR_BASE); - I1 = I0; - I2 = I0; - I3 = I0; - B0 = I0; - B1 = I0; - B2 = I0; - B3 = I0; - I1.L = lo(DCPLB_ADDR0); - I2.L = lo(DCPLB_DATA0); - I3.L = lo(ICPLB_ADDR0); - B0.L = lo(ICPLB_DATA0); - B1.L = lo(EVT2); - B2.L = lo(IMASK); - B3.L = lo(TCNTL); - - /* DCPLB Addr */ - FP = I1; - PM_PUSH(0, DCPLB_ADDR0) - PM_PUSH(1, DCPLB_ADDR1) - PM_PUSH(2, DCPLB_ADDR2) - PM_PUSH(3, DCPLB_ADDR3) - PM_PUSH(4, DCPLB_ADDR4) - PM_PUSH(5, DCPLB_ADDR5) - PM_PUSH(6, DCPLB_ADDR6) - PM_PUSH(7, DCPLB_ADDR7) - PM_PUSH(8, DCPLB_ADDR8) - PM_PUSH(9, DCPLB_ADDR9) - PM_PUSH(10, DCPLB_ADDR10) - PM_PUSH(11, DCPLB_ADDR11) - PM_PUSH(12, DCPLB_ADDR12) - PM_PUSH(13, DCPLB_ADDR13) - PM_PUSH_SYNC(13) - PM_PUSH(0, DCPLB_ADDR14) - PM_PUSH(1, DCPLB_ADDR15) - - /* DCPLB Data */ - FP = I2; - PM_PUSH(2, DCPLB_DATA0) - PM_PUSH(3, DCPLB_DATA1) - PM_PUSH(4, DCPLB_DATA2) - PM_PUSH(5, DCPLB_DATA3) - PM_PUSH(6, DCPLB_DATA4) - PM_PUSH(7, DCPLB_DATA5) - PM_PUSH(8, DCPLB_DATA6) - PM_PUSH(9, DCPLB_DATA7) - PM_PUSH(10, DCPLB_DATA8) - PM_PUSH(11, DCPLB_DATA9) - PM_PUSH(12, DCPLB_DATA10) - PM_PUSH(13, DCPLB_DATA11) - PM_PUSH_SYNC(13) - PM_PUSH(0, DCPLB_DATA12) - PM_PUSH(1, DCPLB_DATA13) - PM_PUSH(2, DCPLB_DATA14) - PM_PUSH(3, DCPLB_DATA15) - - /* ICPLB Addr */ - FP = I3; - PM_PUSH(4, ICPLB_ADDR0) - PM_PUSH(5, ICPLB_ADDR1) - PM_PUSH(6, ICPLB_ADDR2) - PM_PUSH(7, ICPLB_ADDR3) - PM_PUSH(8, ICPLB_ADDR4) - PM_PUSH(9, ICPLB_ADDR5) - PM_PUSH(10, ICPLB_ADDR6) - PM_PUSH(11, ICPLB_ADDR7) - PM_PUSH(12, ICPLB_ADDR8) - PM_PUSH(13, ICPLB_ADDR9) - PM_PUSH_SYNC(13) - PM_PUSH(0, ICPLB_ADDR10) - PM_PUSH(1, ICPLB_ADDR11) - PM_PUSH(2, ICPLB_ADDR12) - PM_PUSH(3, ICPLB_ADDR13) - PM_PUSH(4, ICPLB_ADDR14) - PM_PUSH(5, ICPLB_ADDR15) - - /* ICPLB Data */ - FP = B0; - PM_PUSH(6, ICPLB_DATA0) - PM_PUSH(7, ICPLB_DATA1) - PM_PUSH(8, ICPLB_DATA2) - PM_PUSH(9, ICPLB_DATA3) - PM_PUSH(10, ICPLB_DATA4) - PM_PUSH(11, ICPLB_DATA5) - PM_PUSH(12, ICPLB_DATA6) - PM_PUSH(13, ICPLB_DATA7) - PM_PUSH_SYNC(13) - PM_PUSH(0, ICPLB_DATA8) - PM_PUSH(1, ICPLB_DATA9) - PM_PUSH(2, ICPLB_DATA10) - PM_PUSH(3, ICPLB_DATA11) - PM_PUSH(4, ICPLB_DATA12) - PM_PUSH(5, ICPLB_DATA13) - PM_PUSH(6, ICPLB_DATA14) - PM_PUSH(7, ICPLB_DATA15) - - /* Event Vectors */ - FP = B1; - PM_PUSH(8, EVT2) - PM_PUSH(9, EVT3) - FP += 4; /* EVT4 */ - PM_PUSH(10, EVT5) - PM_PUSH(11, EVT6) - PM_PUSH(12, EVT7) - PM_PUSH(13, EVT8) - PM_PUSH_SYNC(13) - PM_PUSH(0, EVT9) - PM_PUSH(1, EVT10) - PM_PUSH(2, EVT11) - PM_PUSH(3, EVT12) - PM_PUSH(4, EVT13) - PM_PUSH(5, EVT14) - PM_PUSH(6, EVT15) - - /* CEC */ - FP = B2; - PM_PUSH(7, IMASK) - FP += 4; /* IPEND */ - PM_PUSH(8, ILAT) - PM_PUSH(9, IPRIO) - - /* Core Timer */ - FP = B3; - PM_PUSH(10, TCNTL) - PM_PUSH(11, TPERIOD) - PM_PUSH(12, TSCALE) - PM_PUSH(13, TCOUNT) - PM_PUSH_SYNC(13) - - /* Misc non-contiguous registers */ - FP = I0; - PM_CORE_PUSH(0, DMEM_CONTROL); - PM_CORE_PUSH(1, IMEM_CONTROL); - PM_CORE_PUSH(2, TBUFCTL); - PM_PUSH_SYNC(2) + bfin_cpu_reg_save; + bfin_sys_mmr_save; + bfin_core_mmr_save; /* Setup args to hibernate mode early for pipeline optimization */ R0 = M3; @@ -618,274 +309,9 @@ .Lpm_resume_here: - /* Restore Core MMRs */ - I0.H = hi(COREMMR_BASE); - I0.L = lo(COREMMR_BASE); - I1 = I0; - I2 = I0; - I3 = I0; - B0 = I0; - B1 = I0; - B2 = I0; - B3 = I0; - I1.L = lo(DCPLB_ADDR15); - I2.L = lo(DCPLB_DATA15); - I3.L = lo(ICPLB_ADDR15); - B0.L = lo(ICPLB_DATA15); - B1.L = lo(EVT15); - B2.L = lo(IPRIO); - B3.L = lo(TCOUNT); - - /* Misc non-contiguous registers */ - FP = I0; - PM_POP_SYNC(2) - PM_CORE_POP(2, TBUFCTL) - PM_CORE_POP(1, IMEM_CONTROL) - PM_CORE_POP(0, DMEM_CONTROL) - - /* Core Timer */ - PM_POP_SYNC(13) - FP = B3; - PM_POP(13, TCOUNT) - PM_POP(12, TSCALE) - PM_POP(11, TPERIOD) - PM_POP(10, TCNTL) - - /* CEC */ - FP = B2; - PM_POP(9, IPRIO) - PM_POP(8, ILAT) - FP += -4; /* IPEND */ - PM_POP(7, IMASK) - - /* Event Vectors */ - FP = B1; - PM_POP(6, EVT15) - PM_POP(5, EVT14) - PM_POP(4, EVT13) - PM_POP(3, EVT12) - PM_POP(2, EVT11) - PM_POP(1, EVT10) - PM_POP(0, EVT9) - PM_POP_SYNC(13) - PM_POP(13, EVT8) - PM_POP(12, EVT7) - PM_POP(11, EVT6) - PM_POP(10, EVT5) - FP += -4; /* EVT4 */ - PM_POP(9, EVT3) - PM_POP(8, EVT2) - - /* ICPLB Data */ - FP = B0; - PM_POP(7, ICPLB_DATA15) - PM_POP(6, ICPLB_DATA14) - PM_POP(5, ICPLB_DATA13) - PM_POP(4, ICPLB_DATA12) - PM_POP(3, ICPLB_DATA11) - PM_POP(2, ICPLB_DATA10) - PM_POP(1, ICPLB_DATA9) - PM_POP(0, ICPLB_DATA8) - PM_POP_SYNC(13) - PM_POP(13, ICPLB_DATA7) - PM_POP(12, ICPLB_DATA6) - PM_POP(11, ICPLB_DATA5) - PM_POP(10, ICPLB_DATA4) - PM_POP(9, ICPLB_DATA3) - PM_POP(8, ICPLB_DATA2) - PM_POP(7, ICPLB_DATA1) - PM_POP(6, ICPLB_DATA0) - - /* ICPLB Addr */ - FP = I3; - PM_POP(5, ICPLB_ADDR15) - PM_POP(4, ICPLB_ADDR14) - PM_POP(3, ICPLB_ADDR13) - PM_POP(2, ICPLB_ADDR12) - PM_POP(1, ICPLB_ADDR11) - PM_POP(0, ICPLB_ADDR10) - PM_POP_SYNC(13) - PM_POP(13, ICPLB_ADDR9) - PM_POP(12, ICPLB_ADDR8) - PM_POP(11, ICPLB_ADDR7) - PM_POP(10, ICPLB_ADDR6) - PM_POP(9, ICPLB_ADDR5) - PM_POP(8, ICPLB_ADDR4) - PM_POP(7, ICPLB_ADDR3) - PM_POP(6, ICPLB_ADDR2) - PM_POP(5, ICPLB_ADDR1) - PM_POP(4, ICPLB_ADDR0) - - /* DCPLB Data */ - FP = I2; - PM_POP(3, DCPLB_DATA15) - PM_POP(2, DCPLB_DATA14) - PM_POP(1, DCPLB_DATA13) - PM_POP(0, DCPLB_DATA12) - PM_POP_SYNC(13) - PM_POP(13, DCPLB_DATA11) - PM_POP(12, DCPLB_DATA10) - PM_POP(11, DCPLB_DATA9) - PM_POP(10, DCPLB_DATA8) - PM_POP(9, DCPLB_DATA7) - PM_POP(8, DCPLB_DATA6) - PM_POP(7, DCPLB_DATA5) - PM_POP(6, DCPLB_DATA4) - PM_POP(5, DCPLB_DATA3) - PM_POP(4, DCPLB_DATA2) - PM_POP(3, DCPLB_DATA1) - PM_POP(2, DCPLB_DATA0) - - /* DCPLB Addr */ - FP = I1; - PM_POP(1, DCPLB_ADDR15) - PM_POP(0, DCPLB_ADDR14) - PM_POP_SYNC(13) - PM_POP(13, DCPLB_ADDR13) - PM_POP(12, DCPLB_ADDR12) - PM_POP(11, DCPLB_ADDR11) - PM_POP(10, DCPLB_ADDR10) - PM_POP(9, DCPLB_ADDR9) - PM_POP(8, DCPLB_ADDR8) - PM_POP(7, DCPLB_ADDR7) - PM_POP(6, DCPLB_ADDR6) - PM_POP(5, DCPLB_ADDR5) - PM_POP(4, DCPLB_ADDR4) - PM_POP(3, DCPLB_ADDR3) - PM_POP(2, DCPLB_ADDR2) - PM_POP(1, DCPLB_ADDR1) - PM_POP(0, DCPLB_ADDR0) - - /* Restore System MMRs */ - FP.H = hi(SYSMMR_BASE); - FP.L = lo(SYSMMR_BASE); - -#ifdef EBIU_FCTL - PM_POP_SYNC(12) - PM_SYS_POP(12, EBIU_FCTL) - PM_SYS_POP(11, EBIU_MODE) - PM_SYS_POP(10, EBIU_MBSCTL) -#else - PM_POP_SYNC(9) -#endif - PM_SYS_POP(9, EBIU_AMBCTL1) - PM_SYS_POP(8, EBIU_AMBCTL0) - PM_SYS_POP16(7, EBIU_AMGCTL) - - PM_SYS_POP16(6, SYSCR) - -#ifdef PINT0_ASSIGN - PM_SYS_POP(5, PINT3_EDGE_SET) - PM_SYS_POP(4, PINT2_EDGE_SET) - PM_SYS_POP(3, PINT1_EDGE_SET) - PM_SYS_POP(2, PINT0_EDGE_SET) - PM_SYS_POP(1, PINT3_INVERT_SET) - PM_SYS_POP(0, PINT2_INVERT_SET) - PM_POP_SYNC(13) - PM_SYS_POP(13, PINT1_INVERT_SET) - PM_SYS_POP(12, PINT0_INVERT_SET) - PM_SYS_POP(11, PINT3_ASSIGN) - PM_SYS_POP(10, PINT2_ASSIGN) - PM_SYS_POP(9, PINT1_ASSIGN) - PM_SYS_POP(8, PINT0_ASSIGN) - PM_SYS_POP(7, PINT3_MASK_SET) - PM_SYS_POP(6, PINT2_MASK_SET) - PM_SYS_POP(5, PINT1_MASK_SET) - PM_SYS_POP(4, PINT0_MASK_SET) -#endif - -#ifdef SIC_IWR2 - PM_SYS_POP(3, SIC_IWR2) -#endif -#ifdef SIC_IWR1 - PM_SYS_POP(2, SIC_IWR1) -#endif -#ifdef SIC_IWR0 - PM_SYS_POP(1, SIC_IWR0) -#endif -#ifdef SIC_IWR - PM_SYS_POP(1, SIC_IWR) -#endif - -#ifdef SIC_IAR11 - PM_SYS_POP(0, SIC_IAR11) -#endif - PM_POP_SYNC(13) -#ifdef SIC_IAR8 - PM_SYS_POP(13, SIC_IAR10) - PM_SYS_POP(12, SIC_IAR9) - PM_SYS_POP(11, SIC_IAR8) -#endif -#ifdef SIC_IAR7 - PM_SYS_POP(10, SIC_IAR7) -#endif -#ifdef SIC_IAR6 - PM_SYS_POP(9, SIC_IAR6) - PM_SYS_POP(8, SIC_IAR5) - PM_SYS_POP(7, SIC_IAR4) -#endif -#ifdef SIC_IAR3 - PM_SYS_POP(6, SIC_IAR3) -#endif -#ifdef SIC_IAR0 - PM_SYS_POP(5, SIC_IAR2) - PM_SYS_POP(4, SIC_IAR1) - PM_SYS_POP(3, SIC_IAR0) -#endif -#ifdef SIC_IMASK0 -# ifdef SIC_IMASK2 - PM_SYS_POP(2, SIC_IMASK2) -# endif - PM_SYS_POP(1, SIC_IMASK1) - PM_SYS_POP(0, SIC_IMASK0) -#else - PM_SYS_POP(0, SIC_IMASK) -#endif - - /* Restore Core Registers */ - RETI = [sp++]; - SEQSTAT = [sp++]; - RETX = [sp++]; - SYSCFG = [sp++]; - CYCLES2 = [sp++]; - CYCLES = [sp++]; - ASTAT = [sp++]; - RETS = [sp++]; - - LB1 = [sp++]; - LB0 = [sp++]; - LT1 = [sp++]; - LT0 = [sp++]; - LC1 = [sp++]; - LC0 = [sp++]; - - a1.w = [sp++]; - a1.x = [sp++]; - a0.w = [sp++]; - a0.x = [sp++]; - b3 = [sp++]; - b2 = [sp++]; - b1 = [sp++]; - b0 = [sp++]; - - l3 = [sp++]; - l2 = [sp++]; - l1 = [sp++]; - l0 = [sp++]; - - m3 = [sp++]; - m2 = [sp++]; - m1 = [sp++]; - m0 = [sp++]; - - i3 = [sp++]; - i2 = [sp++]; - i1 = [sp++]; - i0 = [sp++]; - - usp = [sp++]; - fp = [sp++]; - (R7:0, P5:0) = [sp++]; + bfin_core_mmr_restore; + bfin_sys_mmr_restore; + bfin_cpu_reg_restore; [--sp] = RETI; /* Clear Global Interrupt Disable */ SP += 4;
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 4698a98..80aa253 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S
@@ -1141,7 +1141,8 @@ sti r0; /* finish the userspace "atomic" functions for it */ - r1 = FIXED_CODE_END; + r1.l = lo(FIXED_CODE_END); + r1.h = hi(FIXED_CODE_END); r2 = [sp + PT_PC]; cc = r1 <= r2; if cc jump .Lresume_userspace (bp); @@ -1376,7 +1377,7 @@ ENTRY(_sys_call_table) .long _sys_restart_syscall /* 0 */ .long _sys_exit - .long _sys_fork + .long _sys_ni_syscall /* fork */ .long _sys_read .long _sys_write .long _sys_open /* 5 */
diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S index 8b4d988..31515f0 100644 --- a/arch/blackfin/mach-common/head.S +++ b/arch/blackfin/mach-common/head.S
@@ -210,14 +210,12 @@ ENTRY(_real_start) /* Enable nested interrupts */ [--sp] = reti; - /* watchdog off for now */ p0.l = lo(WDOG_CTL); p0.h = hi(WDOG_CTL); r0 = 0xAD6(z); w[p0] = r0; ssync; - /* Pass the u-boot arguments to the global value command line */ R0 = R7; call _cmdline_init;
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 332dace..2729cba 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c
@@ -16,6 +16,8 @@ #include <linux/seq_file.h> #include <linux/irq.h> #include <linux/sched.h> +#include <linux/syscore_ops.h> +#include <asm/delay.h> #ifdef CONFIG_IPIPE #include <linux/ipipe.h> #endif @@ -25,7 +27,11 @@ #include <asm/irq_handler.h> #include <asm/dpmc.h> -#define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) +#ifndef CONFIG_BF60x +# define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) +#else +# define SIC_SYSIRQ(irq) ((irq) - IVG15) +#endif /* * NOTES: @@ -50,6 +56,7 @@ unsigned vr_wakeup; #endif +#ifndef CONFIG_BF60x static struct ivgx { /* irq number for request_irq, available in mach-bf5xx/irq.h */ unsigned int irqno; @@ -78,7 +85,8 @@ for (irqN = 0; irqN < NR_PERI_INTS; irqN += 4) { int irqn; - u32 iar = bfin_read32((unsigned long *)SIC_IAR0 + + u32 iar = + bfin_read32((unsigned long *)SIC_IAR0 + #if defined(CONFIG_BF51x) || defined(CONFIG_BF52x) || \ defined(CONFIG_BF538) || defined(CONFIG_BF539) ((irqN % 32) >> 3) + ((irqN / 32) * ((SIC_IAR4 - SIC_IAR0) / 4)) @@ -86,7 +94,6 @@ (irqN >> 3) #endif ); - for (irqn = irqN; irqn < irqN + 4; ++irqn) { int iar_shift = (irqn & 7) * 4; if (ivg == (0xf & (iar >> iar_shift))) { @@ -99,11 +106,11 @@ } } } +#endif /* * This is for core internal IRQs */ - void bfin_ack_noop(struct irq_data *d) { /* Dummy function. */ @@ -136,21 +143,21 @@ void bfin_internal_mask_irq(unsigned int irq) { unsigned long flags = hard_local_irq_save(); - +#ifndef CONFIG_BF60x #ifdef SIC_IMASK0 unsigned mask_bank = SIC_SYSIRQ(irq) / 32; unsigned mask_bit = SIC_SYSIRQ(irq) % 32; bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & - ~(1 << mask_bit)); -# ifdef CONFIG_SMP + ~(1 << mask_bit)); +# if defined(CONFIG_SMP) || defined(CONFIG_ICC) bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) & - ~(1 << mask_bit)); + ~(1 << mask_bit)); # endif #else bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & - ~(1 << SIC_SYSIRQ(irq))); + ~(1 << SIC_SYSIRQ(irq))); +#endif /* end of SIC_IMASK0 */ #endif - hard_local_irq_restore(flags); } @@ -160,7 +167,7 @@ } #ifdef CONFIG_SMP -static void bfin_internal_unmask_irq_affinity(unsigned int irq, +void bfin_internal_unmask_irq_affinity(unsigned int irq, const struct cpumask *affinity) #else void bfin_internal_unmask_irq(unsigned int irq) @@ -168,6 +175,7 @@ { unsigned long flags = hard_local_irq_save(); +#ifndef CONFIG_BF60x #ifdef SIC_IMASK0 unsigned mask_bank = SIC_SYSIRQ(irq) / 32; unsigned mask_bit = SIC_SYSIRQ(irq) % 32; @@ -175,22 +183,239 @@ if (cpumask_test_cpu(0, affinity)) # endif bfin_write_SIC_IMASK(mask_bank, - bfin_read_SIC_IMASK(mask_bank) | - (1 << mask_bit)); + bfin_read_SIC_IMASK(mask_bank) | + (1 << mask_bit)); # ifdef CONFIG_SMP if (cpumask_test_cpu(1, affinity)) bfin_write_SICB_IMASK(mask_bank, - bfin_read_SICB_IMASK(mask_bank) | - (1 << mask_bit)); + bfin_read_SICB_IMASK(mask_bank) | + (1 << mask_bit)); # endif #else bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | - (1 << SIC_SYSIRQ(irq))); + (1 << SIC_SYSIRQ(irq))); #endif +#endif + hard_local_irq_restore(flags); +} + +#ifdef CONFIG_BF60x +static void bfin_sec_preflow_handler(struct irq_data *d) +{ + unsigned long flags = hard_local_irq_save(); + unsigned int sid = SIC_SYSIRQ(d->irq); + + bfin_write_SEC_SCI(0, SEC_CSID, sid); hard_local_irq_restore(flags); } +static void bfin_sec_mask_ack_irq(struct irq_data *d) +{ + unsigned long flags = hard_local_irq_save(); + unsigned int sid = SIC_SYSIRQ(d->irq); + + bfin_write_SEC_SCI(0, SEC_CSID, sid); + + hard_local_irq_restore(flags); +} + +static void bfin_sec_unmask_irq(struct irq_data *d) +{ + unsigned long flags = hard_local_irq_save(); + unsigned int sid = SIC_SYSIRQ(d->irq); + + bfin_write32(SEC_END, sid); + + hard_local_irq_restore(flags); +} + +static void bfin_sec_enable_ssi(unsigned int sid) +{ + unsigned long flags = hard_local_irq_save(); + uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); + + reg_sctl |= SEC_SCTL_SRC_EN; + bfin_write_SEC_SCTL(sid, reg_sctl); + + hard_local_irq_restore(flags); +} + +static void bfin_sec_disable_ssi(unsigned int sid) +{ + unsigned long flags = hard_local_irq_save(); + uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); + + reg_sctl &= ((uint32_t)~SEC_SCTL_SRC_EN); + bfin_write_SEC_SCTL(sid, reg_sctl); + + hard_local_irq_restore(flags); +} + +static void bfin_sec_set_ssi_coreid(unsigned int sid, unsigned int coreid) +{ + unsigned long flags = hard_local_irq_save(); + uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); + + reg_sctl &= ((uint32_t)~SEC_SCTL_CTG); + bfin_write_SEC_SCTL(sid, reg_sctl | ((coreid << 20) & SEC_SCTL_CTG)); + + hard_local_irq_restore(flags); +} + +static void bfin_sec_enable_sci(unsigned int sid) +{ + unsigned long flags = hard_local_irq_save(); + uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); + + if (sid == SIC_SYSIRQ(IRQ_WATCH0)) + reg_sctl |= SEC_SCTL_FAULT_EN; + else + reg_sctl |= SEC_SCTL_INT_EN; + bfin_write_SEC_SCTL(sid, reg_sctl); + + hard_local_irq_restore(flags); +} + +static void bfin_sec_disable_sci(unsigned int sid) +{ + unsigned long flags = hard_local_irq_save(); + uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); + + reg_sctl &= ((uint32_t)~SEC_SCTL_INT_EN); + bfin_write_SEC_SCTL(sid, reg_sctl); + + hard_local_irq_restore(flags); +} + +static void bfin_sec_enable(struct irq_data *d) +{ + unsigned long flags = hard_local_irq_save(); + unsigned int sid = SIC_SYSIRQ(d->irq); + + bfin_sec_enable_sci(sid); + bfin_sec_enable_ssi(sid); + + hard_local_irq_restore(flags); +} + +static void bfin_sec_disable(struct irq_data *d) +{ + unsigned long flags = hard_local_irq_save(); + unsigned int sid = SIC_SYSIRQ(d->irq); + + bfin_sec_disable_sci(sid); + bfin_sec_disable_ssi(sid); + + hard_local_irq_restore(flags); +} + +static void bfin_sec_raise_irq(unsigned int sid) +{ + unsigned long flags = hard_local_irq_save(); + + bfin_write32(SEC_RAISE, sid); + + hard_local_irq_restore(flags); +} + +static void init_software_driven_irq(void) +{ + bfin_sec_set_ssi_coreid(34, 0); + bfin_sec_set_ssi_coreid(35, 1); + bfin_sec_set_ssi_coreid(36, 0); + bfin_sec_set_ssi_coreid(37, 1); +} + +void bfin_sec_resume(void) +{ + bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); + udelay(100); + bfin_write_SEC_GCTL(SEC_GCTL_EN); + bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); +} + +void handle_sec_sfi_fault(uint32_t gstat) +{ + +} + +void handle_sec_sci_fault(uint32_t gstat) +{ + uint32_t core_id; + uint32_t cstat; + + core_id = gstat & SEC_GSTAT_SCI; + cstat = bfin_read_SEC_SCI(core_id, SEC_CSTAT); + if (cstat & SEC_CSTAT_ERR) { + switch (cstat & SEC_CSTAT_ERRC) { + case SEC_CSTAT_ACKERR: + printk(KERN_DEBUG "sec ack err\n"); + break; + default: + printk(KERN_DEBUG "sec sci unknow err\n"); + } + } + +} + +void handle_sec_ssi_fault(uint32_t gstat) +{ + uint32_t sid; + uint32_t sstat; + + sid = gstat & SEC_GSTAT_SID; + sstat = bfin_read_SEC_SSTAT(sid); + +} + +void handle_sec_fault(unsigned int irq, struct irq_desc *desc) +{ + uint32_t sec_gstat; + + raw_spin_lock(&desc->lock); + + sec_gstat = bfin_read32(SEC_GSTAT); + if (sec_gstat & SEC_GSTAT_ERR) { + + switch (sec_gstat & SEC_GSTAT_ERRC) { + case 0: + handle_sec_sfi_fault(sec_gstat); + break; + case SEC_GSTAT_SCIERR: + handle_sec_sci_fault(sec_gstat); + break; + case SEC_GSTAT_SSIERR: + handle_sec_ssi_fault(sec_gstat); + break; + } + + + } + + raw_spin_unlock(&desc->lock); +} + +static int sec_suspend(void) +{ + return 0; +} + +static void sec_resume(void) +{ + bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); + udelay(100); + bfin_write_SEC_GCTL(SEC_GCTL_EN); + bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); +} + +static struct syscore_ops sec_pm_syscore_ops = { + .suspend = sec_suspend, + .resume = sec_resume, +}; + +#endif + #ifdef CONFIG_SMP static void bfin_internal_unmask_irq_chip(struct irq_data *d) { @@ -212,7 +437,7 @@ } #endif -#ifdef CONFIG_PM +#if defined(CONFIG_PM) && !defined(CONFIG_BF60x) int bfin_internal_set_wake(unsigned int irq, unsigned int state) { u32 bank, bit, wakeup = 0; @@ -271,22 +496,20 @@ return bfin_internal_set_wake(d->irq, state); } #else +# define bfin_internal_set_wake(irq, state) # define bfin_internal_set_wake_chip NULL #endif static struct irq_chip bfin_core_irqchip = { .name = "CORE", - .irq_ack = bfin_ack_noop, .irq_mask = bfin_core_mask_irq, .irq_unmask = bfin_core_unmask_irq, }; static struct irq_chip bfin_internal_irqchip = { .name = "INTN", - .irq_ack = bfin_ack_noop, .irq_mask = bfin_internal_mask_irq_chip, .irq_unmask = bfin_internal_unmask_irq_chip, - .irq_mask_ack = bfin_internal_mask_irq_chip, .irq_disable = bfin_internal_mask_irq_chip, .irq_enable = bfin_internal_unmask_irq_chip, #ifdef CONFIG_SMP @@ -295,6 +518,18 @@ .irq_set_wake = bfin_internal_set_wake_chip, }; +#ifdef CONFIG_BF60x +static struct irq_chip bfin_sec_irqchip = { + .name = "SEC", + .irq_mask_ack = bfin_sec_mask_ack_irq, + .irq_mask = bfin_sec_mask_ack_irq, + .irq_unmask = bfin_sec_unmask_irq, + .irq_eoi = bfin_sec_unmask_irq, + .irq_disable = bfin_sec_disable, + .irq_enable = bfin_sec_enable, +}; +#endif + void bfin_handle_irq(unsigned irq) { #ifdef CONFIG_IPIPE @@ -396,8 +631,6 @@ static struct irq_chip bfin_mac_status_irqchip = { .name = "MACST", - .irq_ack = bfin_ack_noop, - .irq_mask_ack = bfin_mac_status_mask_irq, .irq_mask = bfin_mac_status_mask_irq, .irq_unmask = bfin_mac_status_unmask_irq, .irq_set_wake = bfin_mac_status_set_wake, @@ -421,15 +654,15 @@ } else { bfin_mac_status_ack_irq(irq); pr_debug("IRQ %d:" - " MASKED MAC ERROR INTERRUPT ASSERTED\n", - irq); + " MASKED MAC ERROR INTERRUPT ASSERTED\n", + irq); } } else printk(KERN_ERR - "%s : %s : LINE %d :\nIRQ ?: MAC ERROR" - " INTERRUPT ASSERTED BUT NO SOURCE FOUND" - "(EMAC_SYSTAT=0x%X)\n", - __func__, __FILE__, __LINE__, status); + "%s : %s : LINE %d :\nIRQ ?: MAC ERROR" + " INTERRUPT ASSERTED BUT NO SOURCE FOUND" + "(EMAC_SYSTAT=0x%X)\n", + __func__, __FILE__, __LINE__, status); } #endif @@ -583,7 +816,7 @@ } void bfin_demux_gpio_irq(unsigned int inta_irq, - struct irq_desc *desc) + struct irq_desc *desc) { unsigned int irq; @@ -635,9 +868,15 @@ #else +# ifndef CONFIG_BF60x #define NR_PINT_SYS_IRQS 4 -#define NR_PINT_BITS 32 #define NR_PINTS 160 +# else +#define NR_PINT_SYS_IRQS 6 +#define NR_PINTS 112 +#endif + +#define NR_PINT_BITS 32 #define IRQ_NOT_AVAIL 0xFF #define PINT_2_BANK(x) ((x) >> 5) @@ -652,8 +891,13 @@ (struct bfin_pint_regs *)PINT1_MASK_SET, (struct bfin_pint_regs *)PINT2_MASK_SET, (struct bfin_pint_regs *)PINT3_MASK_SET, +#ifdef CONFIG_BF60x + (struct bfin_pint_regs *)PINT4_MASK_SET, + (struct bfin_pint_regs *)PINT5_MASK_SET, +#endif }; +#ifndef CONFIG_BF60x inline unsigned int get_irq_base(u32 bank, u8 bmap) { unsigned int irq_base; @@ -666,6 +910,16 @@ return irq_base; } +#else +inline unsigned int get_irq_base(u32 bank, u8 bmap) +{ + unsigned int irq_base; + + irq_base = IRQ_PA0 + bank * 16 + bmap * 16; + + return irq_base; +} +#endif /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ void init_pint_lut(void) @@ -854,6 +1108,14 @@ case 1: pint_irq = IRQ_PINT1; break; +#ifdef CONFIG_BF60x + case 4: + pint_irq = IRQ_PINT4; + break; + case 5: + pint_irq = IRQ_PINT5; + break; +#endif default: return -EINVAL; } @@ -867,10 +1129,21 @@ #endif void bfin_demux_gpio_irq(unsigned int inta_irq, - struct irq_desc *desc) + struct irq_desc *desc) { u32 bank, pint_val; u32 request, irq; + u32 level_mask; + int umask = 0; + struct irq_chip *chip = irq_desc_get_chip(desc); + + if (chip->irq_mask_ack) { + chip->irq_mask_ack(&desc->irq_data); + } else { + chip->irq_mask(&desc->irq_data); + if (chip->irq_ack) + chip->irq_ack(&desc->irq_data); + } switch (inta_irq) { case IRQ_PINT0: @@ -885,6 +1158,14 @@ case IRQ_PINT1: bank = 1; break; +#ifdef CONFIG_BF60x + case IRQ_PINT4: + bank = 4; + break; + case IRQ_PINT5: + bank = 5; + break; +#endif default: return; } @@ -893,15 +1174,23 @@ request = pint[bank]->request; + level_mask = pint[bank]->edge_set & request; + while (request) { if (request & 1) { irq = pint2irq_lut[pint_val] + SYS_IRQS; + if (level_mask & PINT_BIT(pint_val)) { + umask = 1; + chip->irq_unmask(&desc->irq_data); + } bfin_handle_irq(irq); } pint_val++; request >>= 1; } + if (!umask) + chip->irq_unmask(&desc->irq_data); } #endif @@ -951,6 +1240,7 @@ int irq; unsigned long ilat = 0; +#ifndef CONFIG_BF60x /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ #ifdef SIC_IMASK0 bfin_write_SIC_IMASK0(SIC_UNMASK_ALL); @@ -958,13 +1248,16 @@ # ifdef SIC_IMASK2 bfin_write_SIC_IMASK2(SIC_UNMASK_ALL); # endif -# ifdef CONFIG_SMP +# if defined(CONFIG_SMP) || defined(CONFIG_ICC) bfin_write_SICB_IMASK0(SIC_UNMASK_ALL); bfin_write_SICB_IMASK1(SIC_UNMASK_ALL); # endif #else bfin_write_SIC_IMASK(SIC_UNMASK_ALL); #endif +#else /* CONFIG_BF60x */ + bfin_write_SEC_GCTL(SEC_GCTL_RESET); +#endif local_irq_disable(); @@ -974,6 +1267,10 @@ pint[1]->assign = CONFIG_PINT1_ASSIGN; pint[2]->assign = CONFIG_PINT2_ASSIGN; pint[3]->assign = CONFIG_PINT3_ASSIGN; +# ifdef CONFIG_BF60x + pint[4]->assign = CONFIG_PINT4_ASSIGN; + pint[5]->assign = CONFIG_PINT5_ASSIGN; +# endif # endif /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ init_pint_lut(); @@ -986,6 +1283,7 @@ irq_set_chip(irq, &bfin_internal_irqchip); switch (irq) { +#ifndef CONFIG_BF60x #if BFIN_GPIO_PINT case IRQ_PINT0: case IRQ_PINT1: @@ -1015,12 +1313,13 @@ bfin_demux_mac_status_irq); break; #endif -#ifdef CONFIG_SMP +#if defined(CONFIG_SMP) || defined(CONFIG_ICC) case IRQ_SUPPLE_0: case IRQ_SUPPLE_1: irq_set_handler(irq, handle_percpu_irq); break; #endif +#endif #ifdef CONFIG_TICKSOURCE_CORETMR case IRQ_CORETMR: @@ -1050,7 +1349,8 @@ init_mach_irq(); -#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +#ifndef CONFIG_BF60x +#if (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) && !defined(CONFIG_BF60x) for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++) irq_set_chip_and_handler(irq, &bfin_mac_status_irqchip, handle_level_irq); @@ -1060,7 +1360,28 @@ irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, handle_level_irq); - +#else + for (irq = BFIN_IRQ(0); irq <= SYS_IRQS; irq++) { + if (irq < CORE_IRQS) { + irq_set_chip(irq, &bfin_sec_irqchip); + __irq_set_handler(irq, handle_sec_fault, 0, NULL); + } else if (irq >= BFIN_IRQ(21) && irq <= BFIN_IRQ(26)) { + irq_set_chip(irq, &bfin_sec_irqchip); + irq_set_chained_handler(irq, bfin_demux_gpio_irq); + } else if (irq >= BFIN_IRQ(34) && irq <= BFIN_IRQ(37)) { + irq_set_chip(irq, &bfin_sec_irqchip); + irq_set_handler(irq, handle_percpu_irq); + } else { + irq_set_chip_and_handler(irq, &bfin_sec_irqchip, + handle_fasteoi_irq); + __irq_set_preflow_handler(irq, bfin_sec_preflow_handler); + } + } + for (irq = GPIO_IRQ_BASE; + irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) + irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, + handle_level_irq); +#endif bfin_write_IMASK(0); CSYNC(); ilat = bfin_read_ILAT(); @@ -1072,14 +1393,17 @@ /* IMASK=xxx is equivalent to STI xx or bfin_irq_flags=xx, * local_irq_enable() */ +#ifndef CONFIG_BF60x program_IAR(); /* Therefore it's better to setup IARs before interrupts enabled */ search_IAR(); /* Enable interrupts IVG7-15 */ bfin_irq_flags |= IMASK_IVG15 | - IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | - IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; + IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | + IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; + + bfin_sti(bfin_irq_flags); /* This implicitly covers ANOMALY_05000171 * Boot-ROM code modifies SICA_IWRx wakeup registers @@ -1103,7 +1427,23 @@ #else bfin_write_SIC_IWR(IWR_DISABLE_ALL); #endif +#else /* CONFIG_BF60x */ + /* Enable interrupts IVG7-15 */ + bfin_irq_flags |= IMASK_IVG15 | + IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | + IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; + + bfin_write_SEC_FCTL(SEC_FCTL_EN | SEC_FCTL_SYSRST_EN | SEC_FCTL_FLTIN_EN); + bfin_sec_enable_sci(SIC_SYSIRQ(IRQ_WATCH0)); + bfin_sec_enable_ssi(SIC_SYSIRQ(IRQ_WATCH0)); + bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); + udelay(100); + bfin_write_SEC_GCTL(SEC_GCTL_EN); + bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); + init_software_driven_irq(); + register_syscore_ops(&sec_pm_syscore_ops); +#endif return 0; } @@ -1112,13 +1452,14 @@ #endif static int vec_to_irq(int vec) { +#ifndef CONFIG_BF60x struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; unsigned long sic_status[3]; - +#endif if (likely(vec == EVT_IVTMR_P)) return IRQ_CORETMR; - +#ifndef CONFIG_BF60x #ifdef SIC_ISR sic_status[0] = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); #else @@ -1147,6 +1488,10 @@ #endif return ivg->irqno; } +#else + /* for bf60x read */ + return BFIN_IRQ(bfin_read_SEC_SCI(0, SEC_CSID)); +#endif /* end of CONFIG_BF60x */ } #ifdef CONFIG_DO_IRQ_L1
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index 3c648a0..ca6655e 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c
@@ -19,20 +19,33 @@ #include <asm/gpio.h> #include <asm/dma.h> #include <asm/dpmc.h> +#include <asm/pm.h> +#ifdef CONFIG_BF60x +struct bfin_cpu_pm_fns *bfin_cpu_pm; +#endif void bfin_pm_suspend_standby_enter(void) { +#ifndef CONFIG_BF60x bfin_pm_standby_setup(); - -#ifdef CONFIG_PM_BFIN_SLEEP_DEEPER - sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); -#else - sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); #endif - bfin_pm_standby_restore(); +#ifdef CONFIG_BF60x + bfin_cpu_pm->enter(PM_SUSPEND_STANDBY); +#else +# ifdef CONFIG_PM_BFIN_SLEEP_DEEPER + sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); +# else + sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); +# endif +#endif +#ifndef CONFIG_BF60x + bfin_pm_standby_restore(); +#endif + +#ifndef CONFIG_BF60x #ifdef SIC_IWR0 bfin_write_SIC_IWR0(IWR_DISABLE_ALL); # ifdef SIC_IWR1 @@ -52,6 +65,8 @@ #else bfin_write_SIC_IWR(IWR_DISABLE_ALL); #endif + +#endif } int bf53x_suspend_l1_mem(unsigned char *memptr) @@ -83,10 +98,13 @@ } #if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK) +# ifdef CONFIG_BF60x +__attribute__((l1_text)) +# endif static void flushinv_all_dcache(void) { - u32 way, bank, subbank, set; - u32 status, addr; + register u32 way, bank, subbank, set; + register u32 status, addr; u32 dmem_ctl = bfin_read_DMEM_CONTROL(); for (bank = 0; bank < 2; ++bank) { @@ -133,6 +151,7 @@ return -ENOMEM; } +#ifndef CONFIG_BF60x wakeup = bfin_read_VR_CTL() & ~FREQ; wakeup |= SCKELOW; @@ -142,6 +161,7 @@ #ifdef CONFIG_PM_BFIN_WAKE_GP wakeup |= GPWE; #endif +#endif ret = blackfin_dma_suspend(); @@ -159,7 +179,11 @@ _disable_icplb(); bf53x_suspend_l1_mem(memptr); +#ifndef CONFIG_BF60x do_hibernate(wakeup | vr_wakeup); /* See you later! */ +#else + bfin_cpu_pm->enter(PM_SUSPEND_MEM); +#endif bf53x_resume_l1_mem(memptr); @@ -223,9 +247,39 @@ return 0; } +#ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH +void bfin_pm_end(void) +{ + u32 cycle, cycle2; + u64 usec64; + u32 usec; + + __asm__ __volatile__ ( + "1: %0 = CYCLES2\n" + "%1 = CYCLES\n" + "%2 = CYCLES2\n" + "CC = %2 == %0\n" + "if ! CC jump 1b\n" + : "=d,a" (cycle2), "=d,a" (cycle), "=d,a" (usec) : : "CC" + ); + + usec64 = ((u64)cycle2 << 32) + cycle; + do_div(usec64, get_cclk() / USEC_PER_SEC); + usec = usec64; + if (usec == 0) + usec = 1; + + pr_info("PM: resume of kernel completes after %ld msec %03ld usec\n", + usec / USEC_PER_MSEC, usec % USEC_PER_MSEC); +} +#endif + static const struct platform_suspend_ops bfin_pm_ops = { .enter = bfin_pm_enter, .valid = bfin_pm_valid, +#ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH + .end = bfin_pm_end, +#endif }; static int __init bfin_pm_init(void)
diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c index 78daae0..9cb8553 100644 --- a/arch/blackfin/mm/init.c +++ b/arch/blackfin/mm/init.c
@@ -48,7 +48,7 @@ unsigned long zones_size[MAX_NR_ZONES] = { [0] = 0, - [ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT, + [ZONE_DMA] = (end_mem - CONFIG_PHY_RAM_BASE_ADDRESS) >> PAGE_SHIFT, [ZONE_NORMAL] = 0, #ifdef CONFIG_HIGHMEM [ZONE_HIGHMEM] = 0, @@ -60,7 +60,8 @@ pr_debug("free_area_init -> start_mem is %#lx virtual_end is %#lx\n", PAGE_ALIGN(memory_start), end_mem); - free_area_init(zones_size); + free_area_init_node(0, zones_size, + CONFIG_PHY_RAM_BASE_ADDRESS >> PAGE_SHIFT, NULL); } asmlinkage void __init init_pda(void) @@ -75,9 +76,6 @@ valid pointers to it. */ memset(&cpu_pda[cpu], 0, sizeof(cpu_pda[cpu])); - cpu_pda[0].next = &cpu_pda[1]; - cpu_pda[1].next = &cpu_pda[0]; - #ifdef CONFIG_EXCEPTION_L1_SCRATCH cpu_pda[cpu].ex_stack = (unsigned long *)(L1_SCRATCH_START + \ L1_SCRATCH_LENGTH); @@ -109,10 +107,10 @@ totalram_pages = free_all_bootmem(); reservedpages = 0; - for (tmp = 0; tmp < max_mapnr; tmp++) + for (tmp = ARCH_PFN_OFFSET; tmp < max_mapnr; tmp++) if (PageReserved(pfn_to_page(tmp))) reservedpages++; - freepages = max_mapnr - reservedpages; + freepages = max_mapnr - ARCH_PFN_OFFSET - reservedpages; /* do not count in kernel image between _rambase and _ramstart */ reservedpages -= (_ramstart - _rambase) >> PAGE_SHIFT; @@ -127,7 +125,7 @@ printk(KERN_INFO "Memory available: %luk/%luk RAM, " "(%uk init code, %uk kernel code, %uk data, %uk dma, %uk reserved)\n", - (unsigned long) freepages << (PAGE_SHIFT-10), _ramend >> 10, + (unsigned long) freepages << (PAGE_SHIFT-10), (_ramend - CONFIG_PHY_RAM_BASE_ADDRESS) >> 10, initk, codek, datak, DMA_UNCACHED_REGION >> 10, (reservedpages << (PAGE_SHIFT-10))); }
diff --git a/arch/blackfin/mm/sram-alloc.c b/arch/blackfin/mm/sram-alloc.c index 29d98fa..342e378 100644 --- a/arch/blackfin/mm/sram-alloc.c +++ b/arch/blackfin/mm/sram-alloc.c
@@ -186,9 +186,45 @@ #endif } +#ifdef __ADSPBF60x__ +static irqreturn_t l2_ecc_err(int irq, void *dev_id) +{ + int status; + + printk(KERN_ERR "L2 ecc error happend\n"); + status = bfin_read32(L2CTL0_STAT); + if (status & 0x1) + printk(KERN_ERR "Core channel error type:0x%x, addr:0x%x\n", + bfin_read32(L2CTL0_ET0), bfin_read32(L2CTL0_EADDR0)); + if (status & 0x2) + printk(KERN_ERR "System channel error type:0x%x, addr:0x%x\n", + bfin_read32(L2CTL0_ET1), bfin_read32(L2CTL0_EADDR1)); + + status = status >> 8; + if (status) + printk(KERN_ERR "L2 Bank%d error, addr:0x%x\n", + status, bfin_read32(L2CTL0_ERRADDR0 + status)); + + panic("L2 Ecc error"); + return IRQ_HANDLED; +} +#endif + static void __init l2_sram_init(void) { #if L2_LENGTH != 0 + +#ifdef __ADSPBF60x__ + int ret; + + ret = request_irq(IRQ_L2CTL0_ECC_ERR, l2_ecc_err, 0, "l2-ecc-err", + NULL); + if (unlikely(ret < 0)) { + printk(KERN_INFO "Fail to request l2 ecc error interrupt"); + return; + } +#endif + free_l2_sram_head.next = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); if (!free_l2_sram_head.next) {
diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig index 1c3ccd4..1f15b88 100644 --- a/arch/c6x/Kconfig +++ b/arch/c6x/Kconfig
@@ -3,7 +3,7 @@ # see Documentation/kbuild/kconfig-language.txt. # -config TMS320C6X +config C6X def_bool y select CLKDEV_LOOKUP select GENERIC_IRQ_SHOW @@ -19,24 +19,12 @@ config MMU def_bool n -config ZONE_DMA - def_bool y - config FPU def_bool n -config HIGHMEM - def_bool n - -config NUMA - def_bool n - config RWSEM_GENERIC_SPINLOCK def_bool y -config RWSEM_XCHGADD_ALGORITHM - def_bool n - config GENERIC_CALIBRATE_DELAY def_bool y
diff --git a/arch/c6x/include/asm/elf.h b/arch/c6x/include/asm/elf.h index d57865b..f4552db 100644 --- a/arch/c6x/include/asm/elf.h +++ b/arch/c6x/include/asm/elf.h
@@ -30,7 +30,19 @@ */ #define elf_check_arch(x) ((x)->e_machine == EM_TI_C6000) -#define elf_check_const_displacement(x) (1) +#define elf_check_fdpic(x) (1) +#define elf_check_const_displacement(x) (0) + +#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map, _interp_map, _dynamic_addr) \ +do { \ + _regs->b4 = (_exec_map); \ + _regs->a6 = (_interp_map); \ + _regs->b6 = (_dynamic_addr); \ +} while (0) + +#define ELF_FDPIC_CORE_EFLAGS 0 + +#define ELF_CORE_COPY_FPREGS(...) 0 /* No FPU regs to copy */ /* * These are used to set parameters in the core dumps.
diff --git a/arch/c6x/include/asm/mmu.h b/arch/c6x/include/asm/mmu.h index 41592bf..4467e77 100644 --- a/arch/c6x/include/asm/mmu.h +++ b/arch/c6x/include/asm/mmu.h
@@ -13,6 +13,10 @@ typedef struct { unsigned long end_brk; +#ifdef CONFIG_BINFMT_ELF_FDPIC + unsigned long exec_fdpic_loadmap; + unsigned long interp_fdpic_loadmap; +#endif } mm_context_t; #endif /* _ASM_C6X_MMU_H */
diff --git a/arch/c6x/include/asm/ptrace.h b/arch/c6x/include/asm/ptrace.h index 21e8d79..b04ff59 100644 --- a/arch/c6x/include/asm/ptrace.h +++ b/arch/c6x/include/asm/ptrace.h
@@ -97,6 +97,11 @@ #define PT_DP PT_B14 /* Data Segment Pointer (B14) */ #define PT_SP PT_B15 /* Stack Pointer (B15) */ +#define PTRACE_GETFDPIC 31 /* get the ELF fdpic loadmap address */ + +#define PTRACE_GETFDPIC_EXEC 0 /* [addr] request the executable loadmap */ +#define PTRACE_GETFDPIC_INTERP 1 /* [addr] request the interpreter loadmap */ + #ifndef __ASSEMBLY__ #ifdef _BIG_ENDIAN
diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h index 81c2e27..9b1a92b 100644 --- a/arch/frv/include/asm/processor.h +++ b/arch/frv/include/asm/processor.h
@@ -135,10 +135,6 @@ #define KSTK_EIP(tsk) ((tsk)->thread.frame0->pc) #define KSTK_ESP(tsk) ((tsk)->thread.frame0->sp) -/* Allocation and freeing of basic task resources. */ -extern struct task_struct *alloc_task_struct_node(int node); -extern void free_task_struct(struct task_struct *p); - #define cpu_relax() barrier() /* data cache prefetch */
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index f5104b7..463fb3b 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c
@@ -1174,7 +1174,7 @@ bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) { - return irqchip_in_kernel(vcpu->kcm) == (vcpu->arch.apic != NULL); + return irqchip_in_kernel(vcpu->kvm) == (vcpu->arch.apic != NULL); } int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index cf318f2..41b3bc9 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile
@@ -16,6 +16,13 @@ KBUILD_DEFCONFIG := multi_defconfig +ifneq ($(SUBARCH),$(ARCH)) + ifeq ($(CROSS_COMPILE),) + CROSS_COMPILE := $(call cc-cross-prefix, \ + m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-) + endif +endif + # # Enable processor type. Ordering of these is important - we want to # use the minimum processor type of the range we support. The logic @@ -62,12 +69,6 @@ LDFLAGS := -m m68kelf KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds -ifneq ($(SUBARCH),$(ARCH)) - ifeq ($(CROSS_COMPILE),) - CROSS_COMPILE := $(call cc-cross-prefix, \ - m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-) - endif -endif ifdef CONFIG_SUN3 LDFLAGS_vmlinux = -N
diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c index 7fd8b41..80076d3 100644 --- a/arch/m68k/amiga/platform.c +++ b/arch/m68k/amiga/platform.c
@@ -6,6 +6,7 @@ * for more details. */ +#include <linux/err.h> #include <linux/init.h> #include <linux/platform_device.h> #include <linux/zorro.h> @@ -46,18 +47,25 @@ static int __init amiga_init_bus(void) { + struct platform_device *pdev; + unsigned int n; + if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO)) return -ENODEV; - platform_device_register_simple("amiga-zorro", -1, zorro_resources, - AMIGAHW_PRESENT(ZORRO3) ? 4 : 2); + n = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2; + pdev = platform_device_register_simple("amiga-zorro", -1, + zorro_resources, n); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + return 0; } subsys_initcall(amiga_init_bus); -static int z_dev_present(zorro_id id) +static int __init z_dev_present(zorro_id id) { unsigned int i; @@ -126,72 +134,122 @@ static int __init amiga_init_devices(void) { struct platform_device *pdev; + int error; if (!MACH_IS_AMIGA) return -ENODEV; /* video hardware */ - if (AMIGAHW_PRESENT(AMI_VIDEO)) - platform_device_register_simple("amiga-video", -1, NULL, 0); + if (AMIGAHW_PRESENT(AMI_VIDEO)) { + pdev = platform_device_register_simple("amiga-video", -1, NULL, + 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + } /* sound hardware */ - if (AMIGAHW_PRESENT(AMI_AUDIO)) - platform_device_register_simple("amiga-audio", -1, NULL, 0); + if (AMIGAHW_PRESENT(AMI_AUDIO)) { + pdev = platform_device_register_simple("amiga-audio", -1, NULL, + 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + } /* storage interfaces */ - if (AMIGAHW_PRESENT(AMI_FLOPPY)) - platform_device_register_simple("amiga-floppy", -1, NULL, 0); + if (AMIGAHW_PRESENT(AMI_FLOPPY)) { + pdev = platform_device_register_simple("amiga-floppy", -1, + NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + } - if (AMIGAHW_PRESENT(A3000_SCSI)) - platform_device_register_simple("amiga-a3000-scsi", -1, - &a3000_scsi_resource, 1); + if (AMIGAHW_PRESENT(A3000_SCSI)) { + pdev = platform_device_register_simple("amiga-a3000-scsi", -1, + &a3000_scsi_resource, 1); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + } - if (AMIGAHW_PRESENT(A4000_SCSI)) - platform_device_register_simple("amiga-a4000t-scsi", -1, - &a4000t_scsi_resource, 1); + if (AMIGAHW_PRESENT(A4000_SCSI)) { + pdev = platform_device_register_simple("amiga-a4000t-scsi", -1, + &a4000t_scsi_resource, + 1); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + } if (AMIGAHW_PRESENT(A1200_IDE) || z_dev_present(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE)) { pdev = platform_device_register_simple("amiga-gayle-ide", -1, &a1200_ide_resource, 1); - platform_device_add_data(pdev, &a1200_ide_pdata, - sizeof(a1200_ide_pdata)); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + error = platform_device_add_data(pdev, &a1200_ide_pdata, + sizeof(a1200_ide_pdata)); + if (error) + return error; } if (AMIGAHW_PRESENT(A4000_IDE)) { pdev = platform_device_register_simple("amiga-gayle-ide", -1, &a4000_ide_resource, 1); - platform_device_add_data(pdev, &a4000_ide_pdata, - sizeof(a4000_ide_pdata)); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + error = platform_device_add_data(pdev, &a4000_ide_pdata, + sizeof(a4000_ide_pdata)); + if (error) + return error; } /* other I/O hardware */ - if (AMIGAHW_PRESENT(AMI_KEYBOARD)) - platform_device_register_simple("amiga-keyboard", -1, NULL, 0); + if (AMIGAHW_PRESENT(AMI_KEYBOARD)) { + pdev = platform_device_register_simple("amiga-keyboard", -1, + NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + } - if (AMIGAHW_PRESENT(AMI_MOUSE)) - platform_device_register_simple("amiga-mouse", -1, NULL, 0); + if (AMIGAHW_PRESENT(AMI_MOUSE)) { + pdev = platform_device_register_simple("amiga-mouse", -1, NULL, + 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + } - if (AMIGAHW_PRESENT(AMI_SERIAL)) - platform_device_register_simple("amiga-serial", -1, NULL, 0); + if (AMIGAHW_PRESENT(AMI_SERIAL)) { + pdev = platform_device_register_simple("amiga-serial", -1, + NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + } - if (AMIGAHW_PRESENT(AMI_PARALLEL)) - platform_device_register_simple("amiga-parallel", -1, NULL, 0); + if (AMIGAHW_PRESENT(AMI_PARALLEL)) { + pdev = platform_device_register_simple("amiga-parallel", -1, + NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + } /* real time clocks */ - if (AMIGAHW_PRESENT(A2000_CLK)) - platform_device_register_simple("rtc-msm6242", -1, - &amiga_rtc_resource, 1); + if (AMIGAHW_PRESENT(A2000_CLK)) { + pdev = platform_device_register_simple("rtc-msm6242", -1, + &amiga_rtc_resource, 1); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + } - if (AMIGAHW_PRESENT(A3000_CLK)) - platform_device_register_simple("rtc-rp5c01", -1, - &amiga_rtc_resource, 1); + if (AMIGAHW_PRESENT(A3000_CLK)) { + pdev = platform_device_register_simple("rtc-rp5c01", -1, + &amiga_rtc_resource, 1); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + } return 0; } -device_initcall(amiga_init_devices); +arch_initcall(amiga_init_devices);
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c index 783d8f0..3f41092 100644 --- a/arch/m68k/atari/ataints.c +++ b/arch/m68k/atari/ataints.c
@@ -206,7 +206,7 @@ * hardware with a programmable int vector (probably a VME board). */ -unsigned long atari_register_vme_int(void) +unsigned int atari_register_vme_int(void) { int i; @@ -223,7 +223,7 @@ EXPORT_SYMBOL(atari_register_vme_int); -void atari_unregister_vme_int(unsigned long irq) +void atari_unregister_vme_int(unsigned int irq) { if (irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) { irq -= VME_SOURCE_BASE;
diff --git a/arch/m68k/include/asm/atariints.h b/arch/m68k/include/asm/atariints.h index 656bbbf..5fc13bd 100644 --- a/arch/m68k/include/asm/atariints.h +++ b/arch/m68k/include/asm/atariints.h
@@ -198,7 +198,7 @@ return( get_mfp_bit( irq, MFP_PENDING ) ); } -unsigned long atari_register_vme_int( void ); -void atari_unregister_vme_int( unsigned long ); +unsigned int atari_register_vme_int(void); +void atari_unregister_vme_int(unsigned int); #endif /* linux/atariints.h */
diff --git a/arch/m68k/include/asm/entry.h b/arch/m68k/include/asm/entry.h index 622138d..d7de0f1 100644 --- a/arch/m68k/include/asm/entry.h +++ b/arch/m68k/include/asm/entry.h
@@ -33,13 +33,11 @@ /* the following macro is used when enabling interrupts */ #if defined(MACH_ATARI_ONLY) - /* block out HSYNC on the atari */ -#define ALLOWINT (~0x400) -#define MAX_NOINT_IPL 3 + /* block out HSYNC = ipl 2 on the atari */ +#define ALLOWINT (~0x500) #else /* portable version */ #define ALLOWINT (~0x700) -#define MAX_NOINT_IPL 0 #endif /* machine compilation types */ #ifdef __ASSEMBLY__
diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h index 0fb3468..fa4324b 100644 --- a/arch/m68k/include/asm/io_mm.h +++ b/arch/m68k/include/asm/io_mm.h
@@ -278,6 +278,13 @@ #define readl(addr) in_le32(addr) #define writel(val,addr) out_le32((addr),(val)) +#define readsb(port, buf, nr) raw_insb((port), (u8 *)(buf), (nr)) +#define readsw(port, buf, nr) raw_insw((port), (u16 *)(buf), (nr)) +#define readsl(port, buf, nr) raw_insl((port), (u32 *)(buf), (nr)) +#define writesb(port, buf, nr) raw_outsb((port), (u8 *)(buf), (nr)) +#define writesw(port, buf, nr) raw_outsw((port), (u16 *)(buf), (nr)) +#define writesl(port, buf, nr) raw_outsl((port), (u32 *)(buf), (nr)) + #define mmiowb() static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
diff --git a/arch/m68k/include/asm/vga.h b/arch/m68k/include/asm/vga.h new file mode 100644 index 0000000..d3aa140 --- /dev/null +++ b/arch/m68k/include/asm/vga.h
@@ -0,0 +1,27 @@ +#ifndef _ASM_M68K_VGA_H +#define _ASM_M68K_VGA_H + +#include <asm/raw_io.h> + +/* + * FIXME + * Ugh, we don't have PCI space, so map readb() and friends to use raw I/O + * accessors, which are identical to the z_*() Zorro bus accessors. + * This should make cirrusfb work again on Amiga + */ +#undef inb_p +#undef inw_p +#undef outb_p +#undef outw +#undef readb +#undef writeb +#undef writew +#define inb_p(port) 0 +#define inw_p(port) 0 +#define outb_p(port, val) do { } while (0) +#define outw(port, val) do { } while (0) +#define readb raw_inb +#define writeb raw_outb +#define writew raw_outw + +#endif /* _ASM_M68K_VGA_H */
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c index 6b020a8..aeebbb7 100644 --- a/arch/m68k/mm/fault.c +++ b/arch/m68k/mm/fault.c
@@ -72,7 +72,8 @@ { struct mm_struct *mm = current->mm; struct vm_area_struct * vma; - int write, fault; + int fault; + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; #ifdef DEBUG printk ("do page fault:\nregs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld, %p\n", @@ -87,6 +88,7 @@ if (in_atomic() || !mm) goto no_context; +retry: down_read(&mm->mmap_sem); vma = find_vma(mm, address); @@ -117,14 +119,13 @@ #ifdef DEBUG printk("do_page_fault: good_area\n"); #endif - write = 0; switch (error_code & 3) { default: /* 3: write, present */ /* fall through */ case 2: /* write, not present */ if (!(vma->vm_flags & VM_WRITE)) goto acc_err; - write++; + flags |= FAULT_FLAG_WRITE; break; case 1: /* read, present */ goto acc_err; @@ -139,10 +140,14 @@ * the fault. */ - fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0); + fault = handle_mm_fault(mm, vma, address, flags); #ifdef DEBUG printk("handle_mm_fault returns %d\n",fault); #endif + + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) + return 0; + if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) goto out_of_memory; @@ -150,10 +155,31 @@ goto bus_err; BUG(); } - if (fault & VM_FAULT_MAJOR) - current->maj_flt++; - else - current->min_flt++; + + /* + * Major/minor page fault accounting is only done on the + * initial attempt. If we go through a retry, it is extremely + * likely that the page will be found in page cache at that point. + */ + if (flags & FAULT_FLAG_ALLOW_RETRY) { + if (fault & VM_FAULT_MAJOR) + current->maj_flt++; + else + current->min_flt++; + if (fault & VM_FAULT_RETRY) { + /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk + * of starvation. */ + flags &= ~FAULT_FLAG_ALLOW_RETRY; + + /* + * No need to up_read(&mm->mmap_sem) as we would + * have already released it in __lock_page_or_retry + * in mm/filemap.c. + */ + + goto retry; + } + } up_read(&mm->mmap_sem); return 0;
diff --git a/arch/m68k/platform/520x/config.c b/arch/m68k/platform/520x/config.c index 23594784..09df4b8 100644 --- a/arch/m68k/platform/520x/config.c +++ b/arch/m68k/platform/520x/config.c
@@ -22,7 +22,7 @@ /***************************************************************************/ -#ifdef CONFIG_SPI_COLDFIRE_QSPI +#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) static void __init m520x_qspi_init(void) { @@ -35,7 +35,7 @@ writew(par, MCF_GPIO_PAR_UART); } -#endif /* CONFIG_SPI_COLDFIRE_QSPI */ +#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ /***************************************************************************/ @@ -79,7 +79,7 @@ mach_sched_init = hw_timer_init; m520x_uarts_init(); m520x_fec_init(); -#ifdef CONFIG_SPI_COLDFIRE_QSPI +#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) m520x_qspi_init(); #endif }
diff --git a/arch/m68k/platform/523x/config.c b/arch/m68k/platform/523x/config.c index c8b405d..d47dfd8 100644 --- a/arch/m68k/platform/523x/config.c +++ b/arch/m68k/platform/523x/config.c
@@ -22,7 +22,7 @@ /***************************************************************************/ -#ifdef CONFIG_SPI_COLDFIRE_QSPI +#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) static void __init m523x_qspi_init(void) { @@ -36,7 +36,7 @@ writew(par, MCFGPIO_PAR_TIMER); } -#endif /* CONFIG_SPI_COLDFIRE_QSPI */ +#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ /***************************************************************************/ @@ -58,7 +58,7 @@ { mach_sched_init = hw_timer_init; m523x_fec_init(); -#ifdef CONFIG_SPI_COLDFIRE_QSPI +#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) m523x_qspi_init(); #endif }
diff --git a/arch/m68k/platform/5249/config.c b/arch/m68k/platform/5249/config.c index bbf0513..300e729 100644 --- a/arch/m68k/platform/5249/config.c +++ b/arch/m68k/platform/5249/config.c
@@ -51,7 +51,7 @@ /***************************************************************************/ -#ifdef CONFIG_SPI_COLDFIRE_QSPI +#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) static void __init m5249_qspi_init(void) { @@ -61,7 +61,7 @@ mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI); } -#endif /* CONFIG_SPI_COLDFIRE_QSPI */ +#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ /***************************************************************************/ @@ -90,7 +90,7 @@ #ifdef CONFIG_M5249C3 m5249_smc91x_init(); #endif -#ifdef CONFIG_SPI_COLDFIRE_QSPI +#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) m5249_qspi_init(); #endif }
diff --git a/arch/m68k/platform/527x/config.c b/arch/m68k/platform/527x/config.c index f91a532..b3cb378 100644 --- a/arch/m68k/platform/527x/config.c +++ b/arch/m68k/platform/527x/config.c
@@ -23,7 +23,7 @@ /***************************************************************************/ -#ifdef CONFIG_SPI_COLDFIRE_QSPI +#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) static void __init m527x_qspi_init(void) { @@ -42,7 +42,7 @@ #endif } -#endif /* CONFIG_SPI_COLDFIRE_QSPI */ +#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ /***************************************************************************/ @@ -90,7 +90,7 @@ mach_sched_init = hw_timer_init; m527x_uarts_init(); m527x_fec_init(); -#ifdef CONFIG_SPI_COLDFIRE_QSPI +#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) m527x_qspi_init(); #endif }
diff --git a/arch/m68k/platform/528x/config.c b/arch/m68k/platform/528x/config.c index d449292..c5f11ba 100644 --- a/arch/m68k/platform/528x/config.c +++ b/arch/m68k/platform/528x/config.c
@@ -24,7 +24,7 @@ /***************************************************************************/ -#ifdef CONFIG_SPI_COLDFIRE_QSPI +#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) static void __init m528x_qspi_init(void) { @@ -32,7 +32,7 @@ __raw_writeb(0x07, MCFGPIO_PQSPAR); } -#endif /* CONFIG_SPI_COLDFIRE_QSPI */ +#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ /***************************************************************************/ @@ -98,7 +98,7 @@ mach_sched_init = hw_timer_init; m528x_uarts_init(); m528x_fec_init(); -#ifdef CONFIG_SPI_COLDFIRE_QSPI +#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) m528x_qspi_init(); #endif }
diff --git a/arch/m68k/platform/532x/config.c b/arch/m68k/platform/532x/config.c index 2bec347..37082d0 100644 --- a/arch/m68k/platform/532x/config.c +++ b/arch/m68k/platform/532x/config.c
@@ -30,7 +30,7 @@ /***************************************************************************/ -#ifdef CONFIG_SPI_COLDFIRE_QSPI +#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) static void __init m532x_qspi_init(void) { @@ -38,7 +38,7 @@ writew(0x01f0, MCF_GPIO_PAR_QSPI); } -#endif /* CONFIG_SPI_COLDFIRE_QSPI */ +#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ /***************************************************************************/ @@ -77,7 +77,7 @@ mach_sched_init = hw_timer_init; m532x_uarts_init(); m532x_fec_init(); -#ifdef CONFIG_SPI_COLDFIRE_QSPI +#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) m532x_qspi_init(); #endif
diff --git a/arch/m68k/platform/coldfire/device.c b/arch/m68k/platform/coldfire/device.c index 7af9736..3aa77dd 100644 --- a/arch/m68k/platform/coldfire/device.c +++ b/arch/m68k/platform/coldfire/device.c
@@ -121,7 +121,7 @@ #endif /* MCFFEC_BASE1 */ #endif /* CONFIG_FEC */ -#ifdef CONFIG_SPI_COLDFIRE_QSPI +#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) /* * The ColdFire QSPI module is an SPI protocol hardware block used * on a number of different ColdFire CPUs. @@ -274,7 +274,7 @@ .resource = mcf_qspi_resources, .dev.platform_data = &mcf_qspi_data, }; -#endif /* CONFIG_SPI_COLDFIRE_QSPI */ +#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ static struct platform_device *mcf_devices[] __initdata = { &mcf_uart, @@ -284,7 +284,7 @@ &mcf_fec1, #endif #endif -#ifdef CONFIG_SPI_COLDFIRE_QSPI +#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) &mcf_qspi, #endif };
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index 807c97e..46c61edc 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig
@@ -346,11 +346,8 @@ CONFIG_IXGB=m CONFIG_S2IO=m CONFIG_MYRI10GE=m -CONFIG_TR=y CONFIG_IBMOL=m CONFIG_IBMLS=m -CONFIG_3C359=m -CONFIG_TMS380TR=m CONFIG_TMSPCI=m CONFIG_ABYSS=m CONFIG_USB_CATC=m @@ -376,7 +373,6 @@ CONFIG_PCMCIA_XIRC2PS=m CONFIG_PCMCIA_AXNET=m CONFIG_ARCNET_COM20020_CS=m -CONFIG_PCMCIA_IBMTR=m CONFIG_WAN=y CONFIG_LANMEDIA=m CONFIG_HDLC=m
diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c index 910dddf..9cd69ad 100644 --- a/arch/mn10300/kernel/smp.c +++ b/arch/mn10300/kernel/smp.c
@@ -24,6 +24,7 @@ #include <linux/sched.h> #include <linux/profile.h> #include <linux/smp.h> +#include <linux/cpu.h> #include <asm/tlbflush.h> #include <asm/bitops.h> #include <asm/processor.h> @@ -38,7 +39,6 @@ #include "internal.h" #ifdef CONFIG_HOTPLUG_CPU -#include <linux/cpu.h> #include <asm/cacheflush.h> static unsigned long sleep_mode[NR_CPUS]; @@ -874,10 +874,13 @@ cpu = smp_processor_id(); - local_irq_enable(); + notify_cpu_starting(cpu); + ipi_call_lock(); set_cpu_online(cpu, true); - smp_wmb(); + ipi_call_unlock(); + + local_irq_enable(); } /**
diff --git a/arch/parisc/include/asm/hardware.h b/arch/parisc/include/asm/hardware.h index 4e96268..d1d864b 100644 --- a/arch/parisc/include/asm/hardware.h +++ b/arch/parisc/include/asm/hardware.h
@@ -2,7 +2,6 @@ #define _PARISC_HARDWARE_H #include <linux/mod_devicetable.h> -#include <asm/pdc.h> #define HWTYPE_ANY_ID PA_HWTYPE_ANY_ID #define HVERSION_ANY_ID PA_HVERSION_ANY_ID @@ -95,12 +94,14 @@ #define HPHW_MC 15 #define HPHW_FAULTY 31 +struct parisc_device_id; /* hardware.c: */ extern const char *parisc_hardware_description(struct parisc_device_id *id); extern enum cpu_type parisc_get_cpu_type(unsigned long hversion); struct pci_dev; +struct hardware_path; /* drivers.c: */ extern struct parisc_device *alloc_pa_dev(unsigned long hpa,
diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h index a84cc1f..4e0e7db 100644 --- a/arch/parisc/include/asm/page.h +++ b/arch/parisc/include/asm/page.h
@@ -160,5 +160,11 @@ #include <asm-generic/memory_model.h> #include <asm-generic/getorder.h> +#include <asm/pdc.h> + +#define PAGE0 ((struct zeropage *)__PAGE_OFFSET) + +/* DEFINITION OF THE ZERO-PAGE (PAG0) */ +/* based on work by Jason Eckhardt (jason@equator.com) */ #endif /* _PARISC_PAGE_H */
diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h index 4ca510b..7f0f2d2 100644 --- a/arch/parisc/include/asm/pdc.h +++ b/arch/parisc/include/asm/pdc.h
@@ -343,8 +343,6 @@ #ifdef __KERNEL__ -#include <asm/page.h> /* for __PAGE_OFFSET */ - extern int pdc_type; /* Values for pdc_type */ @@ -677,11 +675,6 @@ #endif /* __KERNEL__ */ -#define PAGE0 ((struct zeropage *)__PAGE_OFFSET) - -/* DEFINITION OF THE ZERO-PAGE (PAG0) */ -/* based on work by Jason Eckhardt (jason@equator.com) */ - /* flags of the device_path */ #define PF_AUTOBOOT 0x80 #define PF_AUTOSEARCH 0x40
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h index 22dadeb..ee99f23 100644 --- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h
@@ -44,6 +44,8 @@ #endif /* !__ASSEMBLY__ */ +#include <asm/page.h> + #define pte_ERROR(e) \ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) #define pmd_ERROR(e) \
diff --git a/arch/parisc/include/asm/prefetch.h b/arch/parisc/include/asm/prefetch.h index c5edc60..1ee7c82 100644 --- a/arch/parisc/include/asm/prefetch.h +++ b/arch/parisc/include/asm/prefetch.h
@@ -21,7 +21,12 @@ #define ARCH_HAS_PREFETCH static inline void prefetch(const void *addr) { - __asm__("ldw 0(%0), %%r0" : : "r" (addr)); + __asm__( +#ifndef CONFIG_PA20 + /* Need to avoid prefetch of NULL on PA7300LC */ + " extrw,u,= %0,31,32,%%r0\n" +#endif + " ldw 0(%0), %%r0" : : "r" (addr)); } /* LDD is a PA2.0 addition. */
diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h index 804aa28..3516e0b 100644 --- a/arch/parisc/include/asm/spinlock.h +++ b/arch/parisc/include/asm/spinlock.h
@@ -1,6 +1,8 @@ #ifndef __ASM_SPINLOCK_H #define __ASM_SPINLOCK_H +#include <asm/barrier.h> +#include <asm/ldcw.h> #include <asm/processor.h> #include <asm/spinlock_types.h>
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 6f05944..5350342 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S
@@ -581,7 +581,11 @@ */ cmpiclr,= 0x01,\tmp,%r0 ldi (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot +#ifdef CONFIG_64BIT depd,z \prot,8,7,\prot +#else + depw,z \prot,8,7,\prot +#endif /* * OK, it is in the temp alias region, check whether "from" or "to". * Check "subtle" note in pacache.S re: r23/r26.
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 93ff3d9..5d7218a 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S
@@ -692,7 +692,7 @@ /* Purge any old translation */ - pitlb (%sr0,%r28) + pitlb (%sr4,%r28) ldil L%icache_stride, %r1 ldw R%icache_stride(%r1), %r1 @@ -706,27 +706,29 @@ sub %r25, %r1, %r25 -1: fic,m %r1(%r28) - fic,m %r1(%r28) - fic,m %r1(%r28) - fic,m %r1(%r28) - fic,m %r1(%r28) - fic,m %r1(%r28) - fic,m %r1(%r28) - fic,m %r1(%r28) - fic,m %r1(%r28) - fic,m %r1(%r28) - fic,m %r1(%r28) - fic,m %r1(%r28) - fic,m %r1(%r28) - fic,m %r1(%r28) - fic,m %r1(%r28) + /* fic only has the type 26 form on PA1.1, requiring an + * explicit space specification, so use %sr4 */ +1: fic,m %r1(%sr4,%r28) + fic,m %r1(%sr4,%r28) + fic,m %r1(%sr4,%r28) + fic,m %r1(%sr4,%r28) + fic,m %r1(%sr4,%r28) + fic,m %r1(%sr4,%r28) + fic,m %r1(%sr4,%r28) + fic,m %r1(%sr4,%r28) + fic,m %r1(%sr4,%r28) + fic,m %r1(%sr4,%r28) + fic,m %r1(%sr4,%r28) + fic,m %r1(%sr4,%r28) + fic,m %r1(%sr4,%r28) + fic,m %r1(%sr4,%r28) + fic,m %r1(%sr4,%r28) cmpb,COND(<<) %r28, %r25,1b - fic,m %r1(%r28) + fic,m %r1(%sr4,%r28) sync bv %r0(%r2) - pitlb (%sr0,%r25) + pitlb (%sr4,%r25) .exit .procend
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c index 4f00459..47341aa 100644 --- a/arch/parisc/kernel/pdc_cons.c +++ b/arch/parisc/kernel/pdc_cons.c
@@ -50,6 +50,7 @@ #include <linux/init.h> #include <linux/major.h> #include <linux/tty.h> +#include <asm/page.h> /* for PAGE0 */ #include <asm/pdc.h> /* for iodc_call() proto and friends */ static DEFINE_SPINLOCK(pdc_console_lock); @@ -104,7 +105,7 @@ static void pdc_console_tty_close(struct tty_struct *tty, struct file *filp) { - if (!tty->count) { + if (tty->count == 1) { del_timer_sync(&pdc_console_timer); tty_port_tty_set(&tty_port, NULL); }
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 0bb1d63..4dc7b79 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c
@@ -31,6 +31,7 @@ #include <linux/delay.h> #include <linux/bitops.h> #include <linux/ftrace.h> +#include <linux/cpu.h> #include <linux/atomic.h> #include <asm/current.h> @@ -295,8 +296,13 @@ printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum); machine_halt(); - } + } + + notify_cpu_starting(cpunum); + + ipi_call_lock(); set_cpu_online(cpunum, true); + ipi_call_unlock(); /* Initialise the idle task for this CPU */ atomic_inc(&init_mm.mm_count);
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 7c07743..70e105d 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c
@@ -29,6 +29,7 @@ #include <asm/uaccess.h> #include <asm/io.h> #include <asm/irq.h> +#include <asm/page.h> #include <asm/param.h> #include <asm/pdc.h> #include <asm/led.h>
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index feab3ba..73ec039 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig
@@ -141,7 +141,7 @@ select IRQ_FORCED_THREADING select HAVE_RCU_TABLE_FREE if SMP select HAVE_SYSCALL_TRACEPOINTS - select HAVE_BPF_JIT if (PPC64 && NET) + select HAVE_BPF_JIT if PPC64 select HAVE_ARCH_JUMP_LABEL select ARCH_HAVE_NMI_SAFE_CMPXCHG
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 548da3a..d58fc4e 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h
@@ -288,13 +288,6 @@ /* Exception addition: Hard disable interrupts */ #define DISABLE_INTS SOFT_DISABLE_INTS(r10,r11) -/* Exception addition: Keep interrupt state */ -#define ENABLE_INTS \ - ld r11,PACAKMSR(r13); \ - ld r12,_MSR(r1); \ - rlwimi r11,r12,0,MSR_EE; \ - mtmsrd r11,1 - #define ADD_NVGPRS \ bl .save_nvgprs
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index aa795cc..fd07f43 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -81,12 +81,13 @@ u64 sdr1; u64 hior; u64 msr_mask; - u64 vsid_next; #ifdef CONFIG_PPC_BOOK3S_32 u32 vsid_pool[VSID_POOL_SIZE]; + u32 vsid_next; #else - u64 vsid_first; - u64 vsid_max; + u64 proto_vsid_first; + u64 proto_vsid_max; + u64 proto_vsid_next; #endif int context_id[SID_CONTEXTS];
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index f8a7a1a1..ef2074c 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S
@@ -588,23 +588,19 @@ fast_exc_return_irq: restore: /* - * This is the main kernel exit path, we first check if we - * have to change our interrupt state. + * This is the main kernel exit path. First we check if we + * are about to re-enable interrupts */ ld r5,SOFTE(r1) lbz r6,PACASOFTIRQEN(r13) - cmpwi cr1,r5,0 - cmpw cr0,r5,r6 - beq cr0,4f + cmpwi cr0,r5,0 + beq restore_irq_off - /* We do, handle disable first, which is easy */ - bne cr1,3f; - li r0,0 - stb r0,PACASOFTIRQEN(r13); - TRACE_DISABLE_INTS - b 4f + /* We are enabling, were we already enabled ? Yes, just return */ + cmpwi cr0,r6,1 + beq cr0,do_restore -3: /* + /* * We are about to soft-enable interrupts (we are hard disabled * at this point). We check if there's anything that needs to * be replayed first. @@ -626,7 +622,7 @@ /* * Final return path. BookE is handled in a different file */ -4: +do_restore: #ifdef CONFIG_PPC_BOOK3E b .exception_return_book3e #else @@ -700,6 +696,25 @@ #endif /* CONFIG_PPC_BOOK3E */ /* + * We are returning to a context with interrupts soft disabled. + * + * However, we may also about to hard enable, so we need to + * make sure that in this case, we also clear PACA_IRQ_HARD_DIS + * or that bit can get out of sync and bad things will happen + */ +restore_irq_off: + ld r3,_MSR(r1) + lbz r7,PACAIRQHAPPENED(r13) + andi. r0,r3,MSR_EE + beq 1f + rlwinm r7,r7,0,~PACA_IRQ_HARD_DIS + stb r7,PACAIRQHAPPENED(r13) +1: li r0,0 + stb r0,PACASOFTIRQEN(r13); + TRACE_DISABLE_INTS + b do_restore + + /* * Something did happen, check if a re-emit is needed * (this also clears paca->irq_happened) */ @@ -748,6 +763,9 @@ #endif /* CONFIG_PPC_BOOK3E */ 1: b .ret_from_except /* What else to do here ? */ + + +3: do_work: #ifdef CONFIG_PREEMPT andi. r0,r3,MSR_PR /* Returning to user mode? */ @@ -767,16 +785,6 @@ SOFT_DISABLE_INTS(r3,r4) 1: bl .preempt_schedule_irq - /* Hard-disable interrupts again (and update PACA) */ -#ifdef CONFIG_PPC_BOOK3E - wrteei 0 -#else - ld r10,PACAKMSR(r13) /* Get kernel MSR without EE */ - mtmsrd r10,1 -#endif /* CONFIG_PPC_BOOK3E */ - li r0,PACA_IRQ_HARD_DIS - stb r0,PACAIRQHAPPENED(r13) - /* Re-test flags and eventually loop */ clrrdi r9,r1,THREAD_SHIFT ld r4,TI_FLAGS(r9) @@ -787,14 +795,6 @@ user_work: #endif /* CONFIG_PREEMPT */ - /* Enable interrupts */ -#ifdef CONFIG_PPC_BOOK3E - wrteei 1 -#else - ori r10,r10,MSR_EE - mtmsrd r10,1 -#endif /* CONFIG_PPC_BOOK3E */ - andi. r0,r4,_TIF_NEED_RESCHED beq 1f bl .restore_interrupts
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index cb705fd..8f880bc 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -768,8 +768,8 @@ std r3,_DAR(r1) std r4,_DSISR(r1) bl .save_nvgprs + DISABLE_INTS addi r3,r1,STACK_FRAME_OVERHEAD - ENABLE_INTS bl .alignment_exception b .ret_from_except
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 43eb74f..641da9e 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c
@@ -229,6 +229,19 @@ */ if (unlikely(irq_happened != PACA_IRQ_HARD_DIS)) __hard_irq_disable(); +#ifdef CONFIG_TRACE_IRQFLAG + else { + /* + * We should already be hard disabled here. We had bugs + * where that wasn't the case so let's dbl check it and + * warn if we are wrong. Only do that when IRQ tracing + * is enabled as mfmsr() can be costly. + */ + if (WARN_ON(mfmsr() & MSR_EE)) + __hard_irq_disable(); + } +#endif /* CONFIG_TRACE_IRQFLAG */ + set_soft_enabled(0); /* @@ -260,11 +273,17 @@ * if they are currently disabled. This is typically called before * schedule() or do_signal() when returning to userspace. We do it * in C to avoid the burden of dealing with lockdep etc... + * + * NOTE: This is called with interrupts hard disabled but not marked + * as such in paca->irq_happened, so we need to resync this. */ void restore_interrupts(void) { - if (irqs_disabled()) + if (irqs_disabled()) { + local_paca->irq_happened |= PACA_IRQ_HARD_DIS; local_irq_enable(); + } else + __hard_irq_enable(); } #endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 6aa0c66..1589723 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c
@@ -248,7 +248,7 @@ addr, regs->nip, regs->link, code); } - if (!arch_irq_disabled_regs(regs)) + if (arch_irqs_disabled() && !arch_irq_disabled_regs(regs)) local_irq_enable(); memset(&info, 0, sizeof(info)); @@ -1019,7 +1019,9 @@ return; } - local_irq_enable(); + /* We restore the interrupt state now */ + if (!arch_irq_disabled_regs(regs)) + local_irq_enable(); #ifdef CONFIG_MATH_EMULATION /* (reason & REASON_ILLEGAL) would be the obvious thing here, @@ -1069,6 +1071,10 @@ { int sig, code, fixed = 0; + /* We restore the interrupt state now */ + if (!arch_irq_disabled_regs(regs)) + local_irq_enable(); + /* we don't implement logging of alignment exceptions */ if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) fixed = fix_alignment(regs);
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index 6f87f39..10fc8ec 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c
@@ -194,14 +194,14 @@ backwards_map = !backwards_map; /* Uh-oh ... out of mappings. Let's flush! */ - if (vcpu_book3s->vsid_next == vcpu_book3s->vsid_max) { - vcpu_book3s->vsid_next = vcpu_book3s->vsid_first; + if (vcpu_book3s->proto_vsid_next == vcpu_book3s->proto_vsid_max) { + vcpu_book3s->proto_vsid_next = vcpu_book3s->proto_vsid_first; memset(vcpu_book3s->sid_map, 0, sizeof(struct kvmppc_sid_map) * SID_MAP_NUM); kvmppc_mmu_pte_flush(vcpu, 0, 0); kvmppc_mmu_flush_segments(vcpu); } - map->host_vsid = vcpu_book3s->vsid_next++; + map->host_vsid = vsid_scramble(vcpu_book3s->proto_vsid_next++, 256M); map->guest_vsid = gvsid; map->valid = true; @@ -319,9 +319,10 @@ return -1; vcpu3s->context_id[0] = err; - vcpu3s->vsid_max = ((vcpu3s->context_id[0] + 1) << USER_ESID_BITS) - 1; - vcpu3s->vsid_first = vcpu3s->context_id[0] << USER_ESID_BITS; - vcpu3s->vsid_next = vcpu3s->vsid_first; + vcpu3s->proto_vsid_max = ((vcpu3s->context_id[0] + 1) + << USER_ESID_BITS) - 1; + vcpu3s->proto_vsid_first = vcpu3s->context_id[0] << USER_ESID_BITS; + vcpu3s->proto_vsid_next = vcpu3s->proto_vsid_first; kvmppc_mmu_hpte_init(vcpu);
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index ddc485a..c3beaee 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -258,6 +258,8 @@ !(memslot->userspace_addr & (s - 1))) { start &= ~(s - 1); pgsize = s; + get_page(hpage); + put_page(page); page = hpage; } } @@ -281,11 +283,8 @@ err = 0; out: - if (got) { - if (PageHuge(page)) - page = compound_head(page); + if (got) put_page(page); - } return err; up_err: @@ -678,8 +677,15 @@ SetPageDirty(page); out_put: - if (page) - put_page(page); + if (page) { + /* + * We drop pages[0] here, not page because page might + * have been set to the head page of a compound, but + * we have to drop the reference on the correct tail + * page to match the get inside gup() + */ + put_page(pages[0]); + } return ret; out_unlock: @@ -979,6 +985,7 @@ pa = *physp; } page = pfn_to_page(pa >> PAGE_SHIFT); + get_page(page); } else { hva = gfn_to_hva_memslot(memslot, gfn); npages = get_user_pages_fast(hva, 1, 1, pages); @@ -991,8 +998,6 @@ page = compound_head(page); psize <<= compound_order(page); } - if (!kvm->arch.using_mmu_notifiers) - get_page(page); offset = gpa & (psize - 1); if (nb_ret) *nb_ret = psize - offset; @@ -1003,7 +1008,6 @@ { struct page *page = virt_to_page(va); - page = compound_head(page); put_page(page); }
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 01294a5..108d1f5 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1192,8 +1192,6 @@ continue; pfn = physp[j] >> PAGE_SHIFT; page = pfn_to_page(pfn); - if (PageHuge(page)) - page = compound_head(page); SetPageDirty(page); put_page(page); }
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index def880a..cec4dad 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -463,6 +463,7 @@ /* insert R and C bits from PTE */ rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C); args[j] |= rcbits << (56 - 5); + hp[0] = 0; continue; }
diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S index 0676ae2..6e6e9ce 100644 --- a/arch/powerpc/kvm/book3s_segment.S +++ b/arch/powerpc/kvm/book3s_segment.S
@@ -197,7 +197,8 @@ /* Save guest PC and MSR */ #ifdef CONFIG_PPC64 BEGIN_FTR_SECTION - andi. r0,r12,0x2 + andi. r0, r12, 0x2 + cmpwi cr1, r0, 0 beq 1f mfspr r3,SPRN_HSRR0 mfspr r4,SPRN_HSRR1 @@ -250,6 +251,12 @@ beq ld_last_prev_inst cmpwi r12, BOOK3S_INTERRUPT_ALIGNMENT beq- ld_last_inst +#ifdef CONFIG_PPC64 +BEGIN_FTR_SECTION + cmpwi r12, BOOK3S_INTERRUPT_H_EMUL_ASSIST + beq- ld_last_inst +END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) +#endif b no_ld_last_inst @@ -316,23 +323,17 @@ * Having set up SRR0/1 with the address where we want * to continue with relocation on (potentially in module * space), we either just go straight there with rfi[d], - * or we jump to an interrupt handler with bctr if there - * is an interrupt to be handled first. In the latter - * case, the rfi[d] at the end of the interrupt handler - * will get us back to where we want to continue. + * or we jump to an interrupt handler if there is an + * interrupt to be handled first. In the latter case, + * the rfi[d] at the end of the interrupt handler will + * get us back to where we want to continue. */ - cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL - beq 1f - cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER - beq 1f - cmpwi r12, BOOK3S_INTERRUPT_PERFMON -1: mtctr r12 - /* Register usage at this point: * * R1 = host R1 * R2 = host R2 + * R10 = raw exit handler id * R12 = exit handler id * R13 = shadow vcpu (32-bit) or PACA (64-bit) * SVCPU.* = guest * @@ -342,12 +343,25 @@ PPC_LL r6, HSTATE_HOST_MSR(r13) PPC_LL r8, HSTATE_VMHANDLER(r13) - /* Restore host msr -> SRR1 */ +#ifdef CONFIG_PPC64 +BEGIN_FTR_SECTION + beq cr1, 1f + mtspr SPRN_HSRR1, r6 + mtspr SPRN_HSRR0, r8 +END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) +#endif +1: /* Restore host msr -> SRR1 */ mtsrr1 r6 /* Load highmem handler address */ mtsrr0 r8 /* RFI into the highmem handler, or jump to interrupt handler */ - beqctr + cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL + beqa BOOK3S_INTERRUPT_EXTERNAL + cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER + beqa BOOK3S_INTERRUPT_DECREMENTER + cmpwi r12, BOOK3S_INTERRUPT_PERFMON + beqa BOOK3S_INTERRUPT_PERFMON + RFI kvmppc_handler_trampoline_exit_end:
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 9015060..b42f286 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig
@@ -217,7 +217,7 @@ def_bool y prompt "Kernel support for 31 bit emulation" depends on 64BIT - select COMPAT_BINFMT_ELF + select COMPAT_BINFMT_ELF if BINFMT_ELF select ARCH_WANT_OLD_COMPAT_IPC help Select this option if you want to enable your system kernel to @@ -234,6 +234,25 @@ config AUDIT_ARCH def_bool y +config HAVE_MARCH_Z900_FEATURES + def_bool n + +config HAVE_MARCH_Z990_FEATURES + def_bool n + select HAVE_MARCH_Z900_FEATURES + +config HAVE_MARCH_Z9_109_FEATURES + def_bool n + select HAVE_MARCH_Z990_FEATURES + +config HAVE_MARCH_Z10_FEATURES + def_bool n + select HAVE_MARCH_Z9_109_FEATURES + +config HAVE_MARCH_Z196_FEATURES + def_bool n + select HAVE_MARCH_Z10_FEATURES + comment "Code generation options" choice @@ -249,6 +268,7 @@ config MARCH_Z900 bool "IBM zSeries model z800 and z900" + select HAVE_MARCH_Z900_FEATURES if 64BIT help Select this to enable optimizations for model z800/z900 (2064 and 2066 series). This will enable some optimizations that are not @@ -256,6 +276,7 @@ config MARCH_Z990 bool "IBM zSeries model z890 and z990" + select HAVE_MARCH_Z990_FEATURES if 64BIT help Select this to enable optimizations for model z890/z990 (2084 and 2086 series). The kernel will be slightly faster but will not work @@ -263,6 +284,7 @@ config MARCH_Z9_109 bool "IBM System z9" + select HAVE_MARCH_Z9_109_FEATURES if 64BIT help Select this to enable optimizations for IBM System z9 (2094 and 2096 series). The kernel will be slightly faster but will not work @@ -270,6 +292,7 @@ config MARCH_Z10 bool "IBM System z10" + select HAVE_MARCH_Z10_FEATURES if 64BIT help Select this to enable optimizations for IBM System z10 (2097 and 2098 series). The kernel will be slightly faster but will not work @@ -277,6 +300,7 @@ config MARCH_Z196 bool "IBM zEnterprise 114 and 196" + select HAVE_MARCH_Z196_FEATURES if 64BIT help Select this to enable optimizations for IBM zEnterprise 114 and 196 (2818 and 2817 series). The kernel will be slightly faster but will @@ -406,33 +430,6 @@ comment "Misc" -config IPL - def_bool y - prompt "Builtin IPL record support" - help - If you want to use the produced kernel to IPL directly from a - device, you have to merge a bootsector specific to the device - into the first bytes of the kernel. You will have to select the - IPL device. - -choice - prompt "IPL method generated into head.S" - depends on IPL - default IPL_VM - help - Select "tape" if you want to IPL the image from a Tape. - - Select "vm_reader" if you are running under VM/ESA and want - to IPL the image from the emulated card reader. - -config IPL_TAPE - bool "tape" - -config IPL_VM - bool "vm_reader" - -endchoice - source "fs/Kconfig.binfmt" config FORCE_MAX_ZONEORDER @@ -569,7 +566,7 @@ config CRASH_DUMP bool "kernel crash dumps" - depends on 64BIT + depends on 64BIT && SMP select KEXEC help Generate crash dump after being started by kexec.
diff --git a/arch/s390/boot/.gitignore b/arch/s390/boot/.gitignore new file mode 100644 index 0000000..017d591 --- /dev/null +++ b/arch/s390/boot/.gitignore
@@ -0,0 +1,2 @@ +image +bzImage
diff --git a/arch/s390/boot/compressed/.gitignore b/arch/s390/boot/compressed/.gitignore new file mode 100644 index 0000000..ae06b9b --- /dev/null +++ b/arch/s390/boot/compressed/.gitignore
@@ -0,0 +1,3 @@ +sizes.h +vmlinux +vmlinux.lds
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 1957a9d..37d2bf2 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig
@@ -155,7 +155,6 @@ CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_DES=m CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SALSA20=m
diff --git a/arch/s390/include/asm/barrier.h b/arch/s390/include/asm/barrier.h index 451273a..10a5088 100644 --- a/arch/s390/include/asm/barrier.h +++ b/arch/s390/include/asm/barrier.h
@@ -11,25 +11,28 @@ * Force strict CPU ordering. * And yes, this is required on UP too when we're talking * to devices. - * - * This is very similar to the ppc eieio/sync instruction in that is - * does a checkpoint syncronisation & makes sure that - * all memory ops have completed wrt other CPU's ( see 7-15 POP DJB ). */ -#define eieio() asm volatile("bcr 15,0" : : : "memory") -#define SYNC_OTHER_CORES(x) eieio() -#define mb() eieio() -#define rmb() eieio() -#define wmb() eieio() -#define read_barrier_depends() do { } while(0) -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define smp_read_barrier_depends() read_barrier_depends() -#define smp_mb__before_clear_bit() smp_mb() -#define smp_mb__after_clear_bit() smp_mb() +static inline void mb(void) +{ +#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES + /* Fast-BCR without checkpoint synchronization */ + asm volatile("bcr 14,0" : : : "memory"); +#else + asm volatile("bcr 15,0" : : : "memory"); +#endif +} -#define set_mb(var, value) do { var = value; mb(); } while (0) +#define rmb() mb() +#define wmb() mb() +#define read_barrier_depends() do { } while(0) +#define smp_mb() mb() +#define smp_rmb() rmb() +#define smp_wmb() wmb() +#define smp_read_barrier_depends() read_barrier_depends() +#define smp_mb__before_clear_bit() smp_mb() +#define smp_mb__after_clear_bit() smp_mb() + +#define set_mb(var, value) do { var = value; mb(); } while (0) #endif /* __ASM_BARRIER_H */
diff --git a/arch/s390/include/asm/ccwgroup.h b/arch/s390/include/asm/ccwgroup.h index f2ea2c5..f2ef34f 100644 --- a/arch/s390/include/asm/ccwgroup.h +++ b/arch/s390/include/asm/ccwgroup.h
@@ -29,9 +29,7 @@ /** * struct ccwgroup_driver - driver for ccw group devices - * @max_slaves: maximum number of slave devices - * @driver_id: unique id - * @probe: function called on probe + * @setup: function called during device creation to setup the device * @remove: function called on remove * @set_online: function called when device is set online * @set_offline: function called when device is set offline @@ -44,10 +42,7 @@ * @driver: embedded driver structure */ struct ccwgroup_driver { - int max_slaves; - unsigned long driver_id; - - int (*probe) (struct ccwgroup_device *); + int (*setup) (struct ccwgroup_device *); void (*remove) (struct ccwgroup_device *); int (*set_online) (struct ccwgroup_device *); int (*set_offline) (struct ccwgroup_device *); @@ -63,9 +58,8 @@ extern int ccwgroup_driver_register (struct ccwgroup_driver *cdriver); extern void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver); -int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, - struct ccw_driver *cdrv, int num_devices, - const char *buf); +int ccwgroup_create_dev(struct device *root, struct ccwgroup_driver *gdrv, + int num_devices, const char *buf); extern int ccwgroup_probe_ccwdev(struct ccw_device *cdev); extern void ccwgroup_remove_ccwdev(struct ccw_device *cdev);
diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h index b7ff6af..27216d3 100644 --- a/arch/s390/include/asm/io.h +++ b/arch/s390/include/asm/io.h
@@ -38,11 +38,8 @@ return (void *) address; } -/* - * Convert a physical pointer to a virtual kernel pointer for /dev/mem - * access - */ -#define xlate_dev_mem_ptr(p) __va(p) +void *xlate_dev_mem_ptr(unsigned long phys); +void unxlate_dev_mem_ptr(unsigned long phys, void *addr); /* * Convert a virtual cached pointer to an uncached pointer
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h index d75c8e7..f039d86 100644 --- a/arch/s390/include/asm/qdio.h +++ b/arch/s390/include/asm/qdio.h
@@ -258,11 +258,6 @@ u8 val[QDIO_MAX_BUFFERS_PER_Q]; } __attribute__ ((packed, aligned(256))); -#define CHSC_AC2_MULTI_BUFFER_AVAILABLE 0x0080 -#define CHSC_AC2_MULTI_BUFFER_ENABLED 0x0040 -#define CHSC_AC2_DATA_DIV_AVAILABLE 0x0010 -#define CHSC_AC2_DATA_DIV_ENABLED 0x0002 - /** * struct qdio_outbuf_state - SBAL related asynchronous operation information * (for communication with upper layer programs) @@ -293,6 +288,8 @@ #define AC1_SC_QEBSM_AVAILABLE 0x02 /* available for subchannel */ #define AC1_SC_QEBSM_ENABLED 0x01 /* enabled for subchannel */ +#define CHSC_AC2_MULTI_BUFFER_AVAILABLE 0x0080 +#define CHSC_AC2_MULTI_BUFFER_ENABLED 0x0040 #define CHSC_AC2_DATA_DIV_AVAILABLE 0x0010 #define CHSC_AC2_DATA_DIV_ENABLED 0x0002 @@ -328,11 +325,13 @@ int, int, unsigned long); /* qdio errors reported to the upper-layer program */ -#define QDIO_ERROR_SIGA_TARGET 0x02 -#define QDIO_ERROR_SIGA_ACCESS_EXCEPTION 0x10 -#define QDIO_ERROR_SIGA_BUSY 0x20 -#define QDIO_ERROR_ACTIVATE_CHECK_CONDITION 0x40 -#define QDIO_ERROR_SLSB_STATE 0x80 +#define QDIO_ERROR_ACTIVATE 0x0001 +#define QDIO_ERROR_GET_BUF_STATE 0x0002 +#define QDIO_ERROR_SET_BUF_STATE 0x0004 +#define QDIO_ERROR_SLSB_STATE 0x0100 + +#define QDIO_ERROR_FATAL 0x00ff +#define QDIO_ERROR_TEMPORARY 0xff00 /* for qdio_cleanup */ #define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index b21e46e..7244e1f 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h
@@ -82,7 +82,6 @@ #define MACHINE_FLAG_LPAR (1UL << 12) #define MACHINE_FLAG_SPP (1UL << 13) #define MACHINE_FLAG_TOPOLOGY (1UL << 14) -#define MACHINE_FLAG_STCKF (1UL << 15) #define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM) #define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM) @@ -101,7 +100,6 @@ #define MACHINE_HAS_PFMF (0) #define MACHINE_HAS_SPP (0) #define MACHINE_HAS_TOPOLOGY (0) -#define MACHINE_HAS_STCKF (0) #else /* __s390x__ */ #define MACHINE_HAS_IEEE (1) #define MACHINE_HAS_CSP (1) @@ -113,7 +111,6 @@ #define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF) #define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP) #define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY) -#define MACHINE_HAS_STCKF (S390_lowcore.machine_flags & MACHINE_FLAG_STCKF) #endif /* __s390x__ */ #define ZFCPDUMP_HSA_SIZE (32UL<<20)
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index a730381..003b04e 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h
@@ -95,7 +95,6 @@ #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ #define TIF_SECCOMP 10 /* secure computing */ #define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */ -#define TIF_SIE 12 /* guest execution active */ #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_31BIT 17 /* 32bit process */ @@ -114,7 +113,6 @@ #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) #define _TIF_SECCOMP (1<<TIF_SECCOMP) #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) -#define _TIF_SIE (1<<TIF_SIE) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_31BIT (1<<TIF_31BIT) #define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP)
diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index c447a27..239ece9 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h
@@ -73,11 +73,15 @@ typedef unsigned long long cycles_t; -static inline unsigned long long get_clock (void) +static inline unsigned long long get_clock(void) { unsigned long long clk; +#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES + asm volatile(".insn s,0xb27c0000,%0" : "=Q" (clk) : : "cc"); +#else asm volatile("stck %0" : "=Q" (clk) : : "cc"); +#endif return clk; } @@ -86,17 +90,6 @@ asm volatile("stcke %0" : "=Q" (*clk) : : "cc"); } -static inline unsigned long long get_clock_fast(void) -{ - unsigned long long clk; - - if (MACHINE_HAS_STCKF) - asm volatile(".insn s,0xb27c0000,%0" : "=Q" (clk) : : "cc"); - else - clk = get_clock(); - return clk; -} - static inline unsigned long long get_clock_xt(void) { unsigned char clk[16];
diff --git a/arch/s390/kernel/.gitignore b/arch/s390/kernel/.gitignore new file mode 100644 index 0000000..c5f676c --- /dev/null +++ b/arch/s390/kernel/.gitignore
@@ -0,0 +1 @@ +vmlinux.lds
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index 28040fd..377c096 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c
@@ -437,13 +437,6 @@ sp = current->sas_ss_sp + current->sas_ss_size; } - /* This is the legacy signal stack switching. */ - else if (!user_mode(regs) && - !(ka->sa.sa_flags & SA_RESTORER) && - ka->sa.sa_restorer) { - sp = (unsigned long) ka->sa.sa_restorer; - } - return (void __user *)((sp - frame_size) & -8ul); }
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 9475e68..d84181f 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c
@@ -374,8 +374,6 @@ S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; if (test_facility(40)) S390_lowcore.machine_flags |= MACHINE_FLAG_SPP; - if (test_facility(25)) - S390_lowcore.machine_flags |= MACHINE_FLAG_STCKF; #endif }
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 74ee563..1ae93b5 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S
@@ -145,22 +145,23 @@ * gpr2 = prev */ ENTRY(__switch_to) + stm %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task + st %r15,__THREAD_ksp(%r2) # store kernel stack of prev l %r4,__THREAD_info(%r2) # get thread_info of prev l %r5,__THREAD_info(%r3) # get thread_info of next + lr %r15,%r5 + ahi %r15,STACK_SIZE # end of kernel stack of next + st %r3,__LC_CURRENT # store task struct of next + st %r5,__LC_THREAD_INFO # store thread info of next + st %r15,__LC_KERNEL_STACK # store end of kernel stack + lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 + mvc __LC_CURRENT_PID(4,%r0),__TASK_pid(%r3) # store pid of next + l %r15,__THREAD_ksp(%r3) # load kernel stack of next tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending? jz 0f ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev oi __TI_flags+3(%r5),_TIF_MCCK_PENDING # set it in next -0: stm %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task - st %r15,__THREAD_ksp(%r2) # store kernel stack of prev - l %r15,__THREAD_ksp(%r3) # load kernel stack of next - lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 - lm %r6,%r15,__SF_GPRS(%r15) # load gprs of next task - st %r3,__LC_CURRENT # store task struct of next - mvc __LC_CURRENT_PID(4,%r0),__TASK_pid(%r3) # store pid of next - st %r5,__LC_THREAD_INFO # store thread info of next - ahi %r5,STACK_SIZE # end of kernel stack of next - st %r5,__LC_KERNEL_STACK # store end of kernel stack +0: lm %r6,%r15,__SF_GPRS(%r15) # load gprs of next task br %r14 __critical_start:
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 4e1c292..229fe1d 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S
@@ -81,16 +81,14 @@ .macro HANDLE_SIE_INTERCEPT scratch #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) - tm __TI_flags+6(%r12),_TIF_SIE>>8 - jz .+42 - tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP - jz .+8 - .insn s,0xb2800000,BASED(.Lhost_id) # set host id + tmhh %r8,0x0001 # interrupting from user ? + jnz .+42 lgr \scratch,%r9 slg \scratch,BASED(.Lsie_loop) clg \scratch,BASED(.Lsie_length) - jhe .+10 + jhe .+22 lg %r9,BASED(.Lsie_loop) + SPP BASED(.Lhost_id) # set host id #endif .endm @@ -148,6 +146,14 @@ ssm __LC_RETURN_PSW .endm + .macro STCK savearea +#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES + .insn s,0xb27c0000,\savearea # store clock fast +#else + .insn s,0xb2050000,\savearea # store clock +#endif + .endm + .section .kprobes.text, "ax" /* @@ -158,22 +164,23 @@ * gpr2 = prev */ ENTRY(__switch_to) + stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task + stg %r15,__THREAD_ksp(%r2) # store kernel stack of prev lg %r4,__THREAD_info(%r2) # get thread_info of prev lg %r5,__THREAD_info(%r3) # get thread_info of next + lgr %r15,%r5 + aghi %r15,STACK_SIZE # end of kernel stack of next + stg %r3,__LC_CURRENT # store task struct of next + stg %r5,__LC_THREAD_INFO # store thread info of next + stg %r15,__LC_KERNEL_STACK # store end of kernel stack + lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 + mvc __LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next + lg %r15,__THREAD_ksp(%r3) # load kernel stack of next tm __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending? jz 0f ni __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev oi __TI_flags+7(%r5),_TIF_MCCK_PENDING # set it in next -0: stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task - stg %r15,__THREAD_ksp(%r2) # store kernel stack of prev - lg %r15,__THREAD_ksp(%r3) # load kernel stack of next - lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 - lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task - stg %r3,__LC_CURRENT # store task struct of next - mvc __LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next - stg %r5,__LC_THREAD_INFO # store thread info of next - aghi %r5,STACK_SIZE # end of kernel stack of next - stg %r5,__LC_KERNEL_STACK # store end of kernel stack +0: lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task br %r14 __critical_start: @@ -458,7 +465,7 @@ * IO interrupt handler routine */ ENTRY(io_int_handler) - stck __LC_INT_CLOCK + STCK __LC_INT_CLOCK stpt __LC_ASYNC_ENTER_TIMER stmg %r8,%r15,__LC_SAVE_AREA_ASYNC lg %r10,__LC_LAST_BREAK @@ -604,7 +611,7 @@ * External interrupt handler routine */ ENTRY(ext_int_handler) - stck __LC_INT_CLOCK + STCK __LC_INT_CLOCK stpt __LC_ASYNC_ENTER_TIMER stmg %r8,%r15,__LC_SAVE_AREA_ASYNC lg %r10,__LC_LAST_BREAK @@ -622,6 +629,7 @@ mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC stmg %r8,%r9,__PT_PSW(%r11) TRACE_IRQS_OFF + xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) lghi %r1,4096 lgr %r2,%r11 # pass pointer to pt_regs llgf %r3,__LC_EXT_CPU_ADDR # get cpu address + interruption code @@ -638,7 +646,7 @@ larl %r1,psw_idle_lpsw+4 stg %r1,__SF_EMPTY+8(%r15) larl %r1,.Lvtimer_max - stck __IDLE_ENTER(%r2) + STCK __IDLE_ENTER(%r2) ltr %r5,%r5 stpt __VQ_IDLE_ENTER(%r3) jz psw_idle_lpsw @@ -654,7 +662,7 @@ * Machine check handler routines */ ENTRY(mcck_int_handler) - stck __LC_MCCK_CLOCK + STCK __LC_MCCK_CLOCK la %r1,4095 # revalidate r1 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs @@ -967,7 +975,6 @@ xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # host id == 0 lmg %r0,%r13,0(%r3) # load guest gprs 0-13 lg %r14,__LC_THREAD_INFO # pointer thread_info struct - oi __TI_flags+6(%r14),_TIF_SIE>>8 sie_loop: lg %r14,__LC_THREAD_INFO # pointer thread_info struct tm __TI_flags+7(%r14),_TIF_EXIT_SIE @@ -985,7 +992,6 @@ lg %r14,__LC_THREAD_INFO # pointer thread_info struct sie_exit: lctlg %c1,%c1,__LC_USER_ASCE # load primary asce - ni __TI_flags+6(%r14),255-(_TIF_SIE>>8) lg %r14,__SF_EMPTY+8(%r15) # load guest register save area stmg %r0,%r13,0(%r14) # save guest gprs 0-13 lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers @@ -994,7 +1000,6 @@ sie_fault: lctlg %c1,%c1,__LC_USER_ASCE # load primary asce lg %r14,__LC_THREAD_INFO # pointer thread_info struct - ni __TI_flags+6(%r14),255-(_TIF_SIE>>8) lg %r14,__SF_EMPTY+8(%r15) # load guest register save area stmg %r0,%r13,0(%r14) # save guest gprs 0-13 lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index adccd90..4939d15 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S
@@ -34,125 +34,7 @@ #endif __HEAD -#ifndef CONFIG_IPL - .org 0 - .long 0x00080000,0x80000000+startup # Just a restart PSW -#else -#ifdef CONFIG_IPL_TAPE -#define IPL_BS 1024 - .org 0 - .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded - .long 0x27000000,0x60000001 # by ipl to addresses 0-23. - .long 0x02000000,0x20000000+IPL_BS # (a PSW and two CCWs). - .long 0x00000000,0x00000000 # external old psw - .long 0x00000000,0x00000000 # svc old psw - .long 0x00000000,0x00000000 # program check old psw - .long 0x00000000,0x00000000 # machine check old psw - .long 0x00000000,0x00000000 # io old psw - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x000a0000,0x00000058 # external new psw - .long 0x000a0000,0x00000060 # svc new psw - .long 0x000a0000,0x00000068 # program check new psw - .long 0x000a0000,0x00000070 # machine check new psw - .long 0x00080000,0x80000000+.Lioint # io new psw - .org 0x100 -# -# subroutine for loading from tape -# Parameters: -# R1 = device number -# R2 = load address -.Lloader: - st %r14,.Lldret - la %r3,.Lorbread # r3 = address of orb - la %r5,.Lirb # r5 = address of irb - st %r2,.Lccwread+4 # initialize CCW data addresses - lctl %c6,%c6,.Lcr6 - slr %r2,%r2 -.Lldlp: - la %r6,3 # 3 retries -.Lssch: - ssch 0(%r3) # load chunk of IPL_BS bytes - bnz .Llderr -.Lw4end: - bas %r14,.Lwait4io - tm 8(%r5),0x82 # do we have a problem ? - bnz .Lrecov - slr %r7,%r7 - icm %r7,3,10(%r5) # get residual count - lcr %r7,%r7 - la %r7,IPL_BS(%r7) # IPL_BS-residual=#bytes read - ar %r2,%r7 # add to total size - tm 8(%r5),0x01 # found a tape mark ? - bnz .Ldone - l %r0,.Lccwread+4 # update CCW data addresses - ar %r0,%r7 - st %r0,.Lccwread+4 - b .Lldlp -.Ldone: - l %r14,.Lldret - br %r14 # r2 contains the total size -.Lrecov: - bas %r14,.Lsense # do the sensing - bct %r6,.Lssch # dec. retry count & branch - b .Llderr -# -# Sense subroutine -# -.Lsense: - st %r14,.Lsnsret - la %r7,.Lorbsense - ssch 0(%r7) # start sense command - bnz .Llderr - bas %r14,.Lwait4io - l %r14,.Lsnsret - tm 8(%r5),0x82 # do we have a problem ? - bnz .Llderr - br %r14 -# -# Wait for interrupt subroutine -# -.Lwait4io: - lpsw .Lwaitpsw -.Lioint: - c %r1,0xb8 # compare subchannel number - bne .Lwait4io - tsch 0(%r5) - slr %r0,%r0 - tm 8(%r5),0x82 # do we have a problem ? - bnz .Lwtexit - tm 8(%r5),0x04 # got device end ? - bz .Lwait4io -.Lwtexit: - br %r14 -.Llderr: - lpsw .Lcrash - - .align 8 -.Lorbread: - .long 0x00000000,0x0080ff00,.Lccwread - .align 8 -.Lorbsense: - .long 0x00000000,0x0080ff00,.Lccwsense - .align 8 -.Lccwread: - .long 0x02200000+IPL_BS,0x00000000 -.Lccwsense: - .long 0x04200001,0x00000000 -.Lwaitpsw: - .long 0x020a0000,0x80000000+.Lioint - -.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -.Lcr6: .long 0xff000000 - .align 8 -.Lcrash:.long 0x000a0000,0x00000000 -.Lldret:.long 0 -.Lsnsret: .long 0 -#endif /* CONFIG_IPL_TAPE */ - -#ifdef CONFIG_IPL_VM #define IPL_BS 0x730 .org 0 .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded @@ -256,7 +138,6 @@ .long 0x02600050,0x00000000 .endr .long 0x02200050,0x00000000 -#endif /* CONFIG_IPL_VM */ iplstart: lh %r1,0xb8 # test if subchannel number @@ -325,7 +206,6 @@ clc 0(3,%r2),.L_eof bz .Lagain2 -#ifdef CONFIG_IPL_VM # # reset files in VM reader # @@ -358,7 +238,6 @@ .long 0x00080000,0x80000000+.Lrdrint .Lrdrwaitpsw: .long 0x020a0000,0x80000000+.Lrdrint -#endif # # everything loaded, go for it @@ -376,8 +255,6 @@ .L_eof: .long 0xc5d6c600 /* C'EOF' */ .L_hdr: .long 0xc8c4d900 /* C'HDR' */ -#endif /* CONFIG_IPL */ - # # SALIPL loader support. Based on a patch by Rob van der Heij. # This entry point is called directly from the SALIPL loader and
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index f7582b2..8a4e2b7 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c
@@ -235,13 +235,6 @@ sp = current->sas_ss_sp + current->sas_ss_size; } - /* This is the legacy signal stack switching. */ - else if (!user_mode(regs) && - !(ka->sa.sa_flags & SA_RESTORER) && - ka->sa.sa_restorer) { - sp = (unsigned long) ka->sa.sa_restorer; - } - return (void __user *)((sp - frame_size) & -8ul); } @@ -414,15 +407,6 @@ struct k_sigaction ka; sigset_t *oldset; - /* - * We want the common case to go fast, which - * is why we may in certain cases get here from - * kernel mode. Just return without doing anything - * if so. - */ - if (!user_mode(regs)) - return; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 1f77227..e505458 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c
@@ -226,6 +226,8 @@ return -ENOMEM; } +#ifdef CONFIG_HOTPLUG_CPU + static void pcpu_free_lowcore(struct pcpu *pcpu) { pcpu_sigp_retry(pcpu, sigp_set_prefix, 0); @@ -247,6 +249,8 @@ } } +#endif /* CONFIG_HOTPLUG_CPU */ + static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu) { struct _lowcore *lc = pcpu->lowcore;
diff --git a/arch/s390/kernel/vdso32/.gitignore b/arch/s390/kernel/vdso32/.gitignore new file mode 100644 index 0000000..e45fba9 --- /dev/null +++ b/arch/s390/kernel/vdso32/.gitignore
@@ -0,0 +1 @@ +vdso32.lds
diff --git a/arch/s390/kernel/vdso64/.gitignore b/arch/s390/kernel/vdso64/.gitignore new file mode 100644 index 0000000..3fd18cf --- /dev/null +++ b/arch/s390/kernel/vdso64/.gitignore
@@ -0,0 +1 @@ +vdso64.lds
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 46ef3fd..72cec9e 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c
@@ -294,7 +294,7 @@ down_read(&mm->mmap_sem); #ifdef CONFIG_PGSTE - if (test_tsk_thread_flag(current, TIF_SIE) && S390_lowcore.gmap) { + if ((current->flags & PF_VCPU) && S390_lowcore.gmap) { address = __gmap_fault(address, (struct gmap *) S390_lowcore.gmap); if (address == -EFAULT) { @@ -549,19 +549,15 @@ if ((subcode & 0xff00) != __SUBCODE_MASK) return; kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++; - if (subcode & 0x0080) { - /* Get the token (= pid of the affected task). */ - pid = sizeof(void *) == 4 ? param32 : param64; - rcu_read_lock(); - tsk = find_task_by_pid_ns(pid, &init_pid_ns); - if (tsk) - get_task_struct(tsk); - rcu_read_unlock(); - if (!tsk) - return; - } else { - tsk = current; - } + /* Get the token (= pid of the affected task). */ + pid = sizeof(void *) == 4 ? param32 : param64; + rcu_read_lock(); + tsk = find_task_by_pid_ns(pid, &init_pid_ns); + if (tsk) + get_task_struct(tsk); + rcu_read_unlock(); + if (!tsk) + return; spin_lock(&pfault_lock); if (subcode & 0x0080) { /* signal bit is set -> a page has been swapped in by VM */ @@ -574,6 +570,7 @@ tsk->thread.pfault_wait = 0; list_del(&tsk->thread.list); wake_up_process(tsk); + put_task_struct(tsk); } else { /* Completion interrupt was faster than initial * interrupt. Set pfault_wait to -1 so the initial @@ -585,24 +582,35 @@ if (tsk->state == TASK_RUNNING) tsk->thread.pfault_wait = -1; } - put_task_struct(tsk); } else { /* signal bit not set -> a real page is missing. */ - if (tsk->thread.pfault_wait == -1) { + if (WARN_ON_ONCE(tsk != current)) + goto out; + if (tsk->thread.pfault_wait == 1) { + /* Already on the list with a reference: put to sleep */ + __set_task_state(tsk, TASK_UNINTERRUPTIBLE); + set_tsk_need_resched(tsk); + } else if (tsk->thread.pfault_wait == -1) { /* Completion interrupt was faster than the initial * interrupt (pfault_wait == -1). Set pfault_wait * back to zero and exit. */ tsk->thread.pfault_wait = 0; } else { /* Initial interrupt arrived before completion - * interrupt. Let the task sleep. */ + * interrupt. Let the task sleep. + * An extra task reference is needed since a different + * cpu may set the task state to TASK_RUNNING again + * before the scheduler is reached. */ + get_task_struct(tsk); tsk->thread.pfault_wait = 1; list_add(&tsk->thread.list, &pfault_list); - set_task_state(tsk, TASK_UNINTERRUPTIBLE); + __set_task_state(tsk, TASK_UNINTERRUPTIBLE); set_tsk_need_resched(tsk); } } +out: spin_unlock(&pfault_lock); + put_task_struct(tsk); } static int __cpuinit pfault_cpu_notify(struct notifier_block *self, @@ -620,6 +628,7 @@ list_del(&thread->list); tsk = container_of(thread, struct task_struct, thread); wake_up_process(tsk); + put_task_struct(tsk); } spin_unlock_irq(&pfault_lock); break;
diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c index 597bb2d..900de2b 100644 --- a/arch/s390/mm/hugetlbpage.c +++ b/arch/s390/mm/hugetlbpage.c
@@ -58,6 +58,8 @@ ptep = (pte_t *) page[1].index; if (!ptep) return; + clear_table((unsigned long *) ptep, _PAGE_TYPE_EMPTY, + PTRS_PER_PTE * sizeof(pte_t)); page_table_free(&init_mm, (unsigned long *) ptep); page[1].index = 0; }
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index e1335dc..795a0a9 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c
@@ -12,6 +12,7 @@ #include <linux/types.h> #include <linux/errno.h> #include <linux/gfp.h> +#include <linux/cpu.h> #include <asm/ctl_reg.h> /* @@ -166,3 +167,69 @@ free_page((unsigned long) buf); return rc; } + +/* + * Check if physical address is within prefix or zero page + */ +static int is_swapped(unsigned long addr) +{ + unsigned long lc; + int cpu; + + if (addr < sizeof(struct _lowcore)) + return 1; + for_each_online_cpu(cpu) { + lc = (unsigned long) lowcore_ptr[cpu]; + if (addr > lc + sizeof(struct _lowcore) - 1 || addr < lc) + continue; + return 1; + } + return 0; +} + +/* + * Return swapped prefix or zero page address + */ +static unsigned long get_swapped(unsigned long addr) +{ + unsigned long prefix = store_prefix(); + + if (addr < sizeof(struct _lowcore)) + return addr + prefix; + if (addr >= prefix && addr < prefix + sizeof(struct _lowcore)) + return addr - prefix; + return addr; +} + +/* + * Convert a physical pointer for /dev/mem access + * + * For swapped prefix pages a new buffer is returned that contains a copy of + * the absolute memory. The buffer size is maximum one page large. + */ +void *xlate_dev_mem_ptr(unsigned long addr) +{ + void *bounce = (void *) addr; + unsigned long size; + + get_online_cpus(); + preempt_disable(); + if (is_swapped(addr)) { + size = PAGE_SIZE - (addr & ~PAGE_MASK); + bounce = (void *) __get_free_page(GFP_ATOMIC); + if (bounce) + memcpy_real(bounce, (void *) get_swapped(addr), size); + } + preempt_enable(); + put_online_cpus(); + return bounce; +} + +/* + * Free converted buffer for /dev/mem access (if necessary) + */ +void unxlate_dev_mem_ptr(unsigned long addr, void *buf) +{ + if ((void *) addr != buf) + free_page((unsigned long) buf); +}
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 6e765bf..a3db5a3 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c
@@ -822,6 +822,8 @@ /* we copy the mm and let dup_mm create the page tables with_pgstes */ tsk->mm->context.alloc_pgste = 1; + /* make sure that both mms have a correct rss state */ + sync_mm_rss(tsk->mm); mm = dup_mm(tsk); tsk->mm->context.alloc_pgste = 0; if (!mm)
diff --git a/arch/sparc/Kbuild b/arch/sparc/Kbuild new file mode 100644 index 0000000..5cd0116 --- /dev/null +++ b/arch/sparc/Kbuild
@@ -0,0 +1,8 @@ +# +# core part of the sparc kernel +# + +obj-y += kernel/ +obj-y += mm/ +obj-y += math-emu/ +obj-y += net/
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 5f6acce..d176c03 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig
@@ -62,6 +62,7 @@ select IRQ_PREFLOW_FASTEOI select ARCH_HAVE_NMI_SAFE_CMPXCHG select HAVE_C_RECORDMCOUNT + select NO_BOOTMEM config ARCH_DEFCONFIG string @@ -74,17 +75,12 @@ default 32 if SPARC32 default 64 if SPARC64 -config ARCH_USES_GETTIMEOFFSET - bool - default y if SPARC32 - config GENERIC_CMOS_UPDATE bool default y config GENERIC_CLOCKEVENTS - bool - default y if SPARC64 + def_bool y config IOMMU_HELPER bool @@ -155,7 +151,7 @@ menu "Processor type and features" config SMP - bool "Symmetric multi-processing support (does not work on sun4/sun4c)" + bool "Symmetric multi-processing support" ---help--- This enables support for systems with more than one CPU. If you have a system with only one CPU, say N. If you have a system with more
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index 0e5de13..b9a72e2 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile
@@ -19,39 +19,27 @@ # sparc32 # -# -# Uncomment the first KBUILD_CFLAGS if you are doing kgdb source level -# debugging of the kernel to get the proper debugging information. - -AS := $(AS) -32 -LDFLAGS := -m elf32_sparc CHECKFLAGS += -D__sparc__ +LDFLAGS := -m elf32_sparc export BITS := 32 UTS_MACHINE := sparc -#KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7 -KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7 -KBUILD_AFLAGS += -m32 -Wa,-Av8 - -#LDFLAGS_vmlinux = -N -Ttext 0xf0004000 -# Since 2.5.40, the first stage is left not btfix-ed. -# Actual linking is done with "make image". -LDFLAGS_vmlinux = -r +KBUILD_CFLAGS += -m32 -mcpu=v8 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7 +KBUILD_AFLAGS += -m32 -Wa,-Av8 else ##### # sparc64 # -CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -D__arch64__ -m64 +CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -D__arch64__ -m64 +LDFLAGS := -m elf64_sparc +export BITS := 64 +UTS_MACHINE := sparc64 -LDFLAGS := -m elf64_sparc -export BITS := 64 -UTS_MACHINE := sparc64 - -KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \ - -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \ - -Wa,--undeclared-regs +KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow +KBUILD_CFLAGS += -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare +KBUILD_CFLAGS += -Wa,--undeclared-regs KBUILD_CFLAGS += $(call cc-option,-mtune=ultrasparc3) KBUILD_AFLAGS += -m64 -mcpu=ultrasparc -Wa,--undeclared-regs @@ -64,26 +52,14 @@ head-y := arch/sparc/kernel/head_$(BITS).o head-y += arch/sparc/kernel/init_task.o -core-y += arch/sparc/kernel/ -core-y += arch/sparc/mm/ arch/sparc/math-emu/ -core-y += arch/sparc/net/ +# See arch/sparc/Kbuild for the core part of the kernel +core-y += arch/sparc/ libs-y += arch/sparc/prom/ libs-y += arch/sparc/lib/ drivers-$(CONFIG_OPROFILE) += arch/sparc/oprofile/ -# Export what is needed by arch/sparc/boot/Makefile -export VMLINUX_INIT VMLINUX_MAIN -VMLINUX_INIT := $(head-y) $(init-y) -VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/ -VMLINUX_MAIN += $(patsubst %/, %/lib.a, $(libs-y)) $(libs-y) -VMLINUX_MAIN += $(drivers-y) $(net-y) - -ifdef CONFIG_KALLSYMS -export kallsyms.o := .tmp_kallsyms2.o -endif - boot := arch/sparc/boot # Default target
diff --git a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile index d56d199..6e63afb 100644 --- a/arch/sparc/boot/Makefile +++ b/arch/sparc/boot/Makefile
@@ -6,8 +6,8 @@ ROOT_IMG := /usr/src/root.img ELFTOAOUT := elftoaout -hostprogs-y := piggyback btfixupprep -targets := tftpboot.img btfix.o btfix.S image zImage vmlinux.aout +hostprogs-y := piggyback +targets := tftpboot.img image zImage vmlinux.aout clean-files := System.map quiet_cmd_elftoaout = ELFTOAOUT $@ @@ -17,58 +17,9 @@ quiet_cmd_strip = STRIP $@ cmd_strip = $(STRIP) -R .comment -R .note -K sun4u_init -K _end -K _start $< -o $@ -ifeq ($(CONFIG_SPARC32),y) -quiet_cmd_btfix = BTFIX $@ - cmd_btfix = $(OBJDUMP) -x vmlinux | $(obj)/btfixupprep > $@ -quiet_cmd_sysmap = SYSMAP $(obj)/System.map - cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap -quiet_cmd_image = LD $@ - cmd_image = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_$(@F)) -o $@ - -define rule_image - $(if $($(quiet)cmd_image), \ - echo ' $($(quiet)cmd_image)' &&) \ - $(cmd_image); \ - $(if $($(quiet)cmd_sysmap), \ - echo ' $($(quiet)cmd_sysmap)' &&) \ - $(cmd_sysmap) $@ $(obj)/System.map; \ - if [ $$? -ne 0 ]; then \ - rm -f $@; \ - /bin/false; \ - fi; \ - echo 'cmd_$@ := $(cmd_image)' > $(@D)/.$(@F).cmd -endef - -BTOBJS := $(patsubst %/, %/built-in.o, $(VMLINUX_INIT)) -BTLIBS := $(patsubst %/, %/built-in.o, $(VMLINUX_MAIN)) -LDFLAGS_image := -T arch/sparc/kernel/vmlinux.lds $(BTOBJS) \ - --start-group $(BTLIBS) --end-group \ - $(kallsyms.o) $(obj)/btfix.o - -# Link the final image including btfixup'ed symbols. -# This is a replacement for the link done in the top-level Makefile. -# Note: No dependency on the prerequisite files since that would require -# make to try check if they are updated - and due to changes -# in gcc options (path for example) this would result in -# these files being recompiled for each build. -$(obj)/image: $(obj)/btfix.o FORCE - $(call if_changed_rule,image) - -$(obj)/zImage: $(obj)/image - $(call if_changed,strip) - @echo ' kernel: $@ is ready' - -$(obj)/btfix.S: $(obj)/btfixupprep vmlinux FORCE - $(call if_changed,btfix) - -endif - ifeq ($(CONFIG_SPARC64),y) # Actual linking -$(obj)/image: vmlinux FORCE - $(call if_changed,strip) - @echo ' kernel: $@ is ready' $(obj)/zImage: $(obj)/image $(call if_changed,gzip) @@ -79,6 +30,10 @@ @echo ' kernel: $@ is ready' else +$(obj)/zImage: $(obj)/image + $(call if_changed,strip) + @echo ' kernel: $@ is ready' + # The following lines make a readable image for U-Boot. # uImage - Binary file read by U-boot # uImage.o - object file of uImage for loading with a @@ -107,6 +62,10 @@ endif +$(obj)/image: vmlinux FORCE + $(call if_changed,strip) + @echo ' kernel: $@ is ready' + $(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback System.map $(ROOT_IMG) FORCE $(call if_changed,elftoaout) $(call if_changed,piggy)
diff --git a/arch/sparc/boot/btfixupprep.c b/arch/sparc/boot/btfixupprep.c deleted file mode 100644 index da03115..0000000 --- a/arch/sparc/boot/btfixupprep.c +++ /dev/null
@@ -1,386 +0,0 @@ -/* - Simple utility to prepare vmlinux image for sparc. - Resolves all BTFIXUP uses and settings and creates - a special .s object to link to the image. - - Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - - 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 <stdio.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <malloc.h> - -#define MAXSYMS 1024 - -static char *symtab = "SYMBOL TABLE:"; -static char *relrec = "RELOCATION RECORDS FOR ["; -static int rellen; -static int symlen; -int mode; - -struct _btfixup; - -typedef struct _btfixuprel { - char *sect; - unsigned long offset; - struct _btfixup *f; - int frel; - struct _btfixuprel *next; -} btfixuprel; - -typedef struct _btfixup { - int type; - int setinitval; - unsigned int initval; - char *initvalstr; - char *name; - btfixuprel *rel; -} btfixup; - -btfixup array[MAXSYMS]; -int last = 0; -char buffer[1024]; -unsigned long lastfoffset = -1; -unsigned long lastfrelno; -btfixup *lastf; - -static void fatal(void) __attribute__((noreturn)); -static void fatal(void) -{ - fprintf(stderr, "Malformed output from objdump\n%s\n", buffer); - exit(1); -} - -static btfixup *find(int type, char *name) -{ - int i; - for (i = 0; i < last; i++) { - if (array[i].type == type && !strcmp(array[i].name, name)) - return array + i; - } - array[last].type = type; - array[last].name = strdup(name); - array[last].setinitval = 0; - if (!array[last].name) fatal(); - array[last].rel = NULL; - last++; - if (last >= MAXSYMS) { - fprintf(stderr, "Ugh. Something strange. More than %d different BTFIXUP symbols\n", MAXSYMS); - exit(1); - } - return array + last - 1; -} - -static void set_mode (char *buffer) -{ - for (mode = 0;; mode++) - if (buffer[mode] < '0' || buffer[mode] > '9') - break; - if (mode != 8 && mode != 16) - fatal(); -} - - -int main(int argc,char **argv) -{ - char *p, *q; - char *sect; - int i, j, k; - unsigned int initval; - int shift; - btfixup *f; - btfixuprel *r, **rr; - unsigned long offset; - char *initvalstr; - - symlen = strlen(symtab); - while (fgets (buffer, 1024, stdin) != NULL) - if (!strncmp (buffer, symtab, symlen)) - goto main0; - fatal(); -main0: - rellen = strlen(relrec); - while (fgets (buffer, 1024, stdin) != NULL) - if (!strncmp (buffer, relrec, rellen)) - goto main1; - fatal(); -main1: - sect = malloc(strlen (buffer + rellen) + 1); - if (!sect) fatal(); - strcpy (sect, buffer + rellen); - p = strchr (sect, ']'); - if (!p) fatal(); - *p = 0; - if (fgets (buffer, 1024, stdin) == NULL) - fatal(); - while (fgets (buffer, 1024, stdin) != NULL) { - int nbase; - if (!strncmp (buffer, relrec, rellen)) - goto main1; - if (mode == 0) - set_mode (buffer); - p = strchr (buffer, '\n'); - if (p) *p = 0; - if (strlen (buffer) < 22+mode) - continue; - if (strncmp (buffer + mode, " R_SPARC_", 9)) - continue; - nbase = 27 - 8 + mode; - if (buffer[nbase] != '_' || buffer[nbase+1] != '_' || buffer[nbase+2] != '_') - continue; - switch (buffer[nbase+3]) { - case 'f': /* CALL */ - case 'b': /* BLACKBOX */ - case 's': /* SIMM13 */ - case 'a': /* HALF */ - case 'h': /* SETHI */ - case 'i': /* INT */ - break; - default: - continue; - } - p = strchr (buffer + nbase+5, '+'); - if (p) *p = 0; - shift = nbase + 5; - if (buffer[nbase+4] == 's' && buffer[nbase+5] == '_') { - shift = nbase + 6; - if (strcmp (sect, ".init.text")) { - fprintf(stderr, - "Wrong use of '%s' BTFIXUPSET in '%s' section.\n" - "BTFIXUPSET_CALL can be used only in" - " __init sections\n", - buffer + shift, sect); - exit(1); - } - } else if (buffer[nbase+4] != '_') - continue; - if (!strcmp (sect, ".text.exit")) - continue; - if (strcmp (sect, ".text") && - strcmp (sect, ".init.text") && - strcmp (sect, ".fixup") && - (strcmp (sect, "__ksymtab") || buffer[nbase+3] != 'f')) { - if (buffer[nbase+3] == 'f') - fprintf(stderr, - "Wrong use of '%s' in '%s' section.\n" - " It can be used only in .text, .init.text," - " .fixup and __ksymtab\n", - buffer + shift, sect); - else - fprintf(stderr, - "Wrong use of '%s' in '%s' section.\n" - " It can be only used in .text, .init.text," - " and .fixup\n", buffer + shift, sect); - exit(1); - } - p = strstr (buffer + shift, "__btset_"); - if (p && buffer[nbase+4] == 's') { - fprintf(stderr, "__btset_ in BTFIXUP name can only be used when defining the variable, not for setting\n%s\n", buffer); - exit(1); - } - initval = 0; - initvalstr = NULL; - if (p) { - if (p[8] != '0' || p[9] != 'x') { - fprintf(stderr, "Pre-initialized values can be only initialized with hexadecimal constants starting 0x\n%s\n", buffer); - exit(1); - } - initval = strtoul(p + 10, &q, 16); - if (*q || !initval) { - fprintf(stderr, "Pre-initialized values can be only in the form name__btset_0xXXXXXXXX where X are hex digits.\nThey cannot be name__btset_0x00000000 though. Use BTFIXUPDEF_XX instead of BTFIXUPDEF_XX_INIT then.\n%s\n", buffer); - exit(1); - } - initvalstr = p + 10; - *p = 0; - } - f = find(buffer[nbase+3], buffer + shift); - if (buffer[nbase+4] == 's') - continue; - switch (buffer[nbase+3]) { - case 'f': - if (initval) { - fprintf(stderr, "Cannot use pre-initialized fixups for calls\n%s\n", buffer); - exit(1); - } - if (!strcmp (sect, "__ksymtab")) { - if (strncmp (buffer + mode+9, "32 ", 10)) { - fprintf(stderr, "BTFIXUP_CALL in EXPORT_SYMBOL results in relocation other than R_SPARC_32\n\%s\n", buffer); - exit(1); - } - } else if (strncmp (buffer + mode+9, "WDISP30 ", 10) && - strncmp (buffer + mode+9, "HI22 ", 10) && - strncmp (buffer + mode+9, "LO10 ", 10)) { - fprintf(stderr, "BTFIXUP_CALL results in relocation other than R_SPARC_WDISP30, R_SPARC_HI22 or R_SPARC_LO10\n%s\n", buffer); - exit(1); - } - break; - case 'b': - if (initval) { - fprintf(stderr, "Cannot use pre-initialized fixups for blackboxes\n%s\n", buffer); - exit(1); - } - if (strncmp (buffer + mode+9, "HI22 ", 10)) { - fprintf(stderr, "BTFIXUP_BLACKBOX results in relocation other than R_SPARC_HI22\n%s\n", buffer); - exit(1); - } - break; - case 's': - if (initval + 0x1000 >= 0x2000) { - fprintf(stderr, "Wrong initializer for SIMM13. Has to be from $fffff000 to $00000fff\n%s\n", buffer); - exit(1); - } - if (strncmp (buffer + mode+9, "13 ", 10)) { - fprintf(stderr, "BTFIXUP_SIMM13 results in relocation other than R_SPARC_13\n%s\n", buffer); - exit(1); - } - break; - case 'a': - if (initval + 0x1000 >= 0x2000 && (initval & 0x3ff)) { - fprintf(stderr, "Wrong initializer for HALF.\n%s\n", buffer); - exit(1); - } - if (strncmp (buffer + mode+9, "13 ", 10)) { - fprintf(stderr, "BTFIXUP_HALF results in relocation other than R_SPARC_13\n%s\n", buffer); - exit(1); - } - break; - case 'h': - if (initval & 0x3ff) { - fprintf(stderr, "Wrong initializer for SETHI. Cannot have set low 10 bits\n%s\n", buffer); - exit(1); - } - if (strncmp (buffer + mode+9, "HI22 ", 10)) { - fprintf(stderr, "BTFIXUP_SETHI results in relocation other than R_SPARC_HI22\n%s\n", buffer); - exit(1); - } - break; - case 'i': - if (initval) { - fprintf(stderr, "Cannot use pre-initialized fixups for INT\n%s\n", buffer); - exit(1); - } - if (strncmp (buffer + mode+9, "HI22 ", 10) && strncmp (buffer + mode+9, "LO10 ", 10)) { - fprintf(stderr, "BTFIXUP_INT results in relocation other than R_SPARC_HI22 and R_SPARC_LO10\n%s\n", buffer); - exit(1); - } - break; - } - if (!f->setinitval) { - f->initval = initval; - if (initvalstr) { - f->initvalstr = strdup(initvalstr); - if (!f->initvalstr) fatal(); - } - f->setinitval = 1; - } else if (f->initval != initval) { - fprintf(stderr, "Btfixup %s previously used with initializer %s which doesn't match with current initializer\n%s\n", - f->name, f->initvalstr ? : "0x00000000", buffer); - exit(1); - } else if (initval && strcmp(f->initvalstr, initvalstr)) { - fprintf(stderr, "Btfixup %s previously used with initializer %s which doesn't match with current initializer.\n" - "Initializers have to match literally as well.\n%s\n", - f->name, f->initvalstr, buffer); - exit(1); - } - offset = strtoul(buffer, &q, 16); - if (q != buffer + mode || (!offset && (mode == 8 ? strncmp (buffer, "00000000 ", 9) : strncmp (buffer, "0000000000000000 ", 17)))) { - fprintf(stderr, "Malformed relocation address in\n%s\n", buffer); - exit(1); - } - for (k = 0, r = f->rel, rr = &f->rel; r; rr = &r->next, r = r->next, k++) - if (r->offset == offset && !strcmp(r->sect, sect)) { - fprintf(stderr, "Ugh. One address has two relocation records\n"); - exit(1); - } - *rr = malloc(sizeof(btfixuprel)); - if (!*rr) fatal(); - (*rr)->offset = offset; - (*rr)->f = NULL; - if (buffer[nbase+3] == 'f') { - lastf = f; - lastfoffset = offset; - lastfrelno = k; - } else if (lastfoffset + 4 == offset) { - (*rr)->f = lastf; - (*rr)->frel = lastfrelno; - } - (*rr)->sect = sect; - (*rr)->next = NULL; - } - printf("! Generated by btfixupprep. Do not edit.\n\n"); - printf("\t.section\t\".data..init\",#alloc,#write\n\t.align\t4\n\n"); - printf("\t.global\t___btfixup_start\n___btfixup_start:\n\n"); - for (i = 0; i < last; i++) { - f = array + i; - printf("\t.global\t___%cs_%s\n", f->type, f->name); - if (f->type == 'f') - printf("___%cs_%s:\n\t.word 0x%08x,0,0,", f->type, f->name, f->type << 24); - else - printf("___%cs_%s:\n\t.word 0x%08x,0,", f->type, f->name, f->type << 24); - for (j = 0, r = f->rel; r != NULL; j++, r = r->next); - if (j) - printf("%d\n\t.word\t", j * 2); - else - printf("0\n"); - for (r = f->rel, j--; r != NULL; j--, r = r->next) { - if (!strcmp (r->sect, ".text")) - printf ("_stext+0x%08lx", r->offset); - else if (!strcmp (r->sect, ".init.text")) - printf ("__init_begin+0x%08lx", r->offset); - else if (!strcmp (r->sect, "__ksymtab")) - printf ("__start___ksymtab+0x%08lx", r->offset); - else if (!strcmp (r->sect, ".fixup")) - printf ("__start___fixup+0x%08lx", r->offset); - else - fatal(); - if (f->type == 'f' || !r->f) - printf (",0"); - else - printf (",___fs_%s+0x%08x", r->f->name, (4 + r->frel*2)*4 + 4); - if (j) printf (","); - else printf ("\n"); - } - printf("\n"); - } - printf("\n\t.global\t___btfixup_end\n___btfixup_end:\n"); - printf("\n\n! Define undefined references\n\n"); - for (i = 0; i < last; i++) { - f = array + i; - if (f->type == 'f') { - printf("\t.global\t___f_%s\n", f->name); - printf("___f_%s:\n", f->name); - } - } - printf("\tretl\n\t nop\n\n"); - for (i = 0; i < last; i++) { - f = array + i; - if (f->type != 'f') { - if (!f->initval) { - printf("\t.global\t___%c_%s\n", f->type, f->name); - printf("___%c_%s = 0\n", f->type, f->name); - } else { - printf("\t.global\t___%c_%s__btset_0x%s\n", f->type, f->name, f->initvalstr); - printf("___%c_%s__btset_0x%s = 0x%08x\n", f->type, f->name, f->initvalstr, f->initval); - } - } - } - printf("\n\n"); - exit(0); -}
diff --git a/arch/sparc/include/asm/asi.h b/arch/sparc/include/asm/asi.h index b2e3db6..cbb93e5 100644 --- a/arch/sparc/include/asm/asi.h +++ b/arch/sparc/include/asm/asi.h
@@ -112,6 +112,20 @@ #define ASI_M_ACTION 0x4c /* Breakpoint Action Register (GNU/Viking) */ +/* LEON ASI */ +#define ASI_LEON_NOCACHE 0x01 + +#define ASI_LEON_DCACHE_MISS 0x01 + +#define ASI_LEON_CACHEREGS 0x02 +#define ASI_LEON_IFLUSH 0x10 +#define ASI_LEON_DFLUSH 0x11 + +#define ASI_LEON_MMUFLUSH 0x18 +#define ASI_LEON_MMUREGS 0x19 +#define ASI_LEON_BYPASS 0x1c +#define ASI_LEON_FLUSH_PAGE 0x10 + /* V9 Architecture mandary ASIs. */ #define ASI_N 0x04 /* Nucleus */ #define ASI_NL 0x0c /* Nucleus, little endian */
diff --git a/arch/sparc/include/asm/asmmacro.h b/arch/sparc/include/asm/asmmacro.h index a995bf8..02a172f 100644 --- a/arch/sparc/include/asm/asmmacro.h +++ b/arch/sparc/include/asm/asmmacro.h
@@ -6,17 +6,6 @@ #ifndef _SPARC_ASMMACRO_H #define _SPARC_ASMMACRO_H -#include <asm/btfixup.h> -#include <asm/asi.h> - -#define GET_PROCESSOR4M_ID(reg) \ - rd %tbr, %reg; \ - srl %reg, 12, %reg; \ - and %reg, 3, %reg; - -#define GET_PROCESSOR4D_ID(reg) \ - lda [%g0] ASI_M_VIKING_TMP1, %reg; - /* All trap entry points _must_ begin with this macro or else you * lose. It makes sure the kernel has a proper window so that * c-code can be called. @@ -31,10 +20,4 @@ /* All traps low-level code here must end with this macro. */ #define RESTORE_ALL b ret_trap_entry; clr %l6; -/* sun4 probably wants half word accesses to ASI_SEGMAP, while sun4c+ - likes byte accesses. These are to avoid ifdef mania. */ - -#define lduXa lduba -#define stXa stba - #endif /* !(_SPARC_ASMMACRO_H) */
diff --git a/arch/sparc/include/asm/btfixup.h b/arch/sparc/include/asm/btfixup.h deleted file mode 100644 index 797722c..0000000 --- a/arch/sparc/include/asm/btfixup.h +++ /dev/null
@@ -1,208 +0,0 @@ -/* - * asm/btfixup.h: Macros for boot time linking. - * - * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - */ - -#ifndef _SPARC_BTFIXUP_H -#define _SPARC_BTFIXUP_H - -#include <linux/init.h> - -#ifndef __ASSEMBLY__ - -#ifdef MODULE -extern unsigned int ___illegal_use_of_BTFIXUP_SIMM13_in_module(void); -extern unsigned int ___illegal_use_of_BTFIXUP_SETHI_in_module(void); -extern unsigned int ___illegal_use_of_BTFIXUP_HALF_in_module(void); -extern unsigned int ___illegal_use_of_BTFIXUP_INT_in_module(void); - -#define BTFIXUP_SIMM13(__name) ___illegal_use_of_BTFIXUP_SIMM13_in_module() -#define BTFIXUP_HALF(__name) ___illegal_use_of_BTFIXUP_HALF_in_module() -#define BTFIXUP_SETHI(__name) ___illegal_use_of_BTFIXUP_SETHI_in_module() -#define BTFIXUP_INT(__name) ___illegal_use_of_BTFIXUP_INT_in_module() -#define BTFIXUP_BLACKBOX(__name) ___illegal_use_of_BTFIXUP_BLACKBOX_in_module - -#else - -#define BTFIXUP_SIMM13(__name) ___sf_##__name() -#define BTFIXUP_HALF(__name) ___af_##__name() -#define BTFIXUP_SETHI(__name) ___hf_##__name() -#define BTFIXUP_INT(__name) ((unsigned int)&___i_##__name) -/* This must be written in assembly and present in a sethi */ -#define BTFIXUP_BLACKBOX(__name) ___b_##__name -#endif /* MODULE */ - -/* Fixup call xx */ - -#define BTFIXUPDEF_CALL(__type, __name, __args...) \ - extern __type ___f_##__name(__args); \ - extern unsigned ___fs_##__name[3]; -#define BTFIXUPDEF_CALL_CONST(__type, __name, __args...) \ - extern __type ___f_##__name(__args) __attribute_const__; \ - extern unsigned ___fs_##__name[3]; -#define BTFIXUP_CALL(__name) ___f_##__name - -#define BTFIXUPDEF_BLACKBOX(__name) \ - extern unsigned ___bs_##__name[2]; - -/* Put bottom 13bits into some register variable */ - -#define BTFIXUPDEF_SIMM13(__name) \ - static inline unsigned int ___sf_##__name(void) __attribute_const__; \ - extern unsigned ___ss_##__name[2]; \ - static inline unsigned int ___sf_##__name(void) { \ - unsigned int ret; \ - __asm__ ("or %%g0, ___s_" #__name ", %0" : "=r"(ret)); \ - return ret; \ - } -#define BTFIXUPDEF_SIMM13_INIT(__name,__val) \ - static inline unsigned int ___sf_##__name(void) __attribute_const__; \ - extern unsigned ___ss_##__name[2]; \ - static inline unsigned int ___sf_##__name(void) { \ - unsigned int ret; \ - __asm__ ("or %%g0, ___s_" #__name "__btset_" #__val ", %0" : "=r"(ret));\ - return ret; \ - } - -/* Put either bottom 13 bits, or upper 22 bits into some register variable - * (depending on the value, this will lead into sethi FIX, reg; or - * mov FIX, reg; ) - */ - -#define BTFIXUPDEF_HALF(__name) \ - static inline unsigned int ___af_##__name(void) __attribute_const__; \ - extern unsigned ___as_##__name[2]; \ - static inline unsigned int ___af_##__name(void) { \ - unsigned int ret; \ - __asm__ ("or %%g0, ___a_" #__name ", %0" : "=r"(ret)); \ - return ret; \ - } -#define BTFIXUPDEF_HALF_INIT(__name,__val) \ - static inline unsigned int ___af_##__name(void) __attribute_const__; \ - extern unsigned ___as_##__name[2]; \ - static inline unsigned int ___af_##__name(void) { \ - unsigned int ret; \ - __asm__ ("or %%g0, ___a_" #__name "__btset_" #__val ", %0" : "=r"(ret));\ - return ret; \ - } - -/* Put upper 22 bits into some register variable */ - -#define BTFIXUPDEF_SETHI(__name) \ - static inline unsigned int ___hf_##__name(void) __attribute_const__; \ - extern unsigned ___hs_##__name[2]; \ - static inline unsigned int ___hf_##__name(void) { \ - unsigned int ret; \ - __asm__ ("sethi %%hi(___h_" #__name "), %0" : "=r"(ret)); \ - return ret; \ - } -#define BTFIXUPDEF_SETHI_INIT(__name,__val) \ - static inline unsigned int ___hf_##__name(void) __attribute_const__; \ - extern unsigned ___hs_##__name[2]; \ - static inline unsigned int ___hf_##__name(void) { \ - unsigned int ret; \ - __asm__ ("sethi %%hi(___h_" #__name "__btset_" #__val "), %0" : \ - "=r"(ret)); \ - return ret; \ - } - -/* Put a full 32bit integer into some register variable */ - -#define BTFIXUPDEF_INT(__name) \ - extern unsigned char ___i_##__name; \ - extern unsigned ___is_##__name[2]; - -#define BTFIXUPCALL_NORM 0x00000000 /* Always call */ -#define BTFIXUPCALL_NOP 0x01000000 /* Possibly optimize to nop */ -#define BTFIXUPCALL_RETINT(i) (0x90102000|((i) & 0x1fff)) /* Possibly optimize to mov i, %o0 */ -#define BTFIXUPCALL_ORINT(i) (0x90122000|((i) & 0x1fff)) /* Possibly optimize to or %o0, i, %o0 */ -#define BTFIXUPCALL_RETO0 0x01000000 /* Return first parameter, actually a nop */ -#define BTFIXUPCALL_ANDNINT(i) (0x902a2000|((i) & 0x1fff)) /* Possibly optimize to andn %o0, i, %o0 */ -#define BTFIXUPCALL_SWAPO0O1 0xd27a0000 /* Possibly optimize to swap [%o0],%o1 */ -#define BTFIXUPCALL_SWAPO0G0 0xc07a0000 /* Possibly optimize to swap [%o0],%g0 */ -#define BTFIXUPCALL_SWAPG1G2 0xc4784000 /* Possibly optimize to swap [%g1],%g2 */ -#define BTFIXUPCALL_STG0O0 0xc0220000 /* Possibly optimize to st %g0,[%o0] */ -#define BTFIXUPCALL_STO1O0 0xd2220000 /* Possibly optimize to st %o1,[%o0] */ - -#define BTFIXUPSET_CALL(__name, __addr, __insn) \ - do { \ - ___fs_##__name[0] |= 1; \ - ___fs_##__name[1] = (unsigned long)__addr; \ - ___fs_##__name[2] = __insn; \ - } while (0) - -#define BTFIXUPSET_BLACKBOX(__name, __func) \ - do { \ - ___bs_##__name[0] |= 1; \ - ___bs_##__name[1] = (unsigned long)__func; \ - } while (0) - -#define BTFIXUPCOPY_CALL(__name, __from) \ - do { \ - ___fs_##__name[0] |= 1; \ - ___fs_##__name[1] = ___fs_##__from[1]; \ - ___fs_##__name[2] = ___fs_##__from[2]; \ - } while (0) - -#define BTFIXUPSET_SIMM13(__name, __val) \ - do { \ - ___ss_##__name[0] |= 1; \ - ___ss_##__name[1] = (unsigned)__val; \ - } while (0) - -#define BTFIXUPCOPY_SIMM13(__name, __from) \ - do { \ - ___ss_##__name[0] |= 1; \ - ___ss_##__name[1] = ___ss_##__from[1]; \ - } while (0) - -#define BTFIXUPSET_HALF(__name, __val) \ - do { \ - ___as_##__name[0] |= 1; \ - ___as_##__name[1] = (unsigned)__val; \ - } while (0) - -#define BTFIXUPCOPY_HALF(__name, __from) \ - do { \ - ___as_##__name[0] |= 1; \ - ___as_##__name[1] = ___as_##__from[1]; \ - } while (0) - -#define BTFIXUPSET_SETHI(__name, __val) \ - do { \ - ___hs_##__name[0] |= 1; \ - ___hs_##__name[1] = (unsigned)__val; \ - } while (0) - -#define BTFIXUPCOPY_SETHI(__name, __from) \ - do { \ - ___hs_##__name[0] |= 1; \ - ___hs_##__name[1] = ___hs_##__from[1]; \ - } while (0) - -#define BTFIXUPSET_INT(__name, __val) \ - do { \ - ___is_##__name[0] |= 1; \ - ___is_##__name[1] = (unsigned)__val; \ - } while (0) - -#define BTFIXUPCOPY_INT(__name, __from) \ - do { \ - ___is_##__name[0] |= 1; \ - ___is_##__name[1] = ___is_##__from[1]; \ - } while (0) - -#define BTFIXUPVAL_CALL(__name) \ - ((unsigned long)___fs_##__name[1]) - -extern void btfixup(void); - -#else /* __ASSEMBLY__ */ - -#define BTFIXUP_SETHI(__name) %hi(___h_ ## __name) -#define BTFIXUP_SETHI_INIT(__name,__val) %hi(___h_ ## __name ## __btset_ ## __val) - -#endif /* __ASSEMBLY__ */ - -#endif /* !(_SPARC_BTFIXUP_H) */
diff --git a/arch/sparc/include/asm/cache.h b/arch/sparc/include/asm/cache.h index 69358b5..5bb6991 100644 --- a/arch/sparc/include/asm/cache.h +++ b/arch/sparc/include/asm/cache.h
@@ -22,118 +22,4 @@ #define __read_mostly __attribute__((__section__(".data..read_mostly"))) -#ifdef CONFIG_SPARC32 -#include <asm/asi.h> - -/* Direct access to the instruction cache is provided through and - * alternate address space. The IDC bit must be off in the ICCR on - * HyperSparcs for these accesses to work. The code below does not do - * any checking, the caller must do so. These routines are for - * diagnostics only, but could end up being useful. Use with care. - * Also, you are asking for trouble if you execute these in one of the - * three instructions following a %asr/%psr access or modification. - */ - -/* First, cache-tag access. */ -static inline unsigned int get_icache_tag(int setnum, int tagnum) -{ - unsigned int vaddr, retval; - - vaddr = ((setnum&1) << 12) | ((tagnum&0x7f) << 5); - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (retval) : - "r" (vaddr), "i" (ASI_M_TXTC_TAG)); - return retval; -} - -static inline void put_icache_tag(int setnum, int tagnum, unsigned int entry) -{ - unsigned int vaddr; - - vaddr = ((setnum&1) << 12) | ((tagnum&0x7f) << 5); - __asm__ __volatile__("sta %0, [%1] %2\n\t" : : - "r" (entry), "r" (vaddr), "i" (ASI_M_TXTC_TAG) : - "memory"); -} - -/* Second cache-data access. The data is returned two-32bit quantities - * at a time. - */ -static inline void get_icache_data(int setnum, int tagnum, int subblock, - unsigned int *data) -{ - unsigned int value1, value2, vaddr; - - vaddr = ((setnum&0x1) << 12) | ((tagnum&0x7f) << 5) | - ((subblock&0x3) << 3); - __asm__ __volatile__("ldda [%2] %3, %%g2\n\t" - "or %%g0, %%g2, %0\n\t" - "or %%g0, %%g3, %1\n\t" : - "=r" (value1), "=r" (value2) : - "r" (vaddr), "i" (ASI_M_TXTC_DATA) : - "g2", "g3"); - data[0] = value1; data[1] = value2; -} - -static inline void put_icache_data(int setnum, int tagnum, int subblock, - unsigned int *data) -{ - unsigned int value1, value2, vaddr; - - vaddr = ((setnum&0x1) << 12) | ((tagnum&0x7f) << 5) | - ((subblock&0x3) << 3); - value1 = data[0]; value2 = data[1]; - __asm__ __volatile__("or %%g0, %0, %%g2\n\t" - "or %%g0, %1, %%g3\n\t" - "stda %%g2, [%2] %3\n\t" : : - "r" (value1), "r" (value2), - "r" (vaddr), "i" (ASI_M_TXTC_DATA) : - "g2", "g3", "memory" /* no joke */); -} - -/* Different types of flushes with the ICACHE. Some of the flushes - * affect both the ICACHE and the external cache. Others only clear - * the ICACHE entries on the cpu itself. V8's (most) allow - * granularity of flushes on the packet (element in line), whole line, - * and entire cache (ie. all lines) level. The ICACHE only flushes are - * ROSS HyperSparc specific and are in ross.h - */ - -/* Flushes which clear out both the on-chip and external caches */ -static inline void flush_ei_page(unsigned int addr) -{ - __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : - "r" (addr), "i" (ASI_M_FLUSH_PAGE) : - "memory"); -} - -static inline void flush_ei_seg(unsigned int addr) -{ - __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : - "r" (addr), "i" (ASI_M_FLUSH_SEG) : - "memory"); -} - -static inline void flush_ei_region(unsigned int addr) -{ - __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : - "r" (addr), "i" (ASI_M_FLUSH_REGION) : - "memory"); -} - -static inline void flush_ei_ctx(unsigned int addr) -{ - __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : - "r" (addr), "i" (ASI_M_FLUSH_CTX) : - "memory"); -} - -static inline void flush_ei_user(unsigned int addr) -{ - __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : - "r" (addr), "i" (ASI_M_FLUSH_USER) : - "memory"); -} -#endif /* CONFIG_SPARC32 */ - #endif /* !(_SPARC_CACHE_H) */
diff --git a/arch/sparc/include/asm/cacheflush.h b/arch/sparc/include/asm/cacheflush.h index 0491680..f6c4839 100644 --- a/arch/sparc/include/asm/cacheflush.h +++ b/arch/sparc/include/asm/cacheflush.h
@@ -1,5 +1,9 @@ #ifndef ___ASM_SPARC_CACHEFLUSH_H #define ___ASM_SPARC_CACHEFLUSH_H + +/* flush addr - to allow use of self-modifying code */ +#define flushi(addr) __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory") + #if defined(__sparc__) && defined(__arch64__) #include <asm/cacheflush_64.h> #else
diff --git a/arch/sparc/include/asm/cacheflush_32.h b/arch/sparc/include/asm/cacheflush_32.h index 68431b4..bb014c2 100644 --- a/arch/sparc/include/asm/cacheflush_32.h +++ b/arch/sparc/include/asm/cacheflush_32.h
@@ -1,56 +1,18 @@ #ifndef _SPARC_CACHEFLUSH_H #define _SPARC_CACHEFLUSH_H -#include <linux/mm.h> /* Common for other includes */ -// #include <linux/kernel.h> from pgalloc.h -// #include <linux/sched.h> from pgalloc.h +#include <asm/cachetlb_32.h> -// #include <asm/page.h> -#include <asm/btfixup.h> - -/* - * Fine grained cache flushing. - */ -#ifdef CONFIG_SMP - -BTFIXUPDEF_CALL(void, local_flush_cache_all, void) -BTFIXUPDEF_CALL(void, local_flush_cache_mm, struct mm_struct *) -BTFIXUPDEF_CALL(void, local_flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long) -BTFIXUPDEF_CALL(void, local_flush_cache_page, struct vm_area_struct *, unsigned long) - -#define local_flush_cache_all() BTFIXUP_CALL(local_flush_cache_all)() -#define local_flush_cache_mm(mm) BTFIXUP_CALL(local_flush_cache_mm)(mm) -#define local_flush_cache_range(vma,start,end) BTFIXUP_CALL(local_flush_cache_range)(vma,start,end) -#define local_flush_cache_page(vma,addr) BTFIXUP_CALL(local_flush_cache_page)(vma,addr) - -BTFIXUPDEF_CALL(void, local_flush_page_to_ram, unsigned long) -BTFIXUPDEF_CALL(void, local_flush_sig_insns, struct mm_struct *, unsigned long) - -#define local_flush_page_to_ram(addr) BTFIXUP_CALL(local_flush_page_to_ram)(addr) -#define local_flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(local_flush_sig_insns)(mm,insn_addr) - -extern void smp_flush_cache_all(void); -extern void smp_flush_cache_mm(struct mm_struct *mm); -extern void smp_flush_cache_range(struct vm_area_struct *vma, - unsigned long start, - unsigned long end); -extern void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page); - -extern void smp_flush_page_to_ram(unsigned long page); -extern void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr); - -#endif /* CONFIG_SMP */ - -BTFIXUPDEF_CALL(void, flush_cache_all, void) -BTFIXUPDEF_CALL(void, flush_cache_mm, struct mm_struct *) -BTFIXUPDEF_CALL(void, flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long) -BTFIXUPDEF_CALL(void, flush_cache_page, struct vm_area_struct *, unsigned long) - -#define flush_cache_all() BTFIXUP_CALL(flush_cache_all)() -#define flush_cache_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm) -#define flush_cache_dup_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm) -#define flush_cache_range(vma,start,end) BTFIXUP_CALL(flush_cache_range)(vma,start,end) -#define flush_cache_page(vma,addr,pfn) BTFIXUP_CALL(flush_cache_page)(vma,addr) +#define flush_cache_all() \ + sparc32_cachetlb_ops->cache_all() +#define flush_cache_mm(mm) \ + sparc32_cachetlb_ops->cache_mm(mm) +#define flush_cache_dup_mm(mm) \ + sparc32_cachetlb_ops->cache_mm(mm) +#define flush_cache_range(vma,start,end) \ + sparc32_cachetlb_ops->cache_range(vma, start, end) +#define flush_cache_page(vma,addr,pfn) \ + sparc32_cachetlb_ops->cache_page(vma, addr) #define flush_icache_range(start, end) do { } while (0) #define flush_icache_page(vma, pg) do { } while (0) @@ -67,11 +29,12 @@ memcpy(dst, src, len); \ } while (0) -BTFIXUPDEF_CALL(void, __flush_page_to_ram, unsigned long) -BTFIXUPDEF_CALL(void, flush_sig_insns, struct mm_struct *, unsigned long) - -#define __flush_page_to_ram(addr) BTFIXUP_CALL(__flush_page_to_ram)(addr) -#define flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(flush_sig_insns)(mm,insn_addr) +#define __flush_page_to_ram(addr) \ + sparc32_cachetlb_ops->page_to_ram(addr) +#define flush_sig_insns(mm,insn_addr) \ + sparc32_cachetlb_ops->sig_insns(mm, insn_addr) +#define flush_page_for_dma(addr) \ + sparc32_cachetlb_ops->page_for_dma(addr) extern void sparc_flush_page_to_ram(struct page *page);
diff --git a/arch/sparc/include/asm/cacheflush_64.h b/arch/sparc/include/asm/cacheflush_64.h index 2efea2f..301736d 100644 --- a/arch/sparc/include/asm/cacheflush_64.h +++ b/arch/sparc/include/asm/cacheflush_64.h
@@ -8,9 +8,6 @@ #include <linux/mm.h> /* Cache flush operations. */ - - -#define flushi(addr) __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory") #define flushw_all() __asm__ __volatile__("flushw") extern void __flushw_user(void);
diff --git a/arch/sparc/include/asm/cachetlb_32.h b/arch/sparc/include/asm/cachetlb_32.h new file mode 100644 index 0000000..efb1988 --- /dev/null +++ b/arch/sparc/include/asm/cachetlb_32.h
@@ -0,0 +1,29 @@ +#ifndef _SPARC_CACHETLB_H +#define _SPARC_CACHETLB_H + +struct mm_struct; +struct vm_area_struct; + +struct sparc32_cachetlb_ops { + void (*cache_all)(void); + void (*cache_mm)(struct mm_struct *); + void (*cache_range)(struct vm_area_struct *, unsigned long, + unsigned long); + void (*cache_page)(struct vm_area_struct *, unsigned long); + + void (*tlb_all)(void); + void (*tlb_mm)(struct mm_struct *); + void (*tlb_range)(struct vm_area_struct *, unsigned long, + unsigned long); + void (*tlb_page)(struct vm_area_struct *, unsigned long); + + void (*page_to_ram)(unsigned long); + void (*sig_insns)(struct mm_struct *, unsigned long); + void (*page_for_dma)(unsigned long); +}; +extern const struct sparc32_cachetlb_ops *sparc32_cachetlb_ops; +#ifdef CONFIG_SMP +extern const struct sparc32_cachetlb_ops *local_ops; +#endif + +#endif /* SPARC_CACHETLB_H */
diff --git a/arch/sparc/include/asm/cmpxchg_32.h b/arch/sparc/include/asm/cmpxchg_32.h index c786b0a..1fae1a0 100644 --- a/arch/sparc/include/asm/cmpxchg_32.h +++ b/arch/sparc/include/asm/cmpxchg_32.h
@@ -11,40 +11,13 @@ #ifndef __ARCH_SPARC_CMPXCHG__ #define __ARCH_SPARC_CMPXCHG__ -#include <asm/btfixup.h> - -/* This has special calling conventions */ -#ifndef CONFIG_SMP -BTFIXUPDEF_CALL(void, ___xchg32, void) -#endif - static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val) { -#ifdef CONFIG_SMP __asm__ __volatile__("swap [%2], %0" : "=&r" (val) : "0" (val), "r" (m) : "memory"); return val; -#else - register unsigned long *ptr asm("g1"); - register unsigned long ret asm("g2"); - - ptr = (unsigned long *) m; - ret = val; - - /* Note: this is magic and the nop there is - really needed. */ - __asm__ __volatile__( - "mov %%o7, %%g4\n\t" - "call ___f____xchg32\n\t" - " nop\n\t" - : "=&r" (ret) - : "0" (ret), "r" (ptr) - : "g3", "g4", "g7", "memory", "cc"); - - return ret; -#endif } extern void __xchg_called_with_bad_pointer(void);
diff --git a/arch/sparc/include/asm/contregs.h b/arch/sparc/include/asm/contregs.h index 48fa8a4..b8abdfc 100644 --- a/arch/sparc/include/asm/contregs.h +++ b/arch/sparc/include/asm/contregs.h
@@ -7,28 +7,6 @@ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) */ -/* 3=sun3 - 4=sun4 (as in sun4 sysmaint student book) - c=sun4c (according to davem) */ - -#define AC_IDPROM 0x00000000 /* 34 ID PROM, R/O, byte, 32 bytes */ -#define AC_PAGEMAP 0x10000000 /* 3 Pagemap R/W, long */ -#define AC_SEGMAP 0x20000000 /* 3 Segment map, byte */ -#define AC_CONTEXT 0x30000000 /* 34c current mmu-context */ -#define AC_SENABLE 0x40000000 /* 34c system dvma/cache/reset enable reg*/ -#define AC_UDVMA_ENB 0x50000000 /* 34 Not used on Sun boards, byte */ -#define AC_BUS_ERROR 0x60000000 /* 34 Not cleared on read, byte. */ -#define AC_SYNC_ERR 0x60000000 /* c fault type */ -#define AC_SYNC_VA 0x60000004 /* c fault virtual address */ -#define AC_ASYNC_ERR 0x60000008 /* c asynchronous fault type */ -#define AC_ASYNC_VA 0x6000000c /* c async fault virtual address */ -#define AC_LEDS 0x70000000 /* 34 Zero turns on LEDs, byte */ -#define AC_CACHETAGS 0x80000000 /* 34c direct access to the VAC tags */ -#define AC_CACHEDDATA 0x90000000 /* 3 c direct access to the VAC data */ -#define AC_UDVMA_MAP 0xD0000000 /* 4 Not used on Sun boards, byte */ -#define AC_VME_VECTOR 0xE0000000 /* 4 For non-Autovector VME, byte */ -#define AC_BOOT_SCC 0xF0000000 /* 34 bypass to access Zilog 8530. byte.*/ - /* s=Swift, h=Ross_HyperSPARC, v=TI_Viking, t=Tsunami, r=Ross_Cypress */ #define AC_M_PCR 0x0000 /* shv Processor Control Reg */ #define AC_M_CTPR 0x0100 /* shv Context Table Pointer Reg */
diff --git a/arch/sparc/include/asm/cpu_type.h b/arch/sparc/include/asm/cpu_type.h index 4ca184d..84d7d83 100644 --- a/arch/sparc/include/asm/cpu_type.h +++ b/arch/sparc/include/asm/cpu_type.h
@@ -5,30 +5,24 @@ * Sparc (general) CPU types */ enum sparc_cpu { - sun4 = 0x00, - sun4c = 0x01, - sun4m = 0x02, - sun4d = 0x03, - sun4e = 0x04, - sun4u = 0x05, /* V8 ploos ploos */ - sun_unknown = 0x06, - ap1000 = 0x07, /* almost a sun4m */ - sparc_leon = 0x08, /* Leon SoC */ + sun4m = 0x00, + sun4d = 0x01, + sun4e = 0x02, + sun4u = 0x03, /* V8 ploos ploos */ + sun_unknown = 0x04, + ap1000 = 0x05, /* almost a sun4m */ + sparc_leon = 0x06, /* Leon SoC */ }; #ifdef CONFIG_SPARC32 extern enum sparc_cpu sparc_cpu_model; -#define ARCH_SUN4C (sparc_cpu_model==sun4c) - #define SUN4M_NCPUS 4 /* Architectural limit of sun4m. */ #else #define sparc_cpu_model sun4u -/* This cannot ever be a sun4c :) That's just history. */ -#define ARCH_SUN4C 0 #endif #endif /* __ASM_CPU_TYPE_H */
diff --git a/arch/sparc/include/asm/cpudata_32.h b/arch/sparc/include/asm/cpudata_32.h index a4c5a93..0300d94 100644 --- a/arch/sparc/include/asm/cpudata_32.h +++ b/arch/sparc/include/asm/cpudata_32.h
@@ -14,7 +14,6 @@ typedef struct { unsigned long udelay_val; unsigned long clock_tick; - unsigned int multiplier; unsigned int counter; #ifdef CONFIG_SMP unsigned int irq_resched_count;
diff --git a/arch/sparc/include/asm/cypress.h b/arch/sparc/include/asm/cypress.h deleted file mode 100644 index 95e9772..0000000 --- a/arch/sparc/include/asm/cypress.h +++ /dev/null
@@ -1,79 +0,0 @@ -/* - * cypress.h: Cypress module specific definitions and defines. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - */ - -#ifndef _SPARC_CYPRESS_H -#define _SPARC_CYPRESS_H - -/* Cypress chips have %psr 'impl' of '0001' and 'vers' of '0001'. */ - -/* The MMU control register fields on the Sparc Cypress 604/605 MMU's. - * - * --------------------------------------------------------------- - * |implvers| MCA | MCM |MV| MID |BM| C|RSV|MR|CM|CL|CE|RSV|NF|ME| - * --------------------------------------------------------------- - * 31 24 23-22 21-20 19 18-15 14 13 12 11 10 9 8 7-2 1 0 - * - * MCA: MultiChip Access -- Used for configuration of multiple - * CY7C604/605 cache units. - * MCM: MultiChip Mask -- Again, for multiple cache unit config. - * MV: MultiChip Valid -- Indicates MCM and MCA have valid settings. - * MID: ModuleID -- Unique processor ID for MBus transactions. (605 only) - * BM: Boot Mode -- 0 = not in boot mode, 1 = in boot mode - * C: Cacheable -- Indicates whether accesses are cacheable while - * the MMU is off. 0=no 1=yes - * MR: MemoryReflection -- Indicates whether the bus attached to the - * MBus supports memory reflection. 0=no 1=yes (605 only) - * CM: CacheMode -- Indicates whether the cache is operating in write - * through or copy-back mode. 0=write-through 1=copy-back - * CL: CacheLock -- Indicates if the entire cache is locked or not. - * 0=not-locked 1=locked (604 only) - * CE: CacheEnable -- Is the virtual cache on? 0=no 1=yes - * NF: NoFault -- Do faults generate traps? 0=yes 1=no - * ME: MmuEnable -- Is the MMU doing translations? 0=no 1=yes - */ - -#define CYPRESS_MCA 0x00c00000 -#define CYPRESS_MCM 0x00300000 -#define CYPRESS_MVALID 0x00080000 -#define CYPRESS_MIDMASK 0x00078000 /* Only on 605 */ -#define CYPRESS_BMODE 0x00004000 -#define CYPRESS_ACENABLE 0x00002000 -#define CYPRESS_MRFLCT 0x00000800 /* Only on 605 */ -#define CYPRESS_CMODE 0x00000400 -#define CYPRESS_CLOCK 0x00000200 /* Only on 604 */ -#define CYPRESS_CENABLE 0x00000100 -#define CYPRESS_NFAULT 0x00000002 -#define CYPRESS_MENABLE 0x00000001 - -static inline void cypress_flush_page(unsigned long page) -{ - __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : - "r" (page), "i" (ASI_M_FLUSH_PAGE)); -} - -static inline void cypress_flush_segment(unsigned long addr) -{ - __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : - "r" (addr), "i" (ASI_M_FLUSH_SEG)); -} - -static inline void cypress_flush_region(unsigned long addr) -{ - __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : - "r" (addr), "i" (ASI_M_FLUSH_REGION)); -} - -static inline void cypress_flush_context(void) -{ - __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : - "i" (ASI_M_FLUSH_CTX)); -} - -/* XXX Displacement flushes for buggy chips and initial testing - * XXX go here. - */ - -#endif /* !(_SPARC_CYPRESS_H) */
diff --git a/arch/sparc/include/asm/dma.h b/arch/sparc/include/asm/dma.h index b554927..3d434ef 100644 --- a/arch/sparc/include/asm/dma.h +++ b/arch/sparc/include/asm/dma.h
@@ -92,27 +92,31 @@ #ifdef CONFIG_SPARC32 /* Routines for data transfer buffers. */ -BTFIXUPDEF_CALL(char *, mmu_lockarea, char *, unsigned long) -BTFIXUPDEF_CALL(void, mmu_unlockarea, char *, unsigned long) - -#define mmu_lockarea(vaddr,len) BTFIXUP_CALL(mmu_lockarea)(vaddr,len) -#define mmu_unlockarea(vaddr,len) BTFIXUP_CALL(mmu_unlockarea)(vaddr,len) - -struct page; struct device; struct scatterlist; -/* These are implementations for sbus_map_sg/sbus_unmap_sg... collapse later */ -BTFIXUPDEF_CALL(__u32, mmu_get_scsi_one, struct device *, char *, unsigned long) -BTFIXUPDEF_CALL(void, mmu_get_scsi_sgl, struct device *, struct scatterlist *, int) -BTFIXUPDEF_CALL(void, mmu_release_scsi_one, struct device *, __u32, unsigned long) -BTFIXUPDEF_CALL(void, mmu_release_scsi_sgl, struct device *, struct scatterlist *, int) +struct sparc32_dma_ops { + __u32 (*get_scsi_one)(struct device *, char *, unsigned long); + void (*get_scsi_sgl)(struct device *, struct scatterlist *, int); + void (*release_scsi_one)(struct device *, __u32, unsigned long); + void (*release_scsi_sgl)(struct device *, struct scatterlist *,int); +#ifdef CONFIG_SBUS + int (*map_dma_area)(struct device *, dma_addr_t *, unsigned long, unsigned long, int); + void (*unmap_dma_area)(struct device *, unsigned long, int); +#endif +}; +extern const struct sparc32_dma_ops *sparc32_dma_ops; -#define mmu_get_scsi_one(dev,vaddr,len) BTFIXUP_CALL(mmu_get_scsi_one)(dev,vaddr,len) -#define mmu_get_scsi_sgl(dev,sg,sz) BTFIXUP_CALL(mmu_get_scsi_sgl)(dev,sg,sz) -#define mmu_release_scsi_one(dev,vaddr,len) BTFIXUP_CALL(mmu_release_scsi_one)(dev,vaddr,len) -#define mmu_release_scsi_sgl(dev,sg,sz) BTFIXUP_CALL(mmu_release_scsi_sgl)(dev,sg,sz) +#define mmu_get_scsi_one(dev,vaddr,len) \ + sparc32_dma_ops->get_scsi_one(dev, vaddr, len) +#define mmu_get_scsi_sgl(dev,sg,sz) \ + sparc32_dma_ops->get_scsi_sgl(dev, sg, sz) +#define mmu_release_scsi_one(dev,vaddr,len) \ + sparc32_dma_ops->release_scsi_one(dev, vaddr,len) +#define mmu_release_scsi_sgl(dev,sg,sz) \ + sparc32_dma_ops->release_scsi_sgl(dev, sg, sz) +#ifdef CONFIG_SBUS /* * mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep. * @@ -123,17 +127,17 @@ * Second mapping is for device visible address, or "bus" address. * The bus address is returned at '*pba'. * - * These functions seem distinct, but are hard to split. On sun4c, - * at least for now, 'a' is equal to bus address, and retured in *pba. + * These functions seem distinct, but are hard to split. * On sun4m, page attributes depend on the CPU type, so we have to * know if we are mapping RAM or I/O, so it has to be an additional argument * to a separate mapping function for CPU visible mappings. */ -BTFIXUPDEF_CALL(int, mmu_map_dma_area, struct device *, dma_addr_t *, unsigned long, unsigned long, int len) -BTFIXUPDEF_CALL(void, mmu_unmap_dma_area, struct device *, unsigned long busa, int len) +#define sbus_map_dma_area(dev,pba,va,a,len) \ + sparc32_dma_ops->map_dma_area(dev, pba, va, a, len) +#define sbus_unmap_dma_area(dev,ba,len) \ + sparc32_dma_ops->unmap_dma_area(dev, ba, len) +#endif /* CONFIG_SBUS */ -#define mmu_map_dma_area(dev,pba,va,a,len) BTFIXUP_CALL(mmu_map_dma_area)(dev,pba,va,a,len) -#define mmu_unmap_dma_area(dev,ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(dev,ba,len) #endif #endif /* !(_ASM_SPARC_DMA_H) */
diff --git a/arch/sparc/include/asm/elf_32.h b/arch/sparc/include/asm/elf_32.h index 4269ca6..2d4d755 100644 --- a/arch/sparc/include/asm/elf_32.h +++ b/arch/sparc/include/asm/elf_32.h
@@ -118,16 +118,9 @@ instruction set this cpu supports. This can NOT be done in userspace on Sparc. */ -/* Sun4c has none of the capabilities, most sun4m's have them all. - * XXX This is gross, set some global variable at boot time. -DaveM - */ -#define ELF_HWCAP ((ARCH_SUN4C) ? 0 : \ - (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \ - HWCAP_SPARC_SWAP | \ - ((srmmu_modtype != Cypress && \ - srmmu_modtype != Cypress_vE && \ - srmmu_modtype != Cypress_vD) ? \ - HWCAP_SPARC_MULDIV : 0))) +/* Most sun4m's have them all. */ +#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \ + HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV) /* This yields a string that ld.so will use to load implementation specific libraries for optimization. This is more specific in
diff --git a/arch/sparc/include/asm/floppy_32.h b/arch/sparc/include/asm/floppy_32.h index 698d955..fb3f169 100644 --- a/arch/sparc/include/asm/floppy_32.h +++ b/arch/sparc/include/asm/floppy_32.h
@@ -12,7 +12,6 @@ #include <asm/page.h> #include <asm/pgtable.h> #include <asm/idprom.h> -#include <asm/machines.h> #include <asm/oplib.h> #include <asm/auxio.h> #include <asm/irq.h> @@ -103,25 +102,13 @@ /* Routines unique to each controller type on a Sun. */ static void sun_set_dor(unsigned char value, int fdc_82077) { - if (sparc_cpu_model == sun4c) { - unsigned int bits = 0; - if (value & 0x10) - bits |= AUXIO_FLPY_DSEL; - if ((value & 0x80) == 0) - bits |= AUXIO_FLPY_EJCT; - set_auxio(bits, (~bits) & (AUXIO_FLPY_DSEL|AUXIO_FLPY_EJCT)); - } - if (fdc_82077) { + if (fdc_82077) sun_fdc->dor_82077 = value; - } } static unsigned char sun_read_dir(void) { - if (sparc_cpu_model == sun4c) - return (get_auxio() & AUXIO_FLPY_DCHG) ? 0x80 : 0; - else - return sun_fdc->dir_82077; + return sun_fdc->dir_82077; } static unsigned char sun_82072_fd_inb(int port) @@ -242,10 +229,7 @@ static inline void sun_fd_disable_dma(void) { doing_pdma = 0; - if (pdma_base) { - mmu_unlockarea(pdma_base, pdma_areasize); - pdma_base = NULL; - } + pdma_base = NULL; } static inline void sun_fd_set_dma_mode(int mode) @@ -275,7 +259,6 @@ static inline void sun_fd_enable_dma(void) { - pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size); pdma_base = pdma_vaddr; pdma_areasize = pdma_size; } @@ -301,38 +284,36 @@ { struct platform_device *op; struct device_node *dp; - char state[128]; - phandle tnode, fd_node; - int num_regs; struct resource r; + char state[128]; + phandle fd_node; + phandle tnode; + int num_regs; use_virtual_dma = 1; /* Forget it if we aren't on a machine that could possibly * ever have a floppy drive. */ - if((sparc_cpu_model != sun4c && sparc_cpu_model != sun4m) || - ((idprom->id_machtype == (SM_SUN4C | SM_4C_SLC)) || - (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC)))) { + if (sparc_cpu_model != sun4m) { /* We certainly don't have a floppy controller. */ goto no_sun_fdc; } /* Well, try to find one. */ tnode = prom_getchild(prom_root_node); fd_node = prom_searchsiblings(tnode, "obio"); - if(fd_node != 0) { + if (fd_node != 0) { tnode = prom_getchild(fd_node); fd_node = prom_searchsiblings(tnode, "SUNW,fdtwo"); } else { fd_node = prom_searchsiblings(tnode, "fd"); } - if(fd_node == 0) { + if (fd_node == 0) { goto no_sun_fdc; } /* The sun4m lets us know if the controller is actually usable. */ - if(sparc_cpu_model == sun4m && - prom_getproperty(fd_node, "status", state, sizeof(state)) != -1) { + if (prom_getproperty(fd_node, "status", state, sizeof(state)) != -1) { if(!strcmp(state, "disabled")) { goto no_sun_fdc; } @@ -343,12 +324,12 @@ memset(&r, 0, sizeof(r)); r.flags = fd_regs[0].which_io; r.start = fd_regs[0].phys_addr; - sun_fdc = (struct sun_flpy_controller *) - of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy"); + sun_fdc = of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy"); /* Look up irq in platform_device. * We try "SUNW,fdtwo" and "fd" */ + op = NULL; for_each_node_by_name(dp, "SUNW,fdtwo") { op = of_find_device_by_node(dp); if (op) @@ -367,7 +348,7 @@ FLOPPY_IRQ = op->archdata.irqs[0]; /* Last minute sanity check... */ - if(sun_fdc->status_82072 == 0xff) { + if (sun_fdc->status_82072 == 0xff) { sun_fdc = NULL; goto no_sun_fdc; }
diff --git a/arch/sparc/include/asm/floppy_64.h b/arch/sparc/include/asm/floppy_64.h index bcef1f5..e204f90 100644 --- a/arch/sparc/include/asm/floppy_64.h +++ b/arch/sparc/include/asm/floppy_64.h
@@ -161,10 +161,7 @@ static void sun_fd_disable_dma(void) { doing_pdma = 0; - if (pdma_base) { - mmu_unlockarea(pdma_base, pdma_areasize); - pdma_base = NULL; - } + pdma_base = NULL; } static void sun_fd_set_dma_mode(int mode) @@ -194,7 +191,6 @@ static void sun_fd_enable_dma(void) { - pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size); pdma_base = pdma_vaddr; pdma_areasize = pdma_size; }
diff --git a/arch/sparc/include/asm/head_32.h b/arch/sparc/include/asm/head_32.h index 7c35491..a768748 100644 --- a/arch/sparc/include/asm/head_32.h +++ b/arch/sparc/include/asm/head_32.h
@@ -2,15 +2,8 @@ #define __SPARC_HEAD_H #define KERNBASE 0xf0000000 /* First address the kernel will eventually be */ -#define LOAD_ADDR 0x4000 /* prom jumps to us here unless this is elf /boot */ -#define SUN4C_SEGSZ (1 << 18) -#define SRMMU_L1_KBASE_OFFSET ((KERNBASE>>24)<<2) /* Used in boot remapping. */ -#define INTS_ENAB 0x01 /* entry.S uses this. */ - -#define SUN4_PROM_VECTOR 0xFFE81000 /* SUN4 PROM needs to be hardwired */ #define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */ -#define NOP_INSN 0x01000000 /* Used to patch sparc_save_state */ /* Here are some trap goodies */ @@ -18,9 +11,7 @@ #define TRAP_ENTRY(type, label) \ rd %psr, %l0; b label; rd %wim, %l3; nop; -/* Data/text faults. Defaults to sun4c version at boot time. */ -#define SPARC_TFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 1, %l7; -#define SPARC_DFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 0, %l7; +/* Data/text faults */ #define SRMMU_TFAULT rd %psr, %l0; rd %wim, %l3; b srmmu_fault; mov 1, %l7; #define SRMMU_DFAULT rd %psr, %l0; rd %wim, %l3; b srmmu_fault; mov 0, %l7; @@ -80,16 +71,6 @@ #define TRAP_ENTRY_INTERRUPT(int_level) \ mov int_level, %l7; rd %psr, %l0; b real_irq_entry; rd %wim, %l3; -/* NMI's (Non Maskable Interrupts) are special, you can't keep them - * from coming in, and basically if you get one, the shows over. ;( - * On the sun4c they are usually asynchronous memory errors, on the - * the sun4m they could be either due to mem errors or a software - * initiated interrupt from the prom/kern on an SMP box saying "I - * command you to do CPU tricks, read your mailbox for more info." - */ -#define NMI_TRAP \ - rd %wim, %l3; b linux_trap_nmi_sun4c; mov %psr, %l0; nop; - /* Window overflows/underflows are special and we need to try to be as * efficient as possible here.... */
diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h index a4e457f..24f802b 100644 --- a/arch/sparc/include/asm/leon.h +++ b/arch/sparc/include/asm/leon.h
@@ -10,19 +10,6 @@ #ifdef CONFIG_SPARC_LEON -#define ASI_LEON_NOCACHE 0x01 - -#define ASI_LEON_DCACHE_MISS 0x1 - -#define ASI_LEON_CACHEREGS 0x02 -#define ASI_LEON_IFLUSH 0x10 -#define ASI_LEON_DFLUSH 0x11 - -#define ASI_LEON_MMUFLUSH 0x18 -#define ASI_LEON_MMUREGS 0x19 -#define ASI_LEON_BYPASS 0x1c -#define ASI_LEON_FLUSH_PAGE 0x10 - /* mmu register access, ASI_LEON_MMUREGS */ #define LEON_CNR_CTRL 0x000 #define LEON_CNR_CTXP 0x100 @@ -57,29 +44,6 @@ #define LEON_IRQMASK_R 0x0000fffe /* bit 15- 1 of lregs.irqmask */ #define LEON_IRQPRIO_R 0xfffe0000 /* bit 31-17 of lregs.irqmask */ -/* leon uart register definitions */ -#define LEON_OFF_UDATA 0x0 -#define LEON_OFF_USTAT 0x4 -#define LEON_OFF_UCTRL 0x8 -#define LEON_OFF_USCAL 0xc - -#define LEON_UCTRL_RE 0x01 -#define LEON_UCTRL_TE 0x02 -#define LEON_UCTRL_RI 0x04 -#define LEON_UCTRL_TI 0x08 -#define LEON_UCTRL_PS 0x10 -#define LEON_UCTRL_PE 0x20 -#define LEON_UCTRL_FL 0x40 -#define LEON_UCTRL_LB 0x80 - -#define LEON_USTAT_DR 0x01 -#define LEON_USTAT_TS 0x02 -#define LEON_USTAT_TH 0x04 -#define LEON_USTAT_BR 0x08 -#define LEON_USTAT_OV 0x10 -#define LEON_USTAT_PE 0x20 -#define LEON_USTAT_FE 0x40 - #define LEON_MCFG2_SRAMDIS 0x00002000 #define LEON_MCFG2_SDRAMEN 0x00004000 #define LEON_MCFG2_SRAMBANKSZ 0x00001e00 /* [12-9] */ @@ -89,8 +53,6 @@ #define LEON_TCNT0_MASK 0x7fffff -#define LEON_USTAT_ERROR (LEON_USTAT_OV | LEON_USTAT_PE | LEON_USTAT_FE) -/* no break yet */ #define ASI_LEON3_SYSCTRL 0x02 #define ASI_LEON3_SYSCTRL_ICFG 0x08 @@ -278,6 +240,8 @@ #define LEON2_CFG_SSIZE_MASK 0x00007000UL #ifndef __ASSEMBLY__ +struct vm_area_struct; + extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr); extern void leon_flush_icache_all(void); extern void leon_flush_dcache_all(void); @@ -285,15 +249,6 @@ extern void leon_flush_tlb_all(void); extern int leon_flush_during_switch; extern int leon_flush_needed(void); - -struct vm_area_struct; -extern void leon_flush_icache_all(void); -extern void leon_flush_dcache_all(void); -extern void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page); -extern void leon_flush_cache_all(void); -extern void leon_flush_tlb_all(void); -extern int leon_flush_during_switch; -extern int leon_flush_needed(void); extern void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page); /* struct that hold LEON3 cache configuration registers */ @@ -321,22 +276,12 @@ extern void leon_update_virq_handling(unsigned int virq, irq_flow_handler_t flow_handler, const char *name, int do_ack); -extern void leon_clear_clock_irq(void); -extern void leon_load_profile_irq(int cpu, unsigned int limit); -extern void leon_init_timers(irq_handler_t counter_fn); -extern void leon_clear_clock_irq(void); -extern void leon_load_profile_irq(int cpu, unsigned int limit); +extern void leon_init_timers(void); extern void leon_trans_init(struct device_node *dp); extern void leon_node_init(struct device_node *dp, struct device_node ***nextp); -extern void leon_init_IRQ(void); -extern void leon_init(void); -extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr); extern void init_leon(void); extern void poke_leonsparc(void); extern void leon3_getCacheRegs(struct leon3_cacheregs *regs); -extern int leon_flush_needed(void); -extern void leon_switch_mm(void); -extern int srmmu_swprobe_trace; extern int leon3_ticker_irq; #ifdef CONFIG_SMP
diff --git a/arch/sparc/include/asm/machines.h b/arch/sparc/include/asm/machines.h index cd9c099..fd6ddb0 100644 --- a/arch/sparc/include/asm/machines.h +++ b/arch/sparc/include/asm/machines.h
@@ -12,11 +12,6 @@ unsigned char id_machtype; }; -/* Current number of machines we know about that has an IDPROM - * machtype entry including one entry for the 0x80 OBP machines. - */ -#define NUM_SUN_MACHINES 16 - /* The machine type in the idprom area looks like this: * * --------------- @@ -24,36 +19,20 @@ * --------------- * 7 4 3 0 * - * The ARCH field determines the architecture line (sun4, sun4c, etc). + * The ARCH field determines the architecture line (sun4m, etc). * The MACH field determines the machine make within that architecture. */ #define SM_ARCH_MASK 0xf0 -#define SM_SUN4 0x20 #define M_LEON 0x30 -#define SM_SUN4C 0x50 #define SM_SUN4M 0x70 #define SM_SUN4M_OBP 0x80 #define SM_TYP_MASK 0x0f -/* Sun4 machines */ -#define SM_4_260 0x01 /* Sun 4/200 series */ -#define SM_4_110 0x02 /* Sun 4/100 series */ -#define SM_4_330 0x03 /* Sun 4/300 series */ -#define SM_4_470 0x04 /* Sun 4/400 series */ /* Leon machines */ #define M_LEON3_SOC 0x02 /* Leon3 SoC */ -/* Sun4c machines Full Name - PROM NAME */ -#define SM_4C_SS1 0x01 /* Sun4c SparcStation 1 - Sun 4/60 */ -#define SM_4C_IPC 0x02 /* Sun4c SparcStation IPC - Sun 4/40 */ -#define SM_4C_SS1PLUS 0x03 /* Sun4c SparcStation 1+ - Sun 4/65 */ -#define SM_4C_SLC 0x04 /* Sun4c SparcStation SLC - Sun 4/20 */ -#define SM_4C_SS2 0x05 /* Sun4c SparcStation 2 - Sun 4/75 */ -#define SM_4C_ELC 0x06 /* Sun4c SparcStation ELC - Sun 4/25 */ -#define SM_4C_IPX 0x07 /* Sun4c SparcStation IPX - Sun 4/50 */ - /* Sun4m machines, these predate the OpenBoot. These values only mean * something if the value in the ARCH field is SM_SUN4M, if it is * SM_SUN4M_OBP then you have the following situation:
diff --git a/arch/sparc/include/asm/mbus.h b/arch/sparc/include/asm/mbus.h index 69f07a0..14128bc 100644 --- a/arch/sparc/include/asm/mbus.h +++ b/arch/sparc/include/asm/mbus.h
@@ -8,14 +8,10 @@ #define _SPARC_MBUS_H #include <asm/ross.h> /* HyperSparc stuff */ -#include <asm/cypress.h> /* Cypress Chips */ #include <asm/viking.h> /* Ugh, bug city... */ enum mbus_module { HyperSparc = 0, - Cypress = 1, - Cypress_vE = 2, - Cypress_vD = 3, Swift_ok = 4, Swift_bad_c = 5, Swift_lots_o_bugs = 6,
diff --git a/arch/sparc/include/asm/memreg.h b/arch/sparc/include/asm/memreg.h deleted file mode 100644 index 845ad2b..0000000 --- a/arch/sparc/include/asm/memreg.h +++ /dev/null
@@ -1,51 +0,0 @@ -#ifndef _SPARC_MEMREG_H -#define _SPARC_MEMREG_H -/* memreg.h: Definitions of the values found in the synchronous - * and asynchronous memory error registers when a fault - * occurs on the sun4c. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - */ - -/* First the synchronous error codes, these are usually just - * normal page faults. - */ - -#define SUN4C_SYNC_WDRESET 0x0001 /* watchdog reset */ -#define SUN4C_SYNC_SIZE 0x0002 /* bad access size? whuz this? */ -#define SUN4C_SYNC_PARITY 0x0008 /* bad ram chips caused a parity error */ -#define SUN4C_SYNC_SBUS 0x0010 /* the SBUS had some problems... */ -#define SUN4C_SYNC_NOMEM 0x0020 /* translation to non-existent ram */ -#define SUN4C_SYNC_PROT 0x0040 /* access violated pte protections */ -#define SUN4C_SYNC_NPRESENT 0x0080 /* pte said that page was not present */ -#define SUN4C_SYNC_BADWRITE 0x8000 /* while writing something went bogus */ - -#define SUN4C_SYNC_BOLIXED \ - (SUN4C_SYNC_WDRESET | SUN4C_SYNC_SIZE | SUN4C_SYNC_SBUS | \ - SUN4C_SYNC_NOMEM | SUN4C_SYNC_PARITY) - -/* Now the asynchronous error codes, these are almost always produced - * by the cache writing things back to memory and getting a bad translation. - * Bad DVMA transactions can cause these faults too. - */ - -#define SUN4C_ASYNC_BADDVMA 0x0010 /* error during DVMA access */ -#define SUN4C_ASYNC_NOMEM 0x0020 /* write back pointed to bad phys addr */ -#define SUN4C_ASYNC_BADWB 0x0080 /* write back points to non-present page */ - -/* Memory parity error register with associated bit constants. */ -#ifndef __ASSEMBLY__ -extern __volatile__ unsigned long __iomem *sun4c_memerr_reg; -#endif - -#define SUN4C_MPE_ERROR 0x80 /* Parity error detected. (ro) */ -#define SUN4C_MPE_MULTI 0x40 /* Multiple parity errors detected. (ro) */ -#define SUN4C_MPE_TEST 0x20 /* Write inverse parity. (rw) */ -#define SUN4C_MPE_CHECK 0x10 /* Enable parity checking. (rw) */ -#define SUN4C_MPE_ERR00 0x08 /* Parity error in bits 0-7. (ro) */ -#define SUN4C_MPE_ERR08 0x04 /* Parity error in bits 8-15. (ro) */ -#define SUN4C_MPE_ERR16 0x02 /* Parity error in bits 16-23. (ro) */ -#define SUN4C_MPE_ERR24 0x01 /* Parity error in bits 24-31. (ro) */ -#define SUN4C_MPE_ERRS 0x0F /* Bit mask for the error bits. (ro) */ - -#endif /* !(_SPARC_MEMREG_H) */
diff --git a/arch/sparc/include/asm/mmu_context_32.h b/arch/sparc/include/asm/mmu_context_32.h index 671a997b..01456c9 100644 --- a/arch/sparc/include/asm/mmu_context_32.h +++ b/arch/sparc/include/asm/mmu_context_32.h
@@ -1,8 +1,6 @@ #ifndef __SPARC_MMU_CONTEXT_H #define __SPARC_MMU_CONTEXT_H -#include <asm/btfixup.h> - #ifndef __ASSEMBLY__ #include <asm-generic/mm_hooks.h> @@ -23,14 +21,11 @@ * all the page tables have been flushed. Our job is to destroy * any remaining processor-specific state. */ -BTFIXUPDEF_CALL(void, destroy_context, struct mm_struct *) - -#define destroy_context(mm) BTFIXUP_CALL(destroy_context)(mm) +void destroy_context(struct mm_struct *mm); /* Switch the current MM context. */ -BTFIXUPDEF_CALL(void, switch_mm, struct mm_struct *, struct mm_struct *, struct task_struct *) - -#define switch_mm(old_mm, mm, tsk) BTFIXUP_CALL(switch_mm)(old_mm, mm, tsk) +void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, + struct task_struct *tsk); #define deactivate_mm(tsk,mm) do { } while (0)
diff --git a/arch/sparc/include/asm/obio.h b/arch/sparc/include/asm/obio.h index 4ade0c8..910c1d9 100644 --- a/arch/sparc/include/asm/obio.h +++ b/arch/sparc/include/asm/obio.h
@@ -220,19 +220,6 @@ "i" (ASI_M_MXCC)); } -/* +-------+-------------+-----------+------------------------------------+ - * | bcast | devid | sid | levels mask | - * +-------+-------------+-----------+------------------------------------+ - * 31 30 23 22 15 14 0 - */ -#define IGEN_MESSAGE(bcast, devid, sid, levels) \ - (((bcast) << 31) | ((devid) << 23) | ((sid) << 15) | (levels)) - -static inline void sun4d_send_ipi(int cpu, int level) -{ - cc_set_igen(IGEN_MESSAGE(0, cpu << 3, 6 + ((level >> 1) & 7), 1 << (level - 1))); -} - #endif /* !__ASSEMBLY__ */ #endif /* !(_SPARC_OBIO_H) */
diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h index 71e5e9a..2751787 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h
@@ -105,14 +105,6 @@ extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table, int context, char *program_counter); -/* Sun4/sun4c specific memory-management startup hook. */ - -/* Map the passed segment in the given context at the passed - * virtual address. - */ -extern void prom_putsegment(int context, unsigned long virt_addr, - int physical_segment); - /* Initialize the memory lists based upon the prom version. */ void prom_meminit(void);
diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h index bb5c2ac..fab78a3 100644 --- a/arch/sparc/include/asm/page_32.h +++ b/arch/sparc/include/asm/page_32.h
@@ -14,8 +14,6 @@ #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) -#include <asm/btfixup.h> - #ifndef __ASSEMBLY__ #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) @@ -45,12 +43,6 @@ extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1]; -/* Cache alias structure. Entry is valid if context != -1. */ -struct cache_palias { - unsigned long vaddr; - int context; -}; - /* passing structs on the Sparc slow us down tremendously... */ /* #define STRICT_MM_TYPECHECKS */ @@ -116,10 +108,7 @@ typedef struct page *pgtable_t; extern unsigned long sparc_unmapped_base; - -BTFIXUPDEF_SETHI(sparc_unmapped_base) - -#define TASK_UNMAPPED_BASE BTFIXUP_SETHI(sparc_unmapped_base) +#define TASK_UNMAPPED_BASE sparc_unmapped_base #else /* !(__ASSEMBLY__) */
diff --git a/arch/sparc/include/asm/pgalloc_32.h b/arch/sparc/include/asm/pgalloc_32.h index ca2b344..e5b169b46 100644 --- a/arch/sparc/include/asm/pgalloc_32.h +++ b/arch/sparc/include/asm/pgalloc_32.h
@@ -4,8 +4,10 @@ #include <linux/kernel.h> #include <linux/sched.h> +#include <asm/pgtsrmmu.h> +#include <asm/pgtable.h> +#include <asm/vaddrs.h> #include <asm/page.h> -#include <asm/btfixup.h> struct page; @@ -15,54 +17,74 @@ unsigned long pgtable_cache_sz; unsigned long pgd_cache_sz; } pgt_quicklists; + +unsigned long srmmu_get_nocache(int size, int align); +void srmmu_free_nocache(unsigned long vaddr, int size); + #define pgd_quicklist (pgt_quicklists.pgd_cache) #define pmd_quicklist ((unsigned long *)0) #define pte_quicklist (pgt_quicklists.pte_cache) #define pgtable_cache_size (pgt_quicklists.pgtable_cache_sz) #define pgd_cache_size (pgt_quicklists.pgd_cache_sz) -extern void check_pgt_cache(void); -BTFIXUPDEF_CALL(void, do_check_pgt_cache, int, int) -#define do_check_pgt_cache(low,high) BTFIXUP_CALL(do_check_pgt_cache)(low,high) +#define check_pgt_cache() do { } while (0) -BTFIXUPDEF_CALL(pgd_t *, get_pgd_fast, void) -#define get_pgd_fast() BTFIXUP_CALL(get_pgd_fast)() - -BTFIXUPDEF_CALL(void, free_pgd_fast, pgd_t *) -#define free_pgd_fast(pgd) BTFIXUP_CALL(free_pgd_fast)(pgd) +pgd_t *get_pgd_fast(void); +static inline void free_pgd_fast(pgd_t *pgd) +{ + srmmu_free_nocache((unsigned long)pgd, SRMMU_PGD_TABLE_SIZE); +} #define pgd_free(mm, pgd) free_pgd_fast(pgd) #define pgd_alloc(mm) get_pgd_fast() -BTFIXUPDEF_CALL(void, pgd_set, pgd_t *, pmd_t *) -#define pgd_set(pgdp,pmdp) BTFIXUP_CALL(pgd_set)(pgdp,pmdp) +static inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp) +{ + unsigned long pa = __nocache_pa((unsigned long)pmdp); + + set_pte((pte_t *)pgdp, (SRMMU_ET_PTD | (pa >> 4))); +} + #define pgd_populate(MM, PGD, PMD) pgd_set(PGD, PMD) -BTFIXUPDEF_CALL(pmd_t *, pmd_alloc_one, struct mm_struct *, unsigned long) -#define pmd_alloc_one(mm, address) BTFIXUP_CALL(pmd_alloc_one)(mm, address) +static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, + unsigned long address) +{ + return (pmd_t *)srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, + SRMMU_PMD_TABLE_SIZE); +} -BTFIXUPDEF_CALL(void, free_pmd_fast, pmd_t *) -#define free_pmd_fast(pmd) BTFIXUP_CALL(free_pmd_fast)(pmd) +static inline void free_pmd_fast(pmd_t * pmd) +{ + srmmu_free_nocache((unsigned long)pmd, SRMMU_PMD_TABLE_SIZE); +} #define pmd_free(mm, pmd) free_pmd_fast(pmd) #define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tlb)->mm, pmd) -BTFIXUPDEF_CALL(void, pmd_populate, pmd_t *, struct page *) -#define pmd_populate(MM, PMD, PTE) BTFIXUP_CALL(pmd_populate)(PMD, PTE) +void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep); #define pmd_pgtable(pmd) pmd_page(pmd) -BTFIXUPDEF_CALL(void, pmd_set, pmd_t *, pte_t *) -#define pmd_populate_kernel(MM, PMD, PTE) BTFIXUP_CALL(pmd_set)(PMD, PTE) -BTFIXUPDEF_CALL(pgtable_t , pte_alloc_one, struct mm_struct *, unsigned long) -#define pte_alloc_one(mm, address) BTFIXUP_CALL(pte_alloc_one)(mm, address) -BTFIXUPDEF_CALL(pte_t *, pte_alloc_one_kernel, struct mm_struct *, unsigned long) -#define pte_alloc_one_kernel(mm, addr) BTFIXUP_CALL(pte_alloc_one_kernel)(mm, addr) +void pmd_set(pmd_t *pmdp, pte_t *ptep); +#define pmd_populate_kernel(MM, PMD, PTE) pmd_set(PMD, PTE) -BTFIXUPDEF_CALL(void, free_pte_fast, pte_t *) -#define pte_free_kernel(mm, pte) BTFIXUP_CALL(free_pte_fast)(pte) +pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address); -BTFIXUPDEF_CALL(void, pte_free, pgtable_t ) -#define pte_free(mm, pte) BTFIXUP_CALL(pte_free)(pte) +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, + unsigned long address) +{ + return (pte_t *)srmmu_get_nocache(PTE_SIZE, PTE_SIZE); +} + + +static inline void free_pte_fast(pte_t *pte) +{ + srmmu_free_nocache((unsigned long)pte, PTE_SIZE); +} + +#define pte_free_kernel(mm, pte) free_pte_fast(pte) + +void pte_free(struct mm_struct * mm, pgtable_t pte); #define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte) #endif /* _SPARC_PGALLOC_H */
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h index 3d71018..cbbbed5 100644 --- a/arch/sparc/include/asm/pgtable_32.h +++ b/arch/sparc/include/asm/pgtable_32.h
@@ -16,11 +16,9 @@ #include <linux/spinlock.h> #include <linux/swap.h> #include <asm/types.h> -#include <asm/pgtsun4c.h> #include <asm/pgtsrmmu.h> -#include <asm/vac-ops.h> +#include <asm/vaddrs.h> #include <asm/oplib.h> -#include <asm/btfixup.h> #include <asm/cpu_type.h> @@ -30,87 +28,55 @@ extern void load_mmu(void); extern unsigned long calc_highpages(void); -BTFIXUPDEF_SIMM13(pgdir_shift) -BTFIXUPDEF_SETHI(pgdir_size) -BTFIXUPDEF_SETHI(pgdir_mask) - -BTFIXUPDEF_SIMM13(ptrs_per_pmd) -BTFIXUPDEF_SIMM13(ptrs_per_pgd) -BTFIXUPDEF_SIMM13(user_ptrs_per_pgd) - #define pte_ERROR(e) __builtin_trap() #define pmd_ERROR(e) __builtin_trap() #define pgd_ERROR(e) __builtin_trap() -BTFIXUPDEF_INT(page_none) -BTFIXUPDEF_INT(page_copy) -BTFIXUPDEF_INT(page_readonly) -BTFIXUPDEF_INT(page_kernel) - -#define PMD_SHIFT SUN4C_PMD_SHIFT +#define PMD_SHIFT 22 #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) #define PMD_ALIGN(__addr) (((__addr) + ~PMD_MASK) & PMD_MASK) -#define PGDIR_SHIFT BTFIXUP_SIMM13(pgdir_shift) -#define PGDIR_SIZE BTFIXUP_SETHI(pgdir_size) -#define PGDIR_MASK BTFIXUP_SETHI(pgdir_mask) +#define PGDIR_SHIFT SRMMU_PGDIR_SHIFT +#define PGDIR_SIZE SRMMU_PGDIR_SIZE +#define PGDIR_MASK SRMMU_PGDIR_MASK #define PTRS_PER_PTE 1024 -#define PTRS_PER_PMD BTFIXUP_SIMM13(ptrs_per_pmd) -#define PTRS_PER_PGD BTFIXUP_SIMM13(ptrs_per_pgd) -#define USER_PTRS_PER_PGD BTFIXUP_SIMM13(user_ptrs_per_pgd) +#define PTRS_PER_PMD SRMMU_PTRS_PER_PMD +#define PTRS_PER_PGD SRMMU_PTRS_PER_PGD +#define USER_PTRS_PER_PGD PAGE_OFFSET / SRMMU_PGDIR_SIZE #define FIRST_USER_ADDRESS 0 #define PTE_SIZE (PTRS_PER_PTE*4) -#define PAGE_NONE __pgprot(BTFIXUP_INT(page_none)) -extern pgprot_t PAGE_SHARED; -#define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy)) -#define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly)) - -extern unsigned long page_kernel; - -#ifdef MODULE -#define PAGE_KERNEL page_kernel -#else -#define PAGE_KERNEL __pgprot(BTFIXUP_INT(page_kernel)) -#endif +#define PAGE_NONE SRMMU_PAGE_NONE +#define PAGE_SHARED SRMMU_PAGE_SHARED +#define PAGE_COPY SRMMU_PAGE_COPY +#define PAGE_READONLY SRMMU_PAGE_RDONLY +#define PAGE_KERNEL SRMMU_PAGE_KERNEL /* Top-level page directory */ extern pgd_t swapper_pg_dir[1024]; extern void paging_init(void); -/* Page table for 0-4MB for everybody, on the Sparc this - * holds the same as on the i386. - */ -extern pte_t pg0[1024]; -extern pte_t pg1[1024]; -extern pte_t pg2[1024]; -extern pte_t pg3[1024]; - extern unsigned long ptr_in_current_pgd; -/* Here is a trick, since mmap.c need the initializer elements for - * protection_map[] to be constant at compile time, I set the following - * to all zeros. I set it to the real values after I link in the - * appropriate MMU page table routines at boot time. - */ -#define __P000 __pgprot(0) -#define __P001 __pgprot(0) -#define __P010 __pgprot(0) -#define __P011 __pgprot(0) -#define __P100 __pgprot(0) -#define __P101 __pgprot(0) -#define __P110 __pgprot(0) -#define __P111 __pgprot(0) +/* xwr */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY -#define __S000 __pgprot(0) -#define __S001 __pgprot(0) -#define __S010 __pgprot(0) -#define __S011 __pgprot(0) -#define __S100 __pgprot(0) -#define __S101 __pgprot(0) -#define __S110 __pgprot(0) -#define __S111 __pgprot(0) +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED extern int num_contexts; @@ -137,82 +103,137 @@ #define ZERO_PAGE(vaddr) (virt_to_page(&empty_zero_page)) /* + * In general all page table modifications should use the V8 atomic + * swap instruction. This insures the mmu and the cpu are in sync + * with respect to ref/mod bits in the page tables. */ -BTFIXUPDEF_CALL_CONST(struct page *, pmd_page, pmd_t) -BTFIXUPDEF_CALL_CONST(unsigned long, pgd_page_vaddr, pgd_t) +static inline unsigned long srmmu_swap(unsigned long *addr, unsigned long value) +{ + __asm__ __volatile__("swap [%2], %0" : "=&r" (value) : "0" (value), "r" (addr)); + return value; +} -#define pmd_page(pmd) BTFIXUP_CALL(pmd_page)(pmd) -#define pgd_page_vaddr(pgd) BTFIXUP_CALL(pgd_page_vaddr)(pgd) +/* Certain architectures need to do special things when pte's + * within a page table are directly modified. Thus, the following + * hook is made available. + */ -BTFIXUPDEF_CALL_CONST(int, pte_present, pte_t) -BTFIXUPDEF_CALL(void, pte_clear, pte_t *) +static inline void set_pte(pte_t *ptep, pte_t pteval) +{ + srmmu_swap((unsigned long *)ptep, pte_val(pteval)); +} + +#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) + +static inline int srmmu_device_memory(unsigned long x) +{ + return ((x & 0xF0000000) != 0); +} + +static inline struct page *pmd_page(pmd_t pmd) +{ + if (srmmu_device_memory(pmd_val(pmd))) + BUG(); + return pfn_to_page((pmd_val(pmd) & SRMMU_PTD_PMASK) >> (PAGE_SHIFT-4)); +} + +static inline unsigned long pgd_page_vaddr(pgd_t pgd) +{ + if (srmmu_device_memory(pgd_val(pgd))) { + return ~0; + } else { + unsigned long v = pgd_val(pgd) & SRMMU_PTD_PMASK; + return (unsigned long)__nocache_va(v << 4); + } +} + +static inline int pte_present(pte_t pte) +{ + return ((pte_val(pte) & SRMMU_ET_MASK) == SRMMU_ET_PTE); +} static inline int pte_none(pte_t pte) { return !pte_val(pte); } -#define pte_present(pte) BTFIXUP_CALL(pte_present)(pte) -#define pte_clear(mm,addr,pte) BTFIXUP_CALL(pte_clear)(pte) +static inline void __pte_clear(pte_t *ptep) +{ + set_pte(ptep, __pte(0)); +} -BTFIXUPDEF_CALL_CONST(int, pmd_bad, pmd_t) -BTFIXUPDEF_CALL_CONST(int, pmd_present, pmd_t) -BTFIXUPDEF_CALL(void, pmd_clear, pmd_t *) +static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + __pte_clear(ptep); +} + +static inline int pmd_bad(pmd_t pmd) +{ + return (pmd_val(pmd) & SRMMU_ET_MASK) != SRMMU_ET_PTD; +} + +static inline int pmd_present(pmd_t pmd) +{ + return ((pmd_val(pmd) & SRMMU_ET_MASK) == SRMMU_ET_PTD); +} static inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); } -#define pmd_bad(pmd) BTFIXUP_CALL(pmd_bad)(pmd) -#define pmd_present(pmd) BTFIXUP_CALL(pmd_present)(pmd) -#define pmd_clear(pmd) BTFIXUP_CALL(pmd_clear)(pmd) +static inline void pmd_clear(pmd_t *pmdp) +{ + int i; + for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) + set_pte((pte_t *)&pmdp->pmdv[i], __pte(0)); +} -BTFIXUPDEF_CALL_CONST(int, pgd_none, pgd_t) -BTFIXUPDEF_CALL_CONST(int, pgd_bad, pgd_t) -BTFIXUPDEF_CALL_CONST(int, pgd_present, pgd_t) -BTFIXUPDEF_CALL(void, pgd_clear, pgd_t *) +static inline int pgd_none(pgd_t pgd) +{ + return !(pgd_val(pgd) & 0xFFFFFFF); +} -#define pgd_none(pgd) BTFIXUP_CALL(pgd_none)(pgd) -#define pgd_bad(pgd) BTFIXUP_CALL(pgd_bad)(pgd) -#define pgd_present(pgd) BTFIXUP_CALL(pgd_present)(pgd) -#define pgd_clear(pgd) BTFIXUP_CALL(pgd_clear)(pgd) +static inline int pgd_bad(pgd_t pgd) +{ + return (pgd_val(pgd) & SRMMU_ET_MASK) != SRMMU_ET_PTD; +} + +static inline int pgd_present(pgd_t pgd) +{ + return ((pgd_val(pgd) & SRMMU_ET_MASK) == SRMMU_ET_PTD); +} + +static inline void pgd_clear(pgd_t *pgdp) +{ + set_pte((pte_t *)pgdp, __pte(0)); +} /* * The following only work if pte_present() is true. * Undefined behaviour if not.. */ -BTFIXUPDEF_HALF(pte_writei) -BTFIXUPDEF_HALF(pte_dirtyi) -BTFIXUPDEF_HALF(pte_youngi) - -static int pte_write(pte_t pte) __attribute_const__; static inline int pte_write(pte_t pte) { - return pte_val(pte) & BTFIXUP_HALF(pte_writei); + return pte_val(pte) & SRMMU_WRITE; } -static int pte_dirty(pte_t pte) __attribute_const__; static inline int pte_dirty(pte_t pte) { - return pte_val(pte) & BTFIXUP_HALF(pte_dirtyi); + return pte_val(pte) & SRMMU_DIRTY; } -static int pte_young(pte_t pte) __attribute_const__; static inline int pte_young(pte_t pte) { - return pte_val(pte) & BTFIXUP_HALF(pte_youngi); + return pte_val(pte) & SRMMU_REF; } /* * The following only work if pte_present() is not true. */ -BTFIXUPDEF_HALF(pte_filei) - -static int pte_file(pte_t pte) __attribute_const__; static inline int pte_file(pte_t pte) { - return pte_val(pte) & BTFIXUP_HALF(pte_filei); + return pte_val(pte) & SRMMU_FILE; } static inline int pte_special(pte_t pte) @@ -220,68 +241,85 @@ return 0; } -/* - */ -BTFIXUPDEF_HALF(pte_wrprotecti) -BTFIXUPDEF_HALF(pte_mkcleani) -BTFIXUPDEF_HALF(pte_mkoldi) - -static pte_t pte_wrprotect(pte_t pte) __attribute_const__; static inline pte_t pte_wrprotect(pte_t pte) { - return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_wrprotecti)); + return __pte(pte_val(pte) & ~SRMMU_WRITE); } -static pte_t pte_mkclean(pte_t pte) __attribute_const__; static inline pte_t pte_mkclean(pte_t pte) { - return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkcleani)); + return __pte(pte_val(pte) & ~SRMMU_DIRTY); } -static pte_t pte_mkold(pte_t pte) __attribute_const__; static inline pte_t pte_mkold(pte_t pte) { - return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkoldi)); + return __pte(pte_val(pte) & ~SRMMU_REF); } -BTFIXUPDEF_CALL_CONST(pte_t, pte_mkwrite, pte_t) -BTFIXUPDEF_CALL_CONST(pte_t, pte_mkdirty, pte_t) -BTFIXUPDEF_CALL_CONST(pte_t, pte_mkyoung, pte_t) +static inline pte_t pte_mkwrite(pte_t pte) +{ + return __pte(pte_val(pte) | SRMMU_WRITE); +} -#define pte_mkwrite(pte) BTFIXUP_CALL(pte_mkwrite)(pte) -#define pte_mkdirty(pte) BTFIXUP_CALL(pte_mkdirty)(pte) -#define pte_mkyoung(pte) BTFIXUP_CALL(pte_mkyoung)(pte) +static inline pte_t pte_mkdirty(pte_t pte) +{ + return __pte(pte_val(pte) | SRMMU_DIRTY); +} + +static inline pte_t pte_mkyoung(pte_t pte) +{ + return __pte(pte_val(pte) | SRMMU_REF); +} #define pte_mkspecial(pte) (pte) #define pfn_pte(pfn, prot) mk_pte(pfn_to_page(pfn), prot) -BTFIXUPDEF_CALL(unsigned long, pte_pfn, pte_t) -#define pte_pfn(pte) BTFIXUP_CALL(pte_pfn)(pte) +static inline unsigned long pte_pfn(pte_t pte) +{ + if (srmmu_device_memory(pte_val(pte))) { + /* Just return something that will cause + * pfn_valid() to return false. This makes + * copy_one_pte() to just directly copy to + * PTE over. + */ + return ~0UL; + } + return (pte_val(pte) & SRMMU_PTE_PMASK) >> (PAGE_SHIFT-4); +} + #define pte_page(pte) pfn_to_page(pte_pfn(pte)) /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ -BTFIXUPDEF_CALL_CONST(pte_t, mk_pte, struct page *, pgprot_t) +static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) +{ + return __pte((page_to_pfn(page) << (PAGE_SHIFT-4)) | pgprot_val(pgprot)); +} -BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_phys, unsigned long, pgprot_t) -BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_io, unsigned long, pgprot_t, int) -BTFIXUPDEF_CALL_CONST(pgprot_t, pgprot_noncached, pgprot_t) +static inline pte_t mk_pte_phys(unsigned long page, pgprot_t pgprot) +{ + return __pte(((page) >> 4) | pgprot_val(pgprot)); +} -#define mk_pte(page,pgprot) BTFIXUP_CALL(mk_pte)(page,pgprot) -#define mk_pte_phys(page,pgprot) BTFIXUP_CALL(mk_pte_phys)(page,pgprot) -#define mk_pte_io(page,pgprot,space) BTFIXUP_CALL(mk_pte_io)(page,pgprot,space) +static inline pte_t mk_pte_io(unsigned long page, pgprot_t pgprot, int space) +{ + return __pte(((page) >> 4) | (space << 28) | pgprot_val(pgprot)); +} -#define pgprot_noncached(pgprot) BTFIXUP_CALL(pgprot_noncached)(pgprot) - -BTFIXUPDEF_INT(pte_modify_mask) +#define pgprot_noncached pgprot_noncached +static inline pgprot_t pgprot_noncached(pgprot_t prot) +{ + prot &= ~__pgprot(SRMMU_CACHE); + return prot; +} static pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__; static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { - return __pte((pte_val(pte) & BTFIXUP_INT(pte_modify_mask)) | + return __pte((pte_val(pte) & SRMMU_CHG_MASK) | pgprot_val(newprot)); } @@ -294,74 +332,69 @@ #define pgd_offset_k(address) pgd_offset(&init_mm, address) /* Find an entry in the second-level page table.. */ -BTFIXUPDEF_CALL(pmd_t *, pmd_offset, pgd_t *, unsigned long) -#define pmd_offset(dir,addr) BTFIXUP_CALL(pmd_offset)(dir,addr) +static inline pmd_t *pmd_offset(pgd_t * dir, unsigned long address) +{ + return (pmd_t *) pgd_page_vaddr(*dir) + + ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1)); +} /* Find an entry in the third-level page table.. */ -BTFIXUPDEF_CALL(pte_t *, pte_offset_kernel, pmd_t *, unsigned long) -#define pte_offset_kernel(dir,addr) BTFIXUP_CALL(pte_offset_kernel)(dir,addr) +pte_t *pte_offset_kernel(pmd_t * dir, unsigned long address); /* - * This shortcut works on sun4m (and sun4d) because the nocache area is static, - * and sun4c is guaranteed to have no highmem anyway. + * This shortcut works on sun4m (and sun4d) because the nocache area is static. */ #define pte_offset_map(d, a) pte_offset_kernel(d,a) #define pte_unmap(pte) do{}while(0) -/* Certain architectures need to do special things when pte's - * within a page table are directly modified. Thus, the following - * hook is made available. - */ - -BTFIXUPDEF_CALL(void, set_pte, pte_t *, pte_t) - -#define set_pte(ptep,pteval) BTFIXUP_CALL(set_pte)(ptep,pteval) -#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) - struct seq_file; -BTFIXUPDEF_CALL(void, mmu_info, struct seq_file *) - -#define mmu_info(p) BTFIXUP_CALL(mmu_info)(p) +void mmu_info(struct seq_file *m); /* Fault handler stuff... */ #define FAULT_CODE_PROT 0x1 #define FAULT_CODE_WRITE 0x2 #define FAULT_CODE_USER 0x4 -BTFIXUPDEF_CALL(void, update_mmu_cache, struct vm_area_struct *, unsigned long, pte_t *) +#define update_mmu_cache(vma, address, ptep) do { } while (0) -#define update_mmu_cache(vma,addr,ptep) BTFIXUP_CALL(update_mmu_cache)(vma,addr,ptep) - -BTFIXUPDEF_CALL(void, sparc_mapiorange, unsigned int, unsigned long, - unsigned long, unsigned int) -BTFIXUPDEF_CALL(void, sparc_unmapiorange, unsigned long, unsigned int) -#define sparc_mapiorange(bus,pa,va,len) BTFIXUP_CALL(sparc_mapiorange)(bus,pa,va,len) -#define sparc_unmapiorange(va,len) BTFIXUP_CALL(sparc_unmapiorange)(va,len) - -extern int invalid_segment; +void srmmu_mapiorange(unsigned int bus, unsigned long xpa, + unsigned long xva, unsigned int len); +void srmmu_unmapiorange(unsigned long virt_addr, unsigned int len); /* Encode and de-code a swap entry */ -BTFIXUPDEF_CALL(unsigned long, __swp_type, swp_entry_t) -BTFIXUPDEF_CALL(unsigned long, __swp_offset, swp_entry_t) -BTFIXUPDEF_CALL(swp_entry_t, __swp_entry, unsigned long, unsigned long) +static inline unsigned long __swp_type(swp_entry_t entry) +{ + return (entry.val >> SRMMU_SWP_TYPE_SHIFT) & SRMMU_SWP_TYPE_MASK; +} -#define __swp_type(__x) BTFIXUP_CALL(__swp_type)(__x) -#define __swp_offset(__x) BTFIXUP_CALL(__swp_offset)(__x) -#define __swp_entry(__type,__off) BTFIXUP_CALL(__swp_entry)(__type,__off) +static inline unsigned long __swp_offset(swp_entry_t entry) +{ + return (entry.val >> SRMMU_SWP_OFF_SHIFT) & SRMMU_SWP_OFF_MASK; +} + +static inline swp_entry_t __swp_entry(unsigned long type, unsigned long offset) +{ + return (swp_entry_t) { + (type & SRMMU_SWP_TYPE_MASK) << SRMMU_SWP_TYPE_SHIFT + | (offset & SRMMU_SWP_OFF_MASK) << SRMMU_SWP_OFF_SHIFT }; +} #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) /* file-offset-in-pte helpers */ -BTFIXUPDEF_CALL(unsigned long, pte_to_pgoff, pte_t pte); -BTFIXUPDEF_CALL(pte_t, pgoff_to_pte, unsigned long pgoff); +static inline unsigned long pte_to_pgoff(pte_t pte) +{ + return pte_val(pte) >> SRMMU_PTE_FILE_SHIFT; +} -#define pte_to_pgoff(pte) BTFIXUP_CALL(pte_to_pgoff)(pte) -#define pgoff_to_pte(off) BTFIXUP_CALL(pgoff_to_pte)(off) +static inline pte_t pgoff_to_pte(unsigned long pgoff) +{ + return __pte((pgoff << SRMMU_PTE_FILE_SHIFT) | SRMMU_FILE); +} /* * This is made a constant because mm/fremap.c required a constant. - * Note that layout of these bits is different between sun4c.c and srmmu.c. */ #define PTE_FILE_MAX_BITS 24 @@ -399,9 +432,6 @@ __get_phys (unsigned long addr) { switch (sparc_cpu_model){ - case sun4: - case sun4c: - return sun4c_get_pte (addr) << PAGE_SHIFT; case sun4m: case sun4d: return ((srmmu_get_pte (addr) & 0xffffff00) << 4); @@ -414,9 +444,6 @@ __get_iospace (unsigned long addr) { switch (sparc_cpu_model){ - case sun4: - case sun4c: - return -1; /* Don't check iospace on sun4c */ case sun4m: case sun4d: return (srmmu_get_pte (addr) >> 28); @@ -463,7 +490,7 @@ set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry); \ flush_tlb_page(__vma, __address); \ } \ - (sparc_cpu_model == sun4c) || __changed; \ + __changed; \ }) #include <asm-generic/pgtable.h> @@ -471,10 +498,8 @@ #endif /* !(__ASSEMBLY__) */ #define VMALLOC_START _AC(0xfe600000,UL) -/* XXX Alter this when I get around to fixing sun4c - Anton */ #define VMALLOC_END _AC(0xffc00000,UL) - /* We provide our own get_unmapped_area to cope with VA holes for userland */ #define HAVE_ARCH_UNMAPPED_AREA
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 76e4a52..61210db1 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h
@@ -717,10 +717,6 @@ struct seq_file; extern void mmu_info(struct seq_file *); -/* These do nothing with the way I have things setup. */ -#define mmu_lockarea(vaddr, len) (vaddr) -#define mmu_unlockarea(vaddr, len) do { } while(0) - struct vm_area_struct; extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
diff --git a/arch/sparc/include/asm/pgtsrmmu.h b/arch/sparc/include/asm/pgtsrmmu.h index f6ae2b2..cb82870 100644 --- a/arch/sparc/include/asm/pgtsrmmu.h +++ b/arch/sparc/include/asm/pgtsrmmu.h
@@ -173,17 +173,6 @@ "memory"); } -static inline unsigned long srmmu_get_ctable_ptr(void) -{ - unsigned int retval; - - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (retval) : - "r" (SRMMU_CTXTBL_PTR), - "i" (ASI_M_MMUREGS)); - return (retval & SRMMU_CTX_PMASK) << 4; -} - static inline void srmmu_set_context(int context) { __asm__ __volatile__("sta %0, [%1] %2\n\t" : : @@ -231,42 +220,6 @@ } /* These flush types are not available on all chips... */ -static inline void srmmu_flush_tlb_ctx(void) -{ - __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : - "r" (0x300), /* Flush TLB ctx.. */ - "i" (ASI_M_FLUSH_PROBE) : "memory"); - -} - -static inline void srmmu_flush_tlb_region(unsigned long addr) -{ - addr &= SRMMU_PGDIR_MASK; - __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : - "r" (addr | 0x200), /* Flush TLB region.. */ - "i" (ASI_M_FLUSH_PROBE) : "memory"); - -} - - -static inline void srmmu_flush_tlb_segment(unsigned long addr) -{ - addr &= SRMMU_REAL_PMD_MASK; - __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : - "r" (addr | 0x100), /* Flush TLB segment.. */ - "i" (ASI_M_FLUSH_PROBE) : "memory"); - -} - -static inline void srmmu_flush_tlb_page(unsigned long page) -{ - page &= PAGE_MASK; - __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : - "r" (page), /* Flush TLB page.. */ - "i" (ASI_M_FLUSH_PROBE) : "memory"); - -} - #ifndef CONFIG_SPARC_LEON static inline unsigned long srmmu_hwprobe(unsigned long vaddr) { @@ -294,9 +247,6 @@ return entry; } -extern unsigned long (*srmmu_read_physical)(unsigned long paddr); -extern void (*srmmu_write_physical)(unsigned long paddr, unsigned long word); - #endif /* !(__ASSEMBLY__) */ #endif /* !(_SPARC_PGTSRMMU_H) */
diff --git a/arch/sparc/include/asm/pgtsun4c.h b/arch/sparc/include/asm/pgtsun4c.h deleted file mode 100644 index aeb25e9..0000000 --- a/arch/sparc/include/asm/pgtsun4c.h +++ /dev/null
@@ -1,172 +0,0 @@ -/* - * pgtsun4c.h: Sun4c specific pgtable.h defines and code. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - */ -#ifndef _SPARC_PGTSUN4C_H -#define _SPARC_PGTSUN4C_H - -#include <asm/contregs.h> - -/* PMD_SHIFT determines the size of the area a second-level page table can map */ -#define SUN4C_PMD_SHIFT 22 - -/* PGDIR_SHIFT determines what a third-level page table entry can map */ -#define SUN4C_PGDIR_SHIFT 22 -#define SUN4C_PGDIR_SIZE (1UL << SUN4C_PGDIR_SHIFT) -#define SUN4C_PGDIR_MASK (~(SUN4C_PGDIR_SIZE-1)) -#define SUN4C_PGDIR_ALIGN(addr) (((addr)+SUN4C_PGDIR_SIZE-1)&SUN4C_PGDIR_MASK) - -/* To represent how the sun4c mmu really lays things out. */ -#define SUN4C_REAL_PGDIR_SHIFT 18 -#define SUN4C_REAL_PGDIR_SIZE (1UL << SUN4C_REAL_PGDIR_SHIFT) -#define SUN4C_REAL_PGDIR_MASK (~(SUN4C_REAL_PGDIR_SIZE-1)) -#define SUN4C_REAL_PGDIR_ALIGN(addr) (((addr)+SUN4C_REAL_PGDIR_SIZE-1)&SUN4C_REAL_PGDIR_MASK) - -/* 16 bit PFN on sun4c */ -#define SUN4C_PFN_MASK 0xffff - -/* Don't increase these unless the structures in sun4c.c are fixed */ -#define SUN4C_MAX_SEGMAPS 256 -#define SUN4C_MAX_CONTEXTS 16 - -/* - * To be efficient, and not have to worry about allocating such - * a huge pgd, we make the kernel sun4c tables each hold 1024 - * entries and the pgd similarly just like the i386 tables. - */ -#define SUN4C_PTRS_PER_PTE 1024 -#define SUN4C_PTRS_PER_PMD 1 -#define SUN4C_PTRS_PER_PGD 1024 - -/* - * Sparc SUN4C pte fields. - */ -#define _SUN4C_PAGE_VALID 0x80000000 -#define _SUN4C_PAGE_SILENT_READ 0x80000000 /* synonym */ -#define _SUN4C_PAGE_DIRTY 0x40000000 -#define _SUN4C_PAGE_SILENT_WRITE 0x40000000 /* synonym */ -#define _SUN4C_PAGE_PRIV 0x20000000 /* privileged page */ -#define _SUN4C_PAGE_NOCACHE 0x10000000 /* non-cacheable page */ -#define _SUN4C_PAGE_PRESENT 0x08000000 /* implemented in software */ -#define _SUN4C_PAGE_IO 0x04000000 /* I/O page */ -#define _SUN4C_PAGE_FILE 0x02000000 /* implemented in software */ -#define _SUN4C_PAGE_READ 0x00800000 /* implemented in software */ -#define _SUN4C_PAGE_WRITE 0x00400000 /* implemented in software */ -#define _SUN4C_PAGE_ACCESSED 0x00200000 /* implemented in software */ -#define _SUN4C_PAGE_MODIFIED 0x00100000 /* implemented in software */ - -#define _SUN4C_READABLE (_SUN4C_PAGE_READ|_SUN4C_PAGE_SILENT_READ|\ - _SUN4C_PAGE_ACCESSED) -#define _SUN4C_WRITEABLE (_SUN4C_PAGE_WRITE|_SUN4C_PAGE_SILENT_WRITE|\ - _SUN4C_PAGE_MODIFIED) - -#define _SUN4C_PAGE_CHG_MASK (0xffff|_SUN4C_PAGE_ACCESSED|_SUN4C_PAGE_MODIFIED) - -#define SUN4C_PAGE_NONE __pgprot(_SUN4C_PAGE_PRESENT) -#define SUN4C_PAGE_SHARED __pgprot(_SUN4C_PAGE_PRESENT|_SUN4C_READABLE|\ - _SUN4C_PAGE_WRITE) -#define SUN4C_PAGE_COPY __pgprot(_SUN4C_PAGE_PRESENT|_SUN4C_READABLE) -#define SUN4C_PAGE_READONLY __pgprot(_SUN4C_PAGE_PRESENT|_SUN4C_READABLE) -#define SUN4C_PAGE_KERNEL __pgprot(_SUN4C_READABLE|_SUN4C_WRITEABLE|\ - _SUN4C_PAGE_DIRTY|_SUN4C_PAGE_PRIV) - -/* SUN4C swap entry encoding - * - * We use 5 bits for the type and 19 for the offset. This gives us - * 32 swapfiles of 4GB each. Encoding looks like: - * - * RRRRRRRRooooooooooooooooooottttt - * fedcba9876543210fedcba9876543210 - * - * The top 8 bits are reserved for protection and status bits, especially - * FILE and PRESENT. - */ -#define SUN4C_SWP_TYPE_MASK 0x1f -#define SUN4C_SWP_OFF_MASK 0x7ffff -#define SUN4C_SWP_OFF_SHIFT 5 - -#ifndef __ASSEMBLY__ - -static inline unsigned long sun4c_get_synchronous_error(void) -{ - unsigned long sync_err; - - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (sync_err) : - "r" (AC_SYNC_ERR), "i" (ASI_CONTROL)); - return sync_err; -} - -static inline unsigned long sun4c_get_synchronous_address(void) -{ - unsigned long sync_addr; - - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (sync_addr) : - "r" (AC_SYNC_VA), "i" (ASI_CONTROL)); - return sync_addr; -} - -/* SUN4C pte, segmap, and context manipulation */ -static inline unsigned long sun4c_get_segmap(unsigned long addr) -{ - register unsigned long entry; - - __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" : - "=r" (entry) : - "r" (addr), "i" (ASI_SEGMAP)); - - return entry; -} - -static inline void sun4c_put_segmap(unsigned long addr, unsigned long entry) -{ - - __asm__ __volatile__("\n\tstba %1, [%0] %2; nop; nop; nop;\n\t" : : - "r" (addr), "r" (entry), - "i" (ASI_SEGMAP) - : "memory"); -} - -static inline unsigned long sun4c_get_pte(unsigned long addr) -{ - register unsigned long entry; - - __asm__ __volatile__("\n\tlda [%1] %2, %0\n\t" : - "=r" (entry) : - "r" (addr), "i" (ASI_PTE)); - return entry; -} - -static inline void sun4c_put_pte(unsigned long addr, unsigned long entry) -{ - __asm__ __volatile__("\n\tsta %1, [%0] %2; nop; nop; nop;\n\t" : : - "r" (addr), - "r" ((entry & ~(_SUN4C_PAGE_PRESENT))), "i" (ASI_PTE) - : "memory"); -} - -static inline int sun4c_get_context(void) -{ - register int ctx; - - __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" : - "=r" (ctx) : - "r" (AC_CONTEXT), "i" (ASI_CONTROL)); - - return ctx; -} - -static inline int sun4c_set_context(int ctx) -{ - __asm__ __volatile__("\n\tstba %0, [%1] %2; nop; nop; nop;\n\t" : : - "r" (ctx), "r" (AC_CONTEXT), "i" (ASI_CONTROL) - : "memory"); - - return ctx; -} - -#endif /* !(__ASSEMBLY__) */ - -#endif /* !(_SPARC_PGTSUN4C_H) */
diff --git a/arch/sparc/include/asm/processor_32.h b/arch/sparc/include/asm/processor_32.h index 09521c6..9cbd854 100644 --- a/arch/sparc/include/asm/processor_32.h +++ b/arch/sparc/include/asm/processor_32.h
@@ -16,7 +16,6 @@ #include <asm/ptrace.h> #include <asm/head.h> #include <asm/signal.h> -#include <asm/btfixup.h> #include <asm/page.h> /*
diff --git a/arch/sparc/include/asm/setup.h b/arch/sparc/include/asm/setup.h index 00497ab..8a83699 100644 --- a/arch/sparc/include/asm/setup.h +++ b/arch/sparc/include/asm/setup.h
@@ -20,10 +20,7 @@ * Only sun4d + leon may have boot_cpu_id != 0 */ extern unsigned char boot_cpu_id; -extern unsigned char boot_cpu_id4; -extern unsigned long empty_bad_page; -extern unsigned long empty_bad_page_table; extern unsigned long empty_zero_page; extern int serial_console;
diff --git a/arch/sparc/include/asm/shmparam_32.h b/arch/sparc/include/asm/shmparam_32.h index 59a1243..142825c 100644 --- a/arch/sparc/include/asm/shmparam_32.h +++ b/arch/sparc/include/asm/shmparam_32.h
@@ -4,8 +4,6 @@ #define __ARCH_FORCE_SHMLBA 1 extern int vac_cache_size; -#define SHMLBA (vac_cache_size ? vac_cache_size : \ - (sparc_cpu_model == sun4c ? (64 * 1024) : \ - (sparc_cpu_model == sun4 ? (128 * 1024) : PAGE_SIZE))) +#define SHMLBA (vac_cache_size ? vac_cache_size : PAGE_SIZE) #endif /* _ASMSPARC_SHMPARAM_H */
diff --git a/arch/sparc/include/asm/smp_32.h b/arch/sparc/include/asm/smp_32.h index 01c51c7..b73da3c 100644 --- a/arch/sparc/include/asm/smp_32.h +++ b/arch/sparc/include/asm/smp_32.h
@@ -8,7 +8,6 @@ #include <linux/threads.h> #include <asm/head.h> -#include <asm/btfixup.h> #ifndef __ASSEMBLY__ @@ -58,27 +57,43 @@ void smp_bogo(struct seq_file *); void smp_info(struct seq_file *); -BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, cpumask_t, unsigned long, unsigned long, unsigned long, unsigned long) -BTFIXUPDEF_CALL(int, __hard_smp_processor_id, void) -BTFIXUPDEF_CALL(void, smp_ipi_resched, int); -BTFIXUPDEF_CALL(void, smp_ipi_single, int); -BTFIXUPDEF_CALL(void, smp_ipi_mask_one, int); -BTFIXUPDEF_BLACKBOX(hard_smp_processor_id) -BTFIXUPDEF_BLACKBOX(load_current) +struct sparc32_ipi_ops { + void (*cross_call)(smpfunc_t func, cpumask_t mask, unsigned long arg1, + unsigned long arg2, unsigned long arg3, + unsigned long arg4); + void (*resched)(int cpu); + void (*single)(int cpu); + void (*mask_one)(int cpu); +}; +extern const struct sparc32_ipi_ops *sparc32_ipi_ops; -#define smp_cross_call(func,mask,arg1,arg2,arg3,arg4) BTFIXUP_CALL(smp_cross_call)(func,mask,arg1,arg2,arg3,arg4) +static inline void xc0(smpfunc_t func) +{ + sparc32_ipi_ops->cross_call(func, *cpu_online_mask, 0, 0, 0, 0); +} -static inline void xc0(smpfunc_t func) { smp_cross_call(func, *cpu_online_mask, 0, 0, 0, 0); } static inline void xc1(smpfunc_t func, unsigned long arg1) -{ smp_cross_call(func, *cpu_online_mask, arg1, 0, 0, 0); } +{ + sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, 0, 0, 0); +} static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2) -{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0); } +{ + sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0); +} + static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2, - unsigned long arg3) -{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, arg3, 0); } + unsigned long arg3) +{ + sparc32_ipi_ops->cross_call(func, *cpu_online_mask, + arg1, arg2, arg3, 0); +} + static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2, - unsigned long arg3, unsigned long arg4) -{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, arg3, arg4); } + unsigned long arg3, unsigned long arg4) +{ + sparc32_ipi_ops->cross_call(func, *cpu_online_mask, + arg1, arg2, arg3, arg4); +} extern void arch_send_call_function_single_ipi(int cpu); extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); @@ -88,74 +103,7 @@ return cpu; } -static inline int hard_smp4m_processor_id(void) -{ - int cpuid; - - __asm__ __volatile__("rd %%tbr, %0\n\t" - "srl %0, 12, %0\n\t" - "and %0, 3, %0\n\t" : - "=&r" (cpuid)); - return cpuid; -} - -static inline int hard_smp4d_processor_id(void) -{ - int cpuid; - - __asm__ __volatile__("lda [%%g0] %1, %0\n\t" : - "=&r" (cpuid) : "i" (ASI_M_VIKING_TMP1)); - return cpuid; -} - -extern inline int hard_smpleon_processor_id(void) -{ - int cpuid; - __asm__ __volatile__("rd %%asr17,%0\n\t" - "srl %0,28,%0" : - "=&r" (cpuid) : ); - return cpuid; -} - -#ifndef MODULE -static inline int hard_smp_processor_id(void) -{ - int cpuid; - - /* Black box - sun4m - __asm__ __volatile__("rd %%tbr, %0\n\t" - "srl %0, 12, %0\n\t" - "and %0, 3, %0\n\t" : - "=&r" (cpuid)); - - sun4d - __asm__ __volatile__("lda [%g0] ASI_M_VIKING_TMP1, %0\n\t" - "nop; nop" : - "=&r" (cpuid)); - - leon - __asm__ __volatile__( "rd %asr17, %0\n\t" - "srl %0, 0x1c, %0\n\t" - "nop\n\t" : - "=&r" (cpuid)); - See btfixup.h and btfixupprep.c to understand how a blackbox works. - */ - __asm__ __volatile__("sethi %%hi(___b_hard_smp_processor_id), %0\n\t" - "sethi %%hi(boot_cpu_id), %0\n\t" - "ldub [%0 + %%lo(boot_cpu_id)], %0\n\t" : - "=&r" (cpuid)); - return cpuid; -} -#else -static inline int hard_smp_processor_id(void) -{ - int cpuid; - - __asm__ __volatile__("mov %%o7, %%g1\n\t" - "call ___f___hard_smp_processor_id\n\t" - " nop\n\t" - "mov %%g2, %0\n\t" : "=r"(cpuid) : : "g1", "g2"); - return cpuid; -} -#endif +extern int hard_smp_processor_id(void); #define raw_smp_processor_id() (current_thread_info()->cpu)
diff --git a/arch/sparc/include/asm/smpprim.h b/arch/sparc/include/asm/smpprim.h deleted file mode 100644 index eb849d8..0000000 --- a/arch/sparc/include/asm/smpprim.h +++ /dev/null
@@ -1,54 +0,0 @@ -/* - * smpprim.h: SMP locking primitives on the Sparc - * - * God knows we won't be actually using this code for some time - * but I thought I'd write it since I knew how. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - */ - -#ifndef __SPARC_SMPPRIM_H -#define __SPARC_SMPPRIM_H - -/* Test and set the unsigned byte at ADDR to 1. Returns the previous - * value. On the Sparc we use the ldstub instruction since it is - * atomic. - */ - -static inline __volatile__ char test_and_set(void *addr) -{ - char state = 0; - - __asm__ __volatile__("ldstub [%0], %1 ! test_and_set\n\t" - "=r" (addr), "=r" (state) : - "0" (addr), "1" (state) : "memory"); - - return state; -} - -/* Initialize a spin-lock. */ -static inline __volatile__ smp_initlock(void *spinlock) -{ - /* Unset the lock. */ - *((unsigned char *) spinlock) = 0; - - return; -} - -/* This routine spins until it acquires the lock at ADDR. */ -static inline __volatile__ smp_lock(void *addr) -{ - while(test_and_set(addr) == 0xff) - ; - - /* We now have the lock */ - return; -} - -/* This routine releases the lock at ADDR. */ -static inline __volatile__ smp_unlock(void *addr) -{ - *((unsigned char *) addr) = 0; -} - -#endif /* !(__SPARC_SMPPRIM_H) */
diff --git a/arch/sparc/include/asm/string_32.h b/arch/sparc/include/asm/string_32.h index edf196e..12f6785 100644 --- a/arch/sparc/include/asm/string_32.h +++ b/arch/sparc/include/asm/string_32.h
@@ -61,68 +61,7 @@ extern __kernel_size_t strlen(const char *); #define __HAVE_ARCH_STRNCMP - -extern int __strncmp(const char *, const char *, __kernel_size_t); - -static inline int __constant_strncmp(const char *src, const char *dest, __kernel_size_t count) -{ - register int retval; - switch(count) { - case 0: return 0; - case 1: return (src[0] - dest[0]); - case 2: retval = (src[0] - dest[0]); - if(!retval && src[0]) - retval = (src[1] - dest[1]); - return retval; - case 3: retval = (src[0] - dest[0]); - if(!retval && src[0]) { - retval = (src[1] - dest[1]); - if(!retval && src[1]) - retval = (src[2] - dest[2]); - } - return retval; - case 4: retval = (src[0] - dest[0]); - if(!retval && src[0]) { - retval = (src[1] - dest[1]); - if(!retval && src[1]) { - retval = (src[2] - dest[2]); - if (!retval && src[2]) - retval = (src[3] - dest[3]); - } - } - return retval; - case 5: retval = (src[0] - dest[0]); - if(!retval && src[0]) { - retval = (src[1] - dest[1]); - if(!retval && src[1]) { - retval = (src[2] - dest[2]); - if (!retval && src[2]) { - retval = (src[3] - dest[3]); - if (!retval && src[3]) - retval = (src[4] - dest[4]); - } - } - } - return retval; - default: - retval = (src[0] - dest[0]); - if(!retval && src[0]) { - retval = (src[1] - dest[1]); - if(!retval && src[1]) { - retval = (src[2] - dest[2]); - if(!retval && src[2]) - retval = __strncmp(src+3,dest+3,count-3); - } - } - return retval; - } -} - -#undef strncmp -#define strncmp(__arg0, __arg1, __arg2) \ -(__builtin_constant_p(__arg2) ? \ - __constant_strncmp(__arg0, __arg1, __arg2) : \ - __strncmp(__arg0, __arg1, __arg2)) +extern int strncmp(const char *, const char *, __kernel_size_t); #endif /* !EXPORT_SYMTAB_STROPS */
diff --git a/arch/sparc/include/asm/sysen.h b/arch/sparc/include/asm/sysen.h deleted file mode 100644 index 6af34ab..0000000 --- a/arch/sparc/include/asm/sysen.h +++ /dev/null
@@ -1,15 +0,0 @@ -/* - * sysen.h: Bit fields within the "System Enable" register accessed via - * the ASI_CONTROL address space at address AC_SYSENABLE. - * - * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) - */ - -#ifndef _SPARC_SYSEN_H -#define _SPARC_SYSEN_H - -#define SENABLE_DVMA 0x20 /* enable dvma transfers */ -#define SENABLE_CACHE 0x10 /* enable VAC cache */ -#define SENABLE_RESET 0x04 /* reset whole machine, danger Will Robinson */ - -#endif /* _SPARC_SYSEN_H */
diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h index c2a1080..cd0b2dc 100644 --- a/arch/sparc/include/asm/thread_info_32.h +++ b/arch/sparc/include/asm/thread_info_32.h
@@ -15,7 +15,6 @@ #ifndef __ASSEMBLY__ -#include <asm/btfixup.h> #include <asm/ptrace.h> #include <asm/page.h> @@ -82,11 +81,8 @@ #define __HAVE_ARCH_THREAD_INFO_ALLOCATOR -BTFIXUPDEF_CALL(struct thread_info *, alloc_thread_info_node, int) -#define alloc_thread_info_node(tsk, node) BTFIXUP_CALL(alloc_thread_info_node)(node) - -BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *) -#define free_thread_info(ti) BTFIXUP_CALL(free_thread_info)(ti) +struct thread_info * alloc_thread_info_node(struct task_struct *tsk, int node); +void free_thread_info(struct thread_info *); #endif /* __ASSEMBLY__ */
diff --git a/arch/sparc/include/asm/timer_32.h b/arch/sparc/include/asm/timer_32.h index 1a91e11..72f40a5 100644 --- a/arch/sparc/include/asm/timer_32.h +++ b/arch/sparc/include/asm/timer_32.h
@@ -8,14 +8,37 @@ #ifndef _SPARC_TIMER_H #define _SPARC_TIMER_H +#include <linux/clocksource.h> +#include <linux/irqreturn.h> + +#include <asm-generic/percpu.h> + #include <asm/cpu_type.h> /* For SUN4M_NCPUS */ -#include <asm/btfixup.h> + +#define SBUS_CLOCK_RATE 2000000 /* 2MHz */ +#define TIMER_VALUE_SHIFT 9 +#define TIMER_VALUE_MASK 0x3fffff +#define TIMER_LIMIT_BIT (1 << 31) /* Bit 31 in Counter-Timer register */ + +/* The counter timer register has the value offset by 9 bits. + * From sun4m manual: + * When a counter reaches the value in the corresponding limit register, + * the Limit bit is set and the counter is set to 500 nS (i.e. 0x00000200). + * + * To compensate for this add one to the value. + */ +static inline unsigned int timer_value(unsigned int value) +{ + return (value + 1) << TIMER_VALUE_SHIFT; +} extern __volatile__ unsigned int *master_l10_counter; -/* FIXME: Make do_[gs]ettimeofday btfixup calls */ -struct timespec; -BTFIXUPDEF_CALL(int, bus_do_settimeofday, struct timespec *tv) -#define bus_do_settimeofday(tv) BTFIXUP_CALL(bus_do_settimeofday)(tv) +extern irqreturn_t notrace timer_interrupt(int dummy, void *dev_id); + +#ifdef CONFIG_SMP +DECLARE_PER_CPU(struct clock_event_device, sparc32_clockevent); +extern void register_percpu_ce(int cpu); +#endif #endif /* !(_SPARC_TIMER_H) */
diff --git a/arch/sparc/include/asm/timex_32.h b/arch/sparc/include/asm/timex_32.h index a254750..b6ccdb0 100644 --- a/arch/sparc/include/asm/timex_32.h +++ b/arch/sparc/include/asm/timex_32.h
@@ -12,5 +12,4 @@ typedef unsigned long cycles_t; #define get_cycles() (0) -extern u32 (*do_arch_gettimeoffset)(void); #endif
diff --git a/arch/sparc/include/asm/tlbflush_32.h b/arch/sparc/include/asm/tlbflush_32.h index fe0a71a..a5c4142 100644 --- a/arch/sparc/include/asm/tlbflush_32.h +++ b/arch/sparc/include/asm/tlbflush_32.h
@@ -1,52 +1,16 @@ #ifndef _SPARC_TLBFLUSH_H #define _SPARC_TLBFLUSH_H -#include <linux/mm.h> -// #include <asm/processor.h> +#include <asm/cachetlb_32.h> -/* - * TLB flushing: - * - * - flush_tlb() flushes the current mm struct TLBs XXX Exists? - * - flush_tlb_all() flushes all processes TLBs - * - flush_tlb_mm(mm) flushes the specified mm context TLB's - * - flush_tlb_page(vma, vmaddr) flushes one page - * - flush_tlb_range(vma, start, end) flushes a range of pages - * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages - */ - -#ifdef CONFIG_SMP - -BTFIXUPDEF_CALL(void, local_flush_tlb_all, void) -BTFIXUPDEF_CALL(void, local_flush_tlb_mm, struct mm_struct *) -BTFIXUPDEF_CALL(void, local_flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long) -BTFIXUPDEF_CALL(void, local_flush_tlb_page, struct vm_area_struct *, unsigned long) - -#define local_flush_tlb_all() BTFIXUP_CALL(local_flush_tlb_all)() -#define local_flush_tlb_mm(mm) BTFIXUP_CALL(local_flush_tlb_mm)(mm) -#define local_flush_tlb_range(vma,start,end) BTFIXUP_CALL(local_flush_tlb_range)(vma,start,end) -#define local_flush_tlb_page(vma,addr) BTFIXUP_CALL(local_flush_tlb_page)(vma,addr) - -extern void smp_flush_tlb_all(void); -extern void smp_flush_tlb_mm(struct mm_struct *mm); -extern void smp_flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, - unsigned long end); -extern void smp_flush_tlb_page(struct vm_area_struct *mm, unsigned long page); - -#endif /* CONFIG_SMP */ - -BTFIXUPDEF_CALL(void, flush_tlb_all, void) -BTFIXUPDEF_CALL(void, flush_tlb_mm, struct mm_struct *) -BTFIXUPDEF_CALL(void, flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long) -BTFIXUPDEF_CALL(void, flush_tlb_page, struct vm_area_struct *, unsigned long) - -#define flush_tlb_all() BTFIXUP_CALL(flush_tlb_all)() -#define flush_tlb_mm(mm) BTFIXUP_CALL(flush_tlb_mm)(mm) -#define flush_tlb_range(vma,start,end) BTFIXUP_CALL(flush_tlb_range)(vma,start,end) -#define flush_tlb_page(vma,addr) BTFIXUP_CALL(flush_tlb_page)(vma,addr) - -// #define flush_tlb() flush_tlb_mm(current->active_mm) /* XXX Sure? */ +#define flush_tlb_all() \ + sparc32_cachetlb_ops->tlb_all() +#define flush_tlb_mm(mm) \ + sparc32_cachetlb_ops->tlb_mm(mm) +#define flush_tlb_range(vma, start, end) \ + sparc32_cachetlb_ops->tlb_range(vma, start, end) +#define flush_tlb_page(vma, addr) \ + sparc32_cachetlb_ops->tlb_page(vma, addr) /* * This is a kludge, until I know better. --zaitcev XXX
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h index 8303ac4..d50c310 100644 --- a/arch/sparc/include/asm/uaccess_32.h +++ b/arch/sparc/include/asm/uaccess_32.h
@@ -12,7 +12,6 @@ #include <linux/sched.h> #include <linux/string.h> #include <linux/errno.h> -#include <asm/vac-ops.h> #endif #ifndef __ASSEMBLY__
diff --git a/arch/sparc/include/asm/vac-ops.h b/arch/sparc/include/asm/vac-ops.h deleted file mode 100644 index a63e88e..0000000 --- a/arch/sparc/include/asm/vac-ops.h +++ /dev/null
@@ -1,127 +0,0 @@ -#ifndef _SPARC_VAC_OPS_H -#define _SPARC_VAC_OPS_H - -/* vac-ops.h: Inline assembly routines to do operations on the Sparc - * VAC (virtual address cache) for the sun4c. - * - * Copyright (C) 1994, David S. Miller (davem@caip.rutgers.edu) - */ - -#include <asm/sysen.h> -#include <asm/contregs.h> -#include <asm/asi.h> - -/* The SUN4C models have a virtually addressed write-through - * cache. - * - * The cache tags are directly accessible through an ASI and - * each have the form: - * - * ------------------------------------------------------------ - * | MBZ | CONTEXT | WRITE | PRIV | VALID | MBZ | TagID | MBZ | - * ------------------------------------------------------------ - * 31 25 24 22 21 20 19 18 16 15 2 1 0 - * - * MBZ: These bits are either unused and/or reserved and should - * be written as zeroes. - * - * CONTEXT: Records the context to which this cache line belongs. - * - * WRITE: A copy of the writable bit from the mmu pte access bits. - * - * PRIV: A copy of the privileged bit from the pte access bits. - * - * VALID: If set, this line is valid, else invalid. - * - * TagID: Fourteen bits of tag ID. - * - * Every virtual address is seen by the cache like this: - * - * ---------------------------------------- - * | RESV | TagID | LINE | BYTE-in-LINE | - * ---------------------------------------- - * 31 30 29 16 15 4 3 0 - * - * RESV: Unused/reserved. - * - * TagID: Used to match the Tag-ID in that vac tags. - * - * LINE: Which line within the cache - * - * BYTE-in-LINE: Which byte within the cache line. - */ - -/* Sun4c VAC Tags */ -#define S4CVACTAG_CID 0x01c00000 -#define S4CVACTAG_W 0x00200000 -#define S4CVACTAG_P 0x00100000 -#define S4CVACTAG_V 0x00080000 -#define S4CVACTAG_TID 0x0000fffc - -/* Sun4c VAC Virtual Address */ -/* These aren't used, why bother? (Anton) */ -#if 0 -#define S4CVACVA_TID 0x3fff0000 -#define S4CVACVA_LINE 0x0000fff0 -#define S4CVACVA_BIL 0x0000000f -#endif - -/* The indexing of cache lines creates a problem. Because the line - * field of a virtual address extends past the page offset within - * the virtual address it is possible to have what are called - * 'bad aliases' which will create inconsistencies. So we must make - * sure that within a context that if a physical page is mapped - * more than once, that 'extra' line bits are the same. If this is - * not the case, and thus is a 'bad alias' we must turn off the - * cacheable bit in the pte's of all such pages. - */ - -#define S4CVAC_BADBITS 0x0000f000 - -/* The following is true if vaddr1 and vaddr2 would cause - * a 'bad alias'. - */ -#define S4CVAC_BADALIAS(vaddr1, vaddr2) \ - ((((unsigned long) (vaddr1)) ^ ((unsigned long) (vaddr2))) & \ - (S4CVAC_BADBITS)) - -/* The following structure describes the characteristics of a sun4c - * VAC as probed from the prom during boot time. - */ -struct sun4c_vac_props { - unsigned int num_bytes; /* Size of the cache */ - unsigned int do_hwflushes; /* Hardware flushing available? */ - unsigned int linesize; /* Size of each line in bytes */ - unsigned int log2lsize; /* log2(linesize) */ - unsigned int on; /* VAC is enabled */ -}; - -extern struct sun4c_vac_props sun4c_vacinfo; - -/* sun4c_enable_vac() enables the sun4c virtual address cache. */ -static inline void sun4c_enable_vac(void) -{ - __asm__ __volatile__("lduba [%0] %1, %%g1\n\t" - "or %%g1, %2, %%g1\n\t" - "stba %%g1, [%0] %1\n\t" - : /* no outputs */ - : "r" ((unsigned int) AC_SENABLE), - "i" (ASI_CONTROL), "i" (SENABLE_CACHE) - : "g1", "memory"); - sun4c_vacinfo.on = 1; -} - -/* sun4c_disable_vac() disables the virtual address cache. */ -static inline void sun4c_disable_vac(void) -{ - __asm__ __volatile__("lduba [%0] %1, %%g1\n\t" - "andn %%g1, %2, %%g1\n\t" - "stba %%g1, [%0] %1\n\t" - : /* no outputs */ - : "r" ((unsigned int) AC_SENABLE), - "i" (ASI_CONTROL), "i" (SENABLE_CACHE) - : "g1", "memory"); - sun4c_vacinfo.on = 0; -} - -#endif /* !(_SPARC_VAC_OPS_H) */
diff --git a/arch/sparc/include/asm/vaddrs.h b/arch/sparc/include/asm/vaddrs.h index 541e137..da6535d 100644 --- a/arch/sparc/include/asm/vaddrs.h +++ b/arch/sparc/include/asm/vaddrs.h
@@ -34,22 +34,6 @@ #define IOBASE_VADDR 0xfe000000 #define IOBASE_END 0xfe600000 -/* - * On the sun4/4c we need a place - * to reliably map locked down kernel data. This includes the - * task_struct and kernel stack pages of each process plus the - * scsi buffers during dvma IO transfers, also the floppy buffers - * during pseudo dma which runs with traps off (no faults allowed). - * Some quick calculations yield: - * NR_TASKS <512> * (3 * PAGE_SIZE) == 0x600000 - * Subtract this from 0xc00000 and you get 0x927C0 of vm left - * over to map SCSI dvma + floppy pseudo-dma buffers. So be - * careful if you change NR_TASKS or else there won't be enough - * room for it all. - */ -#define SUN4C_LOCK_VADDR 0xff000000 -#define SUN4C_LOCK_END 0xffc00000 - #define KADB_DEBUGGER_BEGVM 0xffc00000 /* Where kern debugger is in virt-mem */ #define KADB_DEBUGGER_ENDVM 0xffd00000 #define DEBUG_FIRSTVADDR KADB_DEBUGGER_BEGVM
diff --git a/arch/sparc/include/asm/winmacro.h b/arch/sparc/include/asm/winmacro.h index a9be04b..9b7b217 100644 --- a/arch/sparc/include/asm/winmacro.h +++ b/arch/sparc/include/asm/winmacro.h
@@ -103,37 +103,24 @@ st %scratch, [%cur_reg + TI_W_SAVED]; #ifdef CONFIG_SMP -/* Results of LOAD_CURRENT() after BTFIXUP for SUN4M, SUN4D & LEON (comments) */ -#define LOAD_CURRENT4M(dest_reg, idreg) \ - rd %tbr, %idreg; \ - sethi %hi(current_set), %dest_reg; \ - srl %idreg, 10, %idreg; \ - or %dest_reg, %lo(current_set), %dest_reg; \ - and %idreg, 0xc, %idreg; \ - ld [%idreg + %dest_reg], %dest_reg; - -#define LOAD_CURRENT4D(dest_reg, idreg) \ - lda [%g0] ASI_M_VIKING_TMP1, %idreg; \ - sethi %hi(C_LABEL(current_set)), %dest_reg; \ - sll %idreg, 2, %idreg; \ - or %dest_reg, %lo(C_LABEL(current_set)), %dest_reg; \ - ld [%idreg + %dest_reg], %dest_reg; - -#define LOAD_CURRENT_LEON(dest_reg, idreg) \ - rd %asr17, %idreg; \ - sethi %hi(current_set), %dest_reg; \ - srl %idreg, 0x1c, %idreg; \ - or %dest_reg, %lo(current_set), %dest_reg; \ - sll %idreg, 0x2, %idreg; \ - ld [%idreg + %dest_reg], %dest_reg; - -/* Blackbox - take care with this... - check smp4m and smp4d before changing this. */ -#define LOAD_CURRENT(dest_reg, idreg) \ - sethi %hi(___b_load_current), %idreg; \ - sethi %hi(current_set), %dest_reg; \ - sethi %hi(boot_cpu_id4), %idreg; \ - or %dest_reg, %lo(current_set), %dest_reg; \ - ldub [%idreg + %lo(boot_cpu_id4)], %idreg; \ +#define LOAD_CURRENT(dest_reg, idreg) \ +661: rd %tbr, %idreg; \ + srl %idreg, 10, %idreg; \ + and %idreg, 0xc, %idreg; \ + .section .cpuid_patch, "ax"; \ + /* Instruction location. */ \ + .word 661b; \ + /* SUN4D implementation. */ \ + lda [%g0] ASI_M_VIKING_TMP1, %idreg; \ + sll %idreg, 2, %idreg; \ + nop; \ + /* LEON implementation. */ \ + rd %asr17, %idreg; \ + srl %idreg, 0x1c, %idreg; \ + sll %idreg, 0x02, %idreg; \ + .previous; \ + sethi %hi(current_set), %dest_reg; \ + or %dest_reg, %lo(current_set), %dest_reg;\ ld [%idreg + %dest_reg], %dest_reg; #else #define LOAD_CURRENT(dest_reg, idreg) \
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index cb85458..c19dd02 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile
@@ -28,7 +28,7 @@ # IRQ obj-y += irq_$(BITS).o -obj-$(CONFIG_SPARC32) += sun4m_irq.o sun4c_irq.o sun4d_irq.o +obj-$(CONFIG_SPARC32) += sun4m_irq.o sun4d_irq.o obj-y += process_$(BITS).o obj-y += signal_$(BITS).o @@ -46,7 +46,6 @@ obj-y += ptrace_$(BITS).o obj-y += unaligned_$(BITS).o obj-y += una_asm_$(BITS).o -obj-$(CONFIG_SPARC32) += muldiv.o obj-y += prom_common.o obj-y += prom_$(BITS).o obj-y += of_device_common.o
diff --git a/arch/sparc/kernel/auxio_32.c b/arch/sparc/kernel/auxio_32.c index 56d0f52..e20cc55 100644 --- a/arch/sparc/kernel/auxio_32.c +++ b/arch/sparc/kernel/auxio_32.c
@@ -32,7 +32,6 @@ switch (sparc_cpu_model) { case sparc_leon: case sun4d: - case sun4: return; default: break; @@ -65,9 +64,8 @@ r.start = auxregs[0].phys_addr; r.end = auxregs[0].phys_addr + auxregs[0].reg_size - 1; auxio_register = of_ioremap(&r, 0, auxregs[0].reg_size, "auxio"); - /* Fix the address on sun4m and sun4c. */ - if((((unsigned long) auxregs[0].phys_addr) & 3) == 3 || - sparc_cpu_model == sun4c) + /* Fix the address on sun4m. */ + if ((((unsigned long) auxregs[0].phys_addr) & 3) == 3) auxio_register += (3 - ((unsigned long)auxio_register & 3)); set_auxio(AUXIO_LED, 0); @@ -86,12 +84,7 @@ unsigned char regval; unsigned long flags; spin_lock_irqsave(&auxio_lock, flags); - switch(sparc_cpu_model) { - case sun4c: - regval = sbus_readb(auxio_register); - sbus_writeb(((regval | bits_on) & ~bits_off) | AUXIO_ORMEIN, - auxio_register); - break; + switch (sparc_cpu_model) { case sun4m: if(!auxio_register) break; /* VME chassis sun4m, no auxio. */
diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index 38d48a5..9708851 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c
@@ -269,4 +269,4 @@ return 0; } -subsys_initcall(sunfire_init); +fs_initcall(sunfire_init);
diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c index 6b2f56a..3d465e8 100644 --- a/arch/sparc/kernel/devices.c +++ b/arch/sparc/kernel/devices.c
@@ -21,7 +21,6 @@ #include <asm/cpu_type.h> extern void clock_stop_probe(void); /* tadpole.c */ -extern void sun4c_probe_memerr_reg(void); static char *cpu_mid_prop(void) { @@ -139,7 +138,4 @@ auxio_power_probe(); } clock_stop_probe(); - - if (ARCH_SUN4C) - sun4c_probe_memerr_reg(); }
diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index b93c2c9..f09257c 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c
@@ -868,7 +868,7 @@ static void ds_conn_reset(struct ds_info *dp) { - printk(KERN_ERR "ds-%llu: ds_conn_reset() from %p\n", + printk(KERN_ERR "ds-%llu: ds_conn_reset() from %pf\n", dp->id, __builtin_return_address(0)); }
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index f445e98..2dbe180 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S
@@ -7,6 +7,7 @@ * Copyright (C) 1997 Anton Blanchard (anton@progsoc.uts.edu.au) */ +#include <linux/linkage.h> #include <linux/errno.h> #include <asm/head.h> @@ -17,10 +18,8 @@ #include <asm/asm-offsets.h> #include <asm/psr.h> #include <asm/vaddrs.h> -#include <asm/memreg.h> #include <asm/page.h> #include <asm/pgtable.h> -#include <asm/pgtsun4c.h> #include <asm/winmacro.h> #include <asm/signal.h> #include <asm/obio.h> @@ -125,22 +124,11 @@ set auxio_register, %l7 ld [%l7], %l7 - set sparc_cpu_model, %l5 - ld [%l5], %l5 - subcc %l5, 1, %g0 /* enum { sun4c = 1 }; */ - be 1f - ldub [%l7], %l5 + ldub [%l7], %l5 or %l5, 0xc2, %l5 stb %l5, [%l7] andn %l5, 0x02, %l5 - b 2f - nop - -1: - or %l5, 0xf4, %l5 - stb %l5, [%l7] - andn %l5, 0x04, %l5 2: /* Kill some time so the bits set */ @@ -266,6 +254,11 @@ WRITE_PAUSE RESTORE_ALL +#define GET_PROCESSOR4M_ID(reg) \ + rd %tbr, %reg; \ + srl %reg, 12, %reg; \ + and %reg, 3, %reg; + /* Here is where we check for possible SMP IPI passed to us * on some level other than 15 which is the NMI and only used * for cross calls. That has a separate entry point below. @@ -328,7 +321,7 @@ ld [%o5 + %o0], %o5 ld [%o5 + 0x00], %o3 ! sun4m_irq_percpu[cpu]->pending andcc %o3, %o2, %g0 - be 1f ! Must be an NMI async memory error + be sun4m_nmi_error ! Must be an NMI async memory error st %o2, [%o5 + 0x04] ! sun4m_irq_percpu[cpu]->clear=0x80000000 WRITE_PAUSE ld [%o5 + 0x00], %g0 ! sun4m_irq_percpu[cpu]->pending @@ -342,27 +335,6 @@ nop b ret_trap_lockless_ipi clr %l6 -1: - /* NMI async memory error handling. */ - sethi %hi(0x80000000), %l4 - sethi %hi(sun4m_irq_global), %o5 - ld [%o5 + %lo(sun4m_irq_global)], %l5 - st %l4, [%l5 + 0x0c] ! sun4m_irq_global->mask_set=0x80000000 - WRITE_PAUSE - ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending - WRITE_PAUSE - or %l0, PSR_PIL, %l4 - wr %l4, 0x0, %psr - WRITE_PAUSE - wr %l4, PSR_ET, %psr - WRITE_PAUSE - call sun4m_nmi - nop - st %l4, [%l5 + 0x08] ! sun4m_irq_global->mask_clear=0x80000000 - WRITE_PAUSE - ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending - WRITE_PAUSE - RESTORE_ALL .globl smp4d_ticker /* SMP per-cpu ticker interrupts are handled specially. */ @@ -760,327 +732,38 @@ jmp %l2 ! advance over trap instruction rett %l2 + 0x4 ! like this... - .align 4 - .globl linux_trap_nmi_sun4c -linux_trap_nmi_sun4c: - SAVE_ALL - - /* Ugh, we need to clear the IRQ line. This is now - * a very sun4c specific trap handler... - */ - sethi %hi(interrupt_enable), %l5 - ld [%l5 + %lo(interrupt_enable)], %l5 - ldub [%l5], %l6 - andn %l6, INTS_ENAB, %l6 - stb %l6, [%l5] - - /* Now it is safe to re-enable traps without recursion. */ - or %l0, PSR_PIL, %l0 - wr %l0, PSR_ET, %psr +sun4m_nmi_error: + /* NMI async memory error handling. */ + sethi %hi(0x80000000), %l4 + sethi %hi(sun4m_irq_global), %o5 + ld [%o5 + %lo(sun4m_irq_global)], %l5 + st %l4, [%l5 + 0x0c] ! sun4m_irq_global->mask_set=0x80000000 WRITE_PAUSE - - /* Now call the c-code with the pt_regs frame ptr and the - * memory error registers as arguments. The ordering chosen - * here is due to unlatching semantics. - */ - sethi %hi(AC_SYNC_ERR), %o0 - add %o0, 0x4, %o0 - lda [%o0] ASI_CONTROL, %o2 ! sync vaddr - sub %o0, 0x4, %o0 - lda [%o0] ASI_CONTROL, %o1 ! sync error - add %o0, 0xc, %o0 - lda [%o0] ASI_CONTROL, %o4 ! async vaddr - sub %o0, 0x4, %o0 - lda [%o0] ASI_CONTROL, %o3 ! async error - call sparc_lvl15_nmi - add %sp, STACKFRAME_SZ, %o0 - - RESTORE_ALL - - .align 4 - .globl invalid_segment_patch1_ff - .globl invalid_segment_patch2_ff -invalid_segment_patch1_ff: cmp %l4, 0xff -invalid_segment_patch2_ff: mov 0xff, %l3 - - .align 4 - .globl invalid_segment_patch1_1ff - .globl invalid_segment_patch2_1ff -invalid_segment_patch1_1ff: cmp %l4, 0x1ff -invalid_segment_patch2_1ff: mov 0x1ff, %l3 - - .align 4 - .globl num_context_patch1_16, num_context_patch2_16 -num_context_patch1_16: mov 0x10, %l7 -num_context_patch2_16: mov 0x10, %l7 - - .align 4 - .globl vac_linesize_patch_32 -vac_linesize_patch_32: subcc %l7, 32, %l7 - - .align 4 - .globl vac_hwflush_patch1_on, vac_hwflush_patch2_on - -/* - * Ugly, but we can't use hardware flushing on the sun4 and we'd require - * two instructions (Anton) - */ -vac_hwflush_patch1_on: addcc %l7, -PAGE_SIZE, %l7 - -vac_hwflush_patch2_on: sta %g0, [%l3 + %l7] ASI_HWFLUSHSEG - - .globl invalid_segment_patch1, invalid_segment_patch2 - .globl num_context_patch1 - .globl vac_linesize_patch, vac_hwflush_patch1 - .globl vac_hwflush_patch2 - - .align 4 - .globl sun4c_fault - -! %l0 = %psr -! %l1 = %pc -! %l2 = %npc -! %l3 = %wim -! %l7 = 1 for textfault -! We want error in %l5, vaddr in %l6 -sun4c_fault: - sethi %hi(AC_SYNC_ERR), %l4 - add %l4, 0x4, %l6 ! AC_SYNC_VA in %l6 - lda [%l6] ASI_CONTROL, %l5 ! Address - lda [%l4] ASI_CONTROL, %l6 ! Error, retained for a bit - - andn %l5, 0xfff, %l5 ! Encode all info into l7 - srl %l6, 14, %l4 - - and %l4, 2, %l4 - or %l5, %l4, %l4 - - or %l4, %l7, %l7 ! l7 = [addr,write,txtfault] - - andcc %l0, PSR_PS, %g0 - be sun4c_fault_fromuser - andcc %l7, 1, %g0 ! Text fault? - - be 1f - sethi %hi(KERNBASE), %l4 - - mov %l1, %l5 ! PC - -1: - cmp %l5, %l4 - blu sun4c_fault_fromuser - sethi %hi(~((1 << SUN4C_REAL_PGDIR_SHIFT) - 1)), %l4 - - /* If the kernel references a bum kernel pointer, or a pte which - * points to a non existent page in ram, we will run this code - * _forever_ and lock up the machine!!!!! So we must check for - * this condition, the AC_SYNC_ERR bits are what we must examine. - * Also a parity error would make this happen as well. So we just - * check that we are in fact servicing a tlb miss and not some - * other type of fault for the kernel. - */ - andcc %l6, 0x80, %g0 - be sun4c_fault_fromuser - and %l5, %l4, %l5 - - /* Test for NULL pte_t * in vmalloc area. */ - sethi %hi(VMALLOC_START), %l4 - cmp %l5, %l4 - blu,a invalid_segment_patch1 - lduXa [%l5] ASI_SEGMAP, %l4 - - sethi %hi(swapper_pg_dir), %l4 - srl %l5, SUN4C_PGDIR_SHIFT, %l6 - or %l4, %lo(swapper_pg_dir), %l4 - sll %l6, 2, %l6 - ld [%l4 + %l6], %l4 - andcc %l4, PAGE_MASK, %g0 - be sun4c_fault_fromuser - lduXa [%l5] ASI_SEGMAP, %l4 - -invalid_segment_patch1: - cmp %l4, 0x7f - bne 1f - sethi %hi(sun4c_kfree_ring), %l4 - or %l4, %lo(sun4c_kfree_ring), %l4 - ld [%l4 + 0x18], %l3 - deccc %l3 ! do we have a free entry? - bcs,a 2f ! no, unmap one. - sethi %hi(sun4c_kernel_ring), %l4 - - st %l3, [%l4 + 0x18] ! sun4c_kfree_ring.num_entries-- - - ld [%l4 + 0x00], %l6 ! entry = sun4c_kfree_ring.ringhd.next - st %l5, [%l6 + 0x08] ! entry->vaddr = address - - ld [%l6 + 0x00], %l3 ! next = entry->next - ld [%l6 + 0x04], %l7 ! entry->prev - - st %l7, [%l3 + 0x04] ! next->prev = entry->prev - st %l3, [%l7 + 0x00] ! entry->prev->next = next - - sethi %hi(sun4c_kernel_ring), %l4 - or %l4, %lo(sun4c_kernel_ring), %l4 - ! head = &sun4c_kernel_ring.ringhd - - ld [%l4 + 0x00], %l7 ! head->next - - st %l4, [%l6 + 0x04] ! entry->prev = head - st %l7, [%l6 + 0x00] ! entry->next = head->next - st %l6, [%l7 + 0x04] ! head->next->prev = entry - - st %l6, [%l4 + 0x00] ! head->next = entry - - ld [%l4 + 0x18], %l3 - inc %l3 ! sun4c_kernel_ring.num_entries++ - st %l3, [%l4 + 0x18] - b 4f - ld [%l6 + 0x08], %l5 - -2: - or %l4, %lo(sun4c_kernel_ring), %l4 - ! head = &sun4c_kernel_ring.ringhd - - ld [%l4 + 0x04], %l6 ! entry = head->prev - - ld [%l6 + 0x08], %l3 ! tmp = entry->vaddr - - ! Flush segment from the cache. - sethi %hi((64 * 1024)), %l7 -9: -vac_hwflush_patch1: -vac_linesize_patch: - subcc %l7, 16, %l7 - bne 9b -vac_hwflush_patch2: - sta %g0, [%l3 + %l7] ASI_FLUSHSEG - - st %l5, [%l6 + 0x08] ! entry->vaddr = address - - ld [%l6 + 0x00], %l5 ! next = entry->next - ld [%l6 + 0x04], %l7 ! entry->prev - - st %l7, [%l5 + 0x04] ! next->prev = entry->prev - st %l5, [%l7 + 0x00] ! entry->prev->next = next - st %l4, [%l6 + 0x04] ! entry->prev = head - - ld [%l4 + 0x00], %l7 ! head->next - - st %l7, [%l6 + 0x00] ! entry->next = head->next - st %l6, [%l7 + 0x04] ! head->next->prev = entry - st %l6, [%l4 + 0x00] ! head->next = entry - - mov %l3, %l5 ! address = tmp - -4: -num_context_patch1: - mov 0x08, %l7 - - ld [%l6 + 0x08], %l4 - ldub [%l6 + 0x0c], %l3 - or %l4, %l3, %l4 ! encode new vaddr/pseg into l4 - - sethi %hi(AC_CONTEXT), %l3 - lduba [%l3] ASI_CONTROL, %l6 - - /* Invalidate old mapping, instantiate new mapping, - * for each context. Registers l6/l7 are live across - * this loop. - */ -3: deccc %l7 - sethi %hi(AC_CONTEXT), %l3 - stba %l7, [%l3] ASI_CONTROL -invalid_segment_patch2: - mov 0x7f, %l3 - stXa %l3, [%l5] ASI_SEGMAP - andn %l4, 0x1ff, %l3 - bne 3b - stXa %l4, [%l3] ASI_SEGMAP - - sethi %hi(AC_CONTEXT), %l3 - stba %l6, [%l3] ASI_CONTROL - - andn %l4, 0x1ff, %l5 - -1: - sethi %hi(VMALLOC_START), %l4 - cmp %l5, %l4 - - bgeu 1f - mov 1 << (SUN4C_REAL_PGDIR_SHIFT - PAGE_SHIFT), %l7 - - sethi %hi(KERNBASE), %l6 - - sub %l5, %l6, %l4 - srl %l4, PAGE_SHIFT, %l4 - sethi %hi((SUN4C_PAGE_KERNEL & 0xf4000000)), %l3 - or %l3, %l4, %l3 - - sethi %hi(PAGE_SIZE), %l4 - -2: - sta %l3, [%l5] ASI_PTE - deccc %l7 - inc %l3 - bne 2b - add %l5, %l4, %l5 - - b 7f - sethi %hi(sun4c_kernel_faults), %l4 - -1: - srl %l5, SUN4C_PGDIR_SHIFT, %l3 - sethi %hi(swapper_pg_dir), %l4 - or %l4, %lo(swapper_pg_dir), %l4 - sll %l3, 2, %l3 - ld [%l4 + %l3], %l4 - and %l4, PAGE_MASK, %l4 - - srl %l5, (PAGE_SHIFT - 2), %l6 - and %l6, ((SUN4C_PTRS_PER_PTE - 1) << 2), %l6 - add %l6, %l4, %l6 - - sethi %hi(PAGE_SIZE), %l4 - -2: - ld [%l6], %l3 - deccc %l7 - sta %l3, [%l5] ASI_PTE - add %l6, 0x4, %l6 - bne 2b - add %l5, %l4, %l5 - - sethi %hi(sun4c_kernel_faults), %l4 -7: - ld [%l4 + %lo(sun4c_kernel_faults)], %l3 - inc %l3 - st %l3, [%l4 + %lo(sun4c_kernel_faults)] - - /* Restore condition codes */ - wr %l0, 0x0, %psr + ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending WRITE_PAUSE - jmp %l1 - rett %l2 - -sun4c_fault_fromuser: - SAVE_ALL + or %l0, PSR_PIL, %l4 + wr %l4, 0x0, %psr + WRITE_PAUSE + wr %l4, PSR_ET, %psr + WRITE_PAUSE + call sun4m_nmi nop - - mov %l7, %o1 ! Decode the info from %l7 - mov %l7, %o2 - and %o1, 1, %o1 ! arg2 = text_faultp - mov %l7, %o3 - and %o2, 2, %o2 ! arg3 = writep - andn %o3, 0xfff, %o3 ! arg4 = faulting address - - wr %l0, PSR_ET, %psr + st %l4, [%l5 + 0x08] ! sun4m_irq_global->mask_clear=0x80000000 WRITE_PAUSE - - call do_sun4c_fault - add %sp, STACKFRAME_SZ, %o0 ! arg1 = pt_regs ptr - + ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending + WRITE_PAUSE RESTORE_ALL +#ifndef CONFIG_SMP + .align 4 + .globl linux_trap_ipi15_sun4m +linux_trap_ipi15_sun4m: + SAVE_ALL + + ba sun4m_nmi_error + nop +#endif /* CONFIG_SMP */ + .align 4 .globl srmmu_fault srmmu_fault: @@ -1483,11 +1166,13 @@ .globl __ndelay __ndelay: save %sp, -STACKFRAME_SZ, %sp - mov %i0, %o0 - call .umul ! round multiplier up so large ns ok - mov 0x1ae, %o1 ! 2**32 / (1 000 000 000 / HZ) - call .umul - mov %i1, %o1 ! udelay_val + mov %i0, %o0 ! round multiplier up so large ns ok + mov 0x1ae, %o1 ! 2**32 / (1 000 000 000 / HZ) + umul %o0, %o1, %o0 + rd %y, %o1 + mov %i1, %o1 ! udelay_val + umul %o0, %o1, %o0 + rd %y, %o1 ba delay_continue mov %o1, %o0 ! >>32 later for better resolution @@ -1496,18 +1181,21 @@ save %sp, -STACKFRAME_SZ, %sp mov %i0, %o0 sethi %hi(0x10c7), %o1 ! round multiplier up so large us ok - call .umul - or %o1, %lo(0x10c7), %o1 ! 2**32 / 1 000 000 - call .umul - mov %i1, %o1 ! udelay_val + or %o1, %lo(0x10c7), %o1 ! 2**32 / 1 000 000 + umul %o0, %o1, %o0 + rd %y, %o1 + mov %i1, %o1 ! udelay_val + umul %o0, %o1, %o0 + rd %y, %o1 sethi %hi(0x028f4b62), %l0 ! Add in rounding constant * 2**32, or %g0, %lo(0x028f4b62), %l0 addcc %o0, %l0, %o0 ! 2**32 * 0.009 999 bcs,a 3f add %o1, 0x01, %o1 3: - call .umul - mov HZ, %o0 ! >>32 earlier for wider range + mov HZ, %o0 ! >>32 earlier for wider range + umul %o0, %o1, %o0 + rd %y, %o1 delay_continue: cmp %o0, 0x0 @@ -1670,4 +1358,26 @@ ret restore +#ifdef CONFIG_SMP +ENTRY(hard_smp_processor_id) +661: rd %tbr, %g1 + srl %g1, 12, %o0 + and %o0, 3, %o0 + .section .cpuid_patch, "ax" + /* Instruction location. */ + .word 661b + /* SUN4D implementation. */ + lda [%g0] ASI_M_VIKING_TMP1, %o0 + nop + nop + /* LEON implementation. */ + rd %asr17, %o0 + srl %o0, 0x1c, %o0 + nop + .previous + retl + nop +ENDPROC(hard_smp_processor_id) +#endif + /* End of entry.S */
diff --git a/arch/sparc/kernel/etrap_32.S b/arch/sparc/kernel/etrap_32.S index e806fcd..84b5f0d 100644 --- a/arch/sparc/kernel/etrap_32.S +++ b/arch/sparc/kernel/etrap_32.S
@@ -216,9 +216,7 @@ /* Call MMU-architecture dependent stack checking * routine. */ - .globl tsetup_mmu_patchme -tsetup_mmu_patchme: - b tsetup_sun4c_stackchk + b tsetup_srmmu_stackchk andcc %sp, 0x7, %g0 /* Architecture specific stack checking routines. When either @@ -228,52 +226,6 @@ */ #define glob_tmp g1 -tsetup_sun4c_stackchk: - /* Done by caller: andcc %sp, 0x7, %g0 */ - bne trap_setup_user_stack_is_bolixed - sra %sp, 29, %glob_tmp - - add %glob_tmp, 0x1, %glob_tmp - andncc %glob_tmp, 0x1, %g0 - bne trap_setup_user_stack_is_bolixed - and %sp, 0xfff, %glob_tmp ! delay slot - - /* See if our dump area will be on more than one - * page. - */ - add %glob_tmp, 0x38, %glob_tmp - andncc %glob_tmp, 0xff8, %g0 - be tsetup_sun4c_onepage ! only one page to check - lda [%sp] ASI_PTE, %glob_tmp ! have to check first page anyways - -tsetup_sun4c_twopages: - /* Is first page ok permission wise? */ - srl %glob_tmp, 29, %glob_tmp - cmp %glob_tmp, 0x6 - bne trap_setup_user_stack_is_bolixed - add %sp, 0x38, %glob_tmp /* Is second page in vma hole? */ - - sra %glob_tmp, 29, %glob_tmp - add %glob_tmp, 0x1, %glob_tmp - andncc %glob_tmp, 0x1, %g0 - bne trap_setup_user_stack_is_bolixed - add %sp, 0x38, %glob_tmp - - lda [%glob_tmp] ASI_PTE, %glob_tmp - -tsetup_sun4c_onepage: - srl %glob_tmp, 29, %glob_tmp - cmp %glob_tmp, 0x6 ! can user write to it? - bne trap_setup_user_stack_is_bolixed ! failure - nop - - STORE_WINDOW(sp) - - restore %g0, %g0, %g0 - - jmpl %t_retpc + 0x8, %g0 - mov %t_kstack, %sp - .globl tsetup_srmmu_stackchk tsetup_srmmu_stackchk: /* Check results of callers andcc %sp, 0x7, %g0 */
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S index 5877857..a0f5c20 100644 --- a/arch/sparc/kernel/head_32.S +++ b/arch/sparc/kernel/head_32.S
@@ -26,11 +26,9 @@ #include <asm/pgtsrmmu.h> /* SRMMU_PGDIR_SHIFT */ .data -/* - * The following are used with the prom_vector node-ops to figure out - * the cpu-type +/* The following are used with the prom_vector node-ops to figure out + * the cpu-type */ - .align 4 cputyp: .word 1 @@ -38,384 +36,35 @@ .align 4 .globl cputypval cputypval: - .asciz "sun4c" + .asciz "sun4m" .ascii " " -cputypvalend: -cputypvallen = cputypvar - cputypval - +/* Tested on SS-5, SS-10 */ .align 4 -/* - * Sun people can't spell worth damn. "compatability" indeed. - * At least we *know* we can't spell, and use a spell-checker. - */ - -/* Uh, actually Linus it is I who cannot spell. Too much murky - * Sparc assembly will do this to ya. - */ cputypvar: - .asciz "compatability" - -/* Tested on SS-5, SS-10. Probably someone at Sun applied a spell-checker. */ - .align 4 -cputypvar_sun4m: .asciz "compatible" .align 4 -sun4_notsup: - .asciz "Sparc-Linux sun4 support does no longer exist.\n\n" +sun4c_notsup: + .asciz "Sparc-Linux sun4/sun4c support does no longer exist.\n\n" .align 4 sun4e_notsup: .asciz "Sparc-Linux sun4e support does not exist\n\n" .align 4 - /* The Sparc trap table, bootloader gives us control at _start. */ - __HEAD - .globl _stext, _start, __stext - .globl trapbase -_start: /* danger danger */ -__stext: -_stext: -trapbase: -#ifdef CONFIG_SMP -trapbase_cpu0: -#endif -/* We get control passed to us here at t_zero. */ -t_zero: b gokernel; nop; nop; nop; -t_tflt: SPARC_TFAULT /* Inst. Access Exception */ -t_bins: TRAP_ENTRY(0x2, bad_instruction) /* Illegal Instruction */ -t_pins: TRAP_ENTRY(0x3, priv_instruction) /* Privileged Instruction */ -t_fpd: TRAP_ENTRY(0x4, fpd_trap_handler) /* Floating Point Disabled */ -t_wovf: WINDOW_SPILL /* Window Overflow */ -t_wunf: WINDOW_FILL /* Window Underflow */ -t_mna: TRAP_ENTRY(0x7, mna_handler) /* Memory Address Not Aligned */ -t_fpe: TRAP_ENTRY(0x8, fpe_trap_handler) /* Floating Point Exception */ -t_dflt: SPARC_DFAULT /* Data Miss Exception */ -t_tio: TRAP_ENTRY(0xa, do_tag_overflow) /* Tagged Instruction Ovrflw */ -t_wpt: TRAP_ENTRY(0xb, do_watchpoint) /* Watchpoint Detected */ -t_badc: BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) -t_irq1: TRAP_ENTRY_INTERRUPT(1) /* IRQ Software/SBUS Level 1 */ -t_irq2: TRAP_ENTRY_INTERRUPT(2) /* IRQ SBUS Level 2 */ -t_irq3: TRAP_ENTRY_INTERRUPT(3) /* IRQ SCSI/DMA/SBUS Level 3 */ -t_irq4: TRAP_ENTRY_INTERRUPT(4) /* IRQ Software Level 4 */ -t_irq5: TRAP_ENTRY_INTERRUPT(5) /* IRQ SBUS/Ethernet Level 5 */ -t_irq6: TRAP_ENTRY_INTERRUPT(6) /* IRQ Software Level 6 */ -t_irq7: TRAP_ENTRY_INTERRUPT(7) /* IRQ Video/SBUS Level 5 */ -t_irq8: TRAP_ENTRY_INTERRUPT(8) /* IRQ SBUS Level 6 */ -t_irq9: TRAP_ENTRY_INTERRUPT(9) /* IRQ SBUS Level 7 */ -t_irq10:TRAP_ENTRY_INTERRUPT(10) /* IRQ Timer #1 (one we use) */ -t_irq11:TRAP_ENTRY_INTERRUPT(11) /* IRQ Floppy Intr. */ -t_irq12:TRAP_ENTRY_INTERRUPT(12) /* IRQ Zilog serial chip */ -t_irq13:TRAP_ENTRY_INTERRUPT(13) /* IRQ Audio Intr. */ -t_irq14:TRAP_ENTRY_INTERRUPT(14) /* IRQ Timer #2 */ - .globl t_nmi -#ifndef CONFIG_SMP -t_nmi: NMI_TRAP /* Level 15 (NMI) */ -#else -t_nmi: TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) -#endif -t_racc: TRAP_ENTRY(0x20, do_reg_access) /* General Register Access Error */ -t_iacce:BAD_TRAP(0x21) /* Instr Access Error */ -t_bad22:BAD_TRAP(0x22) BAD_TRAP(0x23) -t_cpdis:TRAP_ENTRY(0x24, do_cp_disabled) /* Co-Processor Disabled */ -t_uflsh:SKIP_TRAP(0x25, unimp_flush) /* Unimplemented FLUSH inst. */ -t_bad26:BAD_TRAP(0x26) BAD_TRAP(0x27) -t_cpexc:TRAP_ENTRY(0x28, do_cp_exception) /* Co-Processor Exception */ -t_dacce:SPARC_DFAULT /* Data Access Error */ -t_hwdz: TRAP_ENTRY(0x2a, do_hw_divzero) /* Division by zero, you lose... */ -t_dserr:BAD_TRAP(0x2b) /* Data Store Error */ -t_daccm:BAD_TRAP(0x2c) /* Data Access MMU-Miss */ -t_bad2d:BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) -t_bad32:BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) -t_bad37:BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) -t_iaccm:BAD_TRAP(0x3c) /* Instr Access MMU-Miss */ -t_bad3d:BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) BAD_TRAP(0x41) -t_bad42:BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) BAD_TRAP(0x46) -t_bad47:BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) BAD_TRAP(0x4b) -t_bad4c:BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) BAD_TRAP(0x50) -t_bad51:BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) -t_bad56:BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) -t_bad5b:BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) -t_bad60:BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) -t_bad65:BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) -t_bad6a:BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) -t_bad6f:BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) -t_bad74:BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) -t_bad79:BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) -t_bad7e:BAD_TRAP(0x7e) BAD_TRAP(0x7f) -t_bad80:BAD_TRAP(0x80) /* SunOS System Call */ -t_sbkpt:BREAKPOINT_TRAP /* Software Breakpoint/KGDB */ -t_divz: TRAP_ENTRY(0x82, do_hw_divzero) /* Divide by zero trap */ -t_flwin:TRAP_ENTRY(0x83, do_flush_windows) /* Flush Windows Trap */ -t_clwin:BAD_TRAP(0x84) /* Clean Windows Trap */ -t_rchk: BAD_TRAP(0x85) /* Range Check */ -t_funal:BAD_TRAP(0x86) /* Fix Unaligned Access Trap */ -t_iovf: BAD_TRAP(0x87) /* Integer Overflow Trap */ -t_bad88:BAD_TRAP(0x88) /* Slowaris System Call */ -t_bad89:BAD_TRAP(0x89) /* Net-B.S. System Call */ -t_bad8a:BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) BAD_TRAP(0x8d) BAD_TRAP(0x8e) -t_bad8f:BAD_TRAP(0x8f) -t_linux:LINUX_SYSCALL_TRAP /* Linux System Call */ -t_bad91:BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) BAD_TRAP(0x95) -t_bad96:BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) BAD_TRAP(0x9a) -t_bad9b:BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) BAD_TRAP(0x9f) -t_getcc:GETCC_TRAP /* Get Condition Codes */ -t_setcc:SETCC_TRAP /* Set Condition Codes */ -t_getpsr:GETPSR_TRAP /* Get PSR Register */ -t_bada3:BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) -t_bada7:BAD_TRAP(0xa7) -t_bada8:BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) -t_badac:BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) -t_badb1:BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) -t_badb6:BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) -t_badbb:BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) -t_badc0:BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) -t_badc5:BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) -t_badca:BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) -t_badcf:BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) -t_badd4:BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) -t_badd9:BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) -t_badde:BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) -t_bade3:BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) -t_bade8:BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) -t_baded:BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) -t_badf2:BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) -t_badf7:BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) -t_badfc:BAD_TRAP(0xfc) -t_kgdb: KGDB_TRAP(0xfd) -dbtrap: BAD_TRAP(0xfe) /* Debugger/PROM breakpoint #1 */ -dbtrap2:BAD_TRAP(0xff) /* Debugger/PROM breakpoint #2 */ +/* The trap-table - located in the __HEAD section */ +#include "ttable_32.S" - .globl end_traptable -end_traptable: - -#ifdef CONFIG_SMP - /* Trap tables for the other cpus. */ - .globl trapbase_cpu1, trapbase_cpu2, trapbase_cpu3 -trapbase_cpu1: - BAD_TRAP(0x0) SRMMU_TFAULT TRAP_ENTRY(0x2, bad_instruction) - TRAP_ENTRY(0x3, priv_instruction) TRAP_ENTRY(0x4, fpd_trap_handler) - WINDOW_SPILL WINDOW_FILL TRAP_ENTRY(0x7, mna_handler) - TRAP_ENTRY(0x8, fpe_trap_handler) SRMMU_DFAULT - TRAP_ENTRY(0xa, do_tag_overflow) TRAP_ENTRY(0xb, do_watchpoint) - BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) - TRAP_ENTRY_INTERRUPT(1) TRAP_ENTRY_INTERRUPT(2) - TRAP_ENTRY_INTERRUPT(3) TRAP_ENTRY_INTERRUPT(4) - TRAP_ENTRY_INTERRUPT(5) TRAP_ENTRY_INTERRUPT(6) - TRAP_ENTRY_INTERRUPT(7) TRAP_ENTRY_INTERRUPT(8) - TRAP_ENTRY_INTERRUPT(9) TRAP_ENTRY_INTERRUPT(10) - TRAP_ENTRY_INTERRUPT(11) TRAP_ENTRY_INTERRUPT(12) - TRAP_ENTRY_INTERRUPT(13) TRAP_ENTRY_INTERRUPT(14) - TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) - TRAP_ENTRY(0x20, do_reg_access) BAD_TRAP(0x21) BAD_TRAP(0x22) - BAD_TRAP(0x23) TRAP_ENTRY(0x24, do_cp_disabled) SKIP_TRAP(0x25, unimp_flush) - BAD_TRAP(0x26) BAD_TRAP(0x27) TRAP_ENTRY(0x28, do_cp_exception) - SRMMU_DFAULT TRAP_ENTRY(0x2a, do_hw_divzero) BAD_TRAP(0x2b) BAD_TRAP(0x2c) - BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) - BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) - BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) - BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) - BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) - BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) - BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) - BAD_TRAP(0x50) - BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) - BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) - BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) - BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) - BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) - BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) - BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) - BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) - BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) - BAD_TRAP(0x7e) BAD_TRAP(0x7f) - BAD_TRAP(0x80) - BREAKPOINT_TRAP - TRAP_ENTRY(0x82, do_hw_divzero) - TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85) - BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88) - BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) - BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) - LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) - BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) - BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) - BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP - BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) - BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) - BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) - BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) - BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) - BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) - BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) - BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) - BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) - BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) - BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) - BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) - BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) - BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) - BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) - BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) - BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) - BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) - BAD_TRAP(0xfc) KGDB_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff) - -trapbase_cpu2: - BAD_TRAP(0x0) SRMMU_TFAULT TRAP_ENTRY(0x2, bad_instruction) - TRAP_ENTRY(0x3, priv_instruction) TRAP_ENTRY(0x4, fpd_trap_handler) - WINDOW_SPILL WINDOW_FILL TRAP_ENTRY(0x7, mna_handler) - TRAP_ENTRY(0x8, fpe_trap_handler) SRMMU_DFAULT - TRAP_ENTRY(0xa, do_tag_overflow) TRAP_ENTRY(0xb, do_watchpoint) - BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) - TRAP_ENTRY_INTERRUPT(1) TRAP_ENTRY_INTERRUPT(2) - TRAP_ENTRY_INTERRUPT(3) TRAP_ENTRY_INTERRUPT(4) - TRAP_ENTRY_INTERRUPT(5) TRAP_ENTRY_INTERRUPT(6) - TRAP_ENTRY_INTERRUPT(7) TRAP_ENTRY_INTERRUPT(8) - TRAP_ENTRY_INTERRUPT(9) TRAP_ENTRY_INTERRUPT(10) - TRAP_ENTRY_INTERRUPT(11) TRAP_ENTRY_INTERRUPT(12) - TRAP_ENTRY_INTERRUPT(13) TRAP_ENTRY_INTERRUPT(14) - TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) - TRAP_ENTRY(0x20, do_reg_access) BAD_TRAP(0x21) BAD_TRAP(0x22) - BAD_TRAP(0x23) TRAP_ENTRY(0x24, do_cp_disabled) SKIP_TRAP(0x25, unimp_flush) - BAD_TRAP(0x26) BAD_TRAP(0x27) TRAP_ENTRY(0x28, do_cp_exception) - SRMMU_DFAULT TRAP_ENTRY(0x2a, do_hw_divzero) BAD_TRAP(0x2b) BAD_TRAP(0x2c) - BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) - BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) - BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) - BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) - BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) - BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) - BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) - BAD_TRAP(0x50) - BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) - BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) - BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) - BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) - BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) - BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) - BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) - BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) - BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) - BAD_TRAP(0x7e) BAD_TRAP(0x7f) - BAD_TRAP(0x80) - BREAKPOINT_TRAP - TRAP_ENTRY(0x82, do_hw_divzero) - TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85) - BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88) - BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) - BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) - LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) - BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) - BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) - BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP - BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) - BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) - BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) - BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) - BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) - BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) - BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) - BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) - BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) - BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) - BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) - BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) - BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) - BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) - BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) - BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) - BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) - BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) - BAD_TRAP(0xfc) KGDB_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff) - -trapbase_cpu3: - BAD_TRAP(0x0) SRMMU_TFAULT TRAP_ENTRY(0x2, bad_instruction) - TRAP_ENTRY(0x3, priv_instruction) TRAP_ENTRY(0x4, fpd_trap_handler) - WINDOW_SPILL WINDOW_FILL TRAP_ENTRY(0x7, mna_handler) - TRAP_ENTRY(0x8, fpe_trap_handler) SRMMU_DFAULT - TRAP_ENTRY(0xa, do_tag_overflow) TRAP_ENTRY(0xb, do_watchpoint) - BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) - TRAP_ENTRY_INTERRUPT(1) TRAP_ENTRY_INTERRUPT(2) - TRAP_ENTRY_INTERRUPT(3) TRAP_ENTRY_INTERRUPT(4) - TRAP_ENTRY_INTERRUPT(5) TRAP_ENTRY_INTERRUPT(6) - TRAP_ENTRY_INTERRUPT(7) TRAP_ENTRY_INTERRUPT(8) - TRAP_ENTRY_INTERRUPT(9) TRAP_ENTRY_INTERRUPT(10) - TRAP_ENTRY_INTERRUPT(11) TRAP_ENTRY_INTERRUPT(12) - TRAP_ENTRY_INTERRUPT(13) TRAP_ENTRY_INTERRUPT(14) - TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) - TRAP_ENTRY(0x20, do_reg_access) BAD_TRAP(0x21) BAD_TRAP(0x22) - BAD_TRAP(0x23) TRAP_ENTRY(0x24, do_cp_disabled) SKIP_TRAP(0x25, unimp_flush) - BAD_TRAP(0x26) BAD_TRAP(0x27) TRAP_ENTRY(0x28, do_cp_exception) - SRMMU_DFAULT TRAP_ENTRY(0x2a, do_hw_divzero) BAD_TRAP(0x2b) BAD_TRAP(0x2c) - BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) - BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) - BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) - BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) - BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) - BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) - BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) - BAD_TRAP(0x50) - BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) - BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) - BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) - BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) - BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) - BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) - BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) - BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) - BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) - BAD_TRAP(0x7e) BAD_TRAP(0x7f) - BAD_TRAP(0x80) - BREAKPOINT_TRAP - TRAP_ENTRY(0x82, do_hw_divzero) - TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85) - BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88) - BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) - BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) - LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) - BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) - BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) - BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP - BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) - BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) - BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) - BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) - BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) - BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) - BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) - BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) - BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) - BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) - BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) - BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) - BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) - BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) - BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) - BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) - BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) - BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) - BAD_TRAP(0xfc) KGDB_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff) - -#endif .align PAGE_SIZE /* This was the only reasonable way I could think of to properly align * these page-table data structures. */ - .globl pg0, pg1, pg2, pg3 - .globl empty_bad_page - .globl empty_bad_page_table - .globl empty_zero_page .globl swapper_pg_dir swapper_pg_dir: .skip PAGE_SIZE -pg0: .skip PAGE_SIZE -pg1: .skip PAGE_SIZE -pg2: .skip PAGE_SIZE -pg3: .skip PAGE_SIZE -empty_bad_page: .skip PAGE_SIZE -empty_bad_page_table: .skip PAGE_SIZE + .globl empty_zero_page empty_zero_page: .skip PAGE_SIZE .global root_flags @@ -523,10 +172,10 @@ ldd [%g2 + 0x8], %g4 std %g4, [%g3 + 0x8] ! Copy proms handler -/* Must determine whether we are on a sun4c MMU, SRMMU, or SUN4/400 MUTANT - * MMU so we can remap ourselves properly. DON'T TOUCH %l0 thru %l5 in these - * remapping routines, we need their values afterwards! +/* DON'T TOUCH %l0 thru %l5 in these remapping routines, + * we need their values afterwards! */ + /* Now check whether we are already mapped, if we * are we can skip all this garbage coming up. */ @@ -535,26 +184,29 @@ be go_to_highmem ! this will be a nop then nop - set LOAD_ADDR, %g6 + /* Validate that we are in fact running on an + * SRMMU based cpu. + */ + set 0x4000, %g6 cmp %g7, %g6 - bne remap_not_a_sun4 ! This is not a Sun4 + bne not_a_sun4 nop - or %g0, 0x1, %g1 - lduba [%g1] ASI_CONTROL, %g1 ! Only safe to try on Sun4. - subcc %g1, 0x24, %g0 ! Is this a mutant Sun4/400??? - be sun4_mutant_remap ! Ugh, it is... +halt_sun4_or_sun4c: + ld [%g7 + 0x68], %o1 + set sun4c_notsup, %o0 + sub %o0, %l6, %o0 + call %o1 + nop + ba halt_me nop - b sun4_normal_remap ! regular sun4, 2 level mmu +not_a_sun4: + lda [%g0] ASI_M_MMUREGS, %g1 + andcc %g1, 1, %g0 + be halt_sun4_or_sun4c nop -remap_not_a_sun4: - lda [%g0] ASI_M_MMUREGS, %g1 ! same as ASI_PTE on sun4c - and %g1, 0x1, %g1 ! Test SRMMU Enable bit ;-) - cmp %g1, 0x0 - be sun4c_remap ! A sun4c MMU or normal Sun4 - nop srmmu_remap: /* First, check for a viking (TI) module. */ set 0x40000000, %g2 @@ -660,72 +312,6 @@ b go_to_highmem nop ! wheee.... - /* This remaps the kernel on Sun4/4xx machines - * that have the Sun Mutant Three Level MMU. - * It's like a platypus, Sun didn't have the - * SRMMU in conception so they kludged the three - * level logic in the regular Sun4 MMU probably. - * - * Basically, you take each entry in the top level - * directory that maps the low 3MB starting at - * address zero and put the mapping in the KERNBASE - * slots. These top level pgd's are called regmaps. - */ -sun4_mutant_remap: - or %g0, %g0, %g3 ! source base - sethi %hi(KERNBASE), %g4 ! destination base - or %g4, %lo(KERNBASE), %g4 - sethi %hi(0x300000), %g5 - or %g5, %lo(0x300000), %g5 ! upper bound 3MB - or %g0, 0x1, %l6 - sll %l6, 24, %l6 ! Regmap mapping size - add %g3, 0x2, %g3 ! Base magic - add %g4, 0x2, %g4 ! Base magic - - /* Main remapping loop on Sun4-Mutant-MMU. - * "I am not an animal..." -Famous Mutant Person - */ -sun4_mutant_loop: - lduha [%g3] ASI_REGMAP, %g2 ! Get lower entry - stha %g2, [%g4] ASI_REGMAP ! Store in high entry - add %g4, %l6, %g4 ! Move up high memory ptr - subcc %g3, %g5, %g0 ! Reached our limit? - blu sun4_mutant_loop ! Nope, loop again - add %g3, %l6, %g3 ! delay, Move up low ptr - b go_to_highmem ! Jump to high memory. - nop - - /* The following is for non-4/4xx sun4 MMU's. */ -sun4_normal_remap: - mov 0, %g3 ! source base - set KERNBASE, %g4 ! destination base - set 0x300000, %g5 ! upper bound 3MB - mov 1, %l6 - sll %l6, 18, %l6 ! sun4 mmu segmap size -sun4_normal_loop: - lduha [%g3] ASI_SEGMAP, %g6 ! load phys_seg - stha %g6, [%g4] ASI_SEGMAP ! stort new virt mapping - add %g3, %l6, %g3 ! increment source pointer - subcc %g3, %g5, %g0 ! reached limit? - blu sun4_normal_loop ! nope, loop again - add %g4, %l6, %g4 ! delay, increment dest ptr - b go_to_highmem - nop - - /* The following works for Sun4c MMU's */ -sun4c_remap: - mov 0, %g3 ! source base - set KERNBASE, %g4 ! destination base - set 0x300000, %g5 ! upper bound 3MB - mov 1, %l6 - sll %l6, 18, %l6 ! sun4c mmu segmap size -sun4c_remap_loop: - lda [%g3] ASI_SEGMAP, %g6 ! load phys_seg - sta %g6, [%g4] ASI_SEGMAP ! store new virt mapping - add %g3, %l6, %g3 ! Increment source ptr - subcc %g3, %g5, %g0 ! Reached limit? - bl sun4c_remap_loop ! Nope, loop again - add %g4, %l6, %g4 ! delay, Increment dest ptr /* Now do a non-relative jump so that PC is in high-memory */ go_to_highmem: @@ -750,35 +336,12 @@ sethi %hi(linux_dbvec), %g1 st %o1, [%g1 + %lo(linux_dbvec)] - ld [%o0 + 0x4], %o3 - and %o3, 0x3, %o5 ! get the version - - cmp %o3, 0x2 ! a v2 prom? - be found_version - nop - - /* paul@sfe.com.au */ - cmp %o3, 0x3 ! a v3 prom? - be found_version - nop - -/* Old sun4's pass our load address into %o0 instead of the prom - * pointer. On sun4's you have to hard code the romvec pointer into - * your code. Sun probably still does that because they don't even - * trust their own "OpenBoot" specifications. - */ - set LOAD_ADDR, %g6 - cmp %o0, %g6 ! an old sun4? - be sun4_init - nop - -found_version: /* Get the machine type via the mysterious romvec node operations. */ - add %g7, 0x1c, %l1 + add %g7, 0x1c, %l1 ld [%l1], %l0 ld [%l0], %l0 - call %l0 + call %l0 or %g0, %g0, %o0 ! next_node(0) = first_node or %o0, %g0, %g6 @@ -786,28 +349,13 @@ or %o1, %lo(cputypvar), %o1 sethi %hi(cputypval), %o2 ! information, the string or %o2, %lo(cputypval), %o2 - ld [%l1], %l0 ! 'compatibility' tells + ld [%l1], %l0 ! 'compatible' tells ld [%l0 + 0xc], %l0 ! that we want 'sun4x' where - call %l0 ! x is one of '', 'c', 'm', - nop ! 'd' or 'e'. %o2 holds pointer + call %l0 ! x is one of 'm', 'd' or 'e'. + nop ! %o2 holds pointer ! to a buf where above string ! will get stored by the prom. - subcc %o0, %g0, %g0 - bpos got_prop ! Got the property - nop - - or %g6, %g0, %o0 - sethi %hi(cputypvar_sun4m), %o1 - or %o1, %lo(cputypvar_sun4m), %o1 - sethi %hi(cputypval), %o2 - or %o2, %lo(cputypval), %o2 - ld [%l1], %l0 - ld [%l0 + 0xc], %l0 - call %l0 - nop - -got_prop: #ifdef CONFIG_SPARC_LEON /* no cpu-type check is needed, it is a SPARC-LEON */ @@ -826,45 +374,29 @@ /* Update boot_cpu_id only on boot cpu */ stub %g1, [%g2 + %lo(boot_cpu_id)] - ba sun4c_continue_boot + ba continue_boot nop #endif + +/* Check to cputype. We may be booted on a sun4u (64 bit box), + * and sun4d needs special treatment. + */ + set cputypval, %o2 ldub [%o2 + 0x4], %l1 - cmp %l1, ' ' - be 1f - cmp %l1, 'c' - be 1f - cmp %l1, 'm' - be 1f + cmp %l1, 'm' + be sun4m_init cmp %l1, 's' - be 1f + be sun4m_init cmp %l1, 'd' - be 1f + be sun4d_init cmp %l1, 'e' be no_sun4e_here ! Could be a sun4e. nop b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :)) nop -1: set cputypval, %l1 - ldub [%l1 + 0x4], %l1 - cmp %l1, 'm' ! Test for sun4d, sun4e ? - be sun4m_init - cmp %l1, 's' ! Treat sun4s as sun4m - be sun4m_init - cmp %l1, 'd' ! Let us see how the beast will die - be sun4d_init - nop - - /* Jump into mmu context zero. */ - set AC_CONTEXT, %g1 - stba %g0, [%g1] ASI_CONTROL - - b sun4c_continue_boot - nop - /* CPUID in bootbus can be found at PA 0xff0140000 */ #define SUN4D_BOOTBUS_CPUID 0xf0140000 @@ -892,66 +424,6 @@ /* Fall through to sun4m_init */ sun4m_init: - /* XXX Fucking Cypress... */ - lda [%g0] ASI_M_MMUREGS, %g5 - srl %g5, 28, %g4 - - cmp %g4, 1 - bne 1f - srl %g5, 24, %g4 - - and %g4, 0xf, %g4 - cmp %g4, 7 /* This would be a HyperSparc. */ - - bne 2f - nop - -1: - -#define PATCH_IT(dst, src) \ - set (dst), %g5; \ - set (src), %g4; \ - ld [%g4], %g3; \ - st %g3, [%g5]; \ - ld [%g4+0x4], %g3; \ - st %g3, [%g5+0x4]; - - /* Signed multiply. */ - PATCH_IT(.mul, .mul_patch) - PATCH_IT(.mul+0x08, .mul_patch+0x08) - - /* Signed remainder. */ - PATCH_IT(.rem, .rem_patch) - PATCH_IT(.rem+0x08, .rem_patch+0x08) - PATCH_IT(.rem+0x10, .rem_patch+0x10) - PATCH_IT(.rem+0x18, .rem_patch+0x18) - PATCH_IT(.rem+0x20, .rem_patch+0x20) - PATCH_IT(.rem+0x28, .rem_patch+0x28) - - /* Signed division. */ - PATCH_IT(.div, .div_patch) - PATCH_IT(.div+0x08, .div_patch+0x08) - PATCH_IT(.div+0x10, .div_patch+0x10) - PATCH_IT(.div+0x18, .div_patch+0x18) - PATCH_IT(.div+0x20, .div_patch+0x20) - - /* Unsigned multiply. */ - PATCH_IT(.umul, .umul_patch) - PATCH_IT(.umul+0x08, .umul_patch+0x08) - - /* Unsigned remainder. */ - PATCH_IT(.urem, .urem_patch) - PATCH_IT(.urem+0x08, .urem_patch+0x08) - PATCH_IT(.urem+0x10, .urem_patch+0x10) - PATCH_IT(.urem+0x18, .urem_patch+0x18) - - /* Unsigned division. */ - PATCH_IT(.udiv, .udiv_patch) - PATCH_IT(.udiv+0x08, .udiv_patch+0x08) - PATCH_IT(.udiv+0x10, .udiv_patch+0x10) - -#undef PATCH_IT - /* Ok, the PROM could have done funny things and apple cider could still * be sitting in the fault status/address registers. Read them all to * clear them so we don't get magic faults later on. @@ -962,7 +434,7 @@ srl %o1, 28, %o1 ! Get a type of the CPU subcc %o1, 4, %g0 ! TI: Viking or MicroSPARC - be sun4c_continue_boot + be continue_boot nop set AC_M_SFSR, %o0 @@ -972,7 +444,7 @@ /* Fujitsu MicroSPARC-II has no asynchronous flavors of FARs */ subcc %o1, 0, %g0 - be sun4c_continue_boot + be continue_boot nop set AC_M_AFSR, %o0 @@ -982,8 +454,7 @@ nop -sun4c_continue_boot: - +continue_boot: /* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's * show-time! @@ -1026,10 +497,7 @@ mov %g0, %g3 stub %g3, [%g2 + %lo(boot_cpu_id)] -1: /* boot_cpu_id set. calculate boot_cpu_id4 = boot_cpu_id*4 */ - sll %g3, 2, %g3 - sethi %hi(boot_cpu_id4), %g2 - stub %g3, [%g2 + %lo(boot_cpu_id4)] +1: sll %g3, 2, %g3 /* Initialize the uwinmask value for init task just in case. * But first make current_set[boot_cpu_id] point to something useful. @@ -1165,19 +633,6 @@ call halt_me nop -sun4_init: - sethi %hi(SUN4_PROM_VECTOR+0x84), %o1 - ld [%o1 + %lo(SUN4_PROM_VECTOR+0x84)], %o1 - set sun4_notsup, %o0 - call %o1 /* printf */ - nop - sethi %hi(SUN4_PROM_VECTOR+0xc4), %o1 - ld [%o1 + %lo(SUN4_PROM_VECTOR+0xc4)], %o1 - call %o1 /* exittomon */ - nop -1: ba 1b ! Cannot exit into KMON - nop - no_sun4e_here: ld [%g7 + 0x68], %o1 set sun4e_notsup, %o0
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index 0d810c2..b42ddbf9 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S
@@ -906,7 +906,7 @@ * error and will instead write junk into the relocation and * you'll have an unbootable kernel. */ -#include "ttable.S" +#include "ttable_64.S" ! 0x0000000000428000
diff --git a/arch/sparc/kernel/idprom.c b/arch/sparc/kernel/idprom.c index 9167db4..6bd7501 100644 --- a/arch/sparc/kernel/idprom.c +++ b/arch/sparc/kernel/idprom.c
@@ -25,22 +25,9 @@ * of the Sparc CPU and have a meaningful IDPROM machtype value that we * know about. See asm-sparc/machines.h for empirical constants. */ -static struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = { -/* First, Sun4's */ -{ .name = "Sun 4/100 Series", .id_machtype = (SM_SUN4 | SM_4_110) }, -{ .name = "Sun 4/200 Series", .id_machtype = (SM_SUN4 | SM_4_260) }, -{ .name = "Sun 4/300 Series", .id_machtype = (SM_SUN4 | SM_4_330) }, -{ .name = "Sun 4/400 Series", .id_machtype = (SM_SUN4 | SM_4_470) }, -/* Now Leon */ +static struct Sun_Machine_Models Sun_Machines[] = { +/* First, Leon */ { .name = "Leon3 System-on-a-Chip", .id_machtype = (M_LEON | M_LEON3_SOC) }, -/* Now, Sun4c's */ -{ .name = "Sun4c SparcStation 1", .id_machtype = (SM_SUN4C | SM_4C_SS1) }, -{ .name = "Sun4c SparcStation IPC", .id_machtype = (SM_SUN4C | SM_4C_IPC) }, -{ .name = "Sun4c SparcStation 1+", .id_machtype = (SM_SUN4C | SM_4C_SS1PLUS) }, -{ .name = "Sun4c SparcStation SLC", .id_machtype = (SM_SUN4C | SM_4C_SLC) }, -{ .name = "Sun4c SparcStation 2", .id_machtype = (SM_SUN4C | SM_4C_SS2) }, -{ .name = "Sun4c SparcStation ELC", .id_machtype = (SM_SUN4C | SM_4C_ELC) }, -{ .name = "Sun4c SparcStation IPX", .id_machtype = (SM_SUN4C | SM_4C_IPX) }, /* Finally, early Sun4m's */ { .name = "Sun4m SparcSystem600", .id_machtype = (SM_SUN4M | SM_4M_SS60) }, { .name = "Sun4m SparcStation10/20", .id_machtype = (SM_SUN4M | SM_4M_SS50) }, @@ -53,7 +40,7 @@ char sysname[128]; register int i; - for (i = 0; i < NUM_SUN_MACHINES; i++) { + for (i = 0; i < ARRAY_SIZE(Sun_Machines); i++) { if (Sun_Machines[i].id_machtype == machtype) { if (machtype != (SM_SUN4M_OBP | 0x00) || prom_getproperty(prom_root_node, "banner-name",
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 21bd739..a2846f5 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c
@@ -50,6 +50,8 @@ #include <asm/io-unit.h> #include <asm/leon.h> +const struct sparc32_dma_ops *sparc32_dma_ops; + /* This function must make sure that caches and memory are coherent after DMA * On LEON systems without cache snooping it flushes the entire D-CACHE. */ @@ -229,7 +231,7 @@ } pa &= PAGE_MASK; - sparc_mapiorange(bus, pa, res->start, resource_size(res)); + srmmu_mapiorange(bus, pa, res->start, resource_size(res)); return (void __iomem *)(unsigned long)(res->start + offset); } @@ -243,7 +245,7 @@ plen = resource_size(res); BUG_ON((plen & (PAGE_SIZE-1)) != 0); - sparc_unmapiorange(res->start, plen); + srmmu_unmapiorange(res->start, plen); release_resource(res); } @@ -292,13 +294,13 @@ goto err_nova; } - // XXX The mmu_map_dma_area does this for us below, see comments. - // sparc_mapiorange(0, virt_to_phys(va), res->start, len_total); + // XXX The sbus_map_dma_area does this for us below, see comments. + // srmmu_mapiorange(0, virt_to_phys(va), res->start, len_total); /* * XXX That's where sdev would be used. Currently we load * all iommu tables with the same translations. */ - if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0) + if (sbus_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0) goto err_noiommu; res->name = op->dev.of_node->name; @@ -343,7 +345,7 @@ kfree(res); pgv = virt_to_page(p); - mmu_unmap_dma_area(dev, ba, n); + sbus_unmap_dma_area(dev, ba, n); __free_pages(pgv, get_order(n)); } @@ -381,11 +383,6 @@ enum dma_data_direction dir, struct dma_attrs *attrs) { mmu_get_scsi_sgl(dev, sg, n); - - /* - * XXX sparc64 can return a partial length here. sun4c should do this - * but it currently panics if it can't fulfill the request - Anton - */ return n; } @@ -469,7 +466,7 @@ printk("pci_alloc_consistent: cannot occupy 0x%lx", len_total); goto err_nova; } - sparc_mapiorange(0, virt_to_phys(va), res->start, len_total); + srmmu_mapiorange(0, virt_to_phys(va), res->start, len_total); *pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */ return (void *) res->start; @@ -514,7 +511,7 @@ } dma_make_coherent(ba, n); - sparc_unmapiorange((unsigned long)p, n); + srmmu_unmapiorange((unsigned long)p, n); release_resource(res); kfree(res);
diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h index 5a021dd..b66b6aa 100644 --- a/arch/sparc/kernel/irq.h +++ b/arch/sparc/kernel/irq.h
@@ -1,6 +1,5 @@ #include <linux/platform_device.h> -#include <asm/btfixup.h> #include <asm/cpu_type.h> struct irq_bucket { @@ -10,6 +9,9 @@ unsigned int pil; }; +#define SUN4M_HARD_INT(x) (0x000000001 << (x)) +#define SUN4M_SOFT_INT(x) (0x000010000 << (x)) + #define SUN4D_MAX_BOARD 10 #define SUN4D_MAX_IRQ ((SUN4D_MAX_BOARD + 2) << 5) @@ -41,52 +43,46 @@ extern struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS]; extern struct sun4m_irq_global __iomem *sun4m_irq_global; +/* The following definitions describe the individual platform features: */ +#define FEAT_L10_CLOCKSOURCE (1 << 0) /* L10 timer is used as a clocksource */ +#define FEAT_L10_CLOCKEVENT (1 << 1) /* L10 timer is used as a clockevent */ +#define FEAT_L14_ONESHOT (1 << 2) /* L14 timer clockevent can oneshot */ + /* - * Platform specific irq configuration + * Platform specific configuration * The individual platforms assign their platform * specifics in their init functions. */ -struct sparc_irq_config { - void (*init_timers)(irq_handler_t); +struct sparc_config { + void (*init_timers)(void); unsigned int (*build_device_irq)(struct platform_device *op, unsigned int real_irq); + + /* generic clockevent features - see FEAT_* above */ + int features; + + /* clock rate used for clock event timer */ + int clock_rate; + + /* one period for clock source timer */ + unsigned int cs_period; + + /* function to obtain offsett for cs period */ + unsigned int (*get_cycles_offset)(void); + + void (*clear_clock_irq)(void); + void (*load_profile_irq)(int cpu, unsigned int limit); }; -extern struct sparc_irq_config sparc_irq_config; +extern struct sparc_config sparc_config; unsigned int irq_alloc(unsigned int real_irq, unsigned int pil); void irq_link(unsigned int irq); void irq_unlink(unsigned int irq); void handler_irq(unsigned int pil, struct pt_regs *regs); -/* Dave Redman (djhr@tadpole.co.uk) - * changed these to function pointers.. it saves cycles and will allow - * the irq dependencies to be split into different files at a later date - * sun4c_irq.c, sun4m_irq.c etc so we could reduce the kernel size. - * Jakub Jelinek (jj@sunsite.mff.cuni.cz) - * Changed these to btfixup entities... It saves cycles :) - */ - -BTFIXUPDEF_CALL(void, clear_clock_irq, void) -BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int) - -static inline void clear_clock_irq(void) -{ - BTFIXUP_CALL(clear_clock_irq)(); -} - -static inline void load_profile_irq(int cpu, int limit) -{ - BTFIXUP_CALL(load_profile_irq)(cpu, limit); -} +unsigned long leon_get_irqmask(unsigned int irq); #ifdef CONFIG_SMP -BTFIXUPDEF_CALL(void, set_cpu_int, int, int) -BTFIXUPDEF_CALL(void, clear_cpu_int, int, int) -BTFIXUPDEF_CALL(void, set_irq_udt, int) - -#define set_cpu_int(cpu,level) BTFIXUP_CALL(set_cpu_int)(cpu,level) -#define clear_cpu_int(cpu,level) BTFIXUP_CALL(clear_cpu_int)(cpu,level) -#define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu) /* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */ #define SUN4D_IPI_IRQ 13
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c index b2668af..ae04914 100644 --- a/arch/sparc/kernel/irq_32.c +++ b/arch/sparc/kernel/irq_32.c
@@ -23,16 +23,8 @@ #include "kernel.h" #include "irq.h" -#ifdef CONFIG_SMP -#define SMP_NOP2 "nop; nop;\n\t" -#define SMP_NOP3 "nop; nop; nop;\n\t" -#else -#define SMP_NOP2 -#define SMP_NOP3 -#endif /* SMP */ - /* platform specific irq setup */ -struct sparc_irq_config sparc_irq_config; +struct sparc_config sparc_config; unsigned long arch_local_irq_save(void) { @@ -41,7 +33,6 @@ __asm__ __volatile__( "rd %%psr, %0\n\t" - SMP_NOP3 /* Sun4m + Cypress + SMP bug */ "or %0, %2, %1\n\t" "wr %1, 0, %%psr\n\t" "nop; nop; nop\n" @@ -59,7 +50,6 @@ __asm__ __volatile__( "rd %%psr, %0\n\t" - SMP_NOP3 /* Sun4m + Cypress + SMP bug */ "andn %0, %1, %0\n\t" "wr %0, 0, %%psr\n\t" "nop; nop; nop\n" @@ -76,7 +66,6 @@ __asm__ __volatile__( "rd %%psr, %0\n\t" "and %2, %1, %2\n\t" - SMP_NOP2 /* Sun4m + Cypress + SMP bug */ "andn %0, %1, %0\n\t" "wr %0, %2, %%psr\n\t" "nop; nop; nop\n" @@ -346,11 +335,6 @@ void __init init_IRQ(void) { switch (sparc_cpu_model) { - case sun4c: - case sun4: - sun4c_init_IRQ(); - break; - case sun4m: pcic_probe(); if (pcic_present()) @@ -371,6 +355,5 @@ prom_printf("Cannot initialize IRQs on this Sun machine..."); break; } - btfixup(); }
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index dff2c3d..9bcbbe2 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c
@@ -799,7 +799,7 @@ prom_limit0 = prom_timers->limit0; prom_limit1 = prom_timers->limit1; - /* Just as in sun4c/sun4m PROM uses timer which ticks at IRQ 14. + /* Just as in sun4c PROM uses timer which ticks at IRQ 14. * We turn both off here just to be paranoid. */ prom_timers->limit0 = 0;
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index fd6c36b..a86372d 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h
@@ -32,9 +32,6 @@ /* traps_32.c */ extern void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr); -/* muldiv.c */ -extern int do_user_muldiv (struct pt_regs *, unsigned long); - /* irq_32.c */ extern struct irqaction static_irqaction[]; extern int static_irq_count; @@ -43,12 +40,7 @@ extern void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs); extern void init_IRQ(void); -/* sun4c_irq.c */ -extern void sun4c_init_IRQ(void); - /* sun4m_irq.c */ -extern unsigned int lvl14_resolution; - extern void sun4m_init_IRQ(void); extern void sun4m_unmask_profile_irq(void); extern void sun4m_clear_profile_irq(int cpu); @@ -85,8 +77,6 @@ extern void floppy_hardint(void); /* trampoline_32.S */ -extern int __smp4m_processor_id(void); -extern int __smp4d_processor_id(void); extern unsigned long sun4m_cpu_startup; extern unsigned long sun4d_cpu_startup;
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 35e43673..77c1b91 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c
@@ -10,6 +10,8 @@ #include <linux/of_platform.h> #include <linux/interrupt.h> #include <linux/of_device.h> +#include <linux/clocksource.h> +#include <linux/clockchips.h> #include <asm/oplib.h> #include <asm/timer.h> @@ -84,7 +86,7 @@ sparc_leon_eirq = eirq; } -static inline unsigned long get_irqmask(unsigned int irq) +unsigned long leon_get_irqmask(unsigned int irq) { unsigned long mask; @@ -210,7 +212,7 @@ unsigned long mask; irq = 0; - mask = get_irqmask(real_irq); + mask = leon_get_irqmask(real_irq); if (mask == 0) goto out; @@ -250,7 +252,38 @@ irq_set_chip_data(virq, (void *)mask); } -void __init leon_init_timers(irq_handler_t counter_fn) +static u32 leon_cycles_offset(void) +{ + u32 rld, val, off; + rld = LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].rld); + val = LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].val); + off = rld - val; + return rld - val; +} + +#ifdef CONFIG_SMP + +/* smp clockevent irq */ +irqreturn_t leon_percpu_timer_ce_interrupt(int irq, void *unused) +{ + struct clock_event_device *ce; + int cpu = smp_processor_id(); + + leon_clear_profile_irq(cpu); + + ce = &per_cpu(sparc32_clockevent, cpu); + + irq_enter(); + if (ce->event_handler) + ce->event_handler(ce); + irq_exit(); + + return IRQ_HANDLED; +} + +#endif /* CONFIG_SMP */ + +void __init leon_init_timers(void) { int irq, eirq; struct device_node *rootnp, *np, *nnp; @@ -260,6 +293,14 @@ int ampopts; int err; + sparc_config.get_cycles_offset = leon_cycles_offset; + sparc_config.cs_period = 1000000 / HZ; + sparc_config.features |= FEAT_L10_CLOCKSOURCE; + +#ifndef CONFIG_SMP + sparc_config.features |= FEAT_L10_CLOCKEVENT; +#endif + leondebug_irq_disable = 0; leon_debug_irqout = 0; master_l10_counter = (unsigned int *)&dummy_master_l10_counter; @@ -369,7 +410,7 @@ leon_eirq_setup(eirq); irq = _leon_build_device_irq(NULL, leon3_gptimer_irq+leon3_gptimer_idx); - err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL); + err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL); if (err) { printk(KERN_ERR "unable to attach timer IRQ%d\n", irq); prom_halt(); @@ -386,7 +427,7 @@ */ local_irq_save(flags); patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */ - local_flush_cache_all(); + local_ops->cache_all(); local_irq_restore(flags); } #endif @@ -401,7 +442,7 @@ /* Install per-cpu IRQ handler for broadcasted ticker */ irq = leon_build_device_irq(leon3_ticker_irq, handle_percpu_irq, "per-cpu", 0); - err = request_irq(irq, leon_percpu_timer_interrupt, + err = request_irq(irq, leon_percpu_timer_ce_interrupt, IRQF_PERCPU | IRQF_TIMER, "ticker", NULL); if (err) { @@ -422,13 +463,12 @@ return; } -void leon_clear_clock_irq(void) +static void leon_clear_clock_irq(void) { } -void leon_load_profile_irq(int cpu, unsigned int limit) +static void leon_load_profile_irq(int cpu, unsigned int limit) { - BUG(); } void __init leon_trans_init(struct device_node *dp) @@ -457,25 +497,6 @@ } #ifdef CONFIG_SMP - -void leon_set_cpu_int(int cpu, int level) -{ - unsigned long mask; - mask = get_irqmask(level); - LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask); -} - -static void leon_clear_ipi(int cpu, int level) -{ - unsigned long mask; - mask = get_irqmask(level); - LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask<<16); -} - -static void leon_set_udt(int cpu) -{ -} - void leon_clear_profile_irq(int cpu) { } @@ -483,7 +504,7 @@ void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu) { unsigned long mask, flags, *addr; - mask = get_irqmask(irq_nr); + mask = leon_get_irqmask(irq_nr); spin_lock_irqsave(&leon_irq_lock, flags); addr = (unsigned long *)LEON_IMASK(cpu); LEON3_BYPASS_STORE_PA(addr, (LEON3_BYPASS_LOAD_PA(addr) | mask)); @@ -494,20 +515,11 @@ void __init leon_init_IRQ(void) { - sparc_irq_config.init_timers = leon_init_timers; - sparc_irq_config.build_device_irq = _leon_build_device_irq; - - BTFIXUPSET_CALL(clear_clock_irq, leon_clear_clock_irq, - BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(load_profile_irq, leon_load_profile_irq, - BTFIXUPCALL_NOP); - -#ifdef CONFIG_SMP - BTFIXUPSET_CALL(set_cpu_int, leon_set_cpu_int, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(clear_cpu_int, leon_clear_ipi, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(set_irq_udt, leon_set_udt, BTFIXUPCALL_NORM); -#endif - + sparc_config.init_timers = leon_init_timers; + sparc_config.build_device_irq = _leon_build_device_irq; + sparc_config.clock_rate = 1000000; + sparc_config.clear_clock_irq = leon_clear_clock_irq; + sparc_config.load_profile_irq = leon_load_profile_irq; } void __init leon_init(void)
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index 160cac9..29325ba 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c
@@ -24,6 +24,7 @@ #include <linux/delay.h> #include <linux/gfp.h> #include <linux/cpu.h> +#include <linux/clockchips.h> #include <asm/cacheflush.h> #include <asm/tlbflush.h> @@ -43,6 +44,7 @@ #include <asm/asi.h> #include <asm/leon.h> #include <asm/leon_amba.h> +#include <asm/timer.h> #include "kernel.h" @@ -69,26 +71,24 @@ return val; } -static void smp_setup_percpu_timer(void); - void __cpuinit leon_callin(void) { - int cpuid = hard_smpleon_processor_id(); + int cpuid = hard_smp_processor_id(); - local_flush_cache_all(); - local_flush_tlb_all(); + local_ops->cache_all(); + local_ops->tlb_all(); leon_configure_cache_smp(); notify_cpu_starting(cpuid); /* Get our local ticker going. */ - smp_setup_percpu_timer(); + register_percpu_ce(cpuid); calibrate_delay(); smp_store_cpu_info(cpuid); - local_flush_cache_all(); - local_flush_tlb_all(); + local_ops->cache_all(); + local_ops->tlb_all(); /* * Unblock the master CPU _only_ when the scheduler state @@ -99,8 +99,8 @@ */ do_swap(&cpu_callin_map[cpuid], 1); - local_flush_cache_all(); - local_flush_tlb_all(); + local_ops->cache_all(); + local_ops->tlb_all(); /* Fix idle thread fields. */ __asm__ __volatile__("ld [%0], %%g6\n\t" : : "r"(¤t_set[cpuid]) @@ -143,8 +143,8 @@ } } - local_flush_cache_all(); - local_flush_tlb_all(); + local_ops->cache_all(); + local_ops->tlb_all(); } void leon_smp_setbroadcast(unsigned int mask) @@ -199,8 +199,7 @@ leon_smp_setbroadcast(1 << LEON3_IRQ_TICKER); leon_configure_cache_smp(); - smp_setup_percpu_timer(); - local_flush_cache_all(); + local_ops->cache_all(); } @@ -227,7 +226,7 @@ /* whirrr, whirrr, whirrrrrrrrr... */ printk(KERN_INFO "Starting CPU %d : (irqmp: 0x%x)\n", (unsigned int)i, (unsigned int)&leon3_irqctrl_regs->mpstatus); - local_flush_cache_all(); + local_ops->cache_all(); /* Make sure all IRQs are of from the start for this new CPU */ LEON_BYPASS_STORE_PA(&leon3_irqctrl_regs->mask[i], 0); @@ -252,7 +251,7 @@ leon_enable_irq_cpu(leon_ipi_irq, i); } - local_flush_cache_all(); + local_ops->cache_all(); return 0; } @@ -272,7 +271,7 @@ } } *prev = first; - local_flush_cache_all(); + local_ops->cache_all(); /* Free unneeded trap tables */ if (!cpu_present(1)) { @@ -338,7 +337,7 @@ local_irq_save(flags); trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (leon_ipi_irq - 1)]; trap_table->inst_three += smpleon_ipi - real_irq_entry; - local_flush_cache_all(); + local_ops->cache_all(); local_irq_restore(flags); for_each_possible_cpu(cpu) { @@ -347,6 +346,13 @@ } } +static void leon_send_ipi(int cpu, int level) +{ + unsigned long mask; + mask = leon_get_irqmask(level); + LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask); +} + static void leon_ipi_single(int cpu) { struct leon_ipi_work *work = &per_cpu(leon_ipi_work, cpu); @@ -355,7 +361,7 @@ work->single = 1; /* Generate IRQ on the CPU */ - set_cpu_int(cpu, leon_ipi_irq); + leon_send_ipi(cpu, leon_ipi_irq); } static void leon_ipi_mask_one(int cpu) @@ -366,7 +372,7 @@ work->msk = 1; /* Generate IRQ on the CPU */ - set_cpu_int(cpu, leon_ipi_irq); + leon_send_ipi(cpu, leon_ipi_irq); } static void leon_ipi_resched(int cpu) @@ -377,7 +383,7 @@ work->resched = 1; /* Generate IRQ on the CPU (any IRQ will cause resched) */ - set_cpu_int(cpu, leon_ipi_irq); + leon_send_ipi(cpu, leon_ipi_irq); } void leonsmp_ipi_interrupt(void) @@ -449,7 +455,7 @@ if (cpumask_test_cpu(i, &mask)) { ccall_info.processors_in[i] = 0; ccall_info.processors_out[i] = 0; - set_cpu_int(i, LEON3_IRQ_CROSS_CALL); + leon_send_ipi(i, LEON3_IRQ_CROSS_CALL); } } @@ -492,68 +498,19 @@ ccall_info.processors_out[i] = 1; } -irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused) -{ - int cpu = smp_processor_id(); - - leon_clear_profile_irq(cpu); - - profile_tick(CPU_PROFILING); - - if (!--prof_counter(cpu)) { - int user = user_mode(get_irq_regs()); - - update_process_times(user); - - prof_counter(cpu) = prof_multiplier(cpu); - } - - return IRQ_HANDLED; -} - -static void __init smp_setup_percpu_timer(void) -{ - int cpu = smp_processor_id(); - - prof_counter(cpu) = prof_multiplier(cpu) = 1; -} - -void __init leon_blackbox_id(unsigned *addr) -{ - int rd = *addr & 0x3e000000; - int rs1 = rd >> 11; - - /* patch places where ___b_hard_smp_processor_id appears */ - addr[0] = 0x81444000 | rd; /* rd %asr17, reg */ - addr[1] = 0x8130201c | rd | rs1; /* srl reg, 0x1c, reg */ - addr[2] = 0x01000000; /* nop */ -} - -void __init leon_blackbox_current(unsigned *addr) -{ - int rd = *addr & 0x3e000000; - int rs1 = rd >> 11; - - /* patch LOAD_CURRENT macro where ___b_load_current appears */ - addr[0] = 0x81444000 | rd; /* rd %asr17, reg */ - addr[2] = 0x8130201c | rd | rs1; /* srl reg, 0x1c, reg */ - addr[4] = 0x81282002 | rd | rs1; /* sll reg, 0x2, reg */ - -} +static const struct sparc32_ipi_ops leon_ipi_ops = { + .cross_call = leon_cross_call, + .resched = leon_ipi_resched, + .single = leon_ipi_single, + .mask_one = leon_ipi_mask_one, +}; void __init leon_init_smp(void) { /* Patch ipi15 trap table */ t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_leon - linux_trap_ipi15_sun4m); - BTFIXUPSET_BLACKBOX(hard_smp_processor_id, leon_blackbox_id); - BTFIXUPSET_BLACKBOX(load_current, leon_blackbox_current); - BTFIXUPSET_CALL(smp_cross_call, leon_cross_call, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(__hard_smp_processor_id, __leon_processor_id, - BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(smp_ipi_resched, leon_ipi_resched, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(smp_ipi_single, leon_ipi_single, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(smp_ipi_mask_one, leon_ipi_mask_one, BTFIXUPCALL_NORM); + sparc32_ipi_ops = &leon_ipi_ops; } #endif /* CONFIG_SPARC_LEON */
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index 276359e..15e0a16 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c
@@ -32,26 +32,11 @@ GFP_KERNEL, PAGE_KERNEL, -1, __builtin_return_address(0)); } - -static char *dot2underscore(char *name) -{ - return name; -} #else static void *module_map(unsigned long size) { return vmalloc(size); } - -/* Replace references to .func with _Func */ -static char *dot2underscore(char *name) -{ - if (name[0] == '.') { - name[0] = '_'; - name[1] = toupper(name[1]); - } - return name; -} #endif /* CONFIG_SPARC64 */ void *module_alloc(unsigned long size) @@ -93,12 +78,8 @@ for (i = 1; i < sechdrs[symidx].sh_size / sizeof(Elf_Sym); i++) { if (sym[i].st_shndx == SHN_UNDEF) { - if (ELF_ST_TYPE(sym[i].st_info) == STT_REGISTER) { + if (ELF_ST_TYPE(sym[i].st_info) == STT_REGISTER) sym[i].st_shndx = SHN_ABS; - } else { - char *name = strtab + sym[i].st_name; - dot2underscore(name); - } } } return 0;
diff --git a/arch/sparc/kernel/muldiv.c b/arch/sparc/kernel/muldiv.c deleted file mode 100644 index f7db516..0000000 --- a/arch/sparc/kernel/muldiv.c +++ /dev/null
@@ -1,238 +0,0 @@ -/* - * muldiv.c: Hardware multiply/division illegal instruction trap - * for sun4c/sun4 (which do not have those instructions) - * - * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) - * - * 2004-12-25 Krzysztof Helt (krzysztof.h1@wp.pl) - * - fixed registers constrains in inline assembly declarations - */ - -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <asm/ptrace.h> -#include <asm/processor.h> -#include <asm/uaccess.h> - -#include "kernel.h" - -/* #define DEBUG_MULDIV */ - -static inline int has_imm13(int insn) -{ - return (insn & 0x2000); -} - -static inline int is_foocc(int insn) -{ - return (insn & 0x800000); -} - -static inline int sign_extend_imm13(int imm) -{ - return imm << 19 >> 19; -} - -static inline void advance(struct pt_regs *regs) -{ - regs->pc = regs->npc; - regs->npc += 4; -} - -static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2, - unsigned int rd) -{ - if(rs2 >= 16 || rs1 >= 16 || rd >= 16) { - /* Wheee... */ - __asm__ __volatile__("save %sp, -0x40, %sp\n\t" - "save %sp, -0x40, %sp\n\t" - "save %sp, -0x40, %sp\n\t" - "save %sp, -0x40, %sp\n\t" - "save %sp, -0x40, %sp\n\t" - "save %sp, -0x40, %sp\n\t" - "save %sp, -0x40, %sp\n\t" - "restore; restore; restore; restore;\n\t" - "restore; restore; restore;\n\t"); - } -} - -#define fetch_reg(reg, regs) ({ \ - struct reg_window32 __user *win; \ - register unsigned long ret; \ - \ - if (!(reg)) ret = 0; \ - else if ((reg) < 16) { \ - ret = regs->u_regs[(reg)]; \ - } else { \ - /* Ho hum, the slightly complicated case. */ \ - win = (struct reg_window32 __user *)regs->u_regs[UREG_FP];\ - if (get_user (ret, &win->locals[(reg) - 16])) return -1;\ - } \ - ret; \ -}) - -static inline int -store_reg(unsigned int result, unsigned int reg, struct pt_regs *regs) -{ - struct reg_window32 __user *win; - - if (!reg) - return 0; - if (reg < 16) { - regs->u_regs[reg] = result; - return 0; - } else { - /* need to use put_user() in this case: */ - win = (struct reg_window32 __user *) regs->u_regs[UREG_FP]; - return (put_user(result, &win->locals[reg - 16])); - } -} - -/* Should return 0 if mul/div emulation succeeded and SIGILL should - * not be issued. - */ -int do_user_muldiv(struct pt_regs *regs, unsigned long pc) -{ - unsigned int insn; - int inst; - unsigned int rs1, rs2, rdv; - - if (!pc) - return -1; /* This happens to often, I think */ - if (get_user (insn, (unsigned int __user *)pc)) - return -1; - if ((insn & 0xc1400000) != 0x80400000) - return -1; - inst = ((insn >> 19) & 0xf); - if ((inst & 0xe) != 10 && (inst & 0xe) != 14) - return -1; - - /* Now we know we have to do something with umul, smul, udiv or sdiv */ - rs1 = (insn >> 14) & 0x1f; - rs2 = insn & 0x1f; - rdv = (insn >> 25) & 0x1f; - if (has_imm13(insn)) { - maybe_flush_windows(rs1, 0, rdv); - rs2 = sign_extend_imm13(insn); - } else { - maybe_flush_windows(rs1, rs2, rdv); - rs2 = fetch_reg(rs2, regs); - } - rs1 = fetch_reg(rs1, regs); - switch (inst) { - case 10: /* umul */ -#ifdef DEBUG_MULDIV - printk ("unsigned muldiv: 0x%x * 0x%x = ", rs1, rs2); -#endif - __asm__ __volatile__ ("\n\t" - "mov %0, %%o0\n\t" - "call .umul\n\t" - " mov %1, %%o1\n\t" - "mov %%o0, %0\n\t" - "mov %%o1, %1\n\t" - : "=r" (rs1), "=r" (rs2) - : "0" (rs1), "1" (rs2) - : "o0", "o1", "o2", "o3", "o4", "o5", "o7", "cc"); -#ifdef DEBUG_MULDIV - printk ("0x%x%08x\n", rs2, rs1); -#endif - if (store_reg(rs1, rdv, regs)) - return -1; - regs->y = rs2; - break; - case 11: /* smul */ -#ifdef DEBUG_MULDIV - printk ("signed muldiv: 0x%x * 0x%x = ", rs1, rs2); -#endif - __asm__ __volatile__ ("\n\t" - "mov %0, %%o0\n\t" - "call .mul\n\t" - " mov %1, %%o1\n\t" - "mov %%o0, %0\n\t" - "mov %%o1, %1\n\t" - : "=r" (rs1), "=r" (rs2) - : "0" (rs1), "1" (rs2) - : "o0", "o1", "o2", "o3", "o4", "o5", "o7", "cc"); -#ifdef DEBUG_MULDIV - printk ("0x%x%08x\n", rs2, rs1); -#endif - if (store_reg(rs1, rdv, regs)) - return -1; - regs->y = rs2; - break; - case 14: /* udiv */ -#ifdef DEBUG_MULDIV - printk ("unsigned muldiv: 0x%x%08x / 0x%x = ", regs->y, rs1, rs2); -#endif - if (!rs2) { -#ifdef DEBUG_MULDIV - printk ("DIVISION BY ZERO\n"); -#endif - handle_hw_divzero (regs, pc, regs->npc, regs->psr); - return 0; - } - __asm__ __volatile__ ("\n\t" - "mov %2, %%o0\n\t" - "mov %0, %%o1\n\t" - "mov %%g0, %%o2\n\t" - "call __udivdi3\n\t" - " mov %1, %%o3\n\t" - "mov %%o1, %0\n\t" - "mov %%o0, %1\n\t" - : "=r" (rs1), "=r" (rs2) - : "r" (regs->y), "0" (rs1), "1" (rs2) - : "o0", "o1", "o2", "o3", "o4", "o5", "o7", - "g1", "g2", "g3", "cc"); -#ifdef DEBUG_MULDIV - printk ("0x%x\n", rs1); -#endif - if (store_reg(rs1, rdv, regs)) - return -1; - break; - case 15: /* sdiv */ -#ifdef DEBUG_MULDIV - printk ("signed muldiv: 0x%x%08x / 0x%x = ", regs->y, rs1, rs2); -#endif - if (!rs2) { -#ifdef DEBUG_MULDIV - printk ("DIVISION BY ZERO\n"); -#endif - handle_hw_divzero (regs, pc, regs->npc, regs->psr); - return 0; - } - __asm__ __volatile__ ("\n\t" - "mov %2, %%o0\n\t" - "mov %0, %%o1\n\t" - "mov %%g0, %%o2\n\t" - "call __divdi3\n\t" - " mov %1, %%o3\n\t" - "mov %%o1, %0\n\t" - "mov %%o0, %1\n\t" - : "=r" (rs1), "=r" (rs2) - : "r" (regs->y), "0" (rs1), "1" (rs2) - : "o0", "o1", "o2", "o3", "o4", "o5", "o7", - "g1", "g2", "g3", "cc"); -#ifdef DEBUG_MULDIV - printk ("0x%x\n", rs1); -#endif - if (store_reg(rs1, rdv, regs)) - return -1; - break; - } - if (is_foocc (insn)) { - regs->psr &= ~PSR_ICC; - if ((inst & 0xe) == 14) { - /* ?div */ - if (rs2) regs->psr |= PSR_V; - } - if (!rs1) regs->psr |= PSR_Z; - if (((int)rs1) < 0) regs->psr |= PSR_N; -#ifdef DEBUG_MULDIV - printk ("psr muldiv: %08x\n", regs->psr); -#endif - } - advance(regs); - return 0; -}
diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 4ee8ce0..185aa96 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c
@@ -356,7 +356,7 @@ op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs); for (i = 0; i < op->archdata.num_irqs; i++) op->archdata.irqs[i] = - sparc_irq_config.build_device_irq(op, intr[i].pri); + sparc_config.build_device_irq(op, intr[i].pri); } else { const unsigned int *irq = of_get_property(dp, "interrupts", &len); @@ -365,7 +365,7 @@ op->archdata.num_irqs = len / sizeof(unsigned int); for (i = 0; i < op->archdata.num_irqs; i++) op->archdata.irqs[i] = - sparc_irq_config.build_device_irq(op, irq[i]); + sparc_config.build_device_irq(op, irq[i]); } else { op->archdata.num_irqs = 0; }
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index fcc148e..ded3f60 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c
@@ -703,31 +703,28 @@ pcic_timer_dummy = readl(pcic0.pcic_regs+PCI_SYS_LIMIT); } -static irqreturn_t pcic_timer_handler (int irq, void *h) -{ - pcic_clear_clock_irq(); - xtime_update(1); -#ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); -#endif - return IRQ_HANDLED; -} +/* CPU frequency is 100 MHz, timer increments every 4 CPU clocks */ +#define USECS_PER_JIFFY (1000000 / HZ) +#define TICK_TIMER_LIMIT ((100 * 1000000 / 4) / HZ) -#define USECS_PER_JIFFY 10000 /* We have 100HZ "standard" timer for sparc */ -#define TICK_TIMER_LIMIT ((100*1000000/4)/100) - -u32 pci_gettimeoffset(void) +static unsigned int pcic_cycles_offset(void) { + u32 value, count; + + value = readl(pcic0.pcic_regs + PCI_SYS_COUNTER); + count = value & ~PCI_SYS_COUNTER_OVERFLOW; + + if (value & PCI_SYS_COUNTER_OVERFLOW) + count += TICK_TIMER_LIMIT; /* - * We divide all by 100 + * We divide all by HZ * to have microsecond resolution and to avoid overflow */ - unsigned long count = - readl(pcic0.pcic_regs+PCI_SYS_COUNTER) & ~PCI_SYS_COUNTER_OVERFLOW; - count = ((count/100)*USECS_PER_JIFFY) / (TICK_TIMER_LIMIT/100); - return count * 1000; -} + count = ((count / HZ) * USECS_PER_JIFFY) / (TICK_TIMER_LIMIT / HZ); + /* Coordinate with the sparc_config.clock_rate setting */ + return count * 2; +} void __init pci_time_init(void) { @@ -736,9 +733,16 @@ int timer_irq, irq; int err; - do_arch_gettimeoffset = pci_gettimeoffset; - - btfixup(); +#ifndef CONFIG_SMP + /* + * The clock_rate is in SBUS dimension. + * We take into account this in pcic_cycles_offset() + */ + sparc_config.clock_rate = SBUS_CLOCK_RATE / HZ; + sparc_config.features |= FEAT_L10_CLOCKEVENT; +#endif + sparc_config.features |= FEAT_L10_CLOCKSOURCE; + sparc_config.get_cycles_offset = pcic_cycles_offset; writel (TICK_TIMER_LIMIT, pcic->pcic_regs+PCI_SYS_LIMIT); /* PROM should set appropriate irq */ @@ -747,7 +751,7 @@ writel (PCI_COUNTER_IRQ_SET(timer_irq, 0), pcic->pcic_regs+PCI_COUNTER_IRQ); irq = pcic_build_device_irq(NULL, timer_irq); - err = request_irq(irq, pcic_timer_handler, + err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL); if (err) { prom_printf("time_init: unable to attach IRQ%d\n", timer_irq); @@ -875,10 +879,9 @@ void __init sun4m_pci_init_IRQ(void) { - sparc_irq_config.build_device_irq = pcic_build_device_irq; - - BTFIXUPSET_CALL(clear_clock_irq, pcic_clear_clock_irq, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(load_profile_irq, pcic_load_profile_irq, BTFIXUPCALL_NORM); + sparc_config.build_device_irq = pcic_build_device_irq; + sparc_config.clear_clock_irq = pcic_clear_clock_irq; + sparc_config.load_profile_irq = pcic_load_profile_irq; } int pcibios_assign_resource(struct pci_dev *pdev, int resource)
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index efa0754..fe6787c 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c
@@ -67,8 +67,6 @@ #ifndef CONFIG_SMP -#define SUN4C_FAULT_HIGH 100 - /* * the idle loop on a Sparc... ;) */ @@ -76,36 +74,6 @@ { /* endless idle loop with no priority at all */ for (;;) { - if (ARCH_SUN4C) { - static int count = HZ; - static unsigned long last_jiffies; - static unsigned long last_faults; - static unsigned long fps; - unsigned long now; - unsigned long faults; - - extern unsigned long sun4c_kernel_faults; - extern void sun4c_grow_kernel_ring(void); - - local_irq_disable(); - now = jiffies; - count -= (now - last_jiffies); - last_jiffies = now; - if (count < 0) { - count += HZ; - faults = sun4c_kernel_faults; - fps = (fps + (faults - last_faults)) >> 1; - last_faults = faults; -#if 0 - printk("kernel faults / second = %ld\n", fps); -#endif - if (fps >= SUN4C_FAULT_HIGH) { - sun4c_grow_kernel_ring(); - } - } - local_irq_enable(); - } - if (pm_idle) { while (!need_resched()) (*pm_idle)(); @@ -114,7 +82,6 @@ cpu_relax(); } schedule_preempt_disabled(); - check_pgt_cache(); } } @@ -137,7 +104,6 @@ cpu_relax(); } schedule_preempt_disabled(); - check_pgt_cache(); } } @@ -179,88 +145,6 @@ machine_halt(); } -#if 0 - -static DEFINE_SPINLOCK(sparc_backtrace_lock); - -void __show_backtrace(unsigned long fp) -{ - struct reg_window32 *rw; - unsigned long flags; - int cpu = smp_processor_id(); - - spin_lock_irqsave(&sparc_backtrace_lock, flags); - - rw = (struct reg_window32 *)fp; - while(rw && (((unsigned long) rw) >= PAGE_OFFSET) && - !(((unsigned long) rw) & 0x7)) { - printk("CPU[%d]: ARGS[%08lx,%08lx,%08lx,%08lx,%08lx,%08lx] " - "FP[%08lx] CALLER[%08lx]: ", cpu, - rw->ins[0], rw->ins[1], rw->ins[2], rw->ins[3], - rw->ins[4], rw->ins[5], - rw->ins[6], - rw->ins[7]); - printk("%pS\n", (void *) rw->ins[7]); - rw = (struct reg_window32 *) rw->ins[6]; - } - spin_unlock_irqrestore(&sparc_backtrace_lock, flags); -} - -#define __SAVE __asm__ __volatile__("save %sp, -0x40, %sp\n\t") -#define __RESTORE __asm__ __volatile__("restore %g0, %g0, %g0\n\t") -#define __GET_FP(fp) __asm__ __volatile__("mov %%i6, %0" : "=r" (fp)) - -void show_backtrace(void) -{ - unsigned long fp; - - __SAVE; __SAVE; __SAVE; __SAVE; - __SAVE; __SAVE; __SAVE; __SAVE; - __RESTORE; __RESTORE; __RESTORE; __RESTORE; - __RESTORE; __RESTORE; __RESTORE; __RESTORE; - - __GET_FP(fp); - - __show_backtrace(fp); -} - -#ifdef CONFIG_SMP -void smp_show_backtrace_all_cpus(void) -{ - xc0((smpfunc_t) show_backtrace); - show_backtrace(); -} -#endif - -void show_stackframe(struct sparc_stackf *sf) -{ - unsigned long size; - unsigned long *stk; - int i; - - printk("l0: %08lx l1: %08lx l2: %08lx l3: %08lx " - "l4: %08lx l5: %08lx l6: %08lx l7: %08lx\n", - sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3], - sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]); - printk("i0: %08lx i1: %08lx i2: %08lx i3: %08lx " - "i4: %08lx i5: %08lx fp: %08lx i7: %08lx\n", - sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3], - sf->ins[4], sf->ins[5], (unsigned long)sf->fp, sf->callers_pc); - printk("sp: %08lx x0: %08lx x1: %08lx x2: %08lx " - "x3: %08lx x4: %08lx x5: %08lx xx: %08lx\n", - (unsigned long)sf->structptr, sf->xargs[0], sf->xargs[1], - sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5], - sf->xxargs[0]); - size = ((unsigned long)sf->fp) - ((unsigned long)sf); - size -= STACKFRAME_SZ; - stk = (unsigned long *)((unsigned long)sf + STACKFRAME_SZ); - i = 0; - do { - printk("s%d: %08lx\n", i++, *stk++); - } while ((size -= sizeof(unsigned long))); -} -#endif - void show_regs(struct pt_regs *r) { struct reg_window32 *rw = (struct reg_window32 *) r->u_regs[14];
diff --git a/arch/sparc/kernel/rtrap_32.S b/arch/sparc/kernel/rtrap_32.S index 5f5f74c..7abc24e 100644 --- a/arch/sparc/kernel/rtrap_32.S +++ b/arch/sparc/kernel/rtrap_32.S
@@ -128,13 +128,12 @@ wr %glob_tmp, 0x0, %wim - /* Here comes the architecture specific - * branch to the user stack checking routine - * for return from traps. - */ - .globl rtrap_mmu_patchme -rtrap_mmu_patchme: b sun4c_rett_stackchk - andcc %fp, 0x7, %g0 + /* Here comes the architecture specific + * branch to the user stack checking routine + * for return from traps. + */ + b srmmu_rett_stackchk + andcc %fp, 0x7, %g0 ret_trap_userwins_ok: LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc) @@ -225,69 +224,6 @@ b signal_p ld [%curptr + TI_FLAGS], %g2 -sun4c_rett_stackchk: - be 1f - and %fp, 0xfff, %g1 ! delay slot - - b ret_trap_user_stack_is_bolixed + 0x4 - wr %t_wim, 0x0, %wim - - /* See if we have to check the sanity of one page or two */ -1: - add %g1, 0x38, %g1 - sra %fp, 29, %g2 - add %g2, 0x1, %g2 - andncc %g2, 0x1, %g0 - be 1f - andncc %g1, 0xff8, %g0 - - /* %sp is in vma hole, yuck */ - b ret_trap_user_stack_is_bolixed + 0x4 - wr %t_wim, 0x0, %wim - -1: - be sun4c_rett_onepage /* Only one page to check */ - lda [%fp] ASI_PTE, %g2 - -sun4c_rett_twopages: - add %fp, 0x38, %g1 - sra %g1, 29, %g2 - add %g2, 0x1, %g2 - andncc %g2, 0x1, %g0 - be 1f - lda [%g1] ASI_PTE, %g2 - - /* Second page is in vma hole */ - b ret_trap_user_stack_is_bolixed + 0x4 - wr %t_wim, 0x0, %wim - -1: - srl %g2, 29, %g2 - andcc %g2, 0x4, %g0 - bne sun4c_rett_onepage - lda [%fp] ASI_PTE, %g2 - - /* Second page has bad perms */ - b ret_trap_user_stack_is_bolixed + 0x4 - wr %t_wim, 0x0, %wim - -sun4c_rett_onepage: - srl %g2, 29, %g2 - andcc %g2, 0x4, %g0 - bne,a 1f - restore %g0, %g0, %g0 - - /* A page had bad page permissions, losing... */ - b ret_trap_user_stack_is_bolixed + 0x4 - wr %t_wim, 0x0, %wim - - /* Whee, things are ok, load the window and continue. */ -1: - LOAD_WINDOW(sp) - - b ret_trap_userwins_ok - save %g0, %g0, %g0 - .globl srmmu_rett_stackchk srmmu_rett_stackchk: bne ret_trap_user_stack_is_bolixed
diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index 9171fc2..afa2a9e 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S
@@ -73,18 +73,8 @@ .globl rtrap_irq, rtrap, irqsz_patchme, rtrap_xcall rtrap_irq: rtrap: -#ifndef CONFIG_SMP - sethi %hi(__cpu_data), %l0 - lduw [%l0 + %lo(__cpu_data)], %l1 -#else - sethi %hi(__cpu_data), %l0 - or %l0, %lo(__cpu_data), %l0 - lduw [%l0 + %g5], %l1 -#endif - cmp %l1, 0 - /* mm/ultra.S:xcall_report_regs KNOWS about this load. */ - ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 + ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 rtrap_xcall: sethi %hi(0xf << 20), %l4 and %l1, %l4, %l4
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index d444468..c052313 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c
@@ -42,7 +42,6 @@ #include <asm/vaddrs.h> #include <asm/mbus.h> #include <asm/idprom.h> -#include <asm/machines.h> #include <asm/cpudata.h> #include <asm/setup.h> #include <asm/cacheflush.h> @@ -106,7 +105,6 @@ /* which CPU booted us (0xff = not set) */ unsigned char boot_cpu_id = 0xff; /* 0xff will make it into DATA section... */ -unsigned char boot_cpu_id4; /* boot_cpu_id << 2 */ static void prom_console_write(struct console *con, const char *s, unsigned n) @@ -182,13 +180,6 @@ } } -/* This routine will in the future do all the nasty prom stuff - * to probe for the mmu type and its parameters, etc. This will - * also be where SMP things happen. - */ - -extern void sun4c_probe_vac(void); - extern unsigned short root_flags; extern unsigned short root_dev; extern unsigned short ram_flags; @@ -200,6 +191,52 @@ char reboot_command[COMMAND_LINE_SIZE]; +struct cpuid_patch_entry { + unsigned int addr; + unsigned int sun4d[3]; + unsigned int leon[3]; +}; +extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; + +static void __init per_cpu_patch(void) +{ + struct cpuid_patch_entry *p; + + if (sparc_cpu_model == sun4m) { + /* Nothing to do, this is what the unpatched code + * targets. + */ + return; + } + + p = &__cpuid_patch; + while (p < &__cpuid_patch_end) { + unsigned long addr = p->addr; + unsigned int *insns; + + switch (sparc_cpu_model) { + case sun4d: + insns = &p->sun4d[0]; + break; + + case sparc_leon: + insns = &p->leon[0]; + break; + default: + prom_printf("Unknown cpu type, halting.\n"); + prom_halt(); + } + *(unsigned int *) (addr + 0) = insns[0]; + flushi(addr + 0); + *(unsigned int *) (addr + 4) = insns[1]; + flushi(addr + 4); + *(unsigned int *) (addr + 8) = insns[2]; + flushi(addr + 8); + + p++; + } +} + enum sparc_cpu sparc_cpu_model; EXPORT_SYMBOL(sparc_cpu_model); @@ -225,10 +262,6 @@ /* Set sparc_cpu_model */ sparc_cpu_model = sun_unknown; - if (!strcmp(&cputypval[0], "sun4 ")) - sparc_cpu_model = sun4; - if (!strcmp(&cputypval[0], "sun4c")) - sparc_cpu_model = sun4c; if (!strcmp(&cputypval[0], "sun4m")) sparc_cpu_model = sun4m; if (!strcmp(&cputypval[0], "sun4s")) @@ -244,12 +277,6 @@ printk("ARCH: "); switch(sparc_cpu_model) { - case sun4: - printk("SUN4\n"); - break; - case sun4c: - printk("SUN4C\n"); - break; case sun4m: printk("SUN4M\n"); break; @@ -275,8 +302,6 @@ #endif idprom_init(); - if (ARCH_SUN4C) - sun4c_probe_vac(); load_mmu(); phys_base = 0xffffffffUL; @@ -313,6 +338,9 @@ init_mm.context = (unsigned long) NO_CONTEXT; init_task.thread.kregs = &fake_swapper_regs; + /* Run-time patch instructions to match the cpu model */ + per_cpu_patch(); + paging_init(); smp_setup_cpu_possible_map();
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 1e750e41..ac8e66b5 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c
@@ -217,12 +217,9 @@ /* Checks if the fp is valid */ static inline int invalid_frame_pointer(void __user *fp, int fplen) { - if ((((unsigned long) fp) & 7) || - !__access_ok((unsigned long)fp, fplen) || - ((sparc_cpu_model == sun4 || sparc_cpu_model == sun4c) && - ((unsigned long) fp < 0xe0000000 && (unsigned long) fp >= 0x20000000))) + if ((((unsigned long) fp) & 7) || !__access_ok((unsigned long)fp, fplen)) return 1; - + return 0; }
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c index f671e7f..5771375 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c
@@ -40,6 +40,8 @@ cpumask_t smp_commenced_mask = CPU_MASK_NONE; +const struct sparc32_ipi_ops *sparc32_ipi_ops; + /* The only guaranteed locking primitive available on all Sparc * processors is 'ldstub [%reg + immediate], %dest_reg' which atomically * places the current byte at the effective address into dest_reg and @@ -85,14 +87,6 @@ (bogosum/(5000/HZ))%100); switch(sparc_cpu_model) { - case sun4: - printk("SUN4\n"); - BUG(); - break; - case sun4c: - printk("SUN4C\n"); - BUG(); - break; case sun4m: smp4m_smp_done(); break; @@ -132,7 +126,7 @@ * a single CPU. The trap handler needs only to do trap entry/return * to call schedule. */ - BTFIXUP_CALL(smp_ipi_resched)(cpu); + sparc32_ipi_ops->resched(cpu); } void smp_send_stop(void) @@ -142,7 +136,7 @@ void arch_send_call_function_single_ipi(int cpu) { /* trigger one IPI single call on one CPU */ - BTFIXUP_CALL(smp_ipi_single)(cpu); + sparc32_ipi_ops->single(cpu); } void arch_send_call_function_ipi_mask(const struct cpumask *mask) @@ -151,7 +145,7 @@ /* trigger IPI mask call on each CPU */ for_each_cpu(cpu, mask) - BTFIXUP_CALL(smp_ipi_mask_one)(cpu); + sparc32_ipi_ops->mask_one(cpu); } void smp_resched_interrupt(void) @@ -179,150 +173,9 @@ irq_exit(); } -void smp_flush_cache_all(void) -{ - xc0((smpfunc_t) BTFIXUP_CALL(local_flush_cache_all)); - local_flush_cache_all(); -} - -void smp_flush_tlb_all(void) -{ - xc0((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_all)); - local_flush_tlb_all(); -} - -void smp_flush_cache_mm(struct mm_struct *mm) -{ - if(mm->context != NO_CONTEXT) { - cpumask_t cpu_mask; - cpumask_copy(&cpu_mask, mm_cpumask(mm)); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - if (!cpumask_empty(&cpu_mask)) - xc1((smpfunc_t) BTFIXUP_CALL(local_flush_cache_mm), (unsigned long) mm); - local_flush_cache_mm(mm); - } -} - -void smp_flush_tlb_mm(struct mm_struct *mm) -{ - if(mm->context != NO_CONTEXT) { - cpumask_t cpu_mask; - cpumask_copy(&cpu_mask, mm_cpumask(mm)); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - if (!cpumask_empty(&cpu_mask)) { - xc1((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_mm), (unsigned long) mm); - if(atomic_read(&mm->mm_users) == 1 && current->active_mm == mm) - cpumask_copy(mm_cpumask(mm), - cpumask_of(smp_processor_id())); - } - local_flush_tlb_mm(mm); - } -} - -void smp_flush_cache_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - - if (mm->context != NO_CONTEXT) { - cpumask_t cpu_mask; - cpumask_copy(&cpu_mask, mm_cpumask(mm)); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - if (!cpumask_empty(&cpu_mask)) - xc3((smpfunc_t) BTFIXUP_CALL(local_flush_cache_range), (unsigned long) vma, start, end); - local_flush_cache_range(vma, start, end); - } -} - -void smp_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - - if (mm->context != NO_CONTEXT) { - cpumask_t cpu_mask; - cpumask_copy(&cpu_mask, mm_cpumask(mm)); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - if (!cpumask_empty(&cpu_mask)) - xc3((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_range), (unsigned long) vma, start, end); - local_flush_tlb_range(vma, start, end); - } -} - -void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - - if(mm->context != NO_CONTEXT) { - cpumask_t cpu_mask; - cpumask_copy(&cpu_mask, mm_cpumask(mm)); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - if (!cpumask_empty(&cpu_mask)) - xc2((smpfunc_t) BTFIXUP_CALL(local_flush_cache_page), (unsigned long) vma, page); - local_flush_cache_page(vma, page); - } -} - -void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - - if(mm->context != NO_CONTEXT) { - cpumask_t cpu_mask; - cpumask_copy(&cpu_mask, mm_cpumask(mm)); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - if (!cpumask_empty(&cpu_mask)) - xc2((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_page), (unsigned long) vma, page); - local_flush_tlb_page(vma, page); - } -} - -void smp_flush_page_to_ram(unsigned long page) -{ - /* Current theory is that those who call this are the one's - * who have just dirtied their cache with the pages contents - * in kernel space, therefore we only run this on local cpu. - * - * XXX This experiment failed, research further... -DaveM - */ -#if 1 - xc1((smpfunc_t) BTFIXUP_CALL(local_flush_page_to_ram), page); -#endif - local_flush_page_to_ram(page); -} - -void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) -{ - cpumask_t cpu_mask; - cpumask_copy(&cpu_mask, mm_cpumask(mm)); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - if (!cpumask_empty(&cpu_mask)) - xc2((smpfunc_t) BTFIXUP_CALL(local_flush_sig_insns), (unsigned long) mm, insn_addr); - local_flush_sig_insns(mm, insn_addr); -} - -extern unsigned int lvl14_resolution; - -/* /proc/profile writes can call this, don't __init it please. */ -static DEFINE_SPINLOCK(prof_setup_lock); - int setup_profiling_timer(unsigned int multiplier) { - int i; - unsigned long flags; - - /* Prevent level14 ticker IRQ flooding. */ - if((!multiplier) || (lvl14_resolution / multiplier) < 500) - return -EINVAL; - - spin_lock_irqsave(&prof_setup_lock, flags); - for_each_possible_cpu(i) { - load_profile_irq(i, lvl14_resolution / multiplier); - prof_multiplier(i) = multiplier; - } - spin_unlock_irqrestore(&prof_setup_lock, flags); - - return 0; + return -EINVAL; } void __init smp_prepare_cpus(unsigned int max_cpus) @@ -345,14 +198,6 @@ smp_store_cpu_info(boot_cpu_id); switch(sparc_cpu_model) { - case sun4: - printk("SUN4\n"); - BUG(); - break; - case sun4c: - printk("SUN4C\n"); - BUG(); - break; case sun4m: smp4m_boot_cpus(); break; @@ -418,14 +263,6 @@ int ret=0; switch(sparc_cpu_model) { - case sun4: - printk("SUN4\n"); - BUG(); - break; - case sun4c: - printk("SUN4C\n"); - BUG(); - break; case sun4m: ret = smp4m_boot_one_cpu(cpu); break;
diff --git a/arch/sparc/kernel/sparc_ksyms_32.c b/arch/sparc/kernel/sparc_ksyms_32.c index baeab87..e521c54 100644 --- a/arch/sparc/kernel/sparc_ksyms_32.c +++ b/arch/sparc/kernel/sparc_ksyms_32.c
@@ -28,19 +28,5 @@ EXPORT_SYMBOL(__ret_efault); EXPORT_SYMBOL(empty_zero_page); -/* Defined using magic */ -#ifndef CONFIG_SMP -EXPORT_SYMBOL(BTFIXUP_CALL(___xchg32)); -#else -EXPORT_SYMBOL(BTFIXUP_CALL(__hard_smp_processor_id)); -#endif -EXPORT_SYMBOL(BTFIXUP_CALL(mmu_unlockarea)); -EXPORT_SYMBOL(BTFIXUP_CALL(mmu_lockarea)); -EXPORT_SYMBOL(BTFIXUP_CALL(mmu_get_scsi_sgl)); -EXPORT_SYMBOL(BTFIXUP_CALL(mmu_get_scsi_one)); -EXPORT_SYMBOL(BTFIXUP_CALL(mmu_release_scsi_sgl)); -EXPORT_SYMBOL(BTFIXUP_CALL(mmu_release_scsi_one)); -EXPORT_SYMBOL(BTFIXUP_CALL(pgprot_noncached)); - /* Exporting a symbol from /init/main.c */ EXPORT_SYMBOL(saved_command_line);
diff --git a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c deleted file mode 100644 index f6bf25a..0000000 --- a/arch/sparc/kernel/sun4c_irq.c +++ /dev/null
@@ -1,264 +0,0 @@ -/* - * sun4c irq support - * - * djhr: Hacked out of irq.c into a CPU dependent version. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) - * Copyright (C) 1995 Pete A. Zaitcev (zaitcev@yahoo.com) - * Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk) - */ - -#include <linux/init.h> - -#include <asm/oplib.h> -#include <asm/timer.h> -#include <asm/irq.h> -#include <asm/io.h> - -#include "irq.h" - -/* Sun4c interrupts are typically laid out as follows: - * - * 1 - Software interrupt, SBUS level 1 - * 2 - SBUS level 2 - * 3 - ESP SCSI, SBUS level 3 - * 4 - Software interrupt - * 5 - Lance ethernet, SBUS level 4 - * 6 - Software interrupt - * 7 - Graphics card, SBUS level 5 - * 8 - SBUS level 6 - * 9 - SBUS level 7 - * 10 - Counter timer - * 11 - Floppy - * 12 - Zilog uart - * 13 - CS4231 audio - * 14 - Profiling timer - * 15 - NMI - * - * The interrupt enable bits in the interrupt mask register are - * really only used to enable/disable the timer interrupts, and - * for signalling software interrupts. There is also a master - * interrupt enable bit in this register. - * - * Interrupts are enabled by setting the SUN4C_INT_* bits, they - * are disabled by clearing those bits. - */ - -/* - * Bit field defines for the interrupt registers on various - * Sparc machines. - */ - -/* The sun4c interrupt register. */ -#define SUN4C_INT_ENABLE 0x01 /* Allow interrupts. */ -#define SUN4C_INT_E14 0x80 /* Enable level 14 IRQ. */ -#define SUN4C_INT_E10 0x20 /* Enable level 10 IRQ. */ -#define SUN4C_INT_E8 0x10 /* Enable level 8 IRQ. */ -#define SUN4C_INT_E6 0x08 /* Enable level 6 IRQ. */ -#define SUN4C_INT_E4 0x04 /* Enable level 4 IRQ. */ -#define SUN4C_INT_E1 0x02 /* Enable level 1 IRQ. */ - -/* - * Pointer to the interrupt enable byte - * Used by entry.S - */ -unsigned char __iomem *interrupt_enable; - -static void sun4c_mask_irq(struct irq_data *data) -{ - unsigned long mask = (unsigned long)data->chip_data; - - if (mask) { - unsigned long flags; - - local_irq_save(flags); - mask = sbus_readb(interrupt_enable) & ~mask; - sbus_writeb(mask, interrupt_enable); - local_irq_restore(flags); - } -} - -static void sun4c_unmask_irq(struct irq_data *data) -{ - unsigned long mask = (unsigned long)data->chip_data; - - if (mask) { - unsigned long flags; - - local_irq_save(flags); - mask = sbus_readb(interrupt_enable) | mask; - sbus_writeb(mask, interrupt_enable); - local_irq_restore(flags); - } -} - -static unsigned int sun4c_startup_irq(struct irq_data *data) -{ - irq_link(data->irq); - sun4c_unmask_irq(data); - - return 0; -} - -static void sun4c_shutdown_irq(struct irq_data *data) -{ - sun4c_mask_irq(data); - irq_unlink(data->irq); -} - -static struct irq_chip sun4c_irq = { - .name = "sun4c", - .irq_startup = sun4c_startup_irq, - .irq_shutdown = sun4c_shutdown_irq, - .irq_mask = sun4c_mask_irq, - .irq_unmask = sun4c_unmask_irq, -}; - -static unsigned int sun4c_build_device_irq(struct platform_device *op, - unsigned int real_irq) -{ - unsigned int irq; - - if (real_irq >= 16) { - prom_printf("Bogus sun4c IRQ %u\n", real_irq); - prom_halt(); - } - - irq = irq_alloc(real_irq, real_irq); - if (irq) { - unsigned long mask = 0UL; - - switch (real_irq) { - case 1: - mask = SUN4C_INT_E1; - break; - case 8: - mask = SUN4C_INT_E8; - break; - case 10: - mask = SUN4C_INT_E10; - break; - case 14: - mask = SUN4C_INT_E14; - break; - default: - /* All the rest are either always enabled, - * or are for signalling software interrupts. - */ - break; - } - irq_set_chip_and_handler_name(irq, &sun4c_irq, - handle_level_irq, "level"); - irq_set_chip_data(irq, (void *)mask); - } - return irq; -} - -struct sun4c_timer_info { - u32 l10_count; - u32 l10_limit; - u32 l14_count; - u32 l14_limit; -}; - -static struct sun4c_timer_info __iomem *sun4c_timers; - -static void sun4c_clear_clock_irq(void) -{ - sbus_readl(&sun4c_timers->l10_limit); -} - -static void sun4c_load_profile_irq(int cpu, unsigned int limit) -{ - /* Errm.. not sure how to do this.. */ -} - -static void __init sun4c_init_timers(irq_handler_t counter_fn) -{ - const struct linux_prom_irqs *prom_irqs; - struct device_node *dp; - unsigned int irq; - const u32 *addr; - int err; - - dp = of_find_node_by_name(NULL, "counter-timer"); - if (!dp) { - prom_printf("sun4c_init_timers: Unable to find counter-timer\n"); - prom_halt(); - } - - addr = of_get_property(dp, "address", NULL); - if (!addr) { - prom_printf("sun4c_init_timers: No address property\n"); - prom_halt(); - } - - sun4c_timers = (void __iomem *) (unsigned long) addr[0]; - - prom_irqs = of_get_property(dp, "intr", NULL); - of_node_put(dp); - if (!prom_irqs) { - prom_printf("sun4c_init_timers: No intr property\n"); - prom_halt(); - } - - /* Have the level 10 timer tick at 100HZ. We don't touch the - * level 14 timer limit since we are letting the prom handle - * them until we have a real console driver so L1-A works. - */ - sbus_writel((((1000000/HZ) + 1) << 10), &sun4c_timers->l10_limit); - - master_l10_counter = &sun4c_timers->l10_count; - - irq = sun4c_build_device_irq(NULL, prom_irqs[0].pri); - err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL); - if (err) { - prom_printf("sun4c_init_timers: request_irq() fails with %d\n", err); - prom_halt(); - } - - /* disable timer interrupt */ - sun4c_mask_irq(irq_get_irq_data(irq)); -} - -#ifdef CONFIG_SMP -static void sun4c_nop(void) -{ -} -#endif - -void __init sun4c_init_IRQ(void) -{ - struct device_node *dp; - const u32 *addr; - - dp = of_find_node_by_name(NULL, "interrupt-enable"); - if (!dp) { - prom_printf("sun4c_init_IRQ: Unable to find interrupt-enable\n"); - prom_halt(); - } - - addr = of_get_property(dp, "address", NULL); - of_node_put(dp); - if (!addr) { - prom_printf("sun4c_init_IRQ: No address property\n"); - prom_halt(); - } - - interrupt_enable = (void __iomem *) (unsigned long) addr[0]; - - BTFIXUPSET_CALL(clear_clock_irq, sun4c_clear_clock_irq, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(load_profile_irq, sun4c_load_profile_irq, BTFIXUPCALL_NOP); - - sparc_irq_config.init_timers = sun4c_init_timers; - sparc_irq_config.build_device_irq = sun4c_build_device_irq; - -#ifdef CONFIG_SMP - BTFIXUPSET_CALL(set_cpu_int, sun4c_nop, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(clear_cpu_int, sun4c_nop, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(set_irq_udt, sun4c_nop, BTFIXUPCALL_NOP); -#endif - sbus_writeb(SUN4C_INT_ENABLE, interrupt_enable); - /* Cannot enable interrupts until OBP ticker is disabled. */ -}
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index 1d13c5b..e490ac9 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c
@@ -15,6 +15,7 @@ #include <asm/sbi.h> #include <asm/cacheflush.h> #include <asm/setup.h> +#include <asm/oplib.h> #include "kernel.h" #include "irq.h" @@ -243,19 +244,6 @@ }; #ifdef CONFIG_SMP -static void sun4d_set_cpu_int(int cpu, int level) -{ - sun4d_send_ipi(cpu, level); -} - -static void sun4d_clear_ipi(int cpu, int level) -{ -} - -static void sun4d_set_udt(int cpu) -{ -} - /* Setup IRQ distribution scheme. */ void __init sun4d_distribute_irqs(void) { @@ -282,7 +270,8 @@ static void sun4d_load_profile_irq(int cpu, unsigned int limit) { - bw_set_prof_limit(cpu, limit); + unsigned int value = limit ? timer_value(limit) : 0; + bw_set_prof_limit(cpu, value); } static void __init sun4d_load_profile_irqs(void) @@ -418,12 +407,12 @@ trap_table->inst_two = lvl14_save[1]; trap_table->inst_three = lvl14_save[2]; trap_table->inst_four = lvl14_save[3]; - local_flush_cache_all(); + local_ops->cache_all(); local_irq_restore(flags); #endif } -static void __init sun4d_init_timers(irq_handler_t counter_fn) +static void __init sun4d_init_timers(void) { struct device_node *dp; struct resource res; @@ -466,12 +455,20 @@ prom_halt(); } - sbus_writel((((1000000/HZ) + 1) << 10), &sun4d_timers->l10_timer_limit); +#ifdef CONFIG_SMP + sparc_config.cs_period = SBUS_CLOCK_RATE * 2; /* 2 seconds */ +#else + sparc_config.cs_period = SBUS_CLOCK_RATE / HZ; /* 1/HZ sec */ + sparc_config.features |= FEAT_L10_CLOCKEVENT; +#endif + sparc_config.features |= FEAT_L10_CLOCKSOURCE; + sbus_writel(timer_value(sparc_config.cs_period), + &sun4d_timers->l10_timer_limit); master_l10_counter = &sun4d_timers->l10_cur_count; irq = sun4d_build_timer_irq(board, SUN4D_TIMER_IRQ); - err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL); + err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL); if (err) { prom_printf("sun4d_init_timers: request_irq() failed with %d\n", err); @@ -509,16 +506,11 @@ { local_irq_disable(); - BTFIXUPSET_CALL(clear_clock_irq, sun4d_clear_clock_irq, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(load_profile_irq, sun4d_load_profile_irq, BTFIXUPCALL_NORM); + sparc_config.init_timers = sun4d_init_timers; + sparc_config.build_device_irq = sun4d_build_device_irq; + sparc_config.clock_rate = SBUS_CLOCK_RATE; + sparc_config.clear_clock_irq = sun4d_clear_clock_irq; + sparc_config.load_profile_irq = sun4d_load_profile_irq; - sparc_irq_config.init_timers = sun4d_init_timers; - sparc_irq_config.build_device_irq = sun4d_build_device_irq; - -#ifdef CONFIG_SMP - BTFIXUPSET_CALL(set_cpu_int, sun4d_set_cpu_int, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(clear_cpu_int, sun4d_clear_ipi, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(set_irq_udt, sun4d_set_udt, BTFIXUPCALL_NOP); -#endif /* Cannot enable interrupts until OBP ticker is disabled. */ }
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index 540b2fe..f9a1a33 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c
@@ -6,16 +6,20 @@ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) */ +#include <linux/clockchips.h> #include <linux/interrupt.h> #include <linux/profile.h> #include <linux/delay.h> +#include <linux/sched.h> #include <linux/cpu.h> +#include <asm/cacheflush.h> +#include <asm/switch_to.h> +#include <asm/tlbflush.h> +#include <asm/timer.h> +#include <asm/oplib.h> #include <asm/sbi.h> #include <asm/mmu.h> -#include <asm/tlbflush.h> -#include <asm/switch_to.h> -#include <asm/cacheflush.h> #include "kernel.h" #include "irq.h" @@ -34,7 +38,6 @@ } static void smp4d_ipi_init(void); -static void smp_setup_percpu_timer(void); static unsigned char cpu_leds[32]; @@ -49,7 +52,7 @@ void __cpuinit smp4d_callin(void) { - int cpuid = hard_smp4d_processor_id(); + int cpuid = hard_smp_processor_id(); unsigned long flags; /* Show we are alive */ @@ -59,8 +62,8 @@ /* Enable level15 interrupt, disable level14 interrupt for now */ cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000); - local_flush_cache_all(); - local_flush_tlb_all(); + local_ops->cache_all(); + local_ops->tlb_all(); notify_cpu_starting(cpuid); /* @@ -70,17 +73,17 @@ * to call the scheduler code. */ /* Get our local ticker going. */ - smp_setup_percpu_timer(); + register_percpu_ce(cpuid); calibrate_delay(); smp_store_cpu_info(cpuid); - local_flush_cache_all(); - local_flush_tlb_all(); + local_ops->cache_all(); + local_ops->tlb_all(); /* Allow master to continue. */ sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); - local_flush_cache_all(); - local_flush_tlb_all(); + local_ops->cache_all(); + local_ops->tlb_all(); while ((unsigned long)current_set[cpuid] < PAGE_OFFSET) barrier(); @@ -100,8 +103,8 @@ atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; - local_flush_cache_all(); - local_flush_tlb_all(); + local_ops->cache_all(); + local_ops->tlb_all(); local_irq_enable(); /* We don't allow PIL 14 yet */ @@ -123,8 +126,7 @@ smp4d_ipi_init(); if (boot_cpu_id) current_set[0] = NULL; - smp_setup_percpu_timer(); - local_flush_cache_all(); + local_ops->cache_all(); } int __cpuinit smp4d_boot_one_cpu(int i) @@ -150,7 +152,7 @@ /* whirrr, whirrr, whirrrrrrrrr... */ printk(KERN_INFO "Starting CPU %d at %p\n", i, entry); - local_flush_cache_all(); + local_ops->cache_all(); prom_startcpu(cpu_node, &smp_penguin_ctable, 0, (char *)entry); @@ -168,7 +170,7 @@ return -ENODEV; } - local_flush_cache_all(); + local_ops->cache_all(); return 0; } @@ -185,7 +187,7 @@ prev = &cpu_data(i).next; } *prev = first; - local_flush_cache_all(); + local_ops->cache_all(); /* Ok, they are spinning and ready to go. */ smp_processors_ready = 1; @@ -233,7 +235,20 @@ } } -static void smp4d_ipi_single(int cpu) +/* +-------+-------------+-----------+------------------------------------+ + * | bcast | devid | sid | levels mask | + * +-------+-------------+-----------+------------------------------------+ + * 31 30 23 22 15 14 0 + */ +#define IGEN_MESSAGE(bcast, devid, sid, levels) \ + (((bcast) << 31) | ((devid) << 23) | ((sid) << 15) | (levels)) + +static void sun4d_send_ipi(int cpu, int level) +{ + cc_set_igen(IGEN_MESSAGE(0, cpu << 3, 6 + ((level >> 1) & 7), 1 << (level - 1))); +} + +static void sun4d_ipi_single(int cpu) { struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu); @@ -244,7 +259,7 @@ sun4d_send_ipi(cpu, SUN4D_IPI_IRQ); } -static void smp4d_ipi_mask_one(int cpu) +static void sun4d_ipi_mask_one(int cpu) { struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu); @@ -255,7 +270,7 @@ sun4d_send_ipi(cpu, SUN4D_IPI_IRQ); } -static void smp4d_ipi_resched(int cpu) +static void sun4d_ipi_resched(int cpu) { struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu); @@ -280,7 +295,7 @@ static DEFINE_SPINLOCK(cross_call_lock); /* Cross calls must be serialized, at least currently. */ -static void smp4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, +static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4) { @@ -352,7 +367,7 @@ /* Running cross calls. */ void smp4d_cross_call_irq(void) { - int i = hard_smp4d_processor_id(); + int i = hard_smp_processor_id(); ccall_info.processors_in[i] = 1; ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, @@ -363,7 +378,8 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs) { struct pt_regs *old_regs; - int cpu = hard_smp4d_processor_id(); + int cpu = hard_smp_processor_id(); + struct clock_event_device *ce; static int cpu_tick[NR_CPUS]; static char led_mask[] = { 0xe, 0xd, 0xb, 0x7, 0xb, 0xd }; @@ -379,45 +395,21 @@ show_leds(cpu); } - profile_tick(CPU_PROFILING); + ce = &per_cpu(sparc32_clockevent, cpu); - if (!--prof_counter(cpu)) { - int user = user_mode(regs); + irq_enter(); + ce->event_handler(ce); + irq_exit(); - irq_enter(); - update_process_times(user); - irq_exit(); - - prof_counter(cpu) = prof_multiplier(cpu); - } set_irq_regs(old_regs); } -static void __cpuinit smp_setup_percpu_timer(void) -{ - int cpu = hard_smp4d_processor_id(); - - prof_counter(cpu) = prof_multiplier(cpu) = 1; - load_profile_irq(cpu, lvl14_resolution); -} - -void __init smp4d_blackbox_id(unsigned *addr) -{ - int rd = *addr & 0x3e000000; - - addr[0] = 0xc0800800 | rd; /* lda [%g0] ASI_M_VIKING_TMP1, reg */ - addr[1] = 0x01000000; /* nop */ - addr[2] = 0x01000000; /* nop */ -} - -void __init smp4d_blackbox_current(unsigned *addr) -{ - int rd = *addr & 0x3e000000; - - addr[0] = 0xc0800800 | rd; /* lda [%g0] ASI_M_VIKING_TMP1, reg */ - addr[2] = 0x81282002 | rd | (rd >> 11); /* sll reg, 2, reg */ - addr[4] = 0x01000000; /* nop */ -} +static const struct sparc32_ipi_ops sun4d_ipi_ops = { + .cross_call = sun4d_cross_call, + .resched = sun4d_ipi_resched, + .single = sun4d_ipi_single, + .mask_one = sun4d_ipi_mask_one, +}; void __init sun4d_init_smp(void) { @@ -426,14 +418,7 @@ /* Patch ipi15 trap table */ t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_sun4d - linux_trap_ipi15_sun4m); - /* And set btfixup... */ - BTFIXUPSET_BLACKBOX(hard_smp_processor_id, smp4d_blackbox_id); - BTFIXUPSET_BLACKBOX(load_current, smp4d_blackbox_current); - BTFIXUPSET_CALL(smp_cross_call, smp4d_cross_call, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(__hard_smp_processor_id, __smp4d_processor_id, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(smp_ipi_resched, smp4d_ipi_resched, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(smp_ipi_single, smp4d_ipi_single, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(smp_ipi_mask_one, smp4d_ipi_mask_one, BTFIXUPCALL_NORM); + sparc32_ipi_ops = &sun4d_ipi_ops; for (i = 0; i < NR_CPUS; i++) { ccall_info.processors_in[i] = 1;
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c index e6116516..c5ade9d 100644 --- a/arch/sparc/kernel/sun4m_irq.c +++ b/arch/sparc/kernel/sun4m_irq.c
@@ -112,9 +112,6 @@ #define SUN4M_INT_E14 0x00000080 #define SUN4M_INT_E10 0x00080000 -#define SUN4M_HARD_INT(x) (0x000000001 << (x)) -#define SUN4M_SOFT_INT(x) (0x000010000 << (x)) - #define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */ #define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */ #define SUN4M_INT_M2S_WRITE_ERR 0x20000000 /* write buffer error */ @@ -282,23 +279,6 @@ return irq; } -#ifdef CONFIG_SMP -static void sun4m_send_ipi(int cpu, int level) -{ - sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set); -} - -static void sun4m_clear_ipi(int cpu, int level) -{ - sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->clear); -} - -static void sun4m_set_udt(int cpu) -{ - sbus_writel(cpu, &sun4m_irq_global->interrupt_target); -} -#endif - struct sun4m_timer_percpu { u32 l14_limit; u32 l14_count; @@ -318,9 +298,6 @@ static struct sun4m_timer_global __iomem *timers_global; - -unsigned int lvl14_resolution = (((1000000/HZ) + 1) << 10); - static void sun4m_clear_clock_irq(void) { sbus_readl(&timers_global->l10_limit); @@ -369,10 +346,11 @@ static void sun4m_load_profile_irq(int cpu, unsigned int limit) { - sbus_writel(limit, &timers_percpu[cpu]->l14_limit); + unsigned int value = limit ? timer_value(limit) : 0; + sbus_writel(value, &timers_percpu[cpu]->l14_limit); } -static void __init sun4m_init_timers(irq_handler_t counter_fn) +static void __init sun4m_init_timers(void) { struct device_node *dp = of_find_node_by_name(NULL, "counter"); int i, err, len, num_cpu_timers; @@ -402,13 +380,22 @@ /* Every per-cpu timer works in timer mode */ sbus_writel(0x00000000, &timers_global->timer_config); - sbus_writel((((1000000/HZ) + 1) << 10), &timers_global->l10_limit); +#ifdef CONFIG_SMP + sparc_config.cs_period = SBUS_CLOCK_RATE * 2; /* 2 seconds */ + sparc_config.features |= FEAT_L14_ONESHOT; +#else + sparc_config.cs_period = SBUS_CLOCK_RATE / HZ; /* 1/HZ sec */ + sparc_config.features |= FEAT_L10_CLOCKEVENT; +#endif + sparc_config.features |= FEAT_L10_CLOCKSOURCE; + sbus_writel(timer_value(sparc_config.cs_period), + &timers_global->l10_limit); master_l10_counter = &timers_global->l10_count; irq = sun4m_build_device_irq(NULL, SUN4M_TIMER_IRQ); - err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL); + err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL); if (err) { printk(KERN_ERR "sun4m_init_timers: Register IRQ error %d.\n", err); @@ -434,7 +421,7 @@ trap_table->inst_two = lvl14_save[1]; trap_table->inst_three = lvl14_save[2]; trap_table->inst_four = lvl14_save[3]; - local_flush_cache_all(); + local_ops->cache_all(); local_irq_restore(flags); } #endif @@ -475,17 +462,12 @@ if (num_cpu_iregs == 4) sbus_writel(0, &sun4m_irq_global->interrupt_target); - BTFIXUPSET_CALL(clear_clock_irq, sun4m_clear_clock_irq, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(load_profile_irq, sun4m_load_profile_irq, BTFIXUPCALL_NORM); + sparc_config.init_timers = sun4m_init_timers; + sparc_config.build_device_irq = sun4m_build_device_irq; + sparc_config.clock_rate = SBUS_CLOCK_RATE; + sparc_config.clear_clock_irq = sun4m_clear_clock_irq; + sparc_config.load_profile_irq = sun4m_load_profile_irq; - sparc_irq_config.init_timers = sun4m_init_timers; - sparc_irq_config.build_device_irq = sun4m_build_device_irq; - -#ifdef CONFIG_SMP - BTFIXUPSET_CALL(set_cpu_int, sun4m_send_ipi, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(clear_cpu_int, sun4m_clear_ipi, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(set_irq_udt, sun4m_set_udt, BTFIXUPCALL_NORM); -#endif /* Cannot enable interrupts until OBP ticker is disabled. */ }
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index 02db9a0..960e8ab 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c
@@ -4,14 +4,18 @@ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) */ +#include <linux/clockchips.h> #include <linux/interrupt.h> #include <linux/profile.h> #include <linux/delay.h> +#include <linux/sched.h> #include <linux/cpu.h> #include <asm/cacheflush.h> #include <asm/switch_to.h> #include <asm/tlbflush.h> +#include <asm/timer.h> +#include <asm/oplib.h> #include "irq.h" #include "kernel.h" @@ -30,26 +34,22 @@ return val; } -static void smp4m_ipi_init(void); -static void smp_setup_percpu_timer(void); - void __cpuinit smp4m_callin(void) { int cpuid = hard_smp_processor_id(); - local_flush_cache_all(); - local_flush_tlb_all(); + local_ops->cache_all(); + local_ops->tlb_all(); notify_cpu_starting(cpuid); - /* Get our local ticker going. */ - smp_setup_percpu_timer(); + register_percpu_ce(cpuid); calibrate_delay(); smp_store_cpu_info(cpuid); - local_flush_cache_all(); - local_flush_tlb_all(); + local_ops->cache_all(); + local_ops->tlb_all(); /* * Unblock the master CPU _only_ when the scheduler state @@ -61,8 +61,8 @@ swap_ulong(&cpu_callin_map[cpuid], 1); /* XXX: What's up with all the flushes? */ - local_flush_cache_all(); - local_flush_tlb_all(); + local_ops->cache_all(); + local_ops->tlb_all(); /* Fix idle thread fields. */ __asm__ __volatile__("ld [%0], %%g6\n\t" @@ -86,9 +86,8 @@ */ void __init smp4m_boot_cpus(void) { - smp4m_ipi_init(); - smp_setup_percpu_timer(); - local_flush_cache_all(); + sun4m_unmask_profile_irq(); + local_ops->cache_all(); } int __cpuinit smp4m_boot_one_cpu(int i) @@ -117,7 +116,7 @@ /* whirrr, whirrr, whirrrrrrrrr... */ printk(KERN_INFO "Starting CPU %d at %p\n", i, entry); - local_flush_cache_all(); + local_ops->cache_all(); prom_startcpu(cpu_node, &smp_penguin_ctable, 0, (char *)entry); /* wheee... it's going... */ @@ -132,7 +131,7 @@ return -ENODEV; } - local_flush_cache_all(); + local_ops->cache_all(); return 0; } @@ -149,30 +148,29 @@ prev = &cpu_data(i).next; } *prev = first; - local_flush_cache_all(); + local_ops->cache_all(); /* Ok, they are spinning and ready to go. */ } - -/* Initialize IPIs on the SUN4M SMP machine */ -static void __init smp4m_ipi_init(void) +static void sun4m_send_ipi(int cpu, int level) { + sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set); } -static void smp4m_ipi_resched(int cpu) +static void sun4m_ipi_resched(int cpu) { - set_cpu_int(cpu, IRQ_IPI_RESCHED); + sun4m_send_ipi(cpu, IRQ_IPI_RESCHED); } -static void smp4m_ipi_single(int cpu) +static void sun4m_ipi_single(int cpu) { - set_cpu_int(cpu, IRQ_IPI_SINGLE); + sun4m_send_ipi(cpu, IRQ_IPI_SINGLE); } -static void smp4m_ipi_mask_one(int cpu) +static void sun4m_ipi_mask_one(int cpu) { - set_cpu_int(cpu, IRQ_IPI_MASK); + sun4m_send_ipi(cpu, IRQ_IPI_MASK); } static struct smp_funcall { @@ -189,7 +187,7 @@ static DEFINE_SPINLOCK(cross_call_lock); /* Cross calls must be serialized, at least currently. */ -static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, +static void sun4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4) { @@ -216,7 +214,7 @@ if (cpumask_test_cpu(i, &mask)) { ccall_info.processors_in[i] = 0; ccall_info.processors_out[i] = 0; - set_cpu_int(i, IRQ_CROSS_CALL); + sun4m_send_ipi(i, IRQ_CROSS_CALL); } else { ccall_info.processors_in[i] = 1; ccall_info.processors_out[i] = 1; @@ -260,64 +258,33 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs) { struct pt_regs *old_regs; + struct clock_event_device *ce; int cpu = smp_processor_id(); old_regs = set_irq_regs(regs); - sun4m_clear_profile_irq(cpu); + ce = &per_cpu(sparc32_clockevent, cpu); - profile_tick(CPU_PROFILING); + if (ce->mode & CLOCK_EVT_MODE_PERIODIC) + sun4m_clear_profile_irq(cpu); + else + sparc_config.load_profile_irq(cpu, 0); /* Is this needless? */ - if (!--prof_counter(cpu)) { - int user = user_mode(regs); + irq_enter(); + ce->event_handler(ce); + irq_exit(); - irq_enter(); - update_process_times(user); - irq_exit(); - - prof_counter(cpu) = prof_multiplier(cpu); - } set_irq_regs(old_regs); } -static void __cpuinit smp_setup_percpu_timer(void) -{ - int cpu = smp_processor_id(); - - prof_counter(cpu) = prof_multiplier(cpu) = 1; - load_profile_irq(cpu, lvl14_resolution); - - if (cpu == boot_cpu_id) - sun4m_unmask_profile_irq(); -} - -static void __init smp4m_blackbox_id(unsigned *addr) -{ - int rd = *addr & 0x3e000000; - int rs1 = rd >> 11; - - addr[0] = 0x81580000 | rd; /* rd %tbr, reg */ - addr[1] = 0x8130200c | rd | rs1; /* srl reg, 0xc, reg */ - addr[2] = 0x80082003 | rd | rs1; /* and reg, 3, reg */ -} - -static void __init smp4m_blackbox_current(unsigned *addr) -{ - int rd = *addr & 0x3e000000; - int rs1 = rd >> 11; - - addr[0] = 0x81580000 | rd; /* rd %tbr, reg */ - addr[2] = 0x8130200a | rd | rs1; /* srl reg, 0xa, reg */ - addr[4] = 0x8008200c | rd | rs1; /* and reg, 0xc, reg */ -} +static const struct sparc32_ipi_ops sun4m_ipi_ops = { + .cross_call = sun4m_cross_call, + .resched = sun4m_ipi_resched, + .single = sun4m_ipi_single, + .mask_one = sun4m_ipi_mask_one, +}; void __init sun4m_init_smp(void) { - BTFIXUPSET_BLACKBOX(hard_smp_processor_id, smp4m_blackbox_id); - BTFIXUPSET_BLACKBOX(load_current, smp4m_blackbox_current); - BTFIXUPSET_CALL(smp_cross_call, smp4m_cross_call, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(__hard_smp_processor_id, __smp4m_processor_id, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(smp_ipi_resched, smp4m_ipi_resched, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(smp_ipi_single, smp4m_ipi_single, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(smp_ipi_mask_one, smp4m_ipi_mask_one, BTFIXUPCALL_NORM); + sparc32_ipi_ops = &sun4m_ipi_ops; }
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c index 42b282f..627e89a 100644 --- a/arch/sparc/kernel/sys_sparc_32.c +++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -53,8 +53,6 @@ /* See asm-sparc/uaccess.h */ if (len > TASK_SIZE - PAGE_SIZE) return -ENOMEM; - if (ARCH_SUN4C && len > 0x20000000) - return -ENOMEM; if (!addr) addr = TASK_UNMAPPED_BASE; @@ -65,10 +63,6 @@ for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { /* At this point: (!vmm || addr < vmm->vm_end). */ - if (ARCH_SUN4C && addr < 0xe0000000 && 0x20000000 - len < addr) { - addr = PAGE_OFFSET; - vmm = find_vma(current->mm, PAGE_OFFSET); - } if (TASK_SIZE - PAGE_SIZE - len < addr) return -ENOMEM; if (!vmm || addr + len <= vmm->vm_start) @@ -99,11 +93,6 @@ int sparc_mmap_check(unsigned long addr, unsigned long len) { - if (ARCH_SUN4C && - (len > 0x20000000 || - (addr < 0xe0000000 && addr + len > 0x20000000))) - return -EINVAL; - /* See asm-sparc/uaccess.h */ if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE) return -EINVAL;
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 7d0c088..9536415 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c
@@ -26,6 +26,8 @@ #include <linux/rtc.h> #include <linux/rtc/m48t59.h> #include <linux/timex.h> +#include <linux/clocksource.h> +#include <linux/clockchips.h> #include <linux/init.h> #include <linux/pci.h> #include <linux/ioport.h> @@ -40,13 +42,24 @@ #include <asm/irq.h> #include <asm/io.h> #include <asm/idprom.h> -#include <asm/machines.h> #include <asm/page.h> #include <asm/pcic.h> #include <asm/irq_regs.h> +#include <asm/setup.h> #include "irq.h" +static __cacheline_aligned_in_smp DEFINE_SEQLOCK(timer_cs_lock); +static __volatile__ u64 timer_cs_internal_counter = 0; +static char timer_cs_enabled = 0; + +static struct clock_event_device timer_ce; +static char timer_ce_enabled = 0; + +#ifdef CONFIG_SMP +DEFINE_PER_CPU(struct clock_event_device, sparc32_clockevent); +#endif + DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -55,7 +68,6 @@ unsigned long profile_pc(struct pt_regs *regs) { extern char __copy_user_begin[], __copy_user_end[]; - extern char __atomic_begin[], __atomic_end[]; extern char __bzero_begin[], __bzero_end[]; unsigned long pc = regs->pc; @@ -63,8 +75,6 @@ if (in_lock_functions(pc) || (pc >= (unsigned long) __copy_user_begin && pc < (unsigned long) __copy_user_end) || - (pc >= (unsigned long) __atomic_begin && - pc < (unsigned long) __atomic_end) || (pc >= (unsigned long) __bzero_begin && pc < (unsigned long) __bzero_end)) pc = regs->u_regs[UREG_RETPC]; @@ -75,36 +85,168 @@ __volatile__ unsigned int *master_l10_counter; -u32 (*do_arch_gettimeoffset)(void); - int update_persistent_clock(struct timespec now) { return set_rtc_mmss(now.tv_sec); } -/* - * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "xtime_update()" routine every clocktick - */ - -#define TICK_SIZE (tick_nsec / 1000) - -static irqreturn_t timer_interrupt(int dummy, void *dev_id) +irqreturn_t notrace timer_interrupt(int dummy, void *dev_id) { -#ifndef CONFIG_SMP - profile_tick(CPU_PROFILING); -#endif + if (timer_cs_enabled) { + write_seqlock(&timer_cs_lock); + timer_cs_internal_counter++; + sparc_config.clear_clock_irq(); + write_sequnlock(&timer_cs_lock); + } else { + sparc_config.clear_clock_irq(); + } - clear_clock_irq(); + if (timer_ce_enabled) + timer_ce.event_handler(&timer_ce); - xtime_update(1); - -#ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); -#endif return IRQ_HANDLED; } +static void timer_ce_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + case CLOCK_EVT_MODE_RESUME: + timer_ce_enabled = 1; + break; + case CLOCK_EVT_MODE_SHUTDOWN: + timer_ce_enabled = 0; + break; + default: + break; + } + smp_mb(); +} + +static __init void setup_timer_ce(void) +{ + struct clock_event_device *ce = &timer_ce; + + BUG_ON(smp_processor_id() != boot_cpu_id); + + ce->name = "timer_ce"; + ce->rating = 100; + ce->features = CLOCK_EVT_FEAT_PERIODIC; + ce->set_mode = timer_ce_set_mode; + ce->cpumask = cpu_possible_mask; + ce->shift = 32; + ce->mult = div_sc(sparc_config.clock_rate, NSEC_PER_SEC, + ce->shift); + clockevents_register_device(ce); +} + +static unsigned int sbus_cycles_offset(void) +{ + unsigned int val, offset; + + val = *master_l10_counter; + offset = (val >> TIMER_VALUE_SHIFT) & TIMER_VALUE_MASK; + + /* Limit hit? */ + if (val & TIMER_LIMIT_BIT) + offset += sparc_config.cs_period; + + return offset; +} + +static cycle_t timer_cs_read(struct clocksource *cs) +{ + unsigned int seq, offset; + u64 cycles; + + do { + seq = read_seqbegin(&timer_cs_lock); + + cycles = timer_cs_internal_counter; + offset = sparc_config.get_cycles_offset(); + } while (read_seqretry(&timer_cs_lock, seq)); + + /* Count absolute cycles */ + cycles *= sparc_config.cs_period; + cycles += offset; + + return cycles; +} + +static struct clocksource timer_cs = { + .name = "timer_cs", + .rating = 100, + .read = timer_cs_read, + .mask = CLOCKSOURCE_MASK(64), + .shift = 2, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static __init int setup_timer_cs(void) +{ + timer_cs_enabled = 1; + timer_cs.mult = clocksource_hz2mult(sparc_config.clock_rate, + timer_cs.shift); + + return clocksource_register(&timer_cs); +} + +#ifdef CONFIG_SMP +static void percpu_ce_setup(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + int cpu = __first_cpu(evt->cpumask); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + sparc_config.load_profile_irq(cpu, + SBUS_CLOCK_RATE / HZ); + break; + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + sparc_config.load_profile_irq(cpu, 0); + break; + default: + break; + } +} + +static int percpu_ce_set_next_event(unsigned long delta, + struct clock_event_device *evt) +{ + int cpu = __first_cpu(evt->cpumask); + unsigned int next = (unsigned int)delta; + + sparc_config.load_profile_irq(cpu, next); + return 0; +} + +void register_percpu_ce(int cpu) +{ + struct clock_event_device *ce = &per_cpu(sparc32_clockevent, cpu); + unsigned int features = CLOCK_EVT_FEAT_PERIODIC; + + if (sparc_config.features & FEAT_L14_ONESHOT) + features |= CLOCK_EVT_FEAT_ONESHOT; + + ce->name = "percpu_ce"; + ce->rating = 200; + ce->features = features; + ce->set_mode = percpu_ce_setup; + ce->set_next_event = percpu_ce_set_next_event; + ce->cpumask = cpumask_of(cpu); + ce->shift = 32; + ce->mult = div_sc(sparc_config.clock_rate, NSEC_PER_SEC, + ce->shift); + ce->max_delta_ns = clockevent_delta2ns(sparc_config.clock_rate, ce); + ce->min_delta_ns = clockevent_delta2ns(100, ce); + + clockevents_register_device(ce); +} +#endif + static unsigned char mostek_read_byte(struct device *dev, u32 ofs) { struct platform_device *pdev = to_platform_device(dev); @@ -195,38 +337,28 @@ */ fs_initcall(clock_init); - -u32 sbus_do_gettimeoffset(void) +static void __init sparc32_late_time_init(void) { - unsigned long val = *master_l10_counter; - unsigned long usec = (val >> 10) & 0x1fffff; - - /* Limit hit? */ - if (val & 0x80000000) - usec += 1000000 / HZ; - - return usec * 1000; -} - - -u32 arch_gettimeoffset(void) -{ - if (unlikely(!do_arch_gettimeoffset)) - return 0; - return do_arch_gettimeoffset(); + if (sparc_config.features & FEAT_L10_CLOCKEVENT) + setup_timer_ce(); + if (sparc_config.features & FEAT_L10_CLOCKSOURCE) + setup_timer_cs(); +#ifdef CONFIG_SMP + register_percpu_ce(smp_processor_id()); +#endif } static void __init sbus_time_init(void) { - do_arch_gettimeoffset = sbus_do_gettimeoffset; - - btfixup(); - - sparc_irq_config.init_timers(timer_interrupt); + sparc_config.get_cycles_offset = sbus_cycles_offset; + sparc_config.init_timers(); } void __init time_init(void) { + sparc_config.features = 0; + late_time_init = sparc32_late_time_init; + if (pcic_present()) pci_time_init(); else
diff --git a/arch/sparc/kernel/trampoline_32.S b/arch/sparc/kernel/trampoline_32.S index 691f484..7364ddc 100644 --- a/arch/sparc/kernel/trampoline_32.S +++ b/arch/sparc/kernel/trampoline_32.S
@@ -15,8 +15,8 @@ #include <asm/contregs.h> #include <asm/thread_info.h> - .globl sun4m_cpu_startup, __smp4m_processor_id, __leon_processor_id - .globl sun4d_cpu_startup, __smp4d_processor_id + .globl sun4m_cpu_startup + .globl sun4d_cpu_startup __CPUINIT .align 4 @@ -94,24 +94,6 @@ call cpu_panic nop -__smp4m_processor_id: - rd %tbr, %g2 - srl %g2, 12, %g2 - and %g2, 3, %g2 - retl - mov %g1, %o7 - -__smp4d_processor_id: - lda [%g0] ASI_M_VIKING_TMP1, %g2 - retl - mov %g1, %o7 - -__leon_processor_id: - rd %asr17,%g2 - srl %g2,28,%g2 - retl - mov %g1, %o7 - /* CPUID in bootbus can be found at PA 0xff0140000 */ #define SUN4D_BOOTBUS_CPUID 0xf0140000
diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c index d2de213..a5785ea 100644 --- a/arch/sparc/kernel/traps_32.c +++ b/arch/sparc/kernel/traps_32.c
@@ -120,8 +120,6 @@ printk("Ill instr. at pc=%08lx instruction is %08lx\n", regs->pc, *(unsigned long *)regs->pc); #endif - if (!do_user_muldiv (regs, pc)) - return; info.si_signo = SIGILL; info.si_errno = 0;
diff --git a/arch/sparc/kernel/ttable_32.S b/arch/sparc/kernel/ttable_32.S new file mode 100644 index 0000000..8a7a96c --- /dev/null +++ b/arch/sparc/kernel/ttable_32.S
@@ -0,0 +1,417 @@ +/* The Sparc trap table, bootloader gives us control at _start. */ + __HEAD + + .globl _start +_start: + + .globl _stext +_stext: + + .globl trapbase +trapbase: + +#ifdef CONFIG_SMP +trapbase_cpu0: +#endif +/* We get control passed to us here at t_zero. */ +t_zero: b gokernel; nop; nop; nop; +t_tflt: SRMMU_TFAULT /* Inst. Access Exception */ +t_bins: TRAP_ENTRY(0x2, bad_instruction) /* Illegal Instruction */ +t_pins: TRAP_ENTRY(0x3, priv_instruction) /* Privileged Instruction */ +t_fpd: TRAP_ENTRY(0x4, fpd_trap_handler) /* Floating Point Disabled */ +t_wovf: WINDOW_SPILL /* Window Overflow */ +t_wunf: WINDOW_FILL /* Window Underflow */ +t_mna: TRAP_ENTRY(0x7, mna_handler) /* Memory Address Not Aligned */ +t_fpe: TRAP_ENTRY(0x8, fpe_trap_handler) /* Floating Point Exception */ +t_dflt: SRMMU_DFAULT /* Data Miss Exception */ +t_tio: TRAP_ENTRY(0xa, do_tag_overflow) /* Tagged Instruction Ovrflw */ +t_wpt: TRAP_ENTRY(0xb, do_watchpoint) /* Watchpoint Detected */ +t_badc: BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) +t_irq1: TRAP_ENTRY_INTERRUPT(1) /* IRQ Software/SBUS Level 1 */ +t_irq2: TRAP_ENTRY_INTERRUPT(2) /* IRQ SBUS Level 2 */ +t_irq3: TRAP_ENTRY_INTERRUPT(3) /* IRQ SCSI/DMA/SBUS Level 3 */ +t_irq4: TRAP_ENTRY_INTERRUPT(4) /* IRQ Software Level 4 */ +t_irq5: TRAP_ENTRY_INTERRUPT(5) /* IRQ SBUS/Ethernet Level 5 */ +t_irq6: TRAP_ENTRY_INTERRUPT(6) /* IRQ Software Level 6 */ +t_irq7: TRAP_ENTRY_INTERRUPT(7) /* IRQ Video/SBUS Level 5 */ +t_irq8: TRAP_ENTRY_INTERRUPT(8) /* IRQ SBUS Level 6 */ +t_irq9: TRAP_ENTRY_INTERRUPT(9) /* IRQ SBUS Level 7 */ +t_irq10:TRAP_ENTRY_INTERRUPT(10) /* IRQ Timer #1 (one we use) */ +t_irq11:TRAP_ENTRY_INTERRUPT(11) /* IRQ Floppy Intr. */ +t_irq12:TRAP_ENTRY_INTERRUPT(12) /* IRQ Zilog serial chip */ +t_irq13:TRAP_ENTRY_INTERRUPT(13) /* IRQ Audio Intr. */ +t_irq14:TRAP_ENTRY_INTERRUPT(14) /* IRQ Timer #2 */ + + .globl t_nmi +t_nmi: TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) + +t_racc: TRAP_ENTRY(0x20, do_reg_access) /* General Register Access Error */ +t_iacce:BAD_TRAP(0x21) /* Instr Access Error */ +t_bad22:BAD_TRAP(0x22) + BAD_TRAP(0x23) +t_cpdis:TRAP_ENTRY(0x24, do_cp_disabled) /* Co-Processor Disabled */ +t_uflsh:SKIP_TRAP(0x25, unimp_flush) /* Unimplemented FLUSH inst. */ +t_bad26:BAD_TRAP(0x26) BAD_TRAP(0x27) +t_cpexc:TRAP_ENTRY(0x28, do_cp_exception) /* Co-Processor Exception */ +t_dacce:SRMMU_DFAULT /* Data Access Error */ +t_hwdz: TRAP_ENTRY(0x2a, do_hw_divzero) /* Division by zero, you lose... */ +t_dserr:BAD_TRAP(0x2b) /* Data Store Error */ +t_daccm:BAD_TRAP(0x2c) /* Data Access MMU-Miss */ +t_bad2d:BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) +t_bad32:BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) +t_bad37:BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) +t_iaccm:BAD_TRAP(0x3c) /* Instr Access MMU-Miss */ +t_bad3d:BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) BAD_TRAP(0x41) +t_bad42:BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) BAD_TRAP(0x46) +t_bad47:BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) BAD_TRAP(0x4b) +t_bad4c:BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) BAD_TRAP(0x50) +t_bad51:BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) +t_bad56:BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) +t_bad5b:BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) +t_bad60:BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) +t_bad65:BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) +t_bad6a:BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) +t_bad6f:BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) +t_bad74:BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) +t_bad79:BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) +t_bad7e:BAD_TRAP(0x7e) BAD_TRAP(0x7f) +t_bad80:BAD_TRAP(0x80) /* SunOS System Call */ +t_sbkpt:BREAKPOINT_TRAP /* Software Breakpoint/KGDB */ +t_divz: TRAP_ENTRY(0x82, do_hw_divzero) /* Divide by zero trap */ +t_flwin:TRAP_ENTRY(0x83, do_flush_windows) /* Flush Windows Trap */ +t_clwin:BAD_TRAP(0x84) /* Clean Windows Trap */ +t_rchk: BAD_TRAP(0x85) /* Range Check */ +t_funal:BAD_TRAP(0x86) /* Fix Unaligned Access Trap */ +t_iovf: BAD_TRAP(0x87) /* Integer Overflow Trap */ +t_bad88:BAD_TRAP(0x88) /* Slowaris System Call */ +t_bad89:BAD_TRAP(0x89) /* Net-B.S. System Call */ +t_bad8a:BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) BAD_TRAP(0x8d) BAD_TRAP(0x8e) +t_bad8f:BAD_TRAP(0x8f) +t_linux:LINUX_SYSCALL_TRAP /* Linux System Call */ +t_bad91:BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) BAD_TRAP(0x95) +t_bad96:BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) BAD_TRAP(0x9a) +t_bad9b:BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) BAD_TRAP(0x9f) +t_getcc:GETCC_TRAP /* Get Condition Codes */ +t_setcc:SETCC_TRAP /* Set Condition Codes */ +t_getpsr:GETPSR_TRAP /* Get PSR Register */ +t_bada3:BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) +t_bada7:BAD_TRAP(0xa7) +t_bada8:BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) +t_badac:BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) +t_badb1:BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) +t_badb6:BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) +t_badbb:BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) +t_badc0:BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) +t_badc5:BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) +t_badca:BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) +t_badcf:BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) +t_badd4:BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) +t_badd9:BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) +t_badde:BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) +t_bade3:BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) +t_bade8:BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) +t_baded:BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) +t_badf2:BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) +t_badf7:BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) +t_badfc:BAD_TRAP(0xfc) +t_kgdb: KGDB_TRAP(0xfd) +dbtrap: BAD_TRAP(0xfe) /* Debugger/PROM breakpoint #1 */ +dbtrap2:BAD_TRAP(0xff) /* Debugger/PROM breakpoint #2 */ + + .globl end_traptable +end_traptable: + +#ifdef CONFIG_SMP + /* Trap tables for the other cpus. */ + .globl trapbase_cpu1, trapbase_cpu2, trapbase_cpu3 +trapbase_cpu1: + BAD_TRAP(0x0) + SRMMU_TFAULT + TRAP_ENTRY(0x2, bad_instruction) + TRAP_ENTRY(0x3, priv_instruction) + TRAP_ENTRY(0x4, fpd_trap_handler) + WINDOW_SPILL + WINDOW_FILL + TRAP_ENTRY(0x7, mna_handler) + TRAP_ENTRY(0x8, fpe_trap_handler) + SRMMU_DFAULT + TRAP_ENTRY(0xa, do_tag_overflow) + TRAP_ENTRY(0xb, do_watchpoint) + BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) + TRAP_ENTRY_INTERRUPT(1) TRAP_ENTRY_INTERRUPT(2) + TRAP_ENTRY_INTERRUPT(3) TRAP_ENTRY_INTERRUPT(4) + TRAP_ENTRY_INTERRUPT(5) TRAP_ENTRY_INTERRUPT(6) + TRAP_ENTRY_INTERRUPT(7) TRAP_ENTRY_INTERRUPT(8) + TRAP_ENTRY_INTERRUPT(9) TRAP_ENTRY_INTERRUPT(10) + TRAP_ENTRY_INTERRUPT(11) TRAP_ENTRY_INTERRUPT(12) + TRAP_ENTRY_INTERRUPT(13) TRAP_ENTRY_INTERRUPT(14) + TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) + TRAP_ENTRY(0x20, do_reg_access) + BAD_TRAP(0x21) + BAD_TRAP(0x22) + BAD_TRAP(0x23) + TRAP_ENTRY(0x24, do_cp_disabled) + SKIP_TRAP(0x25, unimp_flush) + BAD_TRAP(0x26) + BAD_TRAP(0x27) + TRAP_ENTRY(0x28, do_cp_exception) + SRMMU_DFAULT + TRAP_ENTRY(0x2a, do_hw_divzero) + BAD_TRAP(0x2b) + BAD_TRAP(0x2c) + BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) + BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) + BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) + BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) + BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) + BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) + BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) + BAD_TRAP(0x50) + BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) + BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) + BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) + BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) + BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) + BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) + BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) + BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) + BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) + BAD_TRAP(0x7e) BAD_TRAP(0x7f) + BAD_TRAP(0x80) + BREAKPOINT_TRAP + TRAP_ENTRY(0x82, do_hw_divzero) + TRAP_ENTRY(0x83, do_flush_windows) + BAD_TRAP(0x84) BAD_TRAP(0x85) BAD_TRAP(0x86) + BAD_TRAP(0x87) BAD_TRAP(0x88) BAD_TRAP(0x89) + BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) + BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) + LINUX_SYSCALL_TRAP BAD_TRAP(0x91) + BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) + BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) + BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) + BAD_TRAP(0x9f) + GETCC_TRAP + SETCC_TRAP + GETPSR_TRAP + BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) + BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) + BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) + BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) + BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) + BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) + BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) + BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) + BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) + BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) + BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) + BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) + BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) + BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) + BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) + BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) + BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) + BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) + BAD_TRAP(0xfc) + KGDB_TRAP(0xfd) + BAD_TRAP(0xfe) + BAD_TRAP(0xff) + +trapbase_cpu2: + BAD_TRAP(0x0) + SRMMU_TFAULT + TRAP_ENTRY(0x2, bad_instruction) + TRAP_ENTRY(0x3, priv_instruction) + TRAP_ENTRY(0x4, fpd_trap_handler) + WINDOW_SPILL + WINDOW_FILL + TRAP_ENTRY(0x7, mna_handler) + TRAP_ENTRY(0x8, fpe_trap_handler) + SRMMU_DFAULT + TRAP_ENTRY(0xa, do_tag_overflow) + TRAP_ENTRY(0xb, do_watchpoint) + BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) + TRAP_ENTRY_INTERRUPT(1) + TRAP_ENTRY_INTERRUPT(2) + TRAP_ENTRY_INTERRUPT(3) + TRAP_ENTRY_INTERRUPT(4) + TRAP_ENTRY_INTERRUPT(5) + TRAP_ENTRY_INTERRUPT(6) + TRAP_ENTRY_INTERRUPT(7) + TRAP_ENTRY_INTERRUPT(8) + TRAP_ENTRY_INTERRUPT(9) + TRAP_ENTRY_INTERRUPT(10) + TRAP_ENTRY_INTERRUPT(11) + TRAP_ENTRY_INTERRUPT(12) + TRAP_ENTRY_INTERRUPT(13) + TRAP_ENTRY_INTERRUPT(14) + TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) + TRAP_ENTRY(0x20, do_reg_access) + BAD_TRAP(0x21) + BAD_TRAP(0x22) + BAD_TRAP(0x23) + TRAP_ENTRY(0x24, do_cp_disabled) + SKIP_TRAP(0x25, unimp_flush) + BAD_TRAP(0x26) + BAD_TRAP(0x27) + TRAP_ENTRY(0x28, do_cp_exception) + SRMMU_DFAULT + TRAP_ENTRY(0x2a, do_hw_divzero) + BAD_TRAP(0x2b) + BAD_TRAP(0x2c) + BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) + BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) + BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) + BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) + BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) + BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) + BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) + BAD_TRAP(0x50) + BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) + BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) + BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) + BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) + BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) + BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) + BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) + BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) + BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) + BAD_TRAP(0x7e) BAD_TRAP(0x7f) + BAD_TRAP(0x80) + BREAKPOINT_TRAP + TRAP_ENTRY(0x82, do_hw_divzero) + TRAP_ENTRY(0x83, do_flush_windows) + BAD_TRAP(0x84) + BAD_TRAP(0x85) + BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88) + BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) + BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) + LINUX_SYSCALL_TRAP BAD_TRAP(0x91) + BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) + BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) + BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) + BAD_TRAP(0x9f) + GETCC_TRAP + SETCC_TRAP + GETPSR_TRAP + BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) + BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) + BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) + BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) + BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) + BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) + BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) + BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) + BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) + BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) + BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) + BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) + BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) + BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) + BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) + BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) + BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) + BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) + BAD_TRAP(0xfc) + KGDB_TRAP(0xfd) + BAD_TRAP(0xfe) + BAD_TRAP(0xff) + +trapbase_cpu3: + BAD_TRAP(0x0) + SRMMU_TFAULT + TRAP_ENTRY(0x2, bad_instruction) + TRAP_ENTRY(0x3, priv_instruction) + TRAP_ENTRY(0x4, fpd_trap_handler) + WINDOW_SPILL + WINDOW_FILL + TRAP_ENTRY(0x7, mna_handler) + TRAP_ENTRY(0x8, fpe_trap_handler) + SRMMU_DFAULT + TRAP_ENTRY(0xa, do_tag_overflow) + TRAP_ENTRY(0xb, do_watchpoint) + BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) + TRAP_ENTRY_INTERRUPT(1) + TRAP_ENTRY_INTERRUPT(2) + TRAP_ENTRY_INTERRUPT(3) + TRAP_ENTRY_INTERRUPT(4) + TRAP_ENTRY_INTERRUPT(5) + TRAP_ENTRY_INTERRUPT(6) + TRAP_ENTRY_INTERRUPT(7) + TRAP_ENTRY_INTERRUPT(8) + TRAP_ENTRY_INTERRUPT(9) + TRAP_ENTRY_INTERRUPT(10) + TRAP_ENTRY_INTERRUPT(11) + TRAP_ENTRY_INTERRUPT(12) + TRAP_ENTRY_INTERRUPT(13) + TRAP_ENTRY_INTERRUPT(14) + TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) + TRAP_ENTRY(0x20, do_reg_access) + BAD_TRAP(0x21) + BAD_TRAP(0x22) + BAD_TRAP(0x23) + TRAP_ENTRY(0x24, do_cp_disabled) + SKIP_TRAP(0x25, unimp_flush) + BAD_TRAP(0x26) + BAD_TRAP(0x27) + TRAP_ENTRY(0x28, do_cp_exception) + SRMMU_DFAULT + TRAP_ENTRY(0x2a, do_hw_divzero) + BAD_TRAP(0x2b) BAD_TRAP(0x2c) + BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) + BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) + BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) + BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) + BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) + BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) + BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) + BAD_TRAP(0x50) + BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) + BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) + BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) + BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) + BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) + BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) + BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) + BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) + BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) + BAD_TRAP(0x7e) BAD_TRAP(0x7f) + BAD_TRAP(0x80) + BREAKPOINT_TRAP + TRAP_ENTRY(0x82, do_hw_divzero) + TRAP_ENTRY(0x83, do_flush_windows) + BAD_TRAP(0x84) BAD_TRAP(0x85) + BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88) + BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) + BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) + LINUX_SYSCALL_TRAP + BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) + BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) + BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) + BAD_TRAP(0x9f) + GETCC_TRAP + SETCC_TRAP + GETPSR_TRAP + BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) + BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) + BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) + BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) + BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) + BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) + BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) + BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) + BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) + BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) + BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) + BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) + BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) + BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) + BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) + BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) + BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) + BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) + BAD_TRAP(0xfc) + KGDB_TRAP(0xfd) + BAD_TRAP(0xfe) + BAD_TRAP(0xff) + +#endif
diff --git a/arch/sparc/kernel/ttable.S b/arch/sparc/kernel/ttable_64.S similarity index 100% rename from arch/sparc/kernel/ttable.S rename to arch/sparc/kernel/ttable_64.S
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index dae85bc..f81d038 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c
@@ -21,7 +21,6 @@ #include <linux/bitops.h> #include <linux/perf_event.h> #include <linux/ratelimit.h> -#include <linux/bitops.h> #include <asm/fpumacro.h> #include <asm/cacheflush.h>
diff --git a/arch/sparc/kernel/wof.S b/arch/sparc/kernel/wof.S index 3bbcd8d..4c2de3c 100644 --- a/arch/sparc/kernel/wof.S +++ b/arch/sparc/kernel/wof.S
@@ -163,9 +163,8 @@ * the label 'spwin_user_stack_is_bolixed' which will take * care of things at that point. */ - .globl spwin_mmu_patchme -spwin_mmu_patchme: b spwin_sun4c_stackchk - andcc %sp, 0x7, %g0 + b spwin_srmmu_stackchk + andcc %sp, 0x7, %g0 spwin_good_ustack: /* LOCATION: Window to be saved */ @@ -306,73 +305,6 @@ * As noted above %curptr cannot be touched by this routine at all. */ -spwin_sun4c_stackchk: - /* LOCATION: Window to be saved on the stack */ - - /* See if the stack is in the address space hole but first, - * check results of callers andcc %sp, 0x7, %g0 - */ - be 1f - sra %sp, 29, %glob_tmp - - rd %psr, %glob_tmp - b spwin_user_stack_is_bolixed + 0x4 - nop - -1: - add %glob_tmp, 0x1, %glob_tmp - andncc %glob_tmp, 0x1, %g0 - be 1f - and %sp, 0xfff, %glob_tmp ! delay slot - - rd %psr, %glob_tmp - b spwin_user_stack_is_bolixed + 0x4 - nop - - /* See if our dump area will be on more than one - * page. - */ -1: - add %glob_tmp, 0x38, %glob_tmp - andncc %glob_tmp, 0xff8, %g0 - be spwin_sun4c_onepage ! only one page to check - lda [%sp] ASI_PTE, %glob_tmp ! have to check first page anyways - -spwin_sun4c_twopages: - /* Is first page ok permission wise? */ - srl %glob_tmp, 29, %glob_tmp - cmp %glob_tmp, 0x6 - be 1f - add %sp, 0x38, %glob_tmp /* Is second page in vma hole? */ - - rd %psr, %glob_tmp - b spwin_user_stack_is_bolixed + 0x4 - nop - -1: - sra %glob_tmp, 29, %glob_tmp - add %glob_tmp, 0x1, %glob_tmp - andncc %glob_tmp, 0x1, %g0 - be 1f - add %sp, 0x38, %glob_tmp - - rd %psr, %glob_tmp - b spwin_user_stack_is_bolixed + 0x4 - nop - -1: - lda [%glob_tmp] ASI_PTE, %glob_tmp - -spwin_sun4c_onepage: - srl %glob_tmp, 29, %glob_tmp - cmp %glob_tmp, 0x6 ! can user write to it? - be spwin_good_ustack ! success - nop - - rd %psr, %glob_tmp - b spwin_user_stack_is_bolixed + 0x4 - nop - /* This is a generic SRMMU routine. As far as I know this * works for all current v8/srmmu implementations, we'll * see...
diff --git a/arch/sparc/kernel/wuf.S b/arch/sparc/kernel/wuf.S index 779ff750..9fde91a 100644 --- a/arch/sparc/kernel/wuf.S +++ b/arch/sparc/kernel/wuf.S
@@ -131,12 +131,9 @@ /* LOCATION: Window 'W' */ - /* Branch to the architecture specific stack validation - * routine. They can be found below... - */ - .globl fwin_mmu_patchme -fwin_mmu_patchme: b sun4c_fwin_stackchk - andcc %sp, 0x7, %g0 + /* Branch to the stack validation routine */ + b srmmu_fwin_stackchk + andcc %sp, 0x7, %g0 #define STACK_OFFSET (THREAD_SIZE - TRACEREG_SZ - STACKFRAME_SZ) @@ -242,57 +239,6 @@ * 'someone elses' window possibly. */ - .align 4 -sun4c_fwin_stackchk: - /* LOCATION: Window 'W' */ - - /* Caller did 'andcc %sp, 0x7, %g0' */ - be 1f - and %sp, 0xfff, %l0 ! delay slot - - b,a fwin_user_stack_is_bolixed - - /* See if we have to check the sanity of one page or two */ -1: - add %l0, 0x38, %l0 - sra %sp, 29, %l5 - add %l5, 0x1, %l5 - andncc %l5, 0x1, %g0 - be 1f - andncc %l0, 0xff8, %g0 - - b,a fwin_user_stack_is_bolixed /* %sp is in vma hole, yuck */ - -1: - be sun4c_fwin_onepage /* Only one page to check */ - lda [%sp] ASI_PTE, %l1 -sun4c_fwin_twopages: - add %sp, 0x38, %l0 - sra %l0, 29, %l5 - add %l5, 0x1, %l5 - andncc %l5, 0x1, %g0 - be 1f - lda [%l0] ASI_PTE, %l1 - - b,a fwin_user_stack_is_bolixed /* Second page in vma hole */ - -1: - srl %l1, 29, %l1 - andcc %l1, 0x4, %g0 - bne sun4c_fwin_onepage - lda [%sp] ASI_PTE, %l1 - - b,a fwin_user_stack_is_bolixed /* Second page has bad perms */ - -sun4c_fwin_onepage: - srl %l1, 29, %l1 - andcc %l1, 0x4, %g0 - bne fwin_user_stack_is_ok - nop - - /* A page had bad page permissions, losing... */ - b,a fwin_user_stack_is_bolixed - .globl srmmu_fwin_stackchk srmmu_fwin_stackchk: /* LOCATION: Window 'W' */
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index a3fc437..389628f 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile
@@ -4,7 +4,7 @@ asflags-y := -ansi -DST_DIV0=0x02 ccflags-y := -Werror -lib-$(CONFIG_SPARC32) += mul.o rem.o sdiv.o udiv.o umul.o urem.o ashrdi3.o +lib-$(CONFIG_SPARC32) += ashrdi3.o lib-$(CONFIG_SPARC32) += memcpy.o memset.o lib-y += strlen.o lib-y += checksum_$(BITS).o @@ -13,7 +13,7 @@ lib-y += strncpy_from_user_$(BITS).o strlen_user_$(BITS).o lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o lib-$(CONFIG_SPARC32) += copy_user.o locks.o -lib-y += atomic_$(BITS).o +lib-$(CONFIG_SPARC64) += atomic_64.o lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o @@ -40,7 +40,7 @@ lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o obj-y += iomap.o -obj-$(CONFIG_SPARC32) += atomic32.o +obj-$(CONFIG_SPARC32) += atomic32.o ucmpdi2.o obj-y += ksyms.o obj-$(CONFIG_SPARC64) += PeeCeeI.o obj-y += usercopy.o
diff --git a/arch/sparc/lib/ashldi3.S b/arch/sparc/lib/ashldi3.S index 17912e6..86f60de 100644 --- a/arch/sparc/lib/ashldi3.S +++ b/arch/sparc/lib/ashldi3.S
@@ -5,10 +5,10 @@ * Copyright (C) 1999 David S. Miller (davem@redhat.com) */ +#include <linux/linkage.h> + .text - .align 4 - .globl __ashldi3 -__ashldi3: +ENTRY(__ashldi3) cmp %o2, 0 be 9f mov 0x20, %g2 @@ -32,3 +32,4 @@ 9: retl nop +ENDPROC(__ashldi3)
diff --git a/arch/sparc/lib/ashrdi3.S b/arch/sparc/lib/ashrdi3.S index 85398fd6..6eb8ba2 100644 --- a/arch/sparc/lib/ashrdi3.S +++ b/arch/sparc/lib/ashrdi3.S
@@ -5,10 +5,10 @@ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) */ +#include <linux/linkage.h> + .text - .align 4 - .globl __ashrdi3 -__ashrdi3: +ENTRY(__ashrdi3) tst %o2 be 3f or %g0, 32, %g2 @@ -34,3 +34,4 @@ 3: jmpl %o7 + 8, %g0 nop +ENDPROC(__ashrdi3)
diff --git a/arch/sparc/lib/atomic_32.S b/arch/sparc/lib/atomic_32.S deleted file mode 100644 index eb6c735..0000000 --- a/arch/sparc/lib/atomic_32.S +++ /dev/null
@@ -1,44 +0,0 @@ -/* atomic.S: Move this stuff here for better ICACHE hit rates. - * - * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu) - */ - -#include <asm/ptrace.h> -#include <asm/psr.h> - - .text - .align 4 - - .globl __atomic_begin -__atomic_begin: - -#ifndef CONFIG_SMP - .globl ___xchg32_sun4c -___xchg32_sun4c: - rd %psr, %g3 - andcc %g3, PSR_PIL, %g0 - bne 1f - nop - wr %g3, PSR_PIL, %psr - nop; nop; nop -1: - andcc %g3, PSR_PIL, %g0 - ld [%g1], %g7 - bne 1f - st %g2, [%g1] - wr %g3, 0x0, %psr - nop; nop; nop -1: - mov %g7, %g2 - jmpl %o7 + 8, %g0 - mov %g4, %o7 - - .globl ___xchg32_sun4md -___xchg32_sun4md: - swap [%g1], %g2 - jmpl %o7 + 8, %g0 - mov %g4, %o7 -#endif - - .globl __atomic_end -__atomic_end:
diff --git a/arch/sparc/lib/atomic_64.S b/arch/sparc/lib/atomic_64.S index 59186e0..4d502da 100644 --- a/arch/sparc/lib/atomic_64.S +++ b/arch/sparc/lib/atomic_64.S
@@ -3,6 +3,7 @@ * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) */ +#include <linux/linkage.h> #include <asm/asi.h> #include <asm/backoff.h> @@ -13,9 +14,7 @@ * memory barriers, and a second which returns * a value and does the barriers. */ - .globl atomic_add - .type atomic_add,#function -atomic_add: /* %o0 = increment, %o1 = atomic_ptr */ +ENTRY(atomic_add) /* %o0 = increment, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: lduw [%o1], %g1 add %g1, %o0, %g7 @@ -26,11 +25,9 @@ retl nop 2: BACKOFF_SPIN(%o2, %o3, 1b) - .size atomic_add, .-atomic_add +ENDPROC(atomic_add) - .globl atomic_sub - .type atomic_sub,#function -atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ +ENTRY(atomic_sub) /* %o0 = decrement, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: lduw [%o1], %g1 sub %g1, %o0, %g7 @@ -41,11 +38,9 @@ retl nop 2: BACKOFF_SPIN(%o2, %o3, 1b) - .size atomic_sub, .-atomic_sub +ENDPROC(atomic_sub) - .globl atomic_add_ret - .type atomic_add_ret,#function -atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ +ENTRY(atomic_add_ret) /* %o0 = increment, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: lduw [%o1], %g1 add %g1, %o0, %g7 @@ -56,11 +51,9 @@ retl sra %g1, 0, %o0 2: BACKOFF_SPIN(%o2, %o3, 1b) - .size atomic_add_ret, .-atomic_add_ret +ENDPROC(atomic_add_ret) - .globl atomic_sub_ret - .type atomic_sub_ret,#function -atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ +ENTRY(atomic_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: lduw [%o1], %g1 sub %g1, %o0, %g7 @@ -71,11 +64,9 @@ retl sra %g1, 0, %o0 2: BACKOFF_SPIN(%o2, %o3, 1b) - .size atomic_sub_ret, .-atomic_sub_ret +ENDPROC(atomic_sub_ret) - .globl atomic64_add - .type atomic64_add,#function -atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */ +ENTRY(atomic64_add) /* %o0 = increment, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: ldx [%o1], %g1 add %g1, %o0, %g7 @@ -86,11 +77,9 @@ retl nop 2: BACKOFF_SPIN(%o2, %o3, 1b) - .size atomic64_add, .-atomic64_add +ENDPROC(atomic64_add) - .globl atomic64_sub - .type atomic64_sub,#function -atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */ +ENTRY(atomic64_sub) /* %o0 = decrement, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: ldx [%o1], %g1 sub %g1, %o0, %g7 @@ -101,11 +90,9 @@ retl nop 2: BACKOFF_SPIN(%o2, %o3, 1b) - .size atomic64_sub, .-atomic64_sub +ENDPROC(atomic64_sub) - .globl atomic64_add_ret - .type atomic64_add_ret,#function -atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ +ENTRY(atomic64_add_ret) /* %o0 = increment, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: ldx [%o1], %g1 add %g1, %o0, %g7 @@ -116,11 +103,9 @@ retl add %g1, %o0, %o0 2: BACKOFF_SPIN(%o2, %o3, 1b) - .size atomic64_add_ret, .-atomic64_add_ret +ENDPROC(atomic64_add_ret) - .globl atomic64_sub_ret - .type atomic64_sub_ret,#function -atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ +ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: ldx [%o1], %g1 sub %g1, %o0, %g7 @@ -131,4 +116,4 @@ retl sub %g1, %o0, %o0 2: BACKOFF_SPIN(%o2, %o3, 1b) - .size atomic64_sub_ret, .-atomic64_sub_ret +ENDPROC(atomic64_sub_ret)
diff --git a/arch/sparc/lib/bitops.S b/arch/sparc/lib/bitops.S index 3dc61d5..36f72cc 100644 --- a/arch/sparc/lib/bitops.S +++ b/arch/sparc/lib/bitops.S
@@ -3,14 +3,13 @@ * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net) */ +#include <linux/linkage.h> #include <asm/asi.h> #include <asm/backoff.h> .text - .globl test_and_set_bit - .type test_and_set_bit,#function -test_and_set_bit: /* %o0=nr, %o1=addr */ +ENTRY(test_and_set_bit) /* %o0=nr, %o1=addr */ BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 @@ -29,11 +28,9 @@ retl nop 2: BACKOFF_SPIN(%o3, %o4, 1b) - .size test_and_set_bit, .-test_and_set_bit +ENDPROC(test_and_set_bit) - .globl test_and_clear_bit - .type test_and_clear_bit,#function -test_and_clear_bit: /* %o0=nr, %o1=addr */ +ENTRY(test_and_clear_bit) /* %o0=nr, %o1=addr */ BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 @@ -52,11 +49,9 @@ retl nop 2: BACKOFF_SPIN(%o3, %o4, 1b) - .size test_and_clear_bit, .-test_and_clear_bit +ENDPROC(test_and_clear_bit) - .globl test_and_change_bit - .type test_and_change_bit,#function -test_and_change_bit: /* %o0=nr, %o1=addr */ +ENTRY(test_and_change_bit) /* %o0=nr, %o1=addr */ BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 @@ -75,11 +70,9 @@ retl nop 2: BACKOFF_SPIN(%o3, %o4, 1b) - .size test_and_change_bit, .-test_and_change_bit +ENDPROC(test_and_change_bit) - .globl set_bit - .type set_bit,#function -set_bit: /* %o0=nr, %o1=addr */ +ENTRY(set_bit) /* %o0=nr, %o1=addr */ BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 @@ -96,11 +89,9 @@ retl nop 2: BACKOFF_SPIN(%o3, %o4, 1b) - .size set_bit, .-set_bit +ENDPROC(set_bit) - .globl clear_bit - .type clear_bit,#function -clear_bit: /* %o0=nr, %o1=addr */ +ENTRY(clear_bit) /* %o0=nr, %o1=addr */ BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 @@ -117,11 +108,9 @@ retl nop 2: BACKOFF_SPIN(%o3, %o4, 1b) - .size clear_bit, .-clear_bit +ENDPROC(clear_bit) - .globl change_bit - .type change_bit,#function -change_bit: /* %o0=nr, %o1=addr */ +ENTRY(change_bit) /* %o0=nr, %o1=addr */ BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 @@ -138,4 +127,4 @@ retl nop 2: BACKOFF_SPIN(%o3, %o4, 1b) - .size change_bit, .-change_bit +ENDPROC(change_bit)
diff --git a/arch/sparc/lib/blockops.S b/arch/sparc/lib/blockops.S index 804be87..3c77101 100644 --- a/arch/sparc/lib/blockops.S +++ b/arch/sparc/lib/blockops.S
@@ -4,6 +4,7 @@ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) */ +#include <linux/linkage.h> #include <asm/page.h> /* Zero out 64 bytes of memory at (buf + offset). @@ -44,10 +45,7 @@ */ .text - .align 4 - .globl bzero_1page, __copy_1page - -bzero_1page: +ENTRY(bzero_1page) /* NOTE: If you change the number of insns of this routine, please check * arch/sparc/mm/hypersparc.S */ /* %o0 = buf */ @@ -65,8 +63,9 @@ retl nop +ENDPROC(bzero_1page) -__copy_1page: +ENTRY(__copy_1page) /* NOTE: If you change the number of insns of this routine, please check * arch/sparc/mm/hypersparc.S */ /* %o0 = dst, %o1 = src */ @@ -87,3 +86,4 @@ retl nop +ENDPROC(__copy_1page)
diff --git a/arch/sparc/lib/bzero.S b/arch/sparc/lib/bzero.S index 615f401..8c05811 100644 --- a/arch/sparc/lib/bzero.S +++ b/arch/sparc/lib/bzero.S
@@ -4,11 +4,11 @@ * Copyright (C) 2005 David S. Miller <davem@davemloft.net> */ +#include <linux/linkage.h> + .text - .globl memset - .type memset, #function -memset: /* %o0=buf, %o1=pat, %o2=len */ +ENTRY(memset) /* %o0=buf, %o1=pat, %o2=len */ and %o1, 0xff, %o3 mov %o2, %o1 sllx %o3, 8, %g1 @@ -19,9 +19,7 @@ ba,pt %xcc, 1f or %g1, %o2, %o2 - .globl __bzero - .type __bzero, #function -__bzero: /* %o0=buf, %o1=len */ +ENTRY(__bzero) /* %o0=buf, %o1=len */ clr %o2 1: mov %o0, %o3 brz,pn %o1, __bzero_done @@ -78,8 +76,8 @@ __bzero_done: retl mov %o3, %o0 - .size __bzero, .-__bzero - .size memset, .-memset +ENDPROC(__bzero) +ENDPROC(memset) #define EX_ST(x,y) \ 98: x,y; \ @@ -89,9 +87,7 @@ .text; \ .align 4; - .globl __clear_user - .type __clear_user, #function -__clear_user: /* %o0=buf, %o1=len */ +ENTRY(__clear_user) /* %o0=buf, %o1=len */ brz,pn %o1, __clear_user_done cmp %o1, 16 bl,pn %icc, __clear_user_tiny @@ -146,4 +142,4 @@ __clear_user_done: retl clr %o0 - .size __clear_user, .-__clear_user +ENDPROC(__clear_user)
diff --git a/arch/sparc/lib/divdi3.S b/arch/sparc/lib/divdi3.S index d74bc09..9614b48 100644 --- a/arch/sparc/lib/divdi3.S +++ b/arch/sparc/lib/divdi3.S
@@ -19,7 +19,6 @@ .text .align 4 - .global .udiv .globl __divdi3 __divdi3: save %sp,-104,%sp @@ -83,8 +82,9 @@ bne .LL85 mov %i0,%o2 mov 1,%o0 - call .udiv,0 mov 0,%o1 + wr %g0, 0, %y + udiv %o0, %o1, %o0 mov %o0,%o4 mov %i0,%o2 .LL85:
diff --git a/arch/sparc/lib/ipcsum.S b/arch/sparc/lib/ipcsum.S index 58ca5b9..4742d59 100644 --- a/arch/sparc/lib/ipcsum.S +++ b/arch/sparc/lib/ipcsum.S
@@ -1,8 +1,7 @@ +#include <linux/linkage.h> + .text - .align 32 - .globl ip_fast_csum - .type ip_fast_csum,#function -ip_fast_csum: /* %o0 = iph, %o1 = ihl */ +ENTRY(ip_fast_csum) /* %o0 = iph, %o1 = ihl */ sub %o1, 4, %g7 lduw [%o0 + 0x00], %o2 lduw [%o0 + 0x04], %g2 @@ -31,4 +30,4 @@ set 0xffff, %o1 retl and %o2, %o1, %o0 - .size ip_fast_csum, .-ip_fast_csum +ENDPROC(ip_fast_csum)
diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c index f73c224..2dc3087 100644 --- a/arch/sparc/lib/ksyms.c +++ b/arch/sparc/lib/ksyms.c
@@ -56,23 +56,11 @@ extern void (*__copy_1page)(void *, const void *); extern void (*bzero_1page)(void *); -extern int __strncmp(const char *, const char *, __kernel_size_t); - extern void ___rw_read_enter(void); extern void ___rw_read_try(void); extern void ___rw_read_exit(void); extern void ___rw_write_enter(void); -/* Alias functions whose names begin with "." and export the aliases. - * The module references will be fixed up by module_frob_arch_sections. - */ -extern int _Div(int, int); -extern int _Mul(int, int); -extern int _Rem(int, int); -extern unsigned _Udiv(unsigned, unsigned); -extern unsigned _Umul(unsigned, unsigned); -extern unsigned _Urem(unsigned, unsigned); - /* Networking helper routines. */ EXPORT_SYMBOL(__csum_partial_copy_sparc_generic); @@ -81,9 +69,6 @@ EXPORT_SYMBOL(__memmove); EXPORT_SYMBOL(bzero_1page); -/* string functions */ -EXPORT_SYMBOL(__strncmp); - /* Moving data to/from/in userspace. */ EXPORT_SYMBOL(__copy_user); @@ -100,13 +85,6 @@ EXPORT_SYMBOL(__lshrdi3); EXPORT_SYMBOL(__muldi3); EXPORT_SYMBOL(__divdi3); - -EXPORT_SYMBOL(_Rem); -EXPORT_SYMBOL(_Urem); -EXPORT_SYMBOL(_Mul); -EXPORT_SYMBOL(_Umul); -EXPORT_SYMBOL(_Div); -EXPORT_SYMBOL(_Udiv); #endif /*
diff --git a/arch/sparc/lib/lshrdi3.S b/arch/sparc/lib/lshrdi3.S index 47a1354..60ebc7c 100644 --- a/arch/sparc/lib/lshrdi3.S +++ b/arch/sparc/lib/lshrdi3.S
@@ -1,6 +1,6 @@ +#include <linux/linkage.h> - .globl __lshrdi3 -__lshrdi3: +ENTRY(__lshrdi3) cmp %o2, 0 be 3f mov 0x20, %g2 @@ -24,3 +24,4 @@ 3: retl nop +ENDPROC(__lshrdi3)
diff --git a/arch/sparc/lib/memmove.S b/arch/sparc/lib/memmove.S index 9739580..b7f6334 100644 --- a/arch/sparc/lib/memmove.S +++ b/arch/sparc/lib/memmove.S
@@ -4,11 +4,10 @@ * Copyright (C) 1996, 1997, 1998, 1999 Jakub Jelinek (jj@ultra.linux.cz) */ +#include <linux/linkage.h> + .text - .align 32 - .globl memmove - .type memmove,#function -memmove: /* o0=dst o1=src o2=len */ +ENTRY(memmove) /* o0=dst o1=src o2=len */ mov %o0, %g1 cmp %o0, %o1 bleu,pt %xcc, memcpy @@ -28,4 +27,4 @@ retl mov %g1, %o0 - .size memmove, .-memmove +ENDPROC(memmove)
diff --git a/arch/sparc/lib/mul.S b/arch/sparc/lib/mul.S deleted file mode 100644 index c45470d..0000000 --- a/arch/sparc/lib/mul.S +++ /dev/null
@@ -1,137 +0,0 @@ -/* - * mul.S: This routine was taken from glibc-1.09 and is covered - * by the GNU Library General Public License Version 2. - */ - -/* - * Signed multiply, from Appendix E of the Sparc Version 8 - * Architecture Manual. - */ - -/* - * Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the upper 32 bits of - * the 64-bit product). - * - * This code optimizes short (less than 13-bit) multiplies. - */ - - .globl .mul - .globl _Mul -.mul: -_Mul: /* needed for export */ - mov %o0, %y ! multiplier -> Y - andncc %o0, 0xfff, %g0 ! test bits 12..31 - be Lmul_shortway ! if zero, can do it the short way - andcc %g0, %g0, %o4 ! zero the partial product and clear N and V - - /* - * Long multiply. 32 steps, followed by a final shift step. - */ - mulscc %o4, %o1, %o4 ! 1 - mulscc %o4, %o1, %o4 ! 2 - mulscc %o4, %o1, %o4 ! 3 - mulscc %o4, %o1, %o4 ! 4 - mulscc %o4, %o1, %o4 ! 5 - mulscc %o4, %o1, %o4 ! 6 - mulscc %o4, %o1, %o4 ! 7 - mulscc %o4, %o1, %o4 ! 8 - mulscc %o4, %o1, %o4 ! 9 - mulscc %o4, %o1, %o4 ! 10 - mulscc %o4, %o1, %o4 ! 11 - mulscc %o4, %o1, %o4 ! 12 - mulscc %o4, %o1, %o4 ! 13 - mulscc %o4, %o1, %o4 ! 14 - mulscc %o4, %o1, %o4 ! 15 - mulscc %o4, %o1, %o4 ! 16 - mulscc %o4, %o1, %o4 ! 17 - mulscc %o4, %o1, %o4 ! 18 - mulscc %o4, %o1, %o4 ! 19 - mulscc %o4, %o1, %o4 ! 20 - mulscc %o4, %o1, %o4 ! 21 - mulscc %o4, %o1, %o4 ! 22 - mulscc %o4, %o1, %o4 ! 23 - mulscc %o4, %o1, %o4 ! 24 - mulscc %o4, %o1, %o4 ! 25 - mulscc %o4, %o1, %o4 ! 26 - mulscc %o4, %o1, %o4 ! 27 - mulscc %o4, %o1, %o4 ! 28 - mulscc %o4, %o1, %o4 ! 29 - mulscc %o4, %o1, %o4 ! 30 - mulscc %o4, %o1, %o4 ! 31 - mulscc %o4, %o1, %o4 ! 32 - mulscc %o4, %g0, %o4 ! final shift - - ! If %o0 was negative, the result is - ! (%o0 * %o1) + (%o1 << 32)) - ! We fix that here. - -#if 0 - tst %o0 - bge 1f - rd %y, %o0 - - ! %o0 was indeed negative; fix upper 32 bits of result by subtracting - ! %o1 (i.e., return %o4 - %o1 in %o1). - retl - sub %o4, %o1, %o1 - -1: - retl - mov %o4, %o1 -#else - /* Faster code adapted from tege@sics.se's code for umul.S. */ - sra %o0, 31, %o2 ! make mask from sign bit - and %o1, %o2, %o2 ! %o2 = 0 or %o1, depending on sign of %o0 - rd %y, %o0 ! get lower half of product - retl - sub %o4, %o2, %o1 ! subtract compensation - ! and put upper half in place -#endif - -Lmul_shortway: - /* - * Short multiply. 12 steps, followed by a final shift step. - * The resulting bits are off by 12 and (32-12) = 20 bit positions, - * but there is no problem with %o0 being negative (unlike above). - */ - mulscc %o4, %o1, %o4 ! 1 - mulscc %o4, %o1, %o4 ! 2 - mulscc %o4, %o1, %o4 ! 3 - mulscc %o4, %o1, %o4 ! 4 - mulscc %o4, %o1, %o4 ! 5 - mulscc %o4, %o1, %o4 ! 6 - mulscc %o4, %o1, %o4 ! 7 - mulscc %o4, %o1, %o4 ! 8 - mulscc %o4, %o1, %o4 ! 9 - mulscc %o4, %o1, %o4 ! 10 - mulscc %o4, %o1, %o4 ! 11 - mulscc %o4, %o1, %o4 ! 12 - mulscc %o4, %g0, %o4 ! final shift - - /* - * %o4 has 20 of the bits that should be in the low part of the - * result; %y has the bottom 12 (as %y's top 12). That is: - * - * %o4 %y - * +----------------+----------------+ - * | -12- | -20- | -12- | -20- | - * +------(---------+------)---------+ - * --hi-- ----low-part---- - * - * The upper 12 bits of %o4 should be sign-extended to form the - * high part of the product (i.e., highpart = %o4 >> 20). - */ - - rd %y, %o5 - sll %o4, 12, %o0 ! shift middle bits left 12 - srl %o5, 20, %o5 ! shift low bits right 20, zero fill at left - or %o5, %o0, %o0 ! construct low part of result - retl - sra %o4, 20, %o1 ! ... and extract high part of result - - .globl .mul_patch -.mul_patch: - smul %o0, %o1, %o0 - retl - rd %y, %o1 - nop
diff --git a/arch/sparc/lib/muldi3.S b/arch/sparc/lib/muldi3.S index 7f17872..9794939 100644 --- a/arch/sparc/lib/muldi3.S +++ b/arch/sparc/lib/muldi3.S
@@ -63,12 +63,12 @@ rd %y, %o1 mov %o1, %l3 mov %i1, %o0 - call .umul mov %i2, %o1 + umul %o0, %o1, %o0 mov %o0, %l0 mov %i0, %o0 - call .umul mov %i3, %o1 + umul %o0, %o1, %o0 add %l0, %o0, %l0 mov %l2, %i0 add %l2, %l0, %i0
diff --git a/arch/sparc/lib/rem.S b/arch/sparc/lib/rem.S deleted file mode 100644 index 42fb862..0000000 --- a/arch/sparc/lib/rem.S +++ /dev/null
@@ -1,384 +0,0 @@ -/* - * rem.S: This routine was taken from glibc-1.09 and is covered - * by the GNU Library General Public License Version 2. - */ - - -/* This file is generated from divrem.m4; DO NOT EDIT! */ -/* - * Division and remainder, from Appendix E of the Sparc Version 8 - * Architecture Manual, with fixes from Gordon Irlam. - */ - -/* - * Input: dividend and divisor in %o0 and %o1 respectively. - * - * m4 parameters: - * .rem name of function to generate - * rem rem=div => %o0 / %o1; rem=rem => %o0 % %o1 - * true true=true => signed; true=false => unsigned - * - * Algorithm parameters: - * N how many bits per iteration we try to get (4) - * WORDSIZE total number of bits (32) - * - * Derived constants: - * TOPBITS number of bits in the top decade of a number - * - * Important variables: - * Q the partial quotient under development (initially 0) - * R the remainder so far, initially the dividend - * ITER number of main division loop iterations required; - * equal to ceil(log2(quotient) / N). Note that this - * is the log base (2^N) of the quotient. - * V the current comparand, initially divisor*2^(ITER*N-1) - * - * Cost: - * Current estimate for non-large dividend is - * ceil(log2(quotient) / N) * (10 + 7N/2) + C - * A large dividend is one greater than 2^(31-TOPBITS) and takes a - * different path, as the upper bits of the quotient must be developed - * one bit at a time. - */ - - - .globl .rem - .globl _Rem -.rem: -_Rem: /* needed for export */ - ! compute sign of result; if neither is negative, no problem - orcc %o1, %o0, %g0 ! either negative? - bge 2f ! no, go do the divide - mov %o0, %g2 ! compute sign in any case - - tst %o1 - bge 1f - tst %o0 - ! %o1 is definitely negative; %o0 might also be negative - bge 2f ! if %o0 not negative... - sub %g0, %o1, %o1 ! in any case, make %o1 nonneg -1: ! %o0 is negative, %o1 is nonnegative - sub %g0, %o0, %o0 ! make %o0 nonnegative -2: - - ! Ready to divide. Compute size of quotient; scale comparand. - orcc %o1, %g0, %o5 - bne 1f - mov %o0, %o3 - - ! Divide by zero trap. If it returns, return 0 (about as - ! wrong as possible, but that is what SunOS does...). - ta ST_DIV0 - retl - clr %o0 - -1: - cmp %o3, %o5 ! if %o1 exceeds %o0, done - blu Lgot_result ! (and algorithm fails otherwise) - clr %o2 - - sethi %hi(1 << (32 - 4 - 1)), %g1 - - cmp %o3, %g1 - blu Lnot_really_big - clr %o4 - - ! Here the dividend is >= 2**(31-N) or so. We must be careful here, - ! as our usual N-at-a-shot divide step will cause overflow and havoc. - ! The number of bits in the result here is N*ITER+SC, where SC <= N. - ! Compute ITER in an unorthodox manner: know we need to shift V into - ! the top decade: so do not even bother to compare to R. - 1: - cmp %o5, %g1 - bgeu 3f - mov 1, %g7 - - sll %o5, 4, %o5 - - b 1b - add %o4, 1, %o4 - - ! Now compute %g7. - 2: - addcc %o5, %o5, %o5 - - bcc Lnot_too_big - add %g7, 1, %g7 - - ! We get here if the %o1 overflowed while shifting. - ! This means that %o3 has the high-order bit set. - ! Restore %o5 and subtract from %o3. - sll %g1, 4, %g1 ! high order bit - srl %o5, 1, %o5 ! rest of %o5 - add %o5, %g1, %o5 - - b Ldo_single_div - sub %g7, 1, %g7 - - Lnot_too_big: - 3: - cmp %o5, %o3 - blu 2b - nop - - be Ldo_single_div - nop - /* NB: these are commented out in the V8-Sparc manual as well */ - /* (I do not understand this) */ - ! %o5 > %o3: went too far: back up 1 step - ! srl %o5, 1, %o5 - ! dec %g7 - ! do single-bit divide steps - ! - ! We have to be careful here. We know that %o3 >= %o5, so we can do the - ! first divide step without thinking. BUT, the others are conditional, - ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- - ! order bit set in the first step, just falling into the regular - ! division loop will mess up the first time around. - ! So we unroll slightly... - Ldo_single_div: - subcc %g7, 1, %g7 - bl Lend_regular_divide - nop - - sub %o3, %o5, %o3 - mov 1, %o2 - - b Lend_single_divloop - nop - Lsingle_divloop: - sll %o2, 1, %o2 - - bl 1f - srl %o5, 1, %o5 - ! %o3 >= 0 - sub %o3, %o5, %o3 - - b 2f - add %o2, 1, %o2 - 1: ! %o3 < 0 - add %o3, %o5, %o3 - sub %o2, 1, %o2 - 2: - Lend_single_divloop: - subcc %g7, 1, %g7 - bge Lsingle_divloop - tst %o3 - - b,a Lend_regular_divide - -Lnot_really_big: -1: - sll %o5, 4, %o5 - cmp %o5, %o3 - bleu 1b - addcc %o4, 1, %o4 - be Lgot_result - sub %o4, 1, %o4 - - tst %o3 ! set up for initial iteration -Ldivloop: - sll %o2, 4, %o2 - ! depth 1, accumulated bits 0 - bl L.1.16 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 2, accumulated bits 1 - bl L.2.17 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 3, accumulated bits 3 - bl L.3.19 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits 7 - bl L.4.23 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - - b 9f - add %o2, (7*2+1), %o2 - -L.4.23: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (7*2-1), %o2 - -L.3.19: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits 5 - bl L.4.21 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (5*2+1), %o2 - -L.4.21: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (5*2-1), %o2 - -L.2.17: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 3, accumulated bits 1 - bl L.3.17 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits 3 - bl L.4.19 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (3*2+1), %o2 - -L.4.19: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (3*2-1), %o2 - -L.3.17: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits 1 - bl L.4.17 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (1*2+1), %o2 - -L.4.17: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (1*2-1), %o2 - -L.1.16: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 2, accumulated bits -1 - bl L.2.15 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 3, accumulated bits -1 - bl L.3.15 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits -1 - bl L.4.15 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-1*2+1), %o2 - -L.4.15: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-1*2-1), %o2 - -L.3.15: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits -3 - bl L.4.13 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-3*2+1), %o2 - -L.4.13: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-3*2-1), %o2 - -L.2.15: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 3, accumulated bits -3 - bl L.3.13 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits -5 - bl L.4.11 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-5*2+1), %o2 - -L.4.11: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-5*2-1), %o2 - - -L.3.13: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits -7 - bl L.4.9 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-7*2+1), %o2 - -L.4.9: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-7*2-1), %o2 - - 9: -Lend_regular_divide: - subcc %o4, 1, %o4 - bge Ldivloop - tst %o3 - - bl,a Lgot_result - ! non-restoring fixup here (one instruction only!) - add %o3, %o1, %o3 - -Lgot_result: - ! check to see if answer should be < 0 - tst %g2 - bl,a 1f - sub %g0, %o3, %o3 -1: - retl - mov %o3, %o0 - - .globl .rem_patch -.rem_patch: - sra %o0, 0x1f, %o4 - wr %o4, 0x0, %y - nop - nop - nop - sdivcc %o0, %o1, %o2 - bvs,a 1f - xnor %o2, %g0, %o2 -1: smul %o2, %o1, %o2 - retl - sub %o0, %o2, %o0 - nop
diff --git a/arch/sparc/lib/sdiv.S b/arch/sparc/lib/sdiv.S deleted file mode 100644 index f0a0d4e..0000000 --- a/arch/sparc/lib/sdiv.S +++ /dev/null
@@ -1,381 +0,0 @@ -/* - * sdiv.S: This routine was taken from glibc-1.09 and is covered - * by the GNU Library General Public License Version 2. - */ - - -/* This file is generated from divrem.m4; DO NOT EDIT! */ -/* - * Division and remainder, from Appendix E of the Sparc Version 8 - * Architecture Manual, with fixes from Gordon Irlam. - */ - -/* - * Input: dividend and divisor in %o0 and %o1 respectively. - * - * m4 parameters: - * .div name of function to generate - * div div=div => %o0 / %o1; div=rem => %o0 % %o1 - * true true=true => signed; true=false => unsigned - * - * Algorithm parameters: - * N how many bits per iteration we try to get (4) - * WORDSIZE total number of bits (32) - * - * Derived constants: - * TOPBITS number of bits in the top decade of a number - * - * Important variables: - * Q the partial quotient under development (initially 0) - * R the remainder so far, initially the dividend - * ITER number of main division loop iterations required; - * equal to ceil(log2(quotient) / N). Note that this - * is the log base (2^N) of the quotient. - * V the current comparand, initially divisor*2^(ITER*N-1) - * - * Cost: - * Current estimate for non-large dividend is - * ceil(log2(quotient) / N) * (10 + 7N/2) + C - * A large dividend is one greater than 2^(31-TOPBITS) and takes a - * different path, as the upper bits of the quotient must be developed - * one bit at a time. - */ - - - .globl .div - .globl _Div -.div: -_Div: /* needed for export */ - ! compute sign of result; if neither is negative, no problem - orcc %o1, %o0, %g0 ! either negative? - bge 2f ! no, go do the divide - xor %o1, %o0, %g2 ! compute sign in any case - - tst %o1 - bge 1f - tst %o0 - ! %o1 is definitely negative; %o0 might also be negative - bge 2f ! if %o0 not negative... - sub %g0, %o1, %o1 ! in any case, make %o1 nonneg -1: ! %o0 is negative, %o1 is nonnegative - sub %g0, %o0, %o0 ! make %o0 nonnegative -2: - - ! Ready to divide. Compute size of quotient; scale comparand. - orcc %o1, %g0, %o5 - bne 1f - mov %o0, %o3 - - ! Divide by zero trap. If it returns, return 0 (about as - ! wrong as possible, but that is what SunOS does...). - ta ST_DIV0 - retl - clr %o0 - -1: - cmp %o3, %o5 ! if %o1 exceeds %o0, done - blu Lgot_result ! (and algorithm fails otherwise) - clr %o2 - - sethi %hi(1 << (32 - 4 - 1)), %g1 - - cmp %o3, %g1 - blu Lnot_really_big - clr %o4 - - ! Here the dividend is >= 2**(31-N) or so. We must be careful here, - ! as our usual N-at-a-shot divide step will cause overflow and havoc. - ! The number of bits in the result here is N*ITER+SC, where SC <= N. - ! Compute ITER in an unorthodox manner: know we need to shift V into - ! the top decade: so do not even bother to compare to R. - 1: - cmp %o5, %g1 - bgeu 3f - mov 1, %g7 - - sll %o5, 4, %o5 - - b 1b - add %o4, 1, %o4 - - ! Now compute %g7. - 2: - addcc %o5, %o5, %o5 - bcc Lnot_too_big - add %g7, 1, %g7 - - ! We get here if the %o1 overflowed while shifting. - ! This means that %o3 has the high-order bit set. - ! Restore %o5 and subtract from %o3. - sll %g1, 4, %g1 ! high order bit - srl %o5, 1, %o5 ! rest of %o5 - add %o5, %g1, %o5 - - b Ldo_single_div - sub %g7, 1, %g7 - - Lnot_too_big: - 3: - cmp %o5, %o3 - blu 2b - nop - - be Ldo_single_div - nop - /* NB: these are commented out in the V8-Sparc manual as well */ - /* (I do not understand this) */ - ! %o5 > %o3: went too far: back up 1 step - ! srl %o5, 1, %o5 - ! dec %g7 - ! do single-bit divide steps - ! - ! We have to be careful here. We know that %o3 >= %o5, so we can do the - ! first divide step without thinking. BUT, the others are conditional, - ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- - ! order bit set in the first step, just falling into the regular - ! division loop will mess up the first time around. - ! So we unroll slightly... - Ldo_single_div: - subcc %g7, 1, %g7 - bl Lend_regular_divide - nop - - sub %o3, %o5, %o3 - mov 1, %o2 - - b Lend_single_divloop - nop - Lsingle_divloop: - sll %o2, 1, %o2 - - bl 1f - srl %o5, 1, %o5 - ! %o3 >= 0 - sub %o3, %o5, %o3 - - b 2f - add %o2, 1, %o2 - 1: ! %o3 < 0 - add %o3, %o5, %o3 - sub %o2, 1, %o2 - 2: - Lend_single_divloop: - subcc %g7, 1, %g7 - bge Lsingle_divloop - tst %o3 - - b,a Lend_regular_divide - -Lnot_really_big: -1: - sll %o5, 4, %o5 - cmp %o5, %o3 - bleu 1b - addcc %o4, 1, %o4 - - be Lgot_result - sub %o4, 1, %o4 - - tst %o3 ! set up for initial iteration -Ldivloop: - sll %o2, 4, %o2 - ! depth 1, accumulated bits 0 - bl L.1.16 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 2, accumulated bits 1 - bl L.2.17 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 3, accumulated bits 3 - bl L.3.19 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits 7 - bl L.4.23 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (7*2+1), %o2 - -L.4.23: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (7*2-1), %o2 - -L.3.19: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits 5 - bl L.4.21 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (5*2+1), %o2 - -L.4.21: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (5*2-1), %o2 - -L.2.17: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 3, accumulated bits 1 - bl L.3.17 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits 3 - bl L.4.19 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (3*2+1), %o2 - -L.4.19: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (3*2-1), %o2 - - -L.3.17: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits 1 - bl L.4.17 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (1*2+1), %o2 - -L.4.17: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (1*2-1), %o2 - -L.1.16: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 2, accumulated bits -1 - bl L.2.15 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 3, accumulated bits -1 - bl L.3.15 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits -1 - bl L.4.15 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-1*2+1), %o2 - -L.4.15: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-1*2-1), %o2 - -L.3.15: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits -3 - bl L.4.13 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-3*2+1), %o2 - -L.4.13: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-3*2-1), %o2 - -L.2.15: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 3, accumulated bits -3 - bl L.3.13 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits -5 - bl L.4.11 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-5*2+1), %o2 - -L.4.11: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-5*2-1), %o2 - -L.3.13: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits -7 - bl L.4.9 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-7*2+1), %o2 - -L.4.9: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-7*2-1), %o2 - - 9: -Lend_regular_divide: - subcc %o4, 1, %o4 - bge Ldivloop - tst %o3 - - bl,a Lgot_result - ! non-restoring fixup here (one instruction only!) - sub %o2, 1, %o2 - -Lgot_result: - ! check to see if answer should be < 0 - tst %g2 - bl,a 1f - sub %g0, %o2, %o2 -1: - retl - mov %o2, %o0 - - .globl .div_patch -.div_patch: - sra %o0, 0x1f, %o2 - wr %o2, 0x0, %y - nop - nop - nop - sdivcc %o0, %o1, %o0 - bvs,a 1f - xnor %o0, %g0, %o0 -1: retl - nop
diff --git a/arch/sparc/lib/strlen_user_64.S b/arch/sparc/lib/strlen_user_64.S index 114ed11..c3df71f 100644 --- a/arch/sparc/lib/strlen_user_64.S +++ b/arch/sparc/lib/strlen_user_64.S
@@ -8,16 +8,16 @@ * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) */ +#include <linux/linkage.h> #include <asm/asi.h> #define LO_MAGIC 0x01010101 #define HI_MAGIC 0x80808080 .align 4 - .global __strlen_user, __strnlen_user -__strlen_user: +ENTRY(__strlen_user) sethi %hi(32768), %o1 -__strnlen_user: +ENTRY(__strnlen_user) mov %o1, %g1 mov %o0, %o1 andcc %o0, 3, %g0 @@ -78,6 +78,8 @@ mov 2, %o0 23: retl mov 3, %o0 +ENDPROC(__strlen_user) +ENDPROC(__strnlen_user) .section .fixup,#alloc,#execinstr .align 4
diff --git a/arch/sparc/lib/strncmp_32.S b/arch/sparc/lib/strncmp_32.S index 494ec66..c0d1b56 100644 --- a/arch/sparc/lib/strncmp_32.S +++ b/arch/sparc/lib/strncmp_32.S
@@ -3,11 +3,10 @@ * generic strncmp routine. */ +#include <linux/linkage.h> + .text - .align 4 - .global __strncmp, strncmp -__strncmp: -strncmp: +ENTRY(strncmp) mov %o0, %g3 mov 0, %o3 @@ -116,3 +115,4 @@ and %g2, 0xff, %o0 retl sub %o3, %o0, %o0 +ENDPROC(strncmp)
diff --git a/arch/sparc/lib/strncmp_64.S b/arch/sparc/lib/strncmp_64.S index 980e837..0656627 100644 --- a/arch/sparc/lib/strncmp_64.S +++ b/arch/sparc/lib/strncmp_64.S
@@ -4,13 +4,11 @@ * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) */ +#include <linux/linkage.h> #include <asm/asi.h> .text - .align 32 - .globl strncmp - .type strncmp,#function -strncmp: +ENTRY(strncmp) brlez,pn %o2, 3f lduba [%o0] (ASI_PNF), %o3 1: @@ -29,4 +27,4 @@ 3: retl clr %o0 - .size strncmp, .-strncmp +ENDPROC(strncmp)
diff --git a/arch/sparc/lib/strncpy_from_user_32.S b/arch/sparc/lib/strncpy_from_user_32.S index d771989..db0ed29 100644 --- a/arch/sparc/lib/strncpy_from_user_32.S +++ b/arch/sparc/lib/strncpy_from_user_32.S
@@ -3,11 +3,11 @@ * Copyright(C) 1996 David S. Miller */ +#include <linux/linkage.h> #include <asm/ptrace.h> #include <asm/errno.h> .text - .align 4 /* Must return: * @@ -16,8 +16,7 @@ * bytes copied if we hit a null byte */ - .globl __strncpy_from_user -__strncpy_from_user: +ENTRY(__strncpy_from_user) /* %o0=dest, %o1=src, %o2=count */ mov %o2, %o3 1: @@ -35,6 +34,7 @@ add %o2, 1, %o0 retl sub %o3, %o0, %o0 +ENDPROC(__strncpy_from_user) .section .fixup,#alloc,#execinstr .align 4
diff --git a/arch/sparc/lib/strncpy_from_user_64.S b/arch/sparc/lib/strncpy_from_user_64.S index 511c8f1..d1246b7 100644 --- a/arch/sparc/lib/strncpy_from_user_64.S +++ b/arch/sparc/lib/strncpy_from_user_64.S
@@ -4,6 +4,7 @@ * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz) */ +#include <linux/linkage.h> #include <asm/asi.h> #include <asm/errno.h> @@ -12,7 +13,6 @@ 0: .xword 0x0101010101010101 .text - .align 32 /* Must return: * @@ -30,9 +30,7 @@ * and average length is 18 or so. */ - .globl __strncpy_from_user - .type __strncpy_from_user,#function -__strncpy_from_user: +ENTRY(__strncpy_from_user) /* %o0=dest, %o1=src, %o2=count */ andcc %o1, 7, %g0 ! IEU1 Group bne,pn %icc, 30f ! CTI @@ -123,7 +121,7 @@ mov %o2, %o0 2: retl add %o2, %o3, %o0 - .size __strncpy_from_user, .-__strncpy_from_user +ENDPROC(__strncpy_from_user) .section __ex_table,"a" .align 4
diff --git a/arch/sparc/lib/ucmpdi2.c b/arch/sparc/lib/ucmpdi2.c new file mode 100644 index 0000000..1e06ed5 --- /dev/null +++ b/arch/sparc/lib/ucmpdi2.c
@@ -0,0 +1,19 @@ +#include <linux/module.h> +#include "libgcc.h" + +word_type __ucmpdi2(unsigned long long a, unsigned long long b) +{ + const DWunion au = {.ll = a}; + const DWunion bu = {.ll = b}; + + if ((unsigned int) au.s.high < (unsigned int) bu.s.high) + return 0; + else if ((unsigned int) au.s.high > (unsigned int) bu.s.high) + return 2; + if ((unsigned int) au.s.low < (unsigned int) bu.s.low) + return 0; + else if ((unsigned int) au.s.low > (unsigned int) bu.s.low) + return 2; + return 1; +} +EXPORT_SYMBOL(__ucmpdi2);
diff --git a/arch/sparc/lib/udiv.S b/arch/sparc/lib/udiv.S deleted file mode 100644 index 2101405..0000000 --- a/arch/sparc/lib/udiv.S +++ /dev/null
@@ -1,357 +0,0 @@ -/* - * udiv.S: This routine was taken from glibc-1.09 and is covered - * by the GNU Library General Public License Version 2. - */ - - -/* This file is generated from divrem.m4; DO NOT EDIT! */ -/* - * Division and remainder, from Appendix E of the Sparc Version 8 - * Architecture Manual, with fixes from Gordon Irlam. - */ - -/* - * Input: dividend and divisor in %o0 and %o1 respectively. - * - * m4 parameters: - * .udiv name of function to generate - * div div=div => %o0 / %o1; div=rem => %o0 % %o1 - * false false=true => signed; false=false => unsigned - * - * Algorithm parameters: - * N how many bits per iteration we try to get (4) - * WORDSIZE total number of bits (32) - * - * Derived constants: - * TOPBITS number of bits in the top decade of a number - * - * Important variables: - * Q the partial quotient under development (initially 0) - * R the remainder so far, initially the dividend - * ITER number of main division loop iterations required; - * equal to ceil(log2(quotient) / N). Note that this - * is the log base (2^N) of the quotient. - * V the current comparand, initially divisor*2^(ITER*N-1) - * - * Cost: - * Current estimate for non-large dividend is - * ceil(log2(quotient) / N) * (10 + 7N/2) + C - * A large dividend is one greater than 2^(31-TOPBITS) and takes a - * different path, as the upper bits of the quotient must be developed - * one bit at a time. - */ - - - .globl .udiv - .globl _Udiv -.udiv: -_Udiv: /* needed for export */ - - ! Ready to divide. Compute size of quotient; scale comparand. - orcc %o1, %g0, %o5 - bne 1f - mov %o0, %o3 - - ! Divide by zero trap. If it returns, return 0 (about as - ! wrong as possible, but that is what SunOS does...). - ta ST_DIV0 - retl - clr %o0 - -1: - cmp %o3, %o5 ! if %o1 exceeds %o0, done - blu Lgot_result ! (and algorithm fails otherwise) - clr %o2 - - sethi %hi(1 << (32 - 4 - 1)), %g1 - - cmp %o3, %g1 - blu Lnot_really_big - clr %o4 - - ! Here the dividend is >= 2**(31-N) or so. We must be careful here, - ! as our usual N-at-a-shot divide step will cause overflow and havoc. - ! The number of bits in the result here is N*ITER+SC, where SC <= N. - ! Compute ITER in an unorthodox manner: know we need to shift V into - ! the top decade: so do not even bother to compare to R. - 1: - cmp %o5, %g1 - bgeu 3f - mov 1, %g7 - - sll %o5, 4, %o5 - - b 1b - add %o4, 1, %o4 - - ! Now compute %g7. - 2: - addcc %o5, %o5, %o5 - bcc Lnot_too_big - add %g7, 1, %g7 - - ! We get here if the %o1 overflowed while shifting. - ! This means that %o3 has the high-order bit set. - ! Restore %o5 and subtract from %o3. - sll %g1, 4, %g1 ! high order bit - srl %o5, 1, %o5 ! rest of %o5 - add %o5, %g1, %o5 - - b Ldo_single_div - sub %g7, 1, %g7 - - Lnot_too_big: - 3: - cmp %o5, %o3 - blu 2b - nop - - be Ldo_single_div - nop - /* NB: these are commented out in the V8-Sparc manual as well */ - /* (I do not understand this) */ - ! %o5 > %o3: went too far: back up 1 step - ! srl %o5, 1, %o5 - ! dec %g7 - ! do single-bit divide steps - ! - ! We have to be careful here. We know that %o3 >= %o5, so we can do the - ! first divide step without thinking. BUT, the others are conditional, - ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- - ! order bit set in the first step, just falling into the regular - ! division loop will mess up the first time around. - ! So we unroll slightly... - Ldo_single_div: - subcc %g7, 1, %g7 - bl Lend_regular_divide - nop - - sub %o3, %o5, %o3 - mov 1, %o2 - - b Lend_single_divloop - nop - Lsingle_divloop: - sll %o2, 1, %o2 - bl 1f - srl %o5, 1, %o5 - ! %o3 >= 0 - sub %o3, %o5, %o3 - b 2f - add %o2, 1, %o2 - 1: ! %o3 < 0 - add %o3, %o5, %o3 - sub %o2, 1, %o2 - 2: - Lend_single_divloop: - subcc %g7, 1, %g7 - bge Lsingle_divloop - tst %o3 - - b,a Lend_regular_divide - -Lnot_really_big: -1: - sll %o5, 4, %o5 - - cmp %o5, %o3 - bleu 1b - addcc %o4, 1, %o4 - - be Lgot_result - sub %o4, 1, %o4 - - tst %o3 ! set up for initial iteration -Ldivloop: - sll %o2, 4, %o2 - ! depth 1, accumulated bits 0 - bl L.1.16 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 2, accumulated bits 1 - bl L.2.17 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 3, accumulated bits 3 - bl L.3.19 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits 7 - bl L.4.23 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (7*2+1), %o2 - -L.4.23: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (7*2-1), %o2 - -L.3.19: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits 5 - bl L.4.21 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (5*2+1), %o2 - -L.4.21: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (5*2-1), %o2 - -L.2.17: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 3, accumulated bits 1 - bl L.3.17 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits 3 - bl L.4.19 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (3*2+1), %o2 - -L.4.19: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (3*2-1), %o2 - -L.3.17: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits 1 - bl L.4.17 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (1*2+1), %o2 - -L.4.17: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (1*2-1), %o2 - -L.1.16: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 2, accumulated bits -1 - bl L.2.15 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 3, accumulated bits -1 - bl L.3.15 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits -1 - bl L.4.15 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-1*2+1), %o2 - -L.4.15: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-1*2-1), %o2 - -L.3.15: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits -3 - bl L.4.13 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-3*2+1), %o2 - -L.4.13: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-3*2-1), %o2 - -L.2.15: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 3, accumulated bits -3 - bl L.3.13 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits -5 - bl L.4.11 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-5*2+1), %o2 - -L.4.11: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-5*2-1), %o2 - -L.3.13: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits -7 - bl L.4.9 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-7*2+1), %o2 - -L.4.9: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-7*2-1), %o2 - - 9: -Lend_regular_divide: - subcc %o4, 1, %o4 - bge Ldivloop - tst %o3 - - bl,a Lgot_result - ! non-restoring fixup here (one instruction only!) - sub %o2, 1, %o2 - -Lgot_result: - - retl - mov %o2, %o0 - - .globl .udiv_patch -.udiv_patch: - wr %g0, 0x0, %y - nop - nop - retl - udiv %o0, %o1, %o0 - nop
diff --git a/arch/sparc/lib/udivdi3.S b/arch/sparc/lib/udivdi3.S index b430f1f..24e0a35 100644 --- a/arch/sparc/lib/udivdi3.S +++ b/arch/sparc/lib/udivdi3.S
@@ -60,8 +60,9 @@ bne .LL77 mov %i0,%o2 mov 1,%o0 - call .udiv,0 mov 0,%o1 + wr %g0, 0, %y + udiv %o0, %o1, %o0 mov %o0,%o3 mov %i0,%o2 .LL77:
diff --git a/arch/sparc/lib/umul.S b/arch/sparc/lib/umul.S deleted file mode 100644 index 1f36ae6..0000000 --- a/arch/sparc/lib/umul.S +++ /dev/null
@@ -1,171 +0,0 @@ -/* - * umul.S: This routine was taken from glibc-1.09 and is covered - * by the GNU Library General Public License Version 2. - */ - - -/* - * Unsigned multiply. Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the - * upper 32 bits of the 64-bit product). - * - * This code optimizes short (less than 13-bit) multiplies. Short - * multiplies require 25 instruction cycles, and long ones require - * 45 instruction cycles. - * - * On return, overflow has occurred (%o1 is not zero) if and only if - * the Z condition code is clear, allowing, e.g., the following: - * - * call .umul - * nop - * bnz overflow (or tnz) - */ - - .globl .umul - .globl _Umul -.umul: -_Umul: /* needed for export */ - or %o0, %o1, %o4 - mov %o0, %y ! multiplier -> Y - - andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args - be Lmul_shortway ! if zero, can do it the short way - andcc %g0, %g0, %o4 ! zero the partial product and clear N and V - - /* - * Long multiply. 32 steps, followed by a final shift step. - */ - mulscc %o4, %o1, %o4 ! 1 - mulscc %o4, %o1, %o4 ! 2 - mulscc %o4, %o1, %o4 ! 3 - mulscc %o4, %o1, %o4 ! 4 - mulscc %o4, %o1, %o4 ! 5 - mulscc %o4, %o1, %o4 ! 6 - mulscc %o4, %o1, %o4 ! 7 - mulscc %o4, %o1, %o4 ! 8 - mulscc %o4, %o1, %o4 ! 9 - mulscc %o4, %o1, %o4 ! 10 - mulscc %o4, %o1, %o4 ! 11 - mulscc %o4, %o1, %o4 ! 12 - mulscc %o4, %o1, %o4 ! 13 - mulscc %o4, %o1, %o4 ! 14 - mulscc %o4, %o1, %o4 ! 15 - mulscc %o4, %o1, %o4 ! 16 - mulscc %o4, %o1, %o4 ! 17 - mulscc %o4, %o1, %o4 ! 18 - mulscc %o4, %o1, %o4 ! 19 - mulscc %o4, %o1, %o4 ! 20 - mulscc %o4, %o1, %o4 ! 21 - mulscc %o4, %o1, %o4 ! 22 - mulscc %o4, %o1, %o4 ! 23 - mulscc %o4, %o1, %o4 ! 24 - mulscc %o4, %o1, %o4 ! 25 - mulscc %o4, %o1, %o4 ! 26 - mulscc %o4, %o1, %o4 ! 27 - mulscc %o4, %o1, %o4 ! 28 - mulscc %o4, %o1, %o4 ! 29 - mulscc %o4, %o1, %o4 ! 30 - mulscc %o4, %o1, %o4 ! 31 - mulscc %o4, %o1, %o4 ! 32 - mulscc %o4, %g0, %o4 ! final shift - - - /* - * Normally, with the shift-and-add approach, if both numbers are - * positive you get the correct result. With 32-bit two's-complement - * numbers, -x is represented as - * - * x 32 - * ( 2 - ------ ) mod 2 * 2 - * 32 - * 2 - * - * (the `mod 2' subtracts 1 from 1.bbbb). To avoid lots of 2^32s, - * we can treat this as if the radix point were just to the left - * of the sign bit (multiply by 2^32), and get - * - * -x = (2 - x) mod 2 - * - * Then, ignoring the `mod 2's for convenience: - * - * x * y = xy - * -x * y = 2y - xy - * x * -y = 2x - xy - * -x * -y = 4 - 2x - 2y + xy - * - * For signed multiplies, we subtract (x << 32) from the partial - * product to fix this problem for negative multipliers (see mul.s). - * Because of the way the shift into the partial product is calculated - * (N xor V), this term is automatically removed for the multiplicand, - * so we don't have to adjust. - * - * But for unsigned multiplies, the high order bit wasn't a sign bit, - * and the correction is wrong. So for unsigned multiplies where the - * high order bit is one, we end up with xy - (y << 32). To fix it - * we add y << 32. - */ -#if 0 - tst %o1 - bl,a 1f ! if %o1 < 0 (high order bit = 1), - add %o4, %o0, %o4 ! %o4 += %o0 (add y to upper half) - -1: - rd %y, %o0 ! get lower half of product - retl - addcc %o4, %g0, %o1 ! put upper half in place and set Z for %o1==0 -#else - /* Faster code from tege@sics.se. */ - sra %o1, 31, %o2 ! make mask from sign bit - and %o0, %o2, %o2 ! %o2 = 0 or %o0, depending on sign of %o1 - rd %y, %o0 ! get lower half of product - retl - addcc %o4, %o2, %o1 ! add compensation and put upper half in place -#endif - -Lmul_shortway: - /* - * Short multiply. 12 steps, followed by a final shift step. - * The resulting bits are off by 12 and (32-12) = 20 bit positions, - * but there is no problem with %o0 being negative (unlike above), - * and overflow is impossible (the answer is at most 24 bits long). - */ - mulscc %o4, %o1, %o4 ! 1 - mulscc %o4, %o1, %o4 ! 2 - mulscc %o4, %o1, %o4 ! 3 - mulscc %o4, %o1, %o4 ! 4 - mulscc %o4, %o1, %o4 ! 5 - mulscc %o4, %o1, %o4 ! 6 - mulscc %o4, %o1, %o4 ! 7 - mulscc %o4, %o1, %o4 ! 8 - mulscc %o4, %o1, %o4 ! 9 - mulscc %o4, %o1, %o4 ! 10 - mulscc %o4, %o1, %o4 ! 11 - mulscc %o4, %o1, %o4 ! 12 - mulscc %o4, %g0, %o4 ! final shift - - /* - * %o4 has 20 of the bits that should be in the result; %y has - * the bottom 12 (as %y's top 12). That is: - * - * %o4 %y - * +----------------+----------------+ - * | -12- | -20- | -12- | -20- | - * +------(---------+------)---------+ - * -----result----- - * - * The 12 bits of %o4 left of the `result' area are all zero; - * in fact, all top 20 bits of %o4 are zero. - */ - - rd %y, %o5 - sll %o4, 12, %o0 ! shift middle bits left 12 - srl %o5, 20, %o5 ! shift low bits right 20 - or %o5, %o0, %o0 - retl - addcc %g0, %g0, %o1 ! %o1 = zero, and set Z - - .globl .umul_patch -.umul_patch: - umul %o0, %o1, %o0 - retl - rd %y, %o1 - nop
diff --git a/arch/sparc/lib/urem.S b/arch/sparc/lib/urem.S deleted file mode 100644 index 77123eb..0000000 --- a/arch/sparc/lib/urem.S +++ /dev/null
@@ -1,357 +0,0 @@ -/* - * urem.S: This routine was taken from glibc-1.09 and is covered - * by the GNU Library General Public License Version 2. - */ - -/* This file is generated from divrem.m4; DO NOT EDIT! */ -/* - * Division and remainder, from Appendix E of the Sparc Version 8 - * Architecture Manual, with fixes from Gordon Irlam. - */ - -/* - * Input: dividend and divisor in %o0 and %o1 respectively. - * - * m4 parameters: - * .urem name of function to generate - * rem rem=div => %o0 / %o1; rem=rem => %o0 % %o1 - * false false=true => signed; false=false => unsigned - * - * Algorithm parameters: - * N how many bits per iteration we try to get (4) - * WORDSIZE total number of bits (32) - * - * Derived constants: - * TOPBITS number of bits in the top decade of a number - * - * Important variables: - * Q the partial quotient under development (initially 0) - * R the remainder so far, initially the dividend - * ITER number of main division loop iterations required; - * equal to ceil(log2(quotient) / N). Note that this - * is the log base (2^N) of the quotient. - * V the current comparand, initially divisor*2^(ITER*N-1) - * - * Cost: - * Current estimate for non-large dividend is - * ceil(log2(quotient) / N) * (10 + 7N/2) + C - * A large dividend is one greater than 2^(31-TOPBITS) and takes a - * different path, as the upper bits of the quotient must be developed - * one bit at a time. - */ - - .globl .urem - .globl _Urem -.urem: -_Urem: /* needed for export */ - - ! Ready to divide. Compute size of quotient; scale comparand. - orcc %o1, %g0, %o5 - bne 1f - mov %o0, %o3 - - ! Divide by zero trap. If it returns, return 0 (about as - ! wrong as possible, but that is what SunOS does...). - ta ST_DIV0 - retl - clr %o0 - -1: - cmp %o3, %o5 ! if %o1 exceeds %o0, done - blu Lgot_result ! (and algorithm fails otherwise) - clr %o2 - - sethi %hi(1 << (32 - 4 - 1)), %g1 - - cmp %o3, %g1 - blu Lnot_really_big - clr %o4 - - ! Here the dividend is >= 2**(31-N) or so. We must be careful here, - ! as our usual N-at-a-shot divide step will cause overflow and havoc. - ! The number of bits in the result here is N*ITER+SC, where SC <= N. - ! Compute ITER in an unorthodox manner: know we need to shift V into - ! the top decade: so do not even bother to compare to R. - 1: - cmp %o5, %g1 - bgeu 3f - mov 1, %g7 - - sll %o5, 4, %o5 - - b 1b - add %o4, 1, %o4 - - ! Now compute %g7. - 2: - addcc %o5, %o5, %o5 - bcc Lnot_too_big - add %g7, 1, %g7 - - ! We get here if the %o1 overflowed while shifting. - ! This means that %o3 has the high-order bit set. - ! Restore %o5 and subtract from %o3. - sll %g1, 4, %g1 ! high order bit - srl %o5, 1, %o5 ! rest of %o5 - add %o5, %g1, %o5 - - b Ldo_single_div - sub %g7, 1, %g7 - - Lnot_too_big: - 3: - cmp %o5, %o3 - blu 2b - nop - - be Ldo_single_div - nop - /* NB: these are commented out in the V8-Sparc manual as well */ - /* (I do not understand this) */ - ! %o5 > %o3: went too far: back up 1 step - ! srl %o5, 1, %o5 - ! dec %g7 - ! do single-bit divide steps - ! - ! We have to be careful here. We know that %o3 >= %o5, so we can do the - ! first divide step without thinking. BUT, the others are conditional, - ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- - ! order bit set in the first step, just falling into the regular - ! division loop will mess up the first time around. - ! So we unroll slightly... - Ldo_single_div: - subcc %g7, 1, %g7 - bl Lend_regular_divide - nop - - sub %o3, %o5, %o3 - mov 1, %o2 - - b Lend_single_divloop - nop - Lsingle_divloop: - sll %o2, 1, %o2 - bl 1f - srl %o5, 1, %o5 - ! %o3 >= 0 - sub %o3, %o5, %o3 - b 2f - add %o2, 1, %o2 - 1: ! %o3 < 0 - add %o3, %o5, %o3 - sub %o2, 1, %o2 - 2: - Lend_single_divloop: - subcc %g7, 1, %g7 - bge Lsingle_divloop - tst %o3 - - b,a Lend_regular_divide - -Lnot_really_big: -1: - sll %o5, 4, %o5 - - cmp %o5, %o3 - bleu 1b - addcc %o4, 1, %o4 - - be Lgot_result - sub %o4, 1, %o4 - - tst %o3 ! set up for initial iteration -Ldivloop: - sll %o2, 4, %o2 - ! depth 1, accumulated bits 0 - bl L.1.16 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 2, accumulated bits 1 - bl L.2.17 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 3, accumulated bits 3 - bl L.3.19 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits 7 - bl L.4.23 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (7*2+1), %o2 - -L.4.23: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (7*2-1), %o2 - -L.3.19: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits 5 - bl L.4.21 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (5*2+1), %o2 - -L.4.21: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (5*2-1), %o2 - -L.2.17: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 3, accumulated bits 1 - bl L.3.17 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits 3 - bl L.4.19 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (3*2+1), %o2 - -L.4.19: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (3*2-1), %o2 - -L.3.17: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits 1 - bl L.4.17 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (1*2+1), %o2 - -L.4.17: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (1*2-1), %o2 - -L.1.16: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 2, accumulated bits -1 - bl L.2.15 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 3, accumulated bits -1 - bl L.3.15 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits -1 - bl L.4.15 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-1*2+1), %o2 - -L.4.15: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-1*2-1), %o2 - -L.3.15: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits -3 - bl L.4.13 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-3*2+1), %o2 - -L.4.13: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-3*2-1), %o2 - -L.2.15: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 3, accumulated bits -3 - bl L.3.13 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - ! depth 4, accumulated bits -5 - bl L.4.11 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-5*2+1), %o2 - -L.4.11: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-5*2-1), %o2 - -L.3.13: - ! remainder is negative - addcc %o3,%o5,%o3 - ! depth 4, accumulated bits -7 - bl L.4.9 - srl %o5,1,%o5 - ! remainder is positive - subcc %o3,%o5,%o3 - b 9f - add %o2, (-7*2+1), %o2 - -L.4.9: - ! remainder is negative - addcc %o3,%o5,%o3 - b 9f - add %o2, (-7*2-1), %o2 - - 9: -Lend_regular_divide: - subcc %o4, 1, %o4 - bge Ldivloop - tst %o3 - - bl,a Lgot_result - ! non-restoring fixup here (one instruction only!) - add %o3, %o1, %o3 - -Lgot_result: - - retl - mov %o3, %o0 - - .globl .urem_patch -.urem_patch: - wr %g0, 0x0, %y - nop - nop - nop - udiv %o0, %o1, %o2 - umul %o2, %o1, %o2 - retl - sub %o0, %o2, %o0
diff --git a/arch/sparc/lib/xor.S b/arch/sparc/lib/xor.S index f44f58f..2c05641 100644 --- a/arch/sparc/lib/xor.S +++ b/arch/sparc/lib/xor.S
@@ -8,6 +8,7 @@ * Copyright (C) 2006 David S. Miller <davem@davemloft.net> */ +#include <linux/linkage.h> #include <asm/visasm.h> #include <asm/asi.h> #include <asm/dcu.h> @@ -19,12 +20,9 @@ * !(len & 127) && len >= 256 */ .text - .align 32 /* VIS versions. */ - .globl xor_vis_2 - .type xor_vis_2,#function -xor_vis_2: +ENTRY(xor_vis_2) rd %fprs, %o5 andcc %o5, FPRS_FEF|FPRS_DU, %g0 be,pt %icc, 0f @@ -91,11 +89,9 @@ wr %g1, %g0, %asi retl wr %g0, 0, %fprs - .size xor_vis_2, .-xor_vis_2 +ENDPROC(xor_vis_2) - .globl xor_vis_3 - .type xor_vis_3,#function -xor_vis_3: +ENTRY(xor_vis_3) rd %fprs, %o5 andcc %o5, FPRS_FEF|FPRS_DU, %g0 be,pt %icc, 0f @@ -159,11 +155,9 @@ wr %g1, %g0, %asi retl wr %g0, 0, %fprs - .size xor_vis_3, .-xor_vis_3 +ENDPROC(xor_vis_3) - .globl xor_vis_4 - .type xor_vis_4,#function -xor_vis_4: +ENTRY(xor_vis_4) rd %fprs, %o5 andcc %o5, FPRS_FEF|FPRS_DU, %g0 be,pt %icc, 0f @@ -246,11 +240,9 @@ wr %g1, %g0, %asi retl wr %g0, 0, %fprs - .size xor_vis_4, .-xor_vis_4 +ENDPROC(xor_vis_4) - .globl xor_vis_5 - .type xor_vis_5,#function -xor_vis_5: +ENTRY(xor_vis_5) save %sp, -192, %sp rd %fprs, %o5 andcc %o5, FPRS_FEF|FPRS_DU, %g0 @@ -354,12 +346,10 @@ wr %g0, 0, %fprs ret restore - .size xor_vis_5, .-xor_vis_5 +ENDPROC(xor_vis_5) /* Niagara versions. */ - .globl xor_niagara_2 - .type xor_niagara_2,#function -xor_niagara_2: /* %o0=bytes, %o1=dest, %o2=src */ +ENTRY(xor_niagara_2) /* %o0=bytes, %o1=dest, %o2=src */ save %sp, -192, %sp prefetch [%i1], #n_writes prefetch [%i2], #one_read @@ -402,11 +392,9 @@ wr %g7, 0x0, %asi ret restore - .size xor_niagara_2, .-xor_niagara_2 +ENDPROC(xor_niagara_2) - .globl xor_niagara_3 - .type xor_niagara_3,#function -xor_niagara_3: /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2 */ +ENTRY(xor_niagara_3) /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2 */ save %sp, -192, %sp prefetch [%i1], #n_writes prefetch [%i2], #one_read @@ -465,11 +453,9 @@ wr %g7, 0x0, %asi ret restore - .size xor_niagara_3, .-xor_niagara_3 +ENDPROC(xor_niagara_3) - .globl xor_niagara_4 - .type xor_niagara_4,#function -xor_niagara_4: /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3 */ +ENTRY(xor_niagara_4) /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3 */ save %sp, -192, %sp prefetch [%i1], #n_writes prefetch [%i2], #one_read @@ -549,11 +535,9 @@ wr %g7, 0x0, %asi ret restore - .size xor_niagara_4, .-xor_niagara_4 +ENDPROC(xor_niagara_4) - .globl xor_niagara_5 - .type xor_niagara_5,#function -xor_niagara_5: /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3, %o5=src4 */ +ENTRY(xor_niagara_5) /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3, %o5=src4 */ save %sp, -192, %sp prefetch [%i1], #n_writes prefetch [%i2], #one_read @@ -649,4 +633,4 @@ wr %g7, 0x0, %asi ret restore - .size xor_niagara_5, .-xor_niagara_5 +ENDPROC(xor_niagara_5)
diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile index 301421c..69ffd31 100644 --- a/arch/sparc/mm/Makefile +++ b/arch/sparc/mm/Makefile
@@ -7,8 +7,7 @@ obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o gup.o obj-y += fault_$(BITS).o obj-y += init_$(BITS).o -obj-$(CONFIG_SPARC32) += loadmmu.o -obj-$(CONFIG_SPARC32) += extable.o btfixup.o srmmu.o iommu.o io-unit.o +obj-$(CONFIG_SPARC32) += extable.o srmmu.o iommu.o io-unit.o obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o obj-$(CONFIG_SPARC_LEON)+= leon_mm.o @@ -17,9 +16,3 @@ # Only used by sparc32 obj-$(CONFIG_HIGHMEM) += highmem.o - -ifdef CONFIG_SMP -obj-$(CONFIG_SPARC32) += nosun4c.o -else -obj-$(CONFIG_SPARC32) += sun4c.o -endif
diff --git a/arch/sparc/mm/btfixup.c b/arch/sparc/mm/btfixup.c deleted file mode 100644 index 09d6af2..0000000 --- a/arch/sparc/mm/btfixup.c +++ /dev/null
@@ -1,328 +0,0 @@ -/* btfixup.c: Boot time code fixup and relocator, so that - * we can get rid of most indirect calls to achieve single - * image sun4c and srmmu kernel. - * - * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <asm/btfixup.h> -#include <asm/page.h> -#include <asm/pgalloc.h> -#include <asm/pgtable.h> -#include <asm/oplib.h> -#include <asm/cacheflush.h> - -#define BTFIXUP_OPTIMIZE_NOP -#define BTFIXUP_OPTIMIZE_OTHER - -extern char *srmmu_name; -static char version[] __initdata = "Boot time fixup v1.6. 4/Mar/98 Jakub Jelinek (jj@ultra.linux.cz). Patching kernel for "; -static char str_sun4c[] __initdata = "sun4c\n"; -static char str_srmmu[] __initdata = "srmmu[%s]/"; -static char str_iommu[] __initdata = "iommu\n"; -static char str_iounit[] __initdata = "io-unit\n"; - -static int visited __initdata = 0; -extern unsigned int ___btfixup_start[], ___btfixup_end[], __init_begin[], __init_end[], __init_text_end[]; -extern unsigned int _stext[], _end[], __start___ksymtab[], __stop___ksymtab[]; -static char wrong_f[] __initdata = "Trying to set f fixup %p to invalid function %08x\n"; -static char wrong_b[] __initdata = "Trying to set b fixup %p to invalid function %08x\n"; -static char wrong_s[] __initdata = "Trying to set s fixup %p to invalid value %08x\n"; -static char wrong_h[] __initdata = "Trying to set h fixup %p to invalid value %08x\n"; -static char wrong_a[] __initdata = "Trying to set a fixup %p to invalid value %08x\n"; -static char wrong[] __initdata = "Wrong address for %c fixup %p\n"; -static char insn_f[] __initdata = "Fixup f %p refers to weird instructions at %p[%08x,%08x]\n"; -static char insn_b[] __initdata = "Fixup b %p doesn't refer to a SETHI at %p[%08x]\n"; -static char insn_s[] __initdata = "Fixup s %p doesn't refer to an OR at %p[%08x]\n"; -static char insn_h[] __initdata = "Fixup h %p doesn't refer to a SETHI at %p[%08x]\n"; -static char insn_a[] __initdata = "Fixup a %p doesn't refer to a SETHI nor OR at %p[%08x]\n"; -static char insn_i[] __initdata = "Fixup i %p doesn't refer to a valid instruction at %p[%08x]\n"; -static char fca_und[] __initdata = "flush_cache_all undefined in btfixup()\n"; -static char wrong_setaddr[] __initdata = "Garbled CALL/INT patch at %p[%08x,%08x,%08x]=%08x\n"; - -#ifdef BTFIXUP_OPTIMIZE_OTHER -static void __init set_addr(unsigned int *addr, unsigned int q1, int fmangled, unsigned int value) -{ - if (!fmangled) - *addr = value; - else { - unsigned int *q = (unsigned int *)q1; - if (*addr == 0x01000000) { - /* Noped */ - *q = value; - } else if (addr[-1] == *q) { - /* Moved */ - addr[-1] = value; - *q = value; - } else { - prom_printf(wrong_setaddr, addr-1, addr[-1], *addr, *q, value); - prom_halt(); - } - } -} -#else -static inline void set_addr(unsigned int *addr, unsigned int q1, int fmangled, unsigned int value) -{ - *addr = value; -} -#endif - -void __init btfixup(void) -{ - unsigned int *p, *q; - int type, count; - unsigned insn; - unsigned *addr; - int fmangled = 0; - void (*flush_cacheall)(void); - - if (!visited) { - visited++; - printk(version); - if (ARCH_SUN4C) - printk(str_sun4c); - else { - printk(str_srmmu, srmmu_name); - if (sparc_cpu_model == sun4d) - printk(str_iounit); - else - printk(str_iommu); - } - } - for (p = ___btfixup_start; p < ___btfixup_end; ) { - count = p[2]; - q = p + 3; - switch (type = *(unsigned char *)p) { - case 'f': - count = p[3]; - q = p + 4; - if (((p[0] & 1) || p[1]) - && ((p[1] & 3) || (unsigned *)(p[1]) < _stext || (unsigned *)(p[1]) >= _end)) { - prom_printf(wrong_f, p, p[1]); - prom_halt(); - } - break; - case 'b': - if (p[1] < (unsigned long)__init_begin || p[1] >= (unsigned long)__init_text_end || (p[1] & 3)) { - prom_printf(wrong_b, p, p[1]); - prom_halt(); - } - break; - case 's': - if (p[1] + 0x1000 >= 0x2000) { - prom_printf(wrong_s, p, p[1]); - prom_halt(); - } - break; - case 'h': - if (p[1] & 0x3ff) { - prom_printf(wrong_h, p, p[1]); - prom_halt(); - } - break; - case 'a': - if (p[1] + 0x1000 >= 0x2000 && (p[1] & 0x3ff)) { - prom_printf(wrong_a, p, p[1]); - prom_halt(); - } - break; - } - if (p[0] & 1) { - p[0] &= ~1; - while (count) { - fmangled = 0; - addr = (unsigned *)*q; - if (addr < _stext || addr >= _end) { - prom_printf(wrong, type, p); - prom_halt(); - } - insn = *addr; -#ifdef BTFIXUP_OPTIMIZE_OTHER - if (type != 'f' && q[1]) { - insn = *(unsigned int *)q[1]; - if (!insn || insn == 1) - insn = *addr; - else - fmangled = 1; - } -#endif - switch (type) { - case 'f': /* CALL */ - if (addr >= __start___ksymtab && addr < __stop___ksymtab) { - *addr = p[1]; - break; - } else if (!q[1]) { - if ((insn & 0xc1c00000) == 0x01000000) { /* SETHI */ - *addr = (insn & 0xffc00000) | (p[1] >> 10); break; - } else if ((insn & 0xc1f82000) == 0x80102000) { /* OR X, %LO(i), Y */ - *addr = (insn & 0xffffe000) | (p[1] & 0x3ff); break; - } else if ((insn & 0xc0000000) != 0x40000000) { /* !CALL */ - bad_f: - prom_printf(insn_f, p, addr, insn, addr[1]); - prom_halt(); - } - } else if (q[1] != 1) - addr[1] = q[1]; - if (p[2] == BTFIXUPCALL_NORM) { - norm_f: - *addr = 0x40000000 | ((p[1] - (unsigned)addr) >> 2); - q[1] = 0; - break; - } -#ifndef BTFIXUP_OPTIMIZE_NOP - goto norm_f; -#else - if (!(addr[1] & 0x80000000)) { - if ((addr[1] & 0xc1c00000) != 0x01000000) /* !SETHI */ - goto bad_f; /* CALL, Bicc, FBfcc, CBccc are weird in delay slot, aren't they? */ - } else { - if ((addr[1] & 0x01800000) == 0x01800000) { - if ((addr[1] & 0x01f80000) == 0x01e80000) { - /* RESTORE */ - goto norm_f; /* It is dangerous to patch that */ - } - goto bad_f; - } - if ((addr[1] & 0xffffe003) == 0x9e03e000) { - /* ADD %O7, XX, %o7 */ - int displac = (addr[1] << 19); - - displac = (displac >> 21) + 2; - *addr = (0x10800000) + (displac & 0x3fffff); - q[1] = addr[1]; - addr[1] = p[2]; - break; - } - if ((addr[1] & 0x201f) == 0x200f || (addr[1] & 0x7c000) == 0x3c000) - goto norm_f; /* Someone is playing bad tricks with us: rs1 or rs2 is o7 */ - if ((addr[1] & 0x3e000000) == 0x1e000000) - goto norm_f; /* rd is %o7. We'd better take care. */ - } - if (p[2] == BTFIXUPCALL_NOP) { - *addr = 0x01000000; - q[1] = 1; - break; - } -#ifndef BTFIXUP_OPTIMIZE_OTHER - goto norm_f; -#else - if (addr[1] == 0x01000000) { /* NOP in the delay slot */ - q[1] = addr[1]; - *addr = p[2]; - break; - } - if ((addr[1] & 0xc0000000) != 0xc0000000) { - /* Not a memory operation */ - if ((addr[1] & 0x30000000) == 0x10000000) { - /* Ok, non-memory op with rd %oX */ - if ((addr[1] & 0x3e000000) == 0x1c000000) - goto bad_f; /* Aiee. Someone is playing strange %sp tricks */ - if ((addr[1] & 0x3e000000) > 0x12000000 || - ((addr[1] & 0x3e000000) == 0x12000000 && - p[2] != BTFIXUPCALL_STO1O0 && p[2] != BTFIXUPCALL_SWAPO0O1) || - ((p[2] & 0xffffe000) == BTFIXUPCALL_RETINT(0))) { - /* Nobody uses the result. We can nop it out. */ - *addr = p[2]; - q[1] = addr[1]; - addr[1] = 0x01000000; - break; - } - if ((addr[1] & 0xf1ffffe0) == 0x90100000) { - /* MOV %reg, %Ox */ - if ((addr[1] & 0x3e000000) == 0x10000000 && - (p[2] & 0x7c000) == 0x20000) { - /* Ok, it is call xx; mov reg, %o0 and call optimizes - to doing something on %o0. Patch the patch. */ - *addr = (p[2] & ~0x7c000) | ((addr[1] & 0x1f) << 14); - q[1] = addr[1]; - addr[1] = 0x01000000; - break; - } - if ((addr[1] & 0x3e000000) == 0x12000000 && - p[2] == BTFIXUPCALL_STO1O0) { - *addr = (p[2] & ~0x3e000000) | ((addr[1] & 0x1f) << 25); - q[1] = addr[1]; - addr[1] = 0x01000000; - break; - } - } - } - } - *addr = addr[1]; - q[1] = addr[1]; - addr[1] = p[2]; - break; -#endif /* BTFIXUP_OPTIMIZE_OTHER */ -#endif /* BTFIXUP_OPTIMIZE_NOP */ - case 'b': /* BLACKBOX */ - /* Has to be sethi i, xx */ - if ((insn & 0xc1c00000) != 0x01000000) { - prom_printf(insn_b, p, addr, insn); - prom_halt(); - } else { - void (*do_fixup)(unsigned *); - - do_fixup = (void (*)(unsigned *))p[1]; - do_fixup(addr); - } - break; - case 's': /* SIMM13 */ - /* Has to be or %g0, i, xx */ - if ((insn & 0xc1ffe000) != 0x80102000) { - prom_printf(insn_s, p, addr, insn); - prom_halt(); - } - set_addr(addr, q[1], fmangled, (insn & 0xffffe000) | (p[1] & 0x1fff)); - break; - case 'h': /* SETHI */ - /* Has to be sethi i, xx */ - if ((insn & 0xc1c00000) != 0x01000000) { - prom_printf(insn_h, p, addr, insn); - prom_halt(); - } - set_addr(addr, q[1], fmangled, (insn & 0xffc00000) | (p[1] >> 10)); - break; - case 'a': /* HALF */ - /* Has to be sethi i, xx or or %g0, i, xx */ - if ((insn & 0xc1c00000) != 0x01000000 && - (insn & 0xc1ffe000) != 0x80102000) { - prom_printf(insn_a, p, addr, insn); - prom_halt(); - } - if (p[1] & 0x3ff) - set_addr(addr, q[1], fmangled, - (insn & 0x3e000000) | 0x80102000 | (p[1] & 0x1fff)); - else - set_addr(addr, q[1], fmangled, - (insn & 0x3e000000) | 0x01000000 | (p[1] >> 10)); - break; - case 'i': /* INT */ - if ((insn & 0xc1c00000) == 0x01000000) /* %HI */ - set_addr(addr, q[1], fmangled, (insn & 0xffc00000) | (p[1] >> 10)); - else if ((insn & 0x80002000) == 0x80002000) /* %LO */ - set_addr(addr, q[1], fmangled, (insn & 0xffffe000) | (p[1] & 0x3ff)); - else { - prom_printf(insn_i, p, addr, insn); - prom_halt(); - } - break; - } - count -= 2; - q += 2; - } - } else - p = q + count; - } -#ifdef CONFIG_SMP - flush_cacheall = (void (*)(void))BTFIXUPVAL_CALL(local_flush_cache_all); -#else - flush_cacheall = (void (*)(void))BTFIXUPVAL_CALL(flush_cache_all); -#endif - if (!flush_cacheall) { - prom_printf(fca_und); - prom_halt(); - } - (*flush_cacheall)(); -}
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c index df3155a..f46cf6b 100644 --- a/arch/sparc/mm/fault_32.c +++ b/arch/sparc/mm/fault_32.c
@@ -24,29 +24,19 @@ #include <asm/page.h> #include <asm/pgtable.h> -#include <asm/memreg.h> #include <asm/openprom.h> #include <asm/oplib.h> #include <asm/smp.h> #include <asm/traps.h> #include <asm/uaccess.h> -extern int prom_node_root; - int show_unhandled_signals = 1; /* At boot time we determine these two values necessary for setting * up the segment maps and page table entries (pte's). */ -int num_segmaps, num_contexts; -int invalid_segment; - -/* various Virtual Address Cache parameters we find at boot time... */ - -int vac_size, vac_linesize, vac_do_hw_vac_flushes; -int vac_entries_per_context, vac_entries_per_segment; -int vac_entries_per_page; +int num_contexts; /* Return how much physical memory we have. */ unsigned long probe_memory(void) @@ -60,55 +50,36 @@ return total; } -extern void sun4c_complete_all_stores(void); - -/* Whee, a level 15 NMI interrupt memory error. Let's have fun... */ -asmlinkage void sparc_lvl15_nmi(struct pt_regs *regs, unsigned long serr, - unsigned long svaddr, unsigned long aerr, - unsigned long avaddr) -{ - sun4c_complete_all_stores(); - printk("FAULT: NMI received\n"); - printk("SREGS: Synchronous Error %08lx\n", serr); - printk(" Synchronous Vaddr %08lx\n", svaddr); - printk(" Asynchronous Error %08lx\n", aerr); - printk(" Asynchronous Vaddr %08lx\n", avaddr); - if (sun4c_memerr_reg) - printk(" Memory Parity Error %08lx\n", *sun4c_memerr_reg); - printk("REGISTER DUMP:\n"); - show_regs(regs); - prom_halt(); -} - static void unhandled_fault(unsigned long, struct task_struct *, struct pt_regs *) __attribute__ ((noreturn)); -static void unhandled_fault(unsigned long address, struct task_struct *tsk, - struct pt_regs *regs) +static void __noreturn unhandled_fault(unsigned long address, + struct task_struct *tsk, + struct pt_regs *regs) { - if((unsigned long) address < PAGE_SIZE) { + if ((unsigned long) address < PAGE_SIZE) { printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference\n"); } else { - printk(KERN_ALERT "Unable to handle kernel paging request " - "at virtual address %08lx\n", address); + printk(KERN_ALERT "Unable to handle kernel paging request at virtual address %08lx\n", + address); } printk(KERN_ALERT "tsk->{mm,active_mm}->context = %08lx\n", (tsk->mm ? tsk->mm->context : tsk->active_mm->context)); printk(KERN_ALERT "tsk->{mm,active_mm}->pgd = %08lx\n", (tsk->mm ? (unsigned long) tsk->mm->pgd : - (unsigned long) tsk->active_mm->pgd)); + (unsigned long) tsk->active_mm->pgd)); die_if_kernel("Oops", regs); } -asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc, +asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc, unsigned long address) { struct pt_regs regs; unsigned long g2; unsigned int insn; int i; - + i = search_extables_range(ret_pc, &g2); switch (i) { case 3: @@ -128,14 +99,14 @@ /* for _from_ macros */ insn = *((unsigned int *) pc); if (!((insn >> 21) & 1) || ((insn>>19)&0x3f) == 15) - return 2; - break; + return 2; + break; default: break; } - memset(®s, 0, sizeof (regs)); + memset(®s, 0, sizeof(regs)); regs.pc = pc; regs.npc = pc + 4; __asm__ __volatile__( @@ -198,11 +169,10 @@ if (text_fault) return regs->pc; - if (regs->psr & PSR_PS) { + if (regs->psr & PSR_PS) insn = *(unsigned int *) regs->pc; - } else { + else __get_user(insn, (unsigned int *) regs->pc); - } return safe_compute_effective_address(regs, insn); } @@ -228,7 +198,7 @@ unsigned int flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | (write ? FAULT_FLAG_WRITE : 0)); - if(text_fault) + if (text_fault) address = regs->pc; /* @@ -241,36 +211,32 @@ * nothing more. */ code = SEGV_MAPERR; - if (!ARCH_SUN4C && address >= TASK_SIZE) + if (address >= TASK_SIZE) goto vmalloc_fault; /* * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) - goto no_context; + if (in_atomic() || !mm) + goto no_context; perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); retry: down_read(&mm->mmap_sem); - /* - * The kernel referencing a bad kernel pointer can lock up - * a sun4c machine completely, so we must attempt recovery. - */ - if(!from_user && address >= PAGE_OFFSET) + if (!from_user && address >= PAGE_OFFSET) goto bad_area; vma = find_vma(mm, address); - if(!vma) + if (!vma) goto bad_area; - if(vma->vm_start <= address) + if (vma->vm_start <= address) goto good_area; - if(!(vma->vm_flags & VM_GROWSDOWN)) + if (!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; - if(expand_stack(vma, address)) + if (expand_stack(vma, address)) goto bad_area; /* * Ok, we have a good vm_area for this memory access, so @@ -278,12 +244,12 @@ */ good_area: code = SEGV_ACCERR; - if(write) { - if(!(vma->vm_flags & VM_WRITE)) + if (write) { + if (!(vma->vm_flags & VM_WRITE)) goto bad_area; } else { /* Allow reads even for write-only mappings */ - if(!(vma->vm_flags & (VM_READ | VM_EXEC))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; } @@ -349,14 +315,16 @@ g2 = regs->u_regs[UREG_G2]; if (!from_user) { fixup = search_extables_range(regs->pc, &g2); - if (fixup > 10) { /* Values below are reserved for other things */ + /* Values below 10 are reserved for other things */ + if (fixup > 10) { extern const unsigned __memset_start[]; extern const unsigned __memset_end[]; extern const unsigned __csum_partial_copy_start[]; extern const unsigned __csum_partial_copy_end[]; #ifdef DEBUG_EXCEPTIONS - printk("Exception: PC<%08lx> faddr<%08lx>\n", regs->pc, address); + printk("Exception: PC<%08lx> faddr<%08lx>\n", + regs->pc, address); printk("EX_TABLE: insn<%08lx> fixup<%08x> g2<%08lx>\n", regs->pc, fixup, g2); #endif @@ -364,7 +332,7 @@ regs->pc < (unsigned long)__memset_end) || (regs->pc >= (unsigned long)__csum_partial_copy_start && regs->pc < (unsigned long)__csum_partial_copy_end)) { - regs->u_regs[UREG_I4] = address; + regs->u_regs[UREG_I4] = address; regs->u_regs[UREG_I5] = regs->pc; } regs->u_regs[UREG_G2] = g2; @@ -373,8 +341,8 @@ return; } } - - unhandled_fault (address, tsk, regs); + + unhandled_fault(address, tsk, regs); do_exit(SIGKILL); /* @@ -420,97 +388,12 @@ if (pmd_present(*pmd) || !pmd_present(*pmd_k)) goto bad_area_nosemaphore; + *pmd = *pmd_k; return; } } -asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write, - unsigned long address) -{ - extern void sun4c_update_mmu_cache(struct vm_area_struct *, - unsigned long,pte_t *); - extern pte_t *sun4c_pte_offset_kernel(pmd_t *,unsigned long); - struct task_struct *tsk = current; - struct mm_struct *mm = tsk->mm; - pgd_t *pgdp; - pte_t *ptep; - - if (text_fault) { - address = regs->pc; - } else if (!write && - !(regs->psr & PSR_PS)) { - unsigned int insn, __user *ip; - - ip = (unsigned int __user *)regs->pc; - if (!get_user(insn, ip)) { - if ((insn & 0xc1680000) == 0xc0680000) - write = 1; - } - } - - if (!mm) { - /* We are oopsing. */ - do_sparc_fault(regs, text_fault, write, address); - BUG(); /* P3 Oops already, you bitch */ - } - - pgdp = pgd_offset(mm, address); - ptep = sun4c_pte_offset_kernel((pmd_t *) pgdp, address); - - if (pgd_val(*pgdp)) { - if (write) { - if ((pte_val(*ptep) & (_SUN4C_PAGE_WRITE|_SUN4C_PAGE_PRESENT)) - == (_SUN4C_PAGE_WRITE|_SUN4C_PAGE_PRESENT)) { - unsigned long flags; - - *ptep = __pte(pte_val(*ptep) | _SUN4C_PAGE_ACCESSED | - _SUN4C_PAGE_MODIFIED | - _SUN4C_PAGE_VALID | - _SUN4C_PAGE_DIRTY); - - local_irq_save(flags); - if (sun4c_get_segmap(address) != invalid_segment) { - sun4c_put_pte(address, pte_val(*ptep)); - local_irq_restore(flags); - return; - } - local_irq_restore(flags); - } - } else { - if ((pte_val(*ptep) & (_SUN4C_PAGE_READ|_SUN4C_PAGE_PRESENT)) - == (_SUN4C_PAGE_READ|_SUN4C_PAGE_PRESENT)) { - unsigned long flags; - - *ptep = __pte(pte_val(*ptep) | _SUN4C_PAGE_ACCESSED | - _SUN4C_PAGE_VALID); - - local_irq_save(flags); - if (sun4c_get_segmap(address) != invalid_segment) { - sun4c_put_pte(address, pte_val(*ptep)); - local_irq_restore(flags); - return; - } - local_irq_restore(flags); - } - } - } - - /* This conditional is 'interesting'. */ - if (pgd_val(*pgdp) && !(write && !(pte_val(*ptep) & _SUN4C_PAGE_WRITE)) - && (pte_val(*ptep) & _SUN4C_PAGE_VALID)) - /* Note: It is safe to not grab the MMAP semaphore here because - * we know that update_mmu_cache() will not sleep for - * any reason (at least not in the current implementation) - * and therefore there is no danger of another thread getting - * on the CPU and doing a shrink_mmap() on this vma. - */ - sun4c_update_mmu_cache (find_vma(current->mm, address), address, - ptep); - else - do_sparc_fault(regs, text_fault, write, address); -} - /* This always deals with user addresses. */ static void force_user_fault(unsigned long address, int write) { @@ -523,21 +406,21 @@ down_read(&mm->mmap_sem); vma = find_vma(mm, address); - if(!vma) + if (!vma) goto bad_area; - if(vma->vm_start <= address) + if (vma->vm_start <= address) goto good_area; - if(!(vma->vm_flags & VM_GROWSDOWN)) + if (!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; - if(expand_stack(vma, address)) + if (expand_stack(vma, address)) goto bad_area; good_area: code = SEGV_ACCERR; - if(write) { - if(!(vma->vm_flags & VM_WRITE)) + if (write) { + if (!(vma->vm_flags & VM_WRITE)) goto bad_area; } else { - if(!(vma->vm_flags & (VM_READ | VM_EXEC))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; } switch (handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0)) { @@ -568,7 +451,7 @@ unsigned long sp; sp = current_thread_info()->rwbuf_stkptrs[0]; - if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) + if (((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) force_user_fault(sp + 0x38, 1); force_user_fault(sp, 1); @@ -577,7 +460,7 @@ void window_underflow_fault(unsigned long sp) { - if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) + if (((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) force_user_fault(sp + 0x38, 0); force_user_fault(sp, 0); @@ -589,7 +472,7 @@ unsigned long sp; sp = regs->u_regs[UREG_FP]; - if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) + if (((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) force_user_fault(sp + 0x38, 0); force_user_fault(sp, 0);
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c index c5f9021..ef5c779 100644 --- a/arch/sparc/mm/init_32.c +++ b/arch/sparc/mm/init_32.c
@@ -27,7 +27,6 @@ #include <linux/gfp.h> #include <asm/sections.h> -#include <asm/vac-ops.h> #include <asm/page.h> #include <asm/pgtable.h> #include <asm/vaddrs.h> @@ -45,9 +44,6 @@ unsigned long pfn_base; EXPORT_SYMBOL(pfn_base); -unsigned long page_kernel; -EXPORT_SYMBOL(page_kernel); - struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1]; unsigned long sparc_unmapped_base; @@ -287,44 +283,16 @@ } /* - * check_pgt_cache - * - * This is called at the end of unmapping of VMA (zap_page_range), - * to rescan the page cache for architecture specific things, - * presumably something like sun4/sun4c PMEGs. Most architectures - * define check_pgt_cache empty. - * - * We simply copy the 2.4 implementation for now. - */ -static int pgt_cache_water[2] = { 25, 50 }; - -void check_pgt_cache(void) -{ - do_check_pgt_cache(pgt_cache_water[0], pgt_cache_water[1]); -} - -/* * paging_init() sets up the page tables: We call the MMU specific * init routine based upon the Sun model type on the Sparc. * */ -extern void sun4c_paging_init(void); extern void srmmu_paging_init(void); extern void device_scan(void); -pgprot_t PAGE_SHARED __read_mostly; -EXPORT_SYMBOL(PAGE_SHARED); - void __init paging_init(void) { switch(sparc_cpu_model) { - case sun4c: - case sun4e: - case sun4: - sun4c_paging_init(); - sparc_unmapped_base = 0xe0000000; - BTFIXUPSET_SETHI(sparc_unmapped_base, 0xe0000000); - break; case sparc_leon: leon_init(); /* fall through */ @@ -332,7 +300,6 @@ case sun4d: srmmu_paging_init(); sparc_unmapped_base = 0x50000000; - BTFIXUPSET_SETHI(sparc_unmapped_base, 0x50000000); break; default: prom_printf("paging_init: Cannot init paging on this Sparc\n"); @@ -341,24 +308,6 @@ prom_halt(); } - /* Initialize the protection map with non-constant, MMU dependent values. */ - protection_map[0] = PAGE_NONE; - protection_map[1] = PAGE_READONLY; - protection_map[2] = PAGE_COPY; - protection_map[3] = PAGE_COPY; - protection_map[4] = PAGE_READONLY; - protection_map[5] = PAGE_READONLY; - protection_map[6] = PAGE_COPY; - protection_map[7] = PAGE_COPY; - protection_map[8] = PAGE_NONE; - protection_map[9] = PAGE_READONLY; - protection_map[10] = PAGE_SHARED; - protection_map[11] = PAGE_SHARED; - protection_map[12] = PAGE_READONLY; - protection_map[13] = PAGE_READONLY; - protection_map[14] = PAGE_SHARED; - protection_map[15] = PAGE_SHARED; - btfixup(); prom_build_devicetree(); of_fill_in_cpu_data(); device_scan();
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 21faaee..6026fdd 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c
@@ -741,7 +741,6 @@ struct node_mem_mask { unsigned long mask; unsigned long val; - unsigned long bootmem_paddr; }; static struct node_mem_mask node_masks[MAX_NUMNODES]; static int num_node_masks; @@ -806,12 +805,6 @@ return start; } -#else -static u64 memblock_nid_range(u64 start, u64 end, int *nid) -{ - *nid = 0; - return end; -} #endif /* This must be invoked after performing all of the necessary @@ -820,10 +813,11 @@ */ static void __init allocate_node_data(int nid) { - unsigned long paddr, num_pages, start_pfn, end_pfn; struct pglist_data *p; - + unsigned long start_pfn, end_pfn; #ifdef CONFIG_NEED_MULTIPLE_NODES + unsigned long paddr; + paddr = memblock_alloc_try_nid(sizeof(struct pglist_data), SMP_CACHE_BYTES, nid); if (!paddr) { prom_printf("Cannot allocate pglist_data for nid[%d]\n", nid); @@ -832,7 +826,7 @@ NODE_DATA(nid) = __va(paddr); memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); - NODE_DATA(nid)->bdata = &bootmem_node_data[nid]; + NODE_DATA(nid)->node_id = nid; #endif p = NODE_DATA(nid); @@ -840,18 +834,6 @@ get_pfn_range_for_nid(nid, &start_pfn, &end_pfn); p->node_start_pfn = start_pfn; p->node_spanned_pages = end_pfn - start_pfn; - - if (p->node_spanned_pages) { - num_pages = bootmem_bootmap_pages(p->node_spanned_pages); - - paddr = memblock_alloc_try_nid(num_pages << PAGE_SHIFT, PAGE_SIZE, nid); - if (!paddr) { - prom_printf("Cannot allocate bootmap for nid[%d]\n", - nid); - prom_halt(); - } - node_masks[nid].bootmem_paddr = paddr; - } } static void init_node_masks_nonnuma(void) @@ -1292,75 +1274,9 @@ node_set_online(0); } -static void __init reserve_range_in_node(int nid, unsigned long start, - unsigned long end) -{ - numadbg(" reserve_range_in_node(nid[%d],start[%lx],end[%lx]\n", - nid, start, end); - while (start < end) { - unsigned long this_end; - int n; - - this_end = memblock_nid_range(start, end, &n); - if (n == nid) { - numadbg(" MATCH reserving range [%lx:%lx]\n", - start, this_end); - reserve_bootmem_node(NODE_DATA(nid), start, - (this_end - start), BOOTMEM_DEFAULT); - } else - numadbg(" NO MATCH, advancing start to %lx\n", - this_end); - - start = this_end; - } -} - -static void __init trim_reserved_in_node(int nid) -{ - struct memblock_region *reg; - - numadbg(" trim_reserved_in_node(%d)\n", nid); - - for_each_memblock(reserved, reg) - reserve_range_in_node(nid, reg->base, reg->base + reg->size); -} - -static void __init bootmem_init_one_node(int nid) -{ - struct pglist_data *p; - - numadbg("bootmem_init_one_node(%d)\n", nid); - - p = NODE_DATA(nid); - - if (p->node_spanned_pages) { - unsigned long paddr = node_masks[nid].bootmem_paddr; - unsigned long end_pfn; - - end_pfn = p->node_start_pfn + p->node_spanned_pages; - - numadbg(" init_bootmem_node(%d, %lx, %lx, %lx)\n", - nid, paddr >> PAGE_SHIFT, p->node_start_pfn, end_pfn); - - init_bootmem_node(p, paddr >> PAGE_SHIFT, - p->node_start_pfn, end_pfn); - - numadbg(" free_bootmem_with_active_regions(%d, %lx)\n", - nid, end_pfn); - free_bootmem_with_active_regions(nid, end_pfn); - - trim_reserved_in_node(nid); - - numadbg(" sparse_memory_present_with_active_regions(%d)\n", - nid); - sparse_memory_present_with_active_regions(nid); - } -} - static unsigned long __init bootmem_init(unsigned long phys_base) { unsigned long end_pfn; - int nid; end_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT; max_pfn = max_low_pfn = end_pfn; @@ -1369,11 +1285,12 @@ if (bootmem_init_numa() < 0) bootmem_init_nonnuma(); + /* Dump memblock with node info. */ + memblock_dump_all(); + /* XXX cpu notifier XXX */ - for_each_online_node(nid) - bootmem_init_one_node(nid); - + sparse_memory_present_with_active_regions(MAX_NUMNODES); sparse_init(); return end_pfn; @@ -1701,6 +1618,7 @@ { unsigned long end_pfn, shift, phys_base; unsigned long real_end, i; + int node; /* These build time checkes make sure that the dcache_dirty_cpu() * page->flags usage will work. @@ -1826,22 +1744,24 @@ #endif } + /* Setup bootmem... */ + last_valid_pfn = end_pfn = bootmem_init(phys_base); + /* Once the OF device tree and MDESC have been setup, we know * the list of possible cpus. Therefore we can allocate the * IRQ stacks. */ for_each_possible_cpu(i) { - /* XXX Use node local allocations... XXX */ - softirq_stack[i] = __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); - hardirq_stack[i] = __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); + node = cpu_to_node(i); + + softirq_stack[i] = __alloc_bootmem_node(NODE_DATA(node), + THREAD_SIZE, + THREAD_SIZE, 0); + hardirq_stack[i] = __alloc_bootmem_node(NODE_DATA(node), + THREAD_SIZE, + THREAD_SIZE, 0); } - /* Setup bootmem... */ - last_valid_pfn = end_pfn = bootmem_init(phys_base); - -#ifndef CONFIG_NEED_MULTIPLE_NODES - max_mapnr = last_valid_pfn; -#endif kernel_physical_mapping_init(); { @@ -1973,6 +1893,7 @@ free_all_bootmem_node(NODE_DATA(i)); } } + totalram_pages += free_low_memory_core_early(MAX_NUMNODES); } #else totalram_pages = free_all_bootmem();
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index fc58c3e..eb99862 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c
@@ -197,7 +197,7 @@ } #ifdef CONFIG_SBUS -static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, __u32 addr, int len) +static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, unsigned long addr, int len) { struct iounit_struct *iounit = dev->archdata.iommu; unsigned long page, end; @@ -242,29 +242,18 @@ } #endif -static char *iounit_lockarea(char *vaddr, unsigned long len) -{ -/* FIXME: Write this */ - return vaddr; -} - -static void iounit_unlockarea(char *vaddr, unsigned long len) -{ -/* FIXME: Write this */ -} +static const struct sparc32_dma_ops iounit_dma_ops = { + .get_scsi_one = iounit_get_scsi_one, + .get_scsi_sgl = iounit_get_scsi_sgl, + .release_scsi_one = iounit_release_scsi_one, + .release_scsi_sgl = iounit_release_scsi_sgl, +#ifdef CONFIG_SBUS + .map_dma_area = iounit_map_dma_area, + .unmap_dma_area = iounit_unmap_dma_area, +#endif +}; void __init ld_mmu_iounit(void) { - BTFIXUPSET_CALL(mmu_lockarea, iounit_lockarea, BTFIXUPCALL_RETO0); - BTFIXUPSET_CALL(mmu_unlockarea, iounit_unlockarea, BTFIXUPCALL_NOP); - - BTFIXUPSET_CALL(mmu_get_scsi_one, iounit_get_scsi_one, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_get_scsi_sgl, iounit_get_scsi_sgl, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_release_scsi_one, iounit_release_scsi_one, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_release_scsi_sgl, iounit_release_scsi_sgl, BTFIXUPCALL_NORM); - -#ifdef CONFIG_SBUS - BTFIXUPSET_CALL(mmu_map_dma_area, iounit_map_dma_area, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_unmap_dma_area, iounit_unmap_dma_area, BTFIXUPCALL_NORM); -#endif + sparc32_dma_ops = &iounit_dma_ops; }
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index 07fc6a6..a8a58ca 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c
@@ -39,8 +39,6 @@ /* srmmu.c */ extern int viking_mxcc_present; -BTFIXUPDEF_CALL(void, flush_page_for_dma, unsigned long) -#define flush_page_for_dma(page) BTFIXUP_CALL(flush_page_for_dma)(page) extern int flush_page_for_dma_global; static int viking_flush; /* viking.S */ @@ -143,7 +141,6 @@ subsys_initcall(iommu_init); -/* This begs to be btfixup-ed by srmmu. */ /* Flush the iotlb entries to ram. */ /* This could be better if we didn't have to flush whole pages. */ static void iommu_flush_iotlb(iopte_t *iopte, unsigned int niopte) @@ -216,11 +213,6 @@ return busa + off; } -static __u32 iommu_get_scsi_one_noflush(struct device *dev, char *vaddr, unsigned long len) -{ - return iommu_get_scsi_one(dev, vaddr, len); -} - static __u32 iommu_get_scsi_one_gflush(struct device *dev, char *vaddr, unsigned long len) { flush_page_for_dma(0); @@ -238,19 +230,6 @@ return iommu_get_scsi_one(dev, vaddr, len); } -static void iommu_get_scsi_sgl_noflush(struct device *dev, struct scatterlist *sg, int sz) -{ - int n; - - while (sz != 0) { - --sz; - n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; - sg->dma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset; - sg->dma_length = sg->length; - sg = sg_next(sg); - } -} - static void iommu_get_scsi_sgl_gflush(struct device *dev, struct scatterlist *sg, int sz) { int n; @@ -426,40 +405,36 @@ } #endif -static char *iommu_lockarea(char *vaddr, unsigned long len) -{ - return vaddr; -} +static const struct sparc32_dma_ops iommu_dma_gflush_ops = { + .get_scsi_one = iommu_get_scsi_one_gflush, + .get_scsi_sgl = iommu_get_scsi_sgl_gflush, + .release_scsi_one = iommu_release_scsi_one, + .release_scsi_sgl = iommu_release_scsi_sgl, +#ifdef CONFIG_SBUS + .map_dma_area = iommu_map_dma_area, + .unmap_dma_area = iommu_unmap_dma_area, +#endif +}; -static void iommu_unlockarea(char *vaddr, unsigned long len) -{ -} +static const struct sparc32_dma_ops iommu_dma_pflush_ops = { + .get_scsi_one = iommu_get_scsi_one_pflush, + .get_scsi_sgl = iommu_get_scsi_sgl_pflush, + .release_scsi_one = iommu_release_scsi_one, + .release_scsi_sgl = iommu_release_scsi_sgl, +#ifdef CONFIG_SBUS + .map_dma_area = iommu_map_dma_area, + .unmap_dma_area = iommu_unmap_dma_area, +#endif +}; void __init ld_mmu_iommu(void) { - viking_flush = (BTFIXUPVAL_CALL(flush_page_for_dma) == (unsigned long)viking_flush_page); - BTFIXUPSET_CALL(mmu_lockarea, iommu_lockarea, BTFIXUPCALL_RETO0); - BTFIXUPSET_CALL(mmu_unlockarea, iommu_unlockarea, BTFIXUPCALL_NOP); - - if (!BTFIXUPVAL_CALL(flush_page_for_dma)) { - /* IO coherent chip */ - BTFIXUPSET_CALL(mmu_get_scsi_one, iommu_get_scsi_one_noflush, BTFIXUPCALL_RETO0); - BTFIXUPSET_CALL(mmu_get_scsi_sgl, iommu_get_scsi_sgl_noflush, BTFIXUPCALL_NORM); - } else if (flush_page_for_dma_global) { + if (flush_page_for_dma_global) { /* flush_page_for_dma flushes everything, no matter of what page is it */ - BTFIXUPSET_CALL(mmu_get_scsi_one, iommu_get_scsi_one_gflush, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_get_scsi_sgl, iommu_get_scsi_sgl_gflush, BTFIXUPCALL_NORM); + sparc32_dma_ops = &iommu_dma_gflush_ops; } else { - BTFIXUPSET_CALL(mmu_get_scsi_one, iommu_get_scsi_one_pflush, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_get_scsi_sgl, iommu_get_scsi_sgl_pflush, BTFIXUPCALL_NORM); + sparc32_dma_ops = &iommu_dma_pflush_ops; } - BTFIXUPSET_CALL(mmu_release_scsi_one, iommu_release_scsi_one, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_release_scsi_sgl, iommu_release_scsi_sgl, BTFIXUPCALL_NORM); - -#ifdef CONFIG_SBUS - BTFIXUPSET_CALL(mmu_map_dma_area, iommu_map_dma_area, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_unmap_dma_area, iommu_unmap_dma_area, BTFIXUPCALL_NORM); -#endif if (viking_mxcc_present || srmmu_modtype == HyperSparc) { dvma_prot = __pgprot(SRMMU_CACHE | SRMMU_ET_PTE | SRMMU_PRIV);
diff --git a/arch/sparc/mm/leon_mm.c b/arch/sparc/mm/leon_mm.c index 13c2169..4c67ae6e 100644 --- a/arch/sparc/mm/leon_mm.c +++ b/arch/sparc/mm/leon_mm.c
@@ -15,9 +15,23 @@ #include <asm/leon.h> #include <asm/tlbflush.h> +#include "srmmu.h" + int leon_flush_during_switch = 1; int srmmu_swprobe_trace; +static inline unsigned long leon_get_ctable_ptr(void) +{ + unsigned int retval; + + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (retval) : + "r" (SRMMU_CTXTBL_PTR), + "i" (ASI_LEON_MMUREGS)); + return (retval & SRMMU_CTX_PMASK) << 4; +} + + unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr) { @@ -33,10 +47,10 @@ if (srmmu_swprobe_trace) printk(KERN_INFO "swprobe: trace on\n"); - ctxtbl = srmmu_get_ctable_ptr(); + ctxtbl = leon_get_ctable_ptr(); if (!(ctxtbl)) { if (srmmu_swprobe_trace) - printk(KERN_INFO "swprobe: srmmu_get_ctable_ptr returned 0=>0\n"); + printk(KERN_INFO "swprobe: leon_get_ctable_ptr returned 0=>0\n"); return 0; } if (!_pfn_valid(PFN(ctxtbl))) { @@ -258,3 +272,80 @@ if (leon_flush_during_switch) leon_flush_cache_all(); } + +static void leon_flush_cache_mm(struct mm_struct *mm) +{ + leon_flush_cache_all(); +} + +static void leon_flush_cache_page(struct vm_area_struct *vma, unsigned long page) +{ + leon_flush_pcache_all(vma, page); +} + +static void leon_flush_cache_range(struct vm_area_struct *vma, + unsigned long start, + unsigned long end) +{ + leon_flush_cache_all(); +} + +static void leon_flush_tlb_mm(struct mm_struct *mm) +{ + leon_flush_tlb_all(); +} + +static void leon_flush_tlb_page(struct vm_area_struct *vma, + unsigned long page) +{ + leon_flush_tlb_all(); +} + +static void leon_flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, + unsigned long end) +{ + leon_flush_tlb_all(); +} + +static void leon_flush_page_to_ram(unsigned long page) +{ + leon_flush_cache_all(); +} + +static void leon_flush_sig_insns(struct mm_struct *mm, unsigned long page) +{ + leon_flush_cache_all(); +} + +static void leon_flush_page_for_dma(unsigned long page) +{ + leon_flush_dcache_all(); +} + +void __init poke_leonsparc(void) +{ +} + +static const struct sparc32_cachetlb_ops leon_ops = { + .cache_all = leon_flush_cache_all, + .cache_mm = leon_flush_cache_mm, + .cache_page = leon_flush_cache_page, + .cache_range = leon_flush_cache_range, + .tlb_all = leon_flush_tlb_all, + .tlb_mm = leon_flush_tlb_mm, + .tlb_page = leon_flush_tlb_page, + .tlb_range = leon_flush_tlb_range, + .page_to_ram = leon_flush_page_to_ram, + .sig_insns = leon_flush_sig_insns, + .page_for_dma = leon_flush_page_for_dma, +}; + +void __init init_leon(void) +{ + srmmu_name = "LEON"; + sparc32_cachetlb_ops = &leon_ops; + poke_srmmu = poke_leonsparc; + + leon_flush_during_switch = leon_flush_needed(); +}
diff --git a/arch/sparc/mm/loadmmu.c b/arch/sparc/mm/loadmmu.c deleted file mode 100644 index c5bf2a6..0000000 --- a/arch/sparc/mm/loadmmu.c +++ /dev/null
@@ -1,43 +0,0 @@ -/* - * loadmmu.c: This code loads up all the mm function pointers once the - * machine type has been determined. It also sets the static - * mmu values such as PAGE_NONE, etc. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - */ - -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/init.h> - -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/mmu_context.h> -#include <asm/oplib.h> - -struct ctx_list *ctx_list_pool; -struct ctx_list ctx_free; -struct ctx_list ctx_used; - -extern void ld_mmu_sun4c(void); -extern void ld_mmu_srmmu(void); - -void __init load_mmu(void) -{ - switch(sparc_cpu_model) { - case sun4c: - case sun4: - ld_mmu_sun4c(); - break; - case sun4m: - case sun4d: - case sparc_leon: - ld_mmu_srmmu(); - break; - default: - prom_printf("load_mmu: %d unsupported\n", (int)sparc_cpu_model); - prom_halt(); - } - btfixup(); -}
diff --git a/arch/sparc/mm/nosun4c.c b/arch/sparc/mm/nosun4c.c deleted file mode 100644 index 4e62c27..0000000 --- a/arch/sparc/mm/nosun4c.c +++ /dev/null
@@ -1,77 +0,0 @@ -/* - * nosun4c.c: This file is a bunch of dummies for SMP compiles, - * so that it does not need sun4c and avoid ifdefs. - * - * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - */ - -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/init.h> -#include <asm/pgtable.h> - -static char shouldnothappen[] __initdata = "32bit SMP kernel only supports sun4m and sun4d\n"; - -/* Dummies */ -struct sun4c_mmu_ring { - unsigned long xxx1[3]; - unsigned char xxx2[2]; - int xxx3; -}; -struct sun4c_mmu_ring sun4c_kernel_ring; -struct sun4c_mmu_ring sun4c_kfree_ring; -unsigned long sun4c_kernel_faults; -unsigned long *sun4c_memerr_reg; - -static void __init should_not_happen(void) -{ - prom_printf(shouldnothappen); - prom_halt(); -} - -unsigned long __init sun4c_paging_init(unsigned long start_mem, unsigned long end_mem) -{ - should_not_happen(); - return 0; -} - -void __init ld_mmu_sun4c(void) -{ - should_not_happen(); -} - -void sun4c_mapioaddr(unsigned long physaddr, unsigned long virt_addr, int bus_type, int rdonly) -{ -} - -void sun4c_unmapioaddr(unsigned long virt_addr) -{ -} - -void sun4c_complete_all_stores(void) -{ -} - -pte_t *sun4c_pte_offset(pmd_t * dir, unsigned long address) -{ - return NULL; -} - -pte_t *sun4c_pte_offset_kernel(pmd_t *dir, unsigned long address) -{ - return NULL; -} - -void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) -{ -} - -void __init sun4c_probe_vac(void) -{ - should_not_happen(); -} - -void __init sun4c_probe_memerr_reg(void) -{ - should_not_happen(); -}
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index cbef74e..8e97e03 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c
@@ -48,39 +48,37 @@ #include <asm/turbosparc.h> #include <asm/leon.h> -#include <asm/btfixup.h> +#include "srmmu.h" enum mbus_module srmmu_modtype; static unsigned int hwbug_bitmask; int vac_cache_size; int vac_line_size; +struct ctx_list *ctx_list_pool; +struct ctx_list ctx_free; +struct ctx_list ctx_used; + extern struct resource sparc_iomap; extern unsigned long last_valid_pfn; -extern unsigned long page_kernel; - static pgd_t *srmmu_swapper_pg_dir; +const struct sparc32_cachetlb_ops *sparc32_cachetlb_ops; + #ifdef CONFIG_SMP +const struct sparc32_cachetlb_ops *local_ops; + #define FLUSH_BEGIN(mm) #define FLUSH_END #else -#define FLUSH_BEGIN(mm) if((mm)->context != NO_CONTEXT) { +#define FLUSH_BEGIN(mm) if ((mm)->context != NO_CONTEXT) { #define FLUSH_END } #endif -BTFIXUPDEF_CALL(void, flush_page_for_dma, unsigned long) -#define flush_page_for_dma(page) BTFIXUP_CALL(flush_page_for_dma)(page) - int flush_page_for_dma_global = 1; -#ifdef CONFIG_SMP -BTFIXUPDEF_CALL(void, local_flush_page_for_dma, unsigned long) -#define local_flush_page_for_dma(page) BTFIXUP_CALL(local_flush_page_for_dma)(page) -#endif - char *srmmu_name; ctxd_t *srmmu_ctx_table_phys; @@ -91,28 +89,6 @@ static int is_hypersparc; -/* - * In general all page table modifications should use the V8 atomic - * swap instruction. This insures the mmu and the cpu are in sync - * with respect to ref/mod bits in the page tables. - */ -static inline unsigned long srmmu_swap(unsigned long *addr, unsigned long value) -{ - __asm__ __volatile__("swap [%2], %0" : "=&r" (value) : "0" (value), "r" (addr)); - return value; -} - -static inline void srmmu_set_pte(pte_t *ptep, pte_t pteval) -{ - srmmu_swap((unsigned long *)ptep, pte_val(pteval)); -} - -/* The very generic SRMMU page table operations. */ -static inline int srmmu_device_memory(unsigned long x) -{ - return ((x & 0xF0000000) != 0); -} - static int srmmu_cache_pagetables; /* these will be initialized in srmmu_nocache_calcsize() */ @@ -129,145 +105,39 @@ void *srmmu_nocache_bitmap; static struct bit_map srmmu_nocache_map; -static unsigned long srmmu_pte_pfn(pte_t pte) -{ - if (srmmu_device_memory(pte_val(pte))) { - /* Just return something that will cause - * pfn_valid() to return false. This makes - * copy_one_pte() to just directly copy to - * PTE over. - */ - return ~0UL; - } - return (pte_val(pte) & SRMMU_PTE_PMASK) >> (PAGE_SHIFT-4); -} - -static struct page *srmmu_pmd_page(pmd_t pmd) -{ - - if (srmmu_device_memory(pmd_val(pmd))) - BUG(); - return pfn_to_page((pmd_val(pmd) & SRMMU_PTD_PMASK) >> (PAGE_SHIFT-4)); -} - -static inline unsigned long srmmu_pgd_page(pgd_t pgd) -{ return srmmu_device_memory(pgd_val(pgd))?~0:(unsigned long)__nocache_va((pgd_val(pgd) & SRMMU_PTD_PMASK) << 4); } - - -static inline int srmmu_pte_none(pte_t pte) -{ return !(pte_val(pte) & 0xFFFFFFF); } - -static inline int srmmu_pte_present(pte_t pte) -{ return ((pte_val(pte) & SRMMU_ET_MASK) == SRMMU_ET_PTE); } - -static inline void srmmu_pte_clear(pte_t *ptep) -{ srmmu_set_pte(ptep, __pte(0)); } - static inline int srmmu_pmd_none(pmd_t pmd) { return !(pmd_val(pmd) & 0xFFFFFFF); } -static inline int srmmu_pmd_bad(pmd_t pmd) -{ return (pmd_val(pmd) & SRMMU_ET_MASK) != SRMMU_ET_PTD; } - -static inline int srmmu_pmd_present(pmd_t pmd) -{ return ((pmd_val(pmd) & SRMMU_ET_MASK) == SRMMU_ET_PTD); } - -static inline void srmmu_pmd_clear(pmd_t *pmdp) { - int i; - for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) - srmmu_set_pte((pte_t *)&pmdp->pmdv[i], __pte(0)); -} - -static inline int srmmu_pgd_none(pgd_t pgd) -{ return !(pgd_val(pgd) & 0xFFFFFFF); } - -static inline int srmmu_pgd_bad(pgd_t pgd) -{ return (pgd_val(pgd) & SRMMU_ET_MASK) != SRMMU_ET_PTD; } - -static inline int srmmu_pgd_present(pgd_t pgd) -{ return ((pgd_val(pgd) & SRMMU_ET_MASK) == SRMMU_ET_PTD); } - -static inline void srmmu_pgd_clear(pgd_t * pgdp) -{ srmmu_set_pte((pte_t *)pgdp, __pte(0)); } - -static inline pte_t srmmu_pte_wrprotect(pte_t pte) -{ return __pte(pte_val(pte) & ~SRMMU_WRITE);} - -static inline pte_t srmmu_pte_mkclean(pte_t pte) -{ return __pte(pte_val(pte) & ~SRMMU_DIRTY);} - -static inline pte_t srmmu_pte_mkold(pte_t pte) -{ return __pte(pte_val(pte) & ~SRMMU_REF);} - -static inline pte_t srmmu_pte_mkwrite(pte_t pte) -{ return __pte(pte_val(pte) | SRMMU_WRITE);} - -static inline pte_t srmmu_pte_mkdirty(pte_t pte) -{ return __pte(pte_val(pte) | SRMMU_DIRTY);} - -static inline pte_t srmmu_pte_mkyoung(pte_t pte) -{ return __pte(pte_val(pte) | SRMMU_REF);} - -/* - * Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. - */ -static pte_t srmmu_mk_pte(struct page *page, pgprot_t pgprot) -{ return __pte((page_to_pfn(page) << (PAGE_SHIFT-4)) | pgprot_val(pgprot)); } - -static pte_t srmmu_mk_pte_phys(unsigned long page, pgprot_t pgprot) -{ return __pte(((page) >> 4) | pgprot_val(pgprot)); } - -static pte_t srmmu_mk_pte_io(unsigned long page, pgprot_t pgprot, int space) -{ return __pte(((page) >> 4) | (space << 28) | pgprot_val(pgprot)); } - /* XXX should we hyper_flush_whole_icache here - Anton */ static inline void srmmu_ctxd_set(ctxd_t *ctxp, pgd_t *pgdp) -{ srmmu_set_pte((pte_t *)ctxp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pgdp) >> 4))); } +{ set_pte((pte_t *)ctxp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pgdp) >> 4))); } -static inline void srmmu_pgd_set(pgd_t * pgdp, pmd_t * pmdp) -{ srmmu_set_pte((pte_t *)pgdp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pmdp) >> 4))); } - -static void srmmu_pmd_set(pmd_t *pmdp, pte_t *ptep) +void pmd_set(pmd_t *pmdp, pte_t *ptep) { unsigned long ptp; /* Physical address, shifted right by 4 */ int i; ptp = __nocache_pa((unsigned long) ptep) >> 4; for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) { - srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp); + set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp); ptp += (SRMMU_REAL_PTRS_PER_PTE*sizeof(pte_t) >> 4); } } -static void srmmu_pmd_populate(pmd_t *pmdp, struct page *ptep) +void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep) { unsigned long ptp; /* Physical address, shifted right by 4 */ int i; ptp = page_to_pfn(ptep) << (PAGE_SHIFT-4); /* watch for overflow */ for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) { - srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp); + set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp); ptp += (SRMMU_REAL_PTRS_PER_PTE*sizeof(pte_t) >> 4); } } -static inline pte_t srmmu_pte_modify(pte_t pte, pgprot_t newprot) -{ return __pte((pte_val(pte) & SRMMU_CHG_MASK) | pgprot_val(newprot)); } - -/* to find an entry in a top-level page table... */ -static inline pgd_t *srmmu_pgd_offset(struct mm_struct * mm, unsigned long address) -{ return mm->pgd + (address >> SRMMU_PGDIR_SHIFT); } - -/* Find an entry in the second-level page table.. */ -static inline pmd_t *srmmu_pmd_offset(pgd_t * dir, unsigned long address) -{ - return (pmd_t *) srmmu_pgd_page(*dir) + - ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1)); -} - /* Find an entry in the third-level page table.. */ -static inline pte_t *srmmu_pte_offset(pmd_t * dir, unsigned long address) +pte_t *pte_offset_kernel(pmd_t * dir, unsigned long address) { void *pte; @@ -276,23 +146,6 @@ ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); } -static unsigned long srmmu_swp_type(swp_entry_t entry) -{ - return (entry.val >> SRMMU_SWP_TYPE_SHIFT) & SRMMU_SWP_TYPE_MASK; -} - -static unsigned long srmmu_swp_offset(swp_entry_t entry) -{ - return (entry.val >> SRMMU_SWP_OFF_SHIFT) & SRMMU_SWP_OFF_MASK; -} - -static swp_entry_t srmmu_swp_entry(unsigned long type, unsigned long offset) -{ - return (swp_entry_t) { - (type & SRMMU_SWP_TYPE_MASK) << SRMMU_SWP_TYPE_SHIFT - | (offset & SRMMU_SWP_OFF_MASK) << SRMMU_SWP_OFF_SHIFT }; -} - /* * size: bytes to allocate in the nocache area. * align: bytes, number to align at. @@ -325,7 +178,7 @@ return (SRMMU_NOCACHE_VADDR + (offset << SRMMU_NOCACHE_BITMAP_SHIFT)); } -static unsigned long srmmu_get_nocache(int size, int align) +unsigned long srmmu_get_nocache(int size, int align) { unsigned long tmp; @@ -337,7 +190,7 @@ return tmp; } -static void srmmu_free_nocache(unsigned long vaddr, int size) +void srmmu_free_nocache(unsigned long vaddr, int size) { int offset; @@ -429,15 +282,15 @@ while (vaddr < srmmu_nocache_end) { pgd = pgd_offset_k(vaddr); - pmd = srmmu_pmd_offset(__nocache_fix(pgd), vaddr); - pte = srmmu_pte_offset(__nocache_fix(pmd), vaddr); + pmd = pmd_offset(__nocache_fix(pgd), vaddr); + pte = pte_offset_kernel(__nocache_fix(pmd), vaddr); pteval = ((paddr >> 4) | SRMMU_ET_PTE | SRMMU_PRIV); if (srmmu_cache_pagetables) pteval |= SRMMU_CACHE; - srmmu_set_pte(__nocache_fix(pte), __pte(pteval)); + set_pte(__nocache_fix(pte), __pte(pteval)); vaddr += PAGE_SIZE; paddr += PAGE_SIZE; @@ -447,7 +300,7 @@ flush_tlb_all(); } -static inline pgd_t *srmmu_get_pgd_fast(void) +pgd_t *get_pgd_fast(void) { pgd_t *pgd = NULL; @@ -462,21 +315,6 @@ return pgd; } -static void srmmu_free_pgd_fast(pgd_t *pgd) -{ - srmmu_free_nocache((unsigned long)pgd, SRMMU_PGD_TABLE_SIZE); -} - -static pmd_t *srmmu_pmd_alloc_one(struct mm_struct *mm, unsigned long address) -{ - return (pmd_t *)srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); -} - -static void srmmu_pmd_free(pmd_t * pmd) -{ - srmmu_free_nocache((unsigned long)pmd, SRMMU_PMD_TABLE_SIZE); -} - /* * Hardware needs alignment to 256 only, but we align to whole page size * to reduce fragmentation problems due to the buddy principle. @@ -485,31 +323,19 @@ * Alignments up to the page size are the same for physical and virtual * addresses of the nocache area. */ -static pte_t * -srmmu_pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) -{ - return (pte_t *)srmmu_get_nocache(PTE_SIZE, PTE_SIZE); -} - -static pgtable_t -srmmu_pte_alloc_one(struct mm_struct *mm, unsigned long address) +pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) { unsigned long pte; struct page *page; - if ((pte = (unsigned long)srmmu_pte_alloc_one_kernel(mm, address)) == 0) + if ((pte = (unsigned long)pte_alloc_one_kernel(mm, address)) == 0) return NULL; page = pfn_to_page( __nocache_pa(pte) >> PAGE_SHIFT ); pgtable_page_ctor(page); return page; } -static void srmmu_free_pte_fast(pte_t *pte) -{ - srmmu_free_nocache((unsigned long)pte, PTE_SIZE); -} - -static void srmmu_pte_free(pgtable_t pte) +void pte_free(struct mm_struct *mm, pgtable_t pte) { unsigned long p; @@ -560,8 +386,8 @@ } -static void srmmu_switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, - struct task_struct *tsk, int cpu) +void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, + struct task_struct *tsk) { if(mm->context == NO_CONTEXT) { spin_lock(&srmmu_context_spinlock); @@ -590,8 +416,8 @@ physaddr &= PAGE_MASK; pgdp = pgd_offset_k(virt_addr); - pmdp = srmmu_pmd_offset(pgdp, virt_addr); - ptep = srmmu_pte_offset(pmdp, virt_addr); + pmdp = pmd_offset(pgdp, virt_addr); + ptep = pte_offset_kernel(pmdp, virt_addr); tmp = (physaddr >> 4) | SRMMU_ET_PTE; /* @@ -602,11 +428,11 @@ tmp |= (bus_type << 28); tmp |= SRMMU_PRIV; __flush_page_to_ram(virt_addr); - srmmu_set_pte(ptep, __pte(tmp)); + set_pte(ptep, __pte(tmp)); } -static void srmmu_mapiorange(unsigned int bus, unsigned long xpa, - unsigned long xva, unsigned int len) +void srmmu_mapiorange(unsigned int bus, unsigned long xpa, + unsigned long xva, unsigned int len) { while (len != 0) { len -= PAGE_SIZE; @@ -624,14 +450,14 @@ pte_t *ptep; pgdp = pgd_offset_k(virt_addr); - pmdp = srmmu_pmd_offset(pgdp, virt_addr); - ptep = srmmu_pte_offset(pmdp, virt_addr); + pmdp = pmd_offset(pgdp, virt_addr); + ptep = pte_offset_kernel(pmdp, virt_addr); /* No need to flush uncacheable page. */ - srmmu_pte_clear(ptep); + __pte_clear(ptep); } -static void srmmu_unmapiorange(unsigned long virt_addr, unsigned int len) +void srmmu_unmapiorange(unsigned long virt_addr, unsigned int len) { while (len != 0) { len -= PAGE_SIZE; @@ -647,10 +473,9 @@ * pool. As a side effect we are putting a little too much pressure * on the gfp() subsystem. This setup also makes the logic of the * iommu mapping code a lot easier as we can transparently handle - * mappings on the kernel stack without any special code as we did - * need on the sun4c. + * mappings on the kernel stack without any special code. */ -static struct thread_info *srmmu_alloc_thread_info_node(int node) +struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node) { struct thread_info *ret; @@ -664,7 +489,7 @@ return ret; } -static void srmmu_free_thread_info(struct thread_info *ti) +void free_thread_info(struct thread_info *ti) { free_pages((unsigned long)ti, THREAD_INFO_ORDER); } @@ -683,38 +508,6 @@ extern void tsunami_flush_tlb_page(struct vm_area_struct *vma, unsigned long page); extern void tsunami_setup_blockops(void); -/* - * Workaround, until we find what's going on with Swift. When low on memory, - * it sometimes loops in fault/handle_mm_fault incl. flush_tlb_page to find - * out it is already in page tables/ fault again on the same instruction. - * I really don't understand it, have checked it and contexts - * are right, flush_tlb_all is done as well, and it faults again... - * Strange. -jj - * - * The following code is a deadwood that may be necessary when - * we start to make precise page flushes again. --zaitcev - */ -static void swift_update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t *ptep) -{ -#if 0 - static unsigned long last; - unsigned int val; - /* unsigned int n; */ - - if (address == last) { - val = srmmu_hwprobe(address); - if (val != 0 && pte_val(*ptep) != val) { - printk("swift_update_mmu_cache: " - "addr %lx put %08x probed %08x from %p\n", - address, pte_val(*ptep), val, - __builtin_return_address(0)); - srmmu_flush_whole_tlb(); - } - } - last = address; -#endif -} - /* swift.S */ extern void swift_flush_cache_all(void); extern void swift_flush_cache_mm(struct mm_struct *mm); @@ -767,244 +560,6 @@ * with respect to cache coherency. */ -/* Cypress flushes. */ -static void cypress_flush_cache_all(void) -{ - volatile unsigned long cypress_sucks; - unsigned long faddr, tagval; - - flush_user_windows(); - for(faddr = 0; faddr < 0x10000; faddr += 0x20) { - __asm__ __volatile__("lda [%1 + %2] %3, %0\n\t" : - "=r" (tagval) : - "r" (faddr), "r" (0x40000), - "i" (ASI_M_DATAC_TAG)); - - /* If modified and valid, kick it. */ - if((tagval & 0x60) == 0x60) - cypress_sucks = *(unsigned long *)(0xf0020000 + faddr); - } -} - -static void cypress_flush_cache_mm(struct mm_struct *mm) -{ - register unsigned long a, b, c, d, e, f, g; - unsigned long flags, faddr; - int octx; - - FLUSH_BEGIN(mm) - flush_user_windows(); - local_irq_save(flags); - octx = srmmu_get_context(); - srmmu_set_context(mm->context); - a = 0x20; b = 0x40; c = 0x60; - d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0; - - faddr = (0x10000 - 0x100); - goto inside; - do { - faddr -= 0x100; - inside: - __asm__ __volatile__("sta %%g0, [%0] %1\n\t" - "sta %%g0, [%0 + %2] %1\n\t" - "sta %%g0, [%0 + %3] %1\n\t" - "sta %%g0, [%0 + %4] %1\n\t" - "sta %%g0, [%0 + %5] %1\n\t" - "sta %%g0, [%0 + %6] %1\n\t" - "sta %%g0, [%0 + %7] %1\n\t" - "sta %%g0, [%0 + %8] %1\n\t" : : - "r" (faddr), "i" (ASI_M_FLUSH_CTX), - "r" (a), "r" (b), "r" (c), "r" (d), - "r" (e), "r" (f), "r" (g)); - } while(faddr); - srmmu_set_context(octx); - local_irq_restore(flags); - FLUSH_END -} - -static void cypress_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - register unsigned long a, b, c, d, e, f, g; - unsigned long flags, faddr; - int octx; - - FLUSH_BEGIN(mm) - flush_user_windows(); - local_irq_save(flags); - octx = srmmu_get_context(); - srmmu_set_context(mm->context); - a = 0x20; b = 0x40; c = 0x60; - d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0; - - start &= SRMMU_REAL_PMD_MASK; - while(start < end) { - faddr = (start + (0x10000 - 0x100)); - goto inside; - do { - faddr -= 0x100; - inside: - __asm__ __volatile__("sta %%g0, [%0] %1\n\t" - "sta %%g0, [%0 + %2] %1\n\t" - "sta %%g0, [%0 + %3] %1\n\t" - "sta %%g0, [%0 + %4] %1\n\t" - "sta %%g0, [%0 + %5] %1\n\t" - "sta %%g0, [%0 + %6] %1\n\t" - "sta %%g0, [%0 + %7] %1\n\t" - "sta %%g0, [%0 + %8] %1\n\t" : : - "r" (faddr), - "i" (ASI_M_FLUSH_SEG), - "r" (a), "r" (b), "r" (c), "r" (d), - "r" (e), "r" (f), "r" (g)); - } while (faddr != start); - start += SRMMU_REAL_PMD_SIZE; - } - srmmu_set_context(octx); - local_irq_restore(flags); - FLUSH_END -} - -static void cypress_flush_cache_page(struct vm_area_struct *vma, unsigned long page) -{ - register unsigned long a, b, c, d, e, f, g; - struct mm_struct *mm = vma->vm_mm; - unsigned long flags, line; - int octx; - - FLUSH_BEGIN(mm) - flush_user_windows(); - local_irq_save(flags); - octx = srmmu_get_context(); - srmmu_set_context(mm->context); - a = 0x20; b = 0x40; c = 0x60; - d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0; - - page &= PAGE_MASK; - line = (page + PAGE_SIZE) - 0x100; - goto inside; - do { - line -= 0x100; - inside: - __asm__ __volatile__("sta %%g0, [%0] %1\n\t" - "sta %%g0, [%0 + %2] %1\n\t" - "sta %%g0, [%0 + %3] %1\n\t" - "sta %%g0, [%0 + %4] %1\n\t" - "sta %%g0, [%0 + %5] %1\n\t" - "sta %%g0, [%0 + %6] %1\n\t" - "sta %%g0, [%0 + %7] %1\n\t" - "sta %%g0, [%0 + %8] %1\n\t" : : - "r" (line), - "i" (ASI_M_FLUSH_PAGE), - "r" (a), "r" (b), "r" (c), "r" (d), - "r" (e), "r" (f), "r" (g)); - } while(line != page); - srmmu_set_context(octx); - local_irq_restore(flags); - FLUSH_END -} - -/* Cypress is copy-back, at least that is how we configure it. */ -static void cypress_flush_page_to_ram(unsigned long page) -{ - register unsigned long a, b, c, d, e, f, g; - unsigned long line; - - a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0; - page &= PAGE_MASK; - line = (page + PAGE_SIZE) - 0x100; - goto inside; - do { - line -= 0x100; - inside: - __asm__ __volatile__("sta %%g0, [%0] %1\n\t" - "sta %%g0, [%0 + %2] %1\n\t" - "sta %%g0, [%0 + %3] %1\n\t" - "sta %%g0, [%0 + %4] %1\n\t" - "sta %%g0, [%0 + %5] %1\n\t" - "sta %%g0, [%0 + %6] %1\n\t" - "sta %%g0, [%0 + %7] %1\n\t" - "sta %%g0, [%0 + %8] %1\n\t" : : - "r" (line), - "i" (ASI_M_FLUSH_PAGE), - "r" (a), "r" (b), "r" (c), "r" (d), - "r" (e), "r" (f), "r" (g)); - } while(line != page); -} - -/* Cypress is also IO cache coherent. */ -static void cypress_flush_page_for_dma(unsigned long page) -{ -} - -/* Cypress has unified L2 VIPT, from which both instructions and data - * are stored. It does not have an onboard icache of any sort, therefore - * no flush is necessary. - */ -static void cypress_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) -{ -} - -static void cypress_flush_tlb_all(void) -{ - srmmu_flush_whole_tlb(); -} - -static void cypress_flush_tlb_mm(struct mm_struct *mm) -{ - FLUSH_BEGIN(mm) - __asm__ __volatile__( - "lda [%0] %3, %%g5\n\t" - "sta %2, [%0] %3\n\t" - "sta %%g0, [%1] %4\n\t" - "sta %%g5, [%0] %3\n" - : /* no outputs */ - : "r" (SRMMU_CTX_REG), "r" (0x300), "r" (mm->context), - "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE) - : "g5"); - FLUSH_END -} - -static void cypress_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long size; - - FLUSH_BEGIN(mm) - start &= SRMMU_PGDIR_MASK; - size = SRMMU_PGDIR_ALIGN(end) - start; - __asm__ __volatile__( - "lda [%0] %5, %%g5\n\t" - "sta %1, [%0] %5\n" - "1:\n\t" - "subcc %3, %4, %3\n\t" - "bne 1b\n\t" - " sta %%g0, [%2 + %3] %6\n\t" - "sta %%g5, [%0] %5\n" - : /* no outputs */ - : "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (start | 0x200), - "r" (size), "r" (SRMMU_PGDIR_SIZE), "i" (ASI_M_MMUREGS), - "i" (ASI_M_FLUSH_PROBE) - : "g5", "cc"); - FLUSH_END -} - -static void cypress_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - - FLUSH_BEGIN(mm) - __asm__ __volatile__( - "lda [%0] %3, %%g5\n\t" - "sta %1, [%0] %3\n\t" - "sta %%g0, [%2] %4\n\t" - "sta %%g5, [%0] %3\n" - : /* no outputs */ - : "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (page & PAGE_MASK), - "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE) - : "g5"); - FLUSH_END -} - /* viking.S */ extern void viking_flush_cache_all(void); extern void viking_flush_cache_mm(struct mm_struct *mm); @@ -1065,21 +620,21 @@ while(start < end) { pgdp = pgd_offset_k(start); - if(srmmu_pgd_none(*(pgd_t *)__nocache_fix(pgdp))) { + if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) { pmdp = (pmd_t *) __srmmu_get_nocache( SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); if (pmdp == NULL) early_pgtable_allocfail("pmd"); memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE); - srmmu_pgd_set(__nocache_fix(pgdp), pmdp); + pgd_set(__nocache_fix(pgdp), pmdp); } - pmdp = srmmu_pmd_offset(__nocache_fix(pgdp), start); + pmdp = pmd_offset(__nocache_fix(pgdp), start); if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) { ptep = (pte_t *)__srmmu_get_nocache(PTE_SIZE, PTE_SIZE); if (ptep == NULL) early_pgtable_allocfail("pte"); memset(__nocache_fix(ptep), 0, PTE_SIZE); - srmmu_pmd_set(__nocache_fix(pmdp), ptep); + pmd_set(__nocache_fix(pmdp), ptep); } if (start > (0xffffffffUL - PMD_SIZE)) break; @@ -1096,21 +651,21 @@ while(start < end) { pgdp = pgd_offset_k(start); - if(srmmu_pgd_none(*pgdp)) { + if (pgd_none(*pgdp)) { pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); if (pmdp == NULL) early_pgtable_allocfail("pmd"); memset(pmdp, 0, SRMMU_PMD_TABLE_SIZE); - srmmu_pgd_set(pgdp, pmdp); + pgd_set(pgdp, pmdp); } - pmdp = srmmu_pmd_offset(pgdp, start); + pmdp = pmd_offset(pgdp, start); if(srmmu_pmd_none(*pmdp)) { ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE, PTE_SIZE); if (ptep == NULL) early_pgtable_allocfail("pte"); memset(ptep, 0, PTE_SIZE); - srmmu_pmd_set(pmdp, ptep); + pmd_set(pmdp, ptep); } if (start > (0xffffffffUL - PMD_SIZE)) break; @@ -1162,21 +717,21 @@ start += SRMMU_PGDIR_SIZE; continue; } - if(srmmu_pgd_none(*(pgd_t *)__nocache_fix(pgdp))) { + if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) { pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); if (pmdp == NULL) early_pgtable_allocfail("pmd"); memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE); - srmmu_pgd_set(__nocache_fix(pgdp), pmdp); + pgd_set(__nocache_fix(pgdp), pmdp); } - pmdp = srmmu_pmd_offset(__nocache_fix(pgdp), start); + pmdp = pmd_offset(__nocache_fix(pgdp), start); if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) { ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE, PTE_SIZE); if (ptep == NULL) early_pgtable_allocfail("pte"); memset(__nocache_fix(ptep), 0, PTE_SIZE); - srmmu_pmd_set(__nocache_fix(pmdp), ptep); + pmd_set(__nocache_fix(pmdp), ptep); } if(what == 1) { /* @@ -1190,7 +745,7 @@ start += SRMMU_REAL_PMD_SIZE; continue; } - ptep = srmmu_pte_offset(__nocache_fix(pmdp), start); + ptep = pte_offset_kernel(__nocache_fix(pmdp), start); *(pte_t *)__nocache_fix(ptep) = __pte(prompte); start += PAGE_SIZE; } @@ -1231,13 +786,6 @@ return vstart; } -static inline void memprobe_error(char *msg) -{ - prom_printf(msg); - prom_printf("Halting now...\n"); - prom_halt(); -} - static inline void map_kernel(void) { int i; @@ -1249,8 +797,6 @@ for (i = 0; sp_banks[i].num_bytes != 0; i++) { map_spbank((unsigned long)__va(sp_banks[i].base_addr), i); } - - BTFIXUPSET_SIMM13(user_ptrs_per_pgd, PAGE_OFFSET / SRMMU_PGDIR_SIZE); } /* Paging initialization on the Sparc Reference MMU. */ @@ -1312,7 +858,7 @@ srmmu_set_ctable_ptr((unsigned long)srmmu_ctx_table_phys); #ifdef CONFIG_SMP /* Stop from hanging here... */ - local_flush_tlb_all(); + local_ops->tlb_all(); #else flush_tlb_all(); #endif @@ -1326,8 +872,8 @@ srmmu_allocate_ptable_skeleton(PKMAP_BASE, PKMAP_END); pgd = pgd_offset_k(PKMAP_BASE); - pmd = srmmu_pmd_offset(pgd, PKMAP_BASE); - pte = srmmu_pte_offset(pmd, PKMAP_BASE); + pmd = pmd_offset(pgd, PKMAP_BASE); + pte = pte_offset_kernel(pmd, PKMAP_BASE); pkmap_page_table = pte; flush_cache_all(); @@ -1359,7 +905,7 @@ } } -static void srmmu_mmu_info(struct seq_file *m) +void mmu_info(struct seq_file *m) { seq_printf(m, "MMU type\t: %s\n" @@ -1372,11 +918,7 @@ srmmu_nocache_map.used << SRMMU_NOCACHE_BITMAP_SHIFT); } -static void srmmu_update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t pte) -{ -} - -static void srmmu_destroy_context(struct mm_struct *mm) +void destroy_context(struct mm_struct *mm) { if(mm->context != NO_CONTEXT) { @@ -1474,6 +1016,20 @@ clear = srmmu_get_fstatus(); } +static const struct sparc32_cachetlb_ops hypersparc_ops = { + .cache_all = hypersparc_flush_cache_all, + .cache_mm = hypersparc_flush_cache_mm, + .cache_page = hypersparc_flush_cache_page, + .cache_range = hypersparc_flush_cache_range, + .tlb_all = hypersparc_flush_tlb_all, + .tlb_mm = hypersparc_flush_tlb_mm, + .tlb_page = hypersparc_flush_tlb_page, + .tlb_range = hypersparc_flush_tlb_range, + .page_to_ram = hypersparc_flush_page_to_ram, + .sig_insns = hypersparc_flush_sig_insns, + .page_for_dma = hypersparc_flush_page_for_dma, +}; + static void __init init_hypersparc(void) { srmmu_name = "ROSS HyperSparc"; @@ -1482,118 +1038,13 @@ init_vac_layout(); is_hypersparc = 1; - - BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_all, hypersparc_flush_cache_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_mm, hypersparc_flush_cache_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_range, hypersparc_flush_cache_range, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_page, hypersparc_flush_cache_page, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(flush_tlb_all, hypersparc_flush_tlb_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_mm, hypersparc_flush_tlb_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_range, hypersparc_flush_tlb_range, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_page, hypersparc_flush_tlb_page, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(__flush_page_to_ram, hypersparc_flush_page_to_ram, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_sig_insns, hypersparc_flush_sig_insns, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_page_for_dma, hypersparc_flush_page_for_dma, BTFIXUPCALL_NOP); - + sparc32_cachetlb_ops = &hypersparc_ops; poke_srmmu = poke_hypersparc; hypersparc_setup_blockops(); } -static void __cpuinit poke_cypress(void) -{ - unsigned long mreg = srmmu_get_mmureg(); - unsigned long faddr, tagval; - volatile unsigned long cypress_sucks; - volatile unsigned long clear; - - clear = srmmu_get_faddr(); - clear = srmmu_get_fstatus(); - - if (!(mreg & CYPRESS_CENABLE)) { - for(faddr = 0x0; faddr < 0x10000; faddr += 20) { - __asm__ __volatile__("sta %%g0, [%0 + %1] %2\n\t" - "sta %%g0, [%0] %2\n\t" : : - "r" (faddr), "r" (0x40000), - "i" (ASI_M_DATAC_TAG)); - } - } else { - for(faddr = 0; faddr < 0x10000; faddr += 0x20) { - __asm__ __volatile__("lda [%1 + %2] %3, %0\n\t" : - "=r" (tagval) : - "r" (faddr), "r" (0x40000), - "i" (ASI_M_DATAC_TAG)); - - /* If modified and valid, kick it. */ - if((tagval & 0x60) == 0x60) - cypress_sucks = *(unsigned long *) - (0xf0020000 + faddr); - } - } - - /* And one more, for our good neighbor, Mr. Broken Cypress. */ - clear = srmmu_get_faddr(); - clear = srmmu_get_fstatus(); - - mreg |= (CYPRESS_CENABLE | CYPRESS_CMODE); - srmmu_set_mmureg(mreg); -} - -static void __init init_cypress_common(void) -{ - init_vac_layout(); - - BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_all, cypress_flush_cache_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_mm, cypress_flush_cache_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_range, cypress_flush_cache_range, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_page, cypress_flush_cache_page, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(flush_tlb_all, cypress_flush_tlb_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_mm, cypress_flush_tlb_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_page, cypress_flush_tlb_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_range, cypress_flush_tlb_range, BTFIXUPCALL_NORM); - - - BTFIXUPSET_CALL(__flush_page_to_ram, cypress_flush_page_to_ram, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_sig_insns, cypress_flush_sig_insns, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(flush_page_for_dma, cypress_flush_page_for_dma, BTFIXUPCALL_NOP); - - poke_srmmu = poke_cypress; -} - -static void __init init_cypress_604(void) -{ - srmmu_name = "ROSS Cypress-604(UP)"; - srmmu_modtype = Cypress; - init_cypress_common(); -} - -static void __init init_cypress_605(unsigned long mrev) -{ - srmmu_name = "ROSS Cypress-605(MP)"; - if(mrev == 0xe) { - srmmu_modtype = Cypress_vE; - hwbug_bitmask |= HWBUG_COPYBACK_BROKEN; - } else { - if(mrev == 0xd) { - srmmu_modtype = Cypress_vD; - hwbug_bitmask |= HWBUG_ASIFLUSH_BROKEN; - } else { - srmmu_modtype = Cypress; - } - } - init_cypress_common(); -} - static void __cpuinit poke_swift(void) { unsigned long mreg; @@ -1617,6 +1068,20 @@ srmmu_set_mmureg(mreg); } +static const struct sparc32_cachetlb_ops swift_ops = { + .cache_all = swift_flush_cache_all, + .cache_mm = swift_flush_cache_mm, + .cache_page = swift_flush_cache_page, + .cache_range = swift_flush_cache_range, + .tlb_all = swift_flush_tlb_all, + .tlb_mm = swift_flush_tlb_mm, + .tlb_page = swift_flush_tlb_page, + .tlb_range = swift_flush_tlb_range, + .page_to_ram = swift_flush_page_to_ram, + .sig_insns = swift_flush_sig_insns, + .page_for_dma = swift_flush_page_for_dma, +}; + #define SWIFT_MASKID_ADDR 0x10003018 static void __init init_swift(void) { @@ -1667,23 +1132,7 @@ break; } - BTFIXUPSET_CALL(flush_cache_all, swift_flush_cache_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_mm, swift_flush_cache_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_page, swift_flush_cache_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_range, swift_flush_cache_range, BTFIXUPCALL_NORM); - - - BTFIXUPSET_CALL(flush_tlb_all, swift_flush_tlb_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_mm, swift_flush_tlb_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_page, swift_flush_tlb_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_range, swift_flush_tlb_range, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(__flush_page_to_ram, swift_flush_page_to_ram, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_sig_insns, swift_flush_sig_insns, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_page_for_dma, swift_flush_page_for_dma, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(update_mmu_cache, swift_update_mmu_cache, BTFIXUPCALL_NORM); - + sparc32_cachetlb_ops = &swift_ops; flush_page_for_dma_global = 0; /* @@ -1816,26 +1265,25 @@ srmmu_set_mmureg(mreg); } +static const struct sparc32_cachetlb_ops turbosparc_ops = { + .cache_all = turbosparc_flush_cache_all, + .cache_mm = turbosparc_flush_cache_mm, + .cache_page = turbosparc_flush_cache_page, + .cache_range = turbosparc_flush_cache_range, + .tlb_all = turbosparc_flush_tlb_all, + .tlb_mm = turbosparc_flush_tlb_mm, + .tlb_page = turbosparc_flush_tlb_page, + .tlb_range = turbosparc_flush_tlb_range, + .page_to_ram = turbosparc_flush_page_to_ram, + .sig_insns = turbosparc_flush_sig_insns, + .page_for_dma = turbosparc_flush_page_for_dma, +}; + static void __init init_turbosparc(void) { srmmu_name = "Fujitsu TurboSparc"; srmmu_modtype = TurboSparc; - - BTFIXUPSET_CALL(flush_cache_all, turbosparc_flush_cache_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_mm, turbosparc_flush_cache_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_page, turbosparc_flush_cache_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_range, turbosparc_flush_cache_range, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(flush_tlb_all, turbosparc_flush_tlb_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_mm, turbosparc_flush_tlb_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_page, turbosparc_flush_tlb_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_range, turbosparc_flush_tlb_range, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(__flush_page_to_ram, turbosparc_flush_page_to_ram, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(flush_sig_insns, turbosparc_flush_sig_insns, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(flush_page_for_dma, turbosparc_flush_page_for_dma, BTFIXUPCALL_NORM); - + sparc32_cachetlb_ops = &turbosparc_ops; poke_srmmu = poke_turbosparc; } @@ -1850,6 +1298,20 @@ srmmu_set_mmureg(mreg); } +static const struct sparc32_cachetlb_ops tsunami_ops = { + .cache_all = tsunami_flush_cache_all, + .cache_mm = tsunami_flush_cache_mm, + .cache_page = tsunami_flush_cache_page, + .cache_range = tsunami_flush_cache_range, + .tlb_all = tsunami_flush_tlb_all, + .tlb_mm = tsunami_flush_tlb_mm, + .tlb_page = tsunami_flush_tlb_page, + .tlb_range = tsunami_flush_tlb_range, + .page_to_ram = tsunami_flush_page_to_ram, + .sig_insns = tsunami_flush_sig_insns, + .page_for_dma = tsunami_flush_page_for_dma, +}; + static void __init init_tsunami(void) { /* @@ -1860,22 +1322,7 @@ srmmu_name = "TI Tsunami"; srmmu_modtype = Tsunami; - - BTFIXUPSET_CALL(flush_cache_all, tsunami_flush_cache_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_mm, tsunami_flush_cache_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_page, tsunami_flush_cache_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_range, tsunami_flush_cache_range, BTFIXUPCALL_NORM); - - - BTFIXUPSET_CALL(flush_tlb_all, tsunami_flush_tlb_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_mm, tsunami_flush_tlb_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_page, tsunami_flush_tlb_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_range, tsunami_flush_tlb_range, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(__flush_page_to_ram, tsunami_flush_page_to_ram, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(flush_sig_insns, tsunami_flush_sig_insns, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_page_for_dma, tsunami_flush_page_for_dma, BTFIXUPCALL_NORM); - + sparc32_cachetlb_ops = &tsunami_ops; poke_srmmu = poke_tsunami; tsunami_setup_blockops(); @@ -1886,7 +1333,7 @@ unsigned long mreg = srmmu_get_mmureg(); static int smp_catch; - if(viking_mxcc_present) { + if (viking_mxcc_present) { unsigned long mxcc_control = mxcc_get_creg(); mxcc_control |= (MXCC_CTL_ECE | MXCC_CTL_PRE | MXCC_CTL_MCE); @@ -1923,6 +1370,52 @@ srmmu_set_mmureg(mreg); } +static struct sparc32_cachetlb_ops viking_ops = { + .cache_all = viking_flush_cache_all, + .cache_mm = viking_flush_cache_mm, + .cache_page = viking_flush_cache_page, + .cache_range = viking_flush_cache_range, + .tlb_all = viking_flush_tlb_all, + .tlb_mm = viking_flush_tlb_mm, + .tlb_page = viking_flush_tlb_page, + .tlb_range = viking_flush_tlb_range, + .page_to_ram = viking_flush_page_to_ram, + .sig_insns = viking_flush_sig_insns, + .page_for_dma = viking_flush_page_for_dma, +}; + +#ifdef CONFIG_SMP +/* On sun4d the cpu broadcasts local TLB flushes, so we can just + * perform the local TLB flush and all the other cpus will see it. + * But, unfortunately, there is a bug in the sun4d XBUS backplane + * that requires that we add some synchronization to these flushes. + * + * The bug is that the fifo which keeps track of all the pending TLB + * broadcasts in the system is an entry or two too small, so if we + * have too many going at once we'll overflow that fifo and lose a TLB + * flush resulting in corruption. + * + * Our workaround is to take a global spinlock around the TLB flushes, + * which guarentees we won't ever have too many pending. It's a big + * hammer, but a semaphore like system to make sure we only have N TLB + * flushes going at once will require SMP locking anyways so there's + * no real value in trying any harder than this. + */ +static struct sparc32_cachetlb_ops viking_sun4d_smp_ops = { + .cache_all = viking_flush_cache_all, + .cache_mm = viking_flush_cache_mm, + .cache_page = viking_flush_cache_page, + .cache_range = viking_flush_cache_range, + .tlb_all = sun4dsmp_flush_tlb_all, + .tlb_mm = sun4dsmp_flush_tlb_mm, + .tlb_page = sun4dsmp_flush_tlb_page, + .tlb_range = sun4dsmp_flush_tlb_range, + .page_to_ram = viking_flush_page_to_ram, + .sig_insns = viking_flush_sig_insns, + .page_for_dma = viking_flush_page_for_dma, +}; +#endif + static void __init init_viking(void) { unsigned long mreg = srmmu_get_mmureg(); @@ -1933,10 +1426,6 @@ viking_mxcc_present = 0; msi_set_sync(); - BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_NORM); - /* * We need this to make sure old viking takes no hits * on it's cache for dma snoops to workaround the @@ -1944,84 +1433,28 @@ * This is only necessary because of the new way in * which we use the IOMMU. */ - BTFIXUPSET_CALL(flush_page_for_dma, viking_flush_page, BTFIXUPCALL_NORM); - + viking_ops.page_for_dma = viking_flush_page; +#ifdef CONFIG_SMP + viking_sun4d_smp_ops.page_for_dma = viking_flush_page; +#endif flush_page_for_dma_global = 0; } else { srmmu_name = "TI Viking/MXCC"; viking_mxcc_present = 1; - srmmu_cache_pagetables = 1; - - /* MXCC vikings lack the DMA snooping bug. */ - BTFIXUPSET_CALL(flush_page_for_dma, viking_flush_page_for_dma, BTFIXUPCALL_NOP); } - BTFIXUPSET_CALL(flush_cache_all, viking_flush_cache_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_mm, viking_flush_cache_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_page, viking_flush_cache_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_range, viking_flush_cache_range, BTFIXUPCALL_NORM); - + sparc32_cachetlb_ops = (const struct sparc32_cachetlb_ops *) + &viking_ops; #ifdef CONFIG_SMP - if (sparc_cpu_model == sun4d) { - BTFIXUPSET_CALL(flush_tlb_all, sun4dsmp_flush_tlb_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_mm, sun4dsmp_flush_tlb_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_page, sun4dsmp_flush_tlb_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_range, sun4dsmp_flush_tlb_range, BTFIXUPCALL_NORM); - } else + if (sparc_cpu_model == sun4d) + sparc32_cachetlb_ops = (const struct sparc32_cachetlb_ops *) + &viking_sun4d_smp_ops; #endif - { - BTFIXUPSET_CALL(flush_tlb_all, viking_flush_tlb_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_mm, viking_flush_tlb_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_page, viking_flush_tlb_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_range, viking_flush_tlb_range, BTFIXUPCALL_NORM); - } - - BTFIXUPSET_CALL(__flush_page_to_ram, viking_flush_page_to_ram, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(flush_sig_insns, viking_flush_sig_insns, BTFIXUPCALL_NOP); poke_srmmu = poke_viking; } -#ifdef CONFIG_SPARC_LEON - -void __init poke_leonsparc(void) -{ -} - -void __init init_leon(void) -{ - - srmmu_name = "LEON"; - - BTFIXUPSET_CALL(flush_cache_all, leon_flush_cache_all, - BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_mm, leon_flush_cache_all, - BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_page, leon_flush_pcache_all, - BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_range, leon_flush_cache_all, - BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_page_for_dma, leon_flush_dcache_all, - BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(flush_tlb_all, leon_flush_tlb_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_mm, leon_flush_tlb_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_page, leon_flush_tlb_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_range, leon_flush_tlb_all, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(__flush_page_to_ram, leon_flush_cache_all, - BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(flush_sig_insns, leon_flush_cache_all, BTFIXUPCALL_NOP); - - poke_srmmu = poke_leonsparc; - - srmmu_cache_pagetables = 0; - - leon_flush_during_switch = leon_flush_needed(); -} -#endif - /* Probe for the srmmu chip version. */ static void __init get_srmmu_type(void) { @@ -2052,22 +1485,15 @@ break; case 0: case 2: - /* Uniprocessor Cypress */ - init_cypress_604(); - break; case 10: case 11: case 12: - /* _REALLY OLD_ Cypress MP chips... */ case 13: case 14: case 15: - /* MP Cypress mmu/cache-controller */ - init_cypress_605(mod_rev); - break; default: - /* Some other Cypress revision, assume a 605. */ - init_cypress_605(mod_rev); + prom_printf("Sparc-Linux Cypress support does not longer exit.\n"); + prom_halt(); break; } return; @@ -2123,203 +1549,193 @@ srmmu_is_bad(); } -/* don't laugh, static pagetables */ -static void srmmu_check_pgt_cache(int low, int high) -{ -} - -extern unsigned long spwin_mmu_patchme, fwin_mmu_patchme, - tsetup_mmu_patchme, rtrap_mmu_patchme; - -extern unsigned long spwin_srmmu_stackchk, srmmu_fwin_stackchk, - tsetup_srmmu_stackchk, srmmu_rett_stackchk; - -extern unsigned long srmmu_fault; - -#define PATCH_BRANCH(insn, dest) do { \ - iaddr = &(insn); \ - daddr = &(dest); \ - *iaddr = SPARC_BRANCH((unsigned long) daddr, (unsigned long) iaddr); \ - } while(0) - -static void __init patch_window_trap_handlers(void) -{ - unsigned long *iaddr, *daddr; - - PATCH_BRANCH(spwin_mmu_patchme, spwin_srmmu_stackchk); - PATCH_BRANCH(fwin_mmu_patchme, srmmu_fwin_stackchk); - PATCH_BRANCH(tsetup_mmu_patchme, tsetup_srmmu_stackchk); - PATCH_BRANCH(rtrap_mmu_patchme, srmmu_rett_stackchk); - PATCH_BRANCH(sparc_ttable[SP_TRAP_TFLT].inst_three, srmmu_fault); - PATCH_BRANCH(sparc_ttable[SP_TRAP_DFLT].inst_three, srmmu_fault); - PATCH_BRANCH(sparc_ttable[SP_TRAP_DACC].inst_three, srmmu_fault); -} - #ifdef CONFIG_SMP /* Local cross-calls. */ static void smp_flush_page_for_dma(unsigned long page) { - xc1((smpfunc_t) BTFIXUP_CALL(local_flush_page_for_dma), page); - local_flush_page_for_dma(page); + xc1((smpfunc_t) local_ops->page_for_dma, page); + local_ops->page_for_dma(page); } +static void smp_flush_cache_all(void) +{ + xc0((smpfunc_t) local_ops->cache_all); + local_ops->cache_all(); +} + +static void smp_flush_tlb_all(void) +{ + xc0((smpfunc_t) local_ops->tlb_all); + local_ops->tlb_all(); +} + +static void smp_flush_cache_mm(struct mm_struct *mm) +{ + if (mm->context != NO_CONTEXT) { + cpumask_t cpu_mask; + cpumask_copy(&cpu_mask, mm_cpumask(mm)); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); + if (!cpumask_empty(&cpu_mask)) + xc1((smpfunc_t) local_ops->cache_mm, (unsigned long) mm); + local_ops->cache_mm(mm); + } +} + +static void smp_flush_tlb_mm(struct mm_struct *mm) +{ + if (mm->context != NO_CONTEXT) { + cpumask_t cpu_mask; + cpumask_copy(&cpu_mask, mm_cpumask(mm)); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); + if (!cpumask_empty(&cpu_mask)) { + xc1((smpfunc_t) local_ops->tlb_mm, (unsigned long) mm); + if (atomic_read(&mm->mm_users) == 1 && current->active_mm == mm) + cpumask_copy(mm_cpumask(mm), + cpumask_of(smp_processor_id())); + } + local_ops->tlb_mm(mm); + } +} + +static void smp_flush_cache_range(struct vm_area_struct *vma, + unsigned long start, + unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + + if (mm->context != NO_CONTEXT) { + cpumask_t cpu_mask; + cpumask_copy(&cpu_mask, mm_cpumask(mm)); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); + if (!cpumask_empty(&cpu_mask)) + xc3((smpfunc_t) local_ops->cache_range, + (unsigned long) vma, start, end); + local_ops->cache_range(vma, start, end); + } +} + +static void smp_flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, + unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + + if (mm->context != NO_CONTEXT) { + cpumask_t cpu_mask; + cpumask_copy(&cpu_mask, mm_cpumask(mm)); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); + if (!cpumask_empty(&cpu_mask)) + xc3((smpfunc_t) local_ops->tlb_range, + (unsigned long) vma, start, end); + local_ops->tlb_range(vma, start, end); + } +} + +static void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page) +{ + struct mm_struct *mm = vma->vm_mm; + + if (mm->context != NO_CONTEXT) { + cpumask_t cpu_mask; + cpumask_copy(&cpu_mask, mm_cpumask(mm)); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); + if (!cpumask_empty(&cpu_mask)) + xc2((smpfunc_t) local_ops->cache_page, + (unsigned long) vma, page); + local_ops->cache_page(vma, page); + } +} + +static void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + struct mm_struct *mm = vma->vm_mm; + + if (mm->context != NO_CONTEXT) { + cpumask_t cpu_mask; + cpumask_copy(&cpu_mask, mm_cpumask(mm)); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); + if (!cpumask_empty(&cpu_mask)) + xc2((smpfunc_t) local_ops->tlb_page, + (unsigned long) vma, page); + local_ops->tlb_page(vma, page); + } +} + +static void smp_flush_page_to_ram(unsigned long page) +{ + /* Current theory is that those who call this are the one's + * who have just dirtied their cache with the pages contents + * in kernel space, therefore we only run this on local cpu. + * + * XXX This experiment failed, research further... -DaveM + */ +#if 1 + xc1((smpfunc_t) local_ops->page_to_ram, page); +#endif + local_ops->page_to_ram(page); +} + +static void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) +{ + cpumask_t cpu_mask; + cpumask_copy(&cpu_mask, mm_cpumask(mm)); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); + if (!cpumask_empty(&cpu_mask)) + xc2((smpfunc_t) local_ops->sig_insns, + (unsigned long) mm, insn_addr); + local_ops->sig_insns(mm, insn_addr); +} + +static struct sparc32_cachetlb_ops smp_cachetlb_ops = { + .cache_all = smp_flush_cache_all, + .cache_mm = smp_flush_cache_mm, + .cache_page = smp_flush_cache_page, + .cache_range = smp_flush_cache_range, + .tlb_all = smp_flush_tlb_all, + .tlb_mm = smp_flush_tlb_mm, + .tlb_page = smp_flush_tlb_page, + .tlb_range = smp_flush_tlb_range, + .page_to_ram = smp_flush_page_to_ram, + .sig_insns = smp_flush_sig_insns, + .page_for_dma = smp_flush_page_for_dma, +}; #endif -static pte_t srmmu_pgoff_to_pte(unsigned long pgoff) -{ - return __pte((pgoff << SRMMU_PTE_FILE_SHIFT) | SRMMU_FILE); -} - -static unsigned long srmmu_pte_to_pgoff(pte_t pte) -{ - return pte_val(pte) >> SRMMU_PTE_FILE_SHIFT; -} - -static pgprot_t srmmu_pgprot_noncached(pgprot_t prot) -{ - prot &= ~__pgprot(SRMMU_CACHE); - - return prot; -} - /* Load up routines and constants for sun4m and sun4d mmu */ -void __init ld_mmu_srmmu(void) +void __init load_mmu(void) { extern void ld_mmu_iommu(void); extern void ld_mmu_iounit(void); - extern void ___xchg32_sun4md(void); - - BTFIXUPSET_SIMM13(pgdir_shift, SRMMU_PGDIR_SHIFT); - BTFIXUPSET_SETHI(pgdir_size, SRMMU_PGDIR_SIZE); - BTFIXUPSET_SETHI(pgdir_mask, SRMMU_PGDIR_MASK); - - BTFIXUPSET_SIMM13(ptrs_per_pmd, SRMMU_PTRS_PER_PMD); - BTFIXUPSET_SIMM13(ptrs_per_pgd, SRMMU_PTRS_PER_PGD); - - BTFIXUPSET_INT(page_none, pgprot_val(SRMMU_PAGE_NONE)); - PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED); - BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY)); - BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY)); - BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL)); - page_kernel = pgprot_val(SRMMU_PAGE_KERNEL); /* Functions */ - BTFIXUPSET_CALL(pgprot_noncached, srmmu_pgprot_noncached, BTFIXUPCALL_NORM); -#ifndef CONFIG_SMP - BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4md, BTFIXUPCALL_SWAPG1G2); -#endif - BTFIXUPSET_CALL(do_check_pgt_cache, srmmu_check_pgt_cache, BTFIXUPCALL_NOP); - - BTFIXUPSET_CALL(set_pte, srmmu_set_pte, BTFIXUPCALL_SWAPO0O1); - BTFIXUPSET_CALL(switch_mm, srmmu_switch_mm, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(pte_pfn, srmmu_pte_pfn, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_page_vaddr, srmmu_pgd_page, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(pte_present, srmmu_pte_present, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_SWAPO0G0); - - BTFIXUPSET_CALL(pmd_bad, srmmu_pmd_bad, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_present, srmmu_pmd_present, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_SWAPO0G0); - - BTFIXUPSET_CALL(pgd_none, srmmu_pgd_none, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_bad, srmmu_pgd_bad, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_present, srmmu_pgd_present, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_SWAPO0G0); - - BTFIXUPSET_CALL(mk_pte, srmmu_mk_pte, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mk_pte_phys, srmmu_mk_pte_phys, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mk_pte_io, srmmu_mk_pte_io, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_set, srmmu_pgd_set, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_set, srmmu_pmd_set, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_populate, srmmu_pmd_populate, BTFIXUPCALL_NORM); - - BTFIXUPSET_INT(pte_modify_mask, SRMMU_CHG_MASK); - BTFIXUPSET_CALL(pmd_offset, srmmu_pmd_offset, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_offset_kernel, srmmu_pte_offset, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(free_pte_fast, srmmu_free_pte_fast, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_free, srmmu_pte_free, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_alloc_one_kernel, srmmu_pte_alloc_one_kernel, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_alloc_one, srmmu_pte_alloc_one, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(free_pmd_fast, srmmu_pmd_free, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_alloc_one, srmmu_pmd_alloc_one, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(free_pgd_fast, srmmu_free_pgd_fast, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(get_pgd_fast, srmmu_get_pgd_fast, BTFIXUPCALL_NORM); - - BTFIXUPSET_HALF(pte_writei, SRMMU_WRITE); - BTFIXUPSET_HALF(pte_dirtyi, SRMMU_DIRTY); - BTFIXUPSET_HALF(pte_youngi, SRMMU_REF); - BTFIXUPSET_HALF(pte_filei, SRMMU_FILE); - BTFIXUPSET_HALF(pte_wrprotecti, SRMMU_WRITE); - BTFIXUPSET_HALF(pte_mkcleani, SRMMU_DIRTY); - BTFIXUPSET_HALF(pte_mkoldi, SRMMU_REF); - BTFIXUPSET_CALL(pte_mkwrite, srmmu_pte_mkwrite, BTFIXUPCALL_ORINT(SRMMU_WRITE)); - BTFIXUPSET_CALL(pte_mkdirty, srmmu_pte_mkdirty, BTFIXUPCALL_ORINT(SRMMU_DIRTY)); - BTFIXUPSET_CALL(pte_mkyoung, srmmu_pte_mkyoung, BTFIXUPCALL_ORINT(SRMMU_REF)); - BTFIXUPSET_CALL(update_mmu_cache, srmmu_update_mmu_cache, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(destroy_context, srmmu_destroy_context, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(sparc_mapiorange, srmmu_mapiorange, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(sparc_unmapiorange, srmmu_unmapiorange, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(__swp_type, srmmu_swp_type, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(__swp_offset, srmmu_swp_offset, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(__swp_entry, srmmu_swp_entry, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(mmu_info, srmmu_mmu_info, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(alloc_thread_info_node, srmmu_alloc_thread_info_node, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(free_thread_info, srmmu_free_thread_info, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(pte_to_pgoff, srmmu_pte_to_pgoff, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgoff_to_pte, srmmu_pgoff_to_pte, BTFIXUPCALL_NORM); - get_srmmu_type(); - patch_window_trap_handlers(); #ifdef CONFIG_SMP /* El switcheroo... */ + local_ops = sparc32_cachetlb_ops; - BTFIXUPCOPY_CALL(local_flush_cache_all, flush_cache_all); - BTFIXUPCOPY_CALL(local_flush_cache_mm, flush_cache_mm); - BTFIXUPCOPY_CALL(local_flush_cache_range, flush_cache_range); - BTFIXUPCOPY_CALL(local_flush_cache_page, flush_cache_page); - BTFIXUPCOPY_CALL(local_flush_tlb_all, flush_tlb_all); - BTFIXUPCOPY_CALL(local_flush_tlb_mm, flush_tlb_mm); - BTFIXUPCOPY_CALL(local_flush_tlb_range, flush_tlb_range); - BTFIXUPCOPY_CALL(local_flush_tlb_page, flush_tlb_page); - BTFIXUPCOPY_CALL(local_flush_page_to_ram, __flush_page_to_ram); - BTFIXUPCOPY_CALL(local_flush_sig_insns, flush_sig_insns); - BTFIXUPCOPY_CALL(local_flush_page_for_dma, flush_page_for_dma); - - BTFIXUPSET_CALL(flush_cache_all, smp_flush_cache_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_mm, smp_flush_cache_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_range, smp_flush_cache_range, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_page, smp_flush_cache_page, BTFIXUPCALL_NORM); - if (sparc_cpu_model != sun4d && - sparc_cpu_model != sparc_leon) { - BTFIXUPSET_CALL(flush_tlb_all, smp_flush_tlb_all, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_mm, smp_flush_tlb_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_range, smp_flush_tlb_range, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_page, smp_flush_tlb_page, BTFIXUPCALL_NORM); + if (sparc_cpu_model == sun4d || sparc_cpu_model == sparc_leon) { + smp_cachetlb_ops.tlb_all = local_ops->tlb_all; + smp_cachetlb_ops.tlb_mm = local_ops->tlb_mm; + smp_cachetlb_ops.tlb_range = local_ops->tlb_range; + smp_cachetlb_ops.tlb_page = local_ops->tlb_page; } - BTFIXUPSET_CALL(__flush_page_to_ram, smp_flush_page_to_ram, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_sig_insns, smp_flush_sig_insns, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_page_for_dma, smp_flush_page_for_dma, BTFIXUPCALL_NORM); if (poke_srmmu == poke_viking) { /* Avoid unnecessary cross calls. */ - BTFIXUPCOPY_CALL(flush_cache_all, local_flush_cache_all); - BTFIXUPCOPY_CALL(flush_cache_mm, local_flush_cache_mm); - BTFIXUPCOPY_CALL(flush_cache_range, local_flush_cache_range); - BTFIXUPCOPY_CALL(flush_cache_page, local_flush_cache_page); - BTFIXUPCOPY_CALL(__flush_page_to_ram, local_flush_page_to_ram); - BTFIXUPCOPY_CALL(flush_sig_insns, local_flush_sig_insns); - BTFIXUPCOPY_CALL(flush_page_for_dma, local_flush_page_for_dma); + smp_cachetlb_ops.cache_all = local_ops->cache_all; + smp_cachetlb_ops.cache_mm = local_ops->cache_mm; + smp_cachetlb_ops.cache_range = local_ops->cache_range; + smp_cachetlb_ops.cache_page = local_ops->cache_page; + + smp_cachetlb_ops.page_to_ram = local_ops->page_to_ram; + smp_cachetlb_ops.sig_insns = local_ops->sig_insns; + smp_cachetlb_ops.page_for_dma = local_ops->page_for_dma; } + + /* It really is const after this point. */ + sparc32_cachetlb_ops = (const struct sparc32_cachetlb_ops *) + &smp_cachetlb_ops; #endif if (sparc_cpu_model == sun4d)
diff --git a/arch/sparc/mm/srmmu.h b/arch/sparc/mm/srmmu.h new file mode 100644 index 0000000..5703274 --- /dev/null +++ b/arch/sparc/mm/srmmu.h
@@ -0,0 +1,4 @@ +/* srmmu.c */ +extern char *srmmu_name; + +extern void (*poke_srmmu)(void);
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c deleted file mode 100644 index 1cf4f19..0000000 --- a/arch/sparc/mm/sun4c.c +++ /dev/null
@@ -1,2166 +0,0 @@ -/* sun4c.c: Doing in software what should be done in hardware. - * - * Copyright (C) 1996 David S. Miller (davem@davemloft.net) - * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) - * Copyright (C) 1996 Andrew Tridgell (Andrew.Tridgell@anu.edu.au) - * Copyright (C) 1997-2000 Anton Blanchard (anton@samba.org) - * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - */ - -#define NR_TASK_BUCKETS 512 - -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/bootmem.h> -#include <linux/highmem.h> -#include <linux/fs.h> -#include <linux/seq_file.h> -#include <linux/scatterlist.h> -#include <linux/bitmap.h> - -#include <asm/sections.h> -#include <asm/page.h> -#include <asm/pgalloc.h> -#include <asm/pgtable.h> -#include <asm/vaddrs.h> -#include <asm/idprom.h> -#include <asm/machines.h> -#include <asm/memreg.h> -#include <asm/processor.h> -#include <asm/auxio.h> -#include <asm/io.h> -#include <asm/oplib.h> -#include <asm/openprom.h> -#include <asm/mmu_context.h> -#include <asm/highmem.h> -#include <asm/btfixup.h> -#include <asm/cacheflush.h> -#include <asm/tlbflush.h> - -/* Because of our dynamic kernel TLB miss strategy, and how - * our DVMA mapping allocation works, you _MUST_: - * - * 1) Disable interrupts _and_ not touch any dynamic kernel - * memory while messing with kernel MMU state. By - * dynamic memory I mean any object which is not in - * the kernel image itself or a thread_union (both of - * which are locked into the MMU). - * 2) Disable interrupts while messing with user MMU state. - */ - -extern int num_segmaps, num_contexts; - -extern unsigned long page_kernel; - -/* That's it, we prom_halt() on sun4c if the cache size is something other than 65536. - * So let's save some cycles and just use that everywhere except for that bootup - * sanity check. - */ -#define SUN4C_VAC_SIZE 65536 - -#define SUN4C_KERNEL_BUCKETS 32 - -/* Flushing the cache. */ -struct sun4c_vac_props sun4c_vacinfo; -unsigned long sun4c_kernel_faults; - -/* Invalidate every sun4c cache line tag. */ -static void __init sun4c_flush_all(void) -{ - unsigned long begin, end; - - if (sun4c_vacinfo.on) - panic("SUN4C: AIEEE, trying to invalidate vac while it is on."); - - /* Clear 'valid' bit in all cache line tags */ - begin = AC_CACHETAGS; - end = (AC_CACHETAGS + SUN4C_VAC_SIZE); - while (begin < end) { - __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : - "r" (begin), "i" (ASI_CONTROL)); - begin += sun4c_vacinfo.linesize; - } -} - -static void sun4c_flush_context_hw(void) -{ - unsigned long end = SUN4C_VAC_SIZE; - - __asm__ __volatile__( - "1: addcc %0, -4096, %0\n\t" - " bne 1b\n\t" - " sta %%g0, [%0] %2" - : "=&r" (end) - : "0" (end), "i" (ASI_HWFLUSHCONTEXT) - : "cc"); -} - -/* Must be called minimally with IRQs disabled. */ -static void sun4c_flush_segment_hw(unsigned long addr) -{ - if (sun4c_get_segmap(addr) != invalid_segment) { - unsigned long vac_size = SUN4C_VAC_SIZE; - - __asm__ __volatile__( - "1: addcc %0, -4096, %0\n\t" - " bne 1b\n\t" - " sta %%g0, [%2 + %0] %3" - : "=&r" (vac_size) - : "0" (vac_size), "r" (addr), "i" (ASI_HWFLUSHSEG) - : "cc"); - } -} - -/* File local boot time fixups. */ -BTFIXUPDEF_CALL(void, sun4c_flush_page, unsigned long) -BTFIXUPDEF_CALL(void, sun4c_flush_segment, unsigned long) -BTFIXUPDEF_CALL(void, sun4c_flush_context, void) - -#define sun4c_flush_page(addr) BTFIXUP_CALL(sun4c_flush_page)(addr) -#define sun4c_flush_segment(addr) BTFIXUP_CALL(sun4c_flush_segment)(addr) -#define sun4c_flush_context() BTFIXUP_CALL(sun4c_flush_context)() - -/* Must be called minimally with interrupts disabled. */ -static void sun4c_flush_page_hw(unsigned long addr) -{ - addr &= PAGE_MASK; - if ((int)sun4c_get_pte(addr) < 0) - __asm__ __volatile__("sta %%g0, [%0] %1" - : : "r" (addr), "i" (ASI_HWFLUSHPAGE)); -} - -/* Don't inline the software version as it eats too many cache lines if expanded. */ -static void sun4c_flush_context_sw(void) -{ - unsigned long nbytes = SUN4C_VAC_SIZE; - unsigned long lsize = sun4c_vacinfo.linesize; - - __asm__ __volatile__( - "add %2, %2, %%g1\n\t" - "add %2, %%g1, %%g2\n\t" - "add %2, %%g2, %%g3\n\t" - "add %2, %%g3, %%g4\n\t" - "add %2, %%g4, %%g5\n\t" - "add %2, %%g5, %%o4\n\t" - "add %2, %%o4, %%o5\n" - "1:\n\t" - "subcc %0, %%o5, %0\n\t" - "sta %%g0, [%0] %3\n\t" - "sta %%g0, [%0 + %2] %3\n\t" - "sta %%g0, [%0 + %%g1] %3\n\t" - "sta %%g0, [%0 + %%g2] %3\n\t" - "sta %%g0, [%0 + %%g3] %3\n\t" - "sta %%g0, [%0 + %%g4] %3\n\t" - "sta %%g0, [%0 + %%g5] %3\n\t" - "bg 1b\n\t" - " sta %%g0, [%1 + %%o4] %3\n" - : "=&r" (nbytes) - : "0" (nbytes), "r" (lsize), "i" (ASI_FLUSHCTX) - : "g1", "g2", "g3", "g4", "g5", "o4", "o5", "cc"); -} - -/* Don't inline the software version as it eats too many cache lines if expanded. */ -static void sun4c_flush_segment_sw(unsigned long addr) -{ - if (sun4c_get_segmap(addr) != invalid_segment) { - unsigned long nbytes = SUN4C_VAC_SIZE; - unsigned long lsize = sun4c_vacinfo.linesize; - - __asm__ __volatile__( - "add %2, %2, %%g1\n\t" - "add %2, %%g1, %%g2\n\t" - "add %2, %%g2, %%g3\n\t" - "add %2, %%g3, %%g4\n\t" - "add %2, %%g4, %%g5\n\t" - "add %2, %%g5, %%o4\n\t" - "add %2, %%o4, %%o5\n" - "1:\n\t" - "subcc %1, %%o5, %1\n\t" - "sta %%g0, [%0] %6\n\t" - "sta %%g0, [%0 + %2] %6\n\t" - "sta %%g0, [%0 + %%g1] %6\n\t" - "sta %%g0, [%0 + %%g2] %6\n\t" - "sta %%g0, [%0 + %%g3] %6\n\t" - "sta %%g0, [%0 + %%g4] %6\n\t" - "sta %%g0, [%0 + %%g5] %6\n\t" - "sta %%g0, [%0 + %%o4] %6\n\t" - "bg 1b\n\t" - " add %0, %%o5, %0\n" - : "=&r" (addr), "=&r" (nbytes), "=&r" (lsize) - : "0" (addr), "1" (nbytes), "2" (lsize), - "i" (ASI_FLUSHSEG) - : "g1", "g2", "g3", "g4", "g5", "o4", "o5", "cc"); - } -} - -/* Don't inline the software version as it eats too many cache lines if expanded. */ -static void sun4c_flush_page_sw(unsigned long addr) -{ - addr &= PAGE_MASK; - if ((sun4c_get_pte(addr) & (_SUN4C_PAGE_NOCACHE | _SUN4C_PAGE_VALID)) == - _SUN4C_PAGE_VALID) { - unsigned long left = PAGE_SIZE; - unsigned long lsize = sun4c_vacinfo.linesize; - - __asm__ __volatile__( - "add %2, %2, %%g1\n\t" - "add %2, %%g1, %%g2\n\t" - "add %2, %%g2, %%g3\n\t" - "add %2, %%g3, %%g4\n\t" - "add %2, %%g4, %%g5\n\t" - "add %2, %%g5, %%o4\n\t" - "add %2, %%o4, %%o5\n" - "1:\n\t" - "subcc %1, %%o5, %1\n\t" - "sta %%g0, [%0] %6\n\t" - "sta %%g0, [%0 + %2] %6\n\t" - "sta %%g0, [%0 + %%g1] %6\n\t" - "sta %%g0, [%0 + %%g2] %6\n\t" - "sta %%g0, [%0 + %%g3] %6\n\t" - "sta %%g0, [%0 + %%g4] %6\n\t" - "sta %%g0, [%0 + %%g5] %6\n\t" - "sta %%g0, [%0 + %%o4] %6\n\t" - "bg 1b\n\t" - " add %0, %%o5, %0\n" - : "=&r" (addr), "=&r" (left), "=&r" (lsize) - : "0" (addr), "1" (left), "2" (lsize), - "i" (ASI_FLUSHPG) - : "g1", "g2", "g3", "g4", "g5", "o4", "o5", "cc"); - } -} - -/* The sun4c's do have an on chip store buffer. And the way you - * clear them out isn't so obvious. The only way I can think of - * to accomplish this is to read the current context register, - * store the same value there, then read an external hardware - * register. - */ -void sun4c_complete_all_stores(void) -{ - volatile int _unused; - - _unused = sun4c_get_context(); - sun4c_set_context(_unused); - _unused = get_auxio(); -} - -/* Bootup utility functions. */ -static inline void sun4c_init_clean_segmap(unsigned char pseg) -{ - unsigned long vaddr; - - sun4c_put_segmap(0, pseg); - for (vaddr = 0; vaddr < SUN4C_REAL_PGDIR_SIZE; vaddr += PAGE_SIZE) - sun4c_put_pte(vaddr, 0); - sun4c_put_segmap(0, invalid_segment); -} - -static inline void sun4c_init_clean_mmu(unsigned long kernel_end) -{ - unsigned long vaddr; - unsigned char savectx, ctx; - - savectx = sun4c_get_context(); - for (ctx = 0; ctx < num_contexts; ctx++) { - sun4c_set_context(ctx); - for (vaddr = 0; vaddr < 0x20000000; vaddr += SUN4C_REAL_PGDIR_SIZE) - sun4c_put_segmap(vaddr, invalid_segment); - for (vaddr = 0xe0000000; vaddr < KERNBASE; vaddr += SUN4C_REAL_PGDIR_SIZE) - sun4c_put_segmap(vaddr, invalid_segment); - for (vaddr = kernel_end; vaddr < KADB_DEBUGGER_BEGVM; vaddr += SUN4C_REAL_PGDIR_SIZE) - sun4c_put_segmap(vaddr, invalid_segment); - for (vaddr = LINUX_OPPROM_ENDVM; vaddr; vaddr += SUN4C_REAL_PGDIR_SIZE) - sun4c_put_segmap(vaddr, invalid_segment); - } - sun4c_set_context(savectx); -} - -void __init sun4c_probe_vac(void) -{ - sun4c_disable_vac(); - - if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || - (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) { - /* PROM on SS1 lacks this info, to be super safe we - * hard code it here since this arch is cast in stone. - */ - sun4c_vacinfo.num_bytes = 65536; - sun4c_vacinfo.linesize = 16; - } else { - sun4c_vacinfo.num_bytes = - prom_getintdefault(prom_root_node, "vac-size", 65536); - sun4c_vacinfo.linesize = - prom_getintdefault(prom_root_node, "vac-linesize", 16); - } - sun4c_vacinfo.do_hwflushes = - prom_getintdefault(prom_root_node, "vac-hwflush", 0); - - if (sun4c_vacinfo.do_hwflushes == 0) - sun4c_vacinfo.do_hwflushes = - prom_getintdefault(prom_root_node, "vac_hwflush", 0); - - if (sun4c_vacinfo.num_bytes != 65536) { - prom_printf("WEIRD Sun4C VAC cache size, " - "tell sparclinux@vger.kernel.org"); - prom_halt(); - } - - switch (sun4c_vacinfo.linesize) { - case 16: - sun4c_vacinfo.log2lsize = 4; - break; - case 32: - sun4c_vacinfo.log2lsize = 5; - break; - default: - prom_printf("probe_vac: Didn't expect vac-linesize of %d, halting\n", - sun4c_vacinfo.linesize); - prom_halt(); - } - - sun4c_flush_all(); - sun4c_enable_vac(); -} - -/* Patch instructions for the low level kernel fault handler. */ -extern unsigned long invalid_segment_patch1, invalid_segment_patch1_ff; -extern unsigned long invalid_segment_patch2, invalid_segment_patch2_ff; -extern unsigned long invalid_segment_patch1_1ff, invalid_segment_patch2_1ff; -extern unsigned long num_context_patch1, num_context_patch1_16; -extern unsigned long num_context_patch2_16; -extern unsigned long vac_linesize_patch, vac_linesize_patch_32; -extern unsigned long vac_hwflush_patch1, vac_hwflush_patch1_on; -extern unsigned long vac_hwflush_patch2, vac_hwflush_patch2_on; - -#define PATCH_INSN(src, dst) do { \ - daddr = &(dst); \ - iaddr = &(src); \ - *daddr = *iaddr; \ - } while (0) - -static void __init patch_kernel_fault_handler(void) -{ - unsigned long *iaddr, *daddr; - - switch (num_segmaps) { - case 128: - /* Default, nothing to do. */ - break; - case 256: - PATCH_INSN(invalid_segment_patch1_ff, - invalid_segment_patch1); - PATCH_INSN(invalid_segment_patch2_ff, - invalid_segment_patch2); - break; - case 512: - PATCH_INSN(invalid_segment_patch1_1ff, - invalid_segment_patch1); - PATCH_INSN(invalid_segment_patch2_1ff, - invalid_segment_patch2); - break; - default: - prom_printf("Unhandled number of segmaps: %d\n", - num_segmaps); - prom_halt(); - } - switch (num_contexts) { - case 8: - /* Default, nothing to do. */ - break; - case 16: - PATCH_INSN(num_context_patch1_16, - num_context_patch1); - break; - default: - prom_printf("Unhandled number of contexts: %d\n", - num_contexts); - prom_halt(); - } - - if (sun4c_vacinfo.do_hwflushes != 0) { - PATCH_INSN(vac_hwflush_patch1_on, vac_hwflush_patch1); - PATCH_INSN(vac_hwflush_patch2_on, vac_hwflush_patch2); - } else { - switch (sun4c_vacinfo.linesize) { - case 16: - /* Default, nothing to do. */ - break; - case 32: - PATCH_INSN(vac_linesize_patch_32, vac_linesize_patch); - break; - default: - prom_printf("Impossible VAC linesize %d, halting...\n", - sun4c_vacinfo.linesize); - prom_halt(); - } - } -} - -static void __init sun4c_probe_mmu(void) -{ - if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || - (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) { - /* Hardcode these just to be safe, PROM on SS1 does - * not have this info available in the root node. - */ - num_segmaps = 128; - num_contexts = 8; - } else { - num_segmaps = - prom_getintdefault(prom_root_node, "mmu-npmg", 128); - num_contexts = - prom_getintdefault(prom_root_node, "mmu-nctx", 0x8); - } - patch_kernel_fault_handler(); -} - -volatile unsigned long __iomem *sun4c_memerr_reg = NULL; - -void __init sun4c_probe_memerr_reg(void) -{ - phandle node; - struct linux_prom_registers regs[1]; - - node = prom_getchild(prom_root_node); - node = prom_searchsiblings(prom_root_node, "memory-error"); - if (!node) - return; - if (prom_getproperty(node, "reg", (char *)regs, sizeof(regs)) <= 0) - return; - /* hmm I think regs[0].which_io is zero here anyways */ - sun4c_memerr_reg = ioremap(regs[0].phys_addr, regs[0].reg_size); -} - -static inline void sun4c_init_ss2_cache_bug(void) -{ - if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS2)) || - (idprom->id_machtype == (SM_SUN4C | SM_4C_IPX)) || - (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC))) { - /* Whee.. */ - printk("SS2 cache bug detected, uncaching trap table page\n"); - sun4c_flush_page((unsigned int) &_start); - sun4c_put_pte(((unsigned long) &_start), - (sun4c_get_pte((unsigned long) &_start) | _SUN4C_PAGE_NOCACHE)); - } -} - -/* Addr is always aligned on a page boundary for us already. */ -static int sun4c_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, - unsigned long addr, int len) -{ - unsigned long page, end; - - *pba = addr; - - end = PAGE_ALIGN((addr + len)); - while (addr < end) { - page = va; - sun4c_flush_page(page); - page -= PAGE_OFFSET; - page >>= PAGE_SHIFT; - page |= (_SUN4C_PAGE_VALID | _SUN4C_PAGE_DIRTY | - _SUN4C_PAGE_NOCACHE | _SUN4C_PAGE_PRIV); - sun4c_put_pte(addr, page); - addr += PAGE_SIZE; - va += PAGE_SIZE; - } - - return 0; -} - -static void sun4c_unmap_dma_area(struct device *dev, unsigned long busa, int len) -{ - /* Fortunately for us, bus_addr == uncached_virt in sun4c. */ - /* XXX Implement this */ -} - -/* TLB management. */ - -/* Don't change this struct without changing entry.S. This is used - * in the in-window kernel fault handler, and you don't want to mess - * with that. (See sun4c_fault in entry.S). - */ -struct sun4c_mmu_entry { - struct sun4c_mmu_entry *next; - struct sun4c_mmu_entry *prev; - unsigned long vaddr; - unsigned char pseg; - unsigned char locked; - - /* For user mappings only, and completely hidden from kernel - * TLB miss code. - */ - unsigned char ctx; - struct sun4c_mmu_entry *lru_next; - struct sun4c_mmu_entry *lru_prev; -}; - -static struct sun4c_mmu_entry mmu_entry_pool[SUN4C_MAX_SEGMAPS]; - -static void __init sun4c_init_mmu_entry_pool(void) -{ - int i; - - for (i=0; i < SUN4C_MAX_SEGMAPS; i++) { - mmu_entry_pool[i].pseg = i; - mmu_entry_pool[i].next = NULL; - mmu_entry_pool[i].prev = NULL; - mmu_entry_pool[i].vaddr = 0; - mmu_entry_pool[i].locked = 0; - mmu_entry_pool[i].ctx = 0; - mmu_entry_pool[i].lru_next = NULL; - mmu_entry_pool[i].lru_prev = NULL; - } - mmu_entry_pool[invalid_segment].locked = 1; -} - -static inline void fix_permissions(unsigned long vaddr, unsigned long bits_on, - unsigned long bits_off) -{ - unsigned long start, end; - - end = vaddr + SUN4C_REAL_PGDIR_SIZE; - for (start = vaddr; start < end; start += PAGE_SIZE) - if (sun4c_get_pte(start) & _SUN4C_PAGE_VALID) - sun4c_put_pte(start, (sun4c_get_pte(start) | bits_on) & - ~bits_off); -} - -static inline void sun4c_init_map_kernelprom(unsigned long kernel_end) -{ - unsigned long vaddr; - unsigned char pseg, ctx; - - for (vaddr = KADB_DEBUGGER_BEGVM; - vaddr < LINUX_OPPROM_ENDVM; - vaddr += SUN4C_REAL_PGDIR_SIZE) { - pseg = sun4c_get_segmap(vaddr); - if (pseg != invalid_segment) { - mmu_entry_pool[pseg].locked = 1; - for (ctx = 0; ctx < num_contexts; ctx++) - prom_putsegment(ctx, vaddr, pseg); - fix_permissions(vaddr, _SUN4C_PAGE_PRIV, 0); - } - } - - for (vaddr = KERNBASE; vaddr < kernel_end; vaddr += SUN4C_REAL_PGDIR_SIZE) { - pseg = sun4c_get_segmap(vaddr); - mmu_entry_pool[pseg].locked = 1; - for (ctx = 0; ctx < num_contexts; ctx++) - prom_putsegment(ctx, vaddr, pseg); - fix_permissions(vaddr, _SUN4C_PAGE_PRIV, _SUN4C_PAGE_NOCACHE); - } -} - -static void __init sun4c_init_lock_area(unsigned long start, unsigned long end) -{ - int i, ctx; - - while (start < end) { - for (i = 0; i < invalid_segment; i++) - if (!mmu_entry_pool[i].locked) - break; - mmu_entry_pool[i].locked = 1; - sun4c_init_clean_segmap(i); - for (ctx = 0; ctx < num_contexts; ctx++) - prom_putsegment(ctx, start, mmu_entry_pool[i].pseg); - start += SUN4C_REAL_PGDIR_SIZE; - } -} - -/* Don't change this struct without changing entry.S. This is used - * in the in-window kernel fault handler, and you don't want to mess - * with that. (See sun4c_fault in entry.S). - */ -struct sun4c_mmu_ring { - struct sun4c_mmu_entry ringhd; - int num_entries; -}; - -static struct sun4c_mmu_ring sun4c_context_ring[SUN4C_MAX_CONTEXTS]; /* used user entries */ -static struct sun4c_mmu_ring sun4c_ufree_ring; /* free user entries */ -static struct sun4c_mmu_ring sun4c_ulru_ring; /* LRU user entries */ -struct sun4c_mmu_ring sun4c_kernel_ring; /* used kernel entries */ -struct sun4c_mmu_ring sun4c_kfree_ring; /* free kernel entries */ - -static inline void sun4c_init_rings(void) -{ - int i; - - for (i = 0; i < SUN4C_MAX_CONTEXTS; i++) { - sun4c_context_ring[i].ringhd.next = - sun4c_context_ring[i].ringhd.prev = - &sun4c_context_ring[i].ringhd; - sun4c_context_ring[i].num_entries = 0; - } - sun4c_ufree_ring.ringhd.next = sun4c_ufree_ring.ringhd.prev = - &sun4c_ufree_ring.ringhd; - sun4c_ufree_ring.num_entries = 0; - sun4c_ulru_ring.ringhd.lru_next = sun4c_ulru_ring.ringhd.lru_prev = - &sun4c_ulru_ring.ringhd; - sun4c_ulru_ring.num_entries = 0; - sun4c_kernel_ring.ringhd.next = sun4c_kernel_ring.ringhd.prev = - &sun4c_kernel_ring.ringhd; - sun4c_kernel_ring.num_entries = 0; - sun4c_kfree_ring.ringhd.next = sun4c_kfree_ring.ringhd.prev = - &sun4c_kfree_ring.ringhd; - sun4c_kfree_ring.num_entries = 0; -} - -static void add_ring(struct sun4c_mmu_ring *ring, - struct sun4c_mmu_entry *entry) -{ - struct sun4c_mmu_entry *head = &ring->ringhd; - - entry->prev = head; - (entry->next = head->next)->prev = entry; - head->next = entry; - ring->num_entries++; -} - -static inline void add_lru(struct sun4c_mmu_entry *entry) -{ - struct sun4c_mmu_ring *ring = &sun4c_ulru_ring; - struct sun4c_mmu_entry *head = &ring->ringhd; - - entry->lru_next = head; - (entry->lru_prev = head->lru_prev)->lru_next = entry; - head->lru_prev = entry; -} - -static void add_ring_ordered(struct sun4c_mmu_ring *ring, - struct sun4c_mmu_entry *entry) -{ - struct sun4c_mmu_entry *head = &ring->ringhd; - unsigned long addr = entry->vaddr; - - while ((head->next != &ring->ringhd) && (head->next->vaddr < addr)) - head = head->next; - - entry->prev = head; - (entry->next = head->next)->prev = entry; - head->next = entry; - ring->num_entries++; - - add_lru(entry); -} - -static inline void remove_ring(struct sun4c_mmu_ring *ring, - struct sun4c_mmu_entry *entry) -{ - struct sun4c_mmu_entry *next = entry->next; - - (next->prev = entry->prev)->next = next; - ring->num_entries--; -} - -static void remove_lru(struct sun4c_mmu_entry *entry) -{ - struct sun4c_mmu_entry *next = entry->lru_next; - - (next->lru_prev = entry->lru_prev)->lru_next = next; -} - -static void free_user_entry(int ctx, struct sun4c_mmu_entry *entry) -{ - remove_ring(sun4c_context_ring+ctx, entry); - remove_lru(entry); - add_ring(&sun4c_ufree_ring, entry); -} - -static void free_kernel_entry(struct sun4c_mmu_entry *entry, - struct sun4c_mmu_ring *ring) -{ - remove_ring(ring, entry); - add_ring(&sun4c_kfree_ring, entry); -} - -static void __init sun4c_init_fill_kernel_ring(int howmany) -{ - int i; - - while (howmany) { - for (i = 0; i < invalid_segment; i++) - if (!mmu_entry_pool[i].locked) - break; - mmu_entry_pool[i].locked = 1; - sun4c_init_clean_segmap(i); - add_ring(&sun4c_kfree_ring, &mmu_entry_pool[i]); - howmany--; - } -} - -static void __init sun4c_init_fill_user_ring(void) -{ - int i; - - for (i = 0; i < invalid_segment; i++) { - if (mmu_entry_pool[i].locked) - continue; - sun4c_init_clean_segmap(i); - add_ring(&sun4c_ufree_ring, &mmu_entry_pool[i]); - } -} - -static void sun4c_kernel_unmap(struct sun4c_mmu_entry *kentry) -{ - int savectx, ctx; - - savectx = sun4c_get_context(); - for (ctx = 0; ctx < num_contexts; ctx++) { - sun4c_set_context(ctx); - sun4c_put_segmap(kentry->vaddr, invalid_segment); - } - sun4c_set_context(savectx); -} - -static void sun4c_kernel_map(struct sun4c_mmu_entry *kentry) -{ - int savectx, ctx; - - savectx = sun4c_get_context(); - for (ctx = 0; ctx < num_contexts; ctx++) { - sun4c_set_context(ctx); - sun4c_put_segmap(kentry->vaddr, kentry->pseg); - } - sun4c_set_context(savectx); -} - -#define sun4c_user_unmap(__entry) \ - sun4c_put_segmap((__entry)->vaddr, invalid_segment) - -static void sun4c_demap_context(struct sun4c_mmu_ring *crp, unsigned char ctx) -{ - struct sun4c_mmu_entry *head = &crp->ringhd; - unsigned long flags; - - local_irq_save(flags); - if (head->next != head) { - struct sun4c_mmu_entry *entry = head->next; - int savectx = sun4c_get_context(); - - flush_user_windows(); - sun4c_set_context(ctx); - sun4c_flush_context(); - do { - struct sun4c_mmu_entry *next = entry->next; - - sun4c_user_unmap(entry); - free_user_entry(ctx, entry); - - entry = next; - } while (entry != head); - sun4c_set_context(savectx); - } - local_irq_restore(flags); -} - -static int sun4c_user_taken_entries; /* This is how much we have. */ -static int max_user_taken_entries; /* This limits us and prevents deadlock. */ - -static struct sun4c_mmu_entry *sun4c_kernel_strategy(void) -{ - struct sun4c_mmu_entry *this_entry; - - /* If some are free, return first one. */ - if (sun4c_kfree_ring.num_entries) { - this_entry = sun4c_kfree_ring.ringhd.next; - return this_entry; - } - - /* Else free one up. */ - this_entry = sun4c_kernel_ring.ringhd.prev; - sun4c_flush_segment(this_entry->vaddr); - sun4c_kernel_unmap(this_entry); - free_kernel_entry(this_entry, &sun4c_kernel_ring); - this_entry = sun4c_kfree_ring.ringhd.next; - - return this_entry; -} - -/* Using this method to free up mmu entries eliminates a lot of - * potential races since we have a kernel that incurs tlb - * replacement faults. There may be performance penalties. - * - * NOTE: Must be called with interrupts disabled. - */ -static struct sun4c_mmu_entry *sun4c_user_strategy(void) -{ - struct sun4c_mmu_entry *entry; - unsigned char ctx; - int savectx; - - /* If some are free, return first one. */ - if (sun4c_ufree_ring.num_entries) { - entry = sun4c_ufree_ring.ringhd.next; - goto unlink_out; - } - - if (sun4c_user_taken_entries) { - entry = sun4c_kernel_strategy(); - sun4c_user_taken_entries--; - goto kunlink_out; - } - - /* Grab from the beginning of the LRU list. */ - entry = sun4c_ulru_ring.ringhd.lru_next; - ctx = entry->ctx; - - savectx = sun4c_get_context(); - flush_user_windows(); - sun4c_set_context(ctx); - sun4c_flush_segment(entry->vaddr); - sun4c_user_unmap(entry); - remove_ring(sun4c_context_ring + ctx, entry); - remove_lru(entry); - sun4c_set_context(savectx); - - return entry; - -unlink_out: - remove_ring(&sun4c_ufree_ring, entry); - return entry; -kunlink_out: - remove_ring(&sun4c_kfree_ring, entry); - return entry; -} - -/* NOTE: Must be called with interrupts disabled. */ -void sun4c_grow_kernel_ring(void) -{ - struct sun4c_mmu_entry *entry; - - /* Prevent deadlock condition. */ - if (sun4c_user_taken_entries >= max_user_taken_entries) - return; - - if (sun4c_ufree_ring.num_entries) { - entry = sun4c_ufree_ring.ringhd.next; - remove_ring(&sun4c_ufree_ring, entry); - add_ring(&sun4c_kfree_ring, entry); - sun4c_user_taken_entries++; - } -} - -/* 2 page buckets for task struct and kernel stack allocation. - * - * TASK_STACK_BEGIN - * bucket[0] - * bucket[1] - * [ ... ] - * bucket[NR_TASK_BUCKETS-1] - * TASK_STACK_BEGIN + (sizeof(struct task_bucket) * NR_TASK_BUCKETS) - * - * Each slot looks like: - * - * page 1 -- task struct + beginning of kernel stack - * page 2 -- rest of kernel stack - */ - -union task_union *sun4c_bucket[NR_TASK_BUCKETS]; - -static int sun4c_lowbucket_avail; - -#define BUCKET_EMPTY ((union task_union *) 0) -#define BUCKET_SHIFT (PAGE_SHIFT + 1) /* log2(sizeof(struct task_bucket)) */ -#define BUCKET_SIZE (1 << BUCKET_SHIFT) -#define BUCKET_NUM(addr) ((((addr) - SUN4C_LOCK_VADDR) >> BUCKET_SHIFT)) -#define BUCKET_ADDR(num) (((num) << BUCKET_SHIFT) + SUN4C_LOCK_VADDR) -#define BUCKET_PTE(page) \ - ((((page) - PAGE_OFFSET) >> PAGE_SHIFT) | pgprot_val(SUN4C_PAGE_KERNEL)) -#define BUCKET_PTE_PAGE(pte) \ - (PAGE_OFFSET + (((pte) & SUN4C_PFN_MASK) << PAGE_SHIFT)) - -static void get_locked_segment(unsigned long addr) -{ - struct sun4c_mmu_entry *stolen; - unsigned long flags; - - local_irq_save(flags); - addr &= SUN4C_REAL_PGDIR_MASK; - stolen = sun4c_user_strategy(); - max_user_taken_entries--; - stolen->vaddr = addr; - flush_user_windows(); - sun4c_kernel_map(stolen); - local_irq_restore(flags); -} - -static void free_locked_segment(unsigned long addr) -{ - struct sun4c_mmu_entry *entry; - unsigned long flags; - unsigned char pseg; - - local_irq_save(flags); - addr &= SUN4C_REAL_PGDIR_MASK; - pseg = sun4c_get_segmap(addr); - entry = &mmu_entry_pool[pseg]; - - flush_user_windows(); - sun4c_flush_segment(addr); - sun4c_kernel_unmap(entry); - add_ring(&sun4c_ufree_ring, entry); - max_user_taken_entries++; - local_irq_restore(flags); -} - -static inline void garbage_collect(int entry) -{ - int start, end; - - /* 32 buckets per segment... */ - entry &= ~31; - start = entry; - for (end = (start + 32); start < end; start++) - if (sun4c_bucket[start] != BUCKET_EMPTY) - return; - - /* Entire segment empty, release it. */ - free_locked_segment(BUCKET_ADDR(entry)); -} - -static struct thread_info *sun4c_alloc_thread_info_node(int node) -{ - unsigned long addr, pages; - int entry; - - pages = __get_free_pages(GFP_KERNEL, THREAD_INFO_ORDER); - if (!pages) - return NULL; - - for (entry = sun4c_lowbucket_avail; entry < NR_TASK_BUCKETS; entry++) - if (sun4c_bucket[entry] == BUCKET_EMPTY) - break; - if (entry == NR_TASK_BUCKETS) { - free_pages(pages, THREAD_INFO_ORDER); - return NULL; - } - if (entry >= sun4c_lowbucket_avail) - sun4c_lowbucket_avail = entry + 1; - - addr = BUCKET_ADDR(entry); - sun4c_bucket[entry] = (union task_union *) addr; - if(sun4c_get_segmap(addr) == invalid_segment) - get_locked_segment(addr); - - /* We are changing the virtual color of the page(s) - * so we must flush the cache to guarantee consistency. - */ - sun4c_flush_page(pages); - sun4c_flush_page(pages + PAGE_SIZE); - - sun4c_put_pte(addr, BUCKET_PTE(pages)); - sun4c_put_pte(addr + PAGE_SIZE, BUCKET_PTE(pages + PAGE_SIZE)); - -#ifdef CONFIG_DEBUG_STACK_USAGE - memset((void *)addr, 0, PAGE_SIZE << THREAD_INFO_ORDER); -#endif /* DEBUG_STACK_USAGE */ - - return (struct thread_info *) addr; -} - -static void sun4c_free_thread_info(struct thread_info *ti) -{ - unsigned long tiaddr = (unsigned long) ti; - unsigned long pages = BUCKET_PTE_PAGE(sun4c_get_pte(tiaddr)); - int entry = BUCKET_NUM(tiaddr); - - /* We are deleting a mapping, so the flush here is mandatory. */ - sun4c_flush_page(tiaddr); - sun4c_flush_page(tiaddr + PAGE_SIZE); - - sun4c_put_pte(tiaddr, 0); - sun4c_put_pte(tiaddr + PAGE_SIZE, 0); - - sun4c_bucket[entry] = BUCKET_EMPTY; - if (entry < sun4c_lowbucket_avail) - sun4c_lowbucket_avail = entry; - - free_pages(pages, THREAD_INFO_ORDER); - garbage_collect(entry); -} - -static void __init sun4c_init_buckets(void) -{ - int entry; - - if (sizeof(union thread_union) != (PAGE_SIZE << THREAD_INFO_ORDER)) { - extern void thread_info_size_is_bolixed_pete(void); - thread_info_size_is_bolixed_pete(); - } - - for (entry = 0; entry < NR_TASK_BUCKETS; entry++) - sun4c_bucket[entry] = BUCKET_EMPTY; - sun4c_lowbucket_avail = 0; -} - -static unsigned long sun4c_iobuffer_start; -static unsigned long sun4c_iobuffer_end; -static unsigned long sun4c_iobuffer_high; -static unsigned long *sun4c_iobuffer_map; -static int iobuffer_map_size; - -/* - * Alias our pages so they do not cause a trap. - * Also one page may be aliased into several I/O areas and we may - * finish these I/O separately. - */ -static char *sun4c_lockarea(char *vaddr, unsigned long size) -{ - unsigned long base, scan; - unsigned long npages; - unsigned long vpage; - unsigned long pte; - unsigned long apage; - unsigned long high; - unsigned long flags; - - npages = (((unsigned long)vaddr & ~PAGE_MASK) + - size + (PAGE_SIZE-1)) >> PAGE_SHIFT; - - local_irq_save(flags); - base = bitmap_find_next_zero_area(sun4c_iobuffer_map, iobuffer_map_size, - 0, npages, 0); - if (base >= iobuffer_map_size) - goto abend; - - high = ((base + npages) << PAGE_SHIFT) + sun4c_iobuffer_start; - high = SUN4C_REAL_PGDIR_ALIGN(high); - while (high > sun4c_iobuffer_high) { - get_locked_segment(sun4c_iobuffer_high); - sun4c_iobuffer_high += SUN4C_REAL_PGDIR_SIZE; - } - - vpage = ((unsigned long) vaddr) & PAGE_MASK; - for (scan = base; scan < base+npages; scan++) { - pte = ((vpage-PAGE_OFFSET) >> PAGE_SHIFT); - pte |= pgprot_val(SUN4C_PAGE_KERNEL); - pte |= _SUN4C_PAGE_NOCACHE; - set_bit(scan, sun4c_iobuffer_map); - apage = (scan << PAGE_SHIFT) + sun4c_iobuffer_start; - - /* Flush original mapping so we see the right things later. */ - sun4c_flush_page(vpage); - - sun4c_put_pte(apage, pte); - vpage += PAGE_SIZE; - } - local_irq_restore(flags); - return (char *) ((base << PAGE_SHIFT) + sun4c_iobuffer_start + - (((unsigned long) vaddr) & ~PAGE_MASK)); - -abend: - local_irq_restore(flags); - printk("DMA vaddr=0x%p size=%08lx\n", vaddr, size); - panic("Out of iobuffer table"); - return NULL; -} - -static void sun4c_unlockarea(char *vaddr, unsigned long size) -{ - unsigned long vpage, npages; - unsigned long flags; - int scan, high; - - vpage = (unsigned long)vaddr & PAGE_MASK; - npages = (((unsigned long)vaddr & ~PAGE_MASK) + - size + (PAGE_SIZE-1)) >> PAGE_SHIFT; - - local_irq_save(flags); - while (npages != 0) { - --npages; - - /* This mapping is marked non-cachable, no flush necessary. */ - sun4c_put_pte(vpage, 0); - clear_bit((vpage - sun4c_iobuffer_start) >> PAGE_SHIFT, - sun4c_iobuffer_map); - vpage += PAGE_SIZE; - } - - /* garbage collect */ - scan = (sun4c_iobuffer_high - sun4c_iobuffer_start) >> PAGE_SHIFT; - while (scan >= 0 && !sun4c_iobuffer_map[scan >> 5]) - scan -= 32; - scan += 32; - high = sun4c_iobuffer_start + (scan << PAGE_SHIFT); - high = SUN4C_REAL_PGDIR_ALIGN(high) + SUN4C_REAL_PGDIR_SIZE; - while (high < sun4c_iobuffer_high) { - sun4c_iobuffer_high -= SUN4C_REAL_PGDIR_SIZE; - free_locked_segment(sun4c_iobuffer_high); - } - local_irq_restore(flags); -} - -/* Note the scsi code at init time passes to here buffers - * which sit on the kernel stack, those are already locked - * by implication and fool the page locking code above - * if passed to by mistake. - */ -static __u32 sun4c_get_scsi_one(struct device *dev, char *bufptr, unsigned long len) -{ - unsigned long page; - - page = ((unsigned long)bufptr) & PAGE_MASK; - if (!virt_addr_valid(page)) { - sun4c_flush_page(page); - return (__u32)bufptr; /* already locked */ - } - return (__u32)sun4c_lockarea(bufptr, len); -} - -static void sun4c_get_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz) -{ - while (sz != 0) { - --sz; - sg->dma_address = (__u32)sun4c_lockarea(sg_virt(sg), sg->length); - sg->dma_length = sg->length; - sg = sg_next(sg); - } -} - -static void sun4c_release_scsi_one(struct device *dev, __u32 bufptr, unsigned long len) -{ - if (bufptr < sun4c_iobuffer_start) - return; /* On kernel stack or similar, see above */ - sun4c_unlockarea((char *)bufptr, len); -} - -static void sun4c_release_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz) -{ - while (sz != 0) { - --sz; - sun4c_unlockarea((char *)sg->dma_address, sg->length); - sg = sg_next(sg); - } -} - -#define TASK_ENTRY_SIZE BUCKET_SIZE /* see above */ -#define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1)) - -struct vm_area_struct sun4c_kstack_vma; - -static void __init sun4c_init_lock_areas(void) -{ - unsigned long sun4c_taskstack_start; - unsigned long sun4c_taskstack_end; - int bitmap_size; - - sun4c_init_buckets(); - sun4c_taskstack_start = SUN4C_LOCK_VADDR; - sun4c_taskstack_end = (sun4c_taskstack_start + - (TASK_ENTRY_SIZE * NR_TASK_BUCKETS)); - if (sun4c_taskstack_end >= SUN4C_LOCK_END) { - prom_printf("Too many tasks, decrease NR_TASK_BUCKETS please.\n"); - prom_halt(); - } - - sun4c_iobuffer_start = sun4c_iobuffer_high = - SUN4C_REAL_PGDIR_ALIGN(sun4c_taskstack_end); - sun4c_iobuffer_end = SUN4C_LOCK_END; - bitmap_size = (sun4c_iobuffer_end - sun4c_iobuffer_start) >> PAGE_SHIFT; - bitmap_size = (bitmap_size + 7) >> 3; - bitmap_size = LONG_ALIGN(bitmap_size); - iobuffer_map_size = bitmap_size << 3; - sun4c_iobuffer_map = __alloc_bootmem(bitmap_size, SMP_CACHE_BYTES, 0UL); - memset((void *) sun4c_iobuffer_map, 0, bitmap_size); - - sun4c_kstack_vma.vm_mm = &init_mm; - sun4c_kstack_vma.vm_start = sun4c_taskstack_start; - sun4c_kstack_vma.vm_end = sun4c_taskstack_end; - sun4c_kstack_vma.vm_page_prot = PAGE_SHARED; - sun4c_kstack_vma.vm_flags = VM_READ | VM_WRITE | VM_EXEC; - insert_vm_struct(&init_mm, &sun4c_kstack_vma); -} - -/* Cache flushing on the sun4c. */ -static void sun4c_flush_cache_all(void) -{ - unsigned long begin, end; - - flush_user_windows(); - begin = (KERNBASE + SUN4C_REAL_PGDIR_SIZE); - end = (begin + SUN4C_VAC_SIZE); - - if (sun4c_vacinfo.linesize == 32) { - while (begin < end) { - __asm__ __volatile__( - "ld [%0 + 0x00], %%g0\n\t" - "ld [%0 + 0x20], %%g0\n\t" - "ld [%0 + 0x40], %%g0\n\t" - "ld [%0 + 0x60], %%g0\n\t" - "ld [%0 + 0x80], %%g0\n\t" - "ld [%0 + 0xa0], %%g0\n\t" - "ld [%0 + 0xc0], %%g0\n\t" - "ld [%0 + 0xe0], %%g0\n\t" - "ld [%0 + 0x100], %%g0\n\t" - "ld [%0 + 0x120], %%g0\n\t" - "ld [%0 + 0x140], %%g0\n\t" - "ld [%0 + 0x160], %%g0\n\t" - "ld [%0 + 0x180], %%g0\n\t" - "ld [%0 + 0x1a0], %%g0\n\t" - "ld [%0 + 0x1c0], %%g0\n\t" - "ld [%0 + 0x1e0], %%g0\n" - : : "r" (begin)); - begin += 512; - } - } else { - while (begin < end) { - __asm__ __volatile__( - "ld [%0 + 0x00], %%g0\n\t" - "ld [%0 + 0x10], %%g0\n\t" - "ld [%0 + 0x20], %%g0\n\t" - "ld [%0 + 0x30], %%g0\n\t" - "ld [%0 + 0x40], %%g0\n\t" - "ld [%0 + 0x50], %%g0\n\t" - "ld [%0 + 0x60], %%g0\n\t" - "ld [%0 + 0x70], %%g0\n\t" - "ld [%0 + 0x80], %%g0\n\t" - "ld [%0 + 0x90], %%g0\n\t" - "ld [%0 + 0xa0], %%g0\n\t" - "ld [%0 + 0xb0], %%g0\n\t" - "ld [%0 + 0xc0], %%g0\n\t" - "ld [%0 + 0xd0], %%g0\n\t" - "ld [%0 + 0xe0], %%g0\n\t" - "ld [%0 + 0xf0], %%g0\n" - : : "r" (begin)); - begin += 256; - } - } -} - -static void sun4c_flush_cache_mm(struct mm_struct *mm) -{ - int new_ctx = mm->context; - - if (new_ctx != NO_CONTEXT) { - flush_user_windows(); - - if (sun4c_context_ring[new_ctx].num_entries) { - struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd; - unsigned long flags; - - local_irq_save(flags); - if (head->next != head) { - struct sun4c_mmu_entry *entry = head->next; - int savectx = sun4c_get_context(); - - sun4c_set_context(new_ctx); - sun4c_flush_context(); - do { - struct sun4c_mmu_entry *next = entry->next; - - sun4c_user_unmap(entry); - free_user_entry(new_ctx, entry); - - entry = next; - } while (entry != head); - sun4c_set_context(savectx); - } - local_irq_restore(flags); - } - } -} - -static void sun4c_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - int new_ctx = mm->context; - - if (new_ctx != NO_CONTEXT) { - struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd; - struct sun4c_mmu_entry *entry; - unsigned long flags; - - flush_user_windows(); - - local_irq_save(flags); - /* All user segmap chains are ordered on entry->vaddr. */ - for (entry = head->next; - (entry != head) && ((entry->vaddr+SUN4C_REAL_PGDIR_SIZE) < start); - entry = entry->next) - ; - - /* Tracing various job mixtures showed that this conditional - * only passes ~35% of the time for most worse case situations, - * therefore we avoid all of this gross overhead ~65% of the time. - */ - if ((entry != head) && (entry->vaddr < end)) { - int octx = sun4c_get_context(); - sun4c_set_context(new_ctx); - - /* At this point, always, (start >= entry->vaddr) and - * (entry->vaddr < end), once the latter condition - * ceases to hold, or we hit the end of the list, we - * exit the loop. The ordering of all user allocated - * segmaps makes this all work out so beautifully. - */ - do { - struct sun4c_mmu_entry *next = entry->next; - unsigned long realend; - - /* "realstart" is always >= entry->vaddr */ - realend = entry->vaddr + SUN4C_REAL_PGDIR_SIZE; - if (end < realend) - realend = end; - if ((realend - entry->vaddr) <= (PAGE_SIZE << 3)) { - unsigned long page = entry->vaddr; - while (page < realend) { - sun4c_flush_page(page); - page += PAGE_SIZE; - } - } else { - sun4c_flush_segment(entry->vaddr); - sun4c_user_unmap(entry); - free_user_entry(new_ctx, entry); - } - entry = next; - } while ((entry != head) && (entry->vaddr < end)); - sun4c_set_context(octx); - } - local_irq_restore(flags); - } -} - -static void sun4c_flush_cache_page(struct vm_area_struct *vma, unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - int new_ctx = mm->context; - - /* Sun4c has no separate I/D caches so cannot optimize for non - * text page flushes. - */ - if (new_ctx != NO_CONTEXT) { - int octx = sun4c_get_context(); - unsigned long flags; - - flush_user_windows(); - local_irq_save(flags); - sun4c_set_context(new_ctx); - sun4c_flush_page(page); - sun4c_set_context(octx); - local_irq_restore(flags); - } -} - -static void sun4c_flush_page_to_ram(unsigned long page) -{ - unsigned long flags; - - local_irq_save(flags); - sun4c_flush_page(page); - local_irq_restore(flags); -} - -/* Sun4c cache is unified, both instructions and data live there, so - * no need to flush the on-stack instructions for new signal handlers. - */ -static void sun4c_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) -{ -} - -/* TLB flushing on the sun4c. These routines count on the cache - * flushing code to flush the user register windows so that we need - * not do so when we get here. - */ - -static void sun4c_flush_tlb_all(void) -{ - struct sun4c_mmu_entry *this_entry, *next_entry; - unsigned long flags; - int savectx, ctx; - - local_irq_save(flags); - this_entry = sun4c_kernel_ring.ringhd.next; - savectx = sun4c_get_context(); - flush_user_windows(); - while (sun4c_kernel_ring.num_entries) { - next_entry = this_entry->next; - sun4c_flush_segment(this_entry->vaddr); - for (ctx = 0; ctx < num_contexts; ctx++) { - sun4c_set_context(ctx); - sun4c_put_segmap(this_entry->vaddr, invalid_segment); - } - free_kernel_entry(this_entry, &sun4c_kernel_ring); - this_entry = next_entry; - } - sun4c_set_context(savectx); - local_irq_restore(flags); -} - -static void sun4c_flush_tlb_mm(struct mm_struct *mm) -{ - int new_ctx = mm->context; - - if (new_ctx != NO_CONTEXT) { - struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd; - unsigned long flags; - - local_irq_save(flags); - if (head->next != head) { - struct sun4c_mmu_entry *entry = head->next; - int savectx = sun4c_get_context(); - - sun4c_set_context(new_ctx); - sun4c_flush_context(); - do { - struct sun4c_mmu_entry *next = entry->next; - - sun4c_user_unmap(entry); - free_user_entry(new_ctx, entry); - - entry = next; - } while (entry != head); - sun4c_set_context(savectx); - } - local_irq_restore(flags); - } -} - -static void sun4c_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - int new_ctx = mm->context; - - if (new_ctx != NO_CONTEXT) { - struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd; - struct sun4c_mmu_entry *entry; - unsigned long flags; - - local_irq_save(flags); - /* See commentary in sun4c_flush_cache_range(). */ - for (entry = head->next; - (entry != head) && ((entry->vaddr+SUN4C_REAL_PGDIR_SIZE) < start); - entry = entry->next) - ; - - if ((entry != head) && (entry->vaddr < end)) { - int octx = sun4c_get_context(); - - sun4c_set_context(new_ctx); - do { - struct sun4c_mmu_entry *next = entry->next; - - sun4c_flush_segment(entry->vaddr); - sun4c_user_unmap(entry); - free_user_entry(new_ctx, entry); - - entry = next; - } while ((entry != head) && (entry->vaddr < end)); - sun4c_set_context(octx); - } - local_irq_restore(flags); - } -} - -static void sun4c_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - int new_ctx = mm->context; - - if (new_ctx != NO_CONTEXT) { - int savectx = sun4c_get_context(); - unsigned long flags; - - local_irq_save(flags); - sun4c_set_context(new_ctx); - page &= PAGE_MASK; - sun4c_flush_page(page); - sun4c_put_pte(page, 0); - sun4c_set_context(savectx); - local_irq_restore(flags); - } -} - -static inline void sun4c_mapioaddr(unsigned long physaddr, unsigned long virt_addr) -{ - unsigned long page_entry, pg_iobits; - - pg_iobits = _SUN4C_PAGE_PRESENT | _SUN4C_READABLE | _SUN4C_WRITEABLE | - _SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE; - - page_entry = ((physaddr >> PAGE_SHIFT) & SUN4C_PFN_MASK); - page_entry |= ((pg_iobits | _SUN4C_PAGE_PRIV) & ~(_SUN4C_PAGE_PRESENT)); - sun4c_put_pte(virt_addr, page_entry); -} - -static void sun4c_mapiorange(unsigned int bus, unsigned long xpa, - unsigned long xva, unsigned int len) -{ - while (len != 0) { - len -= PAGE_SIZE; - sun4c_mapioaddr(xpa, xva); - xva += PAGE_SIZE; - xpa += PAGE_SIZE; - } -} - -static void sun4c_unmapiorange(unsigned long virt_addr, unsigned int len) -{ - while (len != 0) { - len -= PAGE_SIZE; - sun4c_put_pte(virt_addr, 0); - virt_addr += PAGE_SIZE; - } -} - -static void sun4c_alloc_context(struct mm_struct *old_mm, struct mm_struct *mm) -{ - struct ctx_list *ctxp; - - ctxp = ctx_free.next; - if (ctxp != &ctx_free) { - remove_from_ctx_list(ctxp); - add_to_used_ctxlist(ctxp); - mm->context = ctxp->ctx_number; - ctxp->ctx_mm = mm; - return; - } - ctxp = ctx_used.next; - if (ctxp->ctx_mm == old_mm) - ctxp = ctxp->next; - remove_from_ctx_list(ctxp); - add_to_used_ctxlist(ctxp); - ctxp->ctx_mm->context = NO_CONTEXT; - ctxp->ctx_mm = mm; - mm->context = ctxp->ctx_number; - sun4c_demap_context(&sun4c_context_ring[ctxp->ctx_number], - ctxp->ctx_number); -} - -/* Switch the current MM context. */ -static void sun4c_switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk, int cpu) -{ - struct ctx_list *ctx; - int dirty = 0; - - if (mm->context == NO_CONTEXT) { - dirty = 1; - sun4c_alloc_context(old_mm, mm); - } else { - /* Update the LRU ring of contexts. */ - ctx = ctx_list_pool + mm->context; - remove_from_ctx_list(ctx); - add_to_used_ctxlist(ctx); - } - if (dirty || old_mm != mm) - sun4c_set_context(mm->context); -} - -static void sun4c_destroy_context(struct mm_struct *mm) -{ - struct ctx_list *ctx_old; - - if (mm->context != NO_CONTEXT) { - sun4c_demap_context(&sun4c_context_ring[mm->context], mm->context); - ctx_old = ctx_list_pool + mm->context; - remove_from_ctx_list(ctx_old); - add_to_free_ctxlist(ctx_old); - mm->context = NO_CONTEXT; - } -} - -static void sun4c_mmu_info(struct seq_file *m) -{ - int used_user_entries, i; - - used_user_entries = 0; - for (i = 0; i < num_contexts; i++) - used_user_entries += sun4c_context_ring[i].num_entries; - - seq_printf(m, - "vacsize\t\t: %d bytes\n" - "vachwflush\t: %s\n" - "vaclinesize\t: %d bytes\n" - "mmuctxs\t\t: %d\n" - "mmupsegs\t: %d\n" - "kernelpsegs\t: %d\n" - "kfreepsegs\t: %d\n" - "usedpsegs\t: %d\n" - "ufreepsegs\t: %d\n" - "user_taken\t: %d\n" - "max_taken\t: %d\n", - sun4c_vacinfo.num_bytes, - (sun4c_vacinfo.do_hwflushes ? "yes" : "no"), - sun4c_vacinfo.linesize, - num_contexts, - (invalid_segment + 1), - sun4c_kernel_ring.num_entries, - sun4c_kfree_ring.num_entries, - used_user_entries, - sun4c_ufree_ring.num_entries, - sun4c_user_taken_entries, - max_user_taken_entries); -} - -/* Nothing below here should touch the mmu hardware nor the mmu_entry - * data structures. - */ - -/* First the functions which the mid-level code uses to directly - * manipulate the software page tables. Some defines since we are - * emulating the i386 page directory layout. - */ -#define PGD_PRESENT 0x001 -#define PGD_RW 0x002 -#define PGD_USER 0x004 -#define PGD_ACCESSED 0x020 -#define PGD_DIRTY 0x040 -#define PGD_TABLE (PGD_PRESENT | PGD_RW | PGD_USER | PGD_ACCESSED | PGD_DIRTY) - -static void sun4c_set_pte(pte_t *ptep, pte_t pte) -{ - *ptep = pte; -} - -static void sun4c_pgd_set(pgd_t * pgdp, pmd_t * pmdp) -{ -} - -static void sun4c_pmd_set(pmd_t * pmdp, pte_t * ptep) -{ - pmdp->pmdv[0] = PGD_TABLE | (unsigned long) ptep; -} - -static void sun4c_pmd_populate(pmd_t * pmdp, struct page * ptep) -{ - if (page_address(ptep) == NULL) BUG(); /* No highmem on sun4c */ - pmdp->pmdv[0] = PGD_TABLE | (unsigned long) page_address(ptep); -} - -static int sun4c_pte_present(pte_t pte) -{ - return ((pte_val(pte) & (_SUN4C_PAGE_PRESENT | _SUN4C_PAGE_PRIV)) != 0); -} -static void sun4c_pte_clear(pte_t *ptep) { *ptep = __pte(0); } - -static int sun4c_pmd_bad(pmd_t pmd) -{ - return (((pmd_val(pmd) & ~PAGE_MASK) != PGD_TABLE) || - (!virt_addr_valid(pmd_val(pmd)))); -} - -static int sun4c_pmd_present(pmd_t pmd) -{ - return ((pmd_val(pmd) & PGD_PRESENT) != 0); -} - -#if 0 /* if PMD takes one word */ -static void sun4c_pmd_clear(pmd_t *pmdp) { *pmdp = __pmd(0); } -#else /* if pmd_t is a longish aggregate */ -static void sun4c_pmd_clear(pmd_t *pmdp) { - memset((void *)pmdp, 0, sizeof(pmd_t)); -} -#endif - -static int sun4c_pgd_none(pgd_t pgd) { return 0; } -static int sun4c_pgd_bad(pgd_t pgd) { return 0; } -static int sun4c_pgd_present(pgd_t pgd) { return 1; } -static void sun4c_pgd_clear(pgd_t * pgdp) { } - -/* - * The following only work if pte_present() is true. - * Undefined behaviour if not.. - */ -static pte_t sun4c_pte_mkwrite(pte_t pte) -{ - pte = __pte(pte_val(pte) | _SUN4C_PAGE_WRITE); - if (pte_val(pte) & _SUN4C_PAGE_MODIFIED) - pte = __pte(pte_val(pte) | _SUN4C_PAGE_SILENT_WRITE); - return pte; -} - -static pte_t sun4c_pte_mkdirty(pte_t pte) -{ - pte = __pte(pte_val(pte) | _SUN4C_PAGE_MODIFIED); - if (pte_val(pte) & _SUN4C_PAGE_WRITE) - pte = __pte(pte_val(pte) | _SUN4C_PAGE_SILENT_WRITE); - return pte; -} - -static pte_t sun4c_pte_mkyoung(pte_t pte) -{ - pte = __pte(pte_val(pte) | _SUN4C_PAGE_ACCESSED); - if (pte_val(pte) & _SUN4C_PAGE_READ) - pte = __pte(pte_val(pte) | _SUN4C_PAGE_SILENT_READ); - return pte; -} - -/* - * Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. - */ -static pte_t sun4c_mk_pte(struct page *page, pgprot_t pgprot) -{ - return __pte(page_to_pfn(page) | pgprot_val(pgprot)); -} - -static pte_t sun4c_mk_pte_phys(unsigned long phys_page, pgprot_t pgprot) -{ - return __pte((phys_page >> PAGE_SHIFT) | pgprot_val(pgprot)); -} - -static pte_t sun4c_mk_pte_io(unsigned long page, pgprot_t pgprot, int space) -{ - return __pte(((page - PAGE_OFFSET) >> PAGE_SHIFT) | pgprot_val(pgprot)); -} - -static unsigned long sun4c_pte_pfn(pte_t pte) -{ - return pte_val(pte) & SUN4C_PFN_MASK; -} - -static pte_t sun4c_pgoff_to_pte(unsigned long pgoff) -{ - return __pte(pgoff | _SUN4C_PAGE_FILE); -} - -static unsigned long sun4c_pte_to_pgoff(pte_t pte) -{ - return pte_val(pte) & ((1UL << PTE_FILE_MAX_BITS) - 1); -} - - -static inline unsigned long sun4c_pmd_page_v(pmd_t pmd) -{ - return (pmd_val(pmd) & PAGE_MASK); -} - -static struct page *sun4c_pmd_page(pmd_t pmd) -{ - return virt_to_page(sun4c_pmd_page_v(pmd)); -} - -static unsigned long sun4c_pgd_page(pgd_t pgd) { return 0; } - -/* to find an entry in a page-table-directory */ -static inline pgd_t *sun4c_pgd_offset(struct mm_struct * mm, unsigned long address) -{ - return mm->pgd + (address >> SUN4C_PGDIR_SHIFT); -} - -/* Find an entry in the second-level page table.. */ -static pmd_t *sun4c_pmd_offset(pgd_t * dir, unsigned long address) -{ - return (pmd_t *) dir; -} - -/* Find an entry in the third-level page table.. */ -pte_t *sun4c_pte_offset_kernel(pmd_t * dir, unsigned long address) -{ - return (pte_t *) sun4c_pmd_page_v(*dir) + - ((address >> PAGE_SHIFT) & (SUN4C_PTRS_PER_PTE - 1)); -} - -static unsigned long sun4c_swp_type(swp_entry_t entry) -{ - return (entry.val & SUN4C_SWP_TYPE_MASK); -} - -static unsigned long sun4c_swp_offset(swp_entry_t entry) -{ - return (entry.val >> SUN4C_SWP_OFF_SHIFT) & SUN4C_SWP_OFF_MASK; -} - -static swp_entry_t sun4c_swp_entry(unsigned long type, unsigned long offset) -{ - return (swp_entry_t) { - (offset & SUN4C_SWP_OFF_MASK) << SUN4C_SWP_OFF_SHIFT - | (type & SUN4C_SWP_TYPE_MASK) }; -} - -static void sun4c_free_pte_slow(pte_t *pte) -{ - free_page((unsigned long)pte); -} - -static void sun4c_free_pgd_slow(pgd_t *pgd) -{ - free_page((unsigned long)pgd); -} - -static pgd_t *sun4c_get_pgd_fast(void) -{ - unsigned long *ret; - - if ((ret = pgd_quicklist) != NULL) { - pgd_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - } else { - pgd_t *init; - - ret = (unsigned long *)__get_free_page(GFP_KERNEL); - memset (ret, 0, (KERNBASE / SUN4C_PGDIR_SIZE) * sizeof(pgd_t)); - init = sun4c_pgd_offset(&init_mm, 0); - memcpy (((pgd_t *)ret) + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); - } - return (pgd_t *)ret; -} - -static void sun4c_free_pgd_fast(pgd_t *pgd) -{ - *(unsigned long *)pgd = (unsigned long) pgd_quicklist; - pgd_quicklist = (unsigned long *) pgd; - pgtable_cache_size++; -} - - -static inline pte_t * -sun4c_pte_alloc_one_fast(struct mm_struct *mm, unsigned long address) -{ - unsigned long *ret; - - if ((ret = (unsigned long *)pte_quicklist) != NULL) { - pte_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - } - return (pte_t *)ret; -} - -static pte_t *sun4c_pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) -{ - pte_t *pte; - - if ((pte = sun4c_pte_alloc_one_fast(mm, address)) != NULL) - return pte; - - pte = (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); - return pte; -} - -static pgtable_t sun4c_pte_alloc_one(struct mm_struct *mm, unsigned long address) -{ - pte_t *pte; - struct page *page; - - pte = sun4c_pte_alloc_one_kernel(mm, address); - if (pte == NULL) - return NULL; - page = virt_to_page(pte); - pgtable_page_ctor(page); - return page; -} - -static inline void sun4c_free_pte_fast(pte_t *pte) -{ - *(unsigned long *)pte = (unsigned long) pte_quicklist; - pte_quicklist = (unsigned long *) pte; - pgtable_cache_size++; -} - -static void sun4c_pte_free(pgtable_t pte) -{ - pgtable_page_dtor(pte); - sun4c_free_pte_fast(page_address(pte)); -} - -/* - * allocating and freeing a pmd is trivial: the 1-entry pmd is - * inside the pgd, so has no extra memory associated with it. - */ -static pmd_t *sun4c_pmd_alloc_one(struct mm_struct *mm, unsigned long address) -{ - BUG(); - return NULL; -} - -static void sun4c_free_pmd_fast(pmd_t * pmd) { } - -static void sun4c_check_pgt_cache(int low, int high) -{ - if (pgtable_cache_size > high) { - do { - if (pgd_quicklist) - sun4c_free_pgd_slow(sun4c_get_pgd_fast()); - if (pte_quicklist) - sun4c_free_pte_slow(sun4c_pte_alloc_one_fast(NULL, 0)); - } while (pgtable_cache_size > low); - } -} - -/* An experiment, turn off by default for now... -DaveM */ -#define SUN4C_PRELOAD_PSEG - -void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) -{ - unsigned long flags; - int pseg; - - if (vma->vm_mm->context == NO_CONTEXT) - return; - - local_irq_save(flags); - address &= PAGE_MASK; - if ((pseg = sun4c_get_segmap(address)) == invalid_segment) { - struct sun4c_mmu_entry *entry = sun4c_user_strategy(); - struct mm_struct *mm = vma->vm_mm; - unsigned long start, end; - - entry->vaddr = start = (address & SUN4C_REAL_PGDIR_MASK); - entry->ctx = mm->context; - add_ring_ordered(sun4c_context_ring + mm->context, entry); - sun4c_put_segmap(entry->vaddr, entry->pseg); - end = start + SUN4C_REAL_PGDIR_SIZE; - while (start < end) { -#ifdef SUN4C_PRELOAD_PSEG - pgd_t *pgdp = sun4c_pgd_offset(mm, start); - pte_t *ptep; - - if (!pgdp) - goto no_mapping; - ptep = sun4c_pte_offset_kernel((pmd_t *) pgdp, start); - if (!ptep || !(pte_val(*ptep) & _SUN4C_PAGE_PRESENT)) - goto no_mapping; - sun4c_put_pte(start, pte_val(*ptep)); - goto next; - - no_mapping: -#endif - sun4c_put_pte(start, 0); -#ifdef SUN4C_PRELOAD_PSEG - next: -#endif - start += PAGE_SIZE; - } -#ifndef SUN4C_PRELOAD_PSEG - sun4c_put_pte(address, pte_val(*ptep)); -#endif - local_irq_restore(flags); - return; - } else { - struct sun4c_mmu_entry *entry = &mmu_entry_pool[pseg]; - - remove_lru(entry); - add_lru(entry); - } - - sun4c_put_pte(address, pte_val(*ptep)); - local_irq_restore(flags); -} - -extern void sparc_context_init(int); -extern unsigned long bootmem_init(unsigned long *pages_avail); -extern unsigned long last_valid_pfn; - -void __init sun4c_paging_init(void) -{ - int i, cnt; - unsigned long kernel_end, vaddr; - extern struct resource sparc_iomap; - unsigned long end_pfn, pages_avail; - - kernel_end = (unsigned long) &_end; - kernel_end = SUN4C_REAL_PGDIR_ALIGN(kernel_end); - - pages_avail = 0; - last_valid_pfn = bootmem_init(&pages_avail); - end_pfn = last_valid_pfn; - - sun4c_probe_mmu(); - invalid_segment = (num_segmaps - 1); - sun4c_init_mmu_entry_pool(); - sun4c_init_rings(); - sun4c_init_map_kernelprom(kernel_end); - sun4c_init_clean_mmu(kernel_end); - sun4c_init_fill_kernel_ring(SUN4C_KERNEL_BUCKETS); - sun4c_init_lock_area(sparc_iomap.start, IOBASE_END); - sun4c_init_lock_area(DVMA_VADDR, DVMA_END); - sun4c_init_lock_areas(); - sun4c_init_fill_user_ring(); - - sun4c_set_context(0); - memset(swapper_pg_dir, 0, PAGE_SIZE); - memset(pg0, 0, PAGE_SIZE); - memset(pg1, 0, PAGE_SIZE); - memset(pg2, 0, PAGE_SIZE); - memset(pg3, 0, PAGE_SIZE); - - /* Save work later. */ - vaddr = VMALLOC_START; - swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg0); - vaddr += SUN4C_PGDIR_SIZE; - swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg1); - vaddr += SUN4C_PGDIR_SIZE; - swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg2); - vaddr += SUN4C_PGDIR_SIZE; - swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg3); - sun4c_init_ss2_cache_bug(); - sparc_context_init(num_contexts); - - { - unsigned long zones_size[MAX_NR_ZONES]; - unsigned long zholes_size[MAX_NR_ZONES]; - unsigned long npages; - int znum; - - for (znum = 0; znum < MAX_NR_ZONES; znum++) - zones_size[znum] = zholes_size[znum] = 0; - - npages = max_low_pfn - pfn_base; - - zones_size[ZONE_DMA] = npages; - zholes_size[ZONE_DMA] = npages - pages_avail; - - npages = highend_pfn - max_low_pfn; - zones_size[ZONE_HIGHMEM] = npages; - zholes_size[ZONE_HIGHMEM] = npages - calc_highpages(); - - free_area_init_node(0, zones_size, pfn_base, zholes_size); - } - - cnt = 0; - for (i = 0; i < num_segmaps; i++) - if (mmu_entry_pool[i].locked) - cnt++; - - max_user_taken_entries = num_segmaps - cnt - 40 - 1; - - printk("SUN4C: %d mmu entries for the kernel\n", cnt); -} - -static pgprot_t sun4c_pgprot_noncached(pgprot_t prot) -{ - prot |= __pgprot(_SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE); - - return prot; -} - -/* Load up routines and constants for sun4c mmu */ -void __init ld_mmu_sun4c(void) -{ - extern void ___xchg32_sun4c(void); - - printk("Loading sun4c MMU routines\n"); - - /* First the constants */ - BTFIXUPSET_SIMM13(pgdir_shift, SUN4C_PGDIR_SHIFT); - BTFIXUPSET_SETHI(pgdir_size, SUN4C_PGDIR_SIZE); - BTFIXUPSET_SETHI(pgdir_mask, SUN4C_PGDIR_MASK); - - BTFIXUPSET_SIMM13(ptrs_per_pmd, SUN4C_PTRS_PER_PMD); - BTFIXUPSET_SIMM13(ptrs_per_pgd, SUN4C_PTRS_PER_PGD); - BTFIXUPSET_SIMM13(user_ptrs_per_pgd, KERNBASE / SUN4C_PGDIR_SIZE); - - BTFIXUPSET_INT(page_none, pgprot_val(SUN4C_PAGE_NONE)); - PAGE_SHARED = pgprot_val(SUN4C_PAGE_SHARED); - BTFIXUPSET_INT(page_copy, pgprot_val(SUN4C_PAGE_COPY)); - BTFIXUPSET_INT(page_readonly, pgprot_val(SUN4C_PAGE_READONLY)); - BTFIXUPSET_INT(page_kernel, pgprot_val(SUN4C_PAGE_KERNEL)); - page_kernel = pgprot_val(SUN4C_PAGE_KERNEL); - - /* Functions */ - BTFIXUPSET_CALL(pgprot_noncached, sun4c_pgprot_noncached, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4c, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(do_check_pgt_cache, sun4c_check_pgt_cache, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(flush_cache_all, sun4c_flush_cache_all, BTFIXUPCALL_NORM); - - if (sun4c_vacinfo.do_hwflushes) { - BTFIXUPSET_CALL(sun4c_flush_page, sun4c_flush_page_hw, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(sun4c_flush_segment, sun4c_flush_segment_hw, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(sun4c_flush_context, sun4c_flush_context_hw, BTFIXUPCALL_NORM); - } else { - BTFIXUPSET_CALL(sun4c_flush_page, sun4c_flush_page_sw, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(sun4c_flush_segment, sun4c_flush_segment_sw, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(sun4c_flush_context, sun4c_flush_context_sw, BTFIXUPCALL_NORM); - } - - BTFIXUPSET_CALL(flush_tlb_mm, sun4c_flush_tlb_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_mm, sun4c_flush_cache_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(destroy_context, sun4c_destroy_context, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(switch_mm, sun4c_switch_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_page, sun4c_flush_cache_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_page, sun4c_flush_tlb_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_range, sun4c_flush_tlb_range, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_cache_range, sun4c_flush_cache_range, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(__flush_page_to_ram, sun4c_flush_page_to_ram, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_tlb_all, sun4c_flush_tlb_all, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(flush_sig_insns, sun4c_flush_sig_insns, BTFIXUPCALL_NOP); - - BTFIXUPSET_CALL(set_pte, sun4c_set_pte, BTFIXUPCALL_STO1O0); - - BTFIXUPSET_CALL(pte_pfn, sun4c_pte_pfn, BTFIXUPCALL_NORM); -#if 0 /* PAGE_SHIFT <= 12 */ /* Eek. Investigate. XXX */ - BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_ANDNINT(PAGE_SIZE - 1)); -#else - BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_NORM); -#endif - BTFIXUPSET_CALL(pmd_set, sun4c_pmd_set, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_populate, sun4c_pmd_populate, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(pte_present, sun4c_pte_present, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_clear, sun4c_pte_clear, BTFIXUPCALL_STG0O0); - - BTFIXUPSET_CALL(pmd_bad, sun4c_pmd_bad, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_present, sun4c_pmd_present, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_clear, sun4c_pmd_clear, BTFIXUPCALL_STG0O0); - - BTFIXUPSET_CALL(pgd_none, sun4c_pgd_none, BTFIXUPCALL_RETINT(0)); - BTFIXUPSET_CALL(pgd_bad, sun4c_pgd_bad, BTFIXUPCALL_RETINT(0)); - BTFIXUPSET_CALL(pgd_present, sun4c_pgd_present, BTFIXUPCALL_RETINT(1)); - BTFIXUPSET_CALL(pgd_clear, sun4c_pgd_clear, BTFIXUPCALL_NOP); - - BTFIXUPSET_CALL(mk_pte, sun4c_mk_pte, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mk_pte_phys, sun4c_mk_pte_phys, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mk_pte_io, sun4c_mk_pte_io, BTFIXUPCALL_NORM); - - BTFIXUPSET_INT(pte_modify_mask, _SUN4C_PAGE_CHG_MASK); - BTFIXUPSET_CALL(pmd_offset, sun4c_pmd_offset, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_offset_kernel, sun4c_pte_offset_kernel, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(free_pte_fast, sun4c_free_pte_fast, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_free, sun4c_pte_free, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_alloc_one_kernel, sun4c_pte_alloc_one_kernel, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_alloc_one, sun4c_pte_alloc_one, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(free_pmd_fast, sun4c_free_pmd_fast, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(pmd_alloc_one, sun4c_pmd_alloc_one, BTFIXUPCALL_RETO0); - BTFIXUPSET_CALL(free_pgd_fast, sun4c_free_pgd_fast, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(get_pgd_fast, sun4c_get_pgd_fast, BTFIXUPCALL_NORM); - - BTFIXUPSET_HALF(pte_writei, _SUN4C_PAGE_WRITE); - BTFIXUPSET_HALF(pte_dirtyi, _SUN4C_PAGE_MODIFIED); - BTFIXUPSET_HALF(pte_youngi, _SUN4C_PAGE_ACCESSED); - BTFIXUPSET_HALF(pte_filei, _SUN4C_PAGE_FILE); - BTFIXUPSET_HALF(pte_wrprotecti, _SUN4C_PAGE_WRITE|_SUN4C_PAGE_SILENT_WRITE); - BTFIXUPSET_HALF(pte_mkcleani, _SUN4C_PAGE_MODIFIED|_SUN4C_PAGE_SILENT_WRITE); - BTFIXUPSET_HALF(pte_mkoldi, _SUN4C_PAGE_ACCESSED|_SUN4C_PAGE_SILENT_READ); - BTFIXUPSET_CALL(pte_mkwrite, sun4c_pte_mkwrite, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_mkdirty, sun4c_pte_mkdirty, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_mkyoung, sun4c_pte_mkyoung, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(update_mmu_cache, sun4c_update_mmu_cache, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(pte_to_pgoff, sun4c_pte_to_pgoff, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgoff_to_pte, sun4c_pgoff_to_pte, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(mmu_lockarea, sun4c_lockarea, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_unlockarea, sun4c_unlockarea, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(mmu_get_scsi_one, sun4c_get_scsi_one, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_get_scsi_sgl, sun4c_get_scsi_sgl, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_release_scsi_one, sun4c_release_scsi_one, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_release_scsi_sgl, sun4c_release_scsi_sgl, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(mmu_map_dma_area, sun4c_map_dma_area, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_unmap_dma_area, sun4c_unmap_dma_area, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(sparc_mapiorange, sun4c_mapiorange, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(sparc_unmapiorange, sun4c_unmapiorange, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(__swp_type, sun4c_swp_type, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(__swp_offset, sun4c_swp_offset, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(__swp_entry, sun4c_swp_entry, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(alloc_thread_info_node, sun4c_alloc_thread_info_node, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(free_thread_info, sun4c_free_thread_info, BTFIXUPCALL_NORM); - - BTFIXUPSET_CALL(mmu_info, sun4c_mmu_info, BTFIXUPCALL_NORM); - - /* These should _never_ get called with two level tables. */ - BTFIXUPSET_CALL(pgd_set, sun4c_pgd_set, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(pgd_page_vaddr, sun4c_pgd_page, BTFIXUPCALL_RETO0); -}
diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S index b57a594..874162a 100644 --- a/arch/sparc/mm/ultra.S +++ b/arch/sparc/mm/ultra.S
@@ -495,11 +495,11 @@ stx %o7, [%g1 + GR_SNAP_O7] stx %i7, [%g1 + GR_SNAP_I7] /* Don't try this at home kids... */ - rdpr %cwp, %g2 - sub %g2, 1, %g7 + rdpr %cwp, %g3 + sub %g3, 1, %g7 wrpr %g7, %cwp mov %i7, %g7 - wrpr %g2, %cwp + wrpr %g3, %cwp stx %g7, [%g1 + GR_SNAP_RPC] sethi %hi(trap_block), %g7 or %g7, %lo(trap_block), %g7
diff --git a/arch/sparc/mm/viking.S b/arch/sparc/mm/viking.S index 6dfcc13..bf8ee06 100644 --- a/arch/sparc/mm/viking.S +++ b/arch/sparc/mm/viking.S
@@ -14,7 +14,6 @@ #include <asm/page.h> #include <asm/pgtsrmmu.h> #include <asm/viking.h> -#include <asm/btfixup.h> #ifdef CONFIG_SMP .data
diff --git a/arch/sparc/prom/Makefile b/arch/sparc/prom/Makefile index 8287bbe..020300b1 100644 --- a/arch/sparc/prom/Makefile +++ b/arch/sparc/prom/Makefile
@@ -10,7 +10,6 @@ lib-y += misc_$(BITS).o lib-$(CONFIG_SPARC32) += mp.o lib-$(CONFIG_SPARC32) += ranges.o -lib-$(CONFIG_SPARC32) += segment.o lib-y += console_$(BITS).o lib-y += printf.o lib-y += tree_$(BITS).o
diff --git a/arch/sparc/prom/segment.c b/arch/sparc/prom/segment.c deleted file mode 100644 index 86a663f..0000000 --- a/arch/sparc/prom/segment.c +++ /dev/null
@@ -1,28 +0,0 @@ -/* - * segment.c: Prom routine to map segments in other contexts before - * a standalone is completely mapped. This is for sun4 and - * sun4c architectures only. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - */ - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <asm/openprom.h> -#include <asm/oplib.h> - -extern void restore_current(void); - -/* Set physical segment 'segment' at virtual address 'vaddr' in - * context 'ctx'. - */ -void -prom_putsegment(int ctx, unsigned long vaddr, int segment) -{ - unsigned long flags; - spin_lock_irqsave(&prom_lock, flags); - (*(romvec->pv_setctxt))(ctx, (char *) vaddr, segment); - restore_current(); - spin_unlock_irqrestore(&prom_lock, flags); -}
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 96033e2..74239dd 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig
@@ -11,6 +11,7 @@ select GENERIC_IRQ_PROBE select GENERIC_PENDING_IRQ if SMP select GENERIC_IRQ_SHOW + select HAVE_SYSCALL_WRAPPERS if TILEGX select SYS_HYPERVISOR select ARCH_HAVE_NMI_SAFE_CMPXCHG
diff --git a/arch/tile/include/asm/thread_info.h b/arch/tile/include/asm/thread_info.h index bc4f562..7594764 100644 --- a/arch/tile/include/asm/thread_info.h +++ b/arch/tile/include/asm/thread_info.h
@@ -100,9 +100,14 @@ #else /* __ASSEMBLY__ */ -/* how to get the thread information struct from ASM */ +/* + * How to get the thread information struct from assembly. + * Note that we use different macros since different architectures + * have different semantics in their "mm" instruction and we would + * like to guarantee that the macro expands to exactly one instruction. + */ #ifdef __tilegx__ -#define GET_THREAD_INFO(reg) move reg, sp; mm reg, zero, LOG2_THREAD_SIZE, 63 +#define EXTRACT_THREAD_INFO(reg) mm reg, zero, LOG2_THREAD_SIZE, 63 #else #define GET_THREAD_INFO(reg) mm reg, sp, zero, LOG2_THREAD_SIZE, 31 #endif
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c index 77763cc..cdef6e5 100644 --- a/arch/tile/kernel/compat_signal.c +++ b/arch/tile/kernel/compat_signal.c
@@ -403,19 +403,17 @@ * Set up registers for signal handler. * Registers that we don't modify keep the value they had from * user-space at the time we took the signal. + * We always pass siginfo and mcontext, regardless of SA_SIGINFO, + * since some things rely on this (e.g. glibc's debug/segfault.c). */ regs->pc = ptr_to_compat_reg(ka->sa.sa_handler); regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ regs->sp = ptr_to_compat_reg(frame); regs->lr = restorer; regs->regs[0] = (unsigned long) usig; - - if (ka->sa.sa_flags & SA_SIGINFO) { - /* Need extra arguments, so mark to restore caller-saves. */ - regs->regs[1] = ptr_to_compat_reg(&frame->info); - regs->regs[2] = ptr_to_compat_reg(&frame->uc); - regs->flags |= PT_FLAGS_CALLER_SAVES; - } + regs->regs[1] = ptr_to_compat_reg(&frame->info); + regs->regs[2] = ptr_to_compat_reg(&frame->uc); + regs->flags |= PT_FLAGS_CALLER_SAVES; /* * Notify any tracer that was single-stepping it.
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index 5d56a1e..6943515 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S
@@ -839,6 +839,18 @@ FEEDBACK_REENTER(interrupt_return) /* + * Use r33 to hold whether we have already loaded the callee-saves + * into ptregs. We don't want to do it twice in this loop, since + * then we'd clobber whatever changes are made by ptrace, etc. + * Get base of stack in r32. + */ + { + GET_THREAD_INFO(r32) + movei r33, 0 + } + +.Lretry_work_pending: + /* * Disable interrupts so as to make sure we don't * miss an interrupt that sets any of the thread flags (like * need_resched or sigpending) between sampling and the iret. @@ -848,9 +860,6 @@ IRQ_DISABLE(r20, r21) TRACE_IRQS_OFF /* Note: clobbers registers r0-r29 */ - /* Get base of stack in r32; note r30/31 are used as arguments here. */ - GET_THREAD_INFO(r32) - /* Check to see if there is any work to do before returning to user. */ { @@ -866,16 +875,18 @@ /* * Make sure we have all the registers saved for signal - * handling or single-step. Call out to C code to figure out - * exactly what we need to do for each flag bit, then if - * necessary, reload the flags and recheck. + * handling, notify-resume, or single-step. Call out to C + * code to figure out exactly what we need to do for each flag bit, + * then if necessary, reload the flags and recheck. */ - push_extra_callee_saves r0 { PTREGS_PTR(r0, PTREGS_OFFSET_BASE) - jal do_work_pending + bnz r33, 1f } - bnz r0, .Lresume_userspace + push_extra_callee_saves r0 + movei r33, 1 +1: jal do_work_pending + bnz r0, .Lretry_work_pending /* * In the NMI case we @@ -1180,10 +1191,12 @@ add r20, r20, tp lw r21, r20 addi r21, r21, 1 - sw r20, r21 + { + sw r20, r21 + GET_THREAD_INFO(r31) + } /* Trace syscalls, if requested. */ - GET_THREAD_INFO(r31) addi r31, r31, THREAD_INFO_FLAGS_OFFSET lw r30, r31 andi r30, r30, _TIF_SYSCALL_TRACE @@ -1362,7 +1375,10 @@ 3: /* set PC and continue */ lw r26, r24 - sw r28, r26 + { + sw r28, r26 + GET_THREAD_INFO(r0) + } /* * Clear TIF_SINGLESTEP to prevent recursion if we execute an ill. @@ -1370,7 +1386,6 @@ * need to clear it here and can't really impose on all other arches. * So what's another write between friends? */ - GET_THREAD_INFO(r0) addi r1, r0, THREAD_INFO_FLAGS_OFFSET {
diff --git a/arch/tile/kernel/intvec_64.S b/arch/tile/kernel/intvec_64.S index 49d9d66..30ae76e 100644 --- a/arch/tile/kernel/intvec_64.S +++ b/arch/tile/kernel/intvec_64.S
@@ -647,6 +647,20 @@ FEEDBACK_REENTER(interrupt_return) /* + * Use r33 to hold whether we have already loaded the callee-saves + * into ptregs. We don't want to do it twice in this loop, since + * then we'd clobber whatever changes are made by ptrace, etc. + */ + { + movei r33, 0 + move r32, sp + } + + /* Get base of stack in r32. */ + EXTRACT_THREAD_INFO(r32) + +.Lretry_work_pending: + /* * Disable interrupts so as to make sure we don't * miss an interrupt that sets any of the thread flags (like * need_resched or sigpending) between sampling and the iret. @@ -656,9 +670,6 @@ IRQ_DISABLE(r20, r21) TRACE_IRQS_OFF /* Note: clobbers registers r0-r29 */ - /* Get base of stack in r32; note r30/31 are used as arguments here. */ - GET_THREAD_INFO(r32) - /* Check to see if there is any work to do before returning to user. */ { @@ -674,16 +685,18 @@ /* * Make sure we have all the registers saved for signal - * handling or single-step. Call out to C code to figure out + * handling or notify-resume. Call out to C code to figure out * exactly what we need to do for each flag bit, then if * necessary, reload the flags and recheck. */ - push_extra_callee_saves r0 { PTREGS_PTR(r0, PTREGS_OFFSET_BASE) - jal do_work_pending + bnez r33, 1f } - bnez r0, .Lresume_userspace + push_extra_callee_saves r0 + movei r33, 1 +1: jal do_work_pending + bnez r0, .Lretry_work_pending /* * In the NMI case we @@ -968,11 +981,16 @@ shl16insli r20, r20, hw0(irq_stat + IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET) add r20, r20, tp ld4s r21, r20 - addi r21, r21, 1 - st4 r20, r21 + { + addi r21, r21, 1 + move r31, sp + } + { + st4 r20, r21 + EXTRACT_THREAD_INFO(r31) + } /* Trace syscalls, if requested. */ - GET_THREAD_INFO(r31) addi r31, r31, THREAD_INFO_FLAGS_OFFSET ld r30, r31 andi r30, r30, _TIF_SYSCALL_TRACE
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c index 2d5ef61..54e6c64 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c
@@ -567,6 +567,10 @@ */ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags) { + /* If we enter in kernel mode, do nothing and exit the caller loop. */ + if (!user_mode(regs)) + return 0; + if (thread_info_flags & _TIF_NEED_RESCHED) { schedule(); return 1; @@ -589,8 +593,7 @@ return 1; } if (thread_info_flags & _TIF_SINGLESTEP) { - if ((regs->ex1 & SPR_EX_CONTEXT_1_1__PL_MASK) == 0) - single_step_once(regs); + single_step_once(regs); return 0; } panic("work_pending: bad flags %#x\n", thread_info_flags);
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 1d14cc6..25f87bc 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig
@@ -77,11 +77,11 @@ select GENERIC_CLOCKEVENTS_MIN_ADJUST select IRQ_FORCED_THREADING select USE_GENERIC_SMP_HELPERS if SMP - select HAVE_BPF_JIT if (X86_64 && NET) + select HAVE_BPF_JIT if X86_64 select CLKEVT_I8253 select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_IOMAP - select DCACHE_WORD_ACCESS if !DEBUG_PAGEALLOC + select DCACHE_WORD_ACCESS config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS)
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 41a7237..94e91e4 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile
@@ -134,6 +134,9 @@ KBUILD_CFLAGS += $(mflags-y) KBUILD_AFLAGS += $(mflags-y) +archscripts: + $(Q)$(MAKE) $(build)=arch/x86/tools relocs + ### # Syscall table generation
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index fd55a2f..e398bb5 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile
@@ -40,13 +40,12 @@ $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) +targets += vmlinux.bin.all vmlinux.relocs -targets += vmlinux.bin.all vmlinux.relocs relocs -hostprogs-$(CONFIG_X86_NEED_RELOCS) += relocs - +CMD_RELOCS = arch/x86/tools/relocs quiet_cmd_relocs = RELOCS $@ - cmd_relocs = $(obj)/relocs $< > $@;$(obj)/relocs --abs-relocs $< -$(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE + cmd_relocs = $(CMD_RELOCS) $< > $@;$(CMD_RELOCS) --abs-relocs $< +$(obj)/vmlinux.relocs: vmlinux FORCE $(call if_changed,relocs) vmlinux.bin.all-y := $(obj)/vmlinux.bin
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index 4824fb4..07b3a68 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c
@@ -294,8 +294,7 @@ /* OK, This is the point of no return */ set_personality(PER_LINUX); - set_thread_flag(TIF_IA32); - current->mm->context.ia32_compat = 1; + set_personality_ia32(false); setup_new_exec(bprm);
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index 734c376..183922e 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h
@@ -170,6 +170,9 @@ unsigned int eax, ebx, ecx, edx; char signature[13]; + if (boot_cpu_data.cpuid_level < 0) + return 0; /* So we don't blow up on old processors */ + cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx); memcpy(signature + 0, &ebx, 4); memcpy(signature + 4, &ecx, 4);
diff --git a/arch/x86/include/asm/stat.h b/arch/x86/include/asm/stat.h index e0b1d9b..7b3ddc3 100644 --- a/arch/x86/include/asm/stat.h +++ b/arch/x86/include/asm/stat.h
@@ -25,6 +25,12 @@ unsigned long __unused5; }; +/* We don't need to memset the whole thing just to initialize the padding */ +#define INIT_STRUCT_STAT_PADDING(st) do { \ + st.__unused4 = 0; \ + st.__unused5 = 0; \ +} while (0) + #define STAT64_HAS_BROKEN_ST_INO 1 /* This matches struct stat64 in glibc2.1, hence the absolutely @@ -63,6 +69,12 @@ unsigned long long st_ino; }; +/* We don't need to memset the whole thing just to initialize the padding */ +#define INIT_STRUCT_STAT64_PADDING(st) do { \ + memset(&st.__pad0, 0, sizeof(st.__pad0)); \ + memset(&st.__pad3, 0, sizeof(st.__pad3)); \ +} while (0) + #else /* __i386__ */ struct stat { @@ -87,6 +99,15 @@ unsigned long st_ctime_nsec; long __unused[3]; }; + +/* We don't need to memset the whole thing just to initialize the padding */ +#define INIT_STRUCT_STAT_PADDING(st) do { \ + st.__pad0 = 0; \ + st.__unused[0] = 0; \ + st.__unused[1] = 0; \ + st.__unused[2] = 0; \ +} while (0) + #endif /* for 32bit emulation and 32 bit kernels */
diff --git a/arch/x86/include/asm/word-at-a-time.h b/arch/x86/include/asm/word-at-a-time.h index 6fe6767..e58f03b 100644 --- a/arch/x86/include/asm/word-at-a-time.h +++ b/arch/x86/include/asm/word-at-a-time.h
@@ -43,4 +43,37 @@ return ((a - REPEAT_BYTE(0x01)) & ~a) & REPEAT_BYTE(0x80); } +/* + * Load an unaligned word from kernel space. + * + * In the (very unlikely) case of the word being a page-crosser + * and the next page not being mapped, take the exception and + * return zeroes in the non-existing part. + */ +static inline unsigned long load_unaligned_zeropad(const void *addr) +{ + unsigned long ret, dummy; + + asm( + "1:\tmov %2,%0\n" + "2:\n" + ".section .fixup,\"ax\"\n" + "3:\t" + "lea %2,%1\n\t" + "and %3,%1\n\t" + "mov (%1),%0\n\t" + "leal %2,%%ecx\n\t" + "andl %4,%%ecx\n\t" + "shll $3,%%ecx\n\t" + "shr %%cl,%0\n\t" + "jmp 2b\n" + ".previous\n" + _ASM_EXTABLE(1b, 3b) + :"=&r" (ret),"=&c" (dummy) + :"m" (*(unsigned long *)addr), + "i" (-sizeof(unsigned long)), + "i" (sizeof(unsigned long)-1)); + return ret; +} + #endif /* _ASM_WORD_AT_A_TIME_H */
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index a415b1f..7c439fe 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c
@@ -593,7 +593,7 @@ #ifdef CONFIG_ACPI_HOTPLUG_CPU #include <acpi/processor.h> -static void __cpuinitdata acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) +static void __cpuinit acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) { #ifdef CONFIG_ACPI_NUMA int nid;
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 1c67ca1..146bb62 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c
@@ -580,6 +580,24 @@ } } + /* re-enable TopologyExtensions if switched off by BIOS */ + if ((c->x86 == 0x15) && + (c->x86_model >= 0x10) && (c->x86_model <= 0x1f) && + !cpu_has(c, X86_FEATURE_TOPOEXT)) { + u64 val; + + if (!rdmsrl_amd_safe(0xc0011005, &val)) { + val |= 1ULL << 54; + wrmsrl_amd_safe(0xc0011005, val); + rdmsrl(0xc0011005, val); + if (val & (1ULL << 54)) { + set_cpu_cap(c, X86_FEATURE_TOPOEXT); + printk(KERN_INFO FW_INFO "CPU: Re-enabling " + "disabled Topology Extensions Support\n"); + } + } + } + cpu_detect_cache_sizes(c); /* Multi core CPU? */
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index d086a09..11c9166c 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -945,9 +945,10 @@ atomic_t inuse; struct task_struct *t; __u64 paddr; + int restartable; } mce_info[MCE_INFO_MAX]; -static void mce_save_info(__u64 addr) +static void mce_save_info(__u64 addr, int c) { struct mce_info *mi; @@ -955,6 +956,7 @@ if (atomic_cmpxchg(&mi->inuse, 0, 1) == 0) { mi->t = current; mi->paddr = addr; + mi->restartable = c; return; } } @@ -1130,7 +1132,7 @@ mce_panic("Fatal machine check on current CPU", &m, msg); if (worst == MCE_AR_SEVERITY) { /* schedule action before return to userland */ - mce_save_info(m.addr); + mce_save_info(m.addr, m.mcgstatus & MCG_STATUS_RIPV); set_thread_flag(TIF_MCE_NOTIFY); } else if (kill_it) { force_sig(SIGBUS, current); @@ -1179,7 +1181,13 @@ pr_err("Uncorrected hardware memory error in user-access at %llx", mi->paddr); - if (memory_failure(pfn, MCE_VECTOR, MF_ACTION_REQUIRED) < 0) { + /* + * We must call memory_failure() here even if the current process is + * doomed. We still need to mark the page as poisoned and alert any + * other users of the page. + */ + if (memory_failure(pfn, MCE_VECTOR, MF_ACTION_REQUIRED) < 0 || + mi->restartable == 0) { pr_err("Memory error not recovered"); force_sig(SIGBUS, current); }
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index b8ba6e4..e554e5a 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c
@@ -79,7 +79,6 @@ u32 token; int cpu; bool halted; - struct mm_struct *mm; }; static struct kvm_task_sleep_head { @@ -126,9 +125,7 @@ n.token = token; n.cpu = smp_processor_id(); - n.mm = current->active_mm; n.halted = idle || preempt_count() > 1; - atomic_inc(&n.mm->mm_count); init_waitqueue_head(&n.wq); hlist_add_head(&n.link, &b->list); spin_unlock(&b->lock); @@ -161,9 +158,6 @@ static void apf_task_wake_one(struct kvm_task_sleep_node *n) { hlist_del_init(&n->link); - if (!n->mm) - return; - mmdrop(n->mm); if (n->halted) smp_send_reschedule(n->cpu); else if (waitqueue_active(&n->wq)) @@ -207,7 +201,7 @@ * async PF was not yet handled. * Add dummy entry for the token. */ - n = kmalloc(sizeof(*n), GFP_ATOMIC); + n = kzalloc(sizeof(*n), GFP_ATOMIC); if (!n) { /* * Allocation failed! Busy wait while other cpu @@ -219,7 +213,6 @@ } n->token = token; n->cpu = smp_processor_id(); - n->mm = NULL; init_waitqueue_head(&n->wq); hlist_add_head(&n->link, &b->list); } else
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c index 3ca42d0..0327e2b 100644 --- a/arch/x86/kernel/microcode_intel.c +++ b/arch/x86/kernel/microcode_intel.c
@@ -147,12 +147,6 @@ memset(csig, 0, sizeof(*csig)); - if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || - cpu_has(c, X86_FEATURE_IA64)) { - pr_err("CPU%d not a capable Intel processor\n", cpu_num); - return -1; - } - csig->sig = cpuid_eax(0x00000001); if ((c->x86_model >= 5) || (c->x86 > 6)) { @@ -463,6 +457,14 @@ struct microcode_ops * __init init_intel_microcode(void) { + struct cpuinfo_x86 *c = &cpu_data(0); + + if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || + cpu_has(c, X86_FEATURE_IA64)) { + pr_err("Intel CPU family 0x%x not supported\n", c->x86); + return NULL; + } + return µcode_intel_ops; }
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 733ca39..43d8b48 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c
@@ -423,6 +423,7 @@ current_thread_info()->status |= TS_COMPAT; } } +EXPORT_SYMBOL_GPL(set_personality_ia32); unsigned long get_wchan(struct task_struct *p) {
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 71f4727..5a98aa2 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c
@@ -185,10 +185,22 @@ #endif rc = -EINVAL; if (pcpu_chosen_fc != PCPU_FC_PAGE) { - const size_t atom_size = cpu_has_pse ? PMD_SIZE : PAGE_SIZE; const size_t dyn_size = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE - PERCPU_FIRST_CHUNK_RESERVE; + size_t atom_size; + /* + * On 64bit, use PMD_SIZE for atom_size so that embedded + * percpu areas are aligned to PMD. This, in the future, + * can also allow using PMD mappings in vmalloc area. Use + * PAGE_SIZE on 32bit as vmalloc space is highly contended + * and large vmalloc area allocs can easily fail. + */ +#ifdef CONFIG_X86_64 + atom_size = PMD_SIZE; +#else + atom_size = PAGE_SIZE; +#endif rc = pcpu_embed_first_chunk(PERCPU_FIRST_CHUNK_RESERVE, dyn_size, atom_size, pcpu_cpu_distance,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 91a5e98..185a2b8 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c
@@ -6581,6 +6581,7 @@ kvm_inject_page_fault(vcpu, &fault); } vcpu->arch.apf.halted = false; + vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; } bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/lib/usercopy.c b/arch/x86/lib/usercopy.c index d6ae30b..2e4e4b0 100644 --- a/arch/x86/lib/usercopy.c +++ b/arch/x86/lib/usercopy.c
@@ -44,13 +44,6 @@ } EXPORT_SYMBOL_GPL(copy_from_user_nmi); -static inline unsigned long count_bytes(unsigned long mask) -{ - mask = (mask - 1) & ~mask; - mask >>= 7; - return count_masked_bytes(mask); -} - /* * Do a strncpy, return length of string without final '\0'. * 'count' is the user-supplied count (return 'count' if we @@ -69,16 +62,19 @@ max = count; while (max >= sizeof(unsigned long)) { - unsigned long c; + unsigned long c, mask; /* Fall back to byte-at-a-time if we get a page fault */ if (unlikely(__get_user(c,(unsigned long __user *)(src+res)))) break; - /* This can write a few bytes past the NUL character, but that's ok */ + mask = has_zero(c); + if (mask) { + mask = (mask - 1) & ~mask; + mask >>= 7; + *(unsigned long *)(dst+res) = c & mask; + return res + count_masked_bytes(mask); + } *(unsigned long *)(dst+res) = c; - c = has_zero(c); - if (c) - return res + count_bytes(c); res += sizeof(unsigned long); max -= sizeof(unsigned long); }
diff --git a/arch/x86/platform/geode/net5501.c b/arch/x86/platform/geode/net5501.c index 66d377e..646e3b5 100644 --- a/arch/x86/platform/geode/net5501.c +++ b/arch/x86/platform/geode/net5501.c
@@ -63,7 +63,7 @@ .name = "net5501:1", .gpio = 6, .default_trigger = "default-on", - .active_low = 1, + .active_low = 0, }, };
diff --git a/arch/x86/tools/.gitignore b/arch/x86/tools/.gitignore new file mode 100644 index 0000000..be0ed06 --- /dev/null +++ b/arch/x86/tools/.gitignore
@@ -0,0 +1 @@ +relocs
diff --git a/arch/x86/tools/Makefile b/arch/x86/tools/Makefile index d511aa9..733057b 100644 --- a/arch/x86/tools/Makefile +++ b/arch/x86/tools/Makefile
@@ -36,3 +36,7 @@ $(obj)/test_get_len.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c $(obj)/insn_sanity.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c + +HOST_EXTRACFLAGS += -I$(srctree)/tools/include +hostprogs-y += relocs +relocs: $(obj)/relocs
diff --git a/arch/x86/boot/compressed/relocs.c b/arch/x86/tools/relocs.c similarity index 76% rename from arch/x86/boot/compressed/relocs.c rename to arch/x86/tools/relocs.c index d3c0b02..b43cfcd 100644 --- a/arch/x86/boot/compressed/relocs.c +++ b/arch/x86/tools/relocs.c
@@ -18,6 +18,8 @@ static Elf32_Ehdr ehdr; static unsigned long reloc_count, reloc_idx; static unsigned long *relocs; +static unsigned long reloc16_count, reloc16_idx; +static unsigned long *relocs16; struct section { Elf32_Shdr shdr; @@ -28,52 +30,86 @@ }; static struct section *secs; +enum symtype { + S_ABS, + S_REL, + S_SEG, + S_LIN, + S_NSYMTYPES +}; + +static const char * const sym_regex_kernel[S_NSYMTYPES] = { /* * Following symbols have been audited. There values are constant and do * not change if bzImage is loaded at a different physical address than * the address for which it has been compiled. Don't warn user about * absolute relocations present w.r.t these symbols. */ -static const char abs_sym_regex[] = + [S_ABS] = "^(xen_irq_disable_direct_reloc$|" "xen_save_fl_direct_reloc$|" "VDSO|" - "__crc_)"; -static regex_t abs_sym_regex_c; -static int is_abs_reloc(const char *sym_name) -{ - return !regexec(&abs_sym_regex_c, sym_name, 0, NULL, 0); -} + "__crc_)", /* * These symbols are known to be relative, even if the linker marks them * as absolute (typically defined outside any section in the linker script.) */ -static const char rel_sym_regex[] = - "^_end$"; -static regex_t rel_sym_regex_c; -static int is_rel_reloc(const char *sym_name) + [S_REL] = + "^(__init_(begin|end)|" + "__x86_cpu_dev_(start|end)|" + "(__parainstructions|__alt_instructions)(|_end)|" + "(__iommu_table|__apicdrivers|__smp_locks)(|_end)|" + "_end)$" +}; + + +static const char * const sym_regex_realmode[S_NSYMTYPES] = { +/* + * These are 16-bit segment symbols when compiling 16-bit code. + */ + [S_SEG] = + "^real_mode_seg$", + +/* + * These are offsets belonging to segments, as opposed to linear addresses, + * when compiling 16-bit code. + */ + [S_LIN] = + "^pa_", +}; + +static const char * const *sym_regex; + +static regex_t sym_regex_c[S_NSYMTYPES]; +static int is_reloc(enum symtype type, const char *sym_name) { - return !regexec(&rel_sym_regex_c, sym_name, 0, NULL, 0); + return sym_regex[type] && + !regexec(&sym_regex_c[type], sym_name, 0, NULL, 0); } -static void regex_init(void) +static void regex_init(int use_real_mode) { char errbuf[128]; int err; - - err = regcomp(&abs_sym_regex_c, abs_sym_regex, - REG_EXTENDED|REG_NOSUB); - if (err) { - regerror(err, &abs_sym_regex_c, errbuf, sizeof errbuf); - die("%s", errbuf); - } + int i; - err = regcomp(&rel_sym_regex_c, rel_sym_regex, - REG_EXTENDED|REG_NOSUB); - if (err) { - regerror(err, &rel_sym_regex_c, errbuf, sizeof errbuf); - die("%s", errbuf); + if (use_real_mode) + sym_regex = sym_regex_realmode; + else + sym_regex = sym_regex_kernel; + + for (i = 0; i < S_NSYMTYPES; i++) { + if (!sym_regex[i]) + continue; + + err = regcomp(&sym_regex_c[i], sym_regex[i], + REG_EXTENDED|REG_NOSUB); + + if (err) { + regerror(err, &sym_regex_c[i], errbuf, sizeof errbuf); + die("%s", errbuf); + } } } @@ -154,6 +190,10 @@ REL_TYPE(R_386_RELATIVE), REL_TYPE(R_386_GOTOFF), REL_TYPE(R_386_GOTPC), + REL_TYPE(R_386_8), + REL_TYPE(R_386_PC8), + REL_TYPE(R_386_16), + REL_TYPE(R_386_PC16), #undef REL_TYPE }; const char *name = "unknown type rel type name"; @@ -189,7 +229,7 @@ name = sym_strtab + sym->st_name; } else { - name = sec_name(secs[sym->st_shndx].shdr.sh_name); + name = sec_name(sym->st_shndx); } return name; } @@ -403,13 +443,11 @@ for (i = 0; i < ehdr.e_shnum; i++) { struct section *sec = &secs[i]; char *sym_strtab; - Elf32_Sym *sh_symtab; int j; if (sec->shdr.sh_type != SHT_SYMTAB) { continue; } - sh_symtab = sec->symtab; sym_strtab = sec->link->strtab; for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) { Elf32_Sym *sym; @@ -474,7 +512,7 @@ * Before warning check if this absolute symbol * relocation is harmless. */ - if (is_abs_reloc(name) || is_rel_reloc(name)) + if (is_reloc(S_ABS, name) || is_reloc(S_REL, name)) continue; if (!printed) { @@ -498,7 +536,8 @@ printf("\n"); } -static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) +static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym), + int use_real_mode) { int i; /* Walk through the relocations */ @@ -523,30 +562,67 @@ Elf32_Rel *rel; Elf32_Sym *sym; unsigned r_type; + const char *symname; + int shn_abs; + rel = &sec->reltab[j]; sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; r_type = ELF32_R_TYPE(rel->r_info); - /* Don't visit relocations to absolute symbols */ - if (sym->st_shndx == SHN_ABS && - !is_rel_reloc(sym_name(sym_strtab, sym))) { - continue; - } + + shn_abs = sym->st_shndx == SHN_ABS; + switch (r_type) { case R_386_NONE: case R_386_PC32: + case R_386_PC16: + case R_386_PC8: /* * NONE can be ignored and and PC relative * relocations don't need to be adjusted. */ break; + + case R_386_16: + symname = sym_name(sym_strtab, sym); + if (!use_real_mode) + goto bad; + if (shn_abs) { + if (is_reloc(S_ABS, symname)) + break; + else if (!is_reloc(S_SEG, symname)) + goto bad; + } else { + if (is_reloc(S_LIN, symname)) + goto bad; + else + break; + } + visit(rel, sym); + break; + case R_386_32: - /* Visit relocations that need to be adjusted */ + symname = sym_name(sym_strtab, sym); + if (shn_abs) { + if (is_reloc(S_ABS, symname)) + break; + else if (!is_reloc(S_REL, symname)) + goto bad; + } else { + if (use_real_mode && + !is_reloc(S_LIN, symname)) + break; + } visit(rel, sym); break; default: die("Unsupported relocation type: %s (%d)\n", rel_type(r_type), r_type); break; + bad: + symname = sym_name(sym_strtab, sym); + die("Invalid %s %s relocation: %s\n", + shn_abs ? "absolute" : "relative", + rel_type(r_type), symname); } } } @@ -554,13 +630,19 @@ static void count_reloc(Elf32_Rel *rel, Elf32_Sym *sym) { - reloc_count += 1; + if (ELF32_R_TYPE(rel->r_info) == R_386_16) + reloc16_count++; + else + reloc_count++; } static void collect_reloc(Elf32_Rel *rel, Elf32_Sym *sym) { /* Remember the address that needs to be adjusted. */ - relocs[reloc_idx++] = rel->r_offset; + if (ELF32_R_TYPE(rel->r_info) == R_386_16) + relocs16[reloc16_idx++] = rel->r_offset; + else + relocs[reloc_idx++] = rel->r_offset; } static int cmp_relocs(const void *va, const void *vb) @@ -570,23 +652,41 @@ return (*a == *b)? 0 : (*a > *b)? 1 : -1; } -static void emit_relocs(int as_text) +static int write32(unsigned int v, FILE *f) +{ + unsigned char buf[4]; + + put_unaligned_le32(v, buf); + return fwrite(buf, 1, 4, f) == 4 ? 0 : -1; +} + +static void emit_relocs(int as_text, int use_real_mode) { int i; /* Count how many relocations I have and allocate space for them. */ reloc_count = 0; - walk_relocs(count_reloc); + walk_relocs(count_reloc, use_real_mode); relocs = malloc(reloc_count * sizeof(relocs[0])); if (!relocs) { die("malloc of %d entries for relocs failed\n", reloc_count); } + + relocs16 = malloc(reloc16_count * sizeof(relocs[0])); + if (!relocs16) { + die("malloc of %d entries for relocs16 failed\n", + reloc16_count); + } /* Collect up the relocations */ reloc_idx = 0; - walk_relocs(collect_reloc); + walk_relocs(collect_reloc, use_real_mode); + + if (reloc16_count && !use_real_mode) + die("Segment relocations found but --realmode not specified\n"); /* Order the relocations for more efficient processing */ qsort(relocs, reloc_count, sizeof(relocs[0]), cmp_relocs); + qsort(relocs16, reloc16_count, sizeof(relocs16[0]), cmp_relocs); /* Print the relocations */ if (as_text) { @@ -595,58 +695,83 @@ */ printf(".section \".data.reloc\",\"a\"\n"); printf(".balign 4\n"); - for (i = 0; i < reloc_count; i++) { - printf("\t .long 0x%08lx\n", relocs[i]); + if (use_real_mode) { + printf("\t.long %lu\n", reloc16_count); + for (i = 0; i < reloc16_count; i++) + printf("\t.long 0x%08lx\n", relocs16[i]); + printf("\t.long %lu\n", reloc_count); + for (i = 0; i < reloc_count; i++) { + printf("\t.long 0x%08lx\n", relocs[i]); + } + } else { + /* Print a stop */ + printf("\t.long 0x%08lx\n", (unsigned long)0); + for (i = 0; i < reloc_count; i++) { + printf("\t.long 0x%08lx\n", relocs[i]); + } } + printf("\n"); } else { - unsigned char buf[4]; - /* Print a stop */ - fwrite("\0\0\0\0", 4, 1, stdout); - /* Now print each relocation */ - for (i = 0; i < reloc_count; i++) { - put_unaligned_le32(relocs[i], buf); - fwrite(buf, 4, 1, stdout); + if (use_real_mode) { + write32(reloc16_count, stdout); + for (i = 0; i < reloc16_count; i++) + write32(relocs16[i], stdout); + write32(reloc_count, stdout); + + /* Now print each relocation */ + for (i = 0; i < reloc_count; i++) + write32(relocs[i], stdout); + } else { + /* Print a stop */ + write32(0, stdout); + + /* Now print each relocation */ + for (i = 0; i < reloc_count; i++) { + write32(relocs[i], stdout); + } } } } static void usage(void) { - die("relocs [--abs-syms |--abs-relocs | --text] vmlinux\n"); + die("relocs [--abs-syms|--abs-relocs|--text|--realmode] vmlinux\n"); } int main(int argc, char **argv) { int show_absolute_syms, show_absolute_relocs; - int as_text; + int as_text, use_real_mode; const char *fname; FILE *fp; int i; - regex_init(); - show_absolute_syms = 0; show_absolute_relocs = 0; as_text = 0; + use_real_mode = 0; fname = NULL; for (i = 1; i < argc; i++) { char *arg = argv[i]; if (*arg == '-') { - if (strcmp(argv[1], "--abs-syms") == 0) { + if (strcmp(arg, "--abs-syms") == 0) { show_absolute_syms = 1; continue; } - - if (strcmp(argv[1], "--abs-relocs") == 0) { + if (strcmp(arg, "--abs-relocs") == 0) { show_absolute_relocs = 1; continue; } - else if (strcmp(argv[1], "--text") == 0) { + if (strcmp(arg, "--text") == 0) { as_text = 1; continue; } + if (strcmp(arg, "--realmode") == 0) { + use_real_mode = 1; + continue; + } } else if (!fname) { fname = arg; @@ -657,6 +782,7 @@ if (!fname) { usage(); } + regex_init(use_real_mode); fp = fopen(fname, "r"); if (!fp) { die("Cannot open %s: %s\n", @@ -675,6 +801,6 @@ print_absolute_relocs(); return 0; } - emit_relocs(as_text); + emit_relocs(as_text, use_real_mode); return 0; }
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index a8f8844..95dccce 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c
@@ -63,6 +63,7 @@ #include <asm/stackprotector.h> #include <asm/hypervisor.h> #include <asm/mwait.h> +#include <asm/pci_x86.h> #ifdef CONFIG_ACPI #include <linux/acpi.h> @@ -809,9 +810,40 @@ } #ifdef CONFIG_X86_LOCAL_APIC +static unsigned long xen_set_apic_id(unsigned int x) +{ + WARN_ON(1); + return x; +} +static unsigned int xen_get_apic_id(unsigned long x) +{ + return ((x)>>24) & 0xFFu; +} static u32 xen_apic_read(u32 reg) { - return 0; + struct xen_platform_op op = { + .cmd = XENPF_get_cpuinfo, + .interface_version = XENPF_INTERFACE_VERSION, + .u.pcpu_info.xen_cpuid = 0, + }; + int ret = 0; + + /* Shouldn't need this as APIC is turned off for PV, and we only + * get called on the bootup processor. But just in case. */ + if (!xen_initial_domain() || smp_processor_id()) + return 0; + + if (reg == APIC_LVR) + return 0x10; + + if (reg != APIC_ID) + return 0; + + ret = HYPERVISOR_dom0_op(&op); + if (ret) + return 0; + + return op.u.pcpu_info.apic_id << 24; } static void xen_apic_write(u32 reg, u32 val) @@ -849,6 +881,8 @@ apic->icr_write = xen_apic_icr_write; apic->wait_icr_idle = xen_apic_wait_icr_idle; apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle; + apic->set_apic_id = xen_set_apic_id; + apic->get_apic_id = xen_get_apic_id; } #endif @@ -1365,8 +1399,10 @@ /* Make sure ACS will be enabled */ pci_request_acs(); } - - +#ifdef CONFIG_PCI + /* PCI BIOS service won't work from a PV guest. */ + pci_probe &= ~PCI_PROBE_BIOS; +#endif xen_raw_console_write("about to get started...\n"); xen_setup_runstate_info(0);
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index b8e2794..69f5857 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c
@@ -353,8 +353,13 @@ { if (val & _PAGE_PRESENT) { unsigned long mfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; + unsigned long pfn = mfn_to_pfn(mfn); + pteval_t flags = val & PTE_FLAGS_MASK; - val = ((pteval_t)mfn_to_pfn(mfn) << PAGE_SHIFT) | flags; + if (unlikely(pfn == ~0)) + val = flags & ~_PAGE_PRESENT; + else + val = ((pteval_t)pfn << PAGE_SHIFT) | flags; } return val;
diff --git a/arch/xtensa/configs/common_defconfig b/arch/xtensa/configs/common_defconfig index b90038e..a182a4e 100644 --- a/arch/xtensa/configs/common_defconfig +++ b/arch/xtensa/configs/common_defconfig
@@ -333,11 +333,6 @@ # CONFIG_S2IO is not set # -# Token Ring devices -# -# CONFIG_TR is not set - -# # Wireless LAN (non-hamradio) # CONFIG_NET_RADIO=y
diff --git a/block/genhd.c b/block/genhd.c index df9816e..9cf5583 100644 --- a/block/genhd.c +++ b/block/genhd.c
@@ -743,7 +743,7 @@ struct hd_struct *part; char name_buf[BDEVNAME_SIZE]; char devt_buf[BDEVT_SIZE]; - u8 uuid[PARTITION_META_INFO_UUIDLTH * 2 + 1]; + char uuid_buf[PARTITION_META_INFO_UUIDLTH * 2 + 5]; /* * Don't show empty devices or things that have been @@ -762,14 +762,16 @@ while ((part = disk_part_iter_next(&piter))) { bool is_part0 = part == &disk->part0; - uuid[0] = 0; + uuid_buf[0] = '\0'; if (part->info) - part_unpack_uuid(part->info->uuid, uuid); + snprintf(uuid_buf, sizeof(uuid_buf), "%pU", + part->info->uuid); printk("%s%s %10llu %s %s", is_part0 ? "" : " ", bdevt_str(part_devt(part), devt_buf), (unsigned long long)part->nr_sects >> 1, - disk_name(disk, part->partno, name_buf), uuid); + disk_name(disk, part->partno, name_buf), + uuid_buf); if (is_part0) { if (disk->driverfs_dev != NULL && disk->driverfs_dev->driver != NULL)
diff --git a/block/partitions/ibm.c b/block/partitions/ibm.c index d513a07..1104aca 100644 --- a/block/partitions/ibm.c +++ b/block/partitions/ibm.c
@@ -253,7 +253,7 @@ /* Are we not supposed to report this ? */ goto out_readerr; } else - printk(KERN_WARNING "Warning, expected Label VOL1 not " + printk(KERN_INFO "Expected Label VOL1 not " "found, treating as CDL formated Disk"); }
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 3263b68..3188da3 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c
@@ -250,6 +250,10 @@ return -ENODEV; } + /* For D3cold we should execute _PS3, not _PS4. */ + if (state == ACPI_STATE_D3_COLD) + object_name[3] = '3'; + /* * Transition Power * ----------------
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 7049a7d..0500f71 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c
@@ -631,7 +631,7 @@ * We know a device's inferred power state when all the resources * required for a given D-state are 'on'. */ - for (i = ACPI_STATE_D0; i < ACPI_STATE_D3; i++) { + for (i = ACPI_STATE_D0; i < ACPI_STATE_D3_HOT; i++) { list = &device->power.states[i].resources; if (list->count < 1) continue; @@ -660,7 +660,7 @@ int acpi_power_transition(struct acpi_device *device, int state) { - int result; + int result = 0; if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) return -EINVAL; @@ -679,8 +679,11 @@ * (e.g. so the device doesn't lose power while transitioning). Then, * we dereference all power resources used in the current list. */ - result = acpi_power_on_list(&device->power.states[state].resources); - if (!result) + if (state < ACPI_STATE_D3_COLD) + result = acpi_power_on_list( + &device->power.states[state].resources); + + if (!result && device->power.state < ACPI_STATE_D3_COLD) acpi_power_off_list( &device->power.states[device->power.state].resources);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 767e2dc..85cbfdc 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c
@@ -869,7 +869,7 @@ /* * Enumerate supported power management states */ - for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) { + for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) { struct acpi_device_power_state *ps = &device->power.states[i]; char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' }; @@ -884,21 +884,18 @@ acpi_bus_add_power_resource(ps->resources.handles[j]); } - /* The exist of _PR3 indicates D3Cold support */ - if (i == ACPI_STATE_D3) { - status = acpi_get_handle(device->handle, object_name, &handle); - if (ACPI_SUCCESS(status)) - device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1; - } - /* Evaluate "_PSx" to see if we can do explicit sets */ object_name[2] = 'S'; status = acpi_get_handle(device->handle, object_name, &handle); if (ACPI_SUCCESS(status)) ps->flags.explicit_set = 1; - /* State is valid if we have some power control */ - if (ps->resources.count || ps->flags.explicit_set) + /* + * State is valid if there are means to put the device into it. + * D3hot is only valid if _PR3 present. + */ + if (ps->resources.count || + (ps->flags.explicit_set && i < ACPI_STATE_D3_HOT)) ps->flags.valid = 1; ps->power = -1; /* Unknown - driver assigned */ @@ -911,6 +908,10 @@ device->power.states[ACPI_STATE_D3].flags.valid = 1; device->power.states[ACPI_STATE_D3].power = 0; + /* Set D3cold's explicit_set flag if _PS3 exists. */ + if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set) + device->power.states[ACPI_STATE_D3_COLD].flags.explicit_set = 1; + acpi_bus_init_power(device); return 0;
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 7a3f535..bb80853 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c
@@ -775,9 +775,11 @@ map->format.parse_val(val + i); } else { for (i = 0; i < val_count; i++) { - ret = regmap_read(map, reg + i, val + (i * val_bytes)); + unsigned int ival; + ret = regmap_read(map, reg + i, &ival); if (ret != 0) return ret; + memcpy(val + (i * val_bytes), &ival, val_bytes); } }
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 8db9089..9a13e88 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c
@@ -6580,24 +6580,21 @@ static void DAC960_CreateProcEntries(DAC960_Controller_T *Controller) { - struct proc_dir_entry *StatusProcEntry; struct proc_dir_entry *ControllerProcEntry; - struct proc_dir_entry *UserCommandProcEntry; if (DAC960_ProcDirectoryEntry == NULL) { - DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL); - StatusProcEntry = proc_create("status", 0, - DAC960_ProcDirectoryEntry, - &dac960_proc_fops); + DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL); + proc_create("status", 0, DAC960_ProcDirectoryEntry, + &dac960_proc_fops); } - sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber); - ControllerProcEntry = proc_mkdir(Controller->ControllerName, - DAC960_ProcDirectoryEntry); - proc_create_data("initial_status", 0, ControllerProcEntry, &dac960_initial_status_proc_fops, Controller); - proc_create_data("current_status", 0, ControllerProcEntry, &dac960_current_status_proc_fops, Controller); - UserCommandProcEntry = proc_create_data("user_command", S_IWUSR | S_IRUSR, ControllerProcEntry, &dac960_user_command_proc_fops, Controller); - Controller->ControllerProcEntry = ControllerProcEntry; + sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber); + ControllerProcEntry = proc_mkdir(Controller->ControllerName, + DAC960_ProcDirectoryEntry); + proc_create_data("initial_status", 0, ControllerProcEntry, &dac960_initial_status_proc_fops, Controller); + proc_create_data("current_status", 0, ControllerProcEntry, &dac960_current_status_proc_fops, Controller); + proc_create_data("user_command", S_IWUSR | S_IRUSR, ControllerProcEntry, &dac960_user_command_proc_fops, Controller); + Controller->ControllerProcEntry = ControllerProcEntry; }
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index abfaaca..946166e 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c
@@ -2297,7 +2297,7 @@ return; } - if (!cap_raised(current_cap(), CAP_SYS_ADMIN)) { + if (!capable(CAP_SYS_ADMIN)) { retcode = ERR_PERM; goto fail; }
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 00f9fc9..304000c3 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -2510,8 +2510,10 @@ up(&dd->port->cmd_slot); return NULL; } - if (unlikely(*tag < 0)) + if (unlikely(*tag < 0)) { + up(&dd->port->cmd_slot); return NULL; + } return dd->port->commands[*tag].sg; }
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index ddf86b6..cdf2f54 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c
@@ -1895,6 +1895,13 @@ /* Get port open/close status on the host */ send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1); + + /* + * If a port was open at the time of suspending, we + * have to let the host know that it's still open. + */ + if (port->guest_connected) + send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 1); } return 0; }
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index ab9abb4..371f13c 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig
@@ -111,6 +111,7 @@ depends on S390 select CRYPTO_ALGAPI select CRYPTO_BLKCIPHER + select CRYPTO_DES help This is the s390 hardware accelerated implementation of the DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). @@ -164,6 +165,7 @@ select CRYPTO_ALGAPI select CRYPTO_AES select CRYPTO_BLKCIPHER2 + select CRYPTO_HASH help This driver allows you to utilize the Cryptographic Engines and Security Accelerator (CESA) which can be found on the Marvell Orion
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 445fdf8..bf0d7e4 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c
@@ -245,7 +245,9 @@ dev_vdbg(chan2dev(&atchan->chan_common), "descriptor %u complete\n", txd->cookie); - dma_cookie_complete(txd); + /* mark the descriptor as complete for non cyclic cases only */ + if (!atc_chan_is_cyclic(atchan)) + dma_cookie_complete(txd); /* move children to free_list */ list_splice_init(&desc->tx_list, &atchan->free_list);
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c index e6f133b..f6e9b57 100644 --- a/drivers/dma/ep93xx_dma.c +++ b/drivers/dma/ep93xx_dma.c
@@ -703,7 +703,9 @@ desc = ep93xx_dma_get_active(edmac); if (desc) { if (desc->complete) { - dma_cookie_complete(&desc->txd); + /* mark descriptor complete for non cyclic case only */ + if (!test_bit(EP93XX_DMA_IS_CYCLIC, &edmac->flags)) + dma_cookie_complete(&desc->txd); list_splice_init(&edmac->active, &list); } callback = desc->txd.callback;
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 2ee6e23..fa3fb21 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c
@@ -2322,7 +2322,8 @@ /* Pick up ripe tomatoes */ list_for_each_entry_safe(desc, _dt, &pch->work_list, node) if (desc->status == DONE) { - dma_cookie_complete(&desc->txd); + if (pch->cyclic) + dma_cookie_complete(&desc->txd); list_move_tail(&desc->node, &list); }
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 1adc2ec..4461540 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c
@@ -965,18 +965,15 @@ } _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv); - _gpio_rmw(base, bank->regs->irqstatus, l, - bank->regs->irqenable_inv == false); - _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->debounce_en != 0); - _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->ctrl != 0); + _gpio_rmw(base, bank->regs->irqstatus, l, !bank->regs->irqenable_inv); if (bank->regs->debounce_en) - _gpio_rmw(base, bank->regs->debounce_en, 0, 1); + __raw_writel(0, base + bank->regs->debounce_en); /* Save OE default value (0xffffffff) in the context */ bank->context.oe = __raw_readl(bank->base + bank->regs->direction); /* Initialize interface clk ungated, module enabled */ if (bank->regs->ctrl) - _gpio_rmw(base, bank->regs->ctrl, 0, 1); + __raw_writel(0, base + bank->regs->ctrl); } static __devinit void
diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index e8729cc..2cd958e 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c
@@ -230,16 +230,12 @@ static int pch_irq_type(struct irq_data *d, unsigned int type) { - u32 im; - u32 __iomem *im_reg; - u32 ien; - u32 im_pos; - int ch; - unsigned long flags; - u32 val; - int irq = d->irq; struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct pch_gpio *chip = gc->private; + u32 im, im_pos, val; + u32 __iomem *im_reg; + unsigned long flags; + int ch, irq = d->irq; ch = irq - chip->irq_base; if (irq <= chip->irq_base + 7) { @@ -270,30 +266,22 @@ case IRQ_TYPE_LEVEL_LOW: val = PCH_LEVEL_L; break; - case IRQ_TYPE_PROBE: - goto end; default: - dev_warn(chip->dev, "%s: unknown type(%dd)", - __func__, type); - goto end; + goto unlock; } /* Set interrupt mode */ im = ioread32(im_reg) & ~(PCH_IM_MASK << (im_pos * 4)); iowrite32(im | (val << (im_pos * 4)), im_reg); - /* iclr */ - iowrite32(BIT(ch), &chip->reg->iclr); + /* And the handler */ + if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) + __irq_set_handler_locked(d->irq, handle_level_irq); + else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) + __irq_set_handler_locked(d->irq, handle_edge_irq); - /* IMASKCLR */ - iowrite32(BIT(ch), &chip->reg->imaskclr); - - /* Enable interrupt */ - ien = ioread32(&chip->reg->ien); - iowrite32(ien | BIT(ch), &chip->reg->ien); -end: +unlock: spin_unlock_irqrestore(&chip->spinlock, flags); - return 0; } @@ -313,18 +301,24 @@ iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->imask); } +static void pch_irq_ack(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + struct pch_gpio *chip = gc->private; + + iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->iclr); +} + static irqreturn_t pch_gpio_handler(int irq, void *dev_id) { struct pch_gpio *chip = dev_id; u32 reg_val = ioread32(&chip->reg->istatus); - int i; - int ret = IRQ_NONE; + int i, ret = IRQ_NONE; for (i = 0; i < gpio_pins[chip->ioh]; i++) { if (reg_val & BIT(i)) { dev_dbg(chip->dev, "%s:[%d]:irq=%d status=0x%x\n", __func__, i, irq, reg_val); - iowrite32(BIT(i), &chip->reg->iclr); generic_handle_irq(chip->irq_base + i); ret = IRQ_HANDLED; } @@ -343,6 +337,7 @@ gc->private = chip; ct = gc->chip_types; + ct->chip.irq_ack = pch_irq_ack; ct->chip.irq_mask = pch_irq_mask; ct->chip.irq_unmask = pch_irq_unmask; ct->chip.irq_set_type = pch_irq_type; @@ -357,6 +352,7 @@ s32 ret; struct pch_gpio *chip; int irq_base; + u32 msk; chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) @@ -408,8 +404,13 @@ } chip->irq_base = irq_base; + /* Mask all interrupts, but enable them */ + msk = (1 << gpio_pins[chip->ioh]) - 1; + iowrite32(msk, &chip->reg->imask); + iowrite32(msk, &chip->reg->ien); + ret = request_irq(pdev->irq, pch_gpio_handler, - IRQF_SHARED, KBUILD_MODNAME, chip); + IRQF_SHARED, KBUILD_MODNAME, chip); if (ret != 0) { dev_err(&pdev->dev, "%s request_irq failed\n", __func__); @@ -418,8 +419,6 @@ pch_gpio_alloc_generic_chip(chip, irq_base, gpio_pins[chip->ioh]); - /* Initialize interrupt ien register */ - iowrite32(0, &chip->reg->ien); end: return 0;
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index 19d6fc0..e991d91 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c
@@ -452,12 +452,14 @@ }; #endif +#if defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5) static struct samsung_gpio_cfg exynos_gpio_cfg = { .set_pull = exynos_gpio_setpull, .get_pull = exynos_gpio_getpull, .set_config = samsung_gpio_setcfg_4bit, .get_config = samsung_gpio_getcfg_4bit, }; +#endif #if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450) static struct samsung_gpio_cfg s5p64x0_gpio_cfg_rbank = { @@ -2123,8 +2125,8 @@ * uses the above macro and depends on the banks being listed in order here. */ -static struct samsung_gpio_chip exynos4_gpios_1[] = { #ifdef CONFIG_ARCH_EXYNOS4 +static struct samsung_gpio_chip exynos4_gpios_1[] = { { .chip = { .base = EXYNOS4_GPA0(0), @@ -2222,11 +2224,11 @@ .label = "GPF3", }, }, -#endif }; +#endif -static struct samsung_gpio_chip exynos4_gpios_2[] = { #ifdef CONFIG_ARCH_EXYNOS4 +static struct samsung_gpio_chip exynos4_gpios_2[] = { { .chip = { .base = EXYNOS4_GPJ0(0), @@ -2367,11 +2369,11 @@ .to_irq = samsung_gpiolib_to_irq, }, }, -#endif }; +#endif -static struct samsung_gpio_chip exynos4_gpios_3[] = { #ifdef CONFIG_ARCH_EXYNOS4 +static struct samsung_gpio_chip exynos4_gpios_3[] = { { .chip = { .base = EXYNOS4_GPZ(0), @@ -2379,8 +2381,8 @@ .label = "GPZ", }, }, -#endif }; +#endif #ifdef CONFIG_ARCH_EXYNOS5 static struct samsung_gpio_chip exynos5_gpios_1[] = { @@ -2719,7 +2721,9 @@ { struct samsung_gpio_chip *chip; int i, nr_chips; +#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS5250) void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4; +#endif int group = 0; samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); @@ -2971,6 +2975,7 @@ return 0; +#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS5250) err_ioremap4: iounmap(gpio_base3); err_ioremap3: @@ -2979,6 +2984,7 @@ iounmap(gpio_base1); err_ioremap1: return -ENOMEM; +#endif } core_initcall(samsung_gpiolib_init);
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index b505b70..e6162a1 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1224,6 +1224,9 @@ unsigned long temp, chipset, gfx; int ret; + if (!IS_GEN5(dev)) + return -ENODEV; + ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret;
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 785f67f..ba60f3c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1701,6 +1701,9 @@ unsigned long diffms; u32 count; + if (dev_priv->info->gen != 5) + return; + getrawmonotonic(&now); diff1 = timespec_sub(now, dev_priv->last_time2); @@ -2121,12 +2124,14 @@ setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, (unsigned long) dev); - spin_lock(&mchdev_lock); - i915_mch_dev = dev_priv; - dev_priv->mchdev_lock = &mchdev_lock; - spin_unlock(&mchdev_lock); + if (IS_GEN5(dev)) { + spin_lock(&mchdev_lock); + i915_mch_dev = dev_priv; + dev_priv->mchdev_lock = &mchdev_lock; + spin_unlock(&mchdev_lock); - ips_ping_for_i915_load(); + ips_ping_for_i915_load(); + } return 0;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5908cd5..1b1cf3b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7072,9 +7072,6 @@ struct drm_device *dev = crtc->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - int dpll_reg = DPLL(pipe); - int dpll = I915_READ(dpll_reg); if (HAS_PCH_SPLIT(dev)) return; @@ -7087,10 +7084,15 @@ * the manual case. */ if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) { + int pipe = intel_crtc->pipe; + int dpll_reg = DPLL(pipe); + u32 dpll; + DRM_DEBUG_DRIVER("downclocking LVDS\n"); assert_panel_unlocked(dev_priv, pipe); + dpll = I915_READ(dpll_reg); dpll |= DISPLAY_RATE_SELECT_FPA1; I915_WRITE(dpll_reg, dpll); intel_wait_for_vblank(dev, pipe); @@ -7098,7 +7100,6 @@ if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); } - } /**
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index cae3e5f..2d7f47b 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -136,7 +136,7 @@ val &= ~VIDEO_DIP_SELECT_MASK; - I915_WRITE(VIDEO_DIP_CTL, val | port | flags); + I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | val | port | flags); for (i = 0; i < len; i += 4) { I915_WRITE(VIDEO_DIP_DATA, *data);
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 30e2c82..9c71183 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -750,7 +750,7 @@ .ident = "Hewlett-Packard t5745", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_BOARD_NAME, "hp t5745"), + DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"), }, }, { @@ -758,7 +758,7 @@ .ident = "Hewlett-Packard st5747", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_BOARD_NAME, "hp st5747"), + DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"), }, }, {
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 80fce51..62892a8 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -398,10 +398,8 @@ return ret; } - if (INTEL_INFO(dev)->gen >= 6) { - I915_WRITE(INSTPM, - INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING); + if (IS_GEN6(dev)) { /* From the Sandybridge PRM, volume 1 part 3, page 24: * "If this bit is set, STCunit will have LRA as replacement * policy. [...] This bit must be reset. LRA replacement @@ -411,6 +409,11 @@ CM0_STC_EVICT_DISABLE_LRA_SNB << CM0_MASK_SHIFT); } + if (INTEL_INFO(dev)->gen >= 6) { + I915_WRITE(INSTPM, + INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING); + } + return ret; }
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 232d77d..ae5e748 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1220,8 +1220,14 @@ static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo) { + struct drm_device *dev = intel_sdvo->base.base.dev; u8 response[2]; + /* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise + * on the line. */ + if (IS_I945G(dev) || IS_I945GM(dev)) + return false; + return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, &response, 2) && response[0]; }
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index e2be95a..77e5646 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c
@@ -29,10 +29,6 @@ #include "nouveau_i2c.h" #include "nouveau_hw.h" -#define T_TIMEOUT 2200000 -#define T_RISEFALL 1000 -#define T_HOLD 5000 - static void i2c_drive_scl(void *data, int state) { @@ -113,175 +109,6 @@ return 0; } -static void -i2c_delay(struct nouveau_i2c_chan *port, u32 nsec) -{ - udelay((nsec + 500) / 1000); -} - -static bool -i2c_raise_scl(struct nouveau_i2c_chan *port) -{ - u32 timeout = T_TIMEOUT / T_RISEFALL; - - i2c_drive_scl(port, 1); - do { - i2c_delay(port, T_RISEFALL); - } while (!i2c_sense_scl(port) && --timeout); - - return timeout != 0; -} - -static int -i2c_start(struct nouveau_i2c_chan *port) -{ - int ret = 0; - - port->state = i2c_sense_scl(port); - port->state |= i2c_sense_sda(port) << 1; - if (port->state != 3) { - i2c_drive_scl(port, 0); - i2c_drive_sda(port, 1); - if (!i2c_raise_scl(port)) - ret = -EBUSY; - } - - i2c_drive_sda(port, 0); - i2c_delay(port, T_HOLD); - i2c_drive_scl(port, 0); - i2c_delay(port, T_HOLD); - return ret; -} - -static void -i2c_stop(struct nouveau_i2c_chan *port) -{ - i2c_drive_scl(port, 0); - i2c_drive_sda(port, 0); - i2c_delay(port, T_RISEFALL); - - i2c_drive_scl(port, 1); - i2c_delay(port, T_HOLD); - i2c_drive_sda(port, 1); - i2c_delay(port, T_HOLD); -} - -static int -i2c_bitw(struct nouveau_i2c_chan *port, int sda) -{ - i2c_drive_sda(port, sda); - i2c_delay(port, T_RISEFALL); - - if (!i2c_raise_scl(port)) - return -ETIMEDOUT; - i2c_delay(port, T_HOLD); - - i2c_drive_scl(port, 0); - i2c_delay(port, T_HOLD); - return 0; -} - -static int -i2c_bitr(struct nouveau_i2c_chan *port) -{ - int sda; - - i2c_drive_sda(port, 1); - i2c_delay(port, T_RISEFALL); - - if (!i2c_raise_scl(port)) - return -ETIMEDOUT; - i2c_delay(port, T_HOLD); - - sda = i2c_sense_sda(port); - - i2c_drive_scl(port, 0); - i2c_delay(port, T_HOLD); - return sda; -} - -static int -i2c_get_byte(struct nouveau_i2c_chan *port, u8 *byte, bool last) -{ - int i, bit; - - *byte = 0; - for (i = 7; i >= 0; i--) { - bit = i2c_bitr(port); - if (bit < 0) - return bit; - *byte |= bit << i; - } - - return i2c_bitw(port, last ? 1 : 0); -} - -static int -i2c_put_byte(struct nouveau_i2c_chan *port, u8 byte) -{ - int i, ret; - for (i = 7; i >= 0; i--) { - ret = i2c_bitw(port, !!(byte & (1 << i))); - if (ret < 0) - return ret; - } - - ret = i2c_bitr(port); - if (ret == 1) /* nack */ - ret = -EIO; - return ret; -} - -static int -i2c_addr(struct nouveau_i2c_chan *port, struct i2c_msg *msg) -{ - u32 addr = msg->addr << 1; - if (msg->flags & I2C_M_RD) - addr |= 1; - return i2c_put_byte(port, addr); -} - -static int -i2c_bit_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) -{ - struct nouveau_i2c_chan *port = (struct nouveau_i2c_chan *)adap; - struct i2c_msg *msg = msgs; - int ret = 0, mcnt = num; - - while (!ret && mcnt--) { - u8 remaining = msg->len; - u8 *ptr = msg->buf; - - ret = i2c_start(port); - if (ret == 0) - ret = i2c_addr(port, msg); - - if (msg->flags & I2C_M_RD) { - while (!ret && remaining--) - ret = i2c_get_byte(port, ptr++, !remaining); - } else { - while (!ret && remaining--) - ret = i2c_put_byte(port, *ptr++); - } - - msg++; - } - - i2c_stop(port); - return (ret < 0) ? ret : num; -} - -static u32 -i2c_bit_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -} - -const struct i2c_algorithm nouveau_i2c_bit_algo = { - .master_xfer = i2c_bit_xfer, - .functionality = i2c_bit_func -}; - static const uint32_t nv50_i2c_port[] = { 0x00e138, 0x00e150, 0x00e168, 0x00e180, 0x00e254, 0x00e274, 0x00e764, 0x00e780, @@ -384,12 +211,10 @@ case 0: /* NV04:NV50 */ port->drive = entry[0]; port->sense = entry[1]; - port->adapter.algo = &nouveau_i2c_bit_algo; break; case 4: /* NV4E */ port->drive = 0x600800 + entry[1]; port->sense = port->drive; - port->adapter.algo = &nouveau_i2c_bit_algo; break; case 5: /* NV50- */ port->drive = entry[0] & 0x0f; @@ -402,7 +227,6 @@ port->drive = 0x00d014 + (port->drive * 0x20); port->sense = port->drive; } - port->adapter.algo = &nouveau_i2c_bit_algo; break; case 6: /* NV50- DP AUX */ port->drive = entry[0]; @@ -413,7 +237,7 @@ break; } - if (!port->adapter.algo) { + if (!port->adapter.algo && !port->drive) { NV_ERROR(dev, "I2C%d: type %d index %x/%x unknown\n", i, port->type, port->drive, port->sense); kfree(port); @@ -429,7 +253,26 @@ port->dcb = ROM32(entry[0]); i2c_set_adapdata(&port->adapter, i2c); - ret = i2c_add_adapter(&port->adapter); + if (port->adapter.algo != &nouveau_dp_i2c_algo) { + port->adapter.algo_data = &port->bit; + port->bit.udelay = 10; + port->bit.timeout = usecs_to_jiffies(2200); + port->bit.data = port; + port->bit.setsda = i2c_drive_sda; + port->bit.setscl = i2c_drive_scl; + port->bit.getsda = i2c_sense_sda; + port->bit.getscl = i2c_sense_scl; + + i2c_drive_scl(port, 0); + i2c_drive_sda(port, 1); + i2c_drive_scl(port, 1); + + ret = i2c_bit_add_bus(&port->adapter); + } else { + port->adapter.algo = &nouveau_dp_i2c_algo; + ret = i2c_add_adapter(&port->adapter); + } + if (ret) { NV_ERROR(dev, "I2C%d: failed register: %d\n", i, ret); kfree(port);
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.h b/drivers/gpu/drm/nouveau/nouveau_i2c.h index 4d2e4e9..1d08389 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.h +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.h
@@ -34,6 +34,7 @@ struct nouveau_i2c_chan { struct i2c_adapter adapter; struct drm_device *dev; + struct i2c_algo_bit_data bit; struct list_head head; u8 index; u8 type;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index ea7df16e2..5992502 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -241,8 +241,8 @@ rdev->wb.use_event = true; } } - /* always use writeback/events on NI */ - if (ASIC_IS_DCE5(rdev)) { + /* always use writeback/events on NI, APUs */ + if (rdev->family >= CHIP_PALM) { rdev->wb.enabled = true; rdev->wb.use_event = true; }
diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig index 9b9f43a..15c0640 100644 --- a/drivers/ieee802154/Kconfig +++ b/drivers/ieee802154/Kconfig
@@ -19,4 +19,12 @@ This driver can also be built as a module. To do so say M here. The module will be called 'fakehard'. +config IEEE802154_FAKELB + depends on IEEE802154_DRIVERS && MAC802154 + tristate "IEEE 802.15.4 loopback driver" + ---help--- + Say Y here to enable the fake driver that can emulate a net + of several interconnected radio devices. + This driver can also be built as a module. To do so say M here. + The module will be called 'fakelb'.
diff --git a/drivers/ieee802154/Makefile b/drivers/ieee802154/Makefile index 800a389..ea784ea 100644 --- a/drivers/ieee802154/Makefile +++ b/drivers/ieee802154/Makefile
@@ -1 +1,2 @@ obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o +obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o
diff --git a/drivers/ieee802154/fakelb.c b/drivers/ieee802154/fakelb.c new file mode 100644 index 0000000..e7456fc --- /dev/null +++ b/drivers/ieee802154/fakelb.c
@@ -0,0 +1,294 @@ +/* + * Loopback IEEE 802.15.4 interface + * + * Copyright 2007-2012 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Written by: + * Sergey Lapin <slapin@ossfans.org> + * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> + * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> + */ + +#include <linux/module.h> +#include <linux/timer.h> +#include <linux/platform_device.h> +#include <linux/netdevice.h> +#include <linux/spinlock.h> +#include <net/mac802154.h> +#include <net/wpan-phy.h> + +static int numlbs = 1; + +struct fakelb_dev_priv { + struct ieee802154_dev *dev; + + struct list_head list; + struct fakelb_priv *fake; + + spinlock_t lock; + bool working; +}; + +struct fakelb_priv { + struct list_head list; + rwlock_t lock; +}; + +static int +fakelb_hw_ed(struct ieee802154_dev *dev, u8 *level) +{ + might_sleep(); + BUG_ON(!level); + *level = 0xbe; + + return 0; +} + +static int +fakelb_hw_channel(struct ieee802154_dev *dev, int page, int channel) +{ + pr_debug("set channel to %d\n", channel); + + might_sleep(); + dev->phy->current_page = page; + dev->phy->current_channel = channel; + + return 0; +} + +static void +fakelb_hw_deliver(struct fakelb_dev_priv *priv, struct sk_buff *skb) +{ + struct sk_buff *newskb; + + spin_lock(&priv->lock); + if (priv->working) { + newskb = pskb_copy(skb, GFP_ATOMIC); + ieee802154_rx_irqsafe(priv->dev, newskb, 0xcc); + } + spin_unlock(&priv->lock); +} + +static int +fakelb_hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) +{ + struct fakelb_dev_priv *priv = dev->priv; + struct fakelb_priv *fake = priv->fake; + + might_sleep(); + + read_lock_bh(&fake->lock); + if (priv->list.next == priv->list.prev) { + /* we are the only one device */ + fakelb_hw_deliver(priv, skb); + } else { + struct fakelb_dev_priv *dp; + list_for_each_entry(dp, &priv->fake->list, list) { + if (dp != priv && + (dp->dev->phy->current_channel == + priv->dev->phy->current_channel)) + fakelb_hw_deliver(dp, skb); + } + } + read_unlock_bh(&fake->lock); + + return 0; +} + +static int +fakelb_hw_start(struct ieee802154_dev *dev) { + struct fakelb_dev_priv *priv = dev->priv; + int ret = 0; + + spin_lock(&priv->lock); + if (priv->working) + ret = -EBUSY; + else + priv->working = 1; + spin_unlock(&priv->lock); + + return ret; +} + +static void +fakelb_hw_stop(struct ieee802154_dev *dev) { + struct fakelb_dev_priv *priv = dev->priv; + + spin_lock(&priv->lock); + priv->working = 0; + spin_unlock(&priv->lock); +} + +static struct ieee802154_ops fakelb_ops = { + .owner = THIS_MODULE, + .xmit = fakelb_hw_xmit, + .ed = fakelb_hw_ed, + .set_channel = fakelb_hw_channel, + .start = fakelb_hw_start, + .stop = fakelb_hw_stop, +}; + +/* Number of dummy devices to be set up by this module. */ +module_param(numlbs, int, 0); +MODULE_PARM_DESC(numlbs, " number of pseudo devices"); + +static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake) +{ + struct fakelb_dev_priv *priv; + int err; + struct ieee802154_dev *ieee; + + ieee = ieee802154_alloc_device(sizeof(*priv), &fakelb_ops); + if (!ieee) + return -ENOMEM; + + priv = ieee->priv; + priv->dev = ieee; + + /* 868 MHz BPSK 802.15.4-2003 */ + ieee->phy->channels_supported[0] |= 1; + /* 915 MHz BPSK 802.15.4-2003 */ + ieee->phy->channels_supported[0] |= 0x7fe; + /* 2.4 GHz O-QPSK 802.15.4-2003 */ + ieee->phy->channels_supported[0] |= 0x7FFF800; + /* 868 MHz ASK 802.15.4-2006 */ + ieee->phy->channels_supported[1] |= 1; + /* 915 MHz ASK 802.15.4-2006 */ + ieee->phy->channels_supported[1] |= 0x7fe; + /* 868 MHz O-QPSK 802.15.4-2006 */ + ieee->phy->channels_supported[2] |= 1; + /* 915 MHz O-QPSK 802.15.4-2006 */ + ieee->phy->channels_supported[2] |= 0x7fe; + /* 2.4 GHz CSS 802.15.4a-2007 */ + ieee->phy->channels_supported[3] |= 0x3fff; + /* UWB Sub-gigahertz 802.15.4a-2007 */ + ieee->phy->channels_supported[4] |= 1; + /* UWB Low band 802.15.4a-2007 */ + ieee->phy->channels_supported[4] |= 0x1e; + /* UWB High band 802.15.4a-2007 */ + ieee->phy->channels_supported[4] |= 0xffe0; + /* 750 MHz O-QPSK 802.15.4c-2009 */ + ieee->phy->channels_supported[5] |= 0xf; + /* 750 MHz MPSK 802.15.4c-2009 */ + ieee->phy->channels_supported[5] |= 0xf0; + /* 950 MHz BPSK 802.15.4d-2009 */ + ieee->phy->channels_supported[6] |= 0x3ff; + /* 950 MHz GFSK 802.15.4d-2009 */ + ieee->phy->channels_supported[6] |= 0x3ffc00; + + INIT_LIST_HEAD(&priv->list); + priv->fake = fake; + + spin_lock_init(&priv->lock); + + ieee->parent = dev; + + err = ieee802154_register_device(ieee); + if (err) + goto err_reg; + + write_lock_bh(&fake->lock); + list_add_tail(&priv->list, &fake->list); + write_unlock_bh(&fake->lock); + + return 0; + +err_reg: + ieee802154_free_device(priv->dev); + return err; +} + +static void fakelb_del(struct fakelb_dev_priv *priv) +{ + write_lock_bh(&priv->fake->lock); + list_del(&priv->list); + write_unlock_bh(&priv->fake->lock); + + ieee802154_unregister_device(priv->dev); + ieee802154_free_device(priv->dev); +} + +static int __devinit fakelb_probe(struct platform_device *pdev) +{ + struct fakelb_priv *priv; + struct fakelb_dev_priv *dp; + int err = -ENOMEM; + int i; + + priv = kzalloc(sizeof(struct fakelb_priv), GFP_KERNEL); + if (!priv) + goto err_alloc; + + INIT_LIST_HEAD(&priv->list); + rwlock_init(&priv->lock); + + for (i = 0; i < numlbs; i++) { + err = fakelb_add_one(&pdev->dev, priv); + if (err < 0) + goto err_slave; + } + + platform_set_drvdata(pdev, priv); + dev_info(&pdev->dev, "added ieee802154 hardware\n"); + return 0; + +err_slave: + list_for_each_entry(dp, &priv->list, list) + fakelb_del(dp); + kfree(priv); +err_alloc: + return err; +} + +static int __devexit fakelb_remove(struct platform_device *pdev) +{ + struct fakelb_priv *priv = platform_get_drvdata(pdev); + struct fakelb_dev_priv *dp, *temp; + + list_for_each_entry_safe(dp, temp, &priv->list, list) + fakelb_del(dp); + kfree(priv); + + return 0; +} + +static struct platform_device *ieee802154fake_dev; + +static struct platform_driver ieee802154fake_driver = { + .probe = fakelb_probe, + .remove = __devexit_p(fakelb_remove), + .driver = { + .name = "ieee802154fakelb", + .owner = THIS_MODULE, + }, +}; + +static __init int fakelb_init_module(void) +{ + ieee802154fake_dev = platform_device_register_simple( + "ieee802154fakelb", -1, NULL, 0); + return platform_driver_register(&ieee802154fake_driver); +} + +static __exit void fake_remove_module(void) +{ + platform_driver_unregister(&ieee802154fake_driver); + platform_device_unregister(ieee802154fake_dev); +} + +module_init(fakelb_init_module); +module_exit(fake_remove_module); +MODULE_LICENSE("GPL");
diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c index 6bf2c58..c08fc60 100644 --- a/drivers/isdn/hardware/mISDN/avmfritz.c +++ b/drivers/isdn/hardware/mISDN/avmfritz.c
@@ -30,7 +30,7 @@ #include "ipac.h" -#define AVMFRITZ_REV "2.1" +#define AVMFRITZ_REV "2.3" static int AVM_cnt; static int debug; @@ -69,6 +69,7 @@ #define HDLC_MODE_TRANS 0x02 #define HDLC_MODE_CCR_7 0x04 #define HDLC_MODE_CCR_16 0x08 +#define HDLC_FIFO_SIZE_128 0x20 #define HDLC_MODE_TESTLOOP 0x80 #define HDLC_INT_XPR 0x80 @@ -80,13 +81,16 @@ #define HDLC_STAT_RDO 0x10 #define HDLC_STAT_CRCVFRRAB 0x0E #define HDLC_STAT_CRCVFR 0x06 -#define HDLC_STAT_RML_MASK 0x3f00 +#define HDLC_STAT_RML_MASK_V1 0x3f00 +#define HDLC_STAT_RML_MASK_V2 0x7f00 #define HDLC_CMD_XRS 0x80 #define HDLC_CMD_XME 0x01 #define HDLC_CMD_RRS 0x20 #define HDLC_CMD_XML_MASK 0x3f00 -#define HDLC_FIFO_SIZE 32 + +#define HDLC_FIFO_SIZE_V1 32 +#define HDLC_FIFO_SIZE_V2 128 /* Fritz PCI v2.0 */ @@ -346,11 +350,14 @@ { struct fritzcard *fc = bch->hw; struct hdlc_hw *hdlc; + u8 mode; hdlc = &fc->hdlc[(bch->nr - 1) & 1]; pr_debug("%s: hdlc %c protocol %x-->%x ch %d\n", fc->name, '@' + bch->nr, bch->state, protocol, bch->nr); hdlc->ctrl.ctrl = 0; + mode = (fc->type == AVM_FRITZ_PCIV2) ? HDLC_FIFO_SIZE_128 : 0; + switch (protocol) { case -1: /* used for init */ bch->state = -1; @@ -358,7 +365,7 @@ if (bch->state == ISDN_P_NONE) break; hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; - hdlc->ctrl.sr.mode = HDLC_MODE_TRANS; + hdlc->ctrl.sr.mode = mode | HDLC_MODE_TRANS; write_ctrl(bch, 5); bch->state = ISDN_P_NONE; test_and_clear_bit(FLG_HDLC, &bch->Flags); @@ -367,7 +374,7 @@ case ISDN_P_B_RAW: bch->state = protocol; hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; - hdlc->ctrl.sr.mode = HDLC_MODE_TRANS; + hdlc->ctrl.sr.mode = mode | HDLC_MODE_TRANS; write_ctrl(bch, 5); hdlc->ctrl.sr.cmd = HDLC_CMD_XRS; write_ctrl(bch, 1); @@ -377,7 +384,7 @@ case ISDN_P_B_HDLC: bch->state = protocol; hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; - hdlc->ctrl.sr.mode = HDLC_MODE_ITF_FLG; + hdlc->ctrl.sr.mode = mode | HDLC_MODE_ITF_FLG; write_ctrl(bch, 5); hdlc->ctrl.sr.cmd = HDLC_CMD_XRS; write_ctrl(bch, 1); @@ -397,39 +404,40 @@ u32 *ptr; u8 *p; u32 val, addr; - int cnt = 0; + int cnt; struct fritzcard *fc = bch->hw; pr_debug("%s: %s %d\n", fc->name, __func__, count); - if (!bch->rx_skb) { - bch->rx_skb = mI_alloc_skb(bch->maxlen, GFP_ATOMIC); - if (!bch->rx_skb) { - pr_info("%s: B receive out of memory\n", - fc->name); + if (test_bit(FLG_RX_OFF, &bch->Flags)) { + p = NULL; + bch->dropcnt += count; + } else { + cnt = bchannel_get_rxbuf(bch, count); + if (cnt < 0) { + pr_warning("%s.B%d: No bufferspace for %d bytes\n", + fc->name, bch->nr, count); return; } + p = skb_put(bch->rx_skb, count); } - if ((bch->rx_skb->len + count) > bch->maxlen) { - pr_debug("%s: overrun %d\n", fc->name, - bch->rx_skb->len + count); - return; - } - p = skb_put(bch->rx_skb, count); ptr = (u32 *)p; - if (AVM_FRITZ_PCIV2 == fc->type) + if (fc->type == AVM_FRITZ_PCIV2) addr = fc->addr + (bch->nr == 2 ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1); else { addr = fc->addr + CHIP_WINDOW; outl(bch->nr == 2 ? AVM_HDLC_2 : AVM_HDLC_1, fc->addr); } + cnt = 0; while (cnt < count) { val = le32_to_cpu(inl(addr)); - put_unaligned(val, ptr); - ptr++; + if (p) { + put_unaligned(val, ptr); + ptr++; + } cnt += 4; } - if (debug & DEBUG_HW_BFIFO) { + if (p && (debug & DEBUG_HW_BFIFO)) { snprintf(fc->log, LOG_SIZE, "B%1d-recv %s %d ", bch->nr, fc->name, count); print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count); @@ -441,30 +449,43 @@ { struct fritzcard *fc = bch->hw; struct hdlc_hw *hdlc; - int count, cnt = 0; + int count, fs, cnt = 0, idx, fillempty = 0; u8 *p; u32 *ptr, val, addr; - hdlc = &fc->hdlc[(bch->nr - 1) & 1]; - if (!bch->tx_skb) - return; - count = bch->tx_skb->len - bch->tx_idx; - if (count <= 0) - return; - p = bch->tx_skb->data + bch->tx_idx; + idx = (bch->nr - 1) & 1; + hdlc = &fc->hdlc[idx]; + fs = (fc->type == AVM_FRITZ_PCIV2) ? + HDLC_FIFO_SIZE_V2 : HDLC_FIFO_SIZE_V1; + if (!bch->tx_skb) { + if (!test_bit(FLG_TX_EMPTY, &bch->Flags)) + return; + count = fs; + p = bch->fill; + fillempty = 1; + } else { + count = bch->tx_skb->len - bch->tx_idx; + if (count <= 0) + return; + p = bch->tx_skb->data + bch->tx_idx; + } hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XME; - if (count > HDLC_FIFO_SIZE) { - count = HDLC_FIFO_SIZE; + if (count > fs) { + count = fs; } else { if (test_bit(FLG_HDLC, &bch->Flags)) hdlc->ctrl.sr.cmd |= HDLC_CMD_XME; } - pr_debug("%s: %s %d/%d/%d", fc->name, __func__, count, - bch->tx_idx, bch->tx_skb->len); ptr = (u32 *)p; - bch->tx_idx += count; - hdlc->ctrl.sr.xml = ((count == HDLC_FIFO_SIZE) ? 0 : count); - if (AVM_FRITZ_PCIV2 == fc->type) { + if (fillempty) { + pr_debug("%s.B%d: %d/%d/%d", fc->name, bch->nr, count, + bch->tx_idx, bch->tx_skb->len); + bch->tx_idx += count; + } else { + pr_debug("%s.B%d: fillempty %d\n", fc->name, bch->nr, count); + } + hdlc->ctrl.sr.xml = ((count == fs) ? 0 : count); + if (fc->type == AVM_FRITZ_PCIV2) { __write_ctrl_pciv2(fc, hdlc, bch->nr); addr = fc->addr + (bch->nr == 2 ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1); @@ -472,13 +493,21 @@ __write_ctrl_pci(fc, hdlc, bch->nr); addr = fc->addr + CHIP_WINDOW; } - while (cnt < count) { - val = get_unaligned(ptr); - outl(cpu_to_le32(val), addr); - ptr++; - cnt += 4; + if (fillempty) { + while (cnt < count) { + /* all bytes the same - no worry about endian */ + outl(*ptr, addr); + cnt += 4; + } + } else { + while (cnt < count) { + val = get_unaligned(ptr); + outl(cpu_to_le32(val), addr); + ptr++; + cnt += 4; + } } - if (debug & DEBUG_HW_BFIFO) { + if ((debug & DEBUG_HW_BFIFO) && !fillempty) { snprintf(fc->log, LOG_SIZE, "B%1d-send %s %d ", bch->nr, fc->name, count); print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count); @@ -488,17 +517,17 @@ static void HDLC_irq_xpr(struct bchannel *bch) { - if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len) + if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len) { hdlc_fill_fifo(bch); - else { - if (bch->tx_skb) { - /* send confirm, on trans, free on hdlc. */ - if (test_bit(FLG_TRANSPARENT, &bch->Flags)) - confirm_Bsend(bch); + } else { + if (bch->tx_skb) dev_kfree_skb(bch->tx_skb); - } - if (get_next_bframe(bch)) + if (get_next_bframe(bch)) { hdlc_fill_fifo(bch); + test_and_clear_bit(FLG_TX_EMPTY, &bch->Flags); + } else if (test_bit(FLG_TX_EMPTY, &bch->Flags)) { + hdlc_fill_fifo(bch); + } } } @@ -506,13 +535,23 @@ HDLC_irq(struct bchannel *bch, u32 stat) { struct fritzcard *fc = bch->hw; - int len; + int len, fs; + u32 rmlMask; struct hdlc_hw *hdlc; hdlc = &fc->hdlc[(bch->nr - 1) & 1]; pr_debug("%s: ch%d stat %#x\n", fc->name, bch->nr, stat); + if (fc->type == AVM_FRITZ_PCIV2) { + rmlMask = HDLC_STAT_RML_MASK_V2; + fs = HDLC_FIFO_SIZE_V2; + } else { + rmlMask = HDLC_STAT_RML_MASK_V1; + fs = HDLC_FIFO_SIZE_V1; + } if (stat & HDLC_INT_RPR) { if (stat & HDLC_STAT_RDO) { + pr_warning("%s: ch%d stat %x RDO\n", + fc->name, bch->nr, stat); hdlc->ctrl.sr.xml = 0; hdlc->ctrl.sr.cmd |= HDLC_CMD_RRS; write_ctrl(bch, 1); @@ -521,21 +560,21 @@ if (bch->rx_skb) skb_trim(bch->rx_skb, 0); } else { - len = (stat & HDLC_STAT_RML_MASK) >> 8; + len = (stat & rmlMask) >> 8; if (!len) - len = 32; + len = fs; hdlc_empty_fifo(bch, len); if (!bch->rx_skb) goto handle_tx; - if ((stat & HDLC_STAT_RME) || test_bit(FLG_TRANSPARENT, - &bch->Flags)) { - if (((stat & HDLC_STAT_CRCVFRRAB) == - HDLC_STAT_CRCVFR) || - test_bit(FLG_TRANSPARENT, &bch->Flags)) { - recv_Bchannel(bch, 0); + if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { + recv_Bchannel(bch, 0, false); + } else if (stat & HDLC_STAT_RME) { + if ((stat & HDLC_STAT_CRCVFRRAB) == + HDLC_STAT_CRCVFR) { + recv_Bchannel(bch, 0, false); } else { - pr_debug("%s: got invalid frame\n", - fc->name); + pr_warning("%s: got invalid frame\n", + fc->name); skb_trim(bch->rx_skb, 0); } } @@ -547,16 +586,13 @@ * restart transmitting the whole frame on HDLC * in transparent mode we send the next data */ - if (bch->tx_skb) - pr_debug("%s: ch%d XDU len(%d) idx(%d) Flags(%lx)\n", - fc->name, bch->nr, bch->tx_skb->len, - bch->tx_idx, bch->Flags); - else - pr_debug("%s: ch%d XDU no tx_skb Flags(%lx)\n", - fc->name, bch->nr, bch->Flags); + pr_warning("%s: ch%d stat %x XDU %s\n", fc->name, bch->nr, + stat, bch->tx_skb ? "tx_skb" : "no tx_skb"); if (bch->tx_skb && bch->tx_skb->len) { if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) bch->tx_idx = 0; + } else if (test_bit(FLG_FILLEMPTY, &bch->Flags)) { + test_and_set_bit(FLG_TX_EMPTY, &bch->Flags); } hdlc->ctrl.sr.xml = 0; hdlc->ctrl.sr.cmd |= HDLC_CMD_XRS; @@ -659,22 +695,17 @@ struct fritzcard *fc = bch->hw; int ret = -EINVAL; struct mISDNhead *hh = mISDN_HEAD_P(skb); - u32 id; - u_long flags; + unsigned long flags; switch (hh->prim) { case PH_DATA_REQ: spin_lock_irqsave(&fc->lock, flags); ret = bchannel_senddata(bch, skb); if (ret > 0) { /* direct TX */ - id = hh->id; /* skb can be freed */ hdlc_fill_fifo(bch); ret = 0; - spin_unlock_irqrestore(&fc->lock, flags); - if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) - queue_ch_frame(ch, PH_DATA_CNF, id, NULL); - } else - spin_unlock_irqrestore(&fc->lock, flags); + } + spin_unlock_irqrestore(&fc->lock, flags); return ret; case PH_ACTIVATE_REQ: spin_lock_irqsave(&fc->lock, flags); @@ -783,7 +814,7 @@ inithdlc(fc); enable_hwirq(fc); /* RESET Receiver and Transmitter */ - if (AVM_FRITZ_PCIV2 == fc->type) { + if (fc->type == AVM_FRITZ_PCIV2) { WriteISAC_V2(fc, ISACX_MASK, 0); WriteISAC_V2(fc, ISACX_CMDRD, 0x41); } else { @@ -810,21 +841,7 @@ static int channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) { - int ret = 0; - struct fritzcard *fc = bch->hw; - - switch (cq->op) { - case MISDN_CTRL_GETOP: - cq->op = 0; - break; - /* Nothing implemented yet */ - case MISDN_CTRL_FILL_EMPTY: - default: - pr_info("%s: %s unknown Op %x\n", fc->name, __func__, cq->op); - ret = -EINVAL; - break; - } - return ret; + return mISDN_ctrl_bchannel(bch, cq); } static int @@ -839,14 +856,10 @@ switch (cmd) { case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - if (test_bit(FLG_ACTIVE, &bch->Flags)) { - spin_lock_irqsave(&fc->lock, flags); - mISDN_freebchannel(bch); - test_and_clear_bit(FLG_TX_BUSY, &bch->Flags); - test_and_clear_bit(FLG_ACTIVE, &bch->Flags); - modehdlc(bch, ISDN_P_NONE); - spin_unlock_irqrestore(&fc->lock, flags); - } + spin_lock_irqsave(&fc->lock, flags); + mISDN_freebchannel(bch); + modehdlc(bch, ISDN_P_NONE); + spin_unlock_irqrestore(&fc->lock, flags); ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(THIS_MODULE); @@ -901,7 +914,6 @@ bch = &fc->bch[rq->adr.channel - 1]; if (test_and_set_bit(FLG_OPEN, &bch->Flags)) return -EBUSY; /* b-channel can be only open once */ - test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); bch->ch.protocol = rq->protocol; rq->ch = &bch->ch; return 0; @@ -1024,6 +1036,7 @@ setup_instance(struct fritzcard *card) { int i, err; + unsigned short minsize; u_long flags; snprintf(card->name, MISDN_MAX_IDLEN - 1, "AVM.%d", AVM_cnt + 1); @@ -1043,7 +1056,11 @@ for (i = 0; i < 2; i++) { card->bch[i].nr = i + 1; set_channelmap(i + 1, card->isac.dch.dev.channelmap); - mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM); + if (AVM_FRITZ_PCIV2 == card->type) + minsize = HDLC_FIFO_SIZE_V2; + else + minsize = HDLC_FIFO_SIZE_V1; + mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, minsize); card->bch[i].hw = card; card->bch[i].ch.send = avm_l2l1B; card->bch[i].ch.ctrl = avm_bctrl;
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index 4c128e4..5e402cf2 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -1171,7 +1171,7 @@ hc->DTMFbase = 0x1000; if (test_bit(HFC_CHIP_EXRAM_128, &hc->chip)) { if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: changing to 128K extenal RAM\n", + printk(KERN_DEBUG "%s: changing to 128K external RAM\n", __func__); hc->hw.r_ctrl |= V_EXT_RAM; hc->hw.r_ram_sz = 1; @@ -1182,7 +1182,7 @@ } if (test_bit(HFC_CHIP_EXRAM_512, &hc->chip)) { if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: changing to 512K extenal RAM\n", + printk(KERN_DEBUG "%s: changing to 512K external RAM\n", __func__); hc->hw.r_ctrl |= V_EXT_RAM; hc->hw.r_ram_sz = 2; @@ -2166,13 +2166,9 @@ HFC_wait_nodebug(hc); } - /* send confirm, since get_net_bframe will not do it with trans */ - if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags)) - confirm_Bsend(bch); - - /* check for next frame */ dev_kfree_skb(*sp); - if (bch && get_next_bframe(bch)) { /* hdlc is confirmed here */ + /* check for next frame */ + if (bch && get_next_bframe(bch)) { len = (*sp)->len; goto next_frame; } @@ -2200,24 +2196,20 @@ int f1 = 0, f2 = 0; /* = 0, to make GCC happy */ int again = 0; struct bchannel *bch; - struct dchannel *dch; + struct dchannel *dch = NULL; struct sk_buff *skb, **sp = NULL; int maxlen; bch = hc->chan[ch].bch; - dch = hc->chan[ch].dch; - if ((!dch) && (!bch)) - return; - if (dch) { - if (!test_bit(FLG_ACTIVE, &dch->Flags)) - return; - sp = &dch->rx_skb; - maxlen = dch->maxlen; - } else { + if (bch) { if (!test_bit(FLG_ACTIVE, &bch->Flags)) return; - sp = &bch->rx_skb; - maxlen = bch->maxlen; + } else if (hc->chan[ch].dch) { + dch = hc->chan[ch].dch; + if (!test_bit(FLG_ACTIVE, &dch->Flags)) + return; + } else { + return; } next_frame: /* on first AND before getting next valid frame, R_FIFO must be written @@ -2232,8 +2224,11 @@ HFC_wait_nodebug(hc); /* ignore if rx is off BUT change fifo (above) to start pending TX */ - if (hc->chan[ch].rx_off) + if (hc->chan[ch].rx_off) { + if (bch) + bch->dropcnt += poll; /* not exact but fair enough */ return; + } if (dch || test_bit(FLG_HDLC, &bch->Flags)) { f1 = HFC_inb_nodebug(hc, A_F1); @@ -2264,13 +2259,26 @@ if (Zsize <= 0) return; - if (*sp == NULL) { - *sp = mI_alloc_skb(maxlen + 3, GFP_ATOMIC); - if (*sp == NULL) { - printk(KERN_DEBUG "%s: No mem for rx_skb\n", - __func__); + if (bch) { + maxlen = bchannel_get_rxbuf(bch, Zsize); + if (maxlen < 0) { + pr_warning("card%d.B%d: No bufferspace for %d bytes\n", + hc->id + 1, bch->nr, Zsize); return; } + sp = &bch->rx_skb; + maxlen = bch->maxlen; + } else { /* Dchannel */ + sp = &dch->rx_skb; + maxlen = dch->maxlen + 3; + if (*sp == NULL) { + *sp = mI_alloc_skb(maxlen, GFP_ATOMIC); + if (*sp == NULL) { + pr_warning("card%d: No mem for dch rx_skb\n", + hc->id + 1); + return; + } + } } /* show activity */ if (dch) @@ -2285,7 +2293,7 @@ Zsize, z1, z2, (f1 == f2) ? "fragment" : "COMPLETE", f1, f2, Zsize + (*sp)->len, again); /* HDLC */ - if ((Zsize + (*sp)->len) > (maxlen + 3)) { + if ((Zsize + (*sp)->len) > maxlen) { if (debug & DEBUG_HFCMULTI_FIFO) printk(KERN_DEBUG "%s(card %d): hdlc-frame too large.\n", @@ -2347,7 +2355,7 @@ if (dch) recv_Dchannel(dch); else - recv_Bchannel(bch, MISDN_ID_ANY); + recv_Bchannel(bch, MISDN_ID_ANY, false); *sp = skb; again++; goto next_frame; @@ -2355,32 +2363,14 @@ /* there is an incomplete frame */ } else { /* transparent */ - if (Zsize > skb_tailroom(*sp)) - Zsize = skb_tailroom(*sp); hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize); - if (((*sp)->len) < MISDN_COPY_SIZE) { - skb = *sp; - *sp = mI_alloc_skb(skb->len, GFP_ATOMIC); - if (*sp) { - memcpy(skb_put(*sp, skb->len), - skb->data, skb->len); - skb_trim(skb, 0); - } else { - printk(KERN_DEBUG "%s: No mem\n", __func__); - *sp = skb; - skb = NULL; - } - } else { - skb = NULL; - } if (debug & DEBUG_HFCMULTI_FIFO) printk(KERN_DEBUG "%s(card %d): fifo(%d) reading %d bytes " "(z1=%04x, z2=%04x) TRANS\n", __func__, hc->id + 1, ch, Zsize, z1, z2); /* only bch is transparent */ - recv_Bchannel(bch, hc->chan[ch].Zfill); - *sp = skb; + recv_Bchannel(bch, hc->chan[ch].Zfill, false); } } @@ -3482,8 +3472,7 @@ struct hfc_multi *hc = bch->hw; int ret = -EINVAL; struct mISDNhead *hh = mISDN_HEAD_P(skb); - unsigned int id; - u_long flags; + unsigned long flags; switch (hh->prim) { case PH_DATA_REQ: @@ -3492,19 +3481,13 @@ spin_lock_irqsave(&hc->lock, flags); ret = bchannel_senddata(bch, skb); if (ret > 0) { /* direct TX */ - id = hh->id; /* skb can be freed */ hfcmulti_tx(hc, bch->slot); ret = 0; /* start fifo */ HFC_outb_nodebug(hc, R_FIFO, 0); HFC_wait_nodebug(hc); - if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) { - spin_unlock_irqrestore(&hc->lock, flags); - queue_ch_frame(ch, PH_DATA_CNF, id, NULL); - } else - spin_unlock_irqrestore(&hc->lock, flags); - } else - spin_unlock_irqrestore(&hc->lock, flags); + } + spin_unlock_irqrestore(&hc->lock, flags); return ret; case PH_ACTIVATE_REQ: if (debug & DEBUG_HFCMULTI_MSG) @@ -3594,10 +3577,11 @@ switch (cq->op) { case MISDN_CTRL_GETOP: - cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP - | MISDN_CTRL_RX_OFF | MISDN_CTRL_FILL_EMPTY; + ret = mISDN_ctrl_bchannel(bch, cq); + cq->op |= MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP; break; case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */ + ret = mISDN_ctrl_bchannel(bch, cq); hc->chan[bch->slot].rx_off = !!cq->p1; if (!hc->chan[bch->slot].rx_off) { /* reset fifo on rx on */ @@ -3610,11 +3594,10 @@ printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n", __func__, bch->nr, hc->chan[bch->slot].rx_off); break; - case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */ - test_and_set_bit(FLG_FILLEMPTY, &bch->Flags); - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d " - "off=%d)\n", __func__, bch->nr, !!cq->p1); + case MISDN_CTRL_FILL_EMPTY: + ret = mISDN_ctrl_bchannel(bch, cq); + hc->silence = bch->fill[0]; + memset(hc->silence_data, hc->silence, sizeof(hc->silence_data)); break; case MISDN_CTRL_HW_FEATURES: /* fill features structure */ if (debug & DEBUG_HFCMULTI_MSG) @@ -3703,9 +3686,7 @@ ret = -EINVAL; break; default: - printk(KERN_WARNING "%s: unknown Op %x\n", - __func__, cq->op); - ret = -EINVAL; + ret = mISDN_ctrl_bchannel(bch, cq); break; } return ret; @@ -3725,8 +3706,7 @@ switch (cmd) { case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - if (test_bit(FLG_ACTIVE, &bch->Flags)) - deactivate_bchannel(bch); /* locked there */ + deactivate_bchannel(bch); /* locked there */ ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(THIS_MODULE); @@ -4140,7 +4120,6 @@ } if (test_and_set_bit(FLG_OPEN, &bch->Flags)) return -EBUSY; /* b-channel can be only open once */ - test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); bch->ch.protocol = rq->protocol; hc->chan[ch].rx_off = 0; rq->ch = &bch->ch; @@ -4876,7 +4855,7 @@ bch->nr = ch; bch->slot = ch; bch->debug = debug; - mISDN_initbchannel(bch, MAX_DATA_MEM); + mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1); bch->hw = hc; bch->ch.send = handle_bmsg; bch->ch.ctrl = hfcm_bctrl; @@ -4949,7 +4928,7 @@ bch->nr = ch + 1; bch->slot = i + ch; bch->debug = debug; - mISDN_initbchannel(bch, MAX_DATA_MEM); + mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1); bch->hw = hc; bch->ch.send = handle_bmsg; bch->ch.ctrl = hfcm_bctrl;
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index 5fe993e..81363ff 100644 --- a/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -453,7 +453,7 @@ } bz->za[new_f2].z2 = cpu_to_le16(new_z2); bz->f2 = new_f2; /* next buffer */ - recv_Bchannel(bch, MISDN_ID_ANY); + recv_Bchannel(bch, MISDN_ID_ANY, false); } } @@ -565,11 +565,6 @@ if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) new_z2 -= B_FIFO_SIZE; /* buffer wrap */ - if (fcnt_rx > MAX_DATA_SIZE) { /* flush, if oversized */ - *z2r = cpu_to_le16(new_z2); /* new position */ - return; - } - fcnt_tx = le16_to_cpu(*z2t) - le16_to_cpu(*z1t); if (fcnt_tx <= 0) fcnt_tx += B_FIFO_SIZE; @@ -577,8 +572,16 @@ fcnt_tx = B_FIFO_SIZE - fcnt_tx; /* remaining bytes to send (bytes in tx-fifo) */ - bch->rx_skb = mI_alloc_skb(fcnt_rx, GFP_ATOMIC); - if (bch->rx_skb) { + if (test_bit(FLG_RX_OFF, &bch->Flags)) { + bch->dropcnt += fcnt_rx; + *z2r = cpu_to_le16(new_z2); + return; + } + maxlen = bchannel_get_rxbuf(bch, fcnt_rx); + if (maxlen < 0) { + pr_warning("B%d: No bufferspace for %d bytes\n", + bch->nr, fcnt_rx); + } else { ptr = skb_put(bch->rx_skb, fcnt_rx); if (le16_to_cpu(*z2r) + fcnt_rx <= B_FIFO_SIZE + B_SUB_VAL) maxlen = fcnt_rx; /* complete transfer */ @@ -596,10 +599,8 @@ ptr1 = bdata; /* start of buffer */ memcpy(ptr, ptr1, fcnt_rx); /* rest */ } - recv_Bchannel(bch, fcnt_tx); /* bch, id */ - } else - printk(KERN_WARNING "HFCPCI: receive out of memory\n"); - + recv_Bchannel(bch, fcnt_tx, false); /* bch, id, !force */ + } *z2r = cpu_to_le16(new_z2); /* new position */ } @@ -760,9 +761,14 @@ if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO)) printk(KERN_DEBUG "%s\n", __func__); - if ((!bch->tx_skb) || bch->tx_skb->len <= 0) - return; - count = bch->tx_skb->len - bch->tx_idx; + if ((!bch->tx_skb) || bch->tx_skb->len == 0) { + if (!test_bit(FLG_FILLEMPTY, &bch->Flags) && + !test_bit(FLG_TRANSPARENT, &bch->Flags)) + return; + count = HFCPCI_FILLEMPTY; + } else { + count = bch->tx_skb->len - bch->tx_idx; + } if ((bch->nr & 2) && (!hc->hw.bswapped)) { bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2; bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.txdat_b2; @@ -781,16 +787,10 @@ fcnt = le16_to_cpu(*z2t) - le16_to_cpu(*z1t); if (fcnt <= 0) fcnt += B_FIFO_SIZE; - /* fcnt contains available bytes in fifo */ - fcnt = B_FIFO_SIZE - fcnt; - /* remaining bytes to send (bytes in fifo) */ - - /* "fill fifo if empty" feature */ - if (test_bit(FLG_FILLEMPTY, &bch->Flags) && !fcnt) { - /* printk(KERN_DEBUG "%s: buffer empty, so we have " - "underrun\n", __func__); */ - /* fill buffer, to prevent future underrun */ - count = HFCPCI_FILLEMPTY; + if (test_bit(FLG_FILLEMPTY, &bch->Flags)) { + /* fcnt contains available bytes in fifo */ + if (count > fcnt) + count = fcnt; new_z1 = le16_to_cpu(*z1t) + count; /* new buffer Position */ if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) @@ -802,17 +802,20 @@ printk(KERN_DEBUG "hfcpci_FFt fillempty " "fcnt(%d) maxl(%d) nz1(%x) dst(%p)\n", fcnt, maxlen, new_z1, dst); - fcnt += count; if (maxlen > count) maxlen = count; /* limit size */ - memset(dst, 0x2a, maxlen); /* first copy */ + memset(dst, bch->fill[0], maxlen); /* first copy */ count -= maxlen; /* remaining bytes */ if (count) { dst = bdata; /* start of buffer */ - memset(dst, 0x2a, count); + memset(dst, bch->fill[0], count); } *z1t = cpu_to_le16(new_z1); /* now send data */ + return; } + /* fcnt contains available bytes in fifo */ + fcnt = B_FIFO_SIZE - fcnt; + /* remaining bytes to send (bytes in fifo) */ next_t_frame: count = bch->tx_skb->len - bch->tx_idx; @@ -849,9 +852,6 @@ *z1t = cpu_to_le16(new_z1); /* now send data */ if (bch->tx_idx < bch->tx_skb->len) return; - /* send confirm, on trans, free on hdlc. */ - if (test_bit(FLG_TRANSPARENT, &bch->Flags)) - confirm_Bsend(bch); dev_kfree_skb(bch->tx_skb); if (get_next_bframe(bch)) goto next_t_frame; @@ -1533,24 +1533,7 @@ static int channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) { - int ret = 0; - - switch (cq->op) { - case MISDN_CTRL_GETOP: - cq->op = MISDN_CTRL_FILL_EMPTY; - break; - case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */ - test_and_set_bit(FLG_FILLEMPTY, &bch->Flags); - if (debug & DEBUG_HW_OPEN) - printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d " - "off=%d)\n", __func__, bch->nr, !!cq->p1); - break; - default: - printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op); - ret = -EINVAL; - break; - } - return ret; + return mISDN_ctrl_bchannel(bch, cq); } static int hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg) @@ -1581,8 +1564,7 @@ break; case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - if (test_bit(FLG_ACTIVE, &bch->Flags)) - deactivate_bchannel(bch); + deactivate_bchannel(bch); ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(THIS_MODULE); @@ -1692,22 +1674,17 @@ struct hfc_pci *hc = bch->hw; int ret = -EINVAL; struct mISDNhead *hh = mISDN_HEAD_P(skb); - unsigned int id; - u_long flags; + unsigned long flags; switch (hh->prim) { case PH_DATA_REQ: spin_lock_irqsave(&hc->lock, flags); ret = bchannel_senddata(bch, skb); if (ret > 0) { /* direct TX */ - id = hh->id; /* skb can be freed */ hfcpci_fill_fifo(bch); ret = 0; - spin_unlock_irqrestore(&hc->lock, flags); - if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) - queue_ch_frame(ch, PH_DATA_CNF, id, NULL); - } else - spin_unlock_irqrestore(&hc->lock, flags); + } + spin_unlock_irqrestore(&hc->lock, flags); return ret; case PH_ACTIVATE_REQ: spin_lock_irqsave(&hc->lock, flags); @@ -1972,7 +1949,6 @@ bch = &hc->bch[rq->adr.channel - 1]; if (test_and_set_bit(FLG_OPEN, &bch->Flags)) return -EBUSY; /* b-channel can be only open once */ - test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); bch->ch.protocol = rq->protocol; rq->ch = &bch->ch; /* TODO: E-channel */ if (!try_module_get(THIS_MODULE)) @@ -2124,7 +2100,7 @@ card->bch[i].nr = i + 1; set_channelmap(i + 1, card->dch.dev.channelmap); card->bch[i].debug = debug; - mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM); + mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, poll >> 1); card->bch[i].hw = card; card->bch[i].ch.send = hfcpci_l2l1B; card->bch[i].ch.ctrl = hfc_bctrl;
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c index 8cde2a0..83206e4 100644 --- a/drivers/isdn/hardware/mISDN/hfcsusb.c +++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -226,19 +226,12 @@ if (debug & DBG_HFC_CALL_TRACE) printk(KERN_DEBUG "%s: %s PH_DATA_REQ ret(%i)\n", hw->name, __func__, ret); - if (ret > 0) { - /* - * other l1 drivers don't send early confirms on - * transp data, but hfcsusb does because tx_next - * skb is needed in tx_iso_complete() - */ - queue_ch_frame(ch, PH_DATA_CNF, hh->id, NULL); + if (ret > 0) ret = 0; - } return ret; case PH_ACTIVATE_REQ: if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) { - hfcsusb_start_endpoint(hw, bch->nr); + hfcsusb_start_endpoint(hw, bch->nr - 1); ret = hfcsusb_setup_bch(bch, ch->protocol); } else ret = 0; @@ -498,16 +491,9 @@ bch = &hw->bch[rq->adr.channel - 1]; if (test_and_set_bit(FLG_OPEN, &bch->Flags)) return -EBUSY; /* b-channel can be only open once */ - test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); bch->ch.protocol = rq->protocol; rq->ch = &bch->ch; - /* start USB endpoint for bchannel */ - if (rq->adr.channel == 1) - hfcsusb_start_endpoint(hw, HFC_CHAN_B1); - else - hfcsusb_start_endpoint(hw, HFC_CHAN_B2); - if (!try_module_get(THIS_MODULE)) printk(KERN_WARNING "%s: %s:cannot get module\n", hw->name, __func__); @@ -819,24 +805,7 @@ static int channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) { - int ret = 0; - - switch (cq->op) { - case MISDN_CTRL_GETOP: - cq->op = MISDN_CTRL_FILL_EMPTY; - break; - case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */ - test_and_set_bit(FLG_FILLEMPTY, &bch->Flags); - if (debug & DEBUG_HW_OPEN) - printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d " - "off=%d)\n", __func__, bch->nr, !!cq->p1); - break; - default: - printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op); - ret = -EINVAL; - break; - } - return ret; + return mISDN_ctrl_bchannel(bch, cq); } /* collect data from incoming interrupt or isochron USB data */ @@ -873,7 +842,21 @@ hdlc = 1; } if (fifo->bch) { + if (test_bit(FLG_RX_OFF, &fifo->bch->Flags)) { + fifo->bch->dropcnt += len; + spin_unlock(&hw->lock); + return; + } + maxlen = bchannel_get_rxbuf(fifo->bch, len); rx_skb = fifo->bch->rx_skb; + if (maxlen < 0) { + if (rx_skb) + skb_trim(rx_skb, 0); + pr_warning("%s.B%d: No bufferspace for %d bytes\n", + hw->name, fifo->bch->nr, len); + spin_unlock(&hw->lock); + return; + } maxlen = fifo->bch->maxlen; hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags); } @@ -883,25 +866,22 @@ hdlc = 1; } - if (!rx_skb) { - rx_skb = mI_alloc_skb(maxlen, GFP_ATOMIC); - if (rx_skb) { - if (fifo->dch) - fifo->dch->rx_skb = rx_skb; - if (fifo->bch) - fifo->bch->rx_skb = rx_skb; - if (fifo->ech) - fifo->ech->rx_skb = rx_skb; - skb_trim(rx_skb, 0); - } else { - printk(KERN_DEBUG "%s: %s: No mem for rx_skb\n", - hw->name, __func__); - spin_unlock(&hw->lock); - return; - } - } - if (fifo->dch || fifo->ech) { + if (!rx_skb) { + rx_skb = mI_alloc_skb(maxlen, GFP_ATOMIC); + if (rx_skb) { + if (fifo->dch) + fifo->dch->rx_skb = rx_skb; + if (fifo->ech) + fifo->ech->rx_skb = rx_skb; + skb_trim(rx_skb, 0); + } else { + printk(KERN_DEBUG "%s: %s: No mem for rx_skb\n", + hw->name, __func__); + spin_unlock(&hw->lock); + return; + } + } /* D/E-Channel SKB range check */ if ((rx_skb->len + len) >= MAX_DFRAME_LEN_L1) { printk(KERN_DEBUG "%s: %s: sbk mem exceeded " @@ -911,16 +891,6 @@ spin_unlock(&hw->lock); return; } - } else if (fifo->bch) { - /* B-Channel SKB range check */ - if ((rx_skb->len + len) >= (MAX_BCH_SIZE + 3)) { - printk(KERN_DEBUG "%s: %s: sbk mem exceeded " - "for fifo(%d) HFCUSB_B_RX\n", - hw->name, __func__, fifon); - skb_trim(rx_skb, 0); - spin_unlock(&hw->lock); - return; - } } memcpy(skb_put(rx_skb, len), data, len); @@ -948,7 +918,8 @@ if (fifo->dch) recv_Dchannel(fifo->dch); if (fifo->bch) - recv_Bchannel(fifo->bch, MISDN_ID_ANY); + recv_Bchannel(fifo->bch, MISDN_ID_ANY, + 0); if (fifo->ech) recv_Echannel(fifo->ech, &hw->dch); @@ -969,8 +940,7 @@ } } else { /* deliver transparent data to layer2 */ - if (rx_skb->len >= poll) - recv_Bchannel(fifo->bch, MISDN_ID_ANY); + recv_Bchannel(fifo->bch, MISDN_ID_ANY, false); } spin_unlock(&hw->lock); } @@ -1200,8 +1170,8 @@ int k, tx_offset, num_isoc_packets, sink, remain, current_len, errcode, hdlc, i; int *tx_idx; - int frame_complete, fifon, status; - __u8 threshbit; + int frame_complete, fifon, status, fillempty = 0; + __u8 threshbit, *p; spin_lock(&hw->lock); if (fifo->stop_gracefull) { @@ -1219,6 +1189,9 @@ tx_skb = fifo->bch->tx_skb; tx_idx = &fifo->bch->tx_idx; hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags); + if (!tx_skb && !hdlc && + test_bit(FLG_FILLEMPTY, &fifo->bch->Flags)) + fillempty = 1; } else { printk(KERN_DEBUG "%s: %s: neither BCH nor DCH\n", hw->name, __func__); @@ -1277,6 +1250,8 @@ /* Generate next ISO Packets */ if (tx_skb) remain = tx_skb->len - *tx_idx; + else if (fillempty) + remain = 15; /* > not complete */ else remain = 0; @@ -1307,15 +1282,20 @@ } /* copy tx data to iso-urb buffer */ - memcpy(context_iso_urb->buffer + tx_offset + 1, - (tx_skb->data + *tx_idx), current_len); - *tx_idx += current_len; - + p = context_iso_urb->buffer + tx_offset + 1; + if (fillempty) { + memset(p, fifo->bch->fill[0], + current_len); + } else { + memcpy(p, (tx_skb->data + *tx_idx), + current_len); + *tx_idx += current_len; + } urb->iso_frame_desc[k].offset = tx_offset; urb->iso_frame_desc[k].length = current_len + 1; /* USB data log for every D ISO out */ - if ((fifon == HFCUSB_D_RX) && + if ((fifon == HFCUSB_D_RX) && !fillempty && (debug & DBG_HFC_USB_VERBOSE)) { printk(KERN_DEBUG "%s: %s (%d/%d) offs(%d) len(%d) ", @@ -1365,12 +1345,8 @@ if (fifo->dch && get_next_dframe(fifo->dch)) tx_skb = fifo->dch->tx_skb; else if (fifo->bch && - get_next_bframe(fifo->bch)) { - if (test_bit(FLG_TRANSPARENT, - &fifo->bch->Flags)) - confirm_Bsend(fifo->bch); + get_next_bframe(fifo->bch)) tx_skb = fifo->bch->tx_skb; - } } } errcode = usb_submit_urb(urb, GFP_ATOMIC); @@ -1812,7 +1788,7 @@ mISDN_clear_bchannel(bch); spin_unlock_irqrestore(&hw->lock, flags); hfcsusb_setup_bch(bch, ISDN_P_NONE); - hfcsusb_stop_endpoint(hw, bch->nr); + hfcsusb_stop_endpoint(hw, bch->nr - 1); } /* @@ -1836,8 +1812,7 @@ case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - if (test_bit(FLG_ACTIVE, &bch->Flags)) - deactivate_bchannel(bch); + deactivate_bchannel(bch); ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(THIS_MODULE); @@ -1883,7 +1858,7 @@ hw->bch[i].nr = i + 1; set_channelmap(i + 1, hw->dch.dev.channelmap); hw->bch[i].debug = debug; - mISDN_initbchannel(&hw->bch[i], MAX_DATA_MEM); + mISDN_initbchannel(&hw->bch[i], MAX_DATA_MEM, poll >> 1); hw->bch[i].hw = hw; hw->bch[i].ch.send = hfcusb_l2l1B; hw->bch[i].ch.ctrl = hfc_bctrl;
diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c index 92d4a78..752e082 100644 --- a/drivers/isdn/hardware/mISDN/mISDNipac.c +++ b/drivers/isdn/hardware/mISDN/mISDNipac.c
@@ -933,24 +933,23 @@ hscx_empty_fifo(struct hscx_hw *hscx, u8 count) { u8 *p; + int maxlen; pr_debug("%s: B%1d %d\n", hscx->ip->name, hscx->bch.nr, count); - if (!hscx->bch.rx_skb) { - hscx->bch.rx_skb = mI_alloc_skb(hscx->bch.maxlen, GFP_ATOMIC); - if (!hscx->bch.rx_skb) { - pr_info("%s: B receive out of memory\n", - hscx->ip->name); - hscx_cmdr(hscx, 0x80); /* RMC */ - return; - } - } - if ((hscx->bch.rx_skb->len + count) > hscx->bch.maxlen) { - pr_debug("%s: overrun %d\n", hscx->ip->name, - hscx->bch.rx_skb->len + count); - skb_trim(hscx->bch.rx_skb, 0); + if (test_bit(FLG_RX_OFF, &hscx->bch.Flags)) { + hscx->bch.dropcnt += count; hscx_cmdr(hscx, 0x80); /* RMC */ return; } + maxlen = bchannel_get_rxbuf(&hscx->bch, count); + if (maxlen < 0) { + hscx_cmdr(hscx, 0x80); /* RMC */ + if (hscx->bch.rx_skb) + skb_trim(hscx->bch.rx_skb, 0); + pr_warning("%s.B%d: No bufferspace for %d bytes\n", + hscx->ip->name, hscx->bch.nr, count); + return; + } p = skb_put(hscx->bch.rx_skb, count); if (hscx->ip->type & IPAC_TYPE_IPACX) @@ -975,22 +974,28 @@ int count, more; u8 *p; - if (!hscx->bch.tx_skb) - return; - count = hscx->bch.tx_skb->len - hscx->bch.tx_idx; - if (count <= 0) - return; - p = hscx->bch.tx_skb->data + hscx->bch.tx_idx; - - more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0; - if (count > hscx->fifo_size) { + if (!hscx->bch.tx_skb) { + if (!test_bit(FLG_TX_EMPTY, &hscx->bch.Flags)) + return; count = hscx->fifo_size; more = 1; - } - pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr, count, - hscx->bch.tx_idx, hscx->bch.tx_skb->len); - hscx->bch.tx_idx += count; + p = hscx->log; + memset(p, hscx->bch.fill[0], count); + } else { + count = hscx->bch.tx_skb->len - hscx->bch.tx_idx; + if (count <= 0) + return; + p = hscx->bch.tx_skb->data + hscx->bch.tx_idx; + more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0; + if (count > hscx->fifo_size) { + count = hscx->fifo_size; + more = 1; + } + pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr, + count, hscx->bch.tx_idx, hscx->bch.tx_skb->len); + hscx->bch.tx_idx += count; + } if (hscx->ip->type & IPAC_TYPE_IPACX) hscx->ip->write_fifo(hscx->ip->hw, hscx->off + IPACX_XFIFOB, p, count); @@ -1001,7 +1006,7 @@ } hscx_cmdr(hscx, more ? 0x08 : 0x0a); - if (hscx->bch.debug & DEBUG_HW_BFIFO) { + if (hscx->bch.tx_skb && (hscx->bch.debug & DEBUG_HW_BFIFO)) { snprintf(hscx->log, 64, "B%1d-send %s %d ", hscx->bch.nr, hscx->ip->name, count); print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count); @@ -1011,17 +1016,17 @@ static void hscx_xpr(struct hscx_hw *hx) { - if (hx->bch.tx_skb && hx->bch.tx_idx < hx->bch.tx_skb->len) + if (hx->bch.tx_skb && hx->bch.tx_idx < hx->bch.tx_skb->len) { hscx_fill_fifo(hx); - else { - if (hx->bch.tx_skb) { - /* send confirm, on trans, free on hdlc. */ - if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) - confirm_Bsend(&hx->bch); + } else { + if (hx->bch.tx_skb) dev_kfree_skb(hx->bch.tx_skb); - } - if (get_next_bframe(&hx->bch)) + if (get_next_bframe(&hx->bch)) { hscx_fill_fifo(hx); + test_and_clear_bit(FLG_TX_EMPTY, &hx->bch.Flags); + } else if (test_bit(FLG_TX_EMPTY, &hx->bch.Flags)) { + hscx_fill_fifo(hx); + } } } @@ -1073,7 +1078,7 @@ skb_trim(hx->bch.rx_skb, 0); } else { skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1); - recv_Bchannel(&hx->bch, 0); + recv_Bchannel(&hx->bch, 0, false); } } @@ -1124,11 +1129,8 @@ if (istab & IPACX_B_RPF) { hscx_empty_fifo(hx, hx->fifo_size); - if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) { - /* receive transparent audio data */ - if (hx->bch.rx_skb) - recv_Bchannel(&hx->bch, 0); - } + if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) + recv_Bchannel(&hx->bch, 0, false); } if (istab & IPACX_B_RFO) { @@ -1141,7 +1143,9 @@ if (istab & IPACX_B_XDU) { if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) { - hscx_fill_fifo(hx); + if (test_bit(FLG_FILLEMPTY, &hx->bch.Flags)) + test_and_set_bit(FLG_TX_EMPTY, &hx->bch.Flags); + hscx_xpr(hx); return; } pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name, @@ -1342,22 +1346,17 @@ struct hscx_hw *hx = container_of(bch, struct hscx_hw, bch); int ret = -EINVAL; struct mISDNhead *hh = mISDN_HEAD_P(skb); - u32 id; - u_long flags; + unsigned long flags; switch (hh->prim) { case PH_DATA_REQ: spin_lock_irqsave(hx->ip->hwlock, flags); ret = bchannel_senddata(bch, skb); if (ret > 0) { /* direct TX */ - id = hh->id; /* skb can be freed */ ret = 0; hscx_fill_fifo(hx); - spin_unlock_irqrestore(hx->ip->hwlock, flags); - if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) - queue_ch_frame(ch, PH_DATA_CNF, id, NULL); - } else - spin_unlock_irqrestore(hx->ip->hwlock, flags); + } + spin_unlock_irqrestore(hx->ip->hwlock, flags); return ret; case PH_ACTIVATE_REQ: spin_lock_irqsave(hx->ip->hwlock, flags); @@ -1392,20 +1391,7 @@ static int channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) { - int ret = 0; - - switch (cq->op) { - case MISDN_CTRL_GETOP: - cq->op = 0; - break; - /* Nothing implemented yet */ - case MISDN_CTRL_FILL_EMPTY: - default: - pr_info("%s: unknown Op %x\n", __func__, cq->op); - ret = -EINVAL; - break; - } - return ret; + return mISDN_ctrl_bchannel(bch, cq); } static int @@ -1420,15 +1406,10 @@ switch (cmd) { case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - if (test_bit(FLG_ACTIVE, &bch->Flags)) { - spin_lock_irqsave(hx->ip->hwlock, flags); - mISDN_freebchannel(bch); - hscx_mode(hx, ISDN_P_NONE); - spin_unlock_irqrestore(hx->ip->hwlock, flags); - } else { - skb_queue_purge(&bch->rqueue); - bch->rcount = 0; - } + spin_lock_irqsave(hx->ip->hwlock, flags); + mISDN_freebchannel(bch); + hscx_mode(hx, ISDN_P_NONE); + spin_unlock_irqrestore(hx->ip->hwlock, flags); ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(hx->ip->owner); @@ -1628,7 +1609,8 @@ set_channelmap(i + 1, ipac->isac.dch.dev.channelmap); list_add(&ipac->hscx[i].bch.ch.list, &ipac->isac.dch.dev.bchannels); - mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM); + mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM, + ipac->hscx[i].fifo_size); ipac->hscx[i].bch.ch.nr = i + 1; ipac->hscx[i].bch.ch.send = &hscx_l2l1; ipac->hscx[i].bch.ch.ctrl = hscx_bctrl;
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c index 9a6da6e..be5973d 100644 --- a/drivers/isdn/hardware/mISDN/mISDNisar.c +++ b/drivers/isdn/hardware/mISDN/mISDNisar.c
@@ -421,13 +421,19 @@ static inline void isar_rcv_frame(struct isar_ch *ch) { - u8 *ptr; + u8 *ptr; + int maxlen; if (!ch->is->clsb) { pr_debug("%s; ISAR zero len frame\n", ch->is->name); ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); return; } + if (test_bit(FLG_RX_OFF, &ch->bch.Flags)) { + ch->bch.dropcnt += ch->is->clsb; + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + return; + } switch (ch->bch.state) { case ISDN_P_NONE: pr_debug("%s: ISAR protocol 0 spurious IIS_RDATA %x/%x/%x\n", @@ -437,36 +443,22 @@ case ISDN_P_B_RAW: case ISDN_P_B_L2DTMF: case ISDN_P_B_MODEM_ASYNC: - if (!ch->bch.rx_skb) { - ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen, - GFP_ATOMIC); - if (unlikely(!ch->bch.rx_skb)) { - pr_info("%s: B receive out of memory\n", - ch->is->name); - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); - break; - } + maxlen = bchannel_get_rxbuf(&ch->bch, ch->is->clsb); + if (maxlen < 0) { + pr_warning("%s.B%d: No bufferspace for %d bytes\n", + ch->is->name, ch->bch.nr, ch->is->clsb); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + break; } rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb)); - recv_Bchannel(&ch->bch, 0); + recv_Bchannel(&ch->bch, 0, false); break; case ISDN_P_B_HDLC: - if (!ch->bch.rx_skb) { - ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen, - GFP_ATOMIC); - if (unlikely(!ch->bch.rx_skb)) { - pr_info("%s: B receive out of memory\n", - ch->is->name); - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); - break; - } - } - if ((ch->bch.rx_skb->len + ch->is->clsb) > - (ch->bch.maxlen + 2)) { - pr_debug("%s: incoming packet too large\n", - ch->is->name); + maxlen = bchannel_get_rxbuf(&ch->bch, ch->is->clsb); + if (maxlen < 0) { + pr_warning("%s.B%d: No bufferspace for %d bytes\n", + ch->is->name, ch->bch.nr, ch->is->clsb); ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); - skb_trim(ch->bch.rx_skb, 0); break; } if (ch->is->cmsb & HDLC_ERROR) { @@ -494,7 +486,7 @@ break; } skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2); - recv_Bchannel(&ch->bch, 0); + recv_Bchannel(&ch->bch, 0, false); } break; case ISDN_P_B_T30_FAX: @@ -530,7 +522,7 @@ ch->state = STFAX_ESCAPE; /* set_skb_flag(skb, DF_NOMOREDATA); */ } - recv_Bchannel(&ch->bch, 0); + recv_Bchannel(&ch->bch, 0, false); if (ch->is->cmsb & SART_NMD) deliver_status(ch, HW_MOD_NOCARR); break; @@ -570,7 +562,7 @@ break; } skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2); - recv_Bchannel(&ch->bch, 0); + recv_Bchannel(&ch->bch, 0, false); } if (ch->is->cmsb & SART_NMD) { /* ABORT */ pr_debug("%s: isar_rcv_frame: no more data\n", @@ -598,16 +590,25 @@ u8 msb; u8 *ptr; - pr_debug("%s: ch%d tx_skb %p tx_idx %d\n", - ch->is->name, ch->bch.nr, ch->bch.tx_skb, ch->bch.tx_idx); - if (!ch->bch.tx_skb) - return; - count = ch->bch.tx_skb->len - ch->bch.tx_idx; - if (count <= 0) - return; + pr_debug("%s: ch%d tx_skb %d tx_idx %d\n", ch->is->name, ch->bch.nr, + ch->bch.tx_skb ? ch->bch.tx_skb->len : -1, ch->bch.tx_idx); if (!(ch->is->bstat & (ch->dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2))) return; + if (!ch->bch.tx_skb) { + if (!test_bit(FLG_TX_EMPTY, &ch->bch.Flags) || + (ch->bch.state != ISDN_P_B_RAW)) + return; + count = ch->mml; + /* use the card buffer */ + memset(ch->is->buf, ch->bch.fill[0], count); + send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA, + 0, count, ch->is->buf); + return; + } + count = ch->bch.tx_skb->len - ch->bch.tx_idx; + if (count <= 0) + return; if (count > ch->mml) { msb = 0; count = ch->mml; @@ -686,9 +687,9 @@ static void send_next(struct isar_ch *ch) { - pr_debug("%s: %s ch%d tx_skb %p tx_idx %d\n", - ch->is->name, __func__, ch->bch.nr, - ch->bch.tx_skb, ch->bch.tx_idx); + pr_debug("%s: %s ch%d tx_skb %d tx_idx %d\n", ch->is->name, __func__, + ch->bch.nr, ch->bch.tx_skb ? ch->bch.tx_skb->len : -1, + ch->bch.tx_idx); if (ch->bch.state == ISDN_P_B_T30_FAX) { if (ch->cmd == PCTRL_CMD_FTH) { if (test_bit(FLG_LASTDATA, &ch->bch.Flags)) { @@ -702,15 +703,14 @@ } } } - if (ch->bch.tx_skb) { - /* send confirm, on trans, free on hdlc. */ - if (test_bit(FLG_TRANSPARENT, &ch->bch.Flags)) - confirm_Bsend(&ch->bch); + if (ch->bch.tx_skb) dev_kfree_skb(ch->bch.tx_skb); - } - if (get_next_bframe(&ch->bch)) + if (get_next_bframe(&ch->bch)) { isar_fill_fifo(ch); - else { + test_and_clear_bit(FLG_TX_EMPTY, &ch->bch.Flags); + } else if (test_bit(FLG_TX_EMPTY, &ch->bch.Flags)) { + isar_fill_fifo(ch); + } else { if (test_and_clear_bit(FLG_DLEETX, &ch->bch.Flags)) { if (test_and_clear_bit(FLG_LASTDATA, &ch->bch.Flags)) { @@ -724,6 +724,8 @@ } else { deliver_status(ch, HW_MOD_CONNECT); } + } else if (test_bit(FLG_FILLEMPTY, &ch->bch.Flags)) { + test_and_set_bit(FLG_TX_EMPTY, &ch->bch.Flags); } } } @@ -1487,14 +1489,10 @@ spin_lock_irqsave(ich->is->hwlock, flags); ret = bchannel_senddata(bch, skb); if (ret > 0) { /* direct TX */ - id = hh->id; /* skb can be freed */ ret = 0; isar_fill_fifo(ich); - spin_unlock_irqrestore(ich->is->hwlock, flags); - if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) - queue_ch_frame(ch, PH_DATA_CNF, id, NULL); - } else - spin_unlock_irqrestore(ich->is->hwlock, flags); + } + spin_unlock_irqrestore(ich->is->hwlock, flags); return ret; case PH_ACTIVATE_REQ: spin_lock_irqsave(ich->is->hwlock, flags); @@ -1575,20 +1573,7 @@ static int channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) { - int ret = 0; - - switch (cq->op) { - case MISDN_CTRL_GETOP: - cq->op = 0; - break; - /* Nothing implemented yet */ - case MISDN_CTRL_FILL_EMPTY: - default: - pr_info("%s: unknown Op %x\n", __func__, cq->op); - ret = -EINVAL; - break; - } - return ret; + return mISDN_ctrl_bchannel(bch, cq); } static int @@ -1603,15 +1588,10 @@ switch (cmd) { case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - if (test_bit(FLG_ACTIVE, &bch->Flags)) { - spin_lock_irqsave(ich->is->hwlock, flags); - mISDN_freebchannel(bch); - modeisar(ich, ISDN_P_NONE); - spin_unlock_irqrestore(ich->is->hwlock, flags); - } else { - skb_queue_purge(&bch->rqueue); - bch->rcount = 0; - } + spin_lock_irqsave(ich->is->hwlock, flags); + mISDN_freebchannel(bch); + modeisar(ich, ISDN_P_NONE); + spin_unlock_irqrestore(ich->is->hwlock, flags); ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(ich->is->owner); @@ -1677,7 +1657,6 @@ bch = &isar->ch[rq->adr.channel - 1].bch; if (test_and_set_bit(FLG_OPEN, &bch->Flags)) return -EBUSY; /* b-channel can be only open once */ - test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); bch->ch.protocol = rq->protocol; rq->ch = &bch->ch; return 0; @@ -1691,7 +1670,7 @@ isar->hw = hw; for (i = 0; i < 2; i++) { isar->ch[i].bch.nr = i + 1; - mISDN_initbchannel(&isar->ch[i].bch, MAX_DATA_MEM); + mISDN_initbchannel(&isar->ch[i].bch, MAX_DATA_MEM, 32); isar->ch[i].bch.ch.nr = i + 1; isar->ch[i].bch.ch.send = &isar_l2l1; isar->ch[i].bch.ch.ctrl = isar_bctrl;
diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c index 27998d7..c3e3e76 100644 --- a/drivers/isdn/hardware/mISDN/netjet.c +++ b/drivers/isdn/hardware/mISDN/netjet.c
@@ -386,24 +386,20 @@ bc->bch.nr, idx); } bc->lastrx = idx; - if (!bc->bch.rx_skb) { - bc->bch.rx_skb = mI_alloc_skb(bc->bch.maxlen, GFP_ATOMIC); - if (!bc->bch.rx_skb) { - pr_info("%s: B%1d receive out of memory\n", - card->name, bc->bch.nr); - return; - } + if (test_bit(FLG_RX_OFF, &bc->bch.Flags)) { + bc->bch.dropcnt += cnt; + return; } - - if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) { - if ((bc->bch.rx_skb->len + cnt) > bc->bch.maxlen) { - pr_debug("%s: B%1d overrun %d\n", card->name, - bc->bch.nr, bc->bch.rx_skb->len + cnt); - skb_trim(bc->bch.rx_skb, 0); - return; - } + stat = bchannel_get_rxbuf(&bc->bch, cnt); + /* only transparent use the count here, HDLC overun is detected later */ + if (stat == ENOMEM) { + pr_warning("%s.B%d: No memory for %d bytes\n", + card->name, bc->bch.nr, cnt); + return; + } + if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) p = skb_put(bc->bch.rx_skb, cnt); - } else + else p = bc->hrbuf; for (i = 0; i < cnt; i++) { @@ -414,48 +410,45 @@ idx = 0; p[i] = val & 0xff; } + + if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) { + recv_Bchannel(&bc->bch, 0, false); + return; + } + pn = bc->hrbuf; -next_frame: - if (test_bit(FLG_HDLC, &bc->bch.Flags)) { + while (cnt > 0) { stat = isdnhdlc_decode(&bc->hrecv, pn, cnt, &i, bc->bch.rx_skb->data, bc->bch.maxlen); - if (stat > 0) /* valid frame received */ + if (stat > 0) { /* valid frame received */ p = skb_put(bc->bch.rx_skb, stat); - else if (stat == -HDLC_CRC_ERROR) - pr_info("%s: B%1d receive frame CRC error\n", - card->name, bc->bch.nr); - else if (stat == -HDLC_FRAMING_ERROR) - pr_info("%s: B%1d receive framing error\n", - card->name, bc->bch.nr); - else if (stat == -HDLC_LENGTH_ERROR) - pr_info("%s: B%1d receive frame too long (> %d)\n", - card->name, bc->bch.nr, bc->bch.maxlen); - } else - stat = cnt; - - if (stat > 0) { - if (debug & DEBUG_HW_BFIFO) { - snprintf(card->log, LOG_SIZE, "B%1d-recv %s %d ", - bc->bch.nr, card->name, stat); - print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, - p, stat); - } - recv_Bchannel(&bc->bch, 0); - } - if (test_bit(FLG_HDLC, &bc->bch.Flags)) { - pn += i; - cnt -= i; - if (!bc->bch.rx_skb) { - bc->bch.rx_skb = mI_alloc_skb(bc->bch.maxlen, - GFP_ATOMIC); - if (!bc->bch.rx_skb) { - pr_info("%s: B%1d receive out of memory\n", - card->name, bc->bch.nr); + if (debug & DEBUG_HW_BFIFO) { + snprintf(card->log, LOG_SIZE, + "B%1d-recv %s %d ", bc->bch.nr, + card->name, stat); + print_hex_dump_bytes(card->log, + DUMP_PREFIX_OFFSET, p, + stat); + } + recv_Bchannel(&bc->bch, 0, false); + stat = bchannel_get_rxbuf(&bc->bch, bc->bch.maxlen); + if (stat < 0) { + pr_warning("%s.B%d: No memory for %d bytes\n", + card->name, bc->bch.nr, cnt); return; } + } else if (stat == -HDLC_CRC_ERROR) { + pr_info("%s: B%1d receive frame CRC error\n", + card->name, bc->bch.nr); + } else if (stat == -HDLC_FRAMING_ERROR) { + pr_info("%s: B%1d receive framing error\n", + card->name, bc->bch.nr); + } else if (stat == -HDLC_LENGTH_ERROR) { + pr_info("%s: B%1d receive frame too long (> %d)\n", + card->name, bc->bch.nr, bc->bch.maxlen); } - if (cnt > 0) - goto next_frame; + pn += i; + cnt -= i; } } @@ -544,22 +537,31 @@ fill_dma(struct tiger_ch *bc) { struct tiger_hw *card = bc->bch.hw; - int count, i; - u32 m, v; + int count, i, fillempty = 0; + u32 m, v, n = 0; u8 *p; if (bc->free == 0) return; - count = bc->bch.tx_skb->len - bc->bch.tx_idx; - if (count <= 0) - return; - pr_debug("%s: %s B%1d %d/%d/%d/%d state %x idx %d/%d\n", card->name, - __func__, bc->bch.nr, count, bc->free, bc->bch.tx_idx, - bc->bch.tx_skb->len, bc->txstate, bc->idx, card->send.idx); + if (!bc->bch.tx_skb) { + if (!test_bit(FLG_TX_EMPTY, &bc->bch.Flags)) + return; + fillempty = 1; + count = card->send.size >> 1; + p = bc->bch.fill; + } else { + count = bc->bch.tx_skb->len - bc->bch.tx_idx; + if (count <= 0) + return; + pr_debug("%s: %s B%1d %d/%d/%d/%d state %x idx %d/%d\n", + card->name, __func__, bc->bch.nr, count, bc->free, + bc->bch.tx_idx, bc->bch.tx_skb->len, bc->txstate, + bc->idx, card->send.idx); + p = bc->bch.tx_skb->data + bc->bch.tx_idx; + } if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN)) resync(bc, card); - p = bc->bch.tx_skb->data + bc->bch.tx_idx; - if (test_bit(FLG_HDLC, &bc->bch.Flags)) { + if (test_bit(FLG_HDLC, &bc->bch.Flags) && !fillempty) { count = isdnhdlc_encode(&bc->hsend, p, count, &i, bc->hsbuf, bc->free); pr_debug("%s: B%1d hdlc encoded %d in %d\n", card->name, @@ -570,17 +572,33 @@ } else { if (count > bc->free) count = bc->free; - bc->bch.tx_idx += count; + if (!fillempty) + bc->bch.tx_idx += count; bc->free -= count; } m = (bc->bch.nr & 1) ? 0xffffff00 : 0xffff00ff; - for (i = 0; i < count; i++) { - if (bc->idx >= card->send.size) - bc->idx = 0; - v = card->send.start[bc->idx]; - v &= m; - v |= (bc->bch.nr & 1) ? (u32)(p[i]) : ((u32)(p[i])) << 8; - card->send.start[bc->idx++] = v; + if (fillempty) { + n = p[0]; + if (!(bc->bch.nr & 1)) + n <<= 8; + for (i = 0; i < count; i++) { + if (bc->idx >= card->send.size) + bc->idx = 0; + v = card->send.start[bc->idx]; + v &= m; + v |= n; + card->send.start[bc->idx++] = v; + } + } else { + for (i = 0; i < count; i++) { + if (bc->idx >= card->send.size) + bc->idx = 0; + v = card->send.start[bc->idx]; + v &= m; + n = p[i]; + v |= (bc->bch.nr & 1) ? n : n << 8; + card->send.start[bc->idx++] = v; + } } if (debug & DEBUG_HW_BFIFO) { snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ", @@ -595,21 +613,26 @@ static int bc_next_frame(struct tiger_ch *bc) { - if (bc->bch.tx_skb && bc->bch.tx_idx < bc->bch.tx_skb->len) + int ret = 1; + + if (bc->bch.tx_skb && bc->bch.tx_idx < bc->bch.tx_skb->len) { fill_dma(bc); - else { - if (bc->bch.tx_skb) { - /* send confirm, on trans, free on hdlc. */ - if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) - confirm_Bsend(&bc->bch); + } else { + if (bc->bch.tx_skb) dev_kfree_skb(bc->bch.tx_skb); - } - if (get_next_bframe(&bc->bch)) + if (get_next_bframe(&bc->bch)) { fill_dma(bc); - else - return 0; + test_and_clear_bit(FLG_TX_EMPTY, &bc->bch.Flags); + } else if (test_bit(FLG_TX_EMPTY, &bc->bch.Flags)) { + fill_dma(bc); + } else if (test_bit(FLG_FILLEMPTY, &bc->bch.Flags)) { + test_and_set_bit(FLG_TX_EMPTY, &bc->bch.Flags); + ret = 0; + } else { + ret = 0; + } } - return 1; + return ret; } static void @@ -732,22 +755,17 @@ struct tiger_ch *bc = container_of(bch, struct tiger_ch, bch); struct tiger_hw *card = bch->hw; struct mISDNhead *hh = mISDN_HEAD_P(skb); - u32 id; - u_long flags; + unsigned long flags; switch (hh->prim) { case PH_DATA_REQ: spin_lock_irqsave(&card->lock, flags); ret = bchannel_senddata(bch, skb); if (ret > 0) { /* direct TX */ - id = hh->id; /* skb can be freed */ fill_dma(bc); ret = 0; - spin_unlock_irqrestore(&card->lock, flags); - if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) - queue_ch_frame(ch, PH_DATA_CNF, id, NULL); - } else - spin_unlock_irqrestore(&card->lock, flags); + } + spin_unlock_irqrestore(&card->lock, flags); return ret; case PH_ACTIVATE_REQ: spin_lock_irqsave(&card->lock, flags); @@ -778,21 +796,7 @@ static int channel_bctrl(struct tiger_ch *bc, struct mISDN_ctrl_req *cq) { - int ret = 0; - struct tiger_hw *card = bc->bch.hw; - - switch (cq->op) { - case MISDN_CTRL_GETOP: - cq->op = 0; - break; - /* Nothing implemented yet */ - case MISDN_CTRL_FILL_EMPTY: - default: - pr_info("%s: %s unknown Op %x\n", card->name, __func__, cq->op); - ret = -EINVAL; - break; - } - return ret; + return mISDN_ctrl_bchannel(&bc->bch, cq); } static int @@ -808,14 +812,10 @@ switch (cmd) { case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - if (test_bit(FLG_ACTIVE, &bch->Flags)) { - spin_lock_irqsave(&card->lock, flags); - mISDN_freebchannel(bch); - test_and_clear_bit(FLG_TX_BUSY, &bch->Flags); - test_and_clear_bit(FLG_ACTIVE, &bch->Flags); - mode_tiger(bc, ISDN_P_NONE); - spin_unlock_irqrestore(&card->lock, flags); - } + spin_lock_irqsave(&card->lock, flags); + mISDN_freebchannel(bch); + mode_tiger(bc, ISDN_P_NONE); + spin_unlock_irqrestore(&card->lock, flags); ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(THIS_MODULE); @@ -1030,7 +1030,8 @@ for (i = 0; i < 2; i++) { card->bc[i].bch.nr = i + 1; set_channelmap(i + 1, card->isac.dch.dev.channelmap); - mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM); + mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM, + NJ_DMA_RXSIZE >> 1); card->bc[i].bch.hw = card; card->bc[i].bch.ch.send = nj_l2l1B; card->bc[i].bch.ch.ctrl = nj_bctrl;
diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c index 1d04467..26a86b8 100644 --- a/drivers/isdn/hardware/mISDN/w6692.c +++ b/drivers/isdn/hardware/mISDN/w6692.c
@@ -465,6 +465,7 @@ { struct w6692_hw *card = wch->bch.hw; u8 *ptr; + int maxlen; pr_debug("%s: empty_Bfifo %d\n", card->name, count); if (unlikely(wch->bch.state == ISDN_P_NONE)) { @@ -474,20 +475,18 @@ skb_trim(wch->bch.rx_skb, 0); return; } - if (!wch->bch.rx_skb) { - wch->bch.rx_skb = mI_alloc_skb(wch->bch.maxlen, GFP_ATOMIC); - if (unlikely(!wch->bch.rx_skb)) { - pr_info("%s: B receive out of memory\n", card->name); - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | - W_B_CMDR_RACT); - return; - } - } - if (wch->bch.rx_skb->len + count > wch->bch.maxlen) { - pr_debug("%s: empty_Bfifo incoming packet too large\n", - card->name); + if (test_bit(FLG_RX_OFF, &wch->bch.Flags)) { + wch->bch.dropcnt += count; WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT); - skb_trim(wch->bch.rx_skb, 0); + return; + } + maxlen = bchannel_get_rxbuf(&wch->bch, count); + if (maxlen < 0) { + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT); + if (wch->bch.rx_skb) + skb_trim(wch->bch.rx_skb, 0); + pr_warning("%s.B%d: No bufferspace for %d bytes\n", + card->name, wch->bch.nr, count); return; } ptr = skb_put(wch->bch.rx_skb, count); @@ -504,16 +503,22 @@ W6692_fill_Bfifo(struct w6692_ch *wch) { struct w6692_hw *card = wch->bch.hw; - int count; + int count, fillempty = 0; u8 *ptr, cmd = W_B_CMDR_RACT | W_B_CMDR_XMS; pr_debug("%s: fill Bfifo\n", card->name); - if (!wch->bch.tx_skb) - return; - count = wch->bch.tx_skb->len - wch->bch.tx_idx; - if (count <= 0) - return; - ptr = wch->bch.tx_skb->data + wch->bch.tx_idx; + if (!wch->bch.tx_skb) { + if (!test_bit(FLG_TX_EMPTY, &wch->bch.Flags)) + return; + ptr = wch->bch.fill; + count = W_B_FIFO_THRESH; + fillempty = 1; + } else { + count = wch->bch.tx_skb->len - wch->bch.tx_idx; + if (count <= 0) + return; + ptr = wch->bch.tx_skb->data + wch->bch.tx_idx; + } if (count > W_B_FIFO_THRESH) count = W_B_FIFO_THRESH; else if (test_bit(FLG_HDLC, &wch->bch.Flags)) @@ -522,9 +527,16 @@ pr_debug("%s: fill Bfifo%d/%d\n", card->name, count, wch->bch.tx_idx); wch->bch.tx_idx += count; - outsb(wch->addr + W_B_XFIFO, ptr, count); + if (fillempty) { + while (count > 0) { + outsb(wch->addr + W_B_XFIFO, ptr, MISDN_BCH_FILL_SIZE); + count -= MISDN_BCH_FILL_SIZE; + } + } else { + outsb(wch->addr + W_B_XFIFO, ptr, count); + } WriteW6692B(wch, W_B_CMDR, cmd); - if (debug & DEBUG_HW_DFIFO) { + if ((debug & DEBUG_HW_BFIFO) && !fillempty) { snprintf(card->log, 63, "B%1d-send %s %d ", wch->bch.nr, card->name, count); print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count); @@ -638,17 +650,17 @@ static void send_next(struct w6692_ch *wch) { - if (wch->bch.tx_skb && wch->bch.tx_idx < wch->bch.tx_skb->len) + if (wch->bch.tx_skb && wch->bch.tx_idx < wch->bch.tx_skb->len) { W6692_fill_Bfifo(wch); - else { - if (wch->bch.tx_skb) { - /* send confirm, on trans, free on hdlc. */ - if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags)) - confirm_Bsend(&wch->bch); + } else { + if (wch->bch.tx_skb) dev_kfree_skb(wch->bch.tx_skb); - } - if (get_next_bframe(&wch->bch)) + if (get_next_bframe(&wch->bch)) { W6692_fill_Bfifo(wch); + test_and_clear_bit(FLG_TX_EMPTY, &wch->bch.Flags); + } else if (test_bit(FLG_TX_EMPTY, &wch->bch.Flags)) { + W6692_fill_Bfifo(wch); + } } } @@ -698,7 +710,7 @@ if (count == 0) count = W_B_FIFO_THRESH; W6692_empty_Bfifo(wch, count); - recv_Bchannel(&wch->bch, 0); + recv_Bchannel(&wch->bch, 0, false); } } if (stat & W_B_EXI_RMR) { @@ -714,9 +726,8 @@ W_B_CMDR_RRST | W_B_CMDR_RACT); } else { W6692_empty_Bfifo(wch, W_B_FIFO_THRESH); - if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags) && - wch->bch.rx_skb && (wch->bch.rx_skb->len > 0)) - recv_Bchannel(&wch->bch, 0); + if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags)) + recv_Bchannel(&wch->bch, 0, false); } } if (stat & W_B_EXI_RDOV) { @@ -738,8 +749,8 @@ wch->bch.nr, star); } if (star & W_B_STAR_XDOW) { - pr_debug("%s: B%d XDOW proto=%x\n", card->name, - wch->bch.nr, wch->bch.state); + pr_warning("%s: B%d XDOW proto=%x\n", card->name, + wch->bch.nr, wch->bch.state); #ifdef ERROR_STATISTIC wch->bch.err_xdu++; #endif @@ -752,20 +763,21 @@ } } send_next(wch); - if (stat & W_B_EXI_XDUN) + if (star & W_B_STAR_XDOW) return; /* handle XDOW only once */ } if (stat & W_B_EXI_XDUN) { - pr_debug("%s: B%d XDUN proto=%x\n", card->name, - wch->bch.nr, wch->bch.state); + pr_warning("%s: B%d XDUN proto=%x\n", card->name, + wch->bch.nr, wch->bch.state); #ifdef ERROR_STATISTIC wch->bch.err_xdu++; #endif - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT); - /* resend */ + /* resend - no XRST needed */ if (wch->bch.tx_skb) { if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags)) wch->bch.tx_idx = 0; + } else if (test_bit(FLG_FILLEMPTY, &wch->bch.Flags)) { + test_and_set_bit(FLG_TX_EMPTY, &wch->bch.Flags); } send_next(wch); } @@ -944,22 +956,17 @@ struct w6692_hw *card = bch->hw; int ret = -EINVAL; struct mISDNhead *hh = mISDN_HEAD_P(skb); - u32 id; - u_long flags; + unsigned long flags; switch (hh->prim) { case PH_DATA_REQ: spin_lock_irqsave(&card->lock, flags); ret = bchannel_senddata(bch, skb); if (ret > 0) { /* direct TX */ - id = hh->id; /* skb can be freed */ ret = 0; W6692_fill_Bfifo(bc); - spin_unlock_irqrestore(&card->lock, flags); - if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) - queue_ch_frame(ch, PH_DATA_CNF, id, NULL); - } else - spin_unlock_irqrestore(&card->lock, flags); + } + spin_unlock_irqrestore(&card->lock, flags); return ret; case PH_ACTIVATE_REQ: spin_lock_irqsave(&card->lock, flags); @@ -994,20 +1001,7 @@ static int channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) { - int ret = 0; - - switch (cq->op) { - case MISDN_CTRL_GETOP: - cq->op = 0; - break; - /* Nothing implemented yet */ - case MISDN_CTRL_FILL_EMPTY: - default: - pr_info("%s: unknown Op %x\n", __func__, cq->op); - ret = -EINVAL; - break; - } - return ret; + return mISDN_ctrl_bchannel(bch, cq); } static int @@ -1022,7 +1016,6 @@ bch = &card->bc[rq->adr.channel - 1].bch; if (test_and_set_bit(FLG_OPEN, &bch->Flags)) return -EBUSY; /* b-channel can be only open once */ - test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); bch->ch.protocol = rq->protocol; rq->ch = &bch->ch; return 0; @@ -1061,15 +1054,10 @@ switch (cmd) { case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - if (test_bit(FLG_ACTIVE, &bch->Flags)) { - spin_lock_irqsave(&card->lock, flags); - mISDN_freebchannel(bch); - w6692_mode(bc, ISDN_P_NONE); - spin_unlock_irqrestore(&card->lock, flags); - } else { - skb_queue_purge(&bch->rqueue); - bch->rcount = 0; - } + spin_lock_irqsave(&card->lock, flags); + mISDN_freebchannel(bch); + w6692_mode(bc, ISDN_P_NONE); + spin_unlock_irqrestore(&card->lock, flags); ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(THIS_MODULE); @@ -1323,7 +1311,8 @@ card->dch.hw = card; card->dch.dev.nrbchan = 2; for (i = 0; i < 2; i++) { - mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM); + mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM, + W_B_FIFO_THRESH); card->bc[i].bch.hw = card; card->bc[i].bch.nr = i + 1; card->bc[i].bch.ch.nr = i + 1;
diff --git a/drivers/isdn/i4l/isdn_bsdcomp.c b/drivers/isdn/i4l/isdn_bsdcomp.c index c59e8d2..8837ac5 100644 --- a/drivers/isdn/i4l/isdn_bsdcomp.c +++ b/drivers/isdn/i4l/isdn_bsdcomp.c
@@ -612,7 +612,7 @@ db->n_bits++; /* If output length is too large then this is an incompressible frame. */ - if (!skb_out || (skb_out && skb_out->len >= skb_in->len)) { + if (!skb_out || skb_out->len >= skb_in->len) { ++db->incomp_count; db->incomp_bytes += isize; return 0;
diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c index 2ac2d7a..28c99c6 100644 --- a/drivers/isdn/mISDN/dsp_core.c +++ b/drivers/isdn/mISDN/dsp_core.c
@@ -268,6 +268,7 @@ } cq.op = MISDN_CTRL_FILL_EMPTY; cq.p1 = 1; + cq.p2 = dsp_silence; if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) { printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n", __func__);
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c index c74c363..ef34fd4 100644 --- a/drivers/isdn/mISDN/hwchannel.c +++ b/drivers/isdn/mISDN/hwchannel.c
@@ -81,10 +81,16 @@ EXPORT_SYMBOL(mISDN_initdchannel); int -mISDN_initbchannel(struct bchannel *ch, int maxlen) +mISDN_initbchannel(struct bchannel *ch, unsigned short maxlen, + unsigned short minlen) { ch->Flags = 0; + ch->minlen = minlen; + ch->next_minlen = minlen; + ch->init_minlen = minlen; ch->maxlen = maxlen; + ch->next_maxlen = maxlen; + ch->init_maxlen = maxlen; ch->hw = NULL; ch->rx_skb = NULL; ch->tx_skb = NULL; @@ -134,6 +140,14 @@ test_and_clear_bit(FLG_TX_BUSY, &ch->Flags); test_and_clear_bit(FLG_TX_NEXT, &ch->Flags); test_and_clear_bit(FLG_ACTIVE, &ch->Flags); + test_and_clear_bit(FLG_FILLEMPTY, &ch->Flags); + test_and_clear_bit(FLG_TX_EMPTY, &ch->Flags); + test_and_clear_bit(FLG_RX_OFF, &ch->Flags); + ch->dropcnt = 0; + ch->minlen = ch->init_minlen; + ch->next_minlen = ch->init_minlen; + ch->maxlen = ch->init_maxlen; + ch->next_maxlen = ch->init_maxlen; } EXPORT_SYMBOL(mISDN_clear_bchannel); @@ -148,6 +162,51 @@ } EXPORT_SYMBOL(mISDN_freebchannel); +int +mISDN_ctrl_bchannel(struct bchannel *bch, struct mISDN_ctrl_req *cq) +{ + int ret = 0; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = MISDN_CTRL_RX_BUFFER | MISDN_CTRL_FILL_EMPTY | + MISDN_CTRL_RX_OFF; + break; + case MISDN_CTRL_FILL_EMPTY: + if (cq->p1) { + memset(bch->fill, cq->p2 & 0xff, MISDN_BCH_FILL_SIZE); + test_and_set_bit(FLG_FILLEMPTY, &bch->Flags); + } else { + test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); + } + break; + case MISDN_CTRL_RX_OFF: + /* read back dropped byte count */ + cq->p2 = bch->dropcnt; + if (cq->p1) + test_and_set_bit(FLG_RX_OFF, &bch->Flags); + else + test_and_clear_bit(FLG_RX_OFF, &bch->Flags); + bch->dropcnt = 0; + break; + case MISDN_CTRL_RX_BUFFER: + if (cq->p2 > MISDN_CTRL_RX_SIZE_IGNORE) + bch->next_maxlen = cq->p2; + if (cq->p1 > MISDN_CTRL_RX_SIZE_IGNORE) + bch->next_minlen = cq->p1; + /* we return the old values */ + cq->p1 = bch->minlen; + cq->p2 = bch->maxlen; + break; + default: + pr_info("mISDN unhandled control %x operation\n", cq->op); + ret = -EINVAL; + break; + } + return ret; +} +EXPORT_SYMBOL(mISDN_ctrl_bchannel); + static inline u_int get_sapi_tei(u_char *p) { @@ -197,24 +256,37 @@ EXPORT_SYMBOL(recv_Echannel); void -recv_Bchannel(struct bchannel *bch, unsigned int id) +recv_Bchannel(struct bchannel *bch, unsigned int id, bool force) { struct mISDNhead *hh; - hh = mISDN_HEAD_P(bch->rx_skb); - hh->prim = PH_DATA_IND; - hh->id = id; - if (bch->rcount >= 64) { - printk(KERN_WARNING "B-channel %p receive queue overflow, " - "flushing!\n", bch); - skb_queue_purge(&bch->rqueue); - bch->rcount = 0; + /* if allocation did fail upper functions still may call us */ + if (unlikely(!bch->rx_skb)) return; + if (unlikely(!bch->rx_skb->len)) { + /* we have no data to send - this may happen after recovery + * from overflow or too small allocation. + * We need to free the buffer here */ + dev_kfree_skb(bch->rx_skb); + bch->rx_skb = NULL; + } else { + if (test_bit(FLG_TRANSPARENT, &bch->Flags) && + (bch->rx_skb->len < bch->minlen) && !force) + return; + hh = mISDN_HEAD_P(bch->rx_skb); + hh->prim = PH_DATA_IND; + hh->id = id; + if (bch->rcount >= 64) { + printk(KERN_WARNING + "B%d receive queue overflow - flushing!\n", + bch->nr); + skb_queue_purge(&bch->rqueue); + } + bch->rcount++; + skb_queue_tail(&bch->rqueue, bch->rx_skb); + bch->rx_skb = NULL; + schedule_event(bch, FLG_RECVQUEUE); } - bch->rcount++; - skb_queue_tail(&bch->rqueue, bch->rx_skb); - bch->rx_skb = NULL; - schedule_event(bch, FLG_RECVQUEUE); } EXPORT_SYMBOL(recv_Bchannel); @@ -272,7 +344,7 @@ } EXPORT_SYMBOL(get_next_dframe); -void +static void confirm_Bsend(struct bchannel *bch) { struct sk_buff *skb; @@ -294,7 +366,6 @@ skb_queue_tail(&bch->rqueue, skb); schedule_event(bch, FLG_RECVQUEUE); } -EXPORT_SYMBOL(confirm_Bsend); int get_next_bframe(struct bchannel *bch) @@ -305,8 +376,8 @@ if (bch->tx_skb) { bch->next_skb = NULL; test_and_clear_bit(FLG_TX_NEXT, &bch->Flags); - if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) - confirm_Bsend(bch); /* not for transparent */ + /* confirm imediately to allow next data */ + confirm_Bsend(bch); return 1; } else { test_and_clear_bit(FLG_TX_NEXT, &bch->Flags); @@ -395,7 +466,62 @@ /* write to fifo */ ch->tx_skb = skb; ch->tx_idx = 0; + confirm_Bsend(ch); return 1; } } EXPORT_SYMBOL(bchannel_senddata); + +/* The function allocates a new receive skb on demand with a size for the + * requirements of the current protocol. It returns the tailroom of the + * receive skb or an error. + */ +int +bchannel_get_rxbuf(struct bchannel *bch, int reqlen) +{ + int len; + + if (bch->rx_skb) { + len = skb_tailroom(bch->rx_skb); + if (len < reqlen) { + pr_warning("B%d no space for %d (only %d) bytes\n", + bch->nr, reqlen, len); + if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { + /* send what we have now and try a new buffer */ + recv_Bchannel(bch, 0, true); + } else { + /* on HDLC we have to drop too big frames */ + return -EMSGSIZE; + } + } else { + return len; + } + } + /* update current min/max length first */ + if (unlikely(bch->maxlen != bch->next_maxlen)) + bch->maxlen = bch->next_maxlen; + if (unlikely(bch->minlen != bch->next_minlen)) + bch->minlen = bch->next_minlen; + if (unlikely(reqlen > bch->maxlen)) + return -EMSGSIZE; + if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { + if (reqlen >= bch->minlen) { + len = reqlen; + } else { + len = 2 * bch->minlen; + if (len > bch->maxlen) + len = bch->maxlen; + } + } else { + /* with HDLC we do not know the length yet */ + len = bch->maxlen; + } + bch->rx_skb = mI_alloc_skb(len, GFP_ATOMIC); + if (!bch->rx_skb) { + pr_warning("B%d receive no memory for %d bytes\n", + bch->nr, len); + len = -ENOMEM; + } + return len; +} +EXPORT_SYMBOL(bchannel_get_rxbuf);
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 0f88acf..db50f78 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c
@@ -1420,7 +1420,7 @@ bch->nr = i + ch; bch->slot = i + ch; bch->debug = debug; - mISDN_initbchannel(bch, MAX_DATA_MEM); + mISDN_initbchannel(bch, MAX_DATA_MEM, 0); bch->hw = hc; bch->ch.send = handle_bmsg; bch->ch.ctrl = l1oip_bctrl;
diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c index d8433f2..73973fd 100644 --- a/drivers/leds/leds-netxbig.c +++ b/drivers/leds/leds-netxbig.c
@@ -112,7 +112,7 @@ return err; } -static void __devexit gpio_ext_free(struct netxbig_gpio_ext *gpio_ext) +static void gpio_ext_free(struct netxbig_gpio_ext *gpio_ext) { int i; @@ -294,7 +294,7 @@ static DEVICE_ATTR(sata, 0644, netxbig_led_sata_show, netxbig_led_sata_store); -static void __devexit delete_netxbig_led(struct netxbig_led_data *led_dat) +static void delete_netxbig_led(struct netxbig_led_data *led_dat) { if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) device_remove_file(led_dat->cdev.dev, &dev_attr_sata);
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c index 2f0a1442..01cf89e 100644 --- a/drivers/leds/leds-ns2.c +++ b/drivers/leds/leds-ns2.c
@@ -255,7 +255,7 @@ return ret; } -static void __devexit delete_ns2_led(struct ns2_led_data *led_dat) +static void delete_ns2_led(struct ns2_led_data *led_dat) { device_remove_file(led_dat->cdev.dev, &dev_attr_sata); led_classdev_unregister(&led_dat->cdev);
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 97e73e5..17e2b47 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c
@@ -1727,8 +1727,7 @@ bitmap->chunkshift = (ffz(~mddev->bitmap_info.chunksize) - BITMAP_BLOCK_SHIFT); - /* now that chunksize and chunkshift are set, we can use these macros */ - chunks = (blocks + bitmap->chunkshift - 1) >> + chunks = (blocks + (1 << bitmap->chunkshift) - 1) >> bitmap->chunkshift; pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO;
diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h index 55ca5ae..b44b0aba 100644 --- a/drivers/md/bitmap.h +++ b/drivers/md/bitmap.h
@@ -101,9 +101,6 @@ #define BITMAP_BLOCK_SHIFT 9 -/* how many blocks per chunk? (this is variable) */ -#define CHUNK_BLOCK_RATIO(bitmap) ((bitmap)->mddev->bitmap_info.chunksize >> BITMAP_BLOCK_SHIFT) - #endif /*
diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c index 1f23e04..08d9a20 100644 --- a/drivers/md/dm-log-userspace-transfer.c +++ b/drivers/md/dm-log-userspace-transfer.c
@@ -134,7 +134,7 @@ { struct dm_ulog_request *tfr = (struct dm_ulog_request *)(msg + 1); - if (!cap_raised(current_cap(), CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN)) return; spin_lock(&receiving_list_lock);
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 922a338..754f38f 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c
@@ -718,8 +718,8 @@ return 0; m->hw_handler_name = kstrdup(dm_shift_arg(as), GFP_KERNEL); - request_module("scsi_dh_%s", m->hw_handler_name); - if (scsi_dh_handler_exist(m->hw_handler_name) == 0) { + if (!try_then_request_module(scsi_dh_handler_exist(m->hw_handler_name), + "scsi_dh_%s", m->hw_handler_name)) { ti->error = "unknown hardware handler type"; ret = -EINVAL; goto fail;
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 213ae32..eb3d138 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c
@@ -279,8 +279,10 @@ hlist_del(&cell->list); - bio_list_add(inmates, cell->holder); - bio_list_merge(inmates, &cell->bios); + if (inmates) { + bio_list_add(inmates, cell->holder); + bio_list_merge(inmates, &cell->bios); + } mempool_free(cell, prison->cell_pool); } @@ -303,9 +305,10 @@ */ static void __cell_release_singleton(struct cell *cell, struct bio *bio) { - hlist_del(&cell->list); BUG_ON(cell->holder != bio); BUG_ON(!bio_list_empty(&cell->bios)); + + __cell_release(cell, NULL); } static void cell_release_singleton(struct cell *cell, struct bio *bio) @@ -1177,6 +1180,7 @@ static void process_discard(struct thin_c *tc, struct bio *bio) { int r; + unsigned long flags; struct pool *pool = tc->pool; struct cell *cell, *cell2; struct cell_key key, key2; @@ -1218,7 +1222,9 @@ m->bio = bio; if (!ds_add_work(&pool->all_io_ds, &m->list)) { + spin_lock_irqsave(&pool->lock, flags); list_add(&m->list, &pool->prepared_discards); + spin_unlock_irqrestore(&pool->lock, flags); wake_worker(pool); } } else { @@ -1626,6 +1632,21 @@ pool->low_water_blocks = pt->low_water_blocks; pool->pf = pt->pf; + /* + * If discard_passdown was enabled verify that the data device + * supports discards. Disable discard_passdown if not; otherwise + * -EOPNOTSUPP will be returned. + */ + if (pt->pf.discard_passdown) { + struct request_queue *q = bdev_get_queue(pt->data_dev->bdev); + if (!q || !blk_queue_discard(q)) { + char buf[BDEVNAME_SIZE]; + DMWARN("Discard unsupported by data device (%s): Disabling discard passdown.", + bdevname(pt->data_dev->bdev, buf)); + pool->pf.discard_passdown = 0; + } + } + return 0; } @@ -1982,19 +2003,6 @@ goto out_flags_changed; } - /* - * If discard_passdown was enabled verify that the data device - * supports discards. Disable discard_passdown if not; otherwise - * -EOPNOTSUPP will be returned. - */ - if (pf.discard_passdown) { - struct request_queue *q = bdev_get_queue(data_dev->bdev); - if (!q || !blk_queue_discard(q)) { - DMWARN("Discard unsupported by data device: Disabling discard passdown."); - pf.discard_passdown = 0; - } - } - pt->pool = pool; pt->ti = ti; pt->metadata_dev = metadata_dev; @@ -2379,7 +2387,7 @@ (unsigned long long)pt->low_water_blocks); count = !pool->pf.zero_new_blocks + !pool->pf.discard_enabled + - !pool->pf.discard_passdown; + !pt->pf.discard_passdown; DMEMIT("%u ", count); if (!pool->pf.zero_new_blocks) @@ -2388,7 +2396,7 @@ if (!pool->pf.discard_enabled) DMEMIT("ignore_discard "); - if (!pool->pf.discard_passdown) + if (!pt->pf.discard_passdown) DMEMIT("no_discard_passdown "); break; @@ -2626,8 +2634,10 @@ if (h->all_io_entry) { INIT_LIST_HEAD(&work); ds_dec(h->all_io_entry, &work); + spin_lock_irqsave(&pool->lock, flags); list_for_each_entry_safe(m, tmp, &work, list) list_add(&m->list, &pool->prepared_discards); + spin_unlock_irqrestore(&pool->lock, flags); } mempool_free(h, pool->endio_hook_pool); @@ -2759,6 +2769,6 @@ module_init(dm_thin_init); module_exit(dm_thin_exit); -MODULE_DESCRIPTION(DM_NAME "device-mapper thin provisioning target"); +MODULE_DESCRIPTION(DM_NAME " thin provisioning target"); MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>"); MODULE_LICENSE("GPL");
diff --git a/drivers/md/md.c b/drivers/md/md.c index 477eb2e..01233d8 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c
@@ -391,6 +391,8 @@ synchronize_rcu(); wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0); mddev->pers->quiesce(mddev, 1); + + del_timer_sync(&mddev->safemode_timer); } EXPORT_SYMBOL_GPL(mddev_suspend);
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index c8dbb84..3f91c2e 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c
@@ -3164,12 +3164,40 @@ return size << conf->chunk_shift; } +static void calc_sectors(struct r10conf *conf, sector_t size) +{ + /* Calculate the number of sectors-per-device that will + * actually be used, and set conf->dev_sectors and + * conf->stride + */ + + size = size >> conf->chunk_shift; + sector_div(size, conf->far_copies); + size = size * conf->raid_disks; + sector_div(size, conf->near_copies); + /* 'size' is now the number of chunks in the array */ + /* calculate "used chunks per device" */ + size = size * conf->copies; + + /* We need to round up when dividing by raid_disks to + * get the stride size. + */ + size = DIV_ROUND_UP_SECTOR_T(size, conf->raid_disks); + + conf->dev_sectors = size << conf->chunk_shift; + + if (conf->far_offset) + conf->stride = 1 << conf->chunk_shift; + else { + sector_div(size, conf->far_copies); + conf->stride = size << conf->chunk_shift; + } +} static struct r10conf *setup_conf(struct mddev *mddev) { struct r10conf *conf = NULL; int nc, fc, fo; - sector_t stride, size; int err = -EINVAL; if (mddev->new_chunk_sectors < (PAGE_SIZE >> 9) || @@ -3219,28 +3247,7 @@ if (!conf->r10bio_pool) goto out; - size = mddev->dev_sectors >> conf->chunk_shift; - sector_div(size, fc); - size = size * conf->raid_disks; - sector_div(size, nc); - /* 'size' is now the number of chunks in the array */ - /* calculate "used chunks per device" in 'stride' */ - stride = size * conf->copies; - - /* We need to round up when dividing by raid_disks to - * get the stride size. - */ - stride += conf->raid_disks - 1; - sector_div(stride, conf->raid_disks); - - conf->dev_sectors = stride << conf->chunk_shift; - - if (fo) - stride = 1; - else - sector_div(stride, fc); - conf->stride = stride << conf->chunk_shift; - + calc_sectors(conf, mddev->dev_sectors); spin_lock_init(&conf->device_lock); INIT_LIST_HEAD(&conf->retry_list); @@ -3468,7 +3475,8 @@ mddev->recovery_cp = oldsize; set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); } - mddev->dev_sectors = sectors; + calc_sectors(conf, sectors); + mddev->dev_sectors = conf->dev_sectors; mddev->resync_max_sectors = size; return 0; }
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 0f64d71..cb888d8 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -1921,6 +1921,10 @@ } else { /* default values */ switch (c->delivery_system) { + case SYS_DVBS: + case SYS_DVBS2: + case SYS_ISDBS: + case SYS_TURBO: case SYS_DVBC_ANNEX_A: case SYS_DVBC_ANNEX_C: fepriv->min_delay = HZ / 20;
diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index 860c112..bef5296 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c
@@ -1018,22 +1018,6 @@ spin_lock_init(&dev->hw_lock); - /* claim the resources */ - error = -EBUSY; - dev->hw_io = pnp_port_start(pnp_dev, 0); - if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) { - dev->hw_io = -1; - dev->irq = -1; - goto error; - } - - dev->irq = pnp_irq(pnp_dev, 0); - if (request_irq(dev->irq, ene_isr, - IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) { - dev->irq = -1; - goto error; - } - pnp_set_drvdata(pnp_dev, dev); dev->pnp_dev = pnp_dev; @@ -1086,6 +1070,22 @@ device_set_wakeup_capable(&pnp_dev->dev, true); device_set_wakeup_enable(&pnp_dev->dev, true); + /* claim the resources */ + error = -EBUSY; + dev->hw_io = pnp_port_start(pnp_dev, 0); + if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) { + dev->hw_io = -1; + dev->irq = -1; + goto error; + } + + dev->irq = pnp_irq(pnp_dev, 0); + if (request_irq(dev->irq, ene_isr, + IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) { + dev->irq = -1; + goto error; + } + error = rc_register_device(rdev); if (error < 0) goto error;
diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index 392d4be..4a3a238 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c
@@ -197,7 +197,7 @@ /* * Newer reviews of this chipset uses port 8 instead of 5 */ - if ((chip != 0x0408) || (chip != 0x0804)) + if ((chip != 0x0408) && (chip != 0x0804)) fintek->logical_dev_cir = LOGICAL_DEV_CIR_REV2; else fintek->logical_dev_cir = LOGICAL_DEV_CIR_REV1; @@ -514,16 +514,6 @@ spin_lock_init(&fintek->fintek_lock); - ret = -EBUSY; - /* now claim resources */ - if (!request_region(fintek->cir_addr, - fintek->cir_port_len, FINTEK_DRIVER_NAME)) - goto failure; - - if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED, - FINTEK_DRIVER_NAME, (void *)fintek)) - goto failure; - pnp_set_drvdata(pdev, fintek); fintek->pdev = pdev; @@ -558,6 +548,16 @@ /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD); + ret = -EBUSY; + /* now claim resources */ + if (!request_region(fintek->cir_addr, + fintek->cir_port_len, FINTEK_DRIVER_NAME)) + goto failure; + + if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED, + FINTEK_DRIVER_NAME, (void *)fintek)) + goto failure; + ret = rc_register_device(rdev); if (ret) goto failure;
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index 682009d..0e49c99 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c
@@ -1515,16 +1515,6 @@ /* initialize raw event */ init_ir_raw_event(&itdev->rawir); - ret = -EBUSY; - /* now claim resources */ - if (!request_region(itdev->cir_addr, - dev_desc->io_region_size, ITE_DRIVER_NAME)) - goto failure; - - if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED, - ITE_DRIVER_NAME, (void *)itdev)) - goto failure; - /* set driver data into the pnp device */ pnp_set_drvdata(pdev, itdev); itdev->pdev = pdev; @@ -1600,6 +1590,16 @@ rdev->driver_name = ITE_DRIVER_NAME; rdev->map_name = RC_MAP_RC6_MCE; + ret = -EBUSY; + /* now claim resources */ + if (!request_region(itdev->cir_addr, + dev_desc->io_region_size, ITE_DRIVER_NAME)) + goto failure; + + if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED, + ITE_DRIVER_NAME, (void *)itdev)) + goto failure; + ret = rc_register_device(rdev); if (ret) goto failure;
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 144f3f5..8b2c071 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c
@@ -1021,24 +1021,6 @@ spin_lock_init(&nvt->nvt_lock); spin_lock_init(&nvt->tx.lock); - ret = -EBUSY; - /* now claim resources */ - if (!request_region(nvt->cir_addr, - CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) - goto failure; - - if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED, - NVT_DRIVER_NAME, (void *)nvt)) - goto failure; - - if (!request_region(nvt->cir_wake_addr, - CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) - goto failure; - - if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED, - NVT_DRIVER_NAME, (void *)nvt)) - goto failure; - pnp_set_drvdata(pdev, nvt); nvt->pdev = pdev; @@ -1085,6 +1067,24 @@ rdev->tx_resolution = XYZ; #endif + ret = -EBUSY; + /* now claim resources */ + if (!request_region(nvt->cir_addr, + CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) + goto failure; + + if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED, + NVT_DRIVER_NAME, (void *)nvt)) + goto failure; + + if (!request_region(nvt->cir_wake_addr, + CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) + goto failure; + + if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED, + NVT_DRIVER_NAME, (void *)nvt)) + goto failure; + ret = rc_register_device(rdev); if (ret) goto failure;
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index af52658..342c2c8 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c
@@ -991,39 +991,10 @@ "(w: 0x%lX, e: 0x%lX, s: 0x%lX, i: %u)\n", data->wbase, data->ebase, data->sbase, data->irq); - if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) { - dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", - data->wbase, data->wbase + WAKEUP_IOMEM_LEN - 1); - err = -EBUSY; - goto exit_free_data; - } - - if (!request_region(data->ebase, EHFUNC_IOMEM_LEN, DRVNAME)) { - dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", - data->ebase, data->ebase + EHFUNC_IOMEM_LEN - 1); - err = -EBUSY; - goto exit_release_wbase; - } - - if (!request_region(data->sbase, SP_IOMEM_LEN, DRVNAME)) { - dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", - data->sbase, data->sbase + SP_IOMEM_LEN - 1); - err = -EBUSY; - goto exit_release_ebase; - } - - err = request_irq(data->irq, wbcir_irq_handler, - IRQF_DISABLED, DRVNAME, device); - if (err) { - dev_err(dev, "Failed to claim IRQ %u\n", data->irq); - err = -EBUSY; - goto exit_release_sbase; - } - led_trigger_register_simple("cir-tx", &data->txtrigger); if (!data->txtrigger) { err = -ENOMEM; - goto exit_free_irq; + goto exit_free_data; } led_trigger_register_simple("cir-rx", &data->rxtrigger); @@ -1062,9 +1033,38 @@ data->dev->priv = data; data->dev->dev.parent = &device->dev; + if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) { + dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", + data->wbase, data->wbase + WAKEUP_IOMEM_LEN - 1); + err = -EBUSY; + goto exit_free_rc; + } + + if (!request_region(data->ebase, EHFUNC_IOMEM_LEN, DRVNAME)) { + dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", + data->ebase, data->ebase + EHFUNC_IOMEM_LEN - 1); + err = -EBUSY; + goto exit_release_wbase; + } + + if (!request_region(data->sbase, SP_IOMEM_LEN, DRVNAME)) { + dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", + data->sbase, data->sbase + SP_IOMEM_LEN - 1); + err = -EBUSY; + goto exit_release_ebase; + } + + err = request_irq(data->irq, wbcir_irq_handler, + IRQF_DISABLED, DRVNAME, device); + if (err) { + dev_err(dev, "Failed to claim IRQ %u\n", data->irq); + err = -EBUSY; + goto exit_release_sbase; + } + err = rc_register_device(data->dev); if (err) - goto exit_free_rc; + goto exit_free_irq; device_init_wakeup(&device->dev, 1); @@ -1072,14 +1072,6 @@ return 0; -exit_free_rc: - rc_free_device(data->dev); -exit_unregister_led: - led_classdev_unregister(&data->led); -exit_unregister_rxtrigger: - led_trigger_unregister_simple(data->rxtrigger); -exit_unregister_txtrigger: - led_trigger_unregister_simple(data->txtrigger); exit_free_irq: free_irq(data->irq, device); exit_release_sbase: @@ -1088,6 +1080,14 @@ release_region(data->ebase, EHFUNC_IOMEM_LEN); exit_release_wbase: release_region(data->wbase, WAKEUP_IOMEM_LEN); +exit_free_rc: + rc_free_device(data->dev); +exit_unregister_led: + led_classdev_unregister(&data->led); +exit_unregister_rxtrigger: + led_trigger_unregister_simple(data->rxtrigger); +exit_unregister_txtrigger: + led_trigger_unregister_simple(data->txtrigger); exit_free_data: kfree(data); pnp_set_drvdata(device, NULL);
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index db8e508..863c755 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c
@@ -2923,6 +2923,10 @@ * not the JPEG end of frame ('ff d9'). */ + /* count the packets and their size */ + sd->npkt++; + sd->pktsz += len; + /*fixme: assumption about the following code: * - there can be only one marker in a packet */ @@ -2945,10 +2949,6 @@ data += i; } - /* count the packets and their size */ - sd->npkt++; - sd->pktsz += len; - /* search backwards if there is a marker in the packet */ for (i = len - 1; --i >= 0; ) { if (data[i] != 0xff) {
diff --git a/drivers/media/video/marvell-ccic/mmp-driver.c b/drivers/media/video/marvell-ccic/mmp-driver.c index d235523..c4c17fe 100644 --- a/drivers/media/video/marvell-ccic/mmp-driver.c +++ b/drivers/media/video/marvell-ccic/mmp-driver.c
@@ -181,7 +181,6 @@ INIT_LIST_HEAD(&cam->devlist); mcam = &cam->mcam; - mcam->platform = MHP_Armada610; mcam->plat_power_up = mmpcam_power_up; mcam->plat_power_down = mmpcam_power_down; mcam->dev = &pdev->dev;
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index b06efd2..7e9b2c6 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -246,28 +246,37 @@ } -static unsigned int get_plane_size(struct fimc_frame *fr, unsigned int plane) -{ - if (!fr || plane >= fr->fmt->memplanes) - return 0; - return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8; -} - -static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt, +static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt, unsigned int *num_buffers, unsigned int *num_planes, unsigned int sizes[], void *allocators[]) { + const struct v4l2_pix_format_mplane *pixm = NULL; struct fimc_ctx *ctx = vq->drv_priv; - struct fimc_fmt *fmt = ctx->d_frame.fmt; + struct fimc_frame *frame = &ctx->d_frame; + struct fimc_fmt *fmt = frame->fmt; + unsigned long wh; int i; - if (!fmt) + if (pfmt) { + pixm = &pfmt->fmt.pix_mp; + fmt = fimc_find_format(&pixm->pixelformat, NULL, + FMT_FLAGS_CAM | FMT_FLAGS_M2M, -1); + wh = pixm->width * pixm->height; + } else { + wh = frame->f_width * frame->f_height; + } + + if (fmt == NULL) return -EINVAL; *num_planes = fmt->memplanes; for (i = 0; i < fmt->memplanes; i++) { - sizes[i] = get_plane_size(&ctx->d_frame, i); + unsigned int size = (wh * fmt->depth[i]) / 8; + if (pixm) + sizes[i] = max(size, pixm->plane_fmt[i].sizeimage); + else + sizes[i] = size; allocators[i] = ctx->fimc_dev->alloc_ctx; } @@ -1383,7 +1392,7 @@ fimc_capture_try_crop(ctx, r, crop->pad); if (crop->which == V4L2_SUBDEV_FORMAT_TRY) { - mutex_lock(&fimc->lock); + mutex_unlock(&fimc->lock); *v4l2_subdev_get_try_crop(fh, crop->pad) = *r; return 0; }
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index e184e65..e09ba7b 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -1048,14 +1048,14 @@ * @mask: the color flags to match * @index: offset in the fimc_formats array, ignored if negative */ -struct fimc_fmt *fimc_find_format(u32 *pixelformat, u32 *mbus_code, +struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code, unsigned int mask, int index) { struct fimc_fmt *fmt, *def_fmt = NULL; unsigned int i; int id = 0; - if (index >= ARRAY_SIZE(fimc_formats)) + if (index >= (int)ARRAY_SIZE(fimc_formats)) return NULL; for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) {
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index a18291e..84fd835 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h
@@ -718,7 +718,7 @@ int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f); void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height, struct v4l2_pix_format_mplane *pix); -struct fimc_fmt *fimc_find_format(u32 *pixelformat, u32 *mbus_code, +struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code, unsigned int mask, int index); int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index eb25756..aedb970 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c
@@ -530,7 +530,10 @@ if (icl->reset) icl->reset(icd->pdev); + /* Don't mess with the host during probe */ + mutex_lock(&ici->host_lock); ret = ici->ops->add(icd); + mutex_unlock(&ici->host_lock); if (ret < 0) { dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret); goto eiciadd; @@ -956,7 +959,7 @@ { struct soc_camera_device *icd; - mutex_lock(&list_lock); + mutex_lock(&ici->host_lock); list_for_each_entry(icd, &devices, list) { if (icd->iface == ici->nr) { @@ -967,7 +970,7 @@ } } - mutex_unlock(&list_lock); + mutex_unlock(&ici->host_lock); } #ifdef CONFIG_I2C_BOARDINFO @@ -1313,6 +1316,7 @@ list_add_tail(&ici->list, &hosts); mutex_unlock(&list_lock); + mutex_init(&ici->host_lock); scan_add_host(ici); return 0;
diff --git a/drivers/media/video/videobuf2-dma-contig.c b/drivers/media/video/videobuf2-dma-contig.c index f17ad98..4b71326 100644 --- a/drivers/media/video/videobuf2-dma-contig.c +++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -15,6 +15,7 @@ #include <linux/dma-mapping.h> #include <media/videobuf2-core.h> +#include <media/videobuf2-dma-contig.h> #include <media/videobuf2-memops.h> struct vb2_dc_conf { @@ -85,7 +86,7 @@ { struct vb2_dc_buf *buf = buf_priv; if (!buf) - return 0; + return NULL; return buf->vaddr; }
diff --git a/drivers/media/video/videobuf2-memops.c b/drivers/media/video/videobuf2-memops.c index c41cb60..504cd4c 100644 --- a/drivers/media/video/videobuf2-memops.c +++ b/drivers/media/video/videobuf2-memops.c
@@ -55,6 +55,7 @@ return vma_copy; } +EXPORT_SYMBOL_GPL(vb2_get_vma); /** * vb2_put_userptr() - release a userspace virtual memory area
diff --git a/drivers/message/fusion/mptlan.h b/drivers/message/fusion/mptlan.h index c171afa..69e9d54 100644 --- a/drivers/message/fusion/mptlan.h +++ b/drivers/message/fusion/mptlan.h
@@ -69,7 +69,6 @@ #include <linux/spinlock.h> #include <linux/workqueue.h> #include <linux/delay.h> -// #include <linux/trdevice.h> #include <asm/uaccess.h> #include <asm/io.h>
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 58fc65f..f2f482b 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c
@@ -376,7 +376,7 @@ * Make a fake call to mtd_read_fact_prot_reg() to check if OTP * operations are supported. */ - if (mtd_read_fact_prot_reg(mtd, -1, -1, &retlen, NULL) == -EOPNOTSUPP) + if (mtd_read_fact_prot_reg(mtd, -1, 0, &retlen, NULL) == -EOPNOTSUPP) return -EOPNOTSUPP; switch (mode) {
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index 7341695..861ca8f 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c
@@ -212,18 +212,17 @@ /* Link the private data with the MTD structure */ ams_delta_mtd->priv = this; - if (!request_mem_region(res->start, resource_size(res), - dev_name(&pdev->dev))) { - dev_err(&pdev->dev, "request_mem_region failed\n"); - err = -EBUSY; - goto out_free; - } + /* + * Don't try to request the memory region from here, + * it should have been already requested from the + * gpio-omap driver and requesting it again would fail. + */ io_base = ioremap(res->start, resource_size(res)); if (io_base == NULL) { dev_err(&pdev->dev, "ioremap failed\n"); err = -EIO; - goto out_release_io; + goto out_free; } this->priv = io_base; @@ -271,8 +270,6 @@ platform_set_drvdata(pdev, NULL); gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB); iounmap(io_base); -out_release_io: - release_mem_region(res->start, resource_size(res)); out_free: kfree(ams_delta_mtd); out: @@ -285,7 +282,6 @@ static int __devexit ams_delta_cleanup(struct platform_device *pdev) { void __iomem *io_base = platform_get_drvdata(pdev); - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); /* Release resources, unregister device */ nand_release(ams_delta_mtd); @@ -293,7 +289,6 @@ gpio_free_array(_mandatory_gpio, ARRAY_SIZE(_mandatory_gpio)); gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB); iounmap(io_base); - release_mem_region(res->start, resource_size(res)); /* Free the MTD device structure */ kfree(ams_delta_mtd);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index b982854..0c2bd80 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig
@@ -66,10 +66,7 @@ <http://www.tldp.org/docs.html#guide>. 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. + will be called dummy. config EQUALIZER tristate "EQL (serial line load balancing) support" @@ -285,8 +282,6 @@ source "drivers/s390/net/Kconfig" -source "drivers/net/tokenring/Kconfig" - source "drivers/net/usb/Kconfig" source "drivers/net/wireless/Kconfig"
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index a6b8ce1..3d375ca 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile
@@ -50,7 +50,6 @@ obj-$(CONFIG_SLHC) += slip/ obj-$(CONFIG_NET_SB1000) += sb1000.o obj-$(CONFIG_SUNGEM_PHY) += sungem_phy.o -obj-$(CONFIG_TR) += tokenring/ obj-$(CONFIG_WAN) += wan/ obj-$(CONFIG_WLAN) += wireless/ obj-$(CONFIG_WIMAX) += wimax/
diff --git a/drivers/net/Space.c b/drivers/net/Space.c index 88bbd8f..e3f0fac 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c
@@ -29,7 +29,6 @@ */ #include <linux/netdevice.h> #include <linux/etherdevice.h> -#include <linux/trdevice.h> #include <linux/errno.h> #include <linux/init.h> #include <linux/netlink.h> @@ -134,22 +133,9 @@ {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 */ @@ -279,51 +265,10 @@ (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; -} - -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) { @@ -333,11 +278,6 @@ 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/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 793b001..3463b46 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c
@@ -2173,9 +2173,10 @@ * 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)) { @@ -2184,11 +2185,12 @@ if (!port->slave) { pr_warning("%s: Warning: port of slave %s is uninitialized\n", slave->dev->name, slave->dev->master->name); - return; + return ret; } switch (lacpdu->subtype) { case AD_TYPE_LACPDU: + ret = RX_HANDLER_CONSUMED; pr_debug("Received LACPDU on port %d\n", port->actor_port_number); /* Protect against concurrent state machines */ @@ -2198,6 +2200,7 @@ break; case AD_TYPE_MARKER: + 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) { @@ -2219,6 +2222,7 @@ } } } + return ret; } /** @@ -2456,18 +2460,20 @@ return NETDEV_TX_OK; } -void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, +int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, struct slave *slave) { + int ret = RX_HANDLER_ANOTHER; if (skb->protocol != PKT_TYPE_LACPDU) - return; + return ret; if (!pskb_may_pull(skb, sizeof(struct lacpdu))) - return; + return ret; read_lock(&bond->lock); - bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); + ret = bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); read_unlock(&bond->lock); + return ret; } /*
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index 235b2cc..5ee7e3c 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h
@@ -274,7 +274,7 @@ 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_xmit_xor(struct sk_buff *skb, struct net_device *dev); -void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, +int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, struct slave *slave); int bond_3ad_set_carrier(struct bonding *bond); void bond_3ad_update_lacp_rate(struct bonding *bond);
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 9abfde4..0f59c15 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c
@@ -332,7 +332,7 @@ if ((client_info->assigned) && (client_info->ip_src == arp->ip_dst) && (client_info->ip_dst == arp->ip_src) && - (compare_ether_addr_64bits(client_info->mac_dst, arp->mac_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); client_info->ntt = 1; @@ -342,26 +342,26 @@ _unlock_rx_hashtbl_bh(bond); } -static void rlb_arp_recv(struct sk_buff *skb, struct bonding *bond, +static int rlb_arp_recv(struct sk_buff *skb, struct bonding *bond, struct slave *slave) { struct arp_pkt *arp; if (skb->protocol != cpu_to_be16(ETH_P_ARP)) - return; + goto out; arp = (struct arp_pkt *) skb->data; if (!arp) { pr_debug("Packet has no ARP data\n"); - return; + goto out; } if (!pskb_may_pull(skb, arp_hdr_len(bond->dev))) - return; + goto out; if (skb->len < sizeof(struct arp_pkt)) { pr_debug("Packet is too small to be an ARP\n"); - return; + goto out; } if (arp->op_code == htons(ARPOP_REPLY)) { @@ -369,6 +369,8 @@ rlb_update_entry_from_arp(bond, arp); pr_debug("Server received an ARP Reply from client\n"); } +out: + return RX_HANDLER_ANOTHER; } /* Caller must hold bond lock for read */ @@ -448,8 +450,8 @@ if (assigned_slave) { rx_hash_table[index].slave = assigned_slave; - if (compare_ether_addr_64bits(rx_hash_table[index].mac_dst, - mac_bcast)) { + 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 @@ -561,7 +563,7 @@ client_info = &(bond_info->rx_hashtbl[hash_index]); if ((client_info->slave == slave) && - compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) { + !ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) { client_info->ntt = 1; ntt = 1; } @@ -600,9 +602,9 @@ * unicast mac address. */ if ((client_info->ip_src == src_ip) && - compare_ether_addr_64bits(client_info->slave->dev->dev_addr, - bond->dev->dev_addr) && - compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) { + !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; } @@ -629,7 +631,7 @@ if ((client_info->ip_src == arp->ip_src) && (client_info->ip_dst == arp->ip_dst)) { /* the entry is already assigned to this client */ - if (compare_ether_addr_64bits(arp->mac_dst, mac_bcast)) { + 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); } @@ -664,7 +666,7 @@ memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN); client_info->slave = assigned_slave; - if (compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) { + if (!ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) { client_info->ntt = 1; bond->alb_info.rx_ntt = 1; } else { @@ -1009,18 +1011,18 @@ int perm_curr_diff; int perm_bond_diff; - perm_curr_diff = compare_ether_addr_64bits(slave->perm_hwaddr, - slave->dev->dev_addr); - perm_bond_diff = compare_ether_addr_64bits(slave->perm_hwaddr, - bond->dev->dev_addr); + 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 (!compare_ether_addr_64bits(slave->perm_hwaddr, - tmp_slave->dev->dev_addr)) { + if (ether_addr_equal_64bits(slave->perm_hwaddr, + tmp_slave->dev->dev_addr)) { found = 1; break; } @@ -1074,10 +1076,10 @@ * check uniqueness of slave's mac address against the other * slaves in the bond. */ - if (compare_ether_addr_64bits(slave->perm_hwaddr, bond->dev->dev_addr)) { + if (!ether_addr_equal_64bits(slave->perm_hwaddr, bond->dev->dev_addr)) { bond_for_each_slave(bond, tmp_slave1, i) { - if (!compare_ether_addr_64bits(tmp_slave1->dev->dev_addr, - slave->dev->dev_addr)) { + if (ether_addr_equal_64bits(tmp_slave1->dev->dev_addr, + slave->dev->dev_addr)) { found = 1; break; } @@ -1099,8 +1101,8 @@ bond_for_each_slave(bond, tmp_slave1, i) { found = 0; bond_for_each_slave(bond, tmp_slave2, j) { - if (!compare_ether_addr_64bits(tmp_slave1->perm_hwaddr, - tmp_slave2->dev->dev_addr)) { + if (ether_addr_equal_64bits(tmp_slave1->perm_hwaddr, + tmp_slave2->dev->dev_addr)) { found = 1; break; } @@ -1115,8 +1117,8 @@ } if (!has_bond_addr) { - if (!compare_ether_addr_64bits(tmp_slave1->dev->dev_addr, - bond->dev->dev_addr)) { + if (ether_addr_equal_64bits(tmp_slave1->dev->dev_addr, + bond->dev->dev_addr)) { has_bond_addr = tmp_slave1; } @@ -1257,7 +1259,7 @@ case ETH_P_IP: { const struct iphdr *iph = ip_hdr(skb); - if (!compare_ether_addr_64bits(eth_data->h_dest, mac_bcast) || + if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast) || (iph->daddr == ip_bcast) || (iph->protocol == IPPROTO_IGMP)) { do_tx_balance = 0; @@ -1271,7 +1273,7 @@ /* IPv6 doesn't really use broadcast mac address, but leave * that here just in case. */ - if (!compare_ether_addr_64bits(eth_data->h_dest, mac_bcast)) { + if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast)) { do_tx_balance = 0; break; } @@ -1279,7 +1281,7 @@ /* IPv6 uses all-nodes multicast as an equivalent to * broadcasts in IPv4. */ - if (!compare_ether_addr_64bits(eth_data->h_dest, mac_v6_allmcast)) { + if (ether_addr_equal_64bits(eth_data->h_dest, mac_v6_allmcast)) { do_tx_balance = 0; break; } @@ -1603,8 +1605,8 @@ struct slave *tmp_slave; /* find slave that is holding the bond's mac address */ bond_for_each_slave(bond, tmp_slave, i) { - if (!compare_ether_addr_64bits(tmp_slave->dev->dev_addr, - bond->dev->dev_addr)) { + if (ether_addr_equal_64bits(tmp_slave->dev->dev_addr, + bond->dev->dev_addr)) { swap_slave = tmp_slave; break; } @@ -1681,8 +1683,8 @@ swap_slave = NULL; bond_for_each_slave(bond, slave, i) { - if (!compare_ether_addr_64bits(slave->dev->dev_addr, - bond_dev->dev_addr)) { + if (ether_addr_equal_64bits(slave->dev->dev_addr, + bond_dev->dev_addr)) { swap_slave = slave; break; }
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 16dbf53..2ee8cf9 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c
@@ -1444,8 +1444,9 @@ struct sk_buff *skb = *pskb; struct slave *slave; struct bonding *bond; - void (*recv_probe)(struct sk_buff *, struct bonding *, + int (*recv_probe)(struct sk_buff *, struct bonding *, struct slave *); + int ret = RX_HANDLER_ANOTHER; skb = skb_share_check(skb, GFP_ATOMIC); if (unlikely(!skb)) @@ -1464,8 +1465,12 @@ struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); if (likely(nskb)) { - recv_probe(nskb, bond, slave); + ret = recv_probe(nskb, bond, slave); dev_kfree_skb(nskb); + if (ret == RX_HANDLER_CONSUMED) { + consume_skb(skb); + return ret; + } } } @@ -1487,7 +1492,7 @@ memcpy(eth_hdr(skb)->h_dest, bond->dev->dev_addr, ETH_ALEN); } - return RX_HANDLER_ANOTHER; + return ret; } /* enslave device <slave> to bond device <master> */ @@ -1961,7 +1966,7 @@ write_lock_bh(&bond->lock); if (!bond->params.fail_over_mac) { - if (!compare_ether_addr(bond_dev->dev_addr, slave->perm_hwaddr) && + if (ether_addr_equal(bond_dev->dev_addr, slave->perm_hwaddr) && bond->slave_cnt > 1) pr_warning("%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, @@ -2732,7 +2737,7 @@ } } -static void bond_arp_rcv(struct sk_buff *skb, struct bonding *bond, +static int bond_arp_rcv(struct sk_buff *skb, struct bonding *bond, struct slave *slave) { struct arphdr *arp; @@ -2740,7 +2745,7 @@ __be32 sip, tip; if (skb->protocol != __cpu_to_be16(ETH_P_ARP)) - return; + return RX_HANDLER_ANOTHER; read_lock(&bond->lock); @@ -2785,6 +2790,7 @@ out_unlock: read_unlock(&bond->lock); + return RX_HANDLER_ANOTHER; } /*
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 9f2bae66..4581aa5 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h
@@ -218,7 +218,7 @@ struct slave *primary_slave; bool force_primary; s32 slave_cnt; /* never change this value outside the attach/detach wrappers */ - void (*recv_probe)(struct sk_buff *, struct bonding *, + int (*recv_probe)(struct sk_buff *, struct bonding *, struct slave *); rwlock_t lock; rwlock_t curr_slave_lock;
diff --git a/drivers/net/ethernet/3com/3c509.c b/drivers/net/ethernet/3com/3c509.c index 41719da..1a8eef2 100644 --- a/drivers/net/ethernet/3com/3c509.c +++ b/drivers/net/ethernet/3com/3c509.c
@@ -69,7 +69,6 @@ #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> @@ -102,7 +101,7 @@ #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 @@ -163,7 +162,7 @@ */ #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; @@ -505,41 +504,6 @@ 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 int mca_registered; -#endif /* CONFIG_MCA */ - static const struct net_device_ops netdev_ops = { .ndo_open = el3_open, .ndo_stop = el3_close, @@ -600,76 +564,6 @@ 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; - - - pr_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) { - pr_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); - dev_set_drvdata(device, dev); - err = el3_common_init(dev); - - if (err) { - dev_set_drvdata(device, 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) { @@ -1547,11 +1441,6 @@ 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) @@ -1563,10 +1452,6 @@ if (eisa_registered) ret = 0; #endif -#ifdef CONFIG_MCA - if (mca_registered) - ret = 0; -#endif return ret; } @@ -1584,10 +1469,6 @@ 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/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig index 910895c..2e53867 100644 --- a/drivers/net/ethernet/8390/Kconfig +++ b/drivers/net/ethernet/8390/Kconfig
@@ -182,18 +182,6 @@ To compile this driver as a module, choose M here. The module will be called ne. -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 NE2K_PCI tristate "PCI NE2000 and clones support (see help)" depends on PCI @@ -267,18 +255,6 @@ If unsure, say N. -config ULTRAMCA - tristate "SMC Ultra MCA support" - depends on 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 ISA
diff --git a/drivers/net/ethernet/8390/Makefile b/drivers/net/ethernet/8390/Makefile index 3337d7f..d13790b 100644 --- a/drivers/net/ethernet/8390/Makefile +++ b/drivers/net/ethernet/8390/Makefile
@@ -24,6 +24,5 @@ obj-$(CONFIG_STNIC) += stnic.o 8390.o obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o obj-$(CONFIG_ULTRA32) += smc-ultra32.o 8390.o -obj-$(CONFIG_ULTRAMCA) += smc-mca.o 8390.o obj-$(CONFIG_WD80x3) += wd.o 8390.o obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o
diff --git a/drivers/net/ethernet/8390/ne2.c b/drivers/net/ethernet/8390/ne2.c deleted file mode 100644 index ef85839..0000000 --- a/drivers/net/ethernet/8390/ne2.c +++ /dev/null
@@ -1,798 +0,0 @@ -/* ne2.c: A NE/2 Ethernet Driver for Linux. */ -/* - Based on the NE2000 driver written by Donald Becker (1992-94). - modified by Wim Dumon (Apr 1996) - - 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 wimpie@linux.cc.kuleuven.ac.be - - Currently supported: NE/2 - This patch was never tested on other MCA-ethernet adapters, but it - might work. Just give it a try and let me know if you have problems. - Also mail me if it really works, please! - - Changelog: - Mon Feb 3 16:26:02 MET 1997 - - adapted the driver to work with the 2.1.25 kernel - - multiple ne2 support (untested) - - module support (untested) - - Fri Aug 28 00:18:36 CET 1998 (David Weinehall) - - fixed a few minor typos - - made the MODULE_PARM conditional (it only works with the v2.1.x kernels) - - fixed the module support (Now it's working...) - - Mon Sep 7 19:01:44 CET 1998 (David Weinehall) - - added support for Arco Electronics AE/2-card (experimental) - - Mon Sep 14 09:53:42 CET 1998 (David Weinehall) - - added support for Compex ENET-16MC/P (experimental) - - Tue Sep 15 16:21:12 CET 1998 (David Weinehall, Magnus Jonsson, Tomas Ogren) - - Miscellaneous bugfixes - - Tue Sep 19 16:21:12 CET 1998 (Magnus Jonsson) - - Cleanup - - Wed Sep 23 14:33:34 CET 1998 (David Weinehall) - - Restructuring and rewriting for v2.1.x compliance - - Wed Oct 14 17:19:21 CET 1998 (David Weinehall) - - Added code that unregisters irq and proc-info - - Version# bump - - Mon Nov 16 15:28:23 CET 1998 (Wim Dumon) - - pass 'dev' as last parameter of request_irq in stead of 'NULL' - - Wed Feb 7 21:24:00 CET 2001 (Alfred Arnold) - - added support for the D-Link DE-320CT - - * WARNING - ------- - This is alpha-test software. It is not guaranteed to work. As a - matter of fact, I'm quite sure there are *LOTS* of bugs in here. I - would like to hear from you if you use this driver, even if it works. - If it doesn't work, be sure to send me a mail with the problems ! -*/ - -static const char *version = "ne2.c:v0.91 Nov 16 1998 Wim Dumon <wimpie@kotnet.org>\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/string.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/mca-legacy.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/bitops.h> -#include <linux/jiffies.h> - -#include <asm/io.h> -#include <asm/dma.h> - -#include "8390.h" - -#define DRV_NAME "ne2" - -/* Some defines that people can play with if so inclined. */ - -/* Do we perform extra sanity checks on stuff ? */ -/* #define NE_SANITY_CHECK */ - -/* Do we implement the read before write bugfix ? */ -/* #define NE_RW_BUGFIX */ - -/* Do we have a non std. amount of memory? (in units of 256 byte pages) */ -/* #define PACKETBUF_MEMSIZE 0x40 */ - - -/* ---- No user-serviceable parts below ---- */ - -#define NE_BASE (dev->base_addr) -#define NE_CMD 0x00 -#define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ -#define NE_RESET 0x20 /* Issue a read to reset, a write to clear. */ -#define NE_IO_EXTENT 0x30 - -#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 */ - -/* From the .ADF file: */ -static unsigned int addresses[7] __initdata = - {0x1000, 0x2020, 0x8020, 0xa0a0, 0xb0b0, 0xc0c0, 0xc3d0}; -static int irqs[4] __initdata = {3, 4, 5, 9}; - -/* From the D-Link ADF file: */ -static unsigned int dlink_addresses[4] __initdata = - {0x300, 0x320, 0x340, 0x360}; -static int dlink_irqs[8] __initdata = {3, 4, 5, 9, 10, 11, 14, 15}; - -struct ne2_adapters_t { - unsigned int id; - char *name; -}; - -static struct ne2_adapters_t ne2_adapters[] __initdata = { - { 0x6354, "Arco Ethernet Adapter AE/2" }, - { 0x70DE, "Compex ENET-16 MC/P" }, - { 0x7154, "Novell Ethernet Adapter NE/2" }, - { 0x56ea, "D-Link DE-320CT" }, - { 0x0000, NULL } -}; - -extern int netcard_probe(struct net_device *dev); - -static int ne2_probe1(struct net_device *dev, int slot); - -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); -static void ne_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); -static void ne_block_output(struct net_device *dev, const int count, - const unsigned char *buf, const int start_page); - - -/* - * special code to read the DE-320's MAC address EEPROM. In contrast to a - * standard NE design, this is a serial EEPROM (93C46) that has to be read - * bit by bit. The EEPROM cotrol port at base + 0x1e has the following - * layout: - * - * Bit 0 = Data out (read from EEPROM) - * Bit 1 = Data in (write to EEPROM) - * Bit 2 = Clock - * Bit 3 = Chip Select - * Bit 7 = ~50 kHz clock for defined delays - * - */ - -static void __init dlink_put_eeprom(unsigned char value, unsigned int addr) -{ - int z; - unsigned char v1, v2; - - /* write the value to the NIC EEPROM register */ - - outb(value, addr + 0x1e); - - /* now wait the clock line to toggle twice. Effectively, we are - waiting (at least) for one clock cycle */ - - for (z = 0; z < 2; z++) { - do { - v1 = inb(addr + 0x1e); - v2 = inb(addr + 0x1e); - } - while (!((v1 ^ v2) & 0x80)); - } -} - -static void __init dlink_send_eeprom_bit(unsigned int bit, unsigned int addr) -{ - /* shift data bit into correct position */ - - bit = bit << 1; - - /* write value, keep clock line high for two cycles */ - - dlink_put_eeprom(0x09 | bit, addr); - dlink_put_eeprom(0x0d | bit, addr); - dlink_put_eeprom(0x0d | bit, addr); - dlink_put_eeprom(0x09 | bit, addr); -} - -static void __init dlink_send_eeprom_word(unsigned int value, unsigned int len, unsigned int addr) -{ - int z; - - /* adjust bits so that they are left-aligned in a 16-bit-word */ - - value = value << (16 - len); - - /* shift bits out to the EEPROM */ - - for (z = 0; z < len; z++) { - dlink_send_eeprom_bit((value & 0x8000) >> 15, addr); - value = value << 1; - } -} - -static unsigned int __init dlink_get_eeprom(unsigned int eeaddr, unsigned int addr) -{ - int z; - unsigned int value = 0; - - /* pull the CS line low for a moment. This resets the EEPROM- - internal logic, and makes it ready for a new command. */ - - dlink_put_eeprom(0x01, addr); - dlink_put_eeprom(0x09, addr); - - /* send one start bit, read command (1 - 0), plus the address to - the EEPROM */ - - dlink_send_eeprom_word(0x0180 | (eeaddr & 0x3f), 9, addr); - - /* get the data word. We clock by sending 0s to the EEPROM, which - get ignored during the read process */ - - for (z = 0; z < 16; z++) { - dlink_send_eeprom_bit(0, addr); - value = (value << 1) | (inb(addr + 0x1e) & 0x01); - } - - return value; -} - -/* - * Note that at boot, this probe only picks up one card at a time. - */ - -static int __init do_ne2_probe(struct net_device *dev) -{ - static int current_mca_slot = -1; - int i; - int adapter_found = 0; - - /* 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; (ne2_adapters[i].name != NULL) && !adapter_found; i++) { - current_mca_slot = - mca_find_unused_adapter(ne2_adapters[i].id, 0); - - if((current_mca_slot != MCA_NOTFOUND) && !adapter_found) { - int res; - mca_set_adapter_name(current_mca_slot, - ne2_adapters[i].name); - mca_mark_as_used(current_mca_slot); - - res = ne2_probe1(dev, current_mca_slot); - if (res) - mca_mark_as_unused(current_mca_slot); - return res; - } - } - return -ENODEV; -} - -#ifndef MODULE -struct net_device * __init ne2_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_ne2_probe(dev); - if (err) - goto out; - return dev; -out: - free_netdev(dev); - return ERR_PTR(err); -} -#endif - -static int ne2_procinfo(char *buf, int slot, struct net_device *dev) -{ - int len=0; - - len += sprintf(buf+len, "The NE/2 Ethernet Adapter\n" ); - len += sprintf(buf+len, "Driver written by Wim Dumon "); - len += sprintf(buf+len, "<wimpie@kotnet.org>\n"); - len += sprintf(buf+len, "Modified by "); - len += sprintf(buf+len, "David Weinehall <tao@acc.umu.se>\n"); - len += sprintf(buf+len, "and by Magnus Jonsson <bigfoot@acc.umu.se>\n"); - len += sprintf(buf+len, "Based on the original NE2000 drivers\n" ); - len += sprintf(buf+len, "Base IO: %#x\n", (unsigned int)dev->base_addr); - len += sprintf(buf+len, "IRQ : %d\n", dev->irq); - len += sprintf(buf+len, "HW addr : %pM\n", dev->dev_addr); - - return len; -} - -static int __init ne2_probe1(struct net_device *dev, int slot) -{ - int i, base_addr, irq, retval; - unsigned char POS; - unsigned char SA_prom[32]; - const char *name = "NE/2"; - int start_page, stop_page; - static unsigned version_printed; - - if (ei_debug && version_printed++ == 0) - printk(version); - - printk("NE/2 ethercard found in slot %d:", slot); - - /* Read base IO and IRQ from the POS-registers */ - POS = mca_read_stored_pos(slot, 2); - if(!(POS % 2)) { - printk(" disabled.\n"); - return -ENODEV; - } - - /* handle different POS register structure for D-Link card */ - - if (mca_read_stored_pos(slot, 0) == 0xea) { - base_addr = dlink_addresses[(POS >> 5) & 0x03]; - irq = dlink_irqs[(POS >> 2) & 0x07]; - } - else { - i = (POS & 0xE)>>1; - /* printk("Halleluja sdog, als er na de pijl een 1 staat is 1 - 1 == 0" - " en zou het moeten werken -> %d\n", i); - The above line was for remote testing, thanx to sdog ... */ - base_addr = addresses[i - 1]; - irq = irqs[(POS & 0x60)>>5]; - } - - if (!request_region(base_addr, NE_IO_EXTENT, DRV_NAME)) - return -EBUSY; - -#ifdef DEBUG - printk("POS info : pos 2 = %#x ; base = %#x ; irq = %ld\n", POS, - base_addr, irq); -#endif - -#ifndef CRYNWR_WAY - /* Reset the card the way they do it in the Crynwr packet driver */ - for (i=0; i<8; i++) - outb(0x0, base_addr + NE_RESET); - inb(base_addr + NE_RESET); - outb(0x21, base_addr + NE_CMD); - if (inb(base_addr + NE_CMD) != 0x21) { - printk("NE/2 adapter not responding\n"); - retval = -ENODEV; - goto out; - } - - /* In the crynwr sources they do a RAM-test here. I skip it. I suppose - my RAM is okay. Suppose your memory is broken. Then this test - should fail and you won't be able to use your card. But if I do not - test, you won't be able to use your card, neither. So this test - won't help you. */ - -#else /* _I_ never tested it this way .. Go ahead and try ...*/ - /* Reset card. Who knows what dain-bramaged state it was left in. */ - { - unsigned long reset_start_time = jiffies; - - /* DON'T change these to inb_p/outb_p or reset will fail on - clones.. */ - outb(inb(base_addr + NE_RESET), base_addr + NE_RESET); - - while ((inb_p(base_addr + EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { - printk(" not found (no reset ack).\n"); - retval = -ENODEV; - goto out; - } - - outb_p(0xff, base_addr + EN0_ISR); /* Ack all intr. */ - } -#endif - - - /* Read the 16 bytes of station address PROM. - We must first initialize registers, similar to - NS8390p_init(eifdev, 0). - We can't reliably read the SAPROM address without this. - (I learned the hard way!). */ - { - struct { - unsigned char value, offset; - } program_seq[] = { - /* Select page 0 */ - {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, - {0x49, EN0_DCFG}, /* Set WORD-wide (0x49) access. */ - {0x00, EN0_RCNTLO}, /* Clear the count regs. */ - {0x00, EN0_RCNTHI}, - {0x00, EN0_IMR}, /* Mask completion irq. */ - {0xFF, EN0_ISR}, - {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ - {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ - {32, EN0_RCNTLO}, - {0x00, EN0_RCNTHI}, - {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ - {0x00, EN0_RSARHI}, - {E8390_RREAD+E8390_START, E8390_CMD}, - }; - - for (i = 0; i < ARRAY_SIZE(program_seq); i++) - outb_p(program_seq[i].value, base_addr + - program_seq[i].offset); - - } - for(i = 0; i < 6 /*sizeof(SA_prom)*/; i+=1) { - SA_prom[i] = inb(base_addr + NE_DATAPORT); - } - - /* I don't know whether the previous sequence includes the general - board reset procedure, so better don't omit it and just overwrite - the garbage read from a DE-320 with correct stuff. */ - - if (mca_read_stored_pos(slot, 0) == 0xea) { - unsigned int v; - - for (i = 0; i < 3; i++) { - v = dlink_get_eeprom(i, base_addr); - SA_prom[(i << 1) ] = v & 0xff; - SA_prom[(i << 1) + 1] = (v >> 8) & 0xff; - } - } - - start_page = NESM_START_PG; - stop_page = NESM_STOP_PG; - - dev->irq=irq; - - /* Snarf the interrupt now. There's no point in waiting since we cannot - share and the board will usually be enabled. */ - retval = request_irq(dev->irq, eip_interrupt, 0, DRV_NAME, dev); - if (retval) { - printk (" unable to get IRQ %d (irqval=%d).\n", - dev->irq, retval); - goto out; - } - - dev->base_addr = base_addr; - - for (i = 0; i < ETH_ALEN; i++) - dev->dev_addr[i] = SA_prom[i]; - - printk(" %pM\n", dev->dev_addr); - - printk("%s: %s found at %#x, using IRQ %d.\n", - dev->name, name, base_addr, dev->irq); - - mca_set_adapter_procfn(slot, (MCA_ProcFn) ne2_procinfo, dev); - - ei_status.name = name; - ei_status.tx_start_page = start_page; - ei_status.stop_page = stop_page; - ei_status.word16 = (2 == 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 = &ne_reset_8390; - ei_status.block_input = &ne_block_input; - ei_status.block_output = &ne_block_output; - ei_status.get_8390_hdr = &ne_get_8390_hdr; - - ei_status.priv = slot; - - dev->netdev_ops = &eip_netdev_ops; - NS8390p_init(dev, 0); - - retval = register_netdev(dev); - if (retval) - goto out1; - return 0; -out1: - mca_set_adapter_procfn( ei_status.priv, NULL, NULL); - free_irq(dev->irq, dev); -out: - release_region(base_addr, NE_IO_EXTENT); - return retval; -} - -/* 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; - - if (ei_debug > 1) - printk("resetting the 8390 t=%ld...", 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); - - ei_status.txing = 0; - ei_status.dmaing = 0; - - /* 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("%s: ne_reset_8390() did not complete.\n", - dev->name); - break; - } - outb_p(ENISR_RESET, NE_BASE + 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 ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, - int ring_page) -{ - - int nic_base = dev->base_addr; - - /* 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].\n", - dev->name, ei_status.dmaing, ei_status.irqlock); - return; - } - - ei_status.dmaing |= 0x01; - outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); - outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); - outb_p(0, nic_base + EN0_RCNTHI); - outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */ - outb_p(ring_page, nic_base + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); - - if (ei_status.word16) - insw(NE_BASE + NE_DATAPORT, hdr, - sizeof(struct e8390_pkt_hdr)>>1); - else - insb(NE_BASE + NE_DATAPORT, hdr, - sizeof(struct e8390_pkt_hdr)); - - outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - 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 outb. */ - -static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, - int ring_offset) -{ -#ifdef NE_SANITY_CHECK - int xfer_count = count; -#endif - int nic_base = dev->base_addr; - char *buf = skb->data; - - /* 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].\n", - dev->name, ei_status.dmaing, ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); - outb_p(count & 0xff, nic_base + EN0_RCNTLO); - outb_p(count >> 8, nic_base + EN0_RCNTHI); - 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 + NE_CMD); - if (ei_status.word16) { - insw(NE_BASE + NE_DATAPORT,buf,count>>1); - if (count & 0x01) { - buf[count-1] = inb(NE_BASE + NE_DATAPORT); -#ifdef NE_SANITY_CHECK - xfer_count++; -#endif - } - } else { - insb(NE_BASE + NE_DATAPORT, buf, count); - } - -#ifdef NE_SANITY_CHECK - /* This was for the ALPHA version only, but enough people have - been encountering problems so it is still here. If you see - this message you either 1) have a slightly incompatible clone - or 2) have noise/speed problems with your bus. */ - if (ei_debug > 1) { /* DMA termination address check... */ - int addr, tries = 20; - do { - /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here - -- it's broken for Rx on some cards! */ - int high = inb_p(nic_base + EN0_RSARHI); - int low = inb_p(nic_base + EN0_RSARLO); - addr = (high << 8) + low; - if (((ring_offset + xfer_count) & 0xff) == low) - break; - } while (--tries > 0); - if (tries <= 0) - printk("%s: RX transfer address mismatch," - "%#4.4x (expected) vs. %#4.4x (actual).\n", - dev->name, ring_offset + xfer_count, addr); - } -#endif - outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; -} - -static void ne_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; -#ifdef NE_SANITY_CHECK - int retries = 0; -#endif - - /* 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) { - printk("%s: DMAing conflict in ne_block_output." - "[DMAstat:%d][irqlock:%d]\n", - dev->name, ei_status.dmaing, ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - /* We should already be in page 0, but to be safe... */ - outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); - -#ifdef NE_SANITY_CHECK -retry: -#endif - -#ifdef NE8390_RW_BUGFIX - /* Handle the read-before-write bug the same way as the - Crynwr packet driver -- the NatSemi method doesn't work. - Actually this doesn't always work either, but if you have - problems with your NEx000 this is better than nothing! */ - outb_p(0x42, nic_base + EN0_RCNTLO); - outb_p(0x00, nic_base + EN0_RCNTHI); - outb_p(0x42, nic_base + EN0_RSARLO); - outb_p(0x00, nic_base + EN0_RSARHI); - outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); - /* Make certain that the dummy read has occurred. */ - SLOW_DOWN_IO; - SLOW_DOWN_IO; - SLOW_DOWN_IO; -#endif - - outb_p(ENISR_RDC, nic_base + EN0_ISR); - - /* Now the normal output. */ - outb_p(count & 0xff, nic_base + EN0_RCNTLO); - outb_p(count >> 8, nic_base + EN0_RCNTHI); - outb_p(0x00, nic_base + EN0_RSARLO); - outb_p(start_page, nic_base + EN0_RSARHI); - - outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD); - if (ei_status.word16) { - outsw(NE_BASE + NE_DATAPORT, buf, count>>1); - } else { - outsb(NE_BASE + NE_DATAPORT, buf, count); - } - - dma_start = jiffies; - -#ifdef NE_SANITY_CHECK - /* This was for the ALPHA version only, but enough people have - been encountering problems so it is still here. */ - - if (ei_debug > 1) { /* DMA termination address check... */ - int addr, tries = 20; - do { - int high = inb_p(nic_base + EN0_RSARHI); - int low = inb_p(nic_base + EN0_RSARLO); - addr = (high << 8) + low; - if ((start_page << 8) + count == addr) - break; - } while (--tries > 0); - if (tries <= 0) { - printk("%s: Tx packet transfer address mismatch," - "%#4.4x (expected) vs. %#4.4x (actual).\n", - dev->name, (start_page << 8) + count, addr); - if (retries++ == 0) - goto retry; - } - } -#endif - - while ((inb_p(nic_base + 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); - ne_reset_8390(dev); - NS8390p_init(dev, 1); - break; - } - - outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; -} - - -#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_LICENSE("GPL"); - -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, "(ignored)"); -MODULE_PARM_DESC(irq, "(ignored)"); -MODULE_PARM_DESC(bad, "(ignored)"); - -/* Module code fixed by David Weinehall */ - -int __init init_module(void) -{ - struct net_device *dev; - int this_dev, found = 0; - - for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - 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_ne2_probe(dev) == 0) { - dev_ne[found++] = dev; - continue; - } - free_netdev(dev); - break; - } - if (found) - return 0; - printk(KERN_WARNING "ne2.c: No NE/2 card found\n"); - return -ENXIO; -} - -static void cleanup_card(struct net_device *dev) -{ - mca_mark_as_unused(ei_status.priv); - mca_set_adapter_procfn( ei_status.priv, NULL, NULL); - free_irq(dev->irq, dev); - release_region(dev->base_addr, NE_IO_EXTENT); -} - -void __exit cleanup_module(void) -{ - int this_dev; - - 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); - } - } -} -#endif /* MODULE */
diff --git a/drivers/net/ethernet/8390/smc-mca.c b/drivers/net/ethernet/8390/smc-mca.c deleted file mode 100644 index 7a68590..0000000 --- a/drivers/net/ethernet/8390/smc-mca.c +++ /dev/null
@@ -1,575 +0,0 @@ -/* smc-mca.c: A SMC Ultra ethernet driver for linux. */ -/* - Most of this driver, except for ultramca_probe is nearly - verbatim from smc-ultra.c by Donald Becker. The rest is - written and copyright 1996 by David Weis, weisd3458@uni.edu - - This is a driver for the SMC Ultra and SMC EtherEZ ethercards. - - This driver uses the cards in the 8390-compatible, shared memory mode. - Most of the run-time complexity is handled by the generic code in - 8390.c. - - This driver enables the shared memory only when doing the actual data - transfers to avoid a bug in early version of the card that corrupted - data transferred by a AHA1542. - - This driver does not support the programmed-I/O data transfer mode of - the EtherEZ. That support (if available) is smc-ez.c. Nor does it - use the non-8390-compatible "Altego" mode. (No support currently planned.) - - Changelog: - - Paul Gortmaker : multiple card support for module users. - David Weis : Micro Channel-ized it. - Tom Sightler : Added support for IBM PS/2 Ethernet Adapter/A - Christopher Turcksin : Changed MCA-probe so that multiple adapters are - found correctly (Jul 16, 1997) - Chris Beauregard : Tried to merge the two changes above (Dec 15, 1997) - Tom Sightler : Fixed minor detection bug caused by above merge - Tom Sightler : Added support for three more Western Digital - MCA-adapters - Tom Sightler : Added support for 2.2.x mca_find_unused_adapter - Hartmut Schmidt : - Modified parameter detection to handle each - card differently depending on a switch-list - - 'card_ver' removed from the adapter list - - Some minor bug fixes -*/ - -#include <linux/mca.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> - -#include <asm/io.h> - -#include "8390.h" - -#define DRV_NAME "smc-mca" - -static int ultramca_open(struct net_device *dev); -static void ultramca_reset_8390(struct net_device *dev); -static void ultramca_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, - int ring_page); -static void ultramca_block_input(struct net_device *dev, int count, - struct sk_buff *skb, - int ring_offset); -static void ultramca_block_output(struct net_device *dev, int count, - const unsigned char *buf, - const int start_page); -static int ultramca_close_card(struct net_device *dev); - -#define START_PG 0x00 /* First page of TX buffer */ - -#define ULTRA_CMDREG 0 /* Offset to ASIC command register. */ -#define ULTRA_RESET 0x80 /* Board reset, in ULTRA_CMDREG. */ -#define ULTRA_MEMENB 0x40 /* Enable the shared memory. */ -#define ULTRA_NIC_OFFSET 16 /* NIC register offset from the base_addr. */ -#define ULTRA_IO_EXTENT 32 -#define EN0_ERWCNT 0x08 /* Early receive warning count. */ - -#define _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A 0 -#define _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A 1 -#define _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A 2 -#define _6fc1_WD_Starcard_PLUS_A_WD8003ST_A 3 -#define _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A 4 -#define _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A 5 -#define _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A 6 -#define _efe5_IBM_PS2_Adapter_A_for_Ethernet 7 - -struct smc_mca_adapters_t { - unsigned int id; - char *name; -}; - -#define MAX_ULTRAMCA_CARDS 4 /* Max number of Ultra cards per module */ - -static int ultra_io[MAX_ULTRAMCA_CARDS]; -static int ultra_irq[MAX_ULTRAMCA_CARDS]; -MODULE_LICENSE("GPL"); - -module_param_array(ultra_io, int, NULL, 0); -module_param_array(ultra_irq, int, NULL, 0); -MODULE_PARM_DESC(ultra_io, "SMC Ultra/EtherEZ MCA I/O base address(es)"); -MODULE_PARM_DESC(ultra_irq, "SMC Ultra/EtherEZ MCA IRQ number(s)"); - -static const struct { - unsigned int base_addr; -} addr_table[] = { - { 0x0800 }, - { 0x1800 }, - { 0x2800 }, - { 0x3800 }, - { 0x4800 }, - { 0x5800 }, - { 0x6800 }, - { 0x7800 }, - { 0x8800 }, - { 0x9800 }, - { 0xa800 }, - { 0xb800 }, - { 0xc800 }, - { 0xd800 }, - { 0xe800 }, - { 0xf800 } -}; - -#define MEM_MASK 64 - -static const struct { - unsigned char mem_index; - unsigned long mem_start; - unsigned char num_pages; -} mem_table[] = { - { 16, 0x0c0000, 40 }, - { 18, 0x0c4000, 40 }, - { 20, 0x0c8000, 40 }, - { 22, 0x0cc000, 40 }, - { 24, 0x0d0000, 40 }, - { 26, 0x0d4000, 40 }, - { 28, 0x0d8000, 40 }, - { 30, 0x0dc000, 40 }, - {144, 0xfc0000, 40 }, - {148, 0xfc8000, 40 }, - {154, 0xfd0000, 40 }, - {156, 0xfd8000, 40 }, - { 0, 0x0c0000, 20 }, - { 1, 0x0c2000, 20 }, - { 2, 0x0c4000, 20 }, - { 3, 0x0c6000, 20 } -}; - -#define IRQ_MASK 243 -static const struct { - unsigned char new_irq; - unsigned char old_irq; -} irq_table[] = { - { 3, 3 }, - { 4, 4 }, - { 10, 10 }, - { 14, 15 } -}; - -static short smc_mca_adapter_ids[] __initdata = { - 0x61c8, - 0x61c9, - 0x6fc0, - 0x6fc1, - 0x6fc2, - 0xefd4, - 0xefd5, - 0xefe5, - 0x0000 -}; - -static char *smc_mca_adapter_names[] __initdata = { - "SMC Ethercard PLUS Elite/A BNC/AUI (WD8013EP/A)", - "SMC Ethercard PLUS Elite/A UTP/AUI (WD8013WP/A)", - "WD Ethercard PLUS/A (WD8003E/A or WD8003ET/A)", - "WD Starcard PLUS/A (WD8003ST/A)", - "WD Ethercard PLUS 10T/A (WD8003W/A)", - "IBM PS/2 Adapter/A for Ethernet UTP/AUI (WD8013WP/A)", - "IBM PS/2 Adapter/A for Ethernet BNC/AUI (WD8013EP/A)", - "IBM PS/2 Adapter/A for Ethernet", - NULL -}; - -static int ultra_found = 0; - - -static const struct net_device_ops ultramca_netdev_ops = { - .ndo_open = ultramca_open, - .ndo_stop = ultramca_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 = ei_poll, -#endif -}; - -static int __init ultramca_probe(struct device *gen_dev) -{ - unsigned short ioaddr; - struct net_device *dev; - unsigned char reg4, num_pages; - struct mca_device *mca_dev = to_mca_device(gen_dev); - char slot = mca_dev->slot; - unsigned char pos2 = 0xff, pos3 = 0xff, pos4 = 0xff, pos5 = 0xff; - int i, rc; - int adapter = mca_dev->index; - int tbase = 0; - int tirq = 0; - int base_addr = ultra_io[ultra_found]; - int irq = ultra_irq[ultra_found]; - - if (base_addr || irq) { - printk(KERN_INFO "Probing for SMC MCA adapter"); - if (base_addr) { - printk(KERN_INFO " at I/O address 0x%04x%c", - base_addr, irq ? ' ' : '\n'); - } - if (irq) { - printk(KERN_INFO "using irq %d\n", irq); - } - } - - tirq = 0; - tbase = 0; - - /* If we're trying to match a specificied irq or io address, - * we'll reject the adapter found unless it's the one we're - * looking for */ - - pos2 = mca_device_read_stored_pos(mca_dev, 2); /* io_addr */ - pos3 = mca_device_read_stored_pos(mca_dev, 3); /* shared mem */ - pos4 = mca_device_read_stored_pos(mca_dev, 4); /* ROM bios addr range */ - pos5 = mca_device_read_stored_pos(mca_dev, 5); /* irq, media and RIPL */ - - /* Test the following conditions: - * - If an irq parameter is supplied, compare it - * with the irq of the adapter we found - * - If a base_addr paramater is given, compare it - * with the base_addr of the adapter we found - * - Check that the irq and the base_addr of the - * adapter we found is not already in use by - * this driver - */ - - switch (mca_dev->index) { - case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A: - case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A: - case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A: - case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A: - { - tbase = addr_table[(pos2 & 0xf0) >> 4].base_addr; - tirq = irq_table[(pos5 & 0xc) >> 2].new_irq; - break; - } - case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A: - case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A: - case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A: - case _efe5_IBM_PS2_Adapter_A_for_Ethernet: - { - tbase = ((pos2 & 0x0fe) * 0x10); - tirq = irq_table[(pos5 & 3)].old_irq; - break; - } - } - - if(!tirq || !tbase || - (irq && irq != tirq) || - (base_addr && tbase != base_addr)) - /* FIXME: we're trying to force the ordering of the - * devices here, there should be a way of getting this - * to happen */ - return -ENXIO; - - /* Adapter found. */ - dev = alloc_ei_netdev(); - if(!dev) - return -ENODEV; - - SET_NETDEV_DEV(dev, gen_dev); - mca_device_set_name(mca_dev, smc_mca_adapter_names[adapter]); - mca_device_set_claim(mca_dev, 1); - - printk(KERN_INFO "smc_mca: %s found in slot %d\n", - smc_mca_adapter_names[adapter], slot + 1); - - ultra_found++; - - dev->base_addr = ioaddr = mca_device_transform_ioport(mca_dev, tbase); - dev->irq = mca_device_transform_irq(mca_dev, tirq); - dev->mem_start = 0; - num_pages = 40; - - switch (adapter) { /* card-# in const array above [hs] */ - case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A: - case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A: - { - for (i = 0; i < 16; i++) { /* taking 16 counts - * up to 15 [hs] */ - if (mem_table[i].mem_index == (pos3 & ~MEM_MASK)) { - dev->mem_start = (unsigned long) - mca_device_transform_memory(mca_dev, (void *)mem_table[i].mem_start); - num_pages = mem_table[i].num_pages; - } - } - break; - } - case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A: - case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A: - case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A: - case _efe5_IBM_PS2_Adapter_A_for_Ethernet: - { - dev->mem_start = (unsigned long) - mca_device_transform_memory(mca_dev, (void *)((pos3 & 0xfc) * 0x1000)); - num_pages = 0x40; - break; - } - case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A: - case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A: - { - /* courtesy of gamera@quartz.ocn.ne.jp, pos3 indicates - * the index of the 0x2000 step. - * beware different number of pages [hs] - */ - dev->mem_start = (unsigned long) - mca_device_transform_memory(mca_dev, (void *)(0xc0000 + (0x2000 * (pos3 & 0xf)))); - num_pages = 0x20 + (2 * (pos3 & 0x10)); - break; - } - } - - /* sanity check, shouldn't happen */ - if (dev->mem_start == 0) { - rc = -ENODEV; - goto err_unclaim; - } - - if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME)) { - rc = -ENODEV; - goto err_unclaim; - } - - reg4 = inb(ioaddr + 4) & 0x7f; - outb(reg4, ioaddr + 4); - - for (i = 0; i < 6; i++) - dev->dev_addr[i] = inb(ioaddr + 8 + i); - - printk(KERN_INFO "smc_mca[%d]: Parameters: %#3x, %pM", - slot + 1, ioaddr, dev->dev_addr); - - /* Switch from the station address to the alternate register set - * and read the useful registers there. - */ - - outb(0x80 | reg4, ioaddr + 4); - - /* Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot. - */ - - outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c); - - /* Switch back to the station address register set so that - * the MS-DOS driver can find the card after a warm boot. - */ - - outb(reg4, ioaddr + 4); - - dev_set_drvdata(gen_dev, dev); - - /* The 8390 isn't at the base address, so fake the offset - */ - - dev->base_addr = ioaddr + ULTRA_NIC_OFFSET; - - ei_status.name = "SMC Ultra MCA"; - ei_status.word16 = 1; - ei_status.tx_start_page = START_PG; - ei_status.rx_start_page = START_PG + TX_PAGES; - ei_status.stop_page = num_pages; - - ei_status.mem = ioremap(dev->mem_start, (ei_status.stop_page - START_PG) * 256); - if (!ei_status.mem) { - rc = -ENOMEM; - goto err_release_region; - } - - dev->mem_end = dev->mem_start + (ei_status.stop_page - START_PG) * 256; - - printk(", IRQ %d memory %#lx-%#lx.\n", - dev->irq, dev->mem_start, dev->mem_end - 1); - - ei_status.reset_8390 = &ultramca_reset_8390; - ei_status.block_input = &ultramca_block_input; - ei_status.block_output = &ultramca_block_output; - ei_status.get_8390_hdr = &ultramca_get_8390_hdr; - - ei_status.priv = slot; - - dev->netdev_ops = &ultramca_netdev_ops; - - NS8390_init(dev, 0); - - rc = register_netdev(dev); - if (rc) - goto err_unmap; - - return 0; - -err_unmap: - iounmap(ei_status.mem); -err_release_region: - release_region(ioaddr, ULTRA_IO_EXTENT); -err_unclaim: - mca_device_set_claim(mca_dev, 0); - free_netdev(dev); - return rc; -} - -static int ultramca_open(struct net_device *dev) -{ - int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ - int retval; - - if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) - return retval; - - outb(ULTRA_MEMENB, ioaddr); /* Enable memory */ - outb(0x80, ioaddr + 5); /* ??? */ - outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */ - outb(0x04, ioaddr + 5); /* ??? */ - - /* Set the early receive warning level in window 0 high enough not - * to receive ERW interrupts. - */ - - /* outb_p(E8390_NODMA + E8390_PAGE0, dev->base_addr); - * outb(0xff, dev->base_addr + EN0_ERWCNT); - */ - - ei_open(dev); - return 0; -} - -static void ultramca_reset_8390(struct net_device *dev) -{ - int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ - - outb(ULTRA_RESET, ioaddr); - if (ei_debug > 1) - printk("resetting Ultra, t=%ld...", jiffies); - ei_status.txing = 0; - - outb(0x80, ioaddr + 5); /* ??? */ - outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */ - - if (ei_debug > 1) - printk("reset done\n"); -} - -/* 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 ultramca_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) -{ - void __iomem *hdr_start = ei_status.mem + ((ring_page - START_PG) << 8); - -#ifdef notdef - /* Officially this is what we are doing, but the readl() is faster */ - memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); -#else - ((unsigned int*)hdr)[0] = readl(hdr_start); -#endif -} - -/* Block input and output are easy on shared memory ethercards, the only - * complication is when the ring buffer wraps. - */ - -static void ultramca_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) -{ - void __iomem *xfer_start = ei_status.mem + ring_offset - START_PG * 256; - - if (ring_offset + count > ei_status.stop_page * 256) { - /* We must wrap the input move. */ - int semi_count = ei_status.stop_page * 256 - ring_offset; - memcpy_fromio(skb->data, xfer_start, semi_count); - count -= semi_count; - memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); - } else { - memcpy_fromio(skb->data, xfer_start, count); - } - -} - -static void ultramca_block_output(struct net_device *dev, int count, const unsigned char *buf, - int start_page) -{ - void __iomem *shmem = ei_status.mem + ((start_page - START_PG) << 8); - - memcpy_toio(shmem, buf, count); -} - -static int ultramca_close_card(struct net_device *dev) -{ - int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ - - netif_stop_queue(dev); - - if (ei_debug > 1) - printk("%s: Shutting down ethercard.\n", dev->name); - - outb(0x00, ioaddr + 6); /* Disable interrupts. */ - free_irq(dev->irq, dev); - - NS8390_init(dev, 0); - /* We should someday disable shared memory and change to 8-bit mode - * "just in case"... - */ - - return 0; -} - -static int ultramca_remove(struct device *gen_dev) -{ - struct mca_device *mca_dev = to_mca_device(gen_dev); - struct net_device *dev = dev_get_drvdata(gen_dev); - - if (dev) { - /* NB: ultra_close_card() does free_irq */ - int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; - - unregister_netdev(dev); - mca_device_set_claim(mca_dev, 0); - release_region(ioaddr, ULTRA_IO_EXTENT); - iounmap(ei_status.mem); - free_netdev(dev); - } - return 0; -} - - -static struct mca_driver ultra_driver = { - .id_table = smc_mca_adapter_ids, - .driver = { - .name = "smc-mca", - .bus = &mca_bus_type, - .probe = ultramca_probe, - .remove = ultramca_remove, - } -}; - -static int __init ultramca_init_module(void) -{ - if(!MCA_bus) - return -ENXIO; - - mca_register_driver(&ultra_driver); - - return ultra_found ? 0 : -ENXIO; -} - -static void __exit ultramca_cleanup_module(void) -{ - mca_unregister_driver(&ultra_driver); -} -module_init(ultramca_init_module); -module_exit(ultramca_cleanup_module); -
diff --git a/drivers/net/ethernet/amd/ariadne.c b/drivers/net/ethernet/amd/ariadne.c index f4c228e..f2958df 100644 --- a/drivers/net/ethernet/amd/ariadne.c +++ b/drivers/net/ethernet/amd/ariadne.c
@@ -213,10 +213,10 @@ (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 0x%08x len %d\n", + 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, - (int)skb->data, (int)skb->len); + skb->data, skb->len); netif_rx(skb); dev->stats.rx_packets++; @@ -566,10 +566,10 @@ /* Fill in a Tx ring entry */ - netdev_dbg(dev, "TX pkt type 0x%04x from %pM to %pM data 0x%08x len %d\n", + 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, - (int)skb->data, (int)skb->len); + skb->data, skb->len); local_irq_save(flags);
diff --git a/drivers/net/ethernet/amd/atarilance.c b/drivers/net/ethernet/amd/atarilance.c index 70ed79c..84219df 100644 --- a/drivers/net/ethernet/amd/atarilance.c +++ b/drivers/net/ethernet/amd/atarilance.c
@@ -558,21 +558,18 @@ printk( "Lance: request for irq %d failed\n", IRQ_AUTO_5 ); 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; } if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO, "Riebl-VME Ethernet", dev)) { - printk( "Lance: request for irq %ld failed\n", irq ); + printk( "Lance: request for irq %u failed\n", irq ); return 0; } dev->irq = irq;
diff --git a/drivers/net/ethernet/amd/depca.c b/drivers/net/ethernet/amd/depca.c index 86dd957..c771de7 100644 --- a/drivers/net/ethernet/amd/depca.c +++ b/drivers/net/ethernet/amd/depca.c
@@ -155,23 +155,10 @@ 2 depca's in a PC). ************************************************************************ - Support for MCA EtherWORKS cards added 11-3-98. + Support for MCA EtherWORKS cards added 11-3-98. (MCA since deleted) 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 ---------------- @@ -261,10 +248,6 @@ #include <asm/io.h> #include <asm/dma.h> -#ifdef CONFIG_MCA -#include <linux/mca.h> -#endif - #ifdef CONFIG_EISA #include <linux/eisa.h> #endif @@ -360,44 +343,6 @@ }; #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) @@ -464,8 +409,7 @@ char adapter_name[DEPCA_STRLEN]; /* /proc/ioports string */ enum depca_type adapter; /* Adapter type */ enum { - DEPCA_BUS_MCA = 1, - DEPCA_BUS_ISA, + DEPCA_BUS_ISA = 1, DEPCA_BUS_EISA, } depca_bus; /* type of bus */ struct depca_init init_block; /* Shadow Initialization block */ @@ -624,12 +568,6 @@ dev_name(device), 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); @@ -661,10 +599,7 @@ 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; + 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))) @@ -1079,7 +1014,8 @@ } else { lp->pktStats.multicast++; } - } else if (compare_ether_addr(buf, dev->dev_addr) == 0) { + } else if (ether_addr_equal(buf, + dev->dev_addr)) { lp->pktStats.unicast++; } @@ -1324,130 +1260,6 @@ 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 = netdev_priv(dev); - 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 */ @@ -2058,15 +1870,10 @@ { int err = 0; -#ifdef CONFIG_MCA - err = mca_register_driver(&depca_mca_driver); - if (err) - goto err; -#endif #ifdef CONFIG_EISA err = eisa_driver_register(&depca_eisa_driver); if (err) - goto err_mca; + goto err_eisa; #endif err = platform_driver_register(&depca_isa_driver); if (err) @@ -2078,11 +1885,6 @@ err_eisa: #ifdef CONFIG_EISA eisa_driver_unregister(&depca_eisa_driver); -err_mca: -#endif -#ifdef CONFIG_MCA - mca_unregister_driver(&depca_mca_driver); -err: #endif return err; } @@ -2090,9 +1892,6 @@ 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
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 39b92f5..d55df32 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -195,15 +195,6 @@ #define TG3_RX_OFFSET(tp) (NET_SKB_PAD) #endif -/* This driver uses the new build_skb() API providing a frag as skb->head - * This strategy permits better GRO aggregation, better TCP coalescing, and - * better splice() implementation (avoids a copy from head to a page), at - * minimal memory cost. - * In this 2048 bytes block, we have enough room to store the MTU=1500 frame - * and the struct skb_shared_info. - */ -#define TG3_FRAGSIZE 2048 - /* minimum number of free TX descriptors required to wake up TX process */ #define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4) #define TG3_TX_BD_DMA_MAX_2K 2048 @@ -5631,25 +5622,6 @@ } } -static void *tg3_frag_alloc(struct tg3_rx_prodring_set *tpr) -{ - void *data; - - if (tpr->rx_page_size < TG3_FRAGSIZE) { - struct page *page = alloc_page(GFP_ATOMIC); - - if (!page) - return NULL; - atomic_add((PAGE_SIZE / TG3_FRAGSIZE) - 1, &page->_count); - tpr->rx_page_addr = page_address(page); - tpr->rx_page_size = PAGE_SIZE; - } - data = tpr->rx_page_addr; - tpr->rx_page_addr += TG3_FRAGSIZE; - tpr->rx_page_size -= TG3_FRAGSIZE; - return data; -} - static void tg3_frag_free(bool is_frag, void *data) { if (is_frag) @@ -5668,7 +5640,7 @@ pci_unmap_single(tp->pdev, dma_unmap_addr(ri, mapping), map_sz, PCI_DMA_FROMDEVICE); - tg3_frag_free(skb_size <= TG3_FRAGSIZE, ri->data); + tg3_frag_free(skb_size <= PAGE_SIZE, ri->data); ri->data = NULL; } @@ -5721,9 +5693,9 @@ */ skb_size = SKB_DATA_ALIGN(data_size + TG3_RX_OFFSET(tp)) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - if (skb_size <= TG3_FRAGSIZE) { - data = tg3_frag_alloc(tpr); - *frag_size = TG3_FRAGSIZE; + if (skb_size <= PAGE_SIZE) { + data = netdev_alloc_frag(skb_size); + *frag_size = skb_size; } else { data = kmalloc(skb_size, GFP_ATOMIC); *frag_size = 0; @@ -5736,7 +5708,7 @@ data_size, PCI_DMA_FROMDEVICE); if (unlikely(pci_dma_mapping_error(tp->pdev, mapping))) { - tg3_frag_free(skb_size <= TG3_FRAGSIZE, data); + tg3_frag_free(skb_size <= PAGE_SIZE, data); return -EIO; }
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 7c85545..93865f8 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -2815,8 +2815,6 @@ struct ring_info *rx_jmb_buffers; dma_addr_t rx_std_mapping; dma_addr_t rx_jmb_mapping; - void *rx_page_addr; - unsigned int rx_page_size; }; #define TG3_IRQ_MAX_VECS_RSS 5
diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index b9406cb..845b202 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c
@@ -1,105 +1,27 @@ /* cs89x0.c: A Crystal Semiconductor (Now Cirrus Logic) CS89[02]0 - * driver for linux. + * 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 + * + * Other contributors: + * Mike Cruse : mcruse@cti-ltd.com + * Russ Nelson + * Melody Lee : ethernet@crystal.cirrus.com + * Alan Cox + * Andrew Morton + * Oskar Schirmer : oskar@scara.com + * Deepak Saxena : dsaxena@plexity.net + * Dmitry Pervushin : dpervushin@ru.mvista.com + * Deepak Saxena : dsaxena@plexity.net + * Domenico Andreoli : cavokz@gmail.com */ -/* - 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 : 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 : 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 : 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 : 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 - - Domenico Andreoli : cavokz@gmail.com - : QQ2440 platform support - -*/ - /* * Set this to zero to disable DMA code @@ -119,14 +41,12 @@ */ #define DEBUGGING 1 -/* - Sources: +/* Sources: + * Crynwr packet driver epktisa. + * Crystal Semiconductor data sheets. + */ - Crynwr packet driver epktisa. - - Crystal Semiconductor data sheets. - -*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/module.h> #include <linux/printk.h> @@ -147,8 +67,8 @@ #include <linux/bitops.h> #include <linux/delay.h> #include <linux/gfp.h> +#include <linux/io.h> -#include <asm/io.h> #include <asm/irq.h> #include <linux/atomic.h> #if ALLOW_DMA @@ -157,35 +77,55 @@ #include "cs89x0.h" +#define cs89_dbg(val, level, fmt, ...) \ +do { \ + if (val <= net_debug) \ + pr_##level(fmt, ##__VA_ARGS__); \ +} while (0) + static char version[] __initdata = -"cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton\n"; + "v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton"; #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. */ + * 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. */ + * them to system IRQ numbers. This mapping is card specific and is set to + * the configuration of the Cirrus Eval board for this chip. + */ #if defined(CONFIG_MACH_IXDP2351) #define CS89x0_NONISA_IRQ -static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0}; -static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0}; +static unsigned int netcard_portlist[] __used __initdata = { + IXDP2351_VIRT_CS8900_BASE, 0 +}; +static unsigned int cs8900_irq_map[] = { + IRQ_IXDP2351_CS8900, 0, 0, 0 +}; #elif defined(CONFIG_ARCH_IXDP2X01) #define CS89x0_NONISA_IRQ -static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0}; -static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0}; +static unsigned int netcard_portlist[] __used __initdata = { + IXDP2X01_CS8900_VIRT_BASE, 0 +}; +static unsigned int cs8900_irq_map[] = { + IRQ_IXDP2X01_CS8900, 0, 0, 0 +}; #else #ifndef CONFIG_CS89x0_PLATFORM -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}; +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 #endif @@ -222,6 +162,8 @@ 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; + void __iomem *virt_addr;/* CS89x0 virtual address. */ + unsigned long size; /* Length of CS89x0 memory region. */ #if ALLOW_DMA int use_dma; /* Flag: we're using dma */ int dma; /* DMA channel */ @@ -230,119 +172,42 @@ unsigned char *end_dma_buff; /* points to the end of the buffer */ unsigned char *rx_dma_ptr; /* points to the next packet */ #endif -#ifdef CONFIG_CS89x0_PLATFORM - void __iomem *virt_addr;/* Virtual address for accessing the CS89x0. */ - unsigned long phys_addr;/* Physical address for accessing the CS89x0. */ - unsigned long size; /* Length of CS89x0 memory region. */ -#endif }; -/* Index to functions, as function prototypes. */ - -static int cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular); -static int net_open(struct net_device *dev); -static netdev_tx_t 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_device *dev); -#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) +#if !defined(MODULE) +#if ALLOW_DMA static int g_cs89x0_dma; static int __init dma_fn(char *str) { - g_cs89x0_dma = simple_strtol(str,NULL,0); + g_cs89x0_dma = simple_strtol(str, NULL, 0); return 1; } __setup("cs89x0_dma=", dma_fn); -#endif /* !defined(MODULE) && (ALLOW_DMA != 0) */ +#endif /* ALLOW_DMA */ -#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; + 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); - - -#ifndef CONFIG_CS89x0_PLATFORM -/* 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 #endif #if defined(CONFIG_MACH_IXDP2351) @@ -369,36 +234,22 @@ { __raw_writel(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) +static void readwords(struct net_local *lp, int portno, void *buf, int length) { u8 *buf8 = (u8 *)buf; do { u16 tmp16; - tmp16 = readword(base_addr, portno); + tmp16 = ioread16(lp->virt_addr + portno); *buf8++ = (u8)tmp16; *buf8++ = (u8)(tmp16 >> 8); } while (--length); } -static void -writewords(unsigned long base_addr, int portno, void *buf, int length) +static void writewords(struct net_local *lp, int portno, void *buf, int length) { u8 *buf8 = (u8 *)buf; @@ -407,32 +258,37 @@ tmp16 = *buf8++; tmp16 |= (*buf8++) << 8; - writeword(base_addr, portno, tmp16); + iowrite16(tmp16, lp->virt_addr + portno); } 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); + struct net_local *lp = netdev_priv(dev); + + iowrite16(regno, lp->virt_addr + ADD_PORT); + return ioread16(lp->virt_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); + struct net_local *lp = netdev_priv(dev); + + iowrite16(regno, lp->virt_addr + ADD_PORT); + iowrite16(value, lp->virt_addr + DATA_PORT); } 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) + /* 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; @@ -443,17 +299,19 @@ { int i; - if (net_debug > 3) printk("EEPROM data from %x for %x:\n",off,len); + cs89_dbg(3, info, "EEPROM data from %x for %x:", off, len); for (i = 0; i < len; i++) { - if (wait_eeprom_ready(dev) < 0) return -1; + 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; + if (wait_eeprom_ready(dev) < 0) + return -1; buffer[i] = readreg(dev, PP_EEData); - if (net_debug > 3) printk("%04x ", buffer[i]); + cs89_dbg(3, cont, " %04x", buffer[i]); } - if (net_debug > 3) printk("\n"); - return 0; + cs89_dbg(3, cont, "\n"); + return 0; } static int __init @@ -470,341 +328,52 @@ 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) +static void +write_irq(struct net_device *dev, int chip_type, int irq) { - disable_irq(dev->irq); - net_interrupt(dev->irq, dev); - enable_irq(dev->irq); -} -#endif - -static const struct net_device_ops net_ops = { - .ndo_open = net_open, - .ndo_stop = net_close, - .ndo_tx_timeout = net_timeout, - .ndo_start_xmit = net_send_packet, - .ndo_get_stats = net_get_stats, - .ndo_set_rx_mode = set_multicast_list, - .ndo_set_mac_address = set_mac_address, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = net_poll_controller, -#endif - .ndo_change_mtu = eth_change_mtu, - .ndo_validate_addr = eth_validate_addr, -}; - -/* 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, unsigned long 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; - /* 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 - - } - - /* 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%lx, 0x%x) failed\n", - DRV_NAME, ioaddr, NETCARD_IO_EXTENT); - retval = -EBUSY; - goto out1; - } - - /* 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%lx\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 %lx[%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 %lx[%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. */ - - - 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. */ - - 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 (chip_type == CS8900) { #ifndef CONFIG_CS89x0_PLATFORM - if (lp->chip_type == CS8900) { -#ifdef CS89x0_NONISA_IRQ - i = cs8900_irq_map[0]; + /* 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; #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); - } + /* INTRQ0 pin is used for interrupt generation. */ + i = 0; #endif - } -#endif - if (!dev->irq) - dev->irq = i; + writereg(dev, PP_CS8900_ISAINT, i); + } else { + writereg(dev, PP_CS8920_ISAINT, irq); } - - 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 %pM", dev->dev_addr); - - dev->netdev_ops = &net_ops; - dev->watchdog_timeo = HZ; - - 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; } +static void +count_rx_errors(int status, struct net_device *dev) +{ + dev->stats.rx_errors++; + if (status & RX_RUNT) + dev->stats.rx_length_errors++; + if (status & RX_EXTRA_DATA) + dev->stats.rx_length_errors++; + if ((status & RX_CRC_ERROR) && !(status & (RX_EXTRA_DATA | RX_RUNT))) + /* per str 172 */ + dev->stats.rx_crc_errors++; + if (status & RX_DRIBBLE) + dev->stats.rx_frame_errors++; +} /********************************* * This page contains DMA routines -**********************************/ + *********************************/ #if ALLOW_DMA -#define dma_page_eq(ptr1, ptr2) ((long)(ptr1)>>17 == (long)(ptr2)>>17) +#define dma_page_eq(ptr1, ptr2) ((long)(ptr1) >> 17 == (long)(ptr2) >> 17) static void get_dma_channel(struct net_device *dev) @@ -833,11 +402,10 @@ 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 { + if (chip_type == CS8900) + writereg(dev, PP_CS8900_ISADMA, dma - 5); + else writereg(dev, PP_CS8920_ISADMA, dma); - } } static void @@ -847,18 +415,15 @@ if (lp->use_dma) { if ((lp->isa_config & ANY_ISA_DMA) == 0) { - if (net_debug > 3) - printk("set_dma_cfg(): no DMA\n"); + cs89_dbg(3, err, "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"); + cs89_dbg(3, info, "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"); + cs89_dbg(3, info, "set_dma_cfg(): AUTO_RX_DMA\n"); } } } @@ -868,7 +433,7 @@ { struct net_local *lp = netdev_priv(dev); if (lp->use_dma) - return (lp->isa_config & ANY_ISA_DMA)? RX_DMA_ENBL : 0; + return (lp->isa_config & ANY_ISA_DMA) ? RX_DMA_ENBL : 0; else return 0; } @@ -898,13 +463,13 @@ int status, length; unsigned char *bp = lp->rx_dma_ptr; - status = bp[0] + (bp[1]<<8); - length = bp[2] + (bp[3]<<8); + 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); - } + + cs89_dbg(5, debug, "%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, dev); goto skip_this_frame; @@ -913,14 +478,16 @@ /* Malloc up new buffer. */ skb = netdev_alloc_skb(dev, 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); + /* I don't think we want to do this to a stressed system */ + cs89_dbg(0, err, "%s: Memory squeeze, dropping packet\n", + dev->name); dev->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; + if (bp >= lp->end_dma_buff) + bp -= lp->dmasize * 1024; lp->rx_dma_ptr = bp; return; } @@ -928,63 +495,38 @@ 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, + 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); + memcpy(skb_put(skb, length), bp, length); } bp += (length + 3) & ~3; - if (bp >= lp->end_dma_buff) bp -= lp->dmasize*1024; + 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); + cs89_dbg(3, info, "%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->stats.rx_packets++; dev->stats.rx_bytes += length; } -#endif /* ALLOW_DMA */ - -static void __init reset_chip(struct net_device *dev) +static void release_dma_buff(struct net_local *lp) { -#if !defined(CONFIG_MACH_MX31ADS) -#if !defined(CS89x0_NONISA_IRQ) - struct net_local *lp = netdev_priv(dev); - int ioaddr = dev->base_addr; -#endif /* CS89x0_NONISA_IRQ */ - int reset_start_time; - - writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET); - - /* wait 30 ms */ - msleep(30); - -#if !defined(CS89x0_NONISA_IRQ) - 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); + if (lp->dma_buff) { + free_pages((unsigned long)(lp->dma_buff), + get_order(lp->dmasize * 1024)); + lp->dma_buff = NULL; } -#endif /* CS89x0_NONISA_IRQ */ - - /* Wait until the chip is reset */ - reset_start_time = jiffies; - while( (readreg(dev, PP_SelfST) & INIT_DONE) == 0 && jiffies - reset_start_time < 2) - ; -#endif /* !CONFIG_MACH_MX31ADS */ } +#endif /* ALLOW_DMA */ static void control_dc_dc(struct net_device *dev, int on_not_off) @@ -993,8 +535,9 @@ 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. */ + * 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) @@ -1008,6 +551,49 @@ ; } +/* send a test packet - return true if carrier bits are ok */ +static int +send_test_pkt(struct net_device *dev) +{ + struct net_local *lp = netdev_priv(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); + + iowrite16(TX_AFTER_ALL, lp->virt_addr + TX_CMD_PORT); + iowrite16(ETH_ZLEN, lp->virt_addr + TX_LEN_PORT); + + /* 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(lp, TX_FRAME_PORT, test_packet, (ETH_ZLEN + 1) >> 1); + + cs89_dbg(1, debug, "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) { + cs89_dbg(1, cont, "succeeded\n"); + return 1; + } + cs89_dbg(1, cont, "failed\n"); + return 0; +} + #define DETECTED_NONE 0 #define DETECTED_RJ45H 1 #define DETECTED_RJ45F 2 @@ -1021,40 +607,46 @@ int timenow = jiffies; int fdx; - if (net_debug > 1) printk("%s: Attempting TP\n", dev->name); + cs89_dbg(1, debug, "%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); + /* 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; ) - ; + /* 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) { + switch (lp->force & 0xf0) { #if 0 - case FORCE_AUTO: - printk("%s: cs8900 doesn't autonegotiate\n",dev->name); - return DETECTED_NONE; + case FORCE_AUTO: + pr_info("%s: cs8900 doesn't autonegotiate\n", + dev->name); + return DETECTED_NONE; #endif - /* CS8900 doesn't support AUTO, change to HALF*/ - case FORCE_AUTO: + /* CS8900 doesn't support AUTO, change to HALF*/ + case FORCE_AUTO: lp->force &= ~FORCE_AUTO; - lp->force |= FORCE_HALF; + lp->force |= FORCE_HALF; break; case FORCE_HALF: break; - case FORCE_FULL: - writereg(dev, PP_TestCTL, readreg(dev, PP_TestCTL) | FDX_8900); + 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) { @@ -1067,15 +659,15 @@ 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); + pr_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"); + pr_err("**** Full / half duplex auto-negotiation timed out ****\n"); break; } } @@ -1088,72 +680,15 @@ 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); + cs89_dbg(1, debug, "%s: Attempting BNC\n", dev->name); control_dc_dc(dev, 1); - writereg(dev, PP_LineCTL, (lp->linectl &~ AUTO_AUI_10BASET) | AUI_ONLY); + writereg(dev, PP_LineCTL, (lp->linectl & ~AUTO_AUI_10BASET) | AUI_ONLY); if (send_test_pkt(dev)) return DETECTED_BNC; @@ -1161,361 +696,89 @@ return DETECTED_NONE; } - -static void -write_irq(struct net_device *dev, int chip_type, int irq) -{ - int i; - - if (chip_type == CS8900) { -#ifndef CONFIG_CS89x0_PLATFORM - /* 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; -#else - /* INTRQ0 pin is used for interrupt generation. */ - i = 0; -#endif - 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) +detect_aui(struct net_device *dev) { struct net_local *lp = netdev_priv(dev); - int result = 0; - int i; - int ret; - 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); + cs89_dbg(1, debug, "%s: Attempting AUI\n", dev->name); + control_dc_dc(dev, 0); - 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; - } - } - } + writereg(dev, PP_LineCTL, (lp->linectl & ~AUTO_AUI_10BASET) | AUI_ONLY); - 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; - } - } + if (send_test_pkt(dev)) + return DETECTED_AUI; else - { -#if !defined(CS89x0_NONISA_IRQ) && !defined(CONFIG_CS89x0_PLATFORM) - 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) { - printk(KERN_ERR "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, DMA_RX_MODE); /* 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); - } - if (!result) { - printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name); -release_dma: -#if ALLOW_DMA - free_dma(dev->dma); -release_irq: - 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; + return DETECTED_NONE; } -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 netdev_tx_t net_send_packet(struct sk_buff *skb,struct net_device *dev) +/* 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); - unsigned long flags; + struct sk_buff *skb; + int status, length; - 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]); + status = ioread16(lp->virt_addr + RX_FRAME_PORT); + length = ioread16(lp->virt_addr + RX_FRAME_PORT); + + if ((status & RX_OK) == 0) { + count_rx_errors(status, dev); + return; } - /* keep the upload from being interrupted, since we - ask the chip to start transmitting before the - whole packet has been completely uploaded. */ - - spin_lock_irqsave(&lp->lock, flags); - 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_irqrestore(&lp->lock, flags); - if (net_debug) printk("cs89x0: Tx buffer not free!\n"); - return NETDEV_TX_BUSY; + /* Malloc up new buffer. */ + skb = netdev_alloc_skb(dev, length + 2); + if (skb == NULL) { +#if 0 /* Again, this seems a cruel thing to do */ + pr_warn("%s: Memory squeeze, dropping packet\n", dev->name); +#endif + dev->stats.rx_dropped++; + return; } - /* Write the contents of the packet */ - writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1); - spin_unlock_irqrestore(&lp->lock, flags); - dev->stats.tx_bytes += skb->len; - dev_kfree_skb (skb); + skb_reserve(skb, 2); /* longword align L3 header */ - /* - * 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 - */ + readwords(lp, RX_FRAME_PORT, skb_put(skb, length), length >> 1); + if (length & 1) + skb->data[length-1] = ioread16(lp->virt_addr + RX_FRAME_PORT); - return NETDEV_TX_OK; + cs89_dbg(3, debug, "%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->stats.rx_packets++; + dev->stats.rx_bytes += length; } /* The typical workload of the driver: - Handle the network interface interrupts. */ + * 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; + int 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); + * 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 = ioread16(lp->virt_addr + ISQ_PORT))) { + cs89_dbg(4, debug, "%s: event=%04x\n", dev->name, status); handled = 1; - switch(status & ISQ_EVENT_MASK) { + switch (status & ISQ_EVENT_MASK) { case ISQ_RECEIVER_EVENT: /* Got a packet(s). */ net_rx(dev); @@ -1523,11 +786,11 @@ case ISQ_TRANSMITTER_EVENT: dev->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 | + TX_LOST_CRS | + TX_SQE_ERROR | + TX_LATE_COL | + TX_16_COL)) != TX_OK) { if ((status & TX_OK) == 0) dev->stats.tx_errors++; if (status & TX_LOST_CRS) @@ -1543,37 +806,47 @@ 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. */ + * 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; + cs89_dbg(0, err, "%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 */ + * 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); + while (count) { + cs89_dbg(5, debug, + "%s: receiving %d DMA frames\n", + dev->name, count); + if (count > 1) + cs89_dbg(2, debug, + "%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); + if (count > 0) + cs89_dbg(2, debug, + "%s: continuing with %d DMA frames\n", + dev->name, count); } } #endif @@ -1589,73 +862,274 @@ return IRQ_RETVAL(handled); } -static void -count_rx_errors(int status, struct net_device *dev) +/* 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) { - dev->stats.rx_errors++; - if (status & RX_RUNT) - dev->stats.rx_length_errors++; - if (status & RX_EXTRA_DATA) - dev->stats.rx_length_errors++; - if ((status & RX_CRC_ERROR) && !(status & (RX_EXTRA_DATA|RX_RUNT))) - /* per str 172 */ - dev->stats.rx_crc_errors++; - if (status & RX_DRIBBLE) - dev->stats.rx_frame_errors++; -} + struct net_local *lp = netdev_priv(dev); + int result = 0; + int i; + int ret; -/* We have a good packet(s), get it/them out of the buffers. */ -static void -net_rx(struct net_device *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, dev); - return; - } - - /* Malloc up new buffer. */ - skb = netdev_alloc_skb(dev, 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); + 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 - dev->stats.rx_dropped++; - return; +/* 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. */ + pr_err("can't get an interrupt\n"); + ret = -EAGAIN; + goto bad_out; + } + } else { +#if !defined(CS89x0_NONISA_IRQ) && !defined(CONFIG_CS89x0_PLATFORM) + if (((1 << dev->irq) & lp->irq_map) == 0) { + pr_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) { + pr_err("request_irq(%d) failed\n", dev->irq); + goto bad_out; + } } - 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->stats.rx_packets++; - dev->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; + if (lp->use_dma && (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) { + pr_err("%s: cannot get %dK memory for DMA\n", + dev->name, lp->dmasize); + goto release_irq; + } + cs89_dbg(1, debug, "%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)) { + pr_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)) { + pr_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, DMA_RX_MODE); /* 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); + } + if (!result) { + pr_err("%s: EEPROM is configured for unavailable media\n", + dev->name); +release_dma: +#if ALLOW_DMA + free_dma(dev->dma); +release_irq: + 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) { + pr_warn("%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) { + pr_warn("%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) { + pr_warn("%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) { + result = detect_tp(dev); + if (result != DETECTED_NONE) + break; + } + if (lp->adapter_cnf & A_CNF_AUI) { + result = detect_aui(dev); + if (result != DETECTED_NONE) + break; + } + if (lp->adapter_cnf & A_CNF_10B_2) { + result = detect_bnc(dev); + if (result != DETECTED_NONE) + break; + } + pr_err("%s: no media detected\n", dev->name); + goto release_dma; + } + switch (result) { + case DETECTED_NONE: + pr_err("%s: no network cable attached to configured media\n", + dev->name); + goto release_dma; + case DETECTED_RJ45H: + pr_info("%s: using half-duplex 10Base-T (RJ-45)\n", dev->name); + break; + case DETECTED_RJ45F: + pr_info("%s: using full-duplex 10Base-T (RJ-45)\n", dev->name); + break; + case DETECTED_AUI: + pr_info("%s: using 10Base-5 (AUI)\n", dev->name); + break; + case DETECTED_BNC: + pr_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); + cs89_dbg(1, debug, "net_open() succeeded\n"); + return 0; +bad_out: + return ret; +} /* The inverse routine to net_open(). */ static int @@ -1685,8 +1159,9 @@ return 0; } -/* Get the current statistics. This may be called with the card open or - closed. */ +/* 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) { @@ -1702,34 +1177,97 @@ return &dev->stats; } +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. */ + cs89_dbg(0, err, "%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 netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev) +{ + struct net_local *lp = netdev_priv(dev); + unsigned long flags; + + cs89_dbg(3, debug, "%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_irqsave(&lp->lock, flags); + netif_stop_queue(dev); + + /* initiate a transmit sequence */ + iowrite16(lp->send_cmd, lp->virt_addr + TX_CMD_PORT); + iowrite16(skb->len, lp->virt_addr + TX_LEN_PORT); + + /* 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_irqrestore(&lp->lock, flags); + cs89_dbg(0, err, "Tx buffer not free!\n"); + return NETDEV_TX_BUSY; + } + /* Write the contents of the packet */ + writewords(lp, TX_FRAME_PORT, skb->data, (skb->len + 1) >> 1); + spin_unlock_irqrestore(&lp->lock, flags); + dev->stats.tx_bytes += skb->len; + 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 NETDEV_TX_OK; +} + 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) - { + if (dev->flags & IFF_PROMISC) lp->rx_mode = RX_ALL_ACCEPT; - } else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev)) - { - /* The multicast-accept list is initialized to accept-all, and we - rely on higher-level filtering for now. */ + /* 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)); + /* 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; @@ -1740,23 +1278,476 @@ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - if (net_debug) - printk("%s: Setting MAC address to %pM.\n", - dev->name, dev->dev_addr); + cs89_dbg(0, debug, "%s: Setting MAC address to %pM\n", + dev->name, 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)); + 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 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 + +static const struct net_device_ops net_ops = { + .ndo_open = net_open, + .ndo_stop = net_close, + .ndo_tx_timeout = net_timeout, + .ndo_start_xmit = net_send_packet, + .ndo_get_stats = net_get_stats, + .ndo_set_rx_mode = set_multicast_list, + .ndo_set_mac_address = set_mac_address, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = net_poll_controller, +#endif + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, +}; + +static void __init reset_chip(struct net_device *dev) +{ +#if !defined(CONFIG_MACH_MX31ADS) +#if !defined(CS89x0_NONISA_IRQ) + struct net_local *lp = netdev_priv(dev); +#endif /* CS89x0_NONISA_IRQ */ + int reset_start_time; + + writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET); + + /* wait 30 ms */ + msleep(30); + +#if !defined(CS89x0_NONISA_IRQ) + if (lp->chip_type != CS8900) { + /* Hardware problem requires PNP registers to be reconfigured after a reset */ + iowrite16(PP_CS8920_ISAINT, lp->virt_addr + ADD_PORT); + iowrite8(dev->irq, lp->virt_addr + DATA_PORT); + iowrite8(0, lp->virt_addr + DATA_PORT + 1); + + iowrite16(PP_CS8920_ISAMemB, lp->virt_addr + ADD_PORT); + iowrite8((dev->mem_start >> 16) & 0xff, + lp->virt_addr + DATA_PORT); + iowrite8((dev->mem_start >> 8) & 0xff, + lp->virt_addr + DATA_PORT + 1); + } +#endif /* CS89x0_NONISA_IRQ */ + + /* Wait until the chip is reset */ + reset_start_time = jiffies; + while ((readreg(dev, PP_SelfST) & INIT_DONE) == 0 && + jiffies - reset_start_time < 2) + ; +#endif /* !CONFIG_MACH_MX31ADS */ +} + +/* 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, void __iomem *ioaddr, int modular) +{ + struct net_local *lp = netdev_priv(dev); + int i; + int tmp; + unsigned rev_type = 0; + int eeprom_buff[CHKSUM_LEN]; + int retval; + + /* 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 + } + + pr_debug("PP_addr at %p[%x]: 0x%x\n", + ioaddr, ADD_PORT, ioread16(ioaddr + ADD_PORT)); + iowrite16(PP_ChipID, ioaddr + ADD_PORT); + + tmp = ioread16(ioaddr + DATA_PORT); + if (tmp != CHIP_EISA_ID_SIG) { + pr_debug("%s: incorrect signature at %p[%x]: 0x%x!=" + CHIP_EISA_ID_SIG_STR "\n", + dev->name, ioaddr, DATA_PORT, tmp); + retval = -ENODEV; + goto out1; + } + + lp->virt_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; + + pr_info_once("%s\n", version); + + pr_info("%s: cs89%c0%s rev %c found at %p ", + dev->name, + lp->chip_type == CS8900 ? '0' : '2', + lp->chip_type == CS8920M ? "M" : "", + lp->chip_revision, + lp->virt_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. + */ + + 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; + + cs89_dbg(1, 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; + + pr_cont("[Cirrus EEPROM] "); + } + + pr_cont("\n"); + + /* First check to see if an EEPROM is attached. */ + + if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0) + pr_warn("No EEPROM, relying on command line....\n"); + else if (get_eeprom_data(dev, START_EEPROM_DATA, CHKSUM_LEN, eeprom_buff) < 0) { + pr_warn("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)) + pr_warn("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; + } + cs89_dbg(1, 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; + } + + cs89_dbg(1, 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 + */ + + pr_info("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; +#ifndef CONFIG_CS89x0_PLATFORM + if (lp->chip_type == CS8900) { +#ifdef CS89x0_NONISA_IRQ + i = cs8900_irq_map[0]; +#else + /* Translate the IRQ using the IRQ mapping table. */ + if (i >= ARRAY_SIZE(cs8900_irq_map)) + pr_err("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 + } +#endif + if (!dev->irq) + dev->irq = i; + } + + pr_cont(" IRQ %d", dev->irq); + +#if ALLOW_DMA + if (lp->use_dma) { + get_dma_channel(dev); + pr_cont(", DMA %d", dev->dma); + } else +#endif + pr_cont(", programmed I/O"); + + /* print the ethernet address. */ + pr_cont(", MAC %pM\n", dev->dev_addr); + + dev->netdev_ops = &net_ops; + dev->watchdog_timeo = HZ; + + cs89_dbg(0, info, "cs89x0_probe1() successful\n"); + + retval = register_netdev(dev); + if (retval) + goto out2; + return 0; +out2: + iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT); +out1: + return retval; +} + +#ifndef CONFIG_CS89x0_PLATFORM +/* + * This function converts the I/O port addres used by the cs89x0_probe() and + * init_module() functions to the I/O memory address used by the + * cs89x0_probe1() function. + */ +static int __init +cs89x0_ioport_probe(struct net_device *dev, unsigned long ioport, int modular) +{ + struct net_local *lp = netdev_priv(dev); + int ret; + void __iomem *io_mem; + + if (!lp) + return -ENOMEM; + + dev->base_addr = ioport; + + if (!request_region(ioport, NETCARD_IO_EXTENT, DRV_NAME)) { + ret = -EBUSY; + goto out; + } + + io_mem = ioport_map(ioport & ~3, NETCARD_IO_EXTENT); + if (!io_mem) { + ret = -ENOMEM; + goto release; + } + + /* 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 (ioport & 1) { + cs89_dbg(1, info, "%s: odd ioaddr 0x%lx\n", dev->name, ioport); + if ((ioport & 2) != 2) { + if ((ioread16(io_mem + ADD_PORT) & ADD_MASK) != + ADD_SIG) { + pr_err("%s: bad signature 0x%x\n", + dev->name, ioread16(io_mem + ADD_PORT)); + ret = -ENODEV; + goto unmap; + } + } + } + + ret = cs89x0_probe1(dev, io_mem, modular); + if (!ret) + goto out; +unmap: + ioport_unmap(io_mem); +release: + release_region(ioport, NETCARD_IO_EXTENT); +out: + return ret; +} + +#ifndef MODULE +/* 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; + + cs89_dbg(0, info, "cs89x0_probe(0x%x)\n", io); + + if (io > 0x1ff) { /* Check a single specified location. */ + err = cs89x0_ioport_probe(dev, io, 0); + } else if (io != 0) { /* Don't probe at all. */ + err = -ENXIO; + } else { + for (port = netcard_portlist; *port; port++) { + if (cs89x0_ioport_probe(dev, *port, 0) == 0) + break; + dev->irq = irq; + } + if (!*port) + err = -ENODEV; + } + if (err) + goto out; + return dev; +out: + free_netdev(dev); + pr_warn("no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n"); + return ERR_PTR(err); +} +#endif +#endif + #if defined(MODULE) && !defined(CONFIG_CS89x0_PLATFORM) static struct net_device *dev_cs89x0; -/* - * Support the 'debug' module parm even if we're compiled for non-debug to +/* Support the 'debug' module parm even if we're compiled for non-debug to * avoid breaking someone's startup scripts */ @@ -1764,11 +1755,11 @@ static int irq; static int debug; static char media[8]; -static int duplex=-1; +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 */ +static int dmasize = 16; /* or 64 */ module_param(io, int, 0); module_param(irq, int, 0); @@ -1801,32 +1792,28 @@ MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton"); 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) - - -*/ + * 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) { @@ -1856,8 +1843,8 @@ spin_lock_init(&lp->lock); - /* boy, they'd better get these right */ - if (!strcmp(media, "rj45")) + /* 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; @@ -1866,27 +1853,28 @@ else lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T; - if (duplex==-1) + 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; + if (io == 0) { + pr_err("Module autoprobing not allowed\n"); + pr_err("Append io=0xNNN\n"); + ret = -EPERM; goto out; - } else if (io <= 0x1ff) { + } 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); + pr_err("dma size must be either 16K or 64K, not %dK\n", + dmasize); ret = -EPERM; goto out; } #endif - ret = cs89x0_probe1(dev, io, 1); + ret = cs89x0_ioport_probe(dev, io, 1); if (ret) goto out; @@ -1900,8 +1888,11 @@ void __exit cleanup_module(void) { + struct net_local *lp = netdev_priv(dev_cs89x0); + unregister_netdev(dev_cs89x0); - writeword(dev_cs89x0->base_addr, ADD_PORT, PP_ChipID); + iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT); + ioport_unmap(lp->virt_addr); release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT); free_netdev(dev_cs89x0); } @@ -1913,6 +1904,7 @@ struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); struct net_local *lp; struct resource *mem_res; + void __iomem *virt_addr; int err; if (!dev) @@ -1923,29 +1915,28 @@ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dev->irq = platform_get_irq(pdev, 0); if (mem_res == NULL || dev->irq <= 0) { - dev_warn(&dev->dev, "memory/interrupt resource missing.\n"); + dev_warn(&dev->dev, "memory/interrupt resource missing\n"); err = -ENXIO; goto free; } - lp->phys_addr = mem_res->start; lp->size = resource_size(mem_res); - if (!request_mem_region(lp->phys_addr, lp->size, DRV_NAME)) { - dev_warn(&dev->dev, "request_mem_region() failed.\n"); + if (!request_mem_region(mem_res->start, lp->size, DRV_NAME)) { + dev_warn(&dev->dev, "request_mem_region() failed\n"); err = -EBUSY; goto free; } - lp->virt_addr = ioremap(lp->phys_addr, lp->size); - if (!lp->virt_addr) { - dev_warn(&dev->dev, "ioremap() failed.\n"); + virt_addr = ioremap(mem_res->start, lp->size); + if (!virt_addr) { + dev_warn(&dev->dev, "ioremap() failed\n"); err = -ENOMEM; goto release; } - err = cs89x0_probe1(dev, (unsigned long)lp->virt_addr, 0); + err = cs89x0_probe1(dev, virt_addr, 0); if (err) { - dev_warn(&dev->dev, "no cs8900 or cs8920 detected.\n"); + dev_warn(&dev->dev, "no cs8900 or cs8920 detected\n"); goto unmap; } @@ -1953,9 +1944,9 @@ return 0; unmap: - iounmap(lp->virt_addr); + iounmap(virt_addr); release: - release_mem_region(lp->phys_addr, lp->size); + release_mem_region(mem_res->start, lp->size); free: free_netdev(dev); return err; @@ -1965,10 +1956,16 @@ { struct net_device *dev = platform_get_drvdata(pdev); struct net_local *lp = netdev_priv(dev); + struct resource *mem_res; + /* This platform_get_resource() call will not return NULL, because + * the same call in cs89x0_platform_probe() has returned a non NULL + * value. + */ + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); unregister_netdev(dev); iounmap(lp->virt_addr); - release_mem_region(lp->phys_addr, lp->size); + release_mem_region(mem_res->start, lp->size); free_netdev(dev); return 0; } @@ -1996,13 +1993,3 @@ module_exit(cs89x0_cleanup); #endif /* CONFIG_CS89x0_PLATFORM */ - -/* - * Local variables: - * version-control: t - * kept-new-versions: 5 - * c-indent-level: 8 - * tab-width: 8 - * End: - * - */
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index d7ac6c1..8132c78 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -944,8 +944,7 @@ for (i = 0; i < enic->mc_count; i++) { for (j = 0; j < mc_count; j++) - if (compare_ether_addr(enic->mc_addr[i], - mc_addr[j]) == 0) + if (ether_addr_equal(enic->mc_addr[i], mc_addr[j])) break; if (j == mc_count) enic_dev_del_addr(enic, enic->mc_addr[i]); @@ -953,8 +952,7 @@ for (i = 0; i < mc_count; i++) { for (j = 0; j < enic->mc_count; j++) - if (compare_ether_addr(mc_addr[i], - enic->mc_addr[j]) == 0) + if (ether_addr_equal(mc_addr[i], enic->mc_addr[j])) break; if (j == enic->mc_count) enic_dev_add_addr(enic, mc_addr[i]); @@ -999,8 +997,7 @@ for (i = 0; i < enic->uc_count; i++) { for (j = 0; j < uc_count; j++) - if (compare_ether_addr(enic->uc_addr[i], - uc_addr[j]) == 0) + if (ether_addr_equal(enic->uc_addr[i], uc_addr[j])) break; if (j == uc_count) enic_dev_del_addr(enic, enic->uc_addr[i]); @@ -1008,8 +1005,7 @@ for (i = 0; i < uc_count; i++) { for (j = 0; j < enic->uc_count; j++) - if (compare_ether_addr(uc_addr[i], - enic->uc_addr[j]) == 0) + if (ether_addr_equal(uc_addr[i], enic->uc_addr[j])) break; if (j == enic->uc_count) enic_dev_add_addr(enic, uc_addr[i]);
diff --git a/drivers/net/ethernet/davicom/Kconfig b/drivers/net/ethernet/davicom/Kconfig index 972b62b..9745fe5 100644 --- a/drivers/net/ethernet/davicom/Kconfig +++ b/drivers/net/ethernet/davicom/Kconfig
@@ -4,7 +4,7 @@ config DM9000 tristate "DM9000 support" - depends on ARM || BLACKFIN || MIPS + depends on ARM || BLACKFIN || MIPS || COLDFIRE select CRC32 select NET_CORE select MII
diff --git a/drivers/net/ethernet/dec/ewrk3.c b/drivers/net/ethernet/dec/ewrk3.c index 1879f84..17ae8c6 100644 --- a/drivers/net/ethernet/dec/ewrk3.c +++ b/drivers/net/ethernet/dec/ewrk3.c
@@ -1016,7 +1016,8 @@ } else { lp->pktStats.multicast++; } - } else if (compare_ether_addr(p, dev->dev_addr) == 0) { + } else if (ether_addr_equal(p, + dev->dev_addr)) { lp->pktStats.unicast++; } lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */
diff --git a/drivers/net/ethernet/dec/tulip/de4x5.c b/drivers/net/ethernet/dec/tulip/de4x5.c index 18b106c..d3cd489 100644 --- a/drivers/net/ethernet/dec/tulip/de4x5.c +++ b/drivers/net/ethernet/dec/tulip/de4x5.c
@@ -1874,7 +1874,7 @@ } else { lp->pktStats.multicast++; } - } else if (compare_ether_addr(buf, dev->dev_addr) == 0) { + } else if (ether_addr_equal(buf, dev->dev_addr)) { lp->pktStats.unicast++; }
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index c3ee910..ff4eb8f 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -313,6 +313,11 @@ u32 tx_rate; }; +enum vf_state { + ENABLED = 0, + ASSIGNED = 1 +}; + #define BE_FLAGS_LINK_STATUS_INIT 1 #define BE_FLAGS_WORKER_SCHEDULED (1 << 3) #define BE_UC_PMAC_COUNT 30 @@ -403,8 +408,9 @@ u32 flash_status; struct completion flash_compl; - u32 num_vfs; - u8 is_virtfn; + u32 num_vfs; /* Number of VFs provisioned by PF driver */ + u32 dev_num_vfs; /* Number of VFs supported by HW */ + u8 virtfn; struct be_vf_cfg *vf_cfg; bool be3_native; u32 sli_family; @@ -415,10 +421,13 @@ bool wol; u32 max_pmac_cnt; /* Max secondary UC MACs programmable */ u32 uc_macs; /* Count of secondary UC MAC programmed */ + u32 msg_enable; }; -#define be_physfn(adapter) (!adapter->is_virtfn) +#define be_physfn(adapter) (!adapter->virtfn) #define sriov_enabled(adapter) (adapter->num_vfs > 0) +#define sriov_want(adapter) (adapter->dev_num_vfs && num_vfs && \ + be_physfn(adapter)) #define for_all_vfs(adapter, vf_cfg, i) \ for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \ i++, vf_cfg++) @@ -547,14 +556,6 @@ return val; } -static inline void be_check_sriov_fn_type(struct be_adapter *adapter) -{ - u32 sli_intf; - - pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf); - adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0; -} - static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac) { u32 addr; @@ -603,4 +604,6 @@ extern int be_load_fw(struct be_adapter *adapter, u8 *func); extern bool be_is_wol_supported(struct be_adapter *adapter); extern bool be_pause_supported(struct be_adapter *adapter); +extern u32 be_get_fw_log_level(struct be_adapter *adapter); + #endif /* BE_H */
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 43167e8..b24623c 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -2589,4 +2589,60 @@ mutex_unlock(&adapter->mbox_lock); pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma); return status; + +} +int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter, + struct be_dma_mem *cmd) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_get_ext_fat_caps *req; + int status; + + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; + + wrb = wrb_from_mbox(adapter); + if (!wrb) { + status = -EBUSY; + goto err; + } + + req = cmd->va; + be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_GET_EXT_FAT_CAPABILITES, + cmd->size, wrb, cmd); + req->parameter_type = cpu_to_le32(1); + + status = be_mbox_notify_wait(adapter); +err: + mutex_unlock(&adapter->mbox_lock); + return status; +} + +int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter, + struct be_dma_mem *cmd, + struct be_fat_conf_params *configs) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_set_ext_fat_caps *req; + int status; + + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { + status = -EBUSY; + goto err; + } + + req = cmd->va; + memcpy(&req->set_params, configs, sizeof(struct be_fat_conf_params)); + be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_SET_EXT_FAT_CAPABILITES, + cmd->size, wrb, cmd); + + status = be_mcc_notify_wait(adapter); +err: + spin_unlock_bh(&adapter->mcc_lock); + return status; }
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 944f031..0b1029b 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -189,6 +189,8 @@ #define OPCODE_COMMON_GET_PHY_DETAILS 102 #define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103 #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121 +#define OPCODE_COMMON_GET_EXT_FAT_CAPABILITES 125 +#define OPCODE_COMMON_SET_EXT_FAT_CAPABILITES 126 #define OPCODE_COMMON_GET_MAC_LIST 147 #define OPCODE_COMMON_SET_MAC_LIST 148 #define OPCODE_COMMON_GET_HSW_CONFIG 152 @@ -1602,6 +1604,56 @@ } } + +/************** get fat capabilites *******************/ +#define MAX_MODULES 27 +#define MAX_MODES 4 +#define MODE_UART 0 +#define FW_LOG_LEVEL_DEFAULT 48 +#define FW_LOG_LEVEL_FATAL 64 + +struct ext_fat_mode { + u8 mode; + u8 rsvd0; + u16 port_mask; + u32 dbg_lvl; + u64 fun_mask; +} __packed; + +struct ext_fat_modules { + u8 modules_str[32]; + u32 modules_id; + u32 num_modes; + struct ext_fat_mode trace_lvl[MAX_MODES]; +} __packed; + +struct be_fat_conf_params { + u32 max_log_entries; + u32 log_entry_size; + u8 log_type; + u8 max_log_funs; + u8 max_log_ports; + u8 rsvd0; + u32 supp_modes; + u32 num_modules; + struct ext_fat_modules module[MAX_MODULES]; +} __packed; + +struct be_cmd_req_get_ext_fat_caps { + struct be_cmd_req_hdr hdr; + u32 parameter_type; +}; + +struct be_cmd_resp_get_ext_fat_caps { + struct be_cmd_resp_hdr hdr; + struct be_fat_conf_params get_params; +}; + +struct be_cmd_req_set_ext_fat_caps { + struct be_cmd_req_hdr hdr; + struct be_fat_conf_params set_params; +}; + extern int be_pci_fnum_get(struct be_adapter *adapter); extern int be_cmd_POST(struct be_adapter *adapter); extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, @@ -1707,4 +1759,9 @@ extern int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid, u32 domain, u16 intf_id); extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter); +extern int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter, + struct be_dma_mem *cmd); +extern int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter, + struct be_dma_mem *cmd, + struct be_fat_conf_params *cfgs);
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index 747f68f..63e51d4 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -878,6 +878,81 @@ return status; } +static u32 be_get_msg_level(struct net_device *netdev) +{ + struct be_adapter *adapter = netdev_priv(netdev); + + if (lancer_chip(adapter)) { + dev_err(&adapter->pdev->dev, "Operation not supported\n"); + return -EOPNOTSUPP; + } + + return adapter->msg_enable; +} + +static void be_set_fw_log_level(struct be_adapter *adapter, u32 level) +{ + struct be_dma_mem extfat_cmd; + struct be_fat_conf_params *cfgs; + int status; + int i, j; + + memset(&extfat_cmd, 0, sizeof(struct be_dma_mem)); + extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps); + extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size, + &extfat_cmd.dma); + if (!extfat_cmd.va) { + dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n", + __func__); + goto err; + } + status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd); + if (!status) { + cfgs = (struct be_fat_conf_params *)(extfat_cmd.va + + sizeof(struct be_cmd_resp_hdr)); + for (i = 0; i < cfgs->num_modules; i++) { + for (j = 0; j < cfgs->module[i].num_modes; j++) { + if (cfgs->module[i].trace_lvl[j].mode == + MODE_UART) + cfgs->module[i].trace_lvl[j].dbg_lvl = + cpu_to_le32(level); + } + } + status = be_cmd_set_ext_fat_capabilites(adapter, &extfat_cmd, + cfgs); + if (status) + dev_err(&adapter->pdev->dev, + "Message level set failed\n"); + } else { + dev_err(&adapter->pdev->dev, "Message level get failed\n"); + } + + pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va, + extfat_cmd.dma); +err: + return; +} + +static void be_set_msg_level(struct net_device *netdev, u32 level) +{ + struct be_adapter *adapter = netdev_priv(netdev); + + if (lancer_chip(adapter)) { + dev_err(&adapter->pdev->dev, "Operation not supported\n"); + return; + } + + if (adapter->msg_enable == level) + return; + + if ((level & NETIF_MSG_HW) != (adapter->msg_enable & NETIF_MSG_HW)) + be_set_fw_log_level(adapter, level & NETIF_MSG_HW ? + FW_LOG_LEVEL_DEFAULT : FW_LOG_LEVEL_FATAL); + adapter->msg_enable = level; + + return; +} + const struct ethtool_ops be_ethtool_ops = { .get_settings = be_get_settings, .get_drvinfo = be_get_drvinfo, @@ -893,6 +968,8 @@ .set_pauseparam = be_set_pauseparam, .get_strings = be_get_stat_strings, .set_phys_id = be_set_phys_id, + .get_msglevel = be_get_msg_level, + .set_msglevel = be_set_msg_level, .get_sset_count = be_get_sset_count, .get_ethtool_stats = be_get_ethtool_stats, .get_regs_len = be_get_reg_len,
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h index 0949aa6..f38b58c8 100644 --- a/drivers/net/ethernet/emulex/benet/be_hw.h +++ b/drivers/net/ethernet/emulex/benet/be_hw.h
@@ -58,6 +58,8 @@ #define SLI_PORT_CONTROL_IP_MASK 0x08000000 +#define PCICFG_CUST_SCRATCHPAD_CSR 0x1EC + /********* Memory BAR register ************/ #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 6d5d30b..081c777 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1049,6 +1049,29 @@ return status; } +static int be_find_vfs(struct be_adapter *adapter, int vf_state) +{ + struct pci_dev *dev, *pdev = adapter->pdev; + int vfs = 0, assigned_vfs = 0, pos, vf_fn; + u16 offset, stride; + + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); + pci_read_config_word(pdev, pos + PCI_SRIOV_VF_OFFSET, &offset); + pci_read_config_word(pdev, pos + PCI_SRIOV_VF_STRIDE, &stride); + + dev = pci_get_device(pdev->vendor, PCI_ANY_ID, NULL); + while (dev) { + vf_fn = (pdev->devfn + offset + stride * vfs) & 0xFFFF; + if (dev->is_virtfn && dev->devfn == vf_fn) { + vfs++; + if (dev->dev_flags & PCI_DEV_FLAGS_ASSIGNED) + assigned_vfs++; + } + dev = pci_get_device(pdev->vendor, PCI_ANY_ID, dev); + } + return (vf_state == ASSIGNED) ? assigned_vfs : vfs; +} + static void be_eqd_update(struct be_adapter *adapter, struct be_eq_obj *eqo) { struct be_rx_stats *stats = rx_stats(&adapter->rx_obj[eqo->idx]); @@ -1789,9 +1812,9 @@ static int be_num_txqs_want(struct be_adapter *adapter) { - if (sriov_enabled(adapter) || be_is_mc(adapter) || - lancer_chip(adapter) || !be_physfn(adapter) || - adapter->generation == BE_GEN2) + if (sriov_want(adapter) || be_is_mc(adapter) || + lancer_chip(adapter) || !be_physfn(adapter) || + adapter->generation == BE_GEN2) return 1; else return MAX_TX_QS; @@ -2118,7 +2141,7 @@ static uint be_num_rss_want(struct be_adapter *adapter) { if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) && - adapter->num_vfs == 0 && be_physfn(adapter) && + !sriov_want(adapter) && be_physfn(adapter) && !be_is_mc(adapter)) return (adapter->be3_native) ? BE3_MAX_RSS_QS : BE2_MAX_RSS_QS; else @@ -2152,53 +2175,6 @@ return; } -static int be_sriov_enable(struct be_adapter *adapter) -{ - be_check_sriov_fn_type(adapter); - -#ifdef CONFIG_PCI_IOV - if (be_physfn(adapter) && num_vfs) { - int status, pos; - u16 dev_vfs; - - pos = pci_find_ext_capability(adapter->pdev, - PCI_EXT_CAP_ID_SRIOV); - pci_read_config_word(adapter->pdev, - pos + PCI_SRIOV_TOTAL_VF, &dev_vfs); - - adapter->num_vfs = min_t(u16, num_vfs, dev_vfs); - if (adapter->num_vfs != num_vfs) - dev_info(&adapter->pdev->dev, - "Device supports %d VFs and not %d\n", - adapter->num_vfs, num_vfs); - - status = pci_enable_sriov(adapter->pdev, adapter->num_vfs); - if (status) - adapter->num_vfs = 0; - - if (adapter->num_vfs) { - adapter->vf_cfg = kcalloc(num_vfs, - sizeof(struct be_vf_cfg), - GFP_KERNEL); - if (!adapter->vf_cfg) - return -ENOMEM; - } - } -#endif - return 0; -} - -static void be_sriov_disable(struct be_adapter *adapter) -{ -#ifdef CONFIG_PCI_IOV - if (sriov_enabled(adapter)) { - pci_disable_sriov(adapter->pdev); - kfree(adapter->vf_cfg); - adapter->num_vfs = 0; - } -#endif -} - static inline int be_msix_vec_get(struct be_adapter *adapter, struct be_eq_obj *eqo) { @@ -2500,6 +2476,11 @@ struct be_vf_cfg *vf_cfg; u32 vf; + if (be_find_vfs(adapter, ASSIGNED)) { + dev_warn(&adapter->pdev->dev, "VFs are assigned to VMs\n"); + goto done; + } + for_all_vfs(adapter, vf_cfg, vf) { if (lancer_chip(adapter)) be_cmd_set_mac_list(adapter, NULL, 0, vf + 1); @@ -2509,6 +2490,10 @@ be_cmd_if_destroy(adapter, vf_cfg->if_handle, vf + 1); } + pci_disable_sriov(adapter->pdev); +done: + kfree(adapter->vf_cfg); + adapter->num_vfs = 0; } static int be_clear(struct be_adapter *adapter) @@ -2538,29 +2523,60 @@ be_cmd_fw_clean(adapter); be_msix_disable(adapter); - kfree(adapter->pmac_id); + pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 0); return 0; } -static void be_vf_setup_init(struct be_adapter *adapter) +static int be_vf_setup_init(struct be_adapter *adapter) { struct be_vf_cfg *vf_cfg; int vf; + adapter->vf_cfg = kcalloc(adapter->num_vfs, sizeof(*vf_cfg), + GFP_KERNEL); + if (!adapter->vf_cfg) + return -ENOMEM; + for_all_vfs(adapter, vf_cfg, vf) { vf_cfg->if_handle = -1; vf_cfg->pmac_id = -1; } + return 0; } static int be_vf_setup(struct be_adapter *adapter) { struct be_vf_cfg *vf_cfg; + struct device *dev = &adapter->pdev->dev; u32 cap_flags, en_flags, vf; u16 def_vlan, lnk_speed; - int status; + int status, enabled_vfs; - be_vf_setup_init(adapter); + enabled_vfs = be_find_vfs(adapter, ENABLED); + if (enabled_vfs) { + dev_warn(dev, "%d VFs are already enabled\n", enabled_vfs); + dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs); + return 0; + } + + if (num_vfs > adapter->dev_num_vfs) { + dev_warn(dev, "Device supports %d VFs and not %d\n", + adapter->dev_num_vfs, num_vfs); + num_vfs = adapter->dev_num_vfs; + } + + status = pci_enable_sriov(adapter->pdev, num_vfs); + if (!status) { + adapter->num_vfs = num_vfs; + } else { + /* Platform doesn't support SRIOV though device supports it */ + dev_warn(dev, "SRIOV enable failed\n"); + return 0; + } + + status = be_vf_setup_init(adapter); + if (status) + goto err; cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_MULTICAST; @@ -2571,9 +2587,11 @@ goto err; } - status = be_vf_eth_addr_config(adapter); - if (status) - goto err; + if (!enabled_vfs) { + status = be_vf_eth_addr_config(adapter); + if (status) + goto err; + } for_all_vfs(adapter, vf_cfg, vf) { status = be_cmd_link_status_query(adapter, NULL, &lnk_speed, @@ -2630,9 +2648,25 @@ return status; } +/* Routine to query per function resource limits */ +static int be_get_config(struct be_adapter *adapter) +{ + int pos; + u16 dev_num_vfs; + + pos = pci_find_ext_capability(adapter->pdev, PCI_EXT_CAP_ID_SRIOV); + if (pos) { + pci_read_config_word(adapter->pdev, pos + PCI_SRIOV_TOTAL_VF, + &dev_num_vfs); + adapter->dev_num_vfs = dev_num_vfs; + } + return 0; +} + static int be_setup(struct be_adapter *adapter) { struct net_device *netdev = adapter->netdev; + struct device *dev = &adapter->pdev->dev; u32 cap_flags, en_flags; u32 tx_fc, rx_fc; int status; @@ -2640,6 +2674,8 @@ be_setup_init(adapter); + be_get_config(adapter); + be_cmd_req_native_mode(adapter); be_msix_enable(adapter); @@ -2718,10 +2754,11 @@ pcie_set_readrq(adapter->pdev, 4096); - if (sriov_enabled(adapter)) { - status = be_vf_setup(adapter); - if (status) - goto err; + if (be_physfn(adapter) && num_vfs) { + if (adapter->dev_num_vfs) + be_vf_setup(adapter); + else + dev_warn(dev, "device doesn't support SRIOV\n"); } be_cmd_get_phy_info(adapter); @@ -2731,6 +2768,7 @@ schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); adapter->flags |= BE_FLAGS_WORKER_SCHEDULED; + pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 1); return 0; err: be_clear(adapter); @@ -3352,8 +3390,6 @@ be_ctrl_cleanup(adapter); - be_sriov_disable(adapter); - pci_set_drvdata(pdev, NULL); pci_release_regions(pdev); pci_disable_device(pdev); @@ -3367,9 +3403,43 @@ !be_is_wol_excluded(adapter)) ? true : false; } -static int be_get_config(struct be_adapter *adapter) +u32 be_get_fw_log_level(struct be_adapter *adapter) +{ + struct be_dma_mem extfat_cmd; + struct be_fat_conf_params *cfgs; + int status; + u32 level = 0; + int j; + + memset(&extfat_cmd, 0, sizeof(struct be_dma_mem)); + extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps); + extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size, + &extfat_cmd.dma); + + if (!extfat_cmd.va) { + dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n", + __func__); + goto err; + } + + status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd); + if (!status) { + cfgs = (struct be_fat_conf_params *)(extfat_cmd.va + + sizeof(struct be_cmd_resp_hdr)); + for (j = 0; j < cfgs->module[0].num_modes; j++) { + if (cfgs->module[0].trace_lvl[j].mode == MODE_UART) + level = cfgs->module[0].trace_lvl[j].dbg_lvl; + } + } + pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va, + extfat_cmd.dma); +err: + return level; +} +static int be_get_initial_config(struct be_adapter *adapter) { int status; + u32 level; status = be_cmd_query_fw_cfg(adapter, &adapter->port_num, &adapter->function_mode, &adapter->function_caps); @@ -3407,10 +3477,13 @@ if (be_is_wol_supported(adapter)) adapter->wol = true; + level = be_get_fw_log_level(adapter); + adapter->msg_enable = level <= FW_LOG_LEVEL_DEFAULT ? NETIF_MSG_HW : 0; + return 0; } -static int be_dev_family_check(struct be_adapter *adapter) +static int be_dev_type_check(struct be_adapter *adapter) { struct pci_dev *pdev = adapter->pdev; u32 sli_intf = 0, if_type; @@ -3443,6 +3516,9 @@ default: adapter->generation = 0; } + + pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf); + adapter->virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0; return 0; } @@ -3586,6 +3662,14 @@ schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); } +static bool be_reset_required(struct be_adapter *adapter) +{ + u32 reg; + + pci_read_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, ®); + return reg; +} + static int __devinit be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) { @@ -3611,7 +3695,7 @@ adapter->pdev = pdev; pci_set_drvdata(pdev, adapter); - status = be_dev_family_check(adapter); + status = be_dev_type_check(adapter); if (status) goto free_netdev; @@ -3629,13 +3713,9 @@ } } - status = be_sriov_enable(adapter); - if (status) - goto free_netdev; - status = be_ctrl_init(adapter); if (status) - goto disable_sriov; + goto free_netdev; if (lancer_chip(adapter)) { status = lancer_wait_ready(adapter); @@ -3662,9 +3742,11 @@ if (status) goto ctrl_clean; - status = be_cmd_reset_function(adapter); - if (status) - goto ctrl_clean; + if (be_reset_required(adapter)) { + status = be_cmd_reset_function(adapter); + if (status) + goto ctrl_clean; + } /* The INTR bit may be set in the card when probed by a kdump kernel * after a crash. @@ -3676,7 +3758,7 @@ if (status) goto ctrl_clean; - status = be_get_config(adapter); + status = be_get_initial_config(adapter); if (status) goto stats_clean; @@ -3705,8 +3787,6 @@ be_stats_cleanup(adapter); ctrl_clean: be_ctrl_cleanup(adapter); -disable_sriov: - be_sriov_disable(adapter); free_netdev: free_netdev(netdev); pci_set_drvdata(pdev, NULL);
diff --git a/drivers/net/ethernet/fujitsu/at1700.c b/drivers/net/ethernet/fujitsu/at1700.c index 3d94797..4b80dc4 100644 --- a/drivers/net/ethernet/fujitsu/at1700.c +++ b/drivers/net/ethernet/fujitsu/at1700.c
@@ -27,7 +27,7 @@ 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> + MCA bus (AT1720) support (now deleted) by Rene Schmit <rene@bss.lu> Bugs: The MB86965 has a design flaw that makes all probes unreliable. Not @@ -38,7 +38,6 @@ #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> @@ -79,24 +78,6 @@ 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 @@ -114,7 +95,6 @@ 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. */ }; @@ -166,21 +146,6 @@ 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. @@ -194,11 +159,6 @@ 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); } @@ -273,7 +233,7 @@ static const char fmv_irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15}; static const 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; + int ret = -ENODEV; struct net_local *lp = netdev_priv(dev); if (!request_region(ioaddr, AT1700_IO_EXTENT, DRV_NAME)) @@ -288,64 +248,6 @@ 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 < 8; 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 && @@ -360,11 +262,7 @@ goto err_out; } -#ifdef CONFIG_MCA_LEGACY -found: -#endif - - /* Reset the internal state machines. */ + /* Reset the internal state machines. */ outb(0, ioaddr + RESET); if (is_at1700) { @@ -380,11 +278,11 @@ break; } if (i == 8) { - goto err_mca; + goto err_out; } } else { if (fmv18x_probe_list[inb(ioaddr + IOCONFIG) & 0x07] != ioaddr) - goto err_mca; + goto err_out; irq = fmv_irqmap[(inb(ioaddr + IOCONFIG)>>6) & 0x03]; } } @@ -464,23 +362,17 @@ 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; + goto err_out; } 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;
diff --git a/drivers/net/ethernet/i825xx/3c523.c b/drivers/net/ethernet/i825xx/3c523.c deleted file mode 100644 index 8451ecd..0000000 --- a/drivers/net/ethernet/i825xx/3c523.c +++ /dev/null
@@ -1,1312 +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 every time 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/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) { \ - pr_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 netdev_tx_t 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, - dev->name, dev); - if (ret) { - pr_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 = netdev_priv(dev); - 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. - */ - -static void alloc586(struct net_device *dev) -{ - struct priv *p = netdev_priv(dev); - - 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) - pr_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; - - 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: %pM\n", - dev->dev_addr); - - return len; -} /* elmc_getinfo() */ - -static const struct net_device_ops netdev_ops = { - .ndo_open = elmc_open, - .ndo_stop = elmc_close, - .ndo_get_stats = elmc_get_stats, - .ndo_start_xmit = elmc_send_packet, - .ndo_tx_timeout = elmc_timeout, -#ifdef ELMC_MULTICAST - .ndo_set_rx_mode = set_multicast_list, -#endif - .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, -}; - -/*****************************************************************/ - -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 = netdev_priv(dev); - - 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 */ - pr_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; - } - - pr->slot = slot; - - pr_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)) { - pr_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 */ - pr_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); - - pr_info("%s: hardware address %pM\n", - dev->name, dev->dev_addr); - - dev->netdev_ops = &netdev_ops; - dev->watchdog_timeo = HZ; - 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; -} - -#ifdef MODULE -static void cleanup_card(struct net_device *dev) -{ - mca_set_adapter_procfn(((struct priv *)netdev_priv(dev))->slot, - NULL, NULL); - release_region(dev->base_addr, ELMC_IO_EXTENT); -} -#else -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 = netdev_priv(dev); - 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 netdev_hw_addr *ha; - int num_addrs = netdev_mc_count(dev); - - 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)) { - pr_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)) { - pr_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)) { - pr_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) { - pr_warning("%s: TDR: Transceiver problem!\n", dev->name); - } else if (result & TDR_ET_OPN) { - pr_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 :-) */ - pr_warning("%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK); - } else { - pr_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 (num_addrs) { - /* 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) { - pr_err("%s: Ooooops, no memory for MC-Setup!\n", dev->name); - } else { - if (len < num_addrs) { - num_addrs = len; - pr_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; - i = 0; - netdev_for_each_mc_addr(ha, dev) - memcpy((char *) mc_cmd->mc_list[i++], - ha->addr, 6); - 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)) { - pr_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) { - pr_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 = netdev_priv(dev); - - 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 = netdev_priv(dev); - - 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)) { - pr_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 { - pr_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 = netdev_priv(dev); - - 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 = netdev_alloc_skb(dev, 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->stats.rx_packets++; - dev->stats.rx_bytes += totlen; - } else { - dev->stats.rx_dropped++; - } - } else { - pr_warning("%s: received oversized frame.\n", dev->name); - dev->stats.rx_dropped++; - } - } else { /* frame !(ok), only with 'save-bad-frames' */ - pr_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 = netdev_priv(dev); - - 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 */ - - pr_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 = netdev_priv(dev); - - status = p->xmit_cmds[p->xmit_last]->cmd_status; - if (!(status & STAT_COMPL)) { - pr_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) { - pr_warning("%s: late collision detected.\n", dev->name); - dev->stats.collisions++; - } else if (status & TCMD_NOCARRIER) { - dev->stats.tx_carrier_errors++; - pr_warning("%s: no carrier detected.\n", dev->name); - } else if (status & TCMD_LOSTCTS) { - pr_warning("%s: loss of CTS detected.\n", dev->name); - } else if (status & TCMD_UNDERRUN) { - dev->stats.tx_fifo_errors++; - pr_warning("%s: DMA underrun detected.\n", dev->name); - } else if (status & TCMD_MAXCOLL) { - pr_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 = netdev_priv(dev); - - 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 = netdev_priv(dev); - /* COMMAND-UNIT active? */ - if (p->scb->status & CU_ACTIVE) { - pr_debug("%s: strange ... timeout with CU active?!?\n", dev->name); - pr_debug("%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); - 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 { - pr_debug("%s: xmitter timed out, try to restart! stat: %04x\n", - dev->name, p->scb->status); - pr_debug("%s: command-stats: %04x %04x\n", dev->name, - p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status); - elmc_close(dev); - elmc_open(dev); - } -} - -/****************************************************** - * send frame - */ - -static netdev_tx_t 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 = netdev_priv(dev); - - 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(); - 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) { - pr_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])); - 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])); - p->xmit_count = next_nop; - if (p->xmit_count != p->xmit_last) - netif_wake_queue(dev); - dev_kfree_skb(skb); -#endif - return NETDEV_TX_OK; -} - -/******************************************* - * Someone wanna have the statistics - */ - -static struct net_device_stats *elmc_get_stats(struct net_device *dev) -{ - struct priv *p = netdev_priv(dev); - 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; - pr_warning("3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]); - } - - if(found==0) { - if (io[0]==0) - pr_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/ethernet/i825xx/3c523.h b/drivers/net/ethernet/i825xx/3c523.h deleted file mode 100644 index 6956441..0000000 --- a/drivers/net/ethernet/i825xx/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/ethernet/i825xx/3c527.c b/drivers/net/ethernet/i825xx/3c527.c deleted file mode 100644 index 278e791..0000000 --- a/drivers/net/ethernet/i825xx/3c527.c +++ /dev/null
@@ -1,1660 +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 initial 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/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 - -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 netdev_tx_t 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); -} - -static const struct net_device_ops netdev_ops = { - .ndo_open = mc32_open, - .ndo_stop = mc32_close, - .ndo_start_xmit = mc32_send_packet, - .ndo_get_stats = mc32_get_stats, - .ndo_set_rx_mode = mc32_set_multicast_list, - .ndo_tx_timeout = mc32_timeout, - .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, -}; - -/** - * 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 const u16 mca_io_bases[] = { - 0x7280,0x7290, - 0x7680,0x7690, - 0x7A80,0x7A90, - 0x7E80,0x7E90 - }; - static const u32 mca_mem_bases[] = { - 0x00C0000, - 0x00C4000, - 0x00C8000, - 0x00CC000, - 0x00D0000, - 0x00D4000, - 0x00D8000, - 0x00DC000 - }; - static const char * const 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" - }; - - /* Time to play MCA games */ - - if (mc32_debug && version_printed++ == 0) - pr_debug("%s", version); - - pr_info("%s: %s found in slot %d: ", dev->name, cardname, slot); - - POS = mca_read_stored_pos(slot, 2); - - if(!(POS&1)) - { - pr_cont("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)) - { - pr_cont("memory window disabled.\n"); - return -ENODEV; - } - - POS = mca_read_stored_pos(slot, 5); - - i=(POS>>4)&3; - if(i==3) - { - pr_cont("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)) - { - pr_cont("io 0x%3lX, which is busy.\n", dev->base_addr); - return -EBUSY; - } - - pr_cont("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); - } - - pr_info("%s: Address %pM ", dev->name, 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) - pr_cont(": BNC port selected.\n"); - else - pr_cont(": 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, DRV_NAME, dev); - if (err) { - release_region(dev->base_addr, MC32_IO_EXTENT); - pr_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) - { - pr_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) - pr_err("%s: %s%s.\n", dev->name, failures[base-1], - base<0x0A?" test failure":""); - else - pr_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) - { - pr_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 */ - - sema_init(&lp->cmd_mutex, 0); - init_completion(&lp->execution_cmd); - init_completion(&lp->xceiver_cmd); - - pr_info("%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->netdev_ops = &netdev_ops; - 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 initialises 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 - * initialise 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 position 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)) { - pr_info("%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) -{ - pr_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 netdev_tx_t 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 NETDEV_TX_BUSY; - } - - if (skb_padto(skb, ETH_ZLEN)) { - netif_wake_queue(dev); - return NETDEV_TX_OK; - } - - 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 NETDEV_TX_OK; -} - - -/** - * 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 = netdev_alloc_skb(dev, 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 = netdev_alloc_skb(dev, 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->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); - - pr_debug("Status TX%d RX%d EX%d OV%d BC%d\n", - (status&7), (status>>3)&7, (status>>6)&1, - (status>>7)&1, boguscount); - - 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: - pr_notice("%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: - pr_notice("%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) || - netdev_mc_count(dev) > 10) - /* Enable promiscuous mode */ - filt |= 1; - else if (!netdev_mc_empty(dev)) - { - unsigned char block[62]; - unsigned char *bp; - struct netdev_hw_addr *ha; - - if(retry==0) - lp->mc_list_valid = 0; - if(!lp->mc_list_valid) - { - block[1]=0; - block[0]=netdev_mc_count(dev); - bp=block+2; - - netdev_for_each_mc_addr(ha, dev) { - memcpy(bp, ha->addr, 6); - bp+=6; - } - if(mc32_command_nowait(dev, 2, block, - 2+6*netdev_mc_count(dev))==-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/ethernet/i825xx/3c527.h b/drivers/net/ethernet/i825xx/3c527.h deleted file mode 100644 index d693b8d1..0000000 --- a/drivers/net/ethernet/i825xx/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]; -} __packed; - -struct skb_header -{ - u8 status; - u8 control; - u16 next; /* Do not change! */ - u16 length; - u32 data; -} __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]; -} __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/ethernet/i825xx/Kconfig b/drivers/net/ethernet/i825xx/Kconfig index ca1ae98..fed5080 100644 --- a/drivers/net/ethernet/i825xx/Kconfig +++ b/drivers/net/ethernet/i825xx/Kconfig
@@ -43,28 +43,6 @@ To compile this driver as a module, choose M here. The module will be called 3c507. -config ELMC - tristate "3c523 \"EtherLink/MC\" support" - depends on 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 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 ARM_ETHER1 tristate "Acorn Ether1 support" depends on ARM && ARCH_ACORN
diff --git a/drivers/net/ethernet/i825xx/Makefile b/drivers/net/ethernet/i825xx/Makefile index f68a369..6adff85 100644 --- a/drivers/net/ethernet/i825xx/Makefile +++ b/drivers/net/ethernet/i825xx/Makefile
@@ -7,8 +7,6 @@ obj-$(CONFIG_EEXPRESS_PRO) += eepro.o obj-$(CONFIG_ELPLUS) += 3c505.o obj-$(CONFIG_EL16) += 3c507.o -obj-$(CONFIG_ELMC) += 3c523.o -obj-$(CONFIG_ELMC_II) += 3c527.o obj-$(CONFIG_LP486E) += lp486e.o obj-$(CONFIG_NI52) += ni52.o obj-$(CONFIG_SUN3_82586) += sun3_82586.o
diff --git a/drivers/net/ethernet/i825xx/eexpress.c b/drivers/net/ethernet/i825xx/eexpress.c index cc2e66a..7a6a2f0 100644 --- a/drivers/net/ethernet/i825xx/eexpress.c +++ b/drivers/net/ethernet/i825xx/eexpress.c
@@ -9,7 +9,7 @@ * Many modifications, and currently maintained, by * Philip Blundell <philb@gnu.org> * Added the Compaq LTE Alan Cox <alan@lxorguk.ukuu.org.uk> - * Added MCA support Adam Fritzler + * Added MCA support Adam Fritzler (now deleted) * * 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 @@ -111,7 +111,6 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> -#include <linux/mca-legacy.h> #include <linux/spinlock.h> #include <linux/bitops.h> #include <linux/jiffies.h> @@ -227,16 +226,6 @@ /* 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 */ @@ -340,53 +329,6 @@ 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: Transceiver 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;
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index c9069a2..f4d2da0 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c
@@ -3335,6 +3335,8 @@ goto out_shutdown_ports; } + /* Handle any events that might be pending. */ + tasklet_hi_schedule(&adapter->neq_tasklet); ret = 0; goto out;
diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 546efe3..79b07ec 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig
@@ -220,6 +220,17 @@ If unsure, say N. +config IXGBE_PTP + bool "PTP Clock Support" + default n + depends on IXGBE && PTP_1588_CLOCK + ---help--- + Say Y here if you want support for 1588 Timestamping with a + PHC device, using the PTP 1588 Clock support. This is + required to enable timestamping support for the device. + + If unsure, say N. + config IXGBEVF tristate "Intel(R) 82599 Virtual Function Ethernet support" depends on PCI_MSI
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index f1aef68..95731c8 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -493,7 +493,11 @@ static void e1000_down_and_stop(struct e1000_adapter *adapter) { set_bit(__E1000_DOWN, &adapter->flags); - cancel_work_sync(&adapter->reset_task); + + /* Only kill reset task if adapter is not resetting */ + if (!test_bit(__E1000_RESETTING, &adapter->flags)) + cancel_work_sync(&adapter->reset_task); + cancel_delayed_work_sync(&adapter->watchdog_task); cancel_delayed_work_sync(&adapter->phy_info_task); cancel_delayed_work_sync(&adapter->fifo_stall_task); @@ -4066,7 +4070,11 @@ /* errors is only valid for DD + EOP descriptors */ if (unlikely((status & E1000_RXD_STAT_EOP) && (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) { - u8 last_byte = *(skb->data + length - 1); + u8 *mapped; + u8 last_byte; + + mapped = page_address(buffer_info->page); + last_byte = *(mapped + length - 1); if (TBI_ACCEPT(hw, status, rx_desc->errors, length, last_byte)) { spin_lock_irqsave(&adapter->stats_lock, @@ -4391,30 +4399,6 @@ break; } - /* Fix for errata 23, can't cross 64kB boundary */ - if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) { - struct sk_buff *oldskb = skb; - e_err(rx_err, "skb align check failed: %u bytes at " - "%p\n", bufsz, skb->data); - /* Try again, without freeing the previous */ - skb = netdev_alloc_skb_ip_align(netdev, bufsz); - /* Failed allocation, critical failure */ - if (!skb) { - dev_kfree_skb(oldskb); - adapter->alloc_rx_buff_failed++; - break; - } - - if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) { - /* give up */ - dev_kfree_skb(skb); - dev_kfree_skb(oldskb); - break; /* while (cleaned_count--) */ - } - - /* Use new allocation */ - dev_kfree_skb(oldskb); - } buffer_info->skb = skb; buffer_info->length = adapter->rx_buffer_len; check_page:
diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index 11c4666..351a409 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h
@@ -76,7 +76,7 @@ /* Extended Device Control */ #define E1000_CTRL_EXT_LPCD 0x00000004 /* LCD Power Cycle Done */ #define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Definable Pin 3 */ -#define E1000_CTRL_EXT_FORCE_SMBUS 0x00000004 /* Force SMBus mode*/ +#define E1000_CTRL_EXT_FORCE_SMBUS 0x00000800 /* Force SMBus mode */ #define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ #define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */ #define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c index 42444d1..55cc1565b 100644 --- a/drivers/net/ethernet/intel/e1000e/param.c +++ b/drivers/net/ethernet/intel/e1000e/param.c
@@ -344,50 +344,16 @@ 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; - case 4: - e_info("%s set to simplified (2000-8000 ints) mode\n", - opt.name); - adapter->itr_setting = 4; - 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; - } + + /* + * Make sure a message is printed for non-special + * values. And in case of an invalid option, display + * warning, use default and go through itr/itr_setting + * adjustment logic below + */ + if ((adapter->itr > 4) && + e1000_validate_option(&adapter->itr, &opt, adapter)) + adapter->itr = opt.def; } else { /* * If no option specified, use default value and go @@ -399,7 +365,7 @@ * Make sure a message is printed for non-special * default values */ - if (adapter->itr > 40) + if (adapter->itr > 4) e_info("%s set to default %d\n", opt.name, adapter->itr); }
diff --git a/drivers/net/ethernet/intel/igb/Makefile b/drivers/net/ethernet/intel/igb/Makefile index 4bd16e2..97c197f 100644 --- a/drivers/net/ethernet/intel/igb/Makefile +++ b/drivers/net/ethernet/intel/igb/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_IGB) += igb.o igb-objs := igb_main.o igb_ethtool.o e1000_82575.o \ - e1000_mac.o e1000_nvm.o e1000_phy.o e1000_mbx.o + e1000_mac.o e1000_nvm.o e1000_phy.o e1000_mbx.o \ + e1000_i210.o igb-$(CONFIG_IGB_PTP) += igb_ptp.o
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index 08bdc33..e650839 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -36,6 +36,7 @@ #include "e1000_mac.h" #include "e1000_82575.h" +#include "e1000_i210.h" static s32 igb_get_invariants_82575(struct e1000_hw *); static s32 igb_acquire_phy_82575(struct e1000_hw *); @@ -52,6 +53,8 @@ static s32 igb_reset_hw_82575(struct e1000_hw *); static s32 igb_reset_hw_82580(struct e1000_hw *); static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *, bool); +static s32 igb_set_d0_lplu_state_82580(struct e1000_hw *, bool); +static s32 igb_set_d3_lplu_state_82580(struct e1000_hw *, bool); static s32 igb_setup_copper_link_82575(struct e1000_hw *); static s32 igb_setup_serdes_link_82575(struct e1000_hw *); static s32 igb_write_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16); @@ -96,6 +99,8 @@ break; case e1000_82580: case e1000_i350: + case e1000_i210: + case e1000_i211: reg = rd32(E1000_MDICNFG); ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO); break; @@ -150,6 +155,17 @@ case E1000_DEV_ID_I350_SGMII: mac->type = e1000_i350; break; + case E1000_DEV_ID_I210_COPPER: + case E1000_DEV_ID_I210_COPPER_OEM1: + case E1000_DEV_ID_I210_COPPER_IT: + case E1000_DEV_ID_I210_FIBER: + case E1000_DEV_ID_I210_SERDES: + case E1000_DEV_ID_I210_SGMII: + mac->type = e1000_i210; + break; + case E1000_DEV_ID_I211_COPPER: + mac->type = e1000_i211; + break; default: return -E1000_ERR_MAC_INIT; break; @@ -182,26 +198,44 @@ /* Set mta register count */ mac->mta_reg_count = 128; /* Set rar entry count */ - mac->rar_entry_count = E1000_RAR_ENTRIES_82575; - if (mac->type == e1000_82576) + switch (mac->type) { + case e1000_82576: mac->rar_entry_count = E1000_RAR_ENTRIES_82576; - if (mac->type == e1000_82580) + break; + case e1000_82580: mac->rar_entry_count = E1000_RAR_ENTRIES_82580; - if (mac->type == e1000_i350) + break; + case e1000_i350: + case e1000_i210: + case e1000_i211: mac->rar_entry_count = E1000_RAR_ENTRIES_I350; + break; + default: + mac->rar_entry_count = E1000_RAR_ENTRIES_82575; + break; + } /* reset */ if (mac->type >= e1000_82580) mac->ops.reset_hw = igb_reset_hw_82580; else mac->ops.reset_hw = igb_reset_hw_82575; + + if (mac->type >= e1000_i210) { + mac->ops.acquire_swfw_sync = igb_acquire_swfw_sync_i210; + mac->ops.release_swfw_sync = igb_release_swfw_sync_i210; + } else { + mac->ops.acquire_swfw_sync = igb_acquire_swfw_sync_82575; + mac->ops.release_swfw_sync = igb_release_swfw_sync_82575; + } + /* Set if part includes ASF firmware */ mac->asf_firmware_present = true; /* Set if manageability features are enabled. */ mac->arc_subsystem_valid = (rd32(E1000_FWSM) & E1000_FWSM_MODE_MASK) ? true : false; - /* enable EEE on i350 parts */ - if (mac->type == e1000_i350) + /* enable EEE on i350 parts and later parts */ + if (mac->type >= e1000_i350) dev_spec->eee_disable = false; else dev_spec->eee_disable = true; @@ -213,26 +247,6 @@ /* NVM initialization */ eecd = rd32(E1000_EECD); - - 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; - } - - nvm->type = e1000_nvm_eeprom_spi; - size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> E1000_EECD_SIZE_EX_SHIFT); @@ -242,6 +256,33 @@ */ size += NVM_WORD_SIZE_BASE_SHIFT; + nvm->word_size = 1 << size; + if (hw->mac.type < e1000_i210) { + 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; + } + if (nvm->word_size == (1 << 15)) + nvm->page_size = 128; + + nvm->type = e1000_nvm_eeprom_spi; + } else + nvm->type = e1000_nvm_flash_hw; + /* * Check for invalid size */ @@ -249,32 +290,60 @@ pr_notice("The NVM size is not valid, defaulting to 32K\n"); size = 15; } - nvm->word_size = 1 << size; - if (nvm->word_size == (1 << 15)) - nvm->page_size = 128; /* NVM Function Pointers */ - nvm->ops.acquire = igb_acquire_nvm_82575; - if (nvm->word_size < (1 << 15)) - nvm->ops.read = igb_read_nvm_eerd; - else - nvm->ops.read = igb_read_nvm_spi; - - nvm->ops.release = igb_release_nvm_82575; switch (hw->mac.type) { case e1000_82580: nvm->ops.validate = igb_validate_nvm_checksum_82580; nvm->ops.update = igb_update_nvm_checksum_82580; + nvm->ops.acquire = igb_acquire_nvm_82575; + nvm->ops.release = igb_release_nvm_82575; + if (nvm->word_size < (1 << 15)) + nvm->ops.read = igb_read_nvm_eerd; + else + nvm->ops.read = igb_read_nvm_spi; + nvm->ops.write = igb_write_nvm_spi; break; case e1000_i350: nvm->ops.validate = igb_validate_nvm_checksum_i350; nvm->ops.update = igb_update_nvm_checksum_i350; + nvm->ops.acquire = igb_acquire_nvm_82575; + nvm->ops.release = igb_release_nvm_82575; + if (nvm->word_size < (1 << 15)) + nvm->ops.read = igb_read_nvm_eerd; + else + nvm->ops.read = igb_read_nvm_spi; + nvm->ops.write = igb_write_nvm_spi; + break; + case e1000_i210: + nvm->ops.validate = igb_validate_nvm_checksum_i210; + nvm->ops.update = igb_update_nvm_checksum_i210; + nvm->ops.acquire = igb_acquire_nvm_i210; + nvm->ops.release = igb_release_nvm_i210; + nvm->ops.read = igb_read_nvm_srrd_i210; + nvm->ops.valid_led_default = igb_valid_led_default_i210; + break; + case e1000_i211: + nvm->ops.acquire = igb_acquire_nvm_i210; + nvm->ops.release = igb_release_nvm_i210; + nvm->ops.read = igb_read_nvm_i211; + nvm->ops.valid_led_default = igb_valid_led_default_i210; + nvm->ops.validate = NULL; + nvm->ops.update = NULL; + nvm->ops.write = NULL; break; default: nvm->ops.validate = igb_validate_nvm_checksum; nvm->ops.update = igb_update_nvm_checksum; + nvm->ops.acquire = igb_acquire_nvm_82575; + nvm->ops.release = igb_release_nvm_82575; + if (nvm->word_size < (1 << 15)) + nvm->ops.read = igb_read_nvm_eerd; + else + nvm->ops.read = igb_read_nvm_spi; + nvm->ops.write = igb_write_nvm_spi; + break; } - nvm->ops.write = igb_write_nvm_spi; /* if part supports SR-IOV then initialize mailbox parameters */ switch (mac->type) { @@ -312,9 +381,13 @@ if (igb_sgmii_active_82575(hw) && !igb_sgmii_uses_mdio_82575(hw)) { phy->ops.read_reg = igb_read_phy_reg_sgmii_82575; phy->ops.write_reg = igb_write_phy_reg_sgmii_82575; - } else if (hw->mac.type >= e1000_82580) { + } else if ((hw->mac.type == e1000_82580) + || (hw->mac.type == e1000_i350)) { phy->ops.read_reg = igb_read_phy_reg_82580; phy->ops.write_reg = igb_write_phy_reg_82580; + } else if (hw->phy.type >= e1000_phy_i210) { + phy->ops.read_reg = igb_read_phy_reg_gs40g; + phy->ops.write_reg = igb_write_phy_reg_gs40g; } else { phy->ops.read_reg = igb_read_phy_reg_igp; phy->ops.write_reg = igb_write_phy_reg_igp; @@ -343,6 +416,14 @@ else phy->ops.get_cable_length = igb_get_cable_length_m88; + if (phy->id == I210_I_PHY_ID) { + phy->ops.get_cable_length = + igb_get_cable_length_m88_gen2; + phy->ops.set_d0_lplu_state = + igb_set_d0_lplu_state_82580; + phy->ops.set_d3_lplu_state = + igb_set_d3_lplu_state_82580; + } phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88; break; case IGP03E1000_E_PHY_ID: @@ -359,6 +440,17 @@ phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_82580; phy->ops.get_cable_length = igb_get_cable_length_82580; phy->ops.get_phy_info = igb_get_phy_info_82580; + phy->ops.set_d0_lplu_state = igb_set_d0_lplu_state_82580; + phy->ops.set_d3_lplu_state = igb_set_d3_lplu_state_82580; + break; + case I210_I_PHY_ID: + phy->type = e1000_phy_i210; + phy->ops.get_phy_info = igb_get_phy_info_m88; + phy->ops.check_polarity = igb_check_polarity_m88; + phy->ops.get_cable_length = igb_get_cable_length_m88_gen2; + phy->ops.set_d0_lplu_state = igb_set_d0_lplu_state_82580; + phy->ops.set_d3_lplu_state = igb_set_d3_lplu_state_82580; + phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88; break; default: return -E1000_ERR_PHY; @@ -385,7 +477,7 @@ else if (hw->bus.func == E1000_FUNC_3) mask = E1000_SWFW_PHY3_SM; - return igb_acquire_swfw_sync_82575(hw, mask); + return hw->mac.ops.acquire_swfw_sync(hw, mask); } /** @@ -406,7 +498,7 @@ else if (hw->bus.func == E1000_FUNC_3) mask = E1000_SWFW_PHY3_SM; - igb_release_swfw_sync_82575(hw, mask); + hw->mac.ops.release_swfw_sync(hw, mask); } /** @@ -510,6 +602,8 @@ break; case e1000_82580: case e1000_i350: + case e1000_i210: + case e1000_i211: mdic = rd32(E1000_MDICNFG); mdic &= E1000_MDICNFG_PHY_MASK; phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT; @@ -674,6 +768,96 @@ } /** + * igb_set_d0_lplu_state_82580 - 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 igb_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val = 0; + u16 data; + + data = rd32(E1000_82580_PHY_POWER_MGMT); + + if (active) { + data |= E1000_82580_PM_D0_LPLU; + + /* When LPLU is enabled, we should disable SmartSpeed */ + data &= ~E1000_82580_PM_SPD; + } else { + data &= ~E1000_82580_PM_D0_LPLU; + + /* + * 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) + data |= E1000_82580_PM_SPD; + else if (phy->smart_speed == e1000_smart_speed_off) + data &= ~E1000_82580_PM_SPD; } + + wr32(E1000_82580_PHY_POWER_MGMT, data); + return ret_val; +} + +/** + * igb_set_d3_lplu_state_82580 - 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 igb_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val = 0; + u16 data; + + data = rd32(E1000_82580_PHY_POWER_MGMT); + + if (!active) { + data &= ~E1000_82580_PM_D3_LPLU; + /* + * 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) + data |= E1000_82580_PM_SPD; + else if (phy->smart_speed == e1000_smart_speed_off) + data &= ~E1000_82580_PM_SPD; + } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) || + (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || + (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { + data |= E1000_82580_PM_D3_LPLU; + /* When LPLU is enabled, we should disable SmartSpeed */ + data &= ~E1000_82580_PM_SPD; + } + + wr32(E1000_82580_PHY_POWER_MGMT, data); + return ret_val; +} + +/** * igb_acquire_nvm_82575 - Request for access to EEPROM * @hw: pointer to the HW structure * @@ -686,14 +870,14 @@ { s32 ret_val; - ret_val = igb_acquire_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); + ret_val = hw->mac.ops.acquire_swfw_sync(hw, E1000_SWFW_EEP_SM); if (ret_val) goto out; ret_val = igb_acquire_nvm(hw); if (ret_val) - igb_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); + hw->mac.ops.release_swfw_sync(hw, E1000_SWFW_EEP_SM); out: return ret_val; @@ -709,7 +893,7 @@ static void igb_release_nvm_82575(struct e1000_hw *hw) { igb_release_nvm(hw); - igb_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); + hw->mac.ops.release_swfw_sync(hw, E1000_SWFW_EEP_SM); } /** @@ -1080,7 +1264,6 @@ * is no link. */ igb_clear_hw_cntrs_82575(hw); - return ret_val; } @@ -1117,6 +1300,7 @@ } } switch (hw->phy.type) { + case e1000_phy_i210: case e1000_phy_m88: if (hw->phy.id == I347AT4_E_PHY_ID || hw->phy.id == M88E1112_E_PHY_ID) @@ -1757,7 +1941,7 @@ /* Determine whether or not a global dev reset is requested */ if (global_device_reset && - igb_acquire_swfw_sync_82575(hw, swmbsw_mask)) + hw->mac.ops.acquire_swfw_sync(hw, swmbsw_mask)) global_device_reset = false; if (global_device_reset && @@ -1803,7 +1987,7 @@ /* Release semaphore */ if (global_device_reset) - igb_release_swfw_sync_82575(hw, swmbsw_mask); + hw->mac.ops.release_swfw_sync(hw, swmbsw_mask); return ret_val; }
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.h b/drivers/net/ethernet/intel/igb/e1000_82575.h index b927d79..e85c453 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.h +++ b/drivers/net/ethernet/intel/igb/e1000_82575.h
@@ -55,10 +55,11 @@ #define E1000_SRRCTL_DROP_EN 0x80000000 #define E1000_SRRCTL_TIMESTAMP 0x40000000 + #define E1000_MRQC_ENABLE_RSS_4Q 0x00000002 #define E1000_MRQC_ENABLE_VMDQ 0x00000003 -#define E1000_MRQC_ENABLE_VMDQ_RSS_2Q 0x00000005 #define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000 +#define E1000_MRQC_ENABLE_VMDQ_RSS_2Q 0x00000005 #define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000 #define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h index 89eb1f8..ec7e4fe 100644 --- a/drivers/net/ethernet/intel/igb/e1000_defines.h +++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -301,6 +301,8 @@ * transactions */ #define E1000_DMACR_DMAC_LX_SHIFT 28 #define E1000_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */ +/* DMA Coalescing BMC-to-OS Watchdog Enable */ +#define E1000_DMACR_DC_BMC2OSW_EN 0x00008000 #define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF /* DMA Coalescing Transmit * Threshold */ @@ -458,6 +460,7 @@ #define E1000_ERR_INVALID_ARGUMENT 16 #define E1000_ERR_NO_SPACE 17 #define E1000_ERR_NVM_PBA_SECTION 18 +#define E1000_ERR_INVM_VALUE_NOT_FOUND 19 /* Loop limit on how long we wait for auto-negotiation to complete */ #define COPPER_LINK_UP_LIMIT 10 @@ -595,6 +598,25 @@ #define E1000_EECD_AUTO_RD 0x00000200 /* NVM Auto Read done */ #define E1000_EECD_SIZE_EX_MASK 0x00007800 /* NVM Size */ #define E1000_EECD_SIZE_EX_SHIFT 11 +#define E1000_EECD_FLUPD_I210 0x00800000 /* Update FLASH */ +#define E1000_EECD_FLUDONE_I210 0x04000000 /* Update FLASH done*/ +#define E1000_FLUDONE_ATTEMPTS 20000 +#define E1000_EERD_EEWR_MAX_COUNT 512 /* buffered EEPROM words rw */ +#define E1000_I210_FIFO_SEL_RX 0x00 +#define E1000_I210_FIFO_SEL_TX_QAV(_i) (0x02 + (_i)) +#define E1000_I210_FIFO_SEL_TX_LEGACY E1000_I210_FIFO_SEL_TX_QAV(0) +#define E1000_I210_FIFO_SEL_BMC2OS_TX 0x06 +#define E1000_I210_FIFO_SEL_BMC2OS_RX 0x01 +#define E1000_EECD_FLUPD_I210 0x00800000 /* Update FLASH */ +#define E1000_EECD_FLUDONE_I210 0x04000000 /* Update FLASH done*/ +#define E1000_FLUDONE_ATTEMPTS 20000 +#define E1000_EERD_EEWR_MAX_COUNT 512 /* buffered EEPROM words rw */ +#define E1000_I210_FIFO_SEL_RX 0x00 +#define E1000_I210_FIFO_SEL_TX_QAV(_i) (0x02 + (_i)) +#define E1000_I210_FIFO_SEL_TX_LEGACY E1000_I210_FIFO_SEL_TX_QAV(0) +#define E1000_I210_FIFO_SEL_BMC2OS_TX 0x06 +#define E1000_I210_FIFO_SEL_BMC2OS_RX 0x01 + /* Offset to data in NVM read/write registers */ #define E1000_NVM_RW_REG_DATA 16 @@ -613,6 +635,16 @@ #define NVM_CHECKSUM_REG 0x003F #define NVM_COMPATIBILITY_REG_3 0x0003 #define NVM_COMPATIBILITY_BIT_MASK 0x8000 +#define NVM_MAC_ADDR 0x0000 +#define NVM_SUB_DEV_ID 0x000B +#define NVM_SUB_VEN_ID 0x000C +#define NVM_DEV_ID 0x000D +#define NVM_VEN_ID 0x000E +#define NVM_INIT_CTRL_2 0x000F +#define NVM_INIT_CTRL_4 0x0013 +#define NVM_LED_1_CFG 0x001C +#define NVM_LED_0_2_CFG 0x001F + #define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */ #define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */ @@ -639,6 +671,7 @@ #define NVM_PBA_OFFSET_0 8 #define NVM_PBA_OFFSET_1 9 +#define NVM_RESERVED_WORD 0xFFFF #define NVM_PBA_PTR_GUARD 0xFAFA #define NVM_WORD_SIZE_BASE_SHIFT 6 @@ -696,6 +729,7 @@ #define I82580_I_PHY_ID 0x015403A0 #define I350_I_PHY_ID 0x015403B0 #define M88_VENDOR 0x0141 +#define I210_I_PHY_ID 0x01410C00 /* M88E1000 Specific Registers */ #define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ @@ -815,6 +849,7 @@ #define E1000_IPCNFG_EEE_100M_AN 0x00000004 /* EEE Enable 100M AN */ #define E1000_EEER_TX_LPI_EN 0x00010000 /* EEE Tx LPI Enable */ #define E1000_EEER_RX_LPI_EN 0x00020000 /* EEE Rx LPI Enable */ +#define E1000_EEER_FRC_AN 0x10000000 /* Enable EEE in loopback */ #define E1000_EEER_LPI_FC 0x00040000 /* EEE Enable on FC */ /* SerDes Control */
diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h index f67cbd3..c2a51dc 100644 --- a/drivers/net/ethernet/intel/igb/e1000_hw.h +++ b/drivers/net/ethernet/intel/igb/e1000_hw.h
@@ -63,6 +63,13 @@ #define E1000_DEV_ID_I350_FIBER 0x1522 #define E1000_DEV_ID_I350_SERDES 0x1523 #define E1000_DEV_ID_I350_SGMII 0x1524 +#define E1000_DEV_ID_I210_COPPER 0x1533 +#define E1000_DEV_ID_I210_COPPER_OEM1 0x1534 +#define E1000_DEV_ID_I210_COPPER_IT 0x1535 +#define E1000_DEV_ID_I210_FIBER 0x1536 +#define E1000_DEV_ID_I210_SERDES 0x1537 +#define E1000_DEV_ID_I210_SGMII 0x1538 +#define E1000_DEV_ID_I211_COPPER 0x1539 #define E1000_REVISION_2 2 #define E1000_REVISION_4 4 @@ -83,6 +90,8 @@ e1000_82576, e1000_82580, e1000_i350, + e1000_i210, + e1000_i211, e1000_num_macs /* List is 1-based, so subtract 1 for true count. */ }; @@ -117,6 +126,7 @@ e1000_phy_igp_3, e1000_phy_ife, e1000_phy_82580, + e1000_phy_i210, }; enum e1000_bus_type { @@ -313,6 +323,9 @@ void (*rar_set)(struct e1000_hw *, u8 *, u32); s32 (*read_mac_addr)(struct e1000_hw *); s32 (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *); + s32 (*acquire_swfw_sync)(struct e1000_hw *, u16); + void (*release_swfw_sync)(struct e1000_hw *, u16); + }; struct e1000_phy_operations { @@ -338,6 +351,7 @@ s32 (*write)(struct e1000_hw *, u16, u16, u16 *); s32 (*update)(struct e1000_hw *); s32 (*validate)(struct e1000_hw *); + s32 (*valid_led_default)(struct e1000_hw *, u16 *); }; struct e1000_info {
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c new file mode 100644 index 0000000..77a5f93 --- /dev/null +++ b/drivers/net/ethernet/intel/igb/e1000_i210.c
@@ -0,0 +1,603 @@ +/******************************************************************************* + + Intel(R) Gigabit Ethernet Linux driver + Copyright(c) 2007-2012 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: + e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +******************************************************************************/ + +/* e1000_i210 + * e1000_i211 + */ + +#include <linux/types.h> +#include <linux/if_ether.h> + +#include "e1000_hw.h" +#include "e1000_i210.h" + +static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw); +static void igb_put_hw_semaphore_i210(struct e1000_hw *hw); +static s32 igb_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data); +static s32 igb_pool_flash_update_done_i210(struct e1000_hw *hw); + +/** + * igb_acquire_nvm_i210 - Request for access to EEPROM + * @hw: pointer to the HW structure + * + * Acquire the necessary semaphores for exclusive access to the EEPROM. + * 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 igb_acquire_nvm_i210(struct e1000_hw *hw) +{ + return igb_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM); +} + +/** + * igb_release_nvm_i210 - Release exclusive access to EEPROM + * @hw: pointer to the HW structure + * + * Stop any current commands to the EEPROM and clear the EEPROM request bit, + * then release the semaphores acquired. + **/ +void igb_release_nvm_i210(struct e1000_hw *hw) +{ + igb_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM); +} + +/** + * igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore + * @hw: pointer to the HW structure + * @mask: specifies which semaphore to acquire + * + * Acquire the SW/FW semaphore to access the PHY or NVM. The mask + * will also specify which port we're acquiring the lock for. + **/ +s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask) +{ + u32 swfw_sync; + u32 swmask = mask; + u32 fwmask = mask << 16; + s32 ret_val = E1000_SUCCESS; + s32 i = 0, timeout = 200; /* FIXME: find real value to use here */ + + while (i < timeout) { + if (igb_get_hw_semaphore_i210(hw)) { + ret_val = -E1000_ERR_SWFW_SYNC; + goto out; + } + + swfw_sync = rd32(E1000_SW_FW_SYNC); + if (!(swfw_sync & fwmask)) + break; + + /* + * Firmware currently using resource (fwmask) + */ + igb_put_hw_semaphore_i210(hw); + mdelay(5); + i++; + } + + if (i == timeout) { + hw_dbg("Driver can't access resource, SW_FW_SYNC timeout.\n"); + ret_val = -E1000_ERR_SWFW_SYNC; + goto out; + } + + swfw_sync |= swmask; + wr32(E1000_SW_FW_SYNC, swfw_sync); + + igb_put_hw_semaphore_i210(hw); +out: + return ret_val; +} + +/** + * igb_release_swfw_sync_i210 - Release SW/FW semaphore + * @hw: pointer to the HW structure + * @mask: specifies which semaphore to acquire + * + * Release the SW/FW semaphore used to access the PHY or NVM. The mask + * will also specify which port we're releasing the lock for. + **/ +void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask) +{ + u32 swfw_sync; + + while (igb_get_hw_semaphore_i210(hw) != E1000_SUCCESS) + ; /* Empty */ + + swfw_sync = rd32(E1000_SW_FW_SYNC); + swfw_sync &= ~mask; + wr32(E1000_SW_FW_SYNC, swfw_sync); + + igb_put_hw_semaphore_i210(hw); +} + +/** + * igb_get_hw_semaphore_i210 - Acquire hardware semaphore + * @hw: pointer to the HW structure + * + * Acquire the HW semaphore to access the PHY or NVM + **/ +static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw) +{ + u32 swsm; + s32 ret_val = E1000_SUCCESS; + s32 timeout = hw->nvm.word_size + 1; + s32 i = 0; + + /* Get the FW semaphore. */ + for (i = 0; i < timeout; i++) { + swsm = rd32(E1000_SWSM); + wr32(E1000_SWSM, swsm | E1000_SWSM_SWESMBI); + + /* Semaphore acquired if bit latched */ + if (rd32(E1000_SWSM) & E1000_SWSM_SWESMBI) + break; + + udelay(50); + } + + if (i == timeout) { + /* Release semaphores */ + igb_put_hw_semaphore(hw); + hw_dbg("Driver can't access the NVM\n"); + ret_val = -E1000_ERR_NVM; + goto out; + } + +out: + return ret_val; +} + +/** + * igb_put_hw_semaphore_i210 - Release hardware semaphore + * @hw: pointer to the HW structure + * + * Release hardware semaphore used to access the PHY or NVM + **/ +static void igb_put_hw_semaphore_i210(struct e1000_hw *hw) +{ + u32 swsm; + + swsm = rd32(E1000_SWSM); + + swsm &= ~E1000_SWSM_SWESMBI; + + wr32(E1000_SWSM, swsm); +} + +/** + * igb_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register + * @hw: pointer to the HW structure + * @offset: offset of word in the Shadow Ram to read + * @words: number of words to read + * @data: word read from the Shadow Ram + * + * Reads a 16 bit word from the Shadow Ram using the EERD register. + * Uses necessary synchronization semaphores. + **/ +s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data) +{ + s32 status = E1000_SUCCESS; + u16 i, count; + + /* We cannot hold synchronization semaphores for too long, + * because of forceful takeover procedure. However it is more efficient + * to read in bursts than synchronizing access for each word. */ + for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) { + count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ? + E1000_EERD_EEWR_MAX_COUNT : (words - i); + if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { + status = igb_read_nvm_eerd(hw, offset, count, + data + i); + hw->nvm.ops.release(hw); + } else { + status = E1000_ERR_SWFW_SYNC; + } + + if (status != E1000_SUCCESS) + break; + } + + return status; +} + +/** + * igb_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR + * @hw: pointer to the HW structure + * @offset: offset within the Shadow RAM to be written to + * @words: number of words to write + * @data: 16 bit word(s) to be written to the Shadow RAM + * + * Writes data to Shadow RAM at offset using EEWR register. + * + * If e1000_update_nvm_checksum is not called after this function , the + * data will not be committed to FLASH and also Shadow RAM will most likely + * contain an invalid checksum. + * + * If error code is returned, data and Shadow RAM may be inconsistent - buffer + * partially written. + **/ +s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data) +{ + s32 status = E1000_SUCCESS; + u16 i, count; + + /* We cannot hold synchronization semaphores for too long, + * because of forceful takeover procedure. However it is more efficient + * to write in bursts than synchronizing access for each word. */ + for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) { + count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ? + E1000_EERD_EEWR_MAX_COUNT : (words - i); + if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { + status = igb_write_nvm_srwr(hw, offset, count, + data + i); + hw->nvm.ops.release(hw); + } else { + status = E1000_ERR_SWFW_SYNC; + } + + if (status != E1000_SUCCESS) + break; + } + + return status; +} + +/** + * igb_write_nvm_srwr - Write to Shadow Ram using EEWR + * @hw: pointer to the HW structure + * @offset: offset within the Shadow Ram to be written to + * @words: number of words to write + * @data: 16 bit word(s) to be written to the Shadow Ram + * + * Writes data to Shadow Ram at offset using EEWR register. + * + * If igb_update_nvm_checksum is not called after this function , the + * Shadow Ram will most likely contain an invalid checksum. + **/ +static s32 igb_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data) +{ + struct e1000_nvm_info *nvm = &hw->nvm; + u32 i, k, eewr = 0; + u32 attempts = 100000; + s32 ret_val = E1000_SUCCESS; + + /* + * 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("nvm parameter(s) out of bounds\n"); + ret_val = -E1000_ERR_NVM; + goto out; + } + + for (i = 0; i < words; i++) { + eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) | + (data[i] << E1000_NVM_RW_REG_DATA) | + E1000_NVM_RW_REG_START; + + wr32(E1000_SRWR, eewr); + + for (k = 0; k < attempts; k++) { + if (E1000_NVM_RW_REG_DONE & + rd32(E1000_SRWR)) { + ret_val = E1000_SUCCESS; + break; + } + udelay(5); + } + + if (ret_val != E1000_SUCCESS) { + hw_dbg("Shadow RAM write EEWR timed out\n"); + break; + } + } + +out: + return ret_val; +} + +/** + * igb_read_nvm_i211 - Read NVM wrapper function for I211 + * @hw: pointer to the HW structure + * @address: the word address (aka eeprom offset) to read + * @data: pointer to the data read + * + * Wrapper function to return data formerly found in the NVM. + **/ +s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data) +{ + s32 ret_val = E1000_SUCCESS; + + /* Only the MAC addr is required to be present in the iNVM */ + switch (offset) { + case NVM_MAC_ADDR: + ret_val = igb_read_invm_i211(hw, offset, &data[0]); + ret_val |= igb_read_invm_i211(hw, offset+1, &data[1]); + ret_val |= igb_read_invm_i211(hw, offset+2, &data[2]); + if (ret_val != E1000_SUCCESS) + hw_dbg("MAC Addr not found in iNVM\n"); + break; + case NVM_ID_LED_SETTINGS: + case NVM_INIT_CTRL_2: + case NVM_INIT_CTRL_4: + case NVM_LED_1_CFG: + case NVM_LED_0_2_CFG: + igb_read_invm_i211(hw, offset, data); + break; + case NVM_COMPAT: + *data = ID_LED_DEFAULT_I210; + break; + case NVM_SUB_DEV_ID: + *data = hw->subsystem_device_id; + break; + case NVM_SUB_VEN_ID: + *data = hw->subsystem_vendor_id; + break; + case NVM_DEV_ID: + *data = hw->device_id; + break; + case NVM_VEN_ID: + *data = hw->vendor_id; + break; + default: + hw_dbg("NVM word 0x%02x is not mapped.\n", offset); + *data = NVM_RESERVED_WORD; + break; + } + return ret_val; +} + +/** + * igb_read_invm_i211 - Reads OTP + * @hw: pointer to the HW structure + * @address: the word address (aka eeprom offset) to read + * @data: pointer to the data read + * + * Reads 16-bit words from the OTP. Return error when the word is not + * stored in OTP. + **/ +s32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data) +{ + s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND; + u32 invm_dword; + u16 i; + u8 record_type, word_address; + + for (i = 0; i < E1000_INVM_SIZE; i++) { + invm_dword = rd32(E1000_INVM_DATA_REG(i)); + /* Get record type */ + record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword); + if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE) + break; + if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE) + i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS; + if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE) + i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS; + if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) { + word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword); + if (word_address == (u8)address) { + *data = INVM_DWORD_TO_WORD_DATA(invm_dword); + hw_dbg("Read INVM Word 0x%02x = %x", + address, *data); + status = E1000_SUCCESS; + break; + } + } + } + if (status != E1000_SUCCESS) + hw_dbg("Requested word 0x%02x not found in OTP\n", address); + return status; +} + +/** + * igb_validate_nvm_checksum_i210 - 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 igb_validate_nvm_checksum_i210(struct e1000_hw *hw) +{ + s32 status = E1000_SUCCESS; + s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *); + + if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { + + /* + * Replace the read function with semaphore grabbing with + * the one that skips this for a while. + * We have semaphore taken already here. + */ + read_op_ptr = hw->nvm.ops.read; + hw->nvm.ops.read = igb_read_nvm_eerd; + + status = igb_validate_nvm_checksum(hw); + + /* Revert original read operation. */ + hw->nvm.ops.read = read_op_ptr; + + hw->nvm.ops.release(hw); + } else { + status = E1000_ERR_SWFW_SYNC; + } + + return status; +} + + +/** + * igb_update_nvm_checksum_i210 - 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. Next commit EEPROM data onto the Flash. + **/ +s32 igb_update_nvm_checksum_i210(struct e1000_hw *hw) +{ + s32 ret_val = E1000_SUCCESS; + u16 checksum = 0; + u16 i, nvm_data; + + /* + * Read the first word from the EEPROM. If this times out or fails, do + * not continue or we could be in for a very long wait while every + * EEPROM read fails + */ + ret_val = igb_read_nvm_eerd(hw, 0, 1, &nvm_data); + if (ret_val != E1000_SUCCESS) { + hw_dbg("EEPROM read failed\n"); + goto out; + } + + if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { + /* + * Do not use hw->nvm.ops.write, hw->nvm.ops.read + * because we do not want to take the synchronization + * semaphores twice here. + */ + + for (i = 0; i < NVM_CHECKSUM_REG; i++) { + ret_val = igb_read_nvm_eerd(hw, i, 1, &nvm_data); + if (ret_val) { + hw->nvm.ops.release(hw); + hw_dbg("NVM Read Error while updating checksum.\n"); + goto out; + } + checksum += nvm_data; + } + checksum = (u16) NVM_SUM - checksum; + ret_val = igb_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1, + &checksum); + if (ret_val != E1000_SUCCESS) { + hw->nvm.ops.release(hw); + hw_dbg("NVM Write Error while updating checksum.\n"); + goto out; + } + + hw->nvm.ops.release(hw); + + ret_val = igb_update_flash_i210(hw); + } else { + ret_val = -E1000_ERR_SWFW_SYNC; + } +out: + return ret_val; +} + +/** + * igb_update_flash_i210 - Commit EEPROM to the flash + * @hw: pointer to the HW structure + * + **/ +s32 igb_update_flash_i210(struct e1000_hw *hw) +{ + s32 ret_val = E1000_SUCCESS; + u32 flup; + + ret_val = igb_pool_flash_update_done_i210(hw); + if (ret_val == -E1000_ERR_NVM) { + hw_dbg("Flash update time out\n"); + goto out; + } + + flup = rd32(E1000_EECD) | E1000_EECD_FLUPD_I210; + wr32(E1000_EECD, flup); + + ret_val = igb_pool_flash_update_done_i210(hw); + if (ret_val == E1000_SUCCESS) + hw_dbg("Flash update complete\n"); + else + hw_dbg("Flash update time out\n"); + +out: + return ret_val; +} + +/** + * igb_pool_flash_update_done_i210 - Pool FLUDONE status. + * @hw: pointer to the HW structure + * + **/ +s32 igb_pool_flash_update_done_i210(struct e1000_hw *hw) +{ + s32 ret_val = -E1000_ERR_NVM; + u32 i, reg; + + for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) { + reg = rd32(E1000_EECD); + if (reg & E1000_EECD_FLUDONE_I210) { + ret_val = E1000_SUCCESS; + break; + } + udelay(5); + } + + return ret_val; +} + +/** + * igb_valid_led_default_i210 - 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 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data) +{ + s32 ret_val; + + ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data); + if (ret_val) { + hw_dbg("NVM Read Error\n"); + goto out; + } + + if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) { + switch (hw->phy.media_type) { + case e1000_media_type_internal_serdes: + *data = ID_LED_DEFAULT_I210_SERDES; + break; + case e1000_media_type_copper: + default: + *data = ID_LED_DEFAULT_I210; + break; + } + } +out: + return ret_val; +}
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.h b/drivers/net/ethernet/intel/igb/e1000_i210.h new file mode 100644 index 0000000..5dc2bd3 --- /dev/null +++ b/drivers/net/ethernet/intel/igb/e1000_i210.h
@@ -0,0 +1,76 @@ +/******************************************************************************* + + Intel(R) Gigabit Ethernet Linux driver + Copyright(c) 2007-2012 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: + e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ + +#ifndef _E1000_I210_H_ +#define _E1000_I210_H_ + +extern s32 igb_update_flash_i210(struct e1000_hw *hw); +extern s32 igb_update_nvm_checksum_i210(struct e1000_hw *hw); +extern s32 igb_validate_nvm_checksum_i210(struct e1000_hw *hw); +extern s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, + u16 words, u16 *data); +extern s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, + u16 words, u16 *data); +extern s32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data); +extern s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask); +extern void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask); +extern s32 igb_acquire_nvm_i210(struct e1000_hw *hw); +extern void igb_release_nvm_i210(struct e1000_hw *hw); +extern s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data); +extern s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data); + +#define E1000_STM_OPCODE 0xDB00 +#define E1000_EEPROM_FLASH_SIZE_WORD 0x11 + +#define INVM_DWORD_TO_RECORD_TYPE(invm_dword) \ + (u8)((invm_dword) & 0x7) +#define INVM_DWORD_TO_WORD_ADDRESS(invm_dword) \ + (u8)(((invm_dword) & 0x0000FE00) >> 9) +#define INVM_DWORD_TO_WORD_DATA(invm_dword) \ + (u16)(((invm_dword) & 0xFFFF0000) >> 16) + +enum E1000_INVM_STRUCTURE_TYPE { + E1000_INVM_UNINITIALIZED_STRUCTURE = 0x00, + E1000_INVM_WORD_AUTOLOAD_STRUCTURE = 0x01, + E1000_INVM_CSR_AUTOLOAD_STRUCTURE = 0x02, + E1000_INVM_PHY_REGISTER_AUTOLOAD_STRUCTURE = 0x03, + E1000_INVM_RSA_KEY_SHA256_STRUCTURE = 0x04, + E1000_INVM_INVALIDATED_STRUCTURE = 0x0F, +}; + +#define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8 +#define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1 + +#define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \ + (ID_LED_OFF1_OFF2 << 4) | \ + (ID_LED_DEF1_DEF2)) +#define ID_LED_DEFAULT_I210_SERDES ((ID_LED_DEF1_DEF2 << 8) | \ + (ID_LED_DEF1_DEF2 << 4) | \ + (ID_LED_DEF1_DEF2)) + +#endif
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.c b/drivers/net/ethernet/intel/igb/e1000_mac.c index f57338a..819c145 100644 --- a/drivers/net/ethernet/intel/igb/e1000_mac.c +++ b/drivers/net/ethernet/intel/igb/e1000_mac.c
@@ -658,6 +658,7 @@ ret_val = igb_set_fc_watermarks(hw); out: + return ret_val; }
diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.c b/drivers/net/ethernet/intel/igb/e1000_nvm.c index fa2c6ba..aa5fcdf 100644 --- a/drivers/net/ethernet/intel/igb/e1000_nvm.c +++ b/drivers/net/ethernet/intel/igb/e1000_nvm.c
@@ -710,4 +710,3 @@ out: return ret_val; } -
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c index 789de5b..7be98b6 100644 --- a/drivers/net/ethernet/intel/igb/e1000_phy.c +++ b/drivers/net/ethernet/intel/igb/e1000_phy.c
@@ -35,6 +35,7 @@ static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl); static s32 igb_wait_autoneg(struct e1000_hw *hw); +static s32 igb_set_master_slave_mode(struct e1000_hw *hw); /* Cable length tables */ static const u16 e1000_m88_cable_length_table[] = @@ -570,6 +571,11 @@ hw_dbg("Error committing the PHY changes\n"); goto out; } + if (phy->type == e1000_phy_i210) { + ret_val = igb_set_master_slave_mode(hw); + if (ret_val) + return ret_val; + } out: return ret_val; @@ -1213,12 +1219,22 @@ goto out; if (!link) { - if (hw->phy.type != e1000_phy_m88 || - hw->phy.id == I347AT4_E_PHY_ID || - hw->phy.id == M88E1112_E_PHY_ID) { - hw_dbg("Link taking longer than expected.\n"); - } else { + bool reset_dsp = true; + switch (hw->phy.id) { + case I347AT4_E_PHY_ID: + case M88E1112_E_PHY_ID: + case I210_I_PHY_ID: + reset_dsp = false; + break; + default: + if (hw->phy.type != e1000_phy_m88) + reset_dsp = false; + break; + } + if (!reset_dsp) + hw_dbg("Link taking longer than expected.\n"); + else { /* * We didn't get link. * Reset the DSP and cross our fingers. @@ -1243,7 +1259,8 @@ if (hw->phy.type != e1000_phy_m88 || hw->phy.id == I347AT4_E_PHY_ID || - hw->phy.id == M88E1112_E_PHY_ID) + hw->phy.id == M88E1112_E_PHY_ID || + hw->phy.id == I210_I_PHY_ID) goto out; ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); @@ -1441,6 +1458,7 @@ u16 phy_data, offset, mask; switch (phy->type) { + case e1000_phy_i210: case e1000_phy_m88: case e1000_phy_gg82563: offset = M88E1000_PHY_SPEC_STATUS; @@ -1476,7 +1494,7 @@ * * Polarity is determined based on the PHY specific status register. **/ -static s32 igb_check_polarity_m88(struct e1000_hw *hw) +s32 igb_check_polarity_m88(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -1665,6 +1683,7 @@ u16 phy_data, phy_data2, index, default_page, is_cm; switch (hw->phy.id) { + case I210_I_PHY_ID: case I347AT4_E_PHY_ID: /* Remember the original page select and set it to 7 */ ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT, @@ -2129,10 +2148,16 @@ void igb_power_up_phy_copper(struct e1000_hw *hw) { u16 mii_reg = 0; + u16 power_reg = 0; /* The PHY will retain its settings across a power down/up cycle */ hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg); mii_reg &= ~MII_CR_POWER_DOWN; + if (hw->phy.type == e1000_phy_i210) { + hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg); + power_reg &= ~GS40G_CS_POWER_DOWN; + hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg); + } hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg); } @@ -2146,10 +2171,18 @@ void igb_power_down_phy_copper(struct e1000_hw *hw) { u16 mii_reg = 0; + u16 power_reg = 0; /* The PHY will retain its settings across a power down/up cycle */ hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg); mii_reg |= MII_CR_POWER_DOWN; + + /* i210 Phy requires an additional bit for power up/down */ + if (hw->phy.type == e1000_phy_i210) { + hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg); + power_reg |= GS40G_CS_POWER_DOWN; + hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg); + } hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg); msleep(1); } @@ -2345,3 +2378,103 @@ out: return ret_val; } + +/** + * igb_write_phy_reg_gs40g - Write GS40G PHY register + * @hw: pointer to the HW structure + * @offset: lower half is register offset to write to + * upper half is page to use. + * @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 igb_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data) +{ + s32 ret_val; + u16 page = offset >> GS40G_PAGE_SHIFT; + + offset = offset & GS40G_OFFSET_MASK; + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + return ret_val; + + ret_val = igb_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page); + if (ret_val) + goto release; + ret_val = igb_write_phy_reg_mdic(hw, offset, data); + +release: + hw->phy.ops.release(hw); + return ret_val; +} + +/** + * igb_read_phy_reg_gs40g - Read GS40G PHY register + * @hw: pointer to the HW structure + * @offset: lower half is register offset to read to + * upper half is page to use. + * @data: data to read at register offset + * + * Acquires semaphore, if necessary, then reads the data in the PHY register + * at the offset. Release any acquired semaphores before exiting. + **/ +s32 igb_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data) +{ + s32 ret_val; + u16 page = offset >> GS40G_PAGE_SHIFT; + + offset = offset & GS40G_OFFSET_MASK; + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + return ret_val; + + ret_val = igb_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page); + if (ret_val) + goto release; + ret_val = igb_read_phy_reg_mdic(hw, offset, data); + +release: + hw->phy.ops.release(hw); + return ret_val; +} + +/** + * igb_set_master_slave_mode - Setup PHY for Master/slave mode + * @hw: pointer to the HW structure + * + * Sets up Master/slave mode + **/ +static s32 igb_set_master_slave_mode(struct e1000_hw *hw) +{ + s32 ret_val; + u16 phy_data; + + /* Resolve Master/Slave mode */ + ret_val = hw->phy.ops.read_reg(hw, PHY_1000T_CTRL, &phy_data); + if (ret_val) + return ret_val; + + /* load defaults for future use */ + hw->phy.original_ms_type = (phy_data & CR_1000T_MS_ENABLE) ? + ((phy_data & CR_1000T_MS_VALUE) ? + e1000_ms_force_master : + e1000_ms_force_slave) : e1000_ms_auto; + + switch (hw->phy.ms_type) { + 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; + /* fall-through */ + default: + break; + } + + return hw->phy.ops.write_reg(hw, PHY_1000T_CTRL, phy_data); +}
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.h b/drivers/net/ethernet/intel/igb/e1000_phy.h index 4c32ac6..34e4061 100644 --- a/drivers/net/ethernet/intel/igb/e1000_phy.h +++ b/drivers/net/ethernet/intel/igb/e1000_phy.h
@@ -73,6 +73,9 @@ s32 igb_get_phy_info_82580(struct e1000_hw *hw); s32 igb_phy_force_speed_duplex_82580(struct e1000_hw *hw); s32 igb_get_cable_length_82580(struct e1000_hw *hw); +s32 igb_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data); +s32 igb_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data); +s32 igb_check_polarity_m88(struct e1000_hw *hw); /* IGP01E1000 Specific Registers */ #define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */ @@ -114,6 +117,13 @@ /* I82580 PHY Diagnostics Status */ #define I82580_DSTATUS_CABLE_LENGTH 0x03FC #define I82580_DSTATUS_CABLE_LENGTH_SHIFT 2 + +/* 82580 PHY Power Management */ +#define E1000_82580_PHY_POWER_MGMT 0xE14 +#define E1000_82580_PM_SPD 0x0001 /* Smart Power Down */ +#define E1000_82580_PM_D0_LPLU 0x0002 /* For D0a states */ +#define E1000_82580_PM_D3_LPLU 0x0004 /* For all other states */ + /* Enable flexible speed on link-up */ #define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */ #define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */ @@ -133,4 +143,16 @@ #define E1000_CABLE_LENGTH_UNDEFINED 0xFF +/* GS40G - I210 PHY defines */ +#define GS40G_PAGE_SELECT 0x16 +#define GS40G_PAGE_SHIFT 16 +#define GS40G_OFFSET_MASK 0xFFFF +#define GS40G_PAGE_2 0x20000 +#define GS40G_MAC_REG2 0x15 +#define GS40G_MAC_LB 0x4140 +#define GS40G_MAC_SPEED_1G 0X0006 +#define GS40G_COPPER_SPEC 0x0010 +#define GS40G_CS_POWER_DOWN 0x0002 +#define GS40G_LINE_LB 0x4000 + #endif
diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h index ccdf36d..35d1e4f 100644 --- a/drivers/net/ethernet/intel/igb/e1000_regs.h +++ b/drivers/net/ethernet/intel/igb/e1000_regs.h
@@ -352,4 +352,18 @@ #define E1000_O2BGPTC 0x08FE4 /* OS2BMC packets received by BMC */ #define E1000_O2BSPC 0x0415C /* OS2BMC packets transmitted by host */ +#define E1000_SRWR 0x12018 /* Shadow Ram Write Register - RW */ +#define E1000_I210_FLMNGCTL 0x12038 +#define E1000_I210_FLMNGDATA 0x1203C +#define E1000_I210_FLMNGCNT 0x12040 + +#define E1000_I210_FLSWCTL 0x12048 +#define E1000_I210_FLSWDATA 0x1204C +#define E1000_I210_FLSWCNT 0x12050 + +#define E1000_I210_FLA 0x1201C + +#define E1000_INVM_DATA_REG(_n) (0x12120 + 4*(_n)) +#define E1000_INVM_SIZE 64 /* Number of INVM Data Registers */ + #endif
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index 3758ad2..ae6d3f3 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -65,10 +65,13 @@ #define MAX_Q_VECTORS 8 /* Transmit and receive queues */ -#define IGB_MAX_RX_QUEUES (adapter->vfs_allocated_count ? 2 : \ - (hw->mac.type > e1000_82575 ? 8 : 4)) +#define IGB_MAX_RX_QUEUES ((adapter->vfs_allocated_count ? 2 : \ + (hw->mac.type > e1000_82575 ? 8 : 4))) +#define IGB_MAX_RX_QUEUES_I210 4 +#define IGB_MAX_RX_QUEUES_I211 2 #define IGB_MAX_TX_QUEUES 16 - +#define IGB_MAX_TX_QUEUES_I210 4 +#define IGB_MAX_TX_QUEUES_I211 2 #define IGB_MAX_VF_MC_ENTRIES 30 #define IGB_MAX_VF_FUNCTIONS 8 #define IGB_MAX_VFTA_ENTRIES 128
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index e10821a..812d4f9 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -335,7 +335,7 @@ static int igb_get_regs_len(struct net_device *netdev) { -#define IGB_REGS_LEN 551 +#define IGB_REGS_LEN 739 return IGB_REGS_LEN * sizeof(u32); } @@ -552,10 +552,49 @@ regs_buff[548] = rd32(E1000_TDFT); regs_buff[549] = rd32(E1000_TDFHS); regs_buff[550] = rd32(E1000_TDFPC); - regs_buff[551] = adapter->stats.o2bgptc; - regs_buff[552] = adapter->stats.b2ospc; - regs_buff[553] = adapter->stats.o2bspc; - regs_buff[554] = adapter->stats.b2ogprc; + + if (hw->mac.type > e1000_82580) { + regs_buff[551] = adapter->stats.o2bgptc; + regs_buff[552] = adapter->stats.b2ospc; + regs_buff[553] = adapter->stats.o2bspc; + regs_buff[554] = adapter->stats.b2ogprc; + } + + if (hw->mac.type != e1000_82576) + return; + for (i = 0; i < 12; i++) + regs_buff[555 + i] = rd32(E1000_SRRCTL(i + 4)); + for (i = 0; i < 4; i++) + regs_buff[567 + i] = rd32(E1000_PSRTYPE(i + 4)); + for (i = 0; i < 12; i++) + regs_buff[571 + i] = rd32(E1000_RDBAL(i + 4)); + for (i = 0; i < 12; i++) + regs_buff[583 + i] = rd32(E1000_RDBAH(i + 4)); + for (i = 0; i < 12; i++) + regs_buff[595 + i] = rd32(E1000_RDLEN(i + 4)); + for (i = 0; i < 12; i++) + regs_buff[607 + i] = rd32(E1000_RDH(i + 4)); + for (i = 0; i < 12; i++) + regs_buff[619 + i] = rd32(E1000_RDT(i + 4)); + for (i = 0; i < 12; i++) + regs_buff[631 + i] = rd32(E1000_RXDCTL(i + 4)); + + for (i = 0; i < 12; i++) + regs_buff[643 + i] = rd32(E1000_TDBAL(i + 4)); + for (i = 0; i < 12; i++) + regs_buff[655 + i] = rd32(E1000_TDBAH(i + 4)); + for (i = 0; i < 12; i++) + regs_buff[667 + i] = rd32(E1000_TDLEN(i + 4)); + for (i = 0; i < 12; i++) + regs_buff[679 + i] = rd32(E1000_TDH(i + 4)); + for (i = 0; i < 12; i++) + regs_buff[691 + i] = rd32(E1000_TDT(i + 4)); + for (i = 0; i < 12; i++) + regs_buff[703 + i] = rd32(E1000_TXDCTL(i + 4)); + for (i = 0; i < 12; i++) + regs_buff[715 + i] = rd32(E1000_TDWBAL(i + 4)); + for (i = 0; i < 12; i++) + regs_buff[727 + i] = rd32(E1000_TDWBAH(i + 4)); } static int igb_get_eeprom_len(struct net_device *netdev) @@ -624,6 +663,9 @@ if (eeprom->len == 0) return -EOPNOTSUPP; + if (hw->mac.type == e1000_i211) + return -EOPNOTSUPP; + if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16))) return -EFAULT; @@ -851,6 +893,36 @@ #define TABLE64_TEST_LO 5 #define TABLE64_TEST_HI 6 +/* i210 reg test */ +static struct igb_reg_test reg_test_i210[] = { + { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF }, + { E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF }, + { E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, + { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, + /* RDH is read-only for i210, only test RDT. */ + { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, + { E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 }, + { E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, + { E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF }, + { E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, + { E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, + { E1000_TDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, + { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 }, + { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB }, + { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF }, + { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 }, + { E1000_RA, 0, 16, TABLE64_TEST_LO, + 0xFFFFFFFF, 0xFFFFFFFF }, + { E1000_RA, 0, 16, TABLE64_TEST_HI, + 0x900FFFFF, 0xFFFFFFFF }, + { E1000_MTA, 0, 128, TABLE32_TEST, + 0xFFFFFFFF, 0xFFFFFFFF }, + { 0, 0, 0, 0, 0 } +}; + /* i350 reg test */ static struct igb_reg_test reg_test_i350[] = { { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, @@ -1073,6 +1145,11 @@ test = reg_test_i350; toggle = 0x7FEFF3FF; break; + case e1000_i210: + case e1000_i211: + test = reg_test_i210; + toggle = 0x7FEFF3FF; + break; case e1000_82580: test = reg_test_82580; toggle = 0x7FEFF3FF; @@ -1154,23 +1231,13 @@ static int igb_eeprom_test(struct igb_adapter *adapter, u64 *data) { - u16 temp; - u16 checksum = 0; - u16 i; - *data = 0; - /* Read and add up the contents of the EEPROM */ - for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { - if ((adapter->hw.nvm.ops.read(&adapter->hw, i, 1, &temp)) < 0) { - *data = 1; - break; - } - checksum += temp; - } - /* If Checksum is not Correct return error else test passed */ - if ((checksum != (u16) NVM_SUM) && !(*data)) - *data = 2; + /* Validate eeprom on all parts but i211 */ + if (adapter->hw.mac.type != e1000_i211) { + if (adapter->hw.nvm.ops.validate(&adapter->hw) < 0) + *data = 2; + } return *data; } @@ -1236,6 +1303,8 @@ ics_mask = 0x77DCFED5; break; case e1000_i350: + case e1000_i210: + case e1000_i211: ics_mask = 0x77DCFED5; break; default: @@ -1402,23 +1471,35 @@ { struct e1000_hw *hw = &adapter->hw; u32 ctrl_reg = 0; + u16 phy_reg = 0; hw->mac.autoneg = false; - if (hw->phy.type == e1000_phy_m88) { + switch (hw->phy.type) { + case e1000_phy_m88: /* Auto-MDI/MDIX Off */ igb_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, 0x0808); /* reset to update Auto-MDI/MDIX */ igb_write_phy_reg(hw, PHY_CONTROL, 0x9140); /* autoneg off */ igb_write_phy_reg(hw, PHY_CONTROL, 0x8140); - } else if (hw->phy.type == e1000_phy_82580) { + break; + case e1000_phy_82580: /* enable MII loopback */ igb_write_phy_reg(hw, I82580_PHY_LBK_CTRL, 0x8041); + break; + case e1000_phy_i210: + /* set loopback speed in PHY */ + igb_read_phy_reg(hw, (GS40G_PAGE_SELECT & GS40G_PAGE_2), + &phy_reg); + phy_reg |= GS40G_MAC_SPEED_1G; + igb_write_phy_reg(hw, (GS40G_PAGE_SELECT & GS40G_PAGE_2), + phy_reg); + ctrl_reg = rd32(E1000_CTRL_EXT); + default: + break; } - ctrl_reg = rd32(E1000_CTRL); - /* force 1000, set loopback */ igb_write_phy_reg(hw, PHY_CONTROL, 0x4140); @@ -1431,7 +1512,7 @@ E1000_CTRL_FD | /* Force Duplex to FULL */ E1000_CTRL_SLU); /* Set link up enable bit */ - if (hw->phy.type == e1000_phy_m88) + if ((hw->phy.type == e1000_phy_m88) || (hw->phy.type == e1000_phy_i210)) ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */ wr32(E1000_CTRL, ctrl_reg); @@ -1439,7 +1520,7 @@ /* Disable the receiver on the PHY so when a cable is plugged in, the * PHY does not begin to autoneg when a cable is reconnected to the NIC. */ - if (hw->phy.type == e1000_phy_m88) + if ((hw->phy.type == e1000_phy_m88) || (hw->phy.type == e1000_phy_i210)) igb_phy_disable_receiver(adapter); udelay(500); @@ -1704,6 +1785,14 @@ *data = 0; goto out; } + if ((adapter->hw.mac.type == e1000_i210) + || (adapter->hw.mac.type == e1000_i210)) { + dev_err(&adapter->pdev->dev, + "Loopback test not supported " + "on this part at this time.\n"); + *data = 0; + goto out; + } *data = igb_setup_desc_rings(adapter); if (*data) goto out;
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 80d52d2..dd3bfe8 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -75,6 +75,11 @@ }; static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = { + { PCI_VDEVICE(INTEL, E1000_DEV_ID_I211_COPPER), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_COPPER), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_FIBER), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_SERDES), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_SGMII), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_COPPER), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_FIBER), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_SERDES), board_82575 }, @@ -641,6 +646,8 @@ case e1000_82575: case e1000_82580: case e1000_i350: + case e1000_i210: + case e1000_i211: default: for (; i < adapter->num_rx_queues; i++) adapter->rx_ring[i]->reg_idx = rbase_offset + i; @@ -727,8 +734,11 @@ if (adapter->hw.mac.type >= e1000_82576) set_bit(IGB_RING_FLAG_RX_SCTP_CSUM, &ring->flags); - /* On i350, loopback VLAN packets have the tag byte-swapped. */ - if (adapter->hw.mac.type == e1000_i350) + /* + * On i350, i210, and i211, loopback VLAN packets + * have the tag byte-swapped. + * */ + if (adapter->hw.mac.type >= e1000_i350) set_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &ring->flags); adapter->rx_ring[i] = ring; @@ -822,6 +832,8 @@ break; case e1000_82580: case e1000_i350: + case e1000_i210: + case e1000_i211: /* * On 82580 and newer adapters the scheme is similar to 82576 * however instead of ordering column-major we have things @@ -888,6 +900,8 @@ case e1000_82576: case e1000_82580: case e1000_i350: + case e1000_i210: + case e1000_i211: /* Turn on MSI-X capability first, or our settings * won't stick. And it will take days to debug. */ wr32(E1000_GPIE, E1000_GPIE_MSIX_MODE | @@ -1034,6 +1048,11 @@ if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS)) numvecs += adapter->num_tx_queues; + /* i210 and i211 can only have 4 MSIX vectors for rx/tx queues. */ + if ((adapter->hw.mac.type == e1000_i210) + || (adapter->hw.mac.type == e1000_i211)) + numvecs = 4; + /* store the number of vectors reserved for queues */ adapter->num_q_vectors = numvecs; @@ -1041,6 +1060,7 @@ numvecs++; adapter->msix_entries = kcalloc(numvecs, sizeof(struct msix_entry), GFP_KERNEL); + if (!adapter->msix_entries) goto msi_only; @@ -1083,9 +1103,12 @@ adapter->flags |= IGB_FLAG_HAS_MSI; out: /* Notify the stack of the (possibly) reduced queue counts. */ + rtnl_lock(); netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues); - return netif_set_real_num_rx_queues(adapter->netdev, - adapter->num_rx_queues); + err = netif_set_real_num_rx_queues(adapter->netdev, + adapter->num_rx_queues); + rtnl_unlock(); + return err; } /** @@ -1631,6 +1654,8 @@ pba &= E1000_RXPBS_SIZE_MASK_82576; break; case e1000_82575: + case e1000_i210: + case e1000_i211: default: pba = E1000_PBA_34K; break; @@ -1826,7 +1851,7 @@ */ if (pdev->is_virtfn) { WARN(1, KERN_ERR "%s (%hx:%hx) should not be a VF!\n", - pci_name(pdev), pdev->vendor, pdev->device); + pci_name(pdev), pdev->vendor, pdev->device); return -EINVAL; } @@ -1980,11 +2005,16 @@ * known good starting state */ hw->mac.ops.reset_hw(hw); - /* make sure the NVM is good */ - if (hw->nvm.ops.validate(hw) < 0) { - dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n"); - err = -EIO; - goto err_eeprom; + /* + * make sure the NVM is good , i211 parts have special NVM that + * doesn't contain a checksum + */ + if (hw->mac.type != e1000_i211) { + if (hw->nvm.ops.validate(hw) < 0) { + dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n"); + err = -EIO; + goto err_eeprom; + } } /* copy the MAC address out of the NVM */ @@ -2118,6 +2148,8 @@ adapter->num_rx_queues, adapter->num_tx_queues); switch (hw->mac.type) { case e1000_i350: + case e1000_i210: + case e1000_i211: igb_set_eee_i350(hw); break; default: @@ -2244,9 +2276,14 @@ { #ifdef CONFIG_PCI_IOV struct pci_dev *pdev = adapter->pdev; + struct e1000_hw *hw = &adapter->hw; int old_vfs = igb_find_enabled_vfs(adapter); int i; + /* Virtualization features not supported on i210 family. */ + if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) + return; + if (old_vfs) { dev_info(&pdev->dev, "%d pre-allocated VFs found - override " "max_vfs setting of %d\n", old_vfs, max_vfs); @@ -2258,6 +2295,7 @@ adapter->vf_data = kcalloc(adapter->vfs_allocated_count, sizeof(struct vf_data_storage), GFP_KERNEL); + /* if allocation failed then we do not support SR-IOV */ if (!adapter->vf_data) { adapter->vfs_allocated_count = 0; @@ -2332,11 +2370,28 @@ } else adapter->vfs_allocated_count = max_vfs; break; + case e1000_i210: + case e1000_i211: + adapter->vfs_allocated_count = 0; + break; default: break; } #endif /* CONFIG_PCI_IOV */ - adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus()); + switch (hw->mac.type) { + case e1000_i210: + adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES_I210, + num_online_cpus()); + break; + case e1000_i211: + adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES_I211, + num_online_cpus()); + break; + default: + adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES, + num_online_cpus()); + break; + } /* i350 cannot do RSS and SR-IOV at the same time */ if (hw->mac.type == e1000_i350 && adapter->vfs_allocated_count) adapter->rss_queues = 1; @@ -2366,7 +2421,7 @@ /* Explicitly disable IRQ since the NIC can be in any state. */ igb_irq_disable(adapter); - if (hw->mac.type == e1000_i350) + if (hw->mac.type >= e1000_i350) adapter->flags &= ~IGB_FLAG_DMAC; set_bit(__IGB_DOWN, &adapter->state); @@ -2819,6 +2874,17 @@ /* Don't need to set TUOFL or IPOFL, they default to 1 */ wr32(E1000_RXCSUM, rxcsum); + /* + * Generate RSS hash based on TCP port numbers and/or + * IPv4/v6 src and dst addresses since UDP cannot be + * hashed reliably due to IP fragmentation + */ + + mrqc = E1000_MRQC_RSS_FIELD_IPV4 | + E1000_MRQC_RSS_FIELD_IPV4_TCP | + E1000_MRQC_RSS_FIELD_IPV6 | + E1000_MRQC_RSS_FIELD_IPV6_TCP | + E1000_MRQC_RSS_FIELD_IPV6_TCP_EX; /* If VMDq is enabled then we set the appropriate mode for that, else * we default to RSS so that an RSS hash is calculated per packet even @@ -2834,25 +2900,15 @@ wr32(E1000_VT_CTL, vtctl); } if (adapter->rss_queues > 1) - mrqc = E1000_MRQC_ENABLE_VMDQ_RSS_2Q; + mrqc |= E1000_MRQC_ENABLE_VMDQ_RSS_2Q; else - mrqc = E1000_MRQC_ENABLE_VMDQ; + mrqc |= E1000_MRQC_ENABLE_VMDQ; } else { - mrqc = E1000_MRQC_ENABLE_RSS_4Q; + if (hw->mac.type != e1000_i211) + mrqc |= E1000_MRQC_ENABLE_RSS_4Q; } igb_vmm_control(adapter); - /* - * Generate RSS hash based on TCP port numbers and/or - * IPv4/v6 src and dst addresses since UDP cannot be - * hashed reliably due to IP fragmentation - */ - mrqc |= E1000_MRQC_RSS_FIELD_IPV4 | - E1000_MRQC_RSS_FIELD_IPV4_TCP | - E1000_MRQC_RSS_FIELD_IPV6 | - E1000_MRQC_RSS_FIELD_IPV6_TCP | - E1000_MRQC_RSS_FIELD_IPV6_TCP_EX; - wr32(E1000_MRQC, mrqc); } @@ -3454,7 +3510,7 @@ * we will have issues with VLAN tag stripping not being done for frames * that are only arriving because we are the default pool */ - if (hw->mac.type < e1000_82576) + if ((hw->mac.type < e1000_82576) || (hw->mac.type > e1000_i350)) return; vmolr |= rd32(E1000_VMOLR(vfn)) & @@ -3551,7 +3607,7 @@ bool ret = false; u32 ctrl_ext, thstat; - /* check for thermal sensor event on i350, copper only */ + /* check for thermal sensor event on i350 copper only */ if (hw->mac.type == e1000_i350) { thstat = rd32(E1000_THSTAT); ctrl_ext = rd32(E1000_CTRL_EXT); @@ -6653,18 +6709,7 @@ pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); - if (!rtnl_is_locked()) { - /* - * shut up ASSERT_RTNL() warning in - * netif_set_real_num_tx/rx_queues. - */ - rtnl_lock(); - err = igb_init_interrupt_scheme(adapter); - rtnl_unlock(); - } else { - err = igb_init_interrupt_scheme(adapter); - } - if (err) { + if (igb_init_interrupt_scheme(adapter)) { dev_err(&pdev->dev, "Unable to allocate memory for queues\n"); return -ENOMEM; } @@ -7027,6 +7072,8 @@ switch (hw->mac.type) { case e1000_82575: + case e1000_i210: + case e1000_i211: default: /* replication is not supported for 82575 */ return; @@ -7100,6 +7147,9 @@ /* watchdog timer= +-1000 usec in 32usec intervals */ reg |= (1000 >> 5); + + /* Disable BMC-to-OS Watchdog Enable */ + reg &= ~E1000_DMACR_DC_BMC2OSW_EN; wr32(E1000_DMACR, reg); /*
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index c9b71c5..d5ee7fa 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -262,6 +262,8 @@ struct e1000_hw *hw = &adapter->hw; switch (hw->mac.type) { + case e1000_i210: + case e1000_i211: case e1000_i350: case e1000_82580: adapter->caps.owner = THIS_MODULE; @@ -362,6 +364,8 @@ unsigned long flags; switch (adapter->hw.mac.type) { + case e1000_i210: + case e1000_i211: case e1000_i350: case e1000_82580: case e1000_82576:
diff --git a/drivers/net/ethernet/intel/ixgbe/Makefile b/drivers/net/ethernet/intel/ixgbe/Makefile index 0708d7e..0bdf06b 100644 --- a/drivers/net/ethernet/intel/ixgbe/Makefile +++ b/drivers/net/ethernet/intel/ixgbe/Makefile
@@ -39,4 +39,6 @@ ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \ ixgbe_dcb_82599.o ixgbe_dcb_nl.o +ixgbe-$(CONFIG_IXGBE_PTP) += ixgbe_ptp.o + ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 425f864..3ef3c52 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -36,6 +36,12 @@ #include <linux/aer.h> #include <linux/if_vlan.h> +#ifdef CONFIG_IXGBE_PTP +#include <linux/clocksource.h> +#include <linux/net_tstamp.h> +#include <linux/ptp_clock_kernel.h> +#endif /* CONFIG_IXGBE_PTP */ + #include "ixgbe_type.h" #include "ixgbe_common.h" #include "ixgbe_dcb.h" @@ -96,6 +102,7 @@ #define IXGBE_TX_FLAGS_FCOE (u32)(1 << 5) #define IXGBE_TX_FLAGS_FSO (u32)(1 << 6) #define IXGBE_TX_FLAGS_TXSW (u32)(1 << 7) +#define IXGBE_TX_FLAGS_TSTAMP (u32)(1 << 8) #define IXGBE_TX_FLAGS_VLAN_MASK 0xffff0000 #define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0xe0000000 #define IXGBE_TX_FLAGS_VLAN_PRIO_SHIFT 29 @@ -458,6 +465,8 @@ #define IXGBE_FLAG2_FDIR_REQUIRES_REINIT (u32)(1 << 7) #define IXGBE_FLAG2_RSS_FIELD_IPV4_UDP (u32)(1 << 8) #define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP (u32)(1 << 9) +#define IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED (u32)(1 << 10) +#define IXGBE_FLAG2_PTP_PPS_ENABLED (u32)(1 << 11) /* Tx fast path data */ int num_tx_queues; @@ -545,6 +554,17 @@ u32 interrupt_event; u32 led_reg; +#ifdef CONFIG_IXGBE_PTP + struct ptp_clock *ptp_clock; + struct ptp_clock_info ptp_caps; + unsigned long last_overflow_check; + spinlock_t tmreg_lock; + struct cyclecounter cc; + struct timecounter tc; + u32 base_incval; + u32 cycle_speed; +#endif /* CONFIG_IXGBE_PTP */ + /* SR-IOV */ DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS); unsigned int num_vfs; @@ -652,12 +672,15 @@ union ixgbe_atr_input *mask); extern void ixgbe_set_rx_mode(struct net_device *netdev); #ifdef CONFIG_IXGBE_DCB +extern void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter); extern int ixgbe_setup_tc(struct net_device *dev, u8 tc); #endif extern void ixgbe_tx_ctxtdesc(struct ixgbe_ring *, u32, u32, u32, u32); extern void ixgbe_do_reset(struct net_device *netdev); +#ifdef CONFIG_IXGBE_HWMON extern void ixgbe_sysfs_exit(struct ixgbe_adapter *adapter); extern int ixgbe_sysfs_init(struct ixgbe_adapter *adapter); +#endif /* CONFIG_IXGBE_HWMON */ #ifdef IXGBE_FCOE extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); extern int ixgbe_fso(struct ixgbe_ring *tx_ring, @@ -688,4 +711,18 @@ return netdev_get_tx_queue(ring->netdev, ring->queue_index); } +#ifdef CONFIG_IXGBE_PTP +extern void ixgbe_ptp_init(struct ixgbe_adapter *adapter); +extern void ixgbe_ptp_stop(struct ixgbe_adapter *adapter); +extern void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); +extern void ixgbe_ptp_tx_hwtstamp(struct ixgbe_q_vector *q_vector, + struct sk_buff *skb); +extern void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, + struct sk_buff *skb); +extern int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, + struct ifreq *ifr, int cmd); +extern void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); +extern void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr); +#endif /* CONFIG_IXGBE_PTP */ + #endif /* _IXGBE_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c index c7e51b8..77ac41f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -2561,7 +2561,7 @@ break; else /* Use interrupt-safe sleep just in case */ - udelay(10); + udelay(1000); } /* For informational purposes only */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c index d3695ed..87592b4 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
@@ -191,54 +191,47 @@ */ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en) { - u32 reg; + u32 fcrtl, reg; u8 i; - if (pfc_en) { - /* Enable Transmit Priority Flow Control */ - reg = IXGBE_READ_REG(hw, IXGBE_RMCS); - reg &= ~IXGBE_RMCS_TFCE_802_3X; - /* correct the reporting of our flow control status */ - reg |= IXGBE_RMCS_TFCE_PRIORITY; - IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); + /* Enable Transmit Priority Flow Control */ + reg = IXGBE_READ_REG(hw, IXGBE_RMCS); + reg &= ~IXGBE_RMCS_TFCE_802_3X; + reg |= IXGBE_RMCS_TFCE_PRIORITY; + IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); - /* Enable Receive Priority Flow Control */ - reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); - reg &= ~IXGBE_FCTRL_RFCE; + /* Enable Receive Priority Flow Control */ + reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); + reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE); + + if (pfc_en) reg |= IXGBE_FCTRL_RPFCE; - IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg); - /* Configure pause time */ - for (i = 0; i < (MAX_TRAFFIC_CLASS >> 1); i++) - IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), 0x68006800); + IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg); - /* Configure flow control refresh threshold value */ - IXGBE_WRITE_REG(hw, IXGBE_FCRTV, 0x3400); - } - - /* - * Configure flow control thresholds and enable priority flow control - * for each traffic class. - */ + fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE; + /* Configure PFC Tx thresholds per TC */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { - int enabled = pfc_en & (1 << i); + if (!(pfc_en & (1 << i))) { + IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0); + IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0); + continue; + } - reg = hw->fc.low_water << 10; - - if (enabled == pfc_enabled_tx || - enabled == pfc_enabled_full) - reg |= IXGBE_FCRTL_XONE; - - IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg); - - reg = hw->fc.high_water[i] << 10; - if (enabled == pfc_enabled_tx || - enabled == pfc_enabled_full) - reg |= IXGBE_FCRTH_FCEN; - + reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; + IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl); IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg); } + /* Configure pause time */ + reg = hw->fc.pause_time * 0x00010001; + for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) + IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); + + /* Configure flow control refresh threshold value */ + IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); + + return 0; }
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c index 65913c5..4eac80d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
@@ -211,24 +211,42 @@ */ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc) { - u32 i, j, reg; + u32 i, j, fcrtl, reg; u8 max_tc = 0; - for (i = 0; i < MAX_USER_PRIORITY; i++) + /* Enable Transmit Priority Flow Control */ + IXGBE_WRITE_REG(hw, IXGBE_FCCFG, IXGBE_FCCFG_TFCE_PRIORITY); + + /* Enable Receive Priority Flow Control */ + reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); + reg |= IXGBE_MFLCN_DPF; + + /* + * X540 supports per TC Rx priority flow control. So + * clear all TCs and only enable those that should be + * enabled. + */ + reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE); + + if (hw->mac.type == ixgbe_mac_X540) + reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT; + + if (pfc_en) + reg |= IXGBE_MFLCN_RPFCE; + + IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg); + + for (i = 0; i < MAX_USER_PRIORITY; i++) { if (prio_tc[i] > max_tc) max_tc = prio_tc[i]; + } + + fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE; /* Configure PFC Tx thresholds per TC */ - for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + for (i = 0; i <= max_tc; i++) { int enabled = 0; - if (i > max_tc) { - reg = 0; - IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg); - IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg); - continue; - } - for (j = 0; j < MAX_USER_PRIORITY; j++) { if ((prio_tc[j] == i) && (pfc_en & (1 << j))) { enabled = 1; @@ -236,51 +254,30 @@ } } - reg = hw->fc.low_water << 10; + if (enabled) { + reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; + IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl); + } else { + reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32; + IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0); + } - if (enabled) - reg |= IXGBE_FCRTL_XONE; - IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg); - - reg = hw->fc.high_water[i] << 10; - if (enabled) - reg |= IXGBE_FCRTH_FCEN; IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg); } - if (pfc_en) { - /* Configure pause time (2 TCs per register) */ - reg = hw->fc.pause_time | (hw->fc.pause_time << 16); - for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) - IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); - - /* Configure flow control refresh threshold value */ - IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); - - - reg = IXGBE_FCCFG_TFCE_PRIORITY; - IXGBE_WRITE_REG(hw, IXGBE_FCCFG, reg); - /* - * Enable Receive PFC - * 82599 will always honor XOFF frames we receive when - * we are in PFC mode however X540 only honors enabled - * traffic classes. - */ - reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); - reg &= ~IXGBE_MFLCN_RFCE; - reg |= IXGBE_MFLCN_RPFCE | IXGBE_MFLCN_DPF; - - if (hw->mac.type == ixgbe_mac_X540) { - reg &= ~IXGBE_MFLCN_RPFCE_MASK; - reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT; - } - - IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg); - - } else { - hw->mac.ops.fc_enable(hw); + for (; i < MAX_TRAFFIC_CLASS; i++) { + IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0); + IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), 0); } + /* Configure pause time (2 TCs per register) */ + reg = hw->fc.pause_time * 0x00010001; + for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) + IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); + + /* Configure flow control refresh threshold value */ + IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); + return 0; }
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c index a09d6b4..5164a21 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
@@ -338,6 +338,8 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_dcb_config *dcb_cfg = &adapter->dcb_cfg; + struct ixgbe_hw *hw = &adapter->hw; int ret = DCB_NO_HW_CHG; int i; @@ -350,32 +352,6 @@ if (!adapter->dcb_set_bitmap) return ret; - if (adapter->dcb_cfg.pfc_mode_enable) { - switch (adapter->hw.mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - if (adapter->hw.fc.current_mode != ixgbe_fc_pfc) - adapter->last_lfc_mode = - adapter->hw.fc.current_mode; - break; - default: - break; - } - adapter->hw.fc.requested_mode = ixgbe_fc_pfc; - } else { - switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: - adapter->hw.fc.requested_mode = ixgbe_fc_none; - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - adapter->hw.fc.requested_mode = adapter->last_lfc_mode; - break; - default: - break; - } - } - if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) { u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS]; u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS]; @@ -388,23 +364,19 @@ max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); #endif - ixgbe_dcb_calculate_tc_credits(&adapter->hw, &adapter->dcb_cfg, - max_frame, DCB_TX_CONFIG); - ixgbe_dcb_calculate_tc_credits(&adapter->hw, &adapter->dcb_cfg, - max_frame, DCB_RX_CONFIG); + ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame, + DCB_TX_CONFIG); + ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame, + DCB_RX_CONFIG); - ixgbe_dcb_unpack_refill(&adapter->dcb_cfg, - DCB_TX_CONFIG, refill); - ixgbe_dcb_unpack_max(&adapter->dcb_cfg, max); - ixgbe_dcb_unpack_bwgid(&adapter->dcb_cfg, - DCB_TX_CONFIG, bwg_id); - ixgbe_dcb_unpack_prio(&adapter->dcb_cfg, - DCB_TX_CONFIG, prio_type); - ixgbe_dcb_unpack_map(&adapter->dcb_cfg, - DCB_TX_CONFIG, prio_tc); + ixgbe_dcb_unpack_refill(dcb_cfg, DCB_TX_CONFIG, refill); + ixgbe_dcb_unpack_max(dcb_cfg, max); + ixgbe_dcb_unpack_bwgid(dcb_cfg, DCB_TX_CONFIG, bwg_id); + ixgbe_dcb_unpack_prio(dcb_cfg, DCB_TX_CONFIG, prio_type); + ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc); - ixgbe_dcb_hw_ets_config(&adapter->hw, refill, max, - bwg_id, prio_type, prio_tc); + ixgbe_dcb_hw_ets_config(hw, refill, max, bwg_id, + prio_type, prio_tc); for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) netdev_set_prio_tc_map(netdev, i, prio_tc[i]); @@ -413,20 +385,22 @@ } if (adapter->dcb_set_bitmap & BIT_PFC) { - u8 pfc_en; - u8 prio_tc[MAX_USER_PRIORITY]; + if (dcb_cfg->pfc_mode_enable) { + u8 pfc_en; + u8 prio_tc[MAX_USER_PRIORITY]; - ixgbe_dcb_unpack_map(&adapter->dcb_cfg, - DCB_TX_CONFIG, prio_tc); - ixgbe_dcb_unpack_pfc(&adapter->dcb_cfg, &pfc_en); - ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc_en, prio_tc); - if (ret != DCB_HW_CHG_RST) - ret = DCB_HW_CHG; + ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc); + ixgbe_dcb_unpack_pfc(dcb_cfg, &pfc_en); + ixgbe_dcb_hw_pfc_config(hw, pfc_en, prio_tc); + } else { + hw->mac.ops.fc_enable(hw); + } + + ixgbe_set_rx_drop_en(adapter); + + ret = DCB_HW_CHG; } - if (adapter->dcb_cfg.pfc_mode_enable) - adapter->hw.fc.current_mode = ixgbe_fc_pfc; - #ifdef IXGBE_FCOE /* Reprogam FCoE hardware offloads when the traffic class * FCoE is using changes. This happens if the APP info @@ -647,7 +621,9 @@ struct ieee_pfc *pfc) { struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ixgbe_hw *hw = &adapter->hw; u8 *prio_tc; + int err; if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) return -EINVAL; @@ -659,16 +635,18 @@ return -ENOMEM; } - if (pfc->pfc_en) { - adapter->last_lfc_mode = adapter->hw.fc.current_mode; - adapter->hw.fc.current_mode = ixgbe_fc_pfc; - } else { - adapter->hw.fc.current_mode = adapter->last_lfc_mode; - } - prio_tc = adapter->ixgbe_ieee_ets->prio_tc; memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc)); - return ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc->pfc_en, prio_tc); + + /* Enable link flow control parameters if PFC is disabled */ + if (pfc->pfc_en) + err = ixgbe_dcb_hw_pfc_config(hw, pfc->pfc_en, prio_tc); + else + err = hw->mac.ops.fc_enable(hw); + + ixgbe_set_rx_drop_en(adapter); + + return err; } static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index cca3e9c..3178f1e 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -391,11 +391,6 @@ } else if (hw->fc.current_mode == ixgbe_fc_full) { pause->rx_pause = 1; pause->tx_pause = 1; -#ifdef CONFIG_DCB - } else if (hw->fc.current_mode == ixgbe_fc_pfc) { - pause->rx_pause = 0; - pause->tx_pause = 0; -#endif } } @@ -404,21 +399,14 @@ { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; - struct ixgbe_fc_info fc; + struct ixgbe_fc_info fc = hw->fc; -#ifdef CONFIG_DCB - if (adapter->dcb_cfg.pfc_mode_enable || - ((hw->mac.type == ixgbe_mac_82598EB) && - (adapter->flags & IXGBE_FLAG_DCB_ENABLED))) + /* 82598 does no support link flow control with DCB enabled */ + if ((hw->mac.type == ixgbe_mac_82598EB) && + (adapter->flags & IXGBE_FLAG_DCB_ENABLED)) return -EINVAL; -#endif - fc = hw->fc; - - if (pause->autoneg != AUTONEG_ENABLE) - fc.disable_fc_autoneg = true; - else - fc.disable_fc_autoneg = false; + fc.disable_fc_autoneg = (pause->autoneg != AUTONEG_ENABLE); if ((pause->rx_pause && pause->tx_pause) || pause->autoneg) fc.requested_mode = ixgbe_fc_full; @@ -426,14 +414,8 @@ fc.requested_mode = ixgbe_fc_rx_pause; else if (!pause->rx_pause && pause->tx_pause) fc.requested_mode = ixgbe_fc_tx_pause; - else if (!pause->rx_pause && !pause->tx_pause) - fc.requested_mode = ixgbe_fc_none; else - return -EINVAL; - -#ifdef CONFIG_DCB - adapter->last_lfc_mode = fc.requested_mode; -#endif + fc.requested_mode = ixgbe_fc_none; /* if the thing changed then we'll update and use new autoneg */ if (memcmp(&fc, &hw->fc, sizeof(struct ixgbe_fc_info))) { @@ -2714,6 +2696,46 @@ return ret; } +static int ixgbe_get_ts_info(struct net_device *dev, + struct ethtool_ts_info *info) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + + switch (adapter->hw.mac.type) { +#ifdef CONFIG_IXGBE_PTP + case ixgbe_mac_X540: + case ixgbe_mac_82599EB: + info->so_timestamping = + SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; + + if (adapter->ptp_clock) + info->phc_index = ptp_clock_index(adapter->ptp_clock); + else + info->phc_index = -1; + + info->tx_types = + (1 << HWTSTAMP_TX_OFF) | + (1 << HWTSTAMP_TX_ON); + + info->rx_filters = + (1 << HWTSTAMP_FILTER_NONE) | + (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) | + (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) | + (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | + (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) | + (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | + (1 << HWTSTAMP_FILTER_SOME); + break; +#endif /* CONFIG_IXGBE_PTP */ + default: + return ethtool_op_get_ts_info(dev, info); + break; + } + return 0; +} + static const struct ethtool_ops ixgbe_ethtool_ops = { .get_settings = ixgbe_get_settings, .set_settings = ixgbe_set_settings, @@ -2742,6 +2764,7 @@ .set_coalesce = ixgbe_set_coalesce, .get_rxnfc = ixgbe_get_rxnfc, .set_rxnfc = ixgbe_set_rxnfc, + .get_ts_info = ixgbe_get_ts_info, }; void ixgbe_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index ea3cb71..bf20457 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -63,8 +63,8 @@ "Intel(R) 10 Gigabit Network Connection"; #endif #define MAJ 3 -#define MIN 8 -#define BUILD 21 +#define MIN 9 +#define BUILD 15 #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ __stringify(BUILD) "-k" const char ixgbe_driver_version[] = DRV_VERSION; @@ -610,39 +610,50 @@ /* tx_buffer must be completely set up in the transmit path */ } +static void ixgbe_update_xoff_rx_lfc(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_hw_stats *hwstats = &adapter->stats; + int i; + u32 data; + + if ((hw->fc.current_mode != ixgbe_fc_full) && + (hw->fc.current_mode != ixgbe_fc_rx_pause)) + return; + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); + break; + default: + data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); + } + hwstats->lxoffrxc += data; + + /* refill credits (no tx hang) if we received xoff */ + if (!data) + return; + + for (i = 0; i < adapter->num_tx_queues; i++) + clear_bit(__IXGBE_HANG_CHECK_ARMED, + &adapter->tx_ring[i]->state); +} + static void ixgbe_update_xoff_received(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw_stats *hwstats = &adapter->stats; - u32 data = 0; u32 xoff[8] = {0}; int i; + bool pfc_en = adapter->dcb_cfg.pfc_mode_enable; - if ((hw->fc.current_mode == ixgbe_fc_full) || - (hw->fc.current_mode == ixgbe_fc_rx_pause)) { - switch (hw->mac.type) { - case ixgbe_mac_82598EB: - data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); - break; - default: - data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); - } - hwstats->lxoffrxc += data; + if (adapter->ixgbe_ieee_pfc) + pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en); - /* refill credits (no tx hang) if we received xoff */ - if (!data) - return; - - for (i = 0; i < adapter->num_tx_queues; i++) - clear_bit(__IXGBE_HANG_CHECK_ARMED, - &adapter->tx_ring[i]->state); + if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED) || !pfc_en) { + ixgbe_update_xoff_rx_lfc(adapter); return; - } else if (((adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE) && - !(adapter->dcb_cfg.pfc_mode_enable)) || - ((adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) && - adapter->ixgbe_ieee_pfc && - !(adapter->ixgbe_ieee_pfc->pfc_en))) - return; + } /* update stats for each tc, only valid with PFC enabled */ for (i = 0; i < MAX_TX_PACKET_BUFFERS; i++) { @@ -778,6 +789,13 @@ total_bytes += tx_buffer->bytecount; total_packets += tx_buffer->gso_segs; +#ifdef CONFIG_IXGBE_PTP + if (unlikely(tx_buffer->tx_flags & + IXGBE_TX_FLAGS_TSTAMP)) + ixgbe_ptp_tx_hwtstamp(q_vector, + tx_buffer->skb); + +#endif /* free the skb */ dev_kfree_skb_any(tx_buffer->skb); @@ -1378,6 +1396,11 @@ ixgbe_rx_checksum(rx_ring, rx_desc, skb); +#ifdef CONFIG_IXGBE_PTP + if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS)) + ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, skb); +#endif + if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan); __vlan_hwaccel_put_tag(skb, vid); @@ -2299,6 +2322,9 @@ } ixgbe_check_fan_failure(adapter, eicr); +#ifdef CONFIG_IXGBE_PTP + ixgbe_ptp_check_pps_event(adapter, eicr); +#endif /* re-enable the original interrupt state, no lsc, no queues */ if (!test_bit(__IXGBE_DOWN, &adapter->state)) @@ -2491,6 +2517,9 @@ } ixgbe_check_fan_failure(adapter, eicr); +#ifdef CONFIG_IXGBE_PTP + ixgbe_ptp_check_pps_event(adapter, eicr); +#endif /* would disable interrupts here but EIAM disabled it */ napi_schedule(&q_vector->napi); @@ -2760,6 +2789,61 @@ ixgbe_configure_tx_ring(adapter, adapter->tx_ring[i]); } +static void ixgbe_enable_rx_drop(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + u8 reg_idx = ring->reg_idx; + u32 srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(reg_idx)); + + srrctl |= IXGBE_SRRCTL_DROP_EN; + + IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(reg_idx), srrctl); +} + +static void ixgbe_disable_rx_drop(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + u8 reg_idx = ring->reg_idx; + u32 srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(reg_idx)); + + srrctl &= ~IXGBE_SRRCTL_DROP_EN; + + IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(reg_idx), srrctl); +} + +#ifdef CONFIG_IXGBE_DCB +void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter) +#else +static void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter) +#endif +{ + int i; + bool pfc_en = adapter->dcb_cfg.pfc_mode_enable; + + if (adapter->ixgbe_ieee_pfc) + pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en); + + /* + * We should set the drop enable bit if: + * SR-IOV is enabled + * or + * Number of Rx queues > 1 and flow control is disabled + * + * This allows us to avoid head of line blocking for security + * and performance reasons. + */ + if (adapter->num_vfs || (adapter->num_rx_queues > 1 && + !(adapter->hw.fc.current_mode & ixgbe_fc_tx_pause) && !pfc_en)) { + for (i = 0; i < adapter->num_rx_queues; i++) + ixgbe_enable_rx_drop(adapter, adapter->rx_ring[i]); + } else { + for (i = 0; i < adapter->num_rx_queues; i++) + ixgbe_disable_rx_drop(adapter, adapter->rx_ring[i]); + } +} + #define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2 static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, @@ -4403,9 +4487,6 @@ /* default flow control settings */ hw->fc.requested_mode = ixgbe_fc_full; hw->fc.current_mode = ixgbe_fc_full; /* init for ethtool output */ -#ifdef CONFIG_DCB - adapter->last_lfc_mode = hw->fc.current_mode; -#endif ixgbe_pbthresh_setup(adapter); hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE; hw->fc.send_xon = true; @@ -5268,8 +5349,10 @@ if (adapter->ixgbe_ieee_pfc) pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en); - if (link_up && !((adapter->flags & IXGBE_FLAG_DCB_ENABLED) && pfc_en)) + if (link_up && !((adapter->flags & IXGBE_FLAG_DCB_ENABLED) && pfc_en)) { hw->mac.ops.fc_enable(hw); + ixgbe_set_rx_drop_en(adapter); + } if (link_up || time_after(jiffies, (adapter->link_check_timeout + @@ -5322,6 +5405,11 @@ flow_rx = false; break; } + +#ifdef CONFIG_IXGBE_PTP + ixgbe_ptp_start_cyclecounter(adapter); +#endif + e_info(drv, "NIC Link is Up %s, Flow Control: %s\n", (link_speed == IXGBE_LINK_SPEED_10GB_FULL ? "10 Gbps" : @@ -5359,6 +5447,10 @@ if (ixgbe_is_sfp(hw) && hw->mac.type == ixgbe_mac_82598EB) adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP; +#ifdef CONFIG_IXGBE_PTP + ixgbe_ptp_start_cyclecounter(adapter); +#endif + e_info(drv, "NIC Link is Down\n"); netif_carrier_off(netdev); } @@ -5658,6 +5750,9 @@ ixgbe_watchdog_subtask(adapter); ixgbe_fdir_reinit_subtask(adapter); ixgbe_check_hang_subtask(adapter); +#ifdef CONFIG_IXGBE_PTP + ixgbe_ptp_overflow_check(adapter); +#endif ixgbe_service_event_complete(adapter); } @@ -5808,6 +5903,11 @@ if (tx_flags & IXGBE_TX_FLAGS_HW_VLAN) cmd_type |= cpu_to_le32(IXGBE_ADVTXD_DCMD_VLE); +#ifdef CONFIG_IXGBE_PTP + if (tx_flags & IXGBE_TX_FLAGS_TSTAMP) + cmd_type |= cpu_to_le32(IXGBE_ADVTXD_MAC_TSTAMP); +#endif + /* set segmentation enable bits for TSO/FSO */ #ifdef IXGBE_FCOE if (tx_flags & (IXGBE_TX_FLAGS_TSO | IXGBE_TX_FLAGS_FSO)) @@ -6198,6 +6298,15 @@ tx_flags |= IXGBE_TX_FLAGS_SW_VLAN; } + skb_tx_timestamp(skb); + +#ifdef CONFIG_IXGBE_PTP + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + tx_flags |= IXGBE_TX_FLAGS_TSTAMP; + } +#endif + #ifdef CONFIG_PCI_IOV /* * Use the l2switch_enable flag - would be false if the DMA @@ -6350,7 +6459,14 @@ { struct ixgbe_adapter *adapter = netdev_priv(netdev); - return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd); + switch (cmd) { +#ifdef CONFIG_IXGBE_PTP + case SIOCSHWTSTAMP: + return ixgbe_ptp_hwtstamp_ioctl(adapter, req, cmd); +#endif + default: + return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd); + } } /** @@ -6542,15 +6658,17 @@ if (tc) { netdev_set_num_tc(dev, tc); - adapter->last_lfc_mode = adapter->hw.fc.current_mode; adapter->flags |= IXGBE_FLAG_DCB_ENABLED; adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; - if (adapter->hw.mac.type == ixgbe_mac_82598EB) + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + adapter->last_lfc_mode = adapter->hw.fc.requested_mode; adapter->hw.fc.requested_mode = ixgbe_fc_none; + } } else { netdev_reset_tc(dev); - adapter->hw.fc.requested_mode = adapter->last_lfc_mode; + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + adapter->hw.fc.requested_mode = adapter->last_lfc_mode; adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; @@ -7135,6 +7253,10 @@ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); +#ifdef CONFIG_IXGBE_PTP + ixgbe_ptp_init(adapter); +#endif /* CONFIG_IXGBE_PTP*/ + /* save off EEPROM version number */ hw->eeprom.ops.read(hw, 0x2e, &adapter->eeprom_verh); hw->eeprom.ops.read(hw, 0x2d, &adapter->eeprom_verl); @@ -7222,8 +7344,10 @@ e_dev_info("%s\n", ixgbe_default_device_descr); cards_found++; +#ifdef CONFIG_IXGBE_HWMON if (ixgbe_sysfs_init(adapter)) e_err(probe, "failed to allocate sysfs resources\n"); +#endif /* CONFIG_IXGBE_HWMON */ return 0; @@ -7263,6 +7387,10 @@ set_bit(__IXGBE_DOWN, &adapter->state); cancel_work_sync(&adapter->service_task); +#ifdef CONFIG_IXGBE_PTP + ixgbe_ptp_stop(adapter); +#endif + #ifdef CONFIG_IXGBE_DCA if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED; @@ -7271,7 +7399,9 @@ } #endif +#ifdef CONFIG_IXGBE_HWMON ixgbe_sysfs_exit(adapter); +#endif /* CONFIG_IXGBE_HWMON */ #ifdef IXGBE_FCOE if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c new file mode 100644 index 0000000..ddc6a4d --- /dev/null +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -0,0 +1,900 @@ +/******************************************************************************* + + Intel 10 Gigabit PCI Express Linux driver + Copyright(c) 1999 - 2012 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: + e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ +#include "ixgbe.h" +#include <linux/export.h> + +/* + * The 82599 and the X540 do not have true 64bit nanosecond scale + * counter registers. Instead, SYSTIME is defined by a fixed point + * system which allows the user to define the scale counter increment + * value at every level change of the oscillator driving the SYSTIME + * value. For both devices the TIMINCA:IV field defines this + * increment. On the X540 device, 31 bits are provided. However on the + * 82599 only provides 24 bits. The time unit is determined by the + * clock frequency of the oscillator in combination with the TIMINCA + * register. When these devices link at 10Gb the oscillator has a + * period of 6.4ns. In order to convert the scale counter into + * nanoseconds the cyclecounter and timecounter structures are + * used. The SYSTIME registers need to be converted to ns values by use + * of only a right shift (division by power of 2). The following math + * determines the largest incvalue that will fit into the available + * bits in the TIMINCA register. + * + * PeriodWidth: Number of bits to store the clock period + * MaxWidth: The maximum width value of the TIMINCA register + * Period: The clock period for the oscillator + * round(): discard the fractional portion of the calculation + * + * Period * [ 2 ^ ( MaxWidth - PeriodWidth ) ] + * + * For the X540, MaxWidth is 31 bits, and the base period is 6.4 ns + * For the 82599, MaxWidth is 24 bits, and the base period is 6.4 ns + * + * The period also changes based on the link speed: + * At 10Gb link or no link, the period remains the same. + * At 1Gb link, the period is multiplied by 10. (64ns) + * At 100Mb link, the period is multiplied by 100. (640ns) + * + * The calculated value allows us to right shift the SYSTIME register + * value in order to quickly convert it into a nanosecond clock, + * while allowing for the maximum possible adjustment value. + * + * These diagrams are only for the 10Gb link period + * + * SYSTIMEH SYSTIMEL + * +--------------+ +--------------+ + * X540 | 32 | | 1 | 3 | 28 | + * *--------------+ +--------------+ + * \________ 36 bits ______/ fract + * + * +--------------+ +--------------+ + * 82599 | 32 | | 8 | 3 | 21 | + * *--------------+ +--------------+ + * \________ 43 bits ______/ fract + * + * The 36 bit X540 SYSTIME overflows every + * 2^36 * 10^-9 / 60 = 1.14 minutes or 69 seconds + * + * The 43 bit 82599 SYSTIME overflows every + * 2^43 * 10^-9 / 3600 = 2.4 hours + */ +#define IXGBE_INCVAL_10GB 0x66666666 +#define IXGBE_INCVAL_1GB 0x40000000 +#define IXGBE_INCVAL_100 0x50000000 + +#define IXGBE_INCVAL_SHIFT_10GB 28 +#define IXGBE_INCVAL_SHIFT_1GB 24 +#define IXGBE_INCVAL_SHIFT_100 21 + +#define IXGBE_INCVAL_SHIFT_82599 7 +#define IXGBE_INCPER_SHIFT_82599 24 +#define IXGBE_MAX_TIMEADJ_VALUE 0x7FFFFFFFFFFFFFFFULL + +#define IXGBE_OVERFLOW_PERIOD (HZ * 30) + +#ifndef NSECS_PER_SEC +#define NSECS_PER_SEC 1000000000ULL +#endif + +/** + * ixgbe_ptp_read - read raw cycle counter (to be used by time counter) + * @cc - the cyclecounter structure + * + * this function reads the cyclecounter registers and is called by the + * cyclecounter structure used to construct a ns counter from the + * arbitrary fixed point registers + */ +static cycle_t ixgbe_ptp_read(const struct cyclecounter *cc) +{ + struct ixgbe_adapter *adapter = + container_of(cc, struct ixgbe_adapter, cc); + struct ixgbe_hw *hw = &adapter->hw; + u64 stamp = 0; + + stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML); + stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32; + + return stamp; +} + +/** + * ixgbe_ptp_adjfreq + * @ptp - the ptp clock structure + * @ppb - parts per billion adjustment from base + * + * adjust the frequency of the ptp cycle counter by the + * indicated ppb from the base frequency. + */ +static int ixgbe_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) +{ + struct ixgbe_adapter *adapter = + container_of(ptp, struct ixgbe_adapter, ptp_caps); + struct ixgbe_hw *hw = &adapter->hw; + u64 freq; + u32 diff, incval; + int neg_adj = 0; + + if (ppb < 0) { + neg_adj = 1; + ppb = -ppb; + } + + smp_mb(); + incval = ACCESS_ONCE(adapter->base_incval); + + freq = incval; + freq *= ppb; + diff = div_u64(freq, 1000000000ULL); + + incval = neg_adj ? (incval - diff) : (incval + diff); + + switch (hw->mac.type) { + case ixgbe_mac_X540: + IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, incval); + break; + case ixgbe_mac_82599EB: + IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, + (1 << IXGBE_INCPER_SHIFT_82599) | + incval); + break; + default: + break; + } + + return 0; +} + +/** + * ixgbe_ptp_adjtime + * @ptp - the ptp clock structure + * @delta - offset to adjust the cycle counter by + * + * adjust the timer by resetting the timecounter structure. + */ +static int ixgbe_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) +{ + struct ixgbe_adapter *adapter = + container_of(ptp, struct ixgbe_adapter, ptp_caps); + unsigned long flags; + u64 now; + + spin_lock_irqsave(&adapter->tmreg_lock, flags); + + now = timecounter_read(&adapter->tc); + now += delta; + + /* reset the timecounter */ + timecounter_init(&adapter->tc, + &adapter->cc, + now); + + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + return 0; +} + +/** + * ixgbe_ptp_gettime + * @ptp - the ptp clock structure + * @ts - timespec structure to hold the current time value + * + * read the timecounter and return the correct value on ns, + * after converting it into a struct timespec. + */ +static int ixgbe_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) +{ + struct ixgbe_adapter *adapter = + container_of(ptp, struct ixgbe_adapter, ptp_caps); + u64 ns; + u32 remainder; + unsigned long flags; + + spin_lock_irqsave(&adapter->tmreg_lock, flags); + ns = timecounter_read(&adapter->tc); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + ts->tv_sec = div_u64_rem(ns, 1000000000ULL, &remainder); + ts->tv_nsec = remainder; + + return 0; +} + +/** + * ixgbe_ptp_settime + * @ptp - the ptp clock structure + * @ts - the timespec containing the new time for the cycle counter + * + * reset the timecounter to use a new base value instead of the kernel + * wall timer value. + */ +static int ixgbe_ptp_settime(struct ptp_clock_info *ptp, + const struct timespec *ts) +{ + struct ixgbe_adapter *adapter = + container_of(ptp, struct ixgbe_adapter, ptp_caps); + u64 ns; + unsigned long flags; + + ns = ts->tv_sec * 1000000000ULL; + ns += ts->tv_nsec; + + /* reset the timecounter */ + spin_lock_irqsave(&adapter->tmreg_lock, flags); + timecounter_init(&adapter->tc, &adapter->cc, ns); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + return 0; +} + +/** + * ixgbe_ptp_enable + * @ptp - the ptp clock structure + * @rq - the requested feature to change + * @on - whether to enable or disable the feature + * + * enable (or disable) ancillary features of the phc subsystem. + * our driver only supports the PPS feature on the X540 + */ +static int ixgbe_ptp_enable(struct ptp_clock_info *ptp, + struct ptp_clock_request *rq, int on) +{ + struct ixgbe_adapter *adapter = + container_of(ptp, struct ixgbe_adapter, ptp_caps); + + /** + * When PPS is enabled, unmask the interrupt for the ClockOut + * feature, so that the interrupt handler can send the PPS + * event when the clock SDP triggers. Clear mask when PPS is + * disabled + */ + if (rq->type == PTP_CLK_REQ_PPS) { + switch (adapter->hw.mac.type) { + case ixgbe_mac_X540: + if (on) + adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED; + else + adapter->flags2 &= + ~IXGBE_FLAG2_PTP_PPS_ENABLED; + return 0; + default: + break; + } + } + + return -ENOTSUPP; +} + +/** + * ixgbe_ptp_check_pps_event + * @adapter - the private adapter structure + * @eicr - the interrupt cause register value + * + * This function is called by the interrupt routine when checking for + * interrupts. It will check and handle a pps event. + */ +void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct ptp_clock_event event; + + event.type = PTP_CLOCK_PPS; + + /* Make sure ptp clock is valid, and PPS event enabled */ + if (!adapter->ptp_clock || + !(adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED)) + return; + + switch (hw->mac.type) { + case ixgbe_mac_X540: + if (eicr & IXGBE_EICR_TIMESYNC) + ptp_clock_event(adapter->ptp_clock, &event); + break; + default: + break; + } +} + +/** + * ixgbe_ptp_enable_sdp + * @hw - the hardware private structure + * @shift - the clock shift for calculating nanoseconds + * + * this function enables the clock out feature on the sdp0 for the + * X540 device. It will create a 1second periodic output that can be + * used as the PPS (via an interrupt). + * + * It calculates when the systime will be on an exact second, and then + * aligns the start of the PPS signal to that value. The shift is + * necessary because it can change based on the link speed. + */ +static void ixgbe_ptp_enable_sdp(struct ixgbe_hw *hw, int shift) +{ + u32 esdp, tsauxc, clktiml, clktimh, trgttiml, trgttimh; + u64 clock_edge = 0; + u32 rem; + + switch (hw->mac.type) { + case ixgbe_mac_X540: + esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + + /* + * enable the SDP0 pin as output, and connected to the native + * function for Timesync (ClockOut) + */ + esdp |= (IXGBE_ESDP_SDP0_DIR | + IXGBE_ESDP_SDP0_NATIVE); + + /* + * enable the Clock Out feature on SDP0, and allow interrupts + * to occur when the pin changes + */ + tsauxc = (IXGBE_TSAUXC_EN_CLK | + IXGBE_TSAUXC_SYNCLK | + IXGBE_TSAUXC_SDP0_INT); + + /* clock period (or pulse length) */ + clktiml = (u32)(NSECS_PER_SEC << shift); + clktimh = (u32)((NSECS_PER_SEC << shift) >> 32); + + clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML); + clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32; + + /* + * account for the fact that we can't do u64 division + * with remainder, by converting the clock values into + * nanoseconds first + */ + clock_edge >>= shift; + div_u64_rem(clock_edge, NSECS_PER_SEC, &rem); + clock_edge += (NSECS_PER_SEC - rem); + clock_edge <<= shift; + + /* specify the initial clock start time */ + trgttiml = (u32)clock_edge; + trgttimh = (u32)(clock_edge >> 32); + + IXGBE_WRITE_REG(hw, IXGBE_CLKTIML, clktiml); + IXGBE_WRITE_REG(hw, IXGBE_CLKTIMH, clktimh); + IXGBE_WRITE_REG(hw, IXGBE_TRGTTIML0, trgttiml); + IXGBE_WRITE_REG(hw, IXGBE_TRGTTIMH0, trgttimh); + + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc); + + IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EICR_TIMESYNC); + break; + default: + break; + } +} + +/** + * ixgbe_ptp_disable_sdp + * @hw - the private hardware structure + * + * this function disables the auxiliary SDP clock out feature + */ +static void ixgbe_ptp_disable_sdp(struct ixgbe_hw *hw) +{ + IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EICR_TIMESYNC); + IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0); +} + +/** + * ixgbe_ptp_overflow_check - delayed work to detect SYSTIME overflow + * @work: structure containing information about this work task + * + * this work function is scheduled to continue reading the timecounter + * in order to prevent missing when the system time registers wrap + * around. This needs to be run approximately twice a minute when no + * PTP activity is occurring. + */ +void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter) +{ + unsigned long elapsed_jiffies = adapter->last_overflow_check - jiffies; + struct timespec ts; + + if ((adapter->flags2 & IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED) && + (elapsed_jiffies >= IXGBE_OVERFLOW_PERIOD)) { + ixgbe_ptp_gettime(&adapter->ptp_caps, &ts); + adapter->last_overflow_check = jiffies; + } +} + +/** + * ixgbe_ptp_tx_hwtstamp - utility function which checks for TX time stamp + * @q_vector: structure containing interrupt and ring information + * @skb: particular skb to send timestamp with + * + * if the timestamp is valid, we convert it into the timecounter ns + * value, then store that result into the shhwtstamps structure which + * is passed up the network stack + */ +void ixgbe_ptp_tx_hwtstamp(struct ixgbe_q_vector *q_vector, + struct sk_buff *skb) +{ + struct ixgbe_adapter *adapter; + struct ixgbe_hw *hw; + struct skb_shared_hwtstamps shhwtstamps; + u64 regval = 0, ns; + u32 tsynctxctl; + unsigned long flags; + + /* we cannot process timestamps on a ring without a q_vector */ + if (!q_vector || !q_vector->adapter) + return; + + adapter = q_vector->adapter; + hw = &adapter->hw; + + tsynctxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL); + regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPL); + regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPH) << 32; + + /* + * if TX timestamp is not valid, exit after clearing the + * timestamp registers + */ + if (!(tsynctxctl & IXGBE_TSYNCTXCTL_VALID)) + return; + + spin_lock_irqsave(&adapter->tmreg_lock, flags); + ns = timecounter_cyc2time(&adapter->tc, regval); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + memset(&shhwtstamps, 0, sizeof(shhwtstamps)); + shhwtstamps.hwtstamp = ns_to_ktime(ns); + skb_tstamp_tx(skb, &shhwtstamps); +} + +/** + * ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp + * @q_vector: structure containing interrupt and ring information + * @skb: particular skb to send timestamp with + * + * if the timestamp is valid, we convert it into the timecounter ns + * value, then store that result into the shhwtstamps structure which + * is passed up the network stack + */ +void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, + struct sk_buff *skb) +{ + struct ixgbe_adapter *adapter; + struct ixgbe_hw *hw; + struct skb_shared_hwtstamps *shhwtstamps; + u64 regval = 0, ns; + u32 tsyncrxctl; + unsigned long flags; + + /* we cannot process timestamps on a ring without a q_vector */ + if (!q_vector || !q_vector->adapter) + return; + + adapter = q_vector->adapter; + hw = &adapter->hw; + + tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); + regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL); + regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32; + + /* + * If this bit is set, then the RX registers contain the time stamp. No + * other packet will be time stamped until we read these registers, so + * read the registers to make them available again. Because only one + * packet can be time stamped at a time, we know that the register + * values must belong to this one here and therefore we don't need to + * compare any of the additional attributes stored for it. + * + * If nothing went wrong, then it should have a skb_shared_tx that we + * can turn into a skb_shared_hwtstamps. + */ + if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID)) + return; + + spin_lock_irqsave(&adapter->tmreg_lock, flags); + ns = timecounter_cyc2time(&adapter->tc, regval); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + shhwtstamps = skb_hwtstamps(skb); + shhwtstamps->hwtstamp = ns_to_ktime(ns); +} + +/** + * ixgbe_ptp_hwtstamp_ioctl - control hardware time stamping + * @adapter: pointer to adapter struct + * @ifreq: ioctl data + * @cmd: particular ioctl requested + * + * Outgoing time stamping can be enabled and disabled. Play nice and + * disable it when requested, although it shouldn't case any overhead + * when no packet needs it. At most one packet in the queue may be + * marked for time stamping, otherwise it would be impossible to tell + * for sure to which packet the hardware time stamp belongs. + * + * Incoming time stamping has to be configured via the hardware + * filters. Not all combinations are supported, in particular event + * type has to be specified. Matching the kind of event packet is + * not supported, with the exception of "all V2 events regardless of + * level 2 or 4". + */ +int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, + struct ifreq *ifr, int cmd) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct hwtstamp_config config; + u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED; + u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED; + u32 tsync_rx_mtrl = 0; + bool is_l4 = false; + bool is_l2 = false; + u32 regval; + + if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) + return -EFAULT; + + /* reserved for future extensions */ + if (config.flags) + return -EINVAL; + + switch (config.tx_type) { + case HWTSTAMP_TX_OFF: + tsync_tx_ctl = 0; + case HWTSTAMP_TX_ON: + break; + default: + return -ERANGE; + } + + switch (config.rx_filter) { + case HWTSTAMP_FILTER_NONE: + tsync_rx_ctl = 0; + break; + case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: + tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; + tsync_rx_mtrl = IXGBE_RXMTRL_V1_SYNC_MSG; + is_l4 = true; + break; + case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: + tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; + tsync_rx_mtrl = IXGBE_RXMTRL_V1_DELAY_REQ_MSG; + is_l4 = true; + break; + case HWTSTAMP_FILTER_PTP_V2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: + tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2; + tsync_rx_mtrl = IXGBE_RXMTRL_V2_SYNC_MSG; + is_l2 = true; + is_l4 = true; + config.rx_filter = HWTSTAMP_FILTER_SOME; + break; + case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: + tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2; + tsync_rx_mtrl = IXGBE_RXMTRL_V2_DELAY_REQ_MSG; + is_l2 = true; + is_l4 = true; + config.rx_filter = HWTSTAMP_FILTER_SOME; + break; + case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_EVENT: + tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2; + config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; + is_l2 = true; + is_l4 = true; + break; + case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: + case HWTSTAMP_FILTER_ALL: + default: + /* + * register RXMTRL must be set, therefore it is not + * possible to time stamp both V1 Sync and Delay_Req messages + * and hardware does not support timestamping all packets + * => return error + */ + return -ERANGE; + } + + if (hw->mac.type == ixgbe_mac_82598EB) { + if (tsync_rx_ctl | tsync_tx_ctl) + return -ERANGE; + return 0; + } + + /* define ethertype filter for timestamped packets */ + if (is_l2) + IXGBE_WRITE_REG(hw, IXGBE_ETQF(3), + (IXGBE_ETQF_FILTER_EN | /* enable filter */ + IXGBE_ETQF_1588 | /* enable timestamping */ + ETH_P_1588)); /* 1588 eth protocol type */ + else + IXGBE_WRITE_REG(hw, IXGBE_ETQF(3), 0); + +#define PTP_PORT 319 + /* L4 Queue Filter[3]: filter by destination port and protocol */ + if (is_l4) { + u32 ftqf = (IXGBE_FTQF_PROTOCOL_UDP /* UDP */ + | IXGBE_FTQF_POOL_MASK_EN /* Pool not compared */ + | IXGBE_FTQF_QUEUE_ENABLE); + + ftqf |= ((IXGBE_FTQF_PROTOCOL_COMP_MASK /* protocol check */ + & IXGBE_FTQF_DEST_PORT_MASK /* dest check */ + & IXGBE_FTQF_SOURCE_PORT_MASK) /* source check */ + << IXGBE_FTQF_5TUPLE_MASK_SHIFT); + + IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(3), + (3 << IXGBE_IMIR_RX_QUEUE_SHIFT_82599 | + IXGBE_IMIR_SIZE_BP_82599)); + + /* enable port check */ + IXGBE_WRITE_REG(hw, IXGBE_SDPQF(3), + (htons(PTP_PORT) | + htons(PTP_PORT) << 16)); + + IXGBE_WRITE_REG(hw, IXGBE_FTQF(3), ftqf); + + tsync_rx_mtrl |= PTP_PORT << 16; + } else { + IXGBE_WRITE_REG(hw, IXGBE_FTQF(3), 0); + } + + /* enable/disable TX */ + regval = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL); + regval &= ~IXGBE_TSYNCTXCTL_ENABLED; + regval |= tsync_tx_ctl; + IXGBE_WRITE_REG(hw, IXGBE_TSYNCTXCTL, regval); + + /* enable/disable RX */ + regval = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); + regval &= ~(IXGBE_TSYNCRXCTL_ENABLED | IXGBE_TSYNCRXCTL_TYPE_MASK); + regval |= tsync_rx_ctl; + IXGBE_WRITE_REG(hw, IXGBE_TSYNCRXCTL, regval); + + /* define which PTP packets are time stamped */ + IXGBE_WRITE_REG(hw, IXGBE_RXMTRL, tsync_rx_mtrl); + + IXGBE_WRITE_FLUSH(hw); + + /* clear TX/RX time stamp registers, just to be sure */ + regval = IXGBE_READ_REG(hw, IXGBE_TXSTMPH); + regval = IXGBE_READ_REG(hw, IXGBE_RXSTMPH); + + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? + -EFAULT : 0; +} + +/** + * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw + * @adapter - pointer to the adapter structure + * + * this function initializes the timecounter and cyclecounter + * structures for use in generated a ns counter from the arbitrary + * fixed point cycles registers in the hardware. + * + * A change in link speed impacts the frequency of the DMA clock on + * the device, which is used to generate the cycle counter + * registers. Therefor this function is called whenever the link speed + * changes. + * + * This function also turns on the SDP pin for clock out feature (X540 + * only), because this is where the shift is first calculated. + */ +void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 incval = 0; + u32 shift = 0; + u32 cycle_speed; + unsigned long flags; + + /** + * Determine what speed we need to set the cyclecounter + * for. It should be different for 100Mb, 1Gb, and 10Gb. Treat + * unknown speeds as 10Gb. (Hence why we can't just copy the + * link_speed. + */ + switch (adapter->link_speed) { + case IXGBE_LINK_SPEED_100_FULL: + case IXGBE_LINK_SPEED_1GB_FULL: + case IXGBE_LINK_SPEED_10GB_FULL: + cycle_speed = adapter->link_speed; + break; + default: + /* cycle speed should be 10Gb when there is no link */ + cycle_speed = IXGBE_LINK_SPEED_10GB_FULL; + break; + } + + /* Bail if the cycle speed didn't change */ + if (adapter->cycle_speed == cycle_speed) + return; + + /* disable the SDP clock out */ + ixgbe_ptp_disable_sdp(hw); + + /** + * Scale the NIC cycle counter by a large factor so that + * relatively small corrections to the frequency can be added + * or subtracted. The drawbacks of a large factor include + * (a) the clock register overflows more quickly, (b) the cycle + * counter structure must be able to convert the systime value + * to nanoseconds using only a multiplier and a right-shift, + * and (c) the value must fit within the timinca register space + * => math based on internal DMA clock rate and available bits + */ + switch (cycle_speed) { + case IXGBE_LINK_SPEED_100_FULL: + incval = IXGBE_INCVAL_100; + shift = IXGBE_INCVAL_SHIFT_100; + break; + case IXGBE_LINK_SPEED_1GB_FULL: + incval = IXGBE_INCVAL_1GB; + shift = IXGBE_INCVAL_SHIFT_1GB; + break; + case IXGBE_LINK_SPEED_10GB_FULL: + incval = IXGBE_INCVAL_10GB; + shift = IXGBE_INCVAL_SHIFT_10GB; + break; + } + + /** + * Modify the calculated values to fit within the correct + * number of bits specified by the hardware. The 82599 doesn't + * have the same space as the X540, so bitshift the calculated + * values to fit. + */ + switch (hw->mac.type) { + case ixgbe_mac_X540: + IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, incval); + break; + case ixgbe_mac_82599EB: + incval >>= IXGBE_INCVAL_SHIFT_82599; + shift -= IXGBE_INCVAL_SHIFT_82599; + IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, + (1 << IXGBE_INCPER_SHIFT_82599) | + incval); + break; + default: + /* other devices aren't supported */ + return; + } + + /* reset the system time registers */ + IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0x00000000); + IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000); + IXGBE_WRITE_FLUSH(hw); + + /* now that the shift has been calculated and the systime + * registers reset, (re-)enable the Clock out feature*/ + ixgbe_ptp_enable_sdp(hw, shift); + + /* store the new cycle speed */ + adapter->cycle_speed = cycle_speed; + + ACCESS_ONCE(adapter->base_incval) = incval; + smp_mb(); + + /* grab the ptp lock */ + spin_lock_irqsave(&adapter->tmreg_lock, flags); + + memset(&adapter->cc, 0, sizeof(adapter->cc)); + adapter->cc.read = ixgbe_ptp_read; + adapter->cc.mask = CLOCKSOURCE_MASK(64); + adapter->cc.shift = shift; + adapter->cc.mult = 1; + + /* reset the ns time counter */ + timecounter_init(&adapter->tc, &adapter->cc, + ktime_to_ns(ktime_get_real())); + + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); +} + +/** + * ixgbe_ptp_init + * @adapter - the ixgbe private adapter structure + * + * This function performs the required steps for enabling ptp + * support. If ptp support has already been loaded it simply calls the + * cyclecounter init routine and exits. + */ +void ixgbe_ptp_init(struct ixgbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_X540: + snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr); + adapter->ptp_caps.owner = THIS_MODULE; + adapter->ptp_caps.max_adj = 250000000; + adapter->ptp_caps.n_alarm = 0; + adapter->ptp_caps.n_ext_ts = 0; + adapter->ptp_caps.n_per_out = 0; + adapter->ptp_caps.pps = 1; + adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq; + adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; + adapter->ptp_caps.gettime = ixgbe_ptp_gettime; + adapter->ptp_caps.settime = ixgbe_ptp_settime; + adapter->ptp_caps.enable = ixgbe_ptp_enable; + break; + case ixgbe_mac_82599EB: + snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr); + adapter->ptp_caps.owner = THIS_MODULE; + adapter->ptp_caps.max_adj = 250000000; + adapter->ptp_caps.n_alarm = 0; + adapter->ptp_caps.n_ext_ts = 0; + adapter->ptp_caps.n_per_out = 0; + adapter->ptp_caps.pps = 0; + adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq; + adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; + adapter->ptp_caps.gettime = ixgbe_ptp_gettime; + adapter->ptp_caps.settime = ixgbe_ptp_settime; + adapter->ptp_caps.enable = ixgbe_ptp_enable; + break; + default: + adapter->ptp_clock = NULL; + return; + } + + spin_lock_init(&adapter->tmreg_lock); + + ixgbe_ptp_start_cyclecounter(adapter); + + /* (Re)start the overflow check */ + adapter->flags2 |= IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED; + + adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps); + if (IS_ERR(adapter->ptp_clock)) { + adapter->ptp_clock = NULL; + e_dev_err("ptp_clock_register failed\n"); + } else + e_dev_info("registered PHC device on %s\n", netdev->name); + + return; +} + +/** + * ixgbe_ptp_stop - disable ptp device and stop the overflow check + * @adapter: pointer to adapter struct + * + * this function stops the ptp support, and cancels the delayed work. + */ +void ixgbe_ptp_stop(struct ixgbe_adapter *adapter) +{ + ixgbe_ptp_disable_sdp(&adapter->hw); + + /* stop the overflow check task */ + adapter->flags2 &= ~IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED; + + if (adapter->ptp_clock) { + ptp_clock_unregister(adapter->ptp_clock); + adapter->ptp_clock = NULL; + e_dev_info("removed PHC on %s\n", + adapter->netdev->name); + } +}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 3985637..2d971d1 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -544,13 +544,18 @@ retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf); - if (retval) + if (retval) { pr_err("Error receiving message from VF\n"); + return retval; + } /* this is a message we already processed, do nothing */ if (msgbuf[0] & (IXGBE_VT_MSGTYPE_ACK | IXGBE_VT_MSGTYPE_NACK)) return retval; + /* flush the ack before we write any messages back */ + IXGBE_WRITE_FLUSH(hw); + /* * until the vf completes a virtual function reset it should not be * allowed to start any configuration. @@ -635,14 +640,14 @@ } break; case IXGBE_VF_SET_MACVLAN: - if (adapter->vfinfo[vf].pf_set_mac) { + index = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> + IXGBE_VT_MSGINFO_SHIFT; + if (adapter->vfinfo[vf].pf_set_mac && index > 0) { e_warn(drv, "VF %d requested MACVLAN filter but is " "administratively denied\n", vf); retval = -1; break; } - index = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> - IXGBE_VT_MSGINFO_SHIFT; /* * If the VF is allowed to set MAC filters then turn off * anti-spoofing to avoid false positives. An index
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c index f81c166..1d80b1c 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c
@@ -37,12 +37,7 @@ #include <linux/netdevice.h> #include <linux/hwmon.h> -/* - * This file provides a sysfs interface to export information from the - * driver. The information presented is READ-ONLY. - */ #ifdef CONFIG_IXGBE_HWMON - /* hwmon callback functions */ static ssize_t ixgbe_hwmon_show_location(struct device *dev, struct device_attribute *attr, @@ -162,17 +157,13 @@ return rc; } -#endif /* CONFIG_IXGBE_HWMON */ static void ixgbe_sysfs_del_adapter(struct ixgbe_adapter *adapter) { -#ifdef CONFIG_IXGBE_HWMON int i; -#endif /* CONFIG_IXGBE_HWMON */ if (adapter == NULL) return; -#ifdef CONFIG_IXGBE_HWMON for (i = 0; i < adapter->ixgbe_hwmon_buff.n_hwmon; i++) { device_remove_file(&adapter->pdev->dev, @@ -183,12 +174,6 @@ if (adapter->ixgbe_hwmon_buff.device) hwmon_device_unregister(adapter->ixgbe_hwmon_buff.device); -#endif /* CONFIG_IXGBE_HWMON */ - - if (adapter->info_kobj != NULL) { - kobject_put(adapter->info_kobj); - adapter->info_kobj = NULL; - } } /* called from ixgbe_main.c */ @@ -200,32 +185,19 @@ /* called from ixgbe_main.c */ int ixgbe_sysfs_init(struct ixgbe_adapter *adapter) { -#ifdef CONFIG_IXGBE_HWMON struct hwmon_buff *ixgbe_hwmon = &adapter->ixgbe_hwmon_buff; unsigned int i; int n_attrs; -#endif /* CONFIG_IXGBE_HWMON */ - struct net_device *netdev = adapter->netdev; int rc = 0; - /* create info kobj and attribute listings in kobj */ - adapter->info_kobj = kobject_create_and_add("info", &netdev->dev.kobj); - if (adapter->info_kobj == NULL) { - rc = -ENOMEM; - goto err; - } - -#ifdef CONFIG_IXGBE_HWMON /* If this method isn't defined we don't support thermals */ if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL) { - rc = -EPERM; - goto err; + goto exit; } /* Don't create thermal hwmon interface if no sensors present */ - rc = adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw); - if (rc) - goto err; + if (adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw)) + goto exit; /* * Allocation space for max attributs @@ -261,7 +233,6 @@ if (rc) goto err; } -#endif /* CONFIG_IXGBE_HWMON */ goto exit; @@ -270,4 +241,5 @@ exit: return rc; } +#endif /* CONFIG_IXGBE_HWMON */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index 5e64c77..204848d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -824,6 +824,8 @@ #define IXGBE_TRGTTIMH0 0x08C28 /* Target Time Register 0 High - RW */ #define IXGBE_TRGTTIML1 0x08C2C /* Target Time Register 1 Low - RW */ #define IXGBE_TRGTTIMH1 0x08C30 /* Target Time Register 1 High - RW */ +#define IXGBE_CLKTIML 0x08C34 /* Clock Out Time Register Low - RW */ +#define IXGBE_CLKTIMH 0x08C38 /* Clock Out Time Register High - RW */ #define IXGBE_FREQOUT0 0x08C34 /* Frequency Out 0 Control register - RW */ #define IXGBE_FREQOUT1 0x08C38 /* Frequency Out 1 Control register - RW */ #define IXGBE_AUXSTMPL0 0x08C3C /* Auxiliary Time Stamp 0 register Low - RO */ @@ -1309,6 +1311,7 @@ #define IXGBE_EICR_LINKSEC 0x00200000 /* PN Threshold */ #define IXGBE_EICR_MNG 0x00400000 /* Manageability Event Interrupt */ #define IXGBE_EICR_TS 0x00800000 /* Thermal Sensor Event */ +#define IXGBE_EICR_TIMESYNC 0x01000000 /* Timesync Event */ #define IXGBE_EICR_GPI_SDP0 0x01000000 /* Gen Purpose Interrupt on SDP0 */ #define IXGBE_EICR_GPI_SDP1 0x02000000 /* Gen Purpose Interrupt on SDP1 */ #define IXGBE_EICR_GPI_SDP2 0x04000000 /* Gen Purpose Interrupt on SDP2 */ @@ -1326,6 +1329,7 @@ #define IXGBE_EICS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */ #define IXGBE_EICS_LSC IXGBE_EICR_LSC /* Link Status Change */ #define IXGBE_EICS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ +#define IXGBE_EICS_TIMESYNC IXGBE_EICR_TIMESYNC /* Timesync Event */ #define IXGBE_EICS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */ #define IXGBE_EICS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */ #define IXGBE_EICS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */ @@ -1344,6 +1348,7 @@ #define IXGBE_EIMS_LSC IXGBE_EICR_LSC /* Link Status Change */ #define IXGBE_EIMS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ #define IXGBE_EIMS_TS IXGBE_EICR_TS /* Thermel Sensor Event */ +#define IXGBE_EIMS_TIMESYNC IXGBE_EICR_TIMESYNC /* Timesync Event */ #define IXGBE_EIMS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */ #define IXGBE_EIMS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */ #define IXGBE_EIMS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */ @@ -1361,6 +1366,7 @@ #define IXGBE_EIMC_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */ #define IXGBE_EIMC_LSC IXGBE_EICR_LSC /* Link Status Change */ #define IXGBE_EIMC_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ +#define IXGBE_EIMC_TIMESYNC IXGBE_EICR_TIMESYNC /* Timesync Event */ #define IXGBE_EIMC_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */ #define IXGBE_EIMC_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */ #define IXGBE_EIMC_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */ @@ -1501,8 +1507,10 @@ #define IXGBE_ESDP_SDP4 0x00000010 /* SDP4 Data Value */ #define IXGBE_ESDP_SDP5 0x00000020 /* SDP5 Data Value */ #define IXGBE_ESDP_SDP6 0x00000040 /* SDP6 Data Value */ +#define IXGBE_ESDP_SDP0_DIR 0x00000100 /* SDP0 IO direction */ #define IXGBE_ESDP_SDP4_DIR 0x00000004 /* SDP4 IO direction */ #define IXGBE_ESDP_SDP5_DIR 0x00002000 /* SDP5 IO direction */ +#define IXGBE_ESDP_SDP0_NATIVE 0x00010000 /* SDP0 Native Function */ /* LEDCTL Bit Masks */ #define IXGBE_LED_IVRT_BASE 0x00000040 @@ -1879,6 +1887,40 @@ #define IXGBE_RXDCTL_RLPML_EN 0x00008000 #define IXGBE_RXDCTL_VME 0x40000000 /* VLAN mode enable */ +#define IXGBE_TSAUXC_EN_CLK 0x00000004 +#define IXGBE_TSAUXC_SYNCLK 0x00000008 +#define IXGBE_TSAUXC_SDP0_INT 0x00000040 + +#define IXGBE_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */ +#define IXGBE_TSYNCTXCTL_ENABLED 0x00000010 /* Tx timestamping enabled */ + +#define IXGBE_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */ +#define IXGBE_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */ +#define IXGBE_TSYNCRXCTL_TYPE_L2_V2 0x00 +#define IXGBE_TSYNCRXCTL_TYPE_L4_V1 0x02 +#define IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2 0x04 +#define IXGBE_TSYNCRXCTL_TYPE_EVENT_V2 0x0A +#define IXGBE_TSYNCRXCTL_ENABLED 0x00000010 /* Rx Timestamping enabled */ + +#define IXGBE_RXMTRL_V1_CTRLT_MASK 0x000000FF +#define IXGBE_RXMTRL_V1_SYNC_MSG 0x00 +#define IXGBE_RXMTRL_V1_DELAY_REQ_MSG 0x01 +#define IXGBE_RXMTRL_V1_FOLLOWUP_MSG 0x02 +#define IXGBE_RXMTRL_V1_DELAY_RESP_MSG 0x03 +#define IXGBE_RXMTRL_V1_MGMT_MSG 0x04 + +#define IXGBE_RXMTRL_V2_MSGID_MASK 0x0000FF00 +#define IXGBE_RXMTRL_V2_SYNC_MSG 0x0000 +#define IXGBE_RXMTRL_V2_DELAY_REQ_MSG 0x0100 +#define IXGBE_RXMTRL_V2_PDELAY_REQ_MSG 0x0200 +#define IXGBE_RXMTRL_V2_PDELAY_RESP_MSG 0x0300 +#define IXGBE_RXMTRL_V2_FOLLOWUP_MSG 0x0800 +#define IXGBE_RXMTRL_V2_DELAY_RESP_MSG 0x0900 +#define IXGBE_RXMTRL_V2_PDELAY_FOLLOWUP_MSG 0x0A00 +#define IXGBE_RXMTRL_V2_ANNOUNCE_MSG 0x0B00 +#define IXGBE_RXMTRL_V2_SIGNALING_MSG 0x0C00 +#define IXGBE_RXMTRL_V2_MGMT_MSG 0x0D00 + #define IXGBE_FCTRL_SBP 0x00000002 /* Store Bad Packet */ #define IXGBE_FCTRL_MPE 0x00000100 /* Multicast Promiscuous Ena*/ #define IXGBE_FCTRL_UPE 0x00000200 /* Unicast Promiscuous Ena */ @@ -2008,6 +2050,7 @@ #define IXGBE_RXDADV_STAT_FCSTAT_NODDP 0x00000010 /* 01: Ctxt w/o DDP */ #define IXGBE_RXDADV_STAT_FCSTAT_FCPRSP 0x00000020 /* 10: Recv. FCP_RSP */ #define IXGBE_RXDADV_STAT_FCSTAT_DDP 0x00000030 /* 11: Ctxt w/ DDP */ +#define IXGBE_RXDADV_STAT_TS 0x00010000 /* IEEE 1588 Time Stamp */ /* PSRTYPE bit definitions */ #define IXGBE_PSRTYPE_TCPHDR 0x00000010 @@ -2285,6 +2328,7 @@ /* Adv Transmit Descriptor Config Masks */ #define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buf length(bytes) */ #define IXGBE_ADVTXD_MAC_LINKSEC 0x00040000 /* Insert LinkSec */ +#define IXGBE_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE 1588 Time Stamp */ #define IXGBE_ADVTXD_IPSEC_SA_INDEX_MASK 0x000003FF /* IPSec SA index */ #define IXGBE_ADVTXD_IPSEC_ESP_LEN_MASK 0x000001FF /* IPSec ESP length */ #define IXGBE_ADVTXD_DTYP_MASK 0x00F00000 /* DTYP mask */ @@ -2573,9 +2617,6 @@ ixgbe_fc_rx_pause, ixgbe_fc_tx_pause, ixgbe_fc_full, -#ifdef CONFIG_DCB - ixgbe_fc_pfc, -#endif ixgbe_fc_default };
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 773c70e..1bcead1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -1254,7 +1254,6 @@ struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state; u32 reply; - u32 slave_status = 0; u8 is_going_down = 0; int i; @@ -1274,10 +1273,8 @@ } /*check if we are in the middle of FLR process, if so return "retry" status to the slave*/ - if (MLX4_COMM_CMD_FLR == slave_state[slave].last_cmd) { - slave_status = MLX4_DELAY_RESET_SLAVE; + if (MLX4_COMM_CMD_FLR == slave_state[slave].last_cmd) goto inform_slave_state; - } /* write the version in the event field */ reply |= mlx4_comm_get_version(); @@ -1557,7 +1554,7 @@ return 0; err_resource: - mlx4_free_resource_tracker(dev); + mlx4_free_resource_tracker(dev, RES_TR_FREE_ALL); err_thread: flush_workqueue(priv->mfunc.master.comm_wq); destroy_workqueue(priv->mfunc.master.comm_wq);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c index 346fdb2..988b242 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c
@@ -101,6 +101,8 @@ int i; params->udp_rss = udp_rss; + params->num_tx_rings_p_up = min_t(int, num_online_cpus(), + MLX4_EN_MAX_TX_RING_P_UP); if (params->udp_rss && !(mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_UDP_RSS)) { mlx4_warn(mdev, "UDP RSS is not supported on this device.\n"); @@ -113,8 +115,8 @@ params->prof[i].tx_ppp = pfctx; params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE; params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE; - params->prof[i].tx_ring_num = MLX4_EN_NUM_TX_RINGS + - MLX4_EN_NUM_PPP_RINGS; + params->prof[i].tx_ring_num = params->num_tx_rings_p_up * + MLX4_EN_NUM_UP; params->prof[i].rss_rings = 0; }
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index eaa8fad..926d8aa 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -47,9 +47,22 @@ static int mlx4_en_setup_tc(struct net_device *dev, u8 up) { - if (up != MLX4_EN_NUM_UP) + struct mlx4_en_priv *priv = netdev_priv(dev); + int i; + unsigned int q, offset = 0; + + if (up && up != MLX4_EN_NUM_UP) return -EINVAL; + netdev_set_num_tc(dev, up); + + /* Partition Tx queues evenly amongst UP's */ + q = priv->tx_ring_num / up; + for (i = 0; i < up; i++) { + netdev_set_tc_queue(dev, i, q, offset); + offset += q; + } + return 0; } @@ -661,7 +674,7 @@ /* Configure ring */ tx_ring = &priv->tx_ring[i]; err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn, - max(0, i - MLX4_EN_NUM_TX_RINGS)); + i / priv->mdev->profile.num_tx_rings_p_up); if (err) { en_err(priv, "Failed allocating Tx ring\n"); mlx4_en_deactivate_cq(priv, cq); @@ -986,6 +999,9 @@ mlx4_en_free_resources(priv); + kfree(priv->tx_ring); + kfree(priv->tx_cq); + free_netdev(dev); } @@ -1091,6 +1107,18 @@ priv->ctrl_flags = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE | MLX4_WQE_CTRL_SOLICITED); priv->tx_ring_num = prof->tx_ring_num; + priv->tx_ring = kzalloc(sizeof(struct mlx4_en_tx_ring) * + priv->tx_ring_num, GFP_KERNEL); + if (!priv->tx_ring) { + err = -ENOMEM; + goto out; + } + priv->tx_cq = kzalloc(sizeof(struct mlx4_en_cq) * priv->tx_ring_num, + GFP_KERNEL); + if (!priv->tx_cq) { + err = -ENOMEM; + goto out; + } priv->rx_ring_num = prof->rx_ring_num; priv->mac_index = -1; priv->msg_enable = MLX4_EN_MSG_LEVEL; @@ -1138,15 +1166,6 @@ netif_set_real_num_tx_queues(dev, priv->tx_ring_num); netif_set_real_num_rx_queues(dev, priv->rx_ring_num); - netdev_set_num_tc(dev, MLX4_EN_NUM_UP); - - /* First 9 rings are for UP 0 */ - netdev_set_tc_queue(dev, 0, MLX4_EN_NUM_TX_RINGS + 1, 0); - - /* Partition Tx queues evenly amongst UP's 1-7 */ - for (i = 1; i < MLX4_EN_NUM_UP; i++) - netdev_set_tc_queue(dev, i, 1, MLX4_EN_NUM_TX_RINGS + i); - SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops); /* Set defualt MAC */
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 9a38483..019d856 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -525,14 +525,17 @@ u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb) { - u16 vlan_tag = 0; + struct mlx4_en_priv *priv = netdev_priv(dev); + u16 rings_p_up = priv->mdev->profile.num_tx_rings_p_up; + u8 up = 0; - if (vlan_tx_tag_present(skb)) { - vlan_tag = vlan_tx_tag_get(skb); - return MLX4_EN_NUM_TX_RINGS + (vlan_tag >> 13); - } + if (dev->num_tc) + return skb_tx_hash(dev, skb); - return skb_tx_hash(dev, skb); + if (vlan_tx_tag_present(skb)) + up = vlan_tx_tag_get(skb) >> VLAN_PRIO_SHIFT; + + return __skb_tx_hash(dev, skb, rings_p_up) + up * rings_p_up; } static void mlx4_bf_copy(void __iomem *dst, unsigned long *src, unsigned bytecnt)
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 2a02ba5..24429a9 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -1164,9 +1164,8 @@ MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); if (err) return err; - priv->mfunc.master.slave_state[slave].init_port_mask |= - (1 << port); } + priv->mfunc.master.slave_state[slave].init_port_mask |= (1 << port); ++priv->mfunc.master.init_port_ref[port]; return 0; }
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 8bb05b4..984ace4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -1306,7 +1306,7 @@ mlx4_bitmap_cleanup(&mlx4_priv(dev)->counters_bitmap); } -int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx) +int __mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx) { struct mlx4_priv *priv = mlx4_priv(dev); @@ -1319,13 +1319,44 @@ return 0; } + +int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx) +{ + u64 out_param; + int err; + + if (mlx4_is_mfunc(dev)) { + err = mlx4_cmd_imm(dev, 0, &out_param, RES_COUNTER, + RES_OP_RESERVE, MLX4_CMD_ALLOC_RES, + MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); + if (!err) + *idx = get_param_l(&out_param); + + return err; + } + return __mlx4_counter_alloc(dev, idx); +} EXPORT_SYMBOL_GPL(mlx4_counter_alloc); -void mlx4_counter_free(struct mlx4_dev *dev, u32 idx) +void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx) { mlx4_bitmap_free(&mlx4_priv(dev)->counters_bitmap, idx); return; } + +void mlx4_counter_free(struct mlx4_dev *dev, u32 idx) +{ + u64 in_param; + + if (mlx4_is_mfunc(dev)) { + set_param_l(&in_param, idx); + mlx4_cmd(dev, in_param, RES_COUNTER, RES_OP_RESERVE, + MLX4_CMD_FREE_RES, MLX4_CMD_TIME_CLASS_A, + MLX4_CMD_WRAPPED); + return; + } + __mlx4_counter_free(dev, idx); +} EXPORT_SYMBOL_GPL(mlx4_counter_free); static int mlx4_setup_hca(struct mlx4_dev *dev) @@ -1865,7 +1896,6 @@ mlx4_err(dev, "Failed to enable sriov," "continuing without sriov enabled" " (err = %d).\n", err); - num_vfs = 0; err = 0; } else { mlx4_warn(dev, "Running in master mode\n"); @@ -2022,7 +2052,7 @@ mlx4_cmd_cleanup(dev); err_sriov: - if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV)) + if (dev->flags & MLX4_FLAG_SRIOV) pci_disable_sriov(pdev); err_rel_own: @@ -2070,6 +2100,10 @@ mlx4_CLOSE_PORT(dev, p); } + if (mlx4_is_master(dev)) + mlx4_free_resource_tracker(dev, + RES_TR_FREE_SLAVES_ONLY); + mlx4_cleanup_counters_table(dev); mlx4_cleanup_mcg_table(dev); mlx4_cleanup_qp_table(dev); @@ -2082,7 +2116,8 @@ mlx4_cleanup_pd_table(dev); if (mlx4_is_master(dev)) - mlx4_free_resource_tracker(dev); + mlx4_free_resource_tracker(dev, + RES_TR_FREE_STRUCTS_ONLY); iounmap(priv->kar); mlx4_uar_free(dev, &priv->driver_uar); @@ -2099,7 +2134,7 @@ if (dev->flags & MLX4_FLAG_MSI_X) pci_disable_msix(pdev); - if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV)) { + if (dev->flags & MLX4_FLAG_SRIOV) { mlx4_warn(dev, "Disabling sriov\n"); pci_disable_sriov(pdev); }
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index 4799e82..f4a8f98 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -357,7 +357,6 @@ u32 prot; int i; bool found; - int last_index; int err; struct mlx4_priv *priv = mlx4_priv(dev); @@ -419,7 +418,6 @@ if (err) goto out_mailbox; } - last_index = entry->index; } /* add the new qpn to list of promisc qps */
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index cd56f1a..86b6e5a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -146,6 +146,11 @@ RES_OP_MAP_ICM, }; +enum mlx4_res_tracker_free_type { + RES_TR_FREE_ALL, + RES_TR_FREE_SLAVES_ONLY, + RES_TR_FREE_STRUCTS_ONLY, +}; /* *Virtual HCR structures. @@ -871,6 +876,10 @@ int __mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac); int __mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt, int start_index, int npages, u64 *page_list); +int __mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx); +void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx); +int __mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn); +void __mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn); void mlx4_start_catas_poll(struct mlx4_dev *dev); void mlx4_stop_catas_poll(struct mlx4_dev *dev); @@ -1027,7 +1036,8 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave_id); int mlx4_init_resource_tracker(struct mlx4_dev *dev); -void mlx4_free_resource_tracker(struct mlx4_dev *dev); +void mlx4_free_resource_tracker(struct mlx4_dev *dev, + enum mlx4_res_tracker_free_type type); int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr,
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 5d87637..6ae3509 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -111,9 +111,7 @@ #define MLX4_EN_MIN_TX_SIZE (4096 / TXBB_SIZE) #define MLX4_EN_SMALL_PKT_SIZE 64 -#define MLX4_EN_NUM_TX_RINGS 8 -#define MLX4_EN_NUM_PPP_RINGS 8 -#define MAX_TX_RINGS (MLX4_EN_NUM_TX_RINGS + MLX4_EN_NUM_PPP_RINGS) +#define MLX4_EN_MAX_TX_RING_P_UP 32 #define MLX4_EN_NUM_UP 8 #define MLX4_EN_DEF_TX_RING_SIZE 512 #define MLX4_EN_DEF_RX_RING_SIZE 1024 @@ -339,6 +337,7 @@ u32 active_ports; u32 small_pkt_int; u8 no_reset; + u8 num_tx_rings_p_up; struct mlx4_en_port_profile prof[MLX4_MAX_PORTS + 1]; }; @@ -477,9 +476,9 @@ u16 num_frags; u16 log_rx_info; - struct mlx4_en_tx_ring tx_ring[MAX_TX_RINGS]; + struct mlx4_en_tx_ring *tx_ring; struct mlx4_en_rx_ring rx_ring[MAX_RX_RINGS]; - struct mlx4_en_cq tx_cq[MAX_TX_RINGS]; + struct mlx4_en_cq *tx_cq; struct mlx4_en_cq rx_cq[MAX_RX_RINGS]; struct work_struct mcast_task; struct work_struct mac_task;
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index fe2ac84..af55b7c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c
@@ -788,7 +788,6 @@ int max_maps, u8 page_shift, struct mlx4_fmr *fmr) { struct mlx4_priv *priv = mlx4_priv(dev); - u64 mtt_offset; int err = -ENOMEM; if (max_maps > dev->caps.max_fmr_maps) @@ -811,8 +810,6 @@ if (err) return err; - mtt_offset = fmr->mr.mtt.offset * dev->caps.mtt_entry_sz; - fmr->mtts = mlx4_table_find(&priv->mr_table.mtt_table, fmr->mr.mtt.offset, &fmr->dma_handle); @@ -895,6 +892,6 @@ int mlx4_SYNC_TPT(struct mlx4_dev *dev) { return mlx4_cmd(dev, 0, 0, 0, MLX4_CMD_SYNC_TPT, 1000, - MLX4_CMD_WRAPPED); + MLX4_CMD_NATIVE); } EXPORT_SYMBOL_GPL(mlx4_SYNC_TPT);
diff --git a/drivers/net/ethernet/mellanox/mlx4/pd.c b/drivers/net/ethernet/mellanox/mlx4/pd.c index db4746d..1ac8863 100644 --- a/drivers/net/ethernet/mellanox/mlx4/pd.c +++ b/drivers/net/ethernet/mellanox/mlx4/pd.c
@@ -63,7 +63,7 @@ } EXPORT_SYMBOL_GPL(mlx4_pd_free); -int mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn) +int __mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn) { struct mlx4_priv *priv = mlx4_priv(dev); @@ -73,11 +73,46 @@ return 0; } + +int mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn) +{ + u64 out_param; + int err; + + if (mlx4_is_mfunc(dev)) { + err = mlx4_cmd_imm(dev, 0, &out_param, + RES_XRCD, RES_OP_RESERVE, + MLX4_CMD_ALLOC_RES, + MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); + if (err) + return err; + + *xrcdn = get_param_l(&out_param); + return 0; + } + return __mlx4_xrcd_alloc(dev, xrcdn); +} EXPORT_SYMBOL_GPL(mlx4_xrcd_alloc); +void __mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn) +{ + mlx4_bitmap_free(&mlx4_priv(dev)->xrcd_bitmap, xrcdn); +} + void mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn) { - mlx4_bitmap_free(&mlx4_priv(dev)->xrcd_bitmap, xrcdn); + u64 in_param; + int err; + + if (mlx4_is_mfunc(dev)) { + set_param_l(&in_param, xrcdn); + err = mlx4_cmd(dev, in_param, RES_XRCD, + RES_OP_RESERVE, MLX4_CMD_FREE_RES, + MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); + if (err) + mlx4_warn(dev, "Failed to release xrcdn %d\n", xrcdn); + } else + __mlx4_xrcd_free(dev, xrcdn); } EXPORT_SYMBOL_GPL(mlx4_xrcd_free);
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index 55b12e6..1fe2c7a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -338,13 +338,12 @@ void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac) { u64 out_param; - int err; if (mlx4_is_mfunc(dev)) { set_param_l(&out_param, port); - err = mlx4_cmd_imm(dev, mac, &out_param, RES_MAC, - RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES, - MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); + (void) mlx4_cmd_imm(dev, mac, &out_param, RES_MAC, + RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES, + MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); return; } __mlx4_unregister_mac(dev, port, mac);
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 8752e6e..b45d0e7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -89,17 +89,6 @@ RES_QP_HW }; -static inline const char *qp_states_str(enum res_qp_states state) -{ - switch (state) { - case RES_QP_BUSY: return "RES_QP_BUSY"; - case RES_QP_RESERVED: return "RES_QP_RESERVED"; - case RES_QP_MAPPED: return "RES_QP_MAPPED"; - case RES_QP_HW: return "RES_QP_HW"; - default: return "Unknown"; - } -} - struct res_qp { struct res_common com; struct res_mtt *mtt; @@ -173,16 +162,6 @@ RES_SRQ_HW, }; -static inline const char *srq_states_str(enum res_srq_states state) -{ - switch (state) { - case RES_SRQ_BUSY: return "RES_SRQ_BUSY"; - case RES_SRQ_ALLOCATED: return "RES_SRQ_ALLOCATED"; - case RES_SRQ_HW: return "RES_SRQ_HW"; - default: return "Unknown"; - } -} - struct res_srq { struct res_common com; struct res_mtt *mtt; @@ -195,20 +174,21 @@ RES_COUNTER_ALLOCATED, }; -static inline const char *counter_states_str(enum res_counter_states state) -{ - switch (state) { - case RES_COUNTER_BUSY: return "RES_COUNTER_BUSY"; - case RES_COUNTER_ALLOCATED: return "RES_COUNTER_ALLOCATED"; - default: return "Unknown"; - } -} - struct res_counter { struct res_common com; int port; }; +enum res_xrcdn_states { + RES_XRCD_BUSY = RES_ANY_BUSY, + RES_XRCD_ALLOCATED, +}; + +struct res_xrcdn { + struct res_common com; + int port; +}; + /* For Debug uses */ static const char *ResourceType(enum mlx4_resource rt) { @@ -221,6 +201,7 @@ case RES_MAC: return "RES_MAC"; case RES_EQ: return "RES_EQ"; case RES_COUNTER: return "RES_COUNTER"; + case RES_XRCD: return "RES_XRCD"; default: return "Unknown resource type !!!"; }; } @@ -254,16 +235,23 @@ return 0 ; } -void mlx4_free_resource_tracker(struct mlx4_dev *dev) +void mlx4_free_resource_tracker(struct mlx4_dev *dev, + enum mlx4_res_tracker_free_type type) { struct mlx4_priv *priv = mlx4_priv(dev); int i; if (priv->mfunc.master.res_tracker.slave_list) { - for (i = 0 ; i < dev->num_slaves; i++) - mlx4_delete_all_resources_for_slave(dev, i); + if (type != RES_TR_FREE_STRUCTS_ONLY) + for (i = 0 ; i < dev->num_slaves; i++) + if (type == RES_TR_FREE_ALL || + dev->caps.function != i) + mlx4_delete_all_resources_for_slave(dev, i); - kfree(priv->mfunc.master.res_tracker.slave_list); + if (type != RES_TR_FREE_SLAVES_ONLY) { + kfree(priv->mfunc.master.res_tracker.slave_list); + priv->mfunc.master.res_tracker.slave_list = NULL; + } } } @@ -471,6 +459,20 @@ return &ret->com; } +static struct res_common *alloc_xrcdn_tr(int id) +{ + struct res_xrcdn *ret; + + ret = kzalloc(sizeof *ret, GFP_KERNEL); + if (!ret) + return NULL; + + ret->com.res_id = id; + ret->com.state = RES_XRCD_ALLOCATED; + + return &ret->com; +} + static struct res_common *alloc_tr(int id, enum mlx4_resource type, int slave, int extra) { @@ -501,7 +503,9 @@ case RES_COUNTER: ret = alloc_counter_tr(id); break; - + case RES_XRCD: + ret = alloc_xrcdn_tr(id); + break; default: return NULL; } @@ -624,6 +628,16 @@ return 0; } +static int remove_xrcdn_ok(struct res_xrcdn *res) +{ + if (res->com.state == RES_XRCD_BUSY) + return -EBUSY; + else if (res->com.state != RES_XRCD_ALLOCATED) + return -EPERM; + + return 0; +} + static int remove_cq_ok(struct res_cq *res) { if (res->com.state == RES_CQ_BUSY) @@ -663,6 +677,8 @@ return remove_eq_ok((struct res_eq *)res); case RES_COUNTER: return remove_counter_ok((struct res_counter *)res); + case RES_XRCD: + return remove_xrcdn_ok((struct res_xrcdn *)res); default: return -EINVAL; } @@ -1269,6 +1285,50 @@ return 0; } +static int counter_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd, + u64 in_param, u64 *out_param) +{ + u32 index; + int err; + + if (op != RES_OP_RESERVE) + return -EINVAL; + + err = __mlx4_counter_alloc(dev, &index); + if (err) + return err; + + err = add_res_range(dev, slave, index, 1, RES_COUNTER, 0); + if (err) + __mlx4_counter_free(dev, index); + else + set_param_l(out_param, index); + + return err; +} + +static int xrcdn_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd, + u64 in_param, u64 *out_param) +{ + u32 xrcdn; + int err; + + if (op != RES_OP_RESERVE) + return -EINVAL; + + err = __mlx4_xrcd_alloc(dev, &xrcdn); + if (err) + return err; + + err = add_res_range(dev, slave, xrcdn, 1, RES_XRCD, 0); + if (err) + __mlx4_xrcd_free(dev, xrcdn); + else + set_param_l(out_param, xrcdn); + + return err; +} + int mlx4_ALLOC_RES_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr, struct mlx4_cmd_mailbox *inbox, @@ -1314,6 +1374,16 @@ vhcr->in_param, &vhcr->out_param); break; + case RES_COUNTER: + err = counter_alloc_res(dev, slave, vhcr->op_modifier, alop, + vhcr->in_param, &vhcr->out_param); + break; + + case RES_XRCD: + err = xrcdn_alloc_res(dev, slave, vhcr->op_modifier, alop, + vhcr->in_param, &vhcr->out_param); + break; + default: err = -EINVAL; break; @@ -1496,6 +1566,44 @@ return 0; } +static int counter_free_res(struct mlx4_dev *dev, int slave, int op, int cmd, + u64 in_param, u64 *out_param) +{ + int index; + int err; + + if (op != RES_OP_RESERVE) + return -EINVAL; + + index = get_param_l(&in_param); + err = rem_res_range(dev, slave, index, 1, RES_COUNTER, 0); + if (err) + return err; + + __mlx4_counter_free(dev, index); + + return err; +} + +static int xrcdn_free_res(struct mlx4_dev *dev, int slave, int op, int cmd, + u64 in_param, u64 *out_param) +{ + int xrcdn; + int err; + + if (op != RES_OP_RESERVE) + return -EINVAL; + + xrcdn = get_param_l(&in_param); + err = rem_res_range(dev, slave, xrcdn, 1, RES_XRCD, 0); + if (err) + return err; + + __mlx4_xrcd_free(dev, xrcdn); + + return err; +} + int mlx4_FREE_RES_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr, struct mlx4_cmd_mailbox *inbox, @@ -1541,6 +1649,15 @@ vhcr->in_param, &vhcr->out_param); break; + case RES_COUNTER: + err = counter_free_res(dev, slave, vhcr->op_modifier, alop, + vhcr->in_param, &vhcr->out_param); + break; + + case RES_XRCD: + err = xrcdn_free_res(dev, slave, vhcr->op_modifier, alop, + vhcr->in_param, &vhcr->out_param); + default: break; } @@ -2536,7 +2653,7 @@ struct mlx4_qp qp; /* dummy for calling attach/detach */ u8 *gid = inbox->buf; enum mlx4_protocol prot = (vhcr->in_modifier >> 28) & 0x7; - int err, err1; + int err; int qpn; struct res_qp *rqp; int attach = vhcr->op_modifier; @@ -2571,7 +2688,7 @@ ex_rem: /* ignore error return below, already in error */ - err1 = rem_mcg_res(dev, slave, rqp, gid, prot, type); + (void) rem_mcg_res(dev, slave, rqp, gid, prot, type); ex_put: put_res(dev, slave, qpn, RES_QP); @@ -2604,13 +2721,12 @@ { struct res_gid *rgid; struct res_gid *tmp; - int err; struct mlx4_qp qp; /* dummy for calling attach/detach */ list_for_each_entry_safe(rgid, tmp, &rqp->mcg_list, list) { qp.qpn = rqp->local_qpn; - err = mlx4_qp_detach_common(dev, &qp, rgid->gid, rgid->prot, - rgid->steer); + (void) mlx4_qp_detach_common(dev, &qp, rgid->gid, rgid->prot, + rgid->steer); list_del(&rgid->list); kfree(rgid); } @@ -3036,14 +3152,13 @@ MLX4_CMD_HW2SW_EQ, MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); - mlx4_dbg(dev, "rem_slave_eqs: failed" - " to move slave %d eqs %d to" - " SW ownership\n", slave, eqn); + if (err) + mlx4_dbg(dev, "rem_slave_eqs: failed" + " to move slave %d eqs %d to" + " SW ownership\n", slave, eqn); mlx4_free_cmd_mailbox(dev, mailbox); - if (!err) { - atomic_dec(&eq->mtt->ref_count); - state = RES_EQ_RESERVED; - } + atomic_dec(&eq->mtt->ref_count); + state = RES_EQ_RESERVED; break; default: @@ -3056,6 +3171,64 @@ spin_unlock_irq(mlx4_tlock(dev)); } +static void rem_slave_counters(struct mlx4_dev *dev, int slave) +{ + struct mlx4_priv *priv = mlx4_priv(dev); + struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; + struct list_head *counter_list = + &tracker->slave_list[slave].res_list[RES_COUNTER]; + struct res_counter *counter; + struct res_counter *tmp; + int err; + int index; + + err = move_all_busy(dev, slave, RES_COUNTER); + if (err) + mlx4_warn(dev, "rem_slave_counters: Could not move all counters to " + "busy for slave %d\n", slave); + + spin_lock_irq(mlx4_tlock(dev)); + list_for_each_entry_safe(counter, tmp, counter_list, com.list) { + if (counter->com.owner == slave) { + index = counter->com.res_id; + radix_tree_delete(&tracker->res_tree[RES_COUNTER], index); + list_del(&counter->com.list); + kfree(counter); + __mlx4_counter_free(dev, index); + } + } + spin_unlock_irq(mlx4_tlock(dev)); +} + +static void rem_slave_xrcdns(struct mlx4_dev *dev, int slave) +{ + struct mlx4_priv *priv = mlx4_priv(dev); + struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; + struct list_head *xrcdn_list = + &tracker->slave_list[slave].res_list[RES_XRCD]; + struct res_xrcdn *xrcd; + struct res_xrcdn *tmp; + int err; + int xrcdn; + + err = move_all_busy(dev, slave, RES_XRCD); + if (err) + mlx4_warn(dev, "rem_slave_xrcdns: Could not move all xrcdns to " + "busy for slave %d\n", slave); + + spin_lock_irq(mlx4_tlock(dev)); + list_for_each_entry_safe(xrcd, tmp, xrcdn_list, com.list) { + if (xrcd->com.owner == slave) { + xrcdn = xrcd->com.res_id; + radix_tree_delete(&tracker->res_tree[RES_XRCD], xrcdn); + list_del(&xrcd->com.list); + kfree(xrcd); + __mlx4_xrcd_free(dev, xrcdn); + } + } + spin_unlock_irq(mlx4_tlock(dev)); +} + void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave) { struct mlx4_priv *priv = mlx4_priv(dev); @@ -3069,5 +3242,7 @@ rem_slave_mrs(dev, slave); rem_slave_eqs(dev, slave); rem_slave_mtts(dev, slave); + rem_slave_counters(dev, slave); + rem_slave_xrcdns(dev, slave); mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex); }
diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index f8dda00..5e313e9 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c
@@ -618,10 +618,8 @@ netif_dbg(ks, intr, ks->netdev, "%s: status 0x%04x\n", __func__, status); - if (status & IRQ_LCI) { - /* should do something about checking link status */ + if (status & IRQ_LCI) handled |= IRQ_LCI; - } if (status & IRQ_LDI) { u16 pmecr = ks8851_rdreg16(ks, KS_PMECR); @@ -684,6 +682,9 @@ mutex_unlock(&ks->lock); + if (status & IRQ_LCI) + mii_check_link(&ks->mii); + if (status & IRQ_TXI) netif_wake_queue(ks->netdev);
diff --git a/drivers/net/ethernet/natsemi/Kconfig b/drivers/net/ethernet/natsemi/Kconfig index eb836f7..f157334 100644 --- a/drivers/net/ethernet/natsemi/Kconfig +++ b/drivers/net/ethernet/natsemi/Kconfig
@@ -6,9 +6,8 @@ bool "National Semi-conductor devices" default y depends on AMIGA_PCMCIA || ARM || EISA || EXPERIMENTAL || H8300 || \ - ISA || M32R || MAC || MACH_JAZZ || MACH_TX49XX || MCA || \ - MCA_LEGACY || MIPS || PCI || PCMCIA || SUPERH || \ - XTENSA_PLATFORM_XT2000 || ZORRO + ISA || M32R || MAC || MACH_JAZZ || MACH_TX49XX || MIPS || \ + PCI || PCMCIA || SUPERH || XTENSA_PLATFORM_XT2000 || ZORRO ---help--- If you have a network (Ethernet) card belonging to this class, say Y and read the Ethernet-HOWTO, available from @@ -21,21 +20,6 @@ if NET_VENDOR_NATSEMI -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 MACSONIC tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)" depends on MAC
diff --git a/drivers/net/ethernet/natsemi/Makefile b/drivers/net/ethernet/natsemi/Makefile index 9aa5dea..764c532a 100644 --- a/drivers/net/ethernet/natsemi/Makefile +++ b/drivers/net/ethernet/natsemi/Makefile
@@ -2,7 +2,6 @@ # Makefile for the National Semi-conductor Sonic devices. # -obj-$(CONFIG_IBMLANA) += ibmlana.o obj-$(CONFIG_MACSONIC) += macsonic.o obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o obj-$(CONFIG_NATSEMI) += natsemi.o
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h index 9f3dbc4..b07311e 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
@@ -584,7 +584,6 @@ /** * struct pch_gbe_adapter - board specific private data structure * @stats_lock: Spinlock structure for status - * @tx_queue_lock: Spinlock structure for transmit * @ethtool_lock: Spinlock structure for ethtool * @irq_sem: Semaphore for interrupt * @netdev: Pointer of network device structure @@ -609,7 +608,6 @@ struct pch_gbe_adapter { spinlock_t stats_lock; - spinlock_t tx_queue_lock; spinlock_t ethtool_lock; atomic_t irq_sem; struct net_device *netdev;
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 9dc7e50..3787c64 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -645,14 +645,11 @@ */ static int pch_gbe_alloc_queues(struct pch_gbe_adapter *adapter) { - int size; - - size = (int)sizeof(struct pch_gbe_tx_ring); - adapter->tx_ring = kzalloc(size, GFP_KERNEL); + adapter->tx_ring = kzalloc(sizeof(*adapter->tx_ring), GFP_KERNEL); if (!adapter->tx_ring) return -ENOMEM; - size = (int)sizeof(struct pch_gbe_rx_ring); - adapter->rx_ring = kzalloc(size, GFP_KERNEL); + + adapter->rx_ring = kzalloc(sizeof(*adapter->rx_ring), GFP_KERNEL); if (!adapter->rx_ring) { kfree(adapter->tx_ring); return -ENOMEM; @@ -1169,7 +1166,6 @@ struct sk_buff *tmp_skb; unsigned int frame_ctrl; unsigned int ring_num; - unsigned long flags; /*-- Set frame control --*/ frame_ctrl = 0; @@ -1216,14 +1212,14 @@ } } } - spin_lock_irqsave(&tx_ring->tx_lock, flags); + ring_num = tx_ring->next_to_use; if (unlikely((ring_num + 1) == tx_ring->count)) tx_ring->next_to_use = 0; else tx_ring->next_to_use = ring_num + 1; - spin_unlock_irqrestore(&tx_ring->tx_lock, flags); + buffer_info = &tx_ring->buffer_info[ring_num]; tmp_skb = buffer_info->skb; @@ -1525,7 +1521,7 @@ &rx_ring->rx_buff_pool_logic, GFP_KERNEL); if (!rx_ring->rx_buff_pool) { - pr_err("Unable to allocate memory for the receive poll buffer\n"); + pr_err("Unable to allocate memory for the receive pool buffer\n"); return -ENOMEM; } memset(rx_ring->rx_buff_pool, 0, size); @@ -1644,15 +1640,17 @@ pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n", cleaned_count); /* Recover from running out of Tx resources in xmit_frame */ + spin_lock(&tx_ring->tx_lock); if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev)))) { netif_wake_queue(adapter->netdev); adapter->stats.tx_restart_count++; pr_debug("Tx wake queue\n"); } - spin_lock(&adapter->tx_queue_lock); + tx_ring->next_to_clean = i; - spin_unlock(&adapter->tx_queue_lock); + pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean); + spin_unlock(&tx_ring->tx_lock); return cleaned; } @@ -2043,7 +2041,6 @@ return -ENOMEM; } spin_lock_init(&adapter->hw.miim_lock); - spin_lock_init(&adapter->tx_queue_lock); spin_lock_init(&adapter->stats_lock); spin_lock_init(&adapter->ethtool_lock); atomic_set(&adapter->irq_sem, 0); @@ -2148,10 +2145,10 @@ tx_ring->next_to_use, tx_ring->next_to_clean); return NETDEV_TX_BUSY; } - spin_unlock_irqrestore(&tx_ring->tx_lock, flags); /* CRC,ITAG no support */ pch_gbe_tx_queue(adapter, tx_ring, skb); + spin_unlock_irqrestore(&tx_ring->tx_lock, flags); return NETDEV_TX_OK; }
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h index b5de8a7..37ccbe5 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h
@@ -53,8 +53,8 @@ #define _NETXEN_NIC_LINUX_MAJOR 4 #define _NETXEN_NIC_LINUX_MINOR 0 -#define _NETXEN_NIC_LINUX_SUBVERSION 78 -#define NETXEN_NIC_LINUX_VERSIONID "4.0.78" +#define _NETXEN_NIC_LINUX_SUBVERSION 79 +#define NETXEN_NIC_LINUX_VERSIONID "4.0.79" #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) #define _major(v) (((v) >> 24) & 0xff) @@ -419,6 +419,8 @@ (((sts_data) >> 52) & 0x1) #define netxen_get_lro_sts_seq_number(sts_data) \ ((sts_data) & 0x0FFFFFFFF) +#define netxen_get_lro_sts_mss(sts_data1) \ + ((sts_data1 >> 32) & 0x0FFFF) struct status_desc { @@ -794,6 +796,7 @@ #define NX_CAP0_JUMBO_CONTIGUOUS NX_CAP_BIT(0, 7) #define NX_CAP0_LRO_CONTIGUOUS NX_CAP_BIT(0, 8) #define NX_CAP0_HW_LRO NX_CAP_BIT(0, 10) +#define NX_CAP0_HW_LRO_MSS NX_CAP_BIT(0, 21) /* * Context state @@ -1073,6 +1076,8 @@ #define NX_FW_CAPABILITY_FVLANTX (1 << 9) #define NX_FW_CAPABILITY_HW_LRO (1 << 10) #define NX_FW_CAPABILITY_GBE_LINK_CFG (1 << 11) +#define NX_FW_CAPABILITY_MORE_CAPS (1 << 31) +#define NX_FW_CAPABILITY_2_LRO_MAX_TCP_SEG (1 << 2) /* module types */ #define LINKEVENT_MODULE_NOT_PRESENT 1 @@ -1155,6 +1160,7 @@ #define NETXEN_NIC_BRIDGE_ENABLED 0X10 #define NETXEN_NIC_DIAG_ENABLED 0x20 #define NETXEN_FW_RESET_OWNER 0x40 +#define NETXEN_FW_MSS_CAP 0x80 #define NETXEN_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED)) @@ -1201,6 +1207,9 @@ #define NX_FORCE_FW_RESET 0xdeaddead +/* Fw dump levels */ +static const u32 FW_DUMP_LEVELS[] = { 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff }; + /* Flash read/write address */ #define NX_FW_DUMP_REG1 0x00130060 #define NX_FW_DUMP_REG2 0x001e0000 @@ -1814,6 +1823,13 @@ char short_name[NETXEN_MAX_SHORT_NAME]; }; +struct netxen_dimm_cfg { + u8 presence; + u8 mem_type; + u8 dimm_type; + u32 size; +}; + static const struct netxen_brdinfo netxen_boards[] = { {NETXEN_BRDTYPE_P2_SB31_10G_CX4, 1, "XGb CX4"}, {NETXEN_BRDTYPE_P2_SB31_10G_HMEZ, 1, "XGb HMEZ"},
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c index f3c0057..7f556a8 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
@@ -229,7 +229,7 @@ adapter->mdump.md_template; adapter->mdump.md_capture_buff = NULL; adapter->mdump.fw_supports_md = 1; - adapter->mdump.md_enabled = 1; + adapter->mdump.md_enabled = 0; return err; @@ -328,6 +328,9 @@ cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN); cap |= (NX_CAP0_JUMBO_CONTIGUOUS | NX_CAP0_LRO_CONTIGUOUS); + if (adapter->flags & NETXEN_FW_MSS_CAP) + cap |= NX_CAP0_HW_LRO_MSS; + prq->capabilities[0] = cpu_to_le32(cap); prq->host_int_crb_mode = cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED);
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c index 8c39299..3973040 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c
@@ -834,7 +834,7 @@ static int netxen_set_dump(struct net_device *netdev, struct ethtool_dump *val) { - int ret = 0; + int i; struct netxen_adapter *adapter = netdev_priv(netdev); struct netxen_minidump *mdump = &adapter->mdump; @@ -844,7 +844,7 @@ mdump->md_enabled = 1; if (adapter->fw_mdump_rdy) { netdev_info(netdev, "Previous dump not cleared, not forcing dump\n"); - return ret; + return 0; } netdev_info(netdev, "Forcing a fw dump\n"); nx_dev_request_reset(adapter); @@ -867,19 +867,21 @@ adapter->flags &= ~NETXEN_FW_RESET_OWNER; break; default: - if (val->flag <= NX_DUMP_MASK_MAX && - val->flag >= NX_DUMP_MASK_MIN) { - mdump->md_capture_mask = val->flag & 0xff; - netdev_info(netdev, "Driver mask changed to: 0x%x\n", + for (i = 0; i < ARRAY_SIZE(FW_DUMP_LEVELS); i++) { + if (val->flag == FW_DUMP_LEVELS[i]) { + mdump->md_capture_mask = val->flag; + netdev_info(netdev, + "Driver mask changed to: 0x%x\n", mdump->md_capture_mask); - break; + return 0; + } } netdev_info(netdev, "Invalid dump level: 0x%x\n", val->flag); return -EINVAL; } - return ret; + return 0; } static int
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h index b1a897c..28e0769 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h
@@ -776,6 +776,7 @@ #define CRB_SW_INT_MASK_3 (NETXEN_NIC_REG(0x1e8)) #define CRB_FW_CAPABILITIES_1 (NETXEN_CAM_RAM(0x128)) +#define CRB_FW_CAPABILITIES_2 (NETXEN_CAM_RAM(0x12c)) #define CRB_MAC_BLOCK_START (NETXEN_CAM_RAM(0x1c0)) /* @@ -955,6 +956,31 @@ #define NX_CRB_DEV_REF_COUNT (NETXEN_CAM_RAM(0x138)) #define NX_CRB_DEV_STATE (NETXEN_CAM_RAM(0x140)) +/* MiniDIMM related macros */ +#define NETXEN_DIMM_CAPABILITY (NETXEN_CAM_RAM(0x258)) +#define NETXEN_DIMM_PRESENT 0x1 +#define NETXEN_DIMM_MEMTYPE_DDR2_SDRAM 0x2 +#define NETXEN_DIMM_SIZE 0x4 +#define NETXEN_DIMM_MEMTYPE(VAL) ((VAL >> 3) & 0xf) +#define NETXEN_DIMM_NUMROWS(VAL) ((VAL >> 7) & 0xf) +#define NETXEN_DIMM_NUMCOLS(VAL) ((VAL >> 11) & 0xf) +#define NETXEN_DIMM_NUMRANKS(VAL) ((VAL >> 15) & 0x3) +#define NETXEN_DIMM_DATAWIDTH(VAL) ((VAL >> 18) & 0x3) +#define NETXEN_DIMM_NUMBANKS(VAL) ((VAL >> 21) & 0xf) +#define NETXEN_DIMM_TYPE(VAL) ((VAL >> 25) & 0x3f) +#define NETXEN_DIMM_VALID_FLAG 0x80000000 + +#define NETXEN_DIMM_MEM_DDR2_SDRAM 0x8 + +#define NETXEN_DIMM_STD_MEM_SIZE 512 + +#define NETXEN_DIMM_TYPE_RDIMM 0x1 +#define NETXEN_DIMM_TYPE_UDIMM 0x2 +#define NETXEN_DIMM_TYPE_SO_DIMM 0x4 +#define NETXEN_DIMM_TYPE_Micro_DIMM 0x8 +#define NETXEN_DIMM_TYPE_Mini_RDIMM 0x10 +#define NETXEN_DIMM_TYPE_Mini_UDIMM 0x20 + /* Device State */ #define NX_DEV_COLD 1 #define NX_DEV_INITALIZING 2
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c index 718b274..0d725dc 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
@@ -1131,7 +1131,6 @@ _build(file_fw_ver)); return -EINVAL; } - val = nx_get_bios_version(adapter); netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios); if ((__force u32)val != bios) { @@ -1661,6 +1660,9 @@ length = skb->len; + if (adapter->flags & NETXEN_FW_MSS_CAP) + skb_shinfo(skb)->gso_size = netxen_get_lro_sts_mss(sts_data1); + netif_receive_skb(skb); adapter->stats.lro_pkts++;
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 65a718f9..342b3a7 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
@@ -1184,6 +1184,7 @@ int err, ring; struct nx_host_rds_ring *rds_ring; struct nx_host_tx_ring *tx_ring; + u32 capab2; if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) return 0; @@ -1192,6 +1193,13 @@ if (err) return err; + adapter->flags &= ~NETXEN_FW_MSS_CAP; + if (adapter->capabilities & NX_FW_CAPABILITY_MORE_CAPS) { + capab2 = NXRD32(adapter, CRB_FW_CAPABILITIES_2); + if (capab2 & NX_FW_CAPABILITY_2_LRO_MAX_TCP_SEG) + adapter->flags |= NETXEN_FW_MSS_CAP; + } + err = netxen_napi_add(adapter, netdev); if (err) return err; @@ -1810,7 +1818,6 @@ flags = FLAGS_VLAN_TAGGED; } else if (vlan_tx_tag_present(skb)) { - flags = FLAGS_VLAN_OOB; vid = vlan_tx_tag_get(skb); netxen_set_tx_vlan_tci(first_desc, vid); @@ -2926,6 +2933,134 @@ .write = netxen_sysfs_write_mem, }; +static ssize_t +netxen_sysfs_read_dimm(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t offset, size_t size) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct netxen_adapter *adapter = dev_get_drvdata(dev); + struct net_device *netdev = adapter->netdev; + struct netxen_dimm_cfg dimm; + u8 dw, rows, cols, banks, ranks; + u32 val; + + if (size != sizeof(struct netxen_dimm_cfg)) { + netdev_err(netdev, "Invalid size\n"); + return -1; + } + + memset(&dimm, 0, sizeof(struct netxen_dimm_cfg)); + val = NXRD32(adapter, NETXEN_DIMM_CAPABILITY); + + /* Checks if DIMM info is valid. */ + if (val & NETXEN_DIMM_VALID_FLAG) { + netdev_err(netdev, "Invalid DIMM flag\n"); + dimm.presence = 0xff; + goto out; + } + + rows = NETXEN_DIMM_NUMROWS(val); + cols = NETXEN_DIMM_NUMCOLS(val); + ranks = NETXEN_DIMM_NUMRANKS(val); + banks = NETXEN_DIMM_NUMBANKS(val); + dw = NETXEN_DIMM_DATAWIDTH(val); + + dimm.presence = (val & NETXEN_DIMM_PRESENT); + + /* Checks if DIMM info is present. */ + if (!dimm.presence) { + netdev_err(netdev, "DIMM not present\n"); + goto out; + } + + dimm.dimm_type = NETXEN_DIMM_TYPE(val); + + switch (dimm.dimm_type) { + case NETXEN_DIMM_TYPE_RDIMM: + case NETXEN_DIMM_TYPE_UDIMM: + case NETXEN_DIMM_TYPE_SO_DIMM: + case NETXEN_DIMM_TYPE_Micro_DIMM: + case NETXEN_DIMM_TYPE_Mini_RDIMM: + case NETXEN_DIMM_TYPE_Mini_UDIMM: + break; + default: + netdev_err(netdev, "Invalid DIMM type %x\n", dimm.dimm_type); + goto out; + } + + if (val & NETXEN_DIMM_MEMTYPE_DDR2_SDRAM) + dimm.mem_type = NETXEN_DIMM_MEM_DDR2_SDRAM; + else + dimm.mem_type = NETXEN_DIMM_MEMTYPE(val); + + if (val & NETXEN_DIMM_SIZE) { + dimm.size = NETXEN_DIMM_STD_MEM_SIZE; + goto out; + } + + if (!rows) { + netdev_err(netdev, "Invalid no of rows %x\n", rows); + goto out; + } + + if (!cols) { + netdev_err(netdev, "Invalid no of columns %x\n", cols); + goto out; + } + + if (!banks) { + netdev_err(netdev, "Invalid no of banks %x\n", banks); + goto out; + } + + ranks += 1; + + switch (dw) { + case 0x0: + dw = 32; + break; + case 0x1: + dw = 33; + break; + case 0x2: + dw = 36; + break; + case 0x3: + dw = 64; + break; + case 0x4: + dw = 72; + break; + case 0x5: + dw = 80; + break; + case 0x6: + dw = 128; + break; + case 0x7: + dw = 144; + break; + default: + netdev_err(netdev, "Invalid data-width %x\n", dw); + goto out; + } + + dimm.size = ((1 << rows) * (1 << cols) * dw * banks * ranks) / 8; + /* Size returned in MB. */ + dimm.size = (dimm.size) / 0x100000; +out: + memcpy(buf, &dimm, sizeof(struct netxen_dimm_cfg)); + return sizeof(struct netxen_dimm_cfg); + +} + +static struct bin_attribute bin_attr_dimm = { + .attr = { .name = "dimm", .mode = (S_IRUGO | S_IWUSR) }, + .size = 0, + .read = netxen_sysfs_read_dimm, +}; + static void netxen_create_sysfs_entries(struct netxen_adapter *adapter) @@ -2963,6 +3098,8 @@ dev_info(dev, "failed to create crb sysfs entry\n"); if (device_create_bin_file(dev, &bin_attr_mem)) dev_info(dev, "failed to create mem sysfs entry\n"); + if (device_create_bin_file(dev, &bin_attr_dimm)) + dev_info(dev, "failed to create dimm sysfs entry\n"); } @@ -2975,6 +3112,7 @@ device_remove_file(dev, &dev_attr_diag_mode); device_remove_bin_file(dev, &bin_attr_crb); device_remove_bin_file(dev, &bin_attr_mem); + device_remove_bin_file(dev, &bin_attr_dimm); } #ifdef CONFIG_INET
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 735423f..9e9e78a 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -1232,7 +1232,12 @@ dump->len = fw_dump->tmpl_hdr->size + fw_dump->size; else dump->len = 0; - dump->flag = fw_dump->tmpl_hdr->drv_cap_mask; + + if (!fw_dump->enable) + dump->flag = ETH_FW_DUMP_DISABLE; + else + dump->flag = fw_dump->tmpl_hdr->drv_cap_mask; + dump->version = adapter->fw_version; return 0; }
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 5c47135..46e77a2 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -1965,7 +1965,7 @@ __le16 vlan_id = 0; u8 hindex; - if (!compare_ether_addr(phdr->h_source, adapter->mac_addr)) + if (ether_addr_equal(phdr->h_source, adapter->mac_addr)) return; if (adapter->fhash.fnum >= adapter->fhash.fmax) @@ -2235,8 +2235,7 @@ if (adapter->flags & QLCNIC_MACSPOOF) { phdr = (struct ethhdr *)skb->data; - if (compare_ether_addr(phdr->h_source, - adapter->mac_addr)) + if (!ether_addr_equal(phdr->h_source, adapter->mac_addr)) goto drop_packet; }
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 00628d8..4f74b97 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c
@@ -63,8 +63,12 @@ #define R8169_MSG_DEFAULT \ (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN) -#define TX_BUFFS_AVAIL(tp) \ - (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1) +#define TX_SLOTS_AVAIL(tp) \ + (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx) + +/* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */ +#define TX_FRAGS_READY_FOR(tp,nr_frags) \ + (TX_SLOTS_AVAIL(tp) >= (nr_frags + 1)) /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). The RTL chips use a 64 element hash table based on the Ethernet CRC. */ @@ -5494,7 +5498,7 @@ u32 opts[2]; int frags; - if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) { + if (unlikely(!TX_FRAGS_READY_FOR(tp, skb_shinfo(skb)->nr_frags))) { netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n"); goto err_stop_0; } @@ -5548,7 +5552,7 @@ mmiowb(); - if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { + if (!TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) { /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must * not miss a ring update when it notices a stopped queue. */ @@ -5562,7 +5566,7 @@ * can't. */ smp_mb(); - if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS) + if (TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) netif_wake_queue(dev); } @@ -5685,7 +5689,7 @@ */ smp_mb(); if (netif_queue_stopped(dev) && - (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) { + TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) { netif_wake_queue(dev); } /*
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 3cbfbff..b95f2e1 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c
@@ -656,25 +656,30 @@ struct efx_channel *channel; struct efx_tx_queue *tx_queue; struct efx_rx_queue *rx_queue; + struct pci_dev *dev = efx->pci_dev; int rc; EFX_ASSERT_RESET_SERIALISED(efx); BUG_ON(efx->port_enabled); - rc = efx_nic_flush_queues(efx); - if (rc && EFX_WORKAROUND_7803(efx)) { - /* Schedule a reset to recover from the flush failure. The - * descriptor caches reference memory we're about to free, - * but falcon_reconfigure_mac_wrapper() won't reconnect - * the MACs because of the pending reset. */ - netif_err(efx, drv, efx->net_dev, - "Resetting to recover from flush failure\n"); - efx_schedule_reset(efx, RESET_TYPE_ALL); - } else if (rc) { - netif_err(efx, drv, efx->net_dev, "failed to flush queues\n"); - } else { - netif_dbg(efx, drv, efx->net_dev, - "successfully flushed all queues\n"); + /* Only perform flush if dma is enabled */ + if (dev->is_busmaster) { + rc = efx_nic_flush_queues(efx); + + if (rc && EFX_WORKAROUND_7803(efx)) { + /* Schedule a reset to recover from the flush failure. The + * descriptor caches reference memory we're about to free, + * but falcon_reconfigure_mac_wrapper() won't reconnect + * the MACs because of the pending reset. */ + netif_err(efx, drv, efx->net_dev, + "Resetting to recover from flush failure\n"); + efx_schedule_reset(efx, RESET_TYPE_ALL); + } else if (rc) { + netif_err(efx, drv, efx->net_dev, "failed to flush queues\n"); + } else { + netif_dbg(efx, drv, efx->net_dev, + "successfully flushed all queues\n"); + } } efx_for_each_channel(channel, efx) { @@ -1349,7 +1354,7 @@ } /* RSS might be usable on VFs even if it is disabled on the PF */ - efx->rss_spread = (efx->n_rx_channels > 1 ? + efx->rss_spread = ((efx->n_rx_channels > 1 || !efx_sriov_wanted(efx)) ? efx->n_rx_channels : efx_vf_size(efx)); return 0; @@ -2492,8 +2497,8 @@ efx_fini_io(efx); netif_dbg(efx, drv, efx->net_dev, "shutdown successful\n"); - pci_set_drvdata(pci_dev, NULL); efx_fini_struct(efx); + pci_set_drvdata(pci_dev, NULL); free_netdev(efx->net_dev); }; @@ -2695,6 +2700,7 @@ fail2: efx_fini_struct(efx); fail1: + pci_set_drvdata(pci_dev, NULL); WARN_ON(rc > 0); netif_dbg(efx, drv, efx->net_dev, "initialisation failed. rc=%d\n", rc); free_netdev(net_dev);
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index f22f45f..03ded36 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -1023,7 +1023,7 @@ return -EINVAL; /* Is it a default UC or MC filter? */ - if (!compare_ether_addr(mac_mask->h_dest, mac_addr_mc_mask) && + if (ether_addr_equal(mac_mask->h_dest, mac_addr_mc_mask) && vlan_tag_mask == 0) { if (is_multicast_ether_addr(mac_entry->h_dest)) rc = efx_filter_set_mc_def(&spec); @@ -1108,6 +1108,39 @@ return 0; } +static int efx_ethtool_get_module_eeprom(struct net_device *net_dev, + struct ethtool_eeprom *ee, + u8 *data) +{ + struct efx_nic *efx = netdev_priv(net_dev); + int ret; + + if (!efx->phy_op || !efx->phy_op->get_module_eeprom) + return -EOPNOTSUPP; + + mutex_lock(&efx->mac_lock); + ret = efx->phy_op->get_module_eeprom(efx, ee, data); + mutex_unlock(&efx->mac_lock); + + return ret; +} + +static int efx_ethtool_get_module_info(struct net_device *net_dev, + struct ethtool_modinfo *modinfo) +{ + struct efx_nic *efx = netdev_priv(net_dev); + int ret; + + if (!efx->phy_op || !efx->phy_op->get_module_info) + return -EOPNOTSUPP; + + mutex_lock(&efx->mac_lock); + ret = efx->phy_op->get_module_info(efx, modinfo); + mutex_unlock(&efx->mac_lock); + + return ret; +} + const struct ethtool_ops efx_ethtool_ops = { .get_settings = efx_ethtool_get_settings, .set_settings = efx_ethtool_set_settings, @@ -1137,4 +1170,6 @@ .get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size, .get_rxfh_indir = efx_ethtool_get_rxfh_indir, .set_rxfh_indir = efx_ethtool_set_rxfh_indir, + .get_module_info = efx_ethtool_get_module_info, + .get_module_eeprom = efx_ethtool_get_module_eeprom, };
diff --git a/drivers/net/ethernet/sfc/mcdi_phy.c b/drivers/net/ethernet/sfc/mcdi_phy.c index 7bcad89..13cb40f 100644 --- a/drivers/net/ethernet/sfc/mcdi_phy.c +++ b/drivers/net/ethernet/sfc/mcdi_phy.c
@@ -739,6 +739,80 @@ return NULL; } +#define SFP_PAGE_SIZE 128 +#define SFP_NUM_PAGES 2 +static int efx_mcdi_phy_get_module_eeprom(struct efx_nic *efx, + struct ethtool_eeprom *ee, u8 *data) +{ + u8 outbuf[MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX]; + u8 inbuf[MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN]; + size_t outlen; + int rc; + unsigned int payload_len; + unsigned int space_remaining = ee->len; + unsigned int page; + unsigned int page_off; + unsigned int to_copy; + u8 *user_data = data; + + BUILD_BUG_ON(SFP_PAGE_SIZE * SFP_NUM_PAGES != ETH_MODULE_SFF_8079_LEN); + + page_off = ee->offset % SFP_PAGE_SIZE; + page = ee->offset / SFP_PAGE_SIZE; + + while (space_remaining && (page < SFP_NUM_PAGES)) { + MCDI_SET_DWORD(inbuf, GET_PHY_MEDIA_INFO_IN_PAGE, page); + + rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_MEDIA_INFO, + inbuf, sizeof(inbuf), + outbuf, sizeof(outbuf), + &outlen); + if (rc) + return rc; + + if (outlen < (MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST + + SFP_PAGE_SIZE)) + return -EIO; + + payload_len = MCDI_DWORD(outbuf, + GET_PHY_MEDIA_INFO_OUT_DATALEN); + if (payload_len != SFP_PAGE_SIZE) + return -EIO; + + /* Copy as much as we can into data */ + payload_len -= page_off; + to_copy = (space_remaining < payload_len) ? + space_remaining : payload_len; + + memcpy(user_data, + outbuf + page_off + + MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST, + to_copy); + + space_remaining -= to_copy; + user_data += to_copy; + page_off = 0; + page++; + } + + return 0; +} + +static int efx_mcdi_phy_get_module_info(struct efx_nic *efx, + struct ethtool_modinfo *modinfo) +{ + struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; + + switch (phy_cfg->media) { + case MC_CMD_MEDIA_SFP_PLUS: + modinfo->type = ETH_MODULE_SFF_8079; + modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN; + return 0; + default: + return -EOPNOTSUPP; + } +} + const struct efx_phy_operations efx_mcdi_phy_ops = { .probe = efx_mcdi_phy_probe, .init = efx_port_dummy_op_int, @@ -751,4 +825,6 @@ .test_alive = efx_mcdi_phy_test_alive, .run_tests = efx_mcdi_phy_run_tests, .test_name = efx_mcdi_phy_test_name, + .get_module_eeprom = efx_mcdi_phy_get_module_eeprom, + .get_module_info = efx_mcdi_phy_get_module_info, };
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index f0385e1..0e57535 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -252,8 +252,6 @@ * @max_fill: RX descriptor maximum fill level (<= ring size) * @fast_fill_trigger: RX descriptor fill level that will trigger a fast fill * (<= @max_fill) - * @fast_fill_limit: The level to which a fast fill will fill - * (@fast_fill_trigger <= @fast_fill_limit <= @max_fill) * @min_fill: RX descriptor minimum non-zero fill level. * This records the minimum fill level observed when a ring * refill was triggered. @@ -274,7 +272,6 @@ int removed_count; unsigned int max_fill; unsigned int fast_fill_trigger; - unsigned int fast_fill_limit; unsigned int min_fill; unsigned int min_overfill; unsigned int alloc_page_count; @@ -522,6 +519,11 @@ int (*test_alive) (struct efx_nic *efx); const char *(*test_name) (struct efx_nic *efx, unsigned int index); int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags); + int (*get_module_eeprom) (struct efx_nic *efx, + struct ethtool_eeprom *ee, + u8 *data); + int (*get_module_info) (struct efx_nic *efx, + struct ethtool_modinfo *modinfo); }; /**
diff --git a/drivers/net/ethernet/sfc/qt202x_phy.c b/drivers/net/ethernet/sfc/qt202x_phy.c index 8a7caf88..326a286 100644 --- a/drivers/net/ethernet/sfc/qt202x_phy.c +++ b/drivers/net/ethernet/sfc/qt202x_phy.c
@@ -449,6 +449,37 @@ efx->phy_data = NULL; } +static int qt202x_phy_get_module_info(struct efx_nic *efx, + struct ethtool_modinfo *modinfo) +{ + modinfo->type = ETH_MODULE_SFF_8079; + modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN; + return 0; +} + +static int qt202x_phy_get_module_eeprom(struct efx_nic *efx, + struct ethtool_eeprom *ee, u8 *data) +{ + int mmd, reg_base, rc, i; + + if (efx->phy_type == PHY_TYPE_QT2025C) { + mmd = MDIO_MMD_PCS; + reg_base = 0xd000; + } else { + mmd = MDIO_MMD_PMAPMD; + reg_base = 0x8007; + } + + for (i = 0; i < ee->len; i++) { + rc = efx_mdio_read(efx, mmd, reg_base + ee->offset + i); + if (rc < 0) + return rc; + data[i] = rc; + } + + return 0; +} + const struct efx_phy_operations falcon_qt202x_phy_ops = { .probe = qt202x_phy_probe, .init = qt202x_phy_init, @@ -459,4 +490,6 @@ .get_settings = qt202x_phy_get_settings, .set_settings = efx_mdio_set_settings, .test_alive = efx_mdio_test_alive, + .get_module_eeprom = qt202x_phy_get_module_eeprom, + .get_module_info = qt202x_phy_get_module_info, };
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 763fa2f..243e91f 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c
@@ -76,12 +76,7 @@ /* This is the percentage fill level below which new RX descriptors * will be added to the RX descriptor ring. */ -static unsigned int rx_refill_threshold = 90; - -/* This is the percentage fill level to which an RX queue will be refilled - * when the "RX refill threshold" is reached. - */ -static unsigned int rx_refill_limit = 95; +static unsigned int rx_refill_threshold; /* * RX maximum head room required. @@ -342,7 +337,7 @@ * efx_fast_push_rx_descriptors - push new RX descriptors quickly * @rx_queue: RX descriptor queue * This will aim to fill the RX descriptor queue up to - * @rx_queue->@fast_fill_limit. If there is insufficient atomic + * @rx_queue->@max_fill. If there is insufficient atomic * memory to do so, a slow fill will be scheduled. * * The caller must provide serialisation (none is used here). In practise, @@ -367,15 +362,14 @@ rx_queue->min_fill = fill_level; } - space = rx_queue->fast_fill_limit - fill_level; - if (space < EFX_RX_BATCH) - goto out; + space = rx_queue->max_fill - fill_level; + EFX_BUG_ON_PARANOID(space < EFX_RX_BATCH); netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev, "RX queue %d fast-filling descriptor ring from" " level %d to level %d using %s allocation\n", efx_rx_queue_index(rx_queue), fill_level, - rx_queue->fast_fill_limit, + rx_queue->max_fill, channel->rx_alloc_push_pages ? "page" : "skb"); do { @@ -681,7 +675,7 @@ void efx_init_rx_queue(struct efx_rx_queue *rx_queue) { struct efx_nic *efx = rx_queue->efx; - unsigned int max_fill, trigger, limit; + unsigned int max_fill, trigger, max_trigger; netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, "initialising RX queue %d\n", efx_rx_queue_index(rx_queue)); @@ -694,12 +688,17 @@ /* Initialise limit fields */ max_fill = efx->rxq_entries - EFX_RXD_HEAD_ROOM; - trigger = max_fill * min(rx_refill_threshold, 100U) / 100U; - limit = max_fill * min(rx_refill_limit, 100U) / 100U; + max_trigger = max_fill - EFX_RX_BATCH; + if (rx_refill_threshold != 0) { + trigger = max_fill * min(rx_refill_threshold, 100U) / 100U; + if (trigger > max_trigger) + trigger = max_trigger; + } else { + trigger = max_trigger; + } rx_queue->max_fill = max_fill; rx_queue->fast_fill_trigger = trigger; - rx_queue->fast_fill_limit = limit; /* Set up RX descriptor ring */ rx_queue->enabled = true; @@ -746,5 +745,5 @@ module_param(rx_refill_threshold, uint, 0444); MODULE_PARM_DESC(rx_refill_threshold, - "RX descriptor ring fast/slow fill threshold (%)"); + "RX descriptor ring refill threshold (%)");
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index f5dedcb..bcd54d6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -247,8 +247,8 @@ struct stmmac_dma_ops { /* DMA core initialization */ - int (*init) (void __iomem *ioaddr, int pbl, int fb, int burst_len, - u32 dma_tx, u32 dma_rx); + int (*init) (void __iomem *ioaddr, int pbl, int fb, int mb, + int burst_len, u32 dma_tx, u32 dma_rx); /* Dump DMA registers */ void (*dump_regs) (void __iomem *ioaddr); /* Set tx/rx threshold in the csr6 register @@ -280,7 +280,7 @@ /* Handle extra events on specific interrupts hw dependent */ void (*host_irq_status) (void __iomem *ioaddr); /* Multicast filter setting */ - void (*set_filter) (struct net_device *dev); + void (*set_filter) (struct net_device *dev, int id); /* Flow control setting */ void (*flow_ctrl) (void __iomem *ioaddr, unsigned int duplex, unsigned int fc, unsigned int pause_time);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index 54339a7..23478bf 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
@@ -61,9 +61,11 @@ }; /* GMAC HW ADDR regs */ -#define GMAC_ADDR_HIGH(reg) (0x00000040+(reg * 8)) -#define GMAC_ADDR_LOW(reg) (0x00000044+(reg * 8)) -#define GMAC_MAX_UNICAST_ADDRESSES 16 +#define GMAC_ADDR_HIGH(reg) (((reg > 15) ? 0x00000800 : 0x00000040) + \ + (reg * 8)) +#define GMAC_ADDR_LOW(reg) (((reg > 15) ? 0x00000804 : 0x00000044) + \ + (reg * 8)) +#define GMAC_MAX_PERFECT_ADDRESSES 32 #define GMAC_AN_CTRL 0x000000c0 /* AN control */ #define GMAC_AN_STATUS 0x000000c4 /* AN status */ @@ -139,6 +141,7 @@ }; #define DMA_BUS_MODE_FB 0x00010000 /* Fixed burst */ +#define DMA_BUS_MODE_MB 0x04000000 /* Mixed burst */ #define DMA_BUS_MODE_RPBL_MASK 0x003e0000 /* Rx-Programmable Burst Len */ #define DMA_BUS_MODE_RPBL_SHIFT 17 #define DMA_BUS_MODE_USP 0x00800000 @@ -205,4 +208,7 @@ #define GMAC_MMC_TX_INTR 0x108 #define GMAC_MMC_RX_CSUM_OFFLOAD 0x208 +/* Synopsys Core versions */ +#define DWMAC_CORE_3_40 34 + extern const struct stmmac_dma_ops dwmac1000_dma_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index e7cbcd9..b5e4d02 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -84,10 +84,11 @@ GMAC_ADDR_LOW(reg_n)); } -static void dwmac1000_set_filter(struct net_device *dev) +static void dwmac1000_set_filter(struct net_device *dev, int id) { void __iomem *ioaddr = (void __iomem *) dev->base_addr; unsigned int value = 0; + unsigned int perfect_addr_number; CHIP_DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n", __func__, netdev_mc_count(dev), netdev_uc_count(dev)); @@ -121,8 +122,14 @@ writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH); } + /* Extra 16 regs are available in cores newer than the 3.40. */ + if (id > DWMAC_CORE_3_40) + perfect_addr_number = GMAC_MAX_PERFECT_ADDRESSES; + else + perfect_addr_number = GMAC_MAX_PERFECT_ADDRESSES / 2; + /* Handle multiple unicast addresses (perfect filtering)*/ - if (netdev_uc_count(dev) > GMAC_MAX_UNICAST_ADDRESSES) + if (netdev_uc_count(dev) > perfect_addr_number) /* Switch to promiscuous mode is more than 16 addrs are required */ value |= GMAC_FRAME_FILTER_PR;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index 3675c57..0335000 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -31,7 +31,7 @@ #include "dwmac_dma.h" static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, - int burst_len, u32 dma_tx, u32 dma_rx) + int mb, int burst_len, u32 dma_tx, u32 dma_rx) { u32 value = readl(ioaddr + DMA_BUS_MODE); int limit; @@ -66,6 +66,10 @@ if (fb) value |= DMA_BUS_MODE_FB; + /* Mixed Burst has no effect when fb is set */ + if (mb) + value |= DMA_BUS_MODE_MB; + #ifdef CONFIG_STMMAC_DA value |= DMA_BUS_MODE_DA; /* Rx has priority over tx */ #endif
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c index efde50f..19e0f4e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
@@ -89,7 +89,7 @@ stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW); } -static void dwmac100_set_filter(struct net_device *dev) +static void dwmac100_set_filter(struct net_device *dev, int id) { void __iomem *ioaddr = (void __iomem *) dev->base_addr; u32 value = readl(ioaddr + MAC_CONTROL);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c index 92ed2e0..c2b4d55 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
@@ -33,7 +33,7 @@ #include "dwmac_dma.h" static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, int fb, - int burst_len, u32 dma_tx, u32 dma_rx) + int mb, int burst_len, u32 dma_tx, u32 dma_rx) { u32 value = readl(ioaddr + DMA_BUS_MODE); int limit;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c index f20aa12..4e0e18a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
@@ -31,6 +31,8 @@ #define DWMAC_LIB_DBG(fmt, args...) do { } while (0) #endif +#define GMAC_HI_REG_AE 0x80000000 + /* CSR1 enables the transmit DMA to check for new descriptor */ void dwmac_enable_dma_transmission(void __iomem *ioaddr) { @@ -233,7 +235,11 @@ unsigned long data; data = (addr[5] << 8) | addr[4]; - writel(data, ioaddr + high); + /* For MAC Addr registers se have to set the Address Enable (AE) + * bit that has no effect on the High Reg 0 where the bit 31 (MO) + * is RO. + */ + writel(data | GMAC_HI_REG_AE, ioaddr + high); data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; writel(data, ioaddr + low); }
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index db2de9a..6b5d060 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -85,6 +85,7 @@ struct clk *stmmac_clk; #endif int clk_csr; + int synopsys_id; }; extern int phyaddr;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 1a4cf81..7096633 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -925,6 +925,7 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) { int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0; + int mixed_burst = 0; /* Some DMA parameters can be passed from the platform; * in case of these are not passed we keep a default @@ -932,10 +933,11 @@ if (priv->plat->dma_cfg) { pbl = priv->plat->dma_cfg->pbl; fixed_burst = priv->plat->dma_cfg->fixed_burst; + mixed_burst = priv->plat->dma_cfg->mixed_burst; burst_len = priv->plat->dma_cfg->burst_len; } - return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, + return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, mixed_burst, burst_len, priv->dma_tx_phy, priv->dma_rx_phy); } @@ -1465,7 +1467,7 @@ struct stmmac_priv *priv = netdev_priv(dev); spin_lock(&priv->lock); - priv->hw->mac->set_filter(dev); + priv->hw->mac->set_filter(dev, priv->synopsys_id); spin_unlock(&priv->lock); } @@ -1638,7 +1640,7 @@ .open = stmmac_sysfs_ring_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = single_release, }; static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v) @@ -1710,7 +1712,7 @@ .open = stmmac_sysfs_dma_cap_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = single_release, }; static int stmmac_init_fs(struct net_device *dev) @@ -1806,7 +1808,7 @@ priv->hw->ring = &ring_mode_ops; /* Get and dump the chip ID */ - stmmac_get_synopsys_id(priv); + priv->synopsys_id = stmmac_get_synopsys_id(priv); /* Get the HW capability (new GMAC newer than 3.50a) */ priv->hw_cap_support = stmmac_get_hw_features(priv); @@ -1987,6 +1989,7 @@ { struct stmmac_priv *priv = netdev_priv(ndev); int dis_ic = 0; + unsigned long flags; if (!ndev || !netif_running(ndev)) return 0; @@ -1994,7 +1997,7 @@ if (priv->phydev) phy_stop(priv->phydev); - spin_lock(&priv->lock); + spin_lock_irqsave(&priv->lock, flags); netif_device_detach(ndev); netif_stop_queue(ndev); @@ -2022,18 +2025,19 @@ /* Disable clock in case of PWM is off */ stmmac_clk_disable(priv); } - spin_unlock(&priv->lock); + spin_unlock_irqrestore(&priv->lock, flags); return 0; } int stmmac_resume(struct net_device *ndev) { struct stmmac_priv *priv = netdev_priv(ndev); + unsigned long flags; if (!netif_running(ndev)) return 0; - spin_lock(&priv->lock); + spin_lock_irqsave(&priv->lock, flags); /* Power Down bit, into the PM register, is cleared * automatically as soon as a magic packet or a Wake-up frame @@ -2061,7 +2065,7 @@ netif_start_queue(ndev); - spin_unlock(&priv->lock); + spin_unlock_irqrestore(&priv->lock, flags); if (priv->phydev) phy_start(priv->phydev);
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 38e3ae9..a108db3 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -618,7 +618,7 @@ struct vnet_port *port; hlist_for_each_entry(port, n, hp, hash) { - if (!compare_ether_addr(port->raddr, skb->data)) + if (ether_addr_equal(port->raddr, skb->data)) return port; } port = NULL;
diff --git a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c index 3d501ec..96070e9 100644 --- a/drivers/net/ethernet/tile/tilepro.c +++ b/drivers/net/ethernet/tile/tilepro.c
@@ -843,7 +843,7 @@ if (!is_multicast_ether_addr(buf)) { /* Filter packets not for our address. */ const u8 *mine = dev->dev_addr; - filter = compare_ether_addr(mine, buf); + filter = !ether_addr_equal(mine, buf); } }
diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c index 5c14f82..961c832 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c
@@ -1590,8 +1590,8 @@ found = 0; oldest = NULL; list_for_each_entry(target, &wl->network_list, list) { - if (!compare_ether_addr(&target->hwinfo->bssid[2], - &scan_info->bssid[2])) { + if (ether_addr_equal(&target->hwinfo->bssid[2], + &scan_info->bssid[2])) { found = 1; pr_debug("%s: same BBS found scanned list\n", __func__); @@ -1691,8 +1691,8 @@ /* If bss specified, check it only */ if (test_bit(GELIC_WL_STAT_BSSID_SET, &wl->stat)) { - if (!compare_ether_addr(&scan_info->hwinfo->bssid[2], - wl->bssid)) { + if (ether_addr_equal(&scan_info->hwinfo->bssid[2], + wl->bssid)) { best_bss = scan_info; pr_debug("%s: bssid matched\n", __func__); break;
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index c358245..4ffcd57 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h
@@ -27,6 +27,7 @@ #include <linux/list.h> #include <linux/hyperv.h> +#include <linux/rndis.h> /* Fwd declaration */ struct hv_netvsc_packet; @@ -506,295 +507,6 @@ void *extension; }; - -/* Status codes */ - - -#ifndef STATUS_SUCCESS -#define STATUS_SUCCESS (0x00000000L) -#endif - -#ifndef STATUS_UNSUCCESSFUL -#define STATUS_UNSUCCESSFUL (0xC0000001L) -#endif - -#ifndef STATUS_PENDING -#define STATUS_PENDING (0x00000103L) -#endif - -#ifndef STATUS_INSUFFICIENT_RESOURCES -#define STATUS_INSUFFICIENT_RESOURCES (0xC000009AL) -#endif - -#ifndef STATUS_BUFFER_OVERFLOW -#define STATUS_BUFFER_OVERFLOW (0x80000005L) -#endif - -#ifndef STATUS_NOT_SUPPORTED -#define STATUS_NOT_SUPPORTED (0xC00000BBL) -#endif - -#define RNDIS_STATUS_SUCCESS (STATUS_SUCCESS) -#define RNDIS_STATUS_PENDING (STATUS_PENDING) -#define RNDIS_STATUS_NOT_RECOGNIZED (0x00010001L) -#define RNDIS_STATUS_NOT_COPIED (0x00010002L) -#define RNDIS_STATUS_NOT_ACCEPTED (0x00010003L) -#define RNDIS_STATUS_CALL_ACTIVE (0x00010007L) - -#define RNDIS_STATUS_ONLINE (0x40010003L) -#define RNDIS_STATUS_RESET_START (0x40010004L) -#define RNDIS_STATUS_RESET_END (0x40010005L) -#define RNDIS_STATUS_RING_STATUS (0x40010006L) -#define RNDIS_STATUS_CLOSED (0x40010007L) -#define RNDIS_STATUS_WAN_LINE_UP (0x40010008L) -#define RNDIS_STATUS_WAN_LINE_DOWN (0x40010009L) -#define RNDIS_STATUS_WAN_FRAGMENT (0x4001000AL) -#define RNDIS_STATUS_MEDIA_CONNECT (0x4001000BL) -#define RNDIS_STATUS_MEDIA_DISCONNECT (0x4001000CL) -#define RNDIS_STATUS_HARDWARE_LINE_UP (0x4001000DL) -#define RNDIS_STATUS_HARDWARE_LINE_DOWN (0x4001000EL) -#define RNDIS_STATUS_INTERFACE_UP (0x4001000FL) -#define RNDIS_STATUS_INTERFACE_DOWN (0x40010010L) -#define RNDIS_STATUS_MEDIA_BUSY (0x40010011L) -#define RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION (0x40010012L) -#define RNDIS_STATUS_WW_INDICATION RDIA_SPECIFIC_INDICATION -#define RNDIS_STATUS_LINK_SPEED_CHANGE (0x40010013L) - -#define RNDIS_STATUS_NOT_RESETTABLE (0x80010001L) -#define RNDIS_STATUS_SOFT_ERRORS (0x80010003L) -#define RNDIS_STATUS_HARD_ERRORS (0x80010004L) -#define RNDIS_STATUS_BUFFER_OVERFLOW (STATUS_BUFFER_OVERFLOW) - -#define RNDIS_STATUS_FAILURE (STATUS_UNSUCCESSFUL) -#define RNDIS_STATUS_RESOURCES (STATUS_INSUFFICIENT_RESOURCES) -#define RNDIS_STATUS_CLOSING (0xC0010002L) -#define RNDIS_STATUS_BAD_VERSION (0xC0010004L) -#define RNDIS_STATUS_BAD_CHARACTERISTICS (0xC0010005L) -#define RNDIS_STATUS_ADAPTER_NOT_FOUND (0xC0010006L) -#define RNDIS_STATUS_OPEN_FAILED (0xC0010007L) -#define RNDIS_STATUS_DEVICE_FAILED (0xC0010008L) -#define RNDIS_STATUS_MULTICAST_FULL (0xC0010009L) -#define RNDIS_STATUS_MULTICAST_EXISTS (0xC001000AL) -#define RNDIS_STATUS_MULTICAST_NOT_FOUND (0xC001000BL) -#define RNDIS_STATUS_REQUEST_ABORTED (0xC001000CL) -#define RNDIS_STATUS_RESET_IN_PROGRESS (0xC001000DL) -#define RNDIS_STATUS_CLOSING_INDICATING (0xC001000EL) -#define RNDIS_STATUS_NOT_SUPPORTED (STATUS_NOT_SUPPORTED) -#define RNDIS_STATUS_INVALID_PACKET (0xC001000FL) -#define RNDIS_STATUS_OPEN_LIST_FULL (0xC0010010L) -#define RNDIS_STATUS_ADAPTER_NOT_READY (0xC0010011L) -#define RNDIS_STATUS_ADAPTER_NOT_OPEN (0xC0010012L) -#define RNDIS_STATUS_NOT_INDICATING (0xC0010013L) -#define RNDIS_STATUS_INVALID_LENGTH (0xC0010014L) -#define RNDIS_STATUS_INVALID_DATA (0xC0010015L) -#define RNDIS_STATUS_BUFFER_TOO_SHORT (0xC0010016L) -#define RNDIS_STATUS_INVALID_OID (0xC0010017L) -#define RNDIS_STATUS_ADAPTER_REMOVED (0xC0010018L) -#define RNDIS_STATUS_UNSUPPORTED_MEDIA (0xC0010019L) -#define RNDIS_STATUS_GROUP_ADDRESS_IN_USE (0xC001001AL) -#define RNDIS_STATUS_FILE_NOT_FOUND (0xC001001BL) -#define RNDIS_STATUS_ERROR_READING_FILE (0xC001001CL) -#define RNDIS_STATUS_ALREADY_MAPPED (0xC001001DL) -#define RNDIS_STATUS_RESOURCE_CONFLICT (0xC001001EL) -#define RNDIS_STATUS_NO_CABLE (0xC001001FL) - -#define RNDIS_STATUS_INVALID_SAP (0xC0010020L) -#define RNDIS_STATUS_SAP_IN_USE (0xC0010021L) -#define RNDIS_STATUS_INVALID_ADDRESS (0xC0010022L) -#define RNDIS_STATUS_VC_NOT_ACTIVATED (0xC0010023L) -#define RNDIS_STATUS_DEST_OUT_OF_ORDER (0xC0010024L) -#define RNDIS_STATUS_VC_NOT_AVAILABLE (0xC0010025L) -#define RNDIS_STATUS_CELLRATE_NOT_AVAILABLE (0xC0010026L) -#define RNDIS_STATUS_INCOMPATABLE_QOS (0xC0010027L) -#define RNDIS_STATUS_AAL_PARAMS_UNSUPPORTED (0xC0010028L) -#define RNDIS_STATUS_NO_ROUTE_TO_DESTINATION (0xC0010029L) - -#define RNDIS_STATUS_TOKEN_RING_OPEN_ERROR (0xC0011000L) - -/* Object Identifiers used by NdisRequest Query/Set Information */ -/* General Objects */ -#define RNDIS_OID_GEN_SUPPORTED_LIST 0x00010101 -#define RNDIS_OID_GEN_HARDWARE_STATUS 0x00010102 -#define RNDIS_OID_GEN_MEDIA_SUPPORTED 0x00010103 -#define RNDIS_OID_GEN_MEDIA_IN_USE 0x00010104 -#define RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 -#define RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 -#define RNDIS_OID_GEN_LINK_SPEED 0x00010107 -#define RNDIS_OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 -#define RNDIS_OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 -#define RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A -#define RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B -#define RNDIS_OID_GEN_VENDOR_ID 0x0001010C -#define RNDIS_OID_GEN_VENDOR_DESCRIPTION 0x0001010D -#define RNDIS_OID_GEN_CURRENT_PACKET_FILTER 0x0001010E -#define RNDIS_OID_GEN_CURRENT_LOOKAHEAD 0x0001010F -#define RNDIS_OID_GEN_DRIVER_VERSION 0x00010110 -#define RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 -#define RNDIS_OID_GEN_PROTOCOL_OPTIONS 0x00010112 -#define RNDIS_OID_GEN_MAC_OPTIONS 0x00010113 -#define RNDIS_OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 -#define RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 -#define RNDIS_OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 -#define RNDIS_OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 -#define RNDIS_OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 -#define RNDIS_OID_GEN_MACHINE_NAME 0x0001021A -#define RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B - -#define RNDIS_OID_GEN_XMIT_OK 0x00020101 -#define RNDIS_OID_GEN_RCV_OK 0x00020102 -#define RNDIS_OID_GEN_XMIT_ERROR 0x00020103 -#define RNDIS_OID_GEN_RCV_ERROR 0x00020104 -#define RNDIS_OID_GEN_RCV_NO_BUFFER 0x00020105 - -#define RNDIS_OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 -#define RNDIS_OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 -#define RNDIS_OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 -#define RNDIS_OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 -#define RNDIS_OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 -#define RNDIS_OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 -#define RNDIS_OID_GEN_DIRECTED_BYTES_RCV 0x00020207 -#define RNDIS_OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 -#define RNDIS_OID_GEN_MULTICAST_BYTES_RCV 0x00020209 -#define RNDIS_OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A -#define RNDIS_OID_GEN_BROADCAST_BYTES_RCV 0x0002020B -#define RNDIS_OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C - -#define RNDIS_OID_GEN_RCV_CRC_ERROR 0x0002020D -#define RNDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E - -#define RNDIS_OID_GEN_GET_TIME_CAPS 0x0002020F -#define RNDIS_OID_GEN_GET_NETCARD_TIME 0x00020210 - -/* These are connection-oriented general OIDs. */ -/* These replace the above OIDs for connection-oriented media. */ -#define RNDIS_OID_GEN_CO_SUPPORTED_LIST 0x00010101 -#define RNDIS_OID_GEN_CO_HARDWARE_STATUS 0x00010102 -#define RNDIS_OID_GEN_CO_MEDIA_SUPPORTED 0x00010103 -#define RNDIS_OID_GEN_CO_MEDIA_IN_USE 0x00010104 -#define RNDIS_OID_GEN_CO_LINK_SPEED 0x00010105 -#define RNDIS_OID_GEN_CO_VENDOR_ID 0x00010106 -#define RNDIS_OID_GEN_CO_VENDOR_DESCRIPTION 0x00010107 -#define RNDIS_OID_GEN_CO_DRIVER_VERSION 0x00010108 -#define RNDIS_OID_GEN_CO_PROTOCOL_OPTIONS 0x00010109 -#define RNDIS_OID_GEN_CO_MAC_OPTIONS 0x0001010A -#define RNDIS_OID_GEN_CO_MEDIA_CONNECT_STATUS 0x0001010B -#define RNDIS_OID_GEN_CO_VENDOR_DRIVER_VERSION 0x0001010C -#define RNDIS_OID_GEN_CO_MINIMUM_LINK_SPEED 0x0001010D - -#define RNDIS_OID_GEN_CO_GET_TIME_CAPS 0x00010201 -#define RNDIS_OID_GEN_CO_GET_NETCARD_TIME 0x00010202 - -/* These are connection-oriented statistics OIDs. */ -#define RNDIS_OID_GEN_CO_XMIT_PDUS_OK 0x00020101 -#define RNDIS_OID_GEN_CO_RCV_PDUS_OK 0x00020102 -#define RNDIS_OID_GEN_CO_XMIT_PDUS_ERROR 0x00020103 -#define RNDIS_OID_GEN_CO_RCV_PDUS_ERROR 0x00020104 -#define RNDIS_OID_GEN_CO_RCV_PDUS_NO_BUFFER 0x00020105 - - -#define RNDIS_OID_GEN_CO_RCV_CRC_ERROR 0x00020201 -#define RNDIS_OID_GEN_CO_TRANSMIT_QUEUE_LENGTH 0x00020202 -#define RNDIS_OID_GEN_CO_BYTES_XMIT 0x00020203 -#define RNDIS_OID_GEN_CO_BYTES_RCV 0x00020204 -#define RNDIS_OID_GEN_CO_BYTES_XMIT_OUTSTANDING 0x00020205 -#define RNDIS_OID_GEN_CO_NETCARD_LOAD 0x00020206 - -/* These are objects for Connection-oriented media call-managers. */ -#define RNDIS_OID_CO_ADD_PVC 0xFF000001 -#define RNDIS_OID_CO_DELETE_PVC 0xFF000002 -#define RNDIS_OID_CO_GET_CALL_INFORMATION 0xFF000003 -#define RNDIS_OID_CO_ADD_ADDRESS 0xFF000004 -#define RNDIS_OID_CO_DELETE_ADDRESS 0xFF000005 -#define RNDIS_OID_CO_GET_ADDRESSES 0xFF000006 -#define RNDIS_OID_CO_ADDRESS_CHANGE 0xFF000007 -#define RNDIS_OID_CO_SIGNALING_ENABLED 0xFF000008 -#define RNDIS_OID_CO_SIGNALING_DISABLED 0xFF000009 - -/* 802.3 Objects (Ethernet) */ -#define RNDIS_OID_802_3_PERMANENT_ADDRESS 0x01010101 -#define RNDIS_OID_802_3_CURRENT_ADDRESS 0x01010102 -#define RNDIS_OID_802_3_MULTICAST_LIST 0x01010103 -#define RNDIS_OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 -#define RNDIS_OID_802_3_MAC_OPTIONS 0x01010105 - -#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 - -#define RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 -#define RNDIS_OID_802_3_XMIT_ONE_COLLISION 0x01020102 -#define RNDIS_OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 - -#define RNDIS_OID_802_3_XMIT_DEFERRED 0x01020201 -#define RNDIS_OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 -#define RNDIS_OID_802_3_RCV_OVERRUN 0x01020203 -#define RNDIS_OID_802_3_XMIT_UNDERRUN 0x01020204 -#define RNDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 -#define RNDIS_OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 -#define RNDIS_OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 - -/* Remote NDIS message types */ -#define REMOTE_NDIS_PACKET_MSG 0x00000001 -#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002 -#define REMOTE_NDIS_HALT_MSG 0x00000003 -#define REMOTE_NDIS_QUERY_MSG 0x00000004 -#define REMOTE_NDIS_SET_MSG 0x00000005 -#define REMOTE_NDIS_RESET_MSG 0x00000006 -#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007 -#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008 - -#define REMOTE_CONDIS_MP_CREATE_VC_MSG 0x00008001 -#define REMOTE_CONDIS_MP_DELETE_VC_MSG 0x00008002 -#define REMOTE_CONDIS_MP_ACTIVATE_VC_MSG 0x00008005 -#define REMOTE_CONDIS_MP_DEACTIVATE_VC_MSG 0x00008006 -#define REMOTE_CONDIS_INDICATE_STATUS_MSG 0x00008007 - -/* Remote NDIS message completion types */ -#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002 -#define REMOTE_NDIS_QUERY_CMPLT 0x80000004 -#define REMOTE_NDIS_SET_CMPLT 0x80000005 -#define REMOTE_NDIS_RESET_CMPLT 0x80000006 -#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008 - -#define REMOTE_CONDIS_MP_CREATE_VC_CMPLT 0x80008001 -#define REMOTE_CONDIS_MP_DELETE_VC_CMPLT 0x80008002 -#define REMOTE_CONDIS_MP_ACTIVATE_VC_CMPLT 0x80008005 -#define REMOTE_CONDIS_MP_DEACTIVATE_VC_CMPLT 0x80008006 - -/* - * Reserved message type for private communication between lower-layer host - * driver and remote device, if necessary. - */ -#define REMOTE_NDIS_BUS_MSG 0xff000001 - -/* Defines for DeviceFlags in struct rndis_initialize_complete */ -#define RNDIS_DF_CONNECTIONLESS 0x00000001 -#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002 -#define RNDIS_DF_RAW_DATA 0x00000004 - -/* Remote NDIS medium types. */ -#define RNDIS_MEDIUM_802_3 0x00000000 -#define RNDIS_MEDIUM_802_5 0x00000001 -#define RNDIS_MEDIUM_FDDI 0x00000002 -#define RNDIS_MEDIUM_WAN 0x00000003 -#define RNDIS_MEDIUM_LOCAL_TALK 0x00000004 -#define RNDIS_MEDIUM_ARCNET_RAW 0x00000006 -#define RNDIS_MEDIUM_ARCNET_878_2 0x00000007 -#define RNDIS_MEDIUM_ATM 0x00000008 -#define RNDIS_MEDIUM_WIRELESS_WAN 0x00000009 -#define RNDIS_MEDIUM_IRDA 0x0000000a -#define RNDIS_MEDIUM_CO_WAN 0x0000000b -/* Not a real medium, defined as an upper-bound */ -#define RNDIS_MEDIUM_MAX 0x0000000d - - -/* Remote NDIS medium connection states. */ -#define RNDIS_MEDIA_STATE_CONNECTED 0x00000000 -#define RNDIS_MEDIA_STATE_DISCONNECTED 0x00000001 - -/* Remote NDIS version numbers */ -#define RNDIS_MAJOR_VERSION 0x00000001 -#define RNDIS_MINOR_VERSION 0x00000000 - - /* NdisInitialize message */ struct rndis_initialize_request { u32 req_id;
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index d6be64b..981ebb1 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c
@@ -129,8 +129,8 @@ netdev = net_device->ndev; switch (rndis_msg->ndis_msg_type) { - case REMOTE_NDIS_PACKET_MSG: - netdev_dbg(netdev, "REMOTE_NDIS_PACKET_MSG (len %u, " + case RNDIS_MSG_PACKET: + netdev_dbg(netdev, "RNDIS_MSG_PACKET (len %u, " "data offset %u data len %u, # oob %u, " "oob offset %u, oob len %u, pkt offset %u, " "pkt len %u\n", @@ -144,8 +144,8 @@ rndis_msg->msg.pkt.per_pkt_info_len); break; - case REMOTE_NDIS_INITIALIZE_CMPLT: - netdev_dbg(netdev, "REMOTE_NDIS_INITIALIZE_CMPLT " + case RNDIS_MSG_INIT_C: + netdev_dbg(netdev, "RNDIS_MSG_INIT_C " "(len %u, id 0x%x, status 0x%x, major %d, minor %d, " "device flags %d, max xfer size 0x%x, max pkts %u, " "pkt aligned %u)\n", @@ -162,8 +162,8 @@ pkt_alignment_factor); break; - case REMOTE_NDIS_QUERY_CMPLT: - netdev_dbg(netdev, "REMOTE_NDIS_QUERY_CMPLT " + case RNDIS_MSG_QUERY_C: + netdev_dbg(netdev, "RNDIS_MSG_QUERY_C " "(len %u, id 0x%x, status 0x%x, buf len %u, " "buf offset %u)\n", rndis_msg->msg_len, @@ -175,16 +175,16 @@ info_buf_offset); break; - case REMOTE_NDIS_SET_CMPLT: + case RNDIS_MSG_SET_C: netdev_dbg(netdev, - "REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)\n", + "RNDIS_MSG_SET_C (len %u, id 0x%x, status 0x%x)\n", rndis_msg->msg_len, rndis_msg->msg.set_complete.req_id, rndis_msg->msg.set_complete.status); break; - case REMOTE_NDIS_INDICATE_STATUS_MSG: - netdev_dbg(netdev, "REMOTE_NDIS_INDICATE_STATUS_MSG " + case RNDIS_MSG_INDICATE: + netdev_dbg(netdev, "RNDIS_MSG_INDICATE " "(len %u, status 0x%x, buf len %u, buf offset %u)\n", rndis_msg->msg_len, rndis_msg->msg.indicate_status.status, @@ -264,14 +264,14 @@ sizeof(struct rndis_filter_packet)); if (resp->ndis_msg_type == - REMOTE_NDIS_RESET_CMPLT) { + RNDIS_MSG_RESET_C) { /* does not have a request id field */ request->response_msg.msg.reset_complete. - status = STATUS_BUFFER_OVERFLOW; + status = RNDIS_STATUS_BUFFER_OVERFLOW; } else { request->response_msg.msg. init_complete.status = - STATUS_BUFFER_OVERFLOW; + RNDIS_STATUS_BUFFER_OVERFLOW; } } @@ -415,19 +415,19 @@ dump_rndis_message(dev, rndis_msg); switch (rndis_msg->ndis_msg_type) { - case REMOTE_NDIS_PACKET_MSG: + case RNDIS_MSG_PACKET: /* data msg */ rndis_filter_receive_data(rndis_dev, rndis_msg, pkt); break; - case REMOTE_NDIS_INITIALIZE_CMPLT: - case REMOTE_NDIS_QUERY_CMPLT: - case REMOTE_NDIS_SET_CMPLT: + case RNDIS_MSG_INIT_C: + case RNDIS_MSG_QUERY_C: + case RNDIS_MSG_SET_C: /* completion msgs */ rndis_filter_receive_response(rndis_dev, rndis_msg); break; - case REMOTE_NDIS_INDICATE_STATUS_MSG: + case RNDIS_MSG_INDICATE: /* notification msgs */ rndis_filter_receive_indicate_status(rndis_dev, rndis_msg); break; @@ -456,7 +456,7 @@ return -EINVAL; *result_size = 0; - request = get_rndis_request(dev, REMOTE_NDIS_QUERY_MSG, + request = get_rndis_request(dev, RNDIS_MSG_QUERY, RNDIS_MESSAGE_SIZE(struct rndis_query_request)); if (!request) { ret = -ENOMEM; @@ -536,7 +536,7 @@ ndev = dev->net_dev->ndev; - request = get_rndis_request(dev, REMOTE_NDIS_SET_MSG, + request = get_rndis_request(dev, RNDIS_MSG_SET, RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32)); if (!request) { @@ -588,7 +588,7 @@ u32 status; int ret, t; - request = get_rndis_request(dev, REMOTE_NDIS_INITIALIZE_MSG, + request = get_rndis_request(dev, RNDIS_MSG_INIT, RNDIS_MESSAGE_SIZE(struct rndis_initialize_request)); if (!request) { ret = -ENOMEM; @@ -641,7 +641,7 @@ struct rndis_halt_request *halt; /* Attempt to do a rndis device halt */ - request = get_rndis_request(dev, REMOTE_NDIS_HALT_MSG, + request = get_rndis_request(dev, RNDIS_MSG_HALT, RNDIS_MESSAGE_SIZE(struct rndis_halt_request)); if (!request) goto cleanup; @@ -805,7 +805,7 @@ if (isvlan) rndis_msg_size += NDIS_VLAN_PPI_SIZE; - rndis_msg->ndis_msg_type = REMOTE_NDIS_PACKET_MSG; + rndis_msg->ndis_msg_type = RNDIS_MSG_PACKET; rndis_msg->msg_len = pkt->total_data_buflen + rndis_msg_size;
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 9653ed6..66a9bfe 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c
@@ -57,7 +57,7 @@ struct hlist_node *n; hlist_for_each_entry_rcu(vlan, n, &port->vlan_hash[addr[5]], hlist) { - if (!compare_ether_addr_64bits(vlan->dev->dev_addr, addr)) + if (ether_addr_equal_64bits(vlan->dev->dev_addr, addr)) return vlan; } return NULL; @@ -96,7 +96,7 @@ * currently in use by the underlying device or * another macvlan. */ - if (!compare_ether_addr_64bits(port->dev->dev_addr, addr)) + if (ether_addr_equal_64bits(port->dev->dev_addr, addr)) return 1; if (macvlan_hash_lookup(port, addr)) @@ -118,8 +118,7 @@ return vlan->forward(dev, skb); skb->dev = dev; - if (!compare_ether_addr_64bits(eth->h_dest, - dev->broadcast)) + if (ether_addr_equal_64bits(eth->h_dest, dev->broadcast)) skb->pkt_type = PACKET_BROADCAST; else skb->pkt_type = PACKET_MULTICAST; @@ -259,7 +258,7 @@ xmit_world: skb->ip_summed = ip_summed; - skb_set_dev(skb, vlan->lowerdev); + skb->dev = vlan->lowerdev; return dev_queue_xmit(skb); }
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 163559c..2ee56de 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c
@@ -1,5 +1,6 @@ #include <linux/etherdevice.h> #include <linux/if_macvlan.h> +#include <linux/if_vlan.h> #include <linux/interrupt.h> #include <linux/nsproxy.h> #include <linux/compat.h> @@ -782,6 +783,8 @@ struct macvlan_dev *vlan; int ret; int vnet_hdr_len = 0; + int vlan_offset = 0; + int copied; if (q->flags & IFF_VNET_HDR) { struct virtio_net_hdr vnet_hdr; @@ -796,18 +799,48 @@ if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr))) return -EFAULT; } + copied = vnet_hdr_len; - len = min_t(int, skb->len, len); + if (!vlan_tx_tag_present(skb)) + len = min_t(int, skb->len, len); + else { + int copy; + struct { + __be16 h_vlan_proto; + __be16 h_vlan_TCI; + } veth; + veth.h_vlan_proto = htons(ETH_P_8021Q); + veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb)); - ret = skb_copy_datagram_const_iovec(skb, 0, iv, vnet_hdr_len, len); + vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); + len = min_t(int, skb->len + VLAN_HLEN, len); + copy = min_t(int, vlan_offset, len); + ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); + len -= copy; + copied += copy; + if (ret || !len) + goto done; + + copy = min_t(int, sizeof(veth), len); + ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy); + len -= copy; + copied += copy; + if (ret || !len) + goto done; + } + + ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); + copied += len; + +done: rcu_read_lock_bh(); vlan = rcu_dereference_bh(q->vlan); if (vlan) - macvlan_count_rx(vlan, len, ret == 0, 0); + macvlan_count_rx(vlan, copied - vnet_hdr_len, ret == 0, 0); rcu_read_unlock_bh(); - return ret ? ret : (len + vnet_hdr_len); + return ret ? ret : copied; } static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb,
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 83d5c9f..683ef1c 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c
@@ -88,7 +88,7 @@ .dev_release = mdiobus_release, }; -#ifdef CONFIG_OF_MDIO +#if IS_ENABLED(CONFIG_OF_MDIO) /* Helper function for of_mdio_find_bus */ static int of_mdio_bus_match(struct device *dev, void *mdio_bus_np) {
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index e8c42d6..de86a55 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c
@@ -207,7 +207,7 @@ * Description: Reads the ID registers of the PHY at @addr on the * @bus, stores it in @phy_id and returns zero on success. */ -int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id) +static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id) { int phy_reg; @@ -230,7 +230,6 @@ return 0; } -EXPORT_SYMBOL(get_phy_id); /** * get_phy_device - reads the specified PHY device and returns its @phy_device struct
diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c index af95a98..a031f6b 100644 --- a/drivers/net/ppp/ppp_async.c +++ b/drivers/net/ppp/ppp_async.c
@@ -613,7 +613,7 @@ *buf++ = PPP_FLAG; ap->olim = buf; - kfree_skb(ap->tpkt); + consume_skb(ap->tpkt); ap->tpkt = NULL; return 1; }
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 21d7151..5c05572 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c
@@ -1092,13 +1092,13 @@ new_skb->data, skb->len + 2, compressor_skb_size); if (len > 0 && (ppp->flags & SC_CCP_UP)) { - kfree_skb(skb); + consume_skb(skb); skb = new_skb; skb_put(skb, len); skb_pull(skb, 2); /* pull off A/C bytes */ } else if (len == 0) { /* didn't compress, or CCP not up yet */ - kfree_skb(new_skb); + consume_skb(new_skb); new_skb = skb; } else { /* @@ -1112,7 +1112,7 @@ if (net_ratelimit()) netdev_err(ppp->dev, "ppp: compressor dropped pkt\n"); kfree_skb(skb); - kfree_skb(new_skb); + consume_skb(new_skb); new_skb = NULL; } return new_skb; @@ -1178,7 +1178,7 @@ !(ppp->flags & SC_NO_TCP_CCID)); if (cp == skb->data + 2) { /* didn't compress */ - kfree_skb(new_skb); + consume_skb(new_skb); } else { if (cp[0] & SL_TYPE_COMPRESSED_TCP) { proto = PPP_VJC_COMP; @@ -1187,7 +1187,7 @@ proto = PPP_VJC_UNCOMP; cp[0] = skb->data[2]; } - kfree_skb(skb); + consume_skb(skb); skb = new_skb; cp = skb_put(skb, len + 2); cp[0] = 0; @@ -1703,7 +1703,7 @@ } skb_reserve(ns, 2); skb_copy_bits(skb, 0, skb_put(ns, skb->len), skb->len); - kfree_skb(skb); + consume_skb(skb); skb = ns; } else @@ -1851,7 +1851,7 @@ goto err; } - kfree_skb(skb); + consume_skb(skb); skb = ns; skb_put(skb, len); skb_pull(skb, 2); /* pull off the A/C bytes */
diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c index 55e466c..1a12033 100644 --- a/drivers/net/ppp/ppp_synctty.c +++ b/drivers/net/ppp/ppp_synctty.c
@@ -588,7 +588,7 @@ skb_reserve(npkt,2); skb_copy_from_linear_data(skb, skb_put(npkt, skb->len), skb->len); - kfree_skb(skb); + consume_skb(skb); skb = npkt; } skb_push(skb,2); @@ -656,7 +656,7 @@ if (sent < ap->tpkt->len) { tty_stuffed = 1; } else { - kfree_skb(ap->tpkt); + consume_skb(ap->tpkt); ap->tpkt = NULL; clear_bit(XMIT_FULL, &ap->xmit_flags); done = 1;
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c index 2fa1a9b..cbf7047 100644 --- a/drivers/net/ppp/pppoe.c +++ b/drivers/net/ppp/pppoe.c
@@ -201,7 +201,7 @@ return 0; } -static struct pppox_sock *__delete_item(struct pppoe_net *pn, __be16 sid, +static void __delete_item(struct pppoe_net *pn, __be16 sid, char *addr, int ifindex) { int hash = hash_item(sid, addr); @@ -220,8 +220,6 @@ src = &ret->next; ret = ret->next; } - - return ret; } /********************************************************************** @@ -264,16 +262,12 @@ return pppox_sock; } -static inline struct pppox_sock *delete_item(struct pppoe_net *pn, __be16 sid, +static inline void delete_item(struct pppoe_net *pn, __be16 sid, char *addr, int ifindex) { - struct pppox_sock *ret; - write_lock_bh(&pn->hash_lock); - ret = __delete_item(pn, sid, addr, ifindex); + __delete_item(pn, sid, addr, ifindex); write_unlock_bh(&pn->hash_lock); - - return ret; } /*************************************************************************** @@ -990,8 +984,10 @@ if (skb) { total_len = min_t(size_t, total_len, skb->len); error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len); - if (error == 0) - error = total_len; + if (error == 0) { + consume_skb(skb); + return total_len; + } } kfree_skb(skb);
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index 72b50f5..1c98321 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c
@@ -209,7 +209,7 @@ } if (skb->sk) skb_set_owner_w(new_skb, skb->sk); - kfree_skb(skb); + consume_skb(skb); skb = new_skb; }
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c deleted file mode 100644 index 0924f57..0000000 --- a/drivers/net/tokenring/3c359.c +++ /dev/null
@@ -1,1831 +0,0 @@ -/* - * 3c359.c (c) 2000 Mike Phillips (mikep@linuxtr.net) All Rights Reserved - * - * Linux driver for 3Com 3c359 Tokenlink Velocity XL PCI NIC - * - * Base Driver Olympic: - * Written 1999 Peter De Schrijver & Mike Phillips - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * 7/17/00 - Clean up, version number 0.9.0. Ready to release to the world. - * - * 2/16/01 - Port up to kernel 2.4.2 ready for submission into the kernel. - * 3/05/01 - Last clean up stuff before submission. - * 2/15/01 - Finally, update to new pci api. - * - * To Do: - */ - -/* - * Technical Card Details - * - * All access to data is done with 16/8 bit transfers. The transfer - * method really sucks. You can only read or write one location at a time. - * - * Also, the microcode for the card must be uploaded if the card does not have - * the flashrom on board. This is a 28K bloat in the driver when compiled - * as a module. - * - * Rx is very simple, status into a ring of descriptors, dma data transfer, - * interrupts to tell us when a packet is received. - * - * Tx is a little more interesting. Similar scenario, descriptor and dma data - * transfers, but we don't have to interrupt the card to tell it another packet - * is ready for transmission, we are just doing simple memory writes, not io or mmio - * writes. The card can be set up to simply poll on the next - * descriptor pointer and when this value is non-zero will automatically download - * the next packet. The card then interrupts us when the packet is done. - * - */ - -#define XL_DEBUG 0 - -#include <linux/jiffies.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/timer.h> -#include <linux/in.h> -#include <linux/ioport.h> -#include <linux/string.h> -#include <linux/proc_fs.h> -#include <linux/ptrace.h> -#include <linux/skbuff.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/trdevice.h> -#include <linux/stddef.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/spinlock.h> -#include <linux/bitops.h> -#include <linux/firmware.h> -#include <linux/slab.h> - -#include <net/checksum.h> - -#include <asm/io.h> - -#include "3c359.h" - -static char version[] __devinitdata = -"3c359.c v1.2.0 2/17/01 - Mike Phillips (mikep@linuxtr.net)" ; - -#define FW_NAME "3com/3C359.bin" -MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ; -MODULE_DESCRIPTION("3Com 3C359 Velocity XL Token Ring Adapter Driver\n") ; -MODULE_FIRMWARE(FW_NAME); - -/* Module parameters */ - -/* Ring Speed 0,4,16 - * 0 = Autosense - * 4,16 = Selected speed only, no autosense - * This allows the card to be the first on the ring - * and become the active monitor. - * - * WARNING: Some hubs will allow you to insert - * at the wrong speed. - * - * The adapter will _not_ fail to open if there are no - * active monitors on the ring, it will simply open up in - * its last known ringspeed if no ringspeed is specified. - */ - -static int ringspeed[XL_MAX_ADAPTERS] = {0,} ; - -module_param_array(ringspeed, int, NULL, 0); -MODULE_PARM_DESC(ringspeed,"3c359: Ringspeed selection - 4,16 or 0") ; - -/* Packet buffer size */ - -static int pkt_buf_sz[XL_MAX_ADAPTERS] = {0,} ; - -module_param_array(pkt_buf_sz, int, NULL, 0) ; -MODULE_PARM_DESC(pkt_buf_sz,"3c359: Initial buffer size") ; -/* Message Level */ - -static int message_level[XL_MAX_ADAPTERS] = {0,} ; - -module_param_array(message_level, int, NULL, 0) ; -MODULE_PARM_DESC(message_level, "3c359: Level of reported messages") ; -/* - * This is a real nasty way of doing this, but otherwise you - * will be stuck with 1555 lines of hex #'s in the code. - */ - -static DEFINE_PCI_DEVICE_TABLE(xl_pci_tbl) = -{ - {PCI_VENDOR_ID_3COM,PCI_DEVICE_ID_3COM_3C359, PCI_ANY_ID, PCI_ANY_ID, }, - { } /* terminate list */ -}; -MODULE_DEVICE_TABLE(pci,xl_pci_tbl) ; - -static int xl_init(struct net_device *dev); -static int xl_open(struct net_device *dev); -static int xl_open_hw(struct net_device *dev) ; -static int xl_hw_reset(struct net_device *dev); -static netdev_tx_t xl_xmit(struct sk_buff *skb, struct net_device *dev); -static void xl_dn_comp(struct net_device *dev); -static int xl_close(struct net_device *dev); -static void xl_set_rx_mode(struct net_device *dev); -static irqreturn_t xl_interrupt(int irq, void *dev_id); -static int xl_set_mac_address(struct net_device *dev, void *addr) ; -static void xl_arb_cmd(struct net_device *dev); -static void xl_asb_cmd(struct net_device *dev) ; -static void xl_srb_cmd(struct net_device *dev, int srb_cmd) ; -static void xl_wait_misr_flags(struct net_device *dev) ; -static int xl_change_mtu(struct net_device *dev, int mtu); -static void xl_srb_bh(struct net_device *dev) ; -static void xl_asb_bh(struct net_device *dev) ; -static void xl_reset(struct net_device *dev) ; -static void xl_freemem(struct net_device *dev) ; - - -/* EEProm Access Functions */ -static u16 xl_ee_read(struct net_device *dev, int ee_addr) ; -static void xl_ee_write(struct net_device *dev, int ee_addr, u16 ee_value) ; - -/* Debugging functions */ -#if XL_DEBUG -static void print_tx_state(struct net_device *dev) ; -static void print_rx_state(struct net_device *dev) ; - -static void print_tx_state(struct net_device *dev) -{ - - struct xl_private *xl_priv = netdev_priv(dev); - struct xl_tx_desc *txd ; - u8 __iomem *xl_mmio = xl_priv->xl_mmio ; - int i ; - - printk("tx_ring_head: %d, tx_ring_tail: %d, free_ent: %d\n",xl_priv->tx_ring_head, - xl_priv->tx_ring_tail, xl_priv->free_ring_entries) ; - printk("Ring , Address , FSH , DnNextPtr, Buffer, Buffer_Len\n"); - for (i = 0; i < 16; i++) { - txd = &(xl_priv->xl_tx_ring[i]) ; - printk("%d, %08lx, %08x, %08x, %08x, %08x\n", i, virt_to_bus(txd), - txd->framestartheader, txd->dnnextptr, txd->buffer, txd->buffer_length ) ; - } - - printk("DNLISTPTR = %04x\n", readl(xl_mmio + MMIO_DNLISTPTR) ); - - printk("DmaCtl = %04x\n", readl(xl_mmio + MMIO_DMA_CTRL) ); - printk("Queue status = %0x\n",netif_running(dev) ) ; -} - -static void print_rx_state(struct net_device *dev) -{ - - struct xl_private *xl_priv = netdev_priv(dev); - struct xl_rx_desc *rxd ; - u8 __iomem *xl_mmio = xl_priv->xl_mmio ; - int i ; - - printk("rx_ring_tail: %d\n", xl_priv->rx_ring_tail); - printk("Ring , Address , FrameState , UPNextPtr, FragAddr, Frag_Len\n"); - for (i = 0; i < 16; i++) { - /* rxd = (struct xl_rx_desc *)xl_priv->rx_ring_dma_addr + (i * sizeof(struct xl_rx_desc)) ; */ - rxd = &(xl_priv->xl_rx_ring[i]) ; - printk("%d, %08lx, %08x, %08x, %08x, %08x\n", i, virt_to_bus(rxd), - rxd->framestatus, rxd->upnextptr, rxd->upfragaddr, rxd->upfraglen ) ; - } - - printk("UPLISTPTR = %04x\n", readl(xl_mmio + MMIO_UPLISTPTR)); - - printk("DmaCtl = %04x\n", readl(xl_mmio + MMIO_DMA_CTRL)); - printk("Queue status = %0x\n",netif_running(dev)); -} -#endif - -/* - * Read values from the on-board EEProm. This looks very strange - * but you have to wait for the EEProm to get/set the value before - * passing/getting the next value from the nic. As with all requests - * on this nic it has to be done in two stages, a) tell the nic which - * memory address you want to access and b) pass/get the value from the nic. - * With the EEProm, you have to wait before and between access a) and b). - * As this is only read at initialization time and the wait period is very - * small we shouldn't have to worry about scheduling issues. - */ - -static u16 xl_ee_read(struct net_device *dev, int ee_addr) -{ - struct xl_private *xl_priv = netdev_priv(dev); - u8 __iomem *xl_mmio = xl_priv->xl_mmio ; - - /* Wait for EEProm to not be busy */ - writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ; - - /* Tell EEProm what we want to do and where */ - writel(IO_WORD_WRITE | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writew(EEREAD + ee_addr, xl_mmio + MMIO_MACDATA) ; - - /* Wait for EEProm to not be busy */ - writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ; - - /* Tell EEProm what we want to do and where */ - writel(IO_WORD_WRITE | EECONTROL , xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writew(EEREAD + ee_addr, xl_mmio + MMIO_MACDATA) ; - - /* Finally read the value from the EEProm */ - writel(IO_WORD_READ | EEDATA , xl_mmio + MMIO_MAC_ACCESS_CMD) ; - return readw(xl_mmio + MMIO_MACDATA) ; -} - -/* - * Write values to the onboard eeprom. As with eeprom read you need to - * set which location to write, wait, value to write, wait, with the - * added twist of having to enable eeprom writes as well. - */ - -static void xl_ee_write(struct net_device *dev, int ee_addr, u16 ee_value) -{ - struct xl_private *xl_priv = netdev_priv(dev); - u8 __iomem *xl_mmio = xl_priv->xl_mmio ; - - /* Wait for EEProm to not be busy */ - writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ; - - /* Enable write/erase */ - writel(IO_WORD_WRITE | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writew(EE_ENABLE_WRITE, xl_mmio + MMIO_MACDATA) ; - - /* Wait for EEProm to not be busy */ - writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ; - - /* Put the value we want to write into EEDATA */ - writel(IO_WORD_WRITE | EEDATA, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writew(ee_value, xl_mmio + MMIO_MACDATA) ; - - /* Tell EEProm to write eevalue into ee_addr */ - writel(IO_WORD_WRITE | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writew(EEWRITE + ee_addr, xl_mmio + MMIO_MACDATA) ; - - /* Wait for EEProm to not be busy, to ensure write gets done */ - writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ; - - return ; -} - -static const struct net_device_ops xl_netdev_ops = { - .ndo_open = xl_open, - .ndo_stop = xl_close, - .ndo_start_xmit = xl_xmit, - .ndo_change_mtu = xl_change_mtu, - .ndo_set_rx_mode = xl_set_rx_mode, - .ndo_set_mac_address = xl_set_mac_address, -}; - -static int __devinit xl_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct net_device *dev ; - struct xl_private *xl_priv ; - static int card_no = -1 ; - int i ; - - card_no++ ; - - if (pci_enable_device(pdev)) { - return -ENODEV ; - } - - pci_set_master(pdev); - - if ((i = pci_request_regions(pdev,"3c359"))) { - return i ; - } - - /* - * Allowing init_trdev to allocate the private data will align - * xl_private on a 32 bytes boundary which we need for the rx/tx - * descriptors - */ - - dev = alloc_trdev(sizeof(struct xl_private)) ; - if (!dev) { - pci_release_regions(pdev) ; - return -ENOMEM ; - } - xl_priv = netdev_priv(dev); - -#if XL_DEBUG - printk("pci_device: %p, dev:%p, dev->priv: %p, ba[0]: %10x, ba[1]:%10x\n", - pdev, dev, netdev_priv(dev), (unsigned int)pdev->resource[0].start, (unsigned int)pdev->resource[1].start); -#endif - - dev->irq=pdev->irq; - dev->base_addr=pci_resource_start(pdev,0) ; - xl_priv->xl_card_name = pci_name(pdev); - xl_priv->xl_mmio=ioremap(pci_resource_start(pdev,1), XL_IO_SPACE); - xl_priv->pdev = pdev ; - - if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) ) - xl_priv->pkt_buf_sz = PKT_BUF_SZ ; - else - xl_priv->pkt_buf_sz = pkt_buf_sz[card_no] ; - - dev->mtu = xl_priv->pkt_buf_sz - TR_HLEN ; - xl_priv->xl_ring_speed = ringspeed[card_no] ; - xl_priv->xl_message_level = message_level[card_no] ; - xl_priv->xl_functional_addr[0] = xl_priv->xl_functional_addr[1] = xl_priv->xl_functional_addr[2] = xl_priv->xl_functional_addr[3] = 0 ; - xl_priv->xl_copy_all_options = 0 ; - - if((i = xl_init(dev))) { - iounmap(xl_priv->xl_mmio) ; - free_netdev(dev) ; - pci_release_regions(pdev) ; - return i ; - } - - dev->netdev_ops = &xl_netdev_ops; - SET_NETDEV_DEV(dev, &pdev->dev); - - pci_set_drvdata(pdev,dev) ; - if ((i = register_netdev(dev))) { - printk(KERN_ERR "3C359, register netdev failed\n") ; - pci_set_drvdata(pdev,NULL) ; - iounmap(xl_priv->xl_mmio) ; - free_netdev(dev) ; - pci_release_regions(pdev) ; - return i ; - } - - printk(KERN_INFO "3C359: %s registered as: %s\n",xl_priv->xl_card_name,dev->name) ; - - return 0; -} - -static int xl_init_firmware(struct xl_private *xl_priv) -{ - int err; - - err = request_firmware(&xl_priv->fw, FW_NAME, &xl_priv->pdev->dev); - if (err) { - printk(KERN_ERR "Failed to load firmware \"%s\"\n", FW_NAME); - return err; - } - - if (xl_priv->fw->size < 16) { - printk(KERN_ERR "Bogus length %zu in \"%s\"\n", - xl_priv->fw->size, FW_NAME); - release_firmware(xl_priv->fw); - err = -EINVAL; - } - - return err; -} - -static int __devinit xl_init(struct net_device *dev) -{ - struct xl_private *xl_priv = netdev_priv(dev); - int err; - - printk(KERN_INFO "%s\n", version); - printk(KERN_INFO "%s: I/O at %hx, MMIO at %p, using irq %d\n", - xl_priv->xl_card_name, (unsigned int)dev->base_addr ,xl_priv->xl_mmio, dev->irq); - - spin_lock_init(&xl_priv->xl_lock) ; - - err = xl_init_firmware(xl_priv); - if (err == 0) - err = xl_hw_reset(dev); - - return err; -} - - -/* - * Hardware reset. This needs to be a separate entity as we need to reset the card - * when we change the EEProm settings. - */ - -static int xl_hw_reset(struct net_device *dev) -{ - struct xl_private *xl_priv = netdev_priv(dev); - u8 __iomem *xl_mmio = xl_priv->xl_mmio ; - unsigned long t ; - u16 i ; - u16 result_16 ; - u8 result_8 ; - u16 start ; - int j ; - - if (xl_priv->fw == NULL) - return -EINVAL; - - /* - * Reset the card. If the card has got the microcode on board, we have - * missed the initialization interrupt, so we must always do this. - */ - - writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ; - - /* - * Must wait for cmdInProgress bit (12) to clear before continuing with - * card configuration. - */ - - t=jiffies; - while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { - schedule(); - if (time_after(jiffies, t + 40 * HZ)) { - printk(KERN_ERR "%s: 3COM 3C359 Velocity XL card not responding to global reset.\n", dev->name); - return -ENODEV; - } - } - - /* - * Enable pmbar by setting bit in CPAttention - */ - - writel( (IO_BYTE_READ | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; - result_8 = readb(xl_mmio + MMIO_MACDATA) ; - result_8 = result_8 | CPA_PMBARVIS ; - writel( (IO_BYTE_WRITE | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(result_8, xl_mmio + MMIO_MACDATA) ; - - /* - * Read cpHold bit in pmbar, if cleared we have got Flashrom on board. - * If not, we need to upload the microcode to the card - */ - - writel( (IO_WORD_READ | PMBAR),xl_mmio + MMIO_MAC_ACCESS_CMD); - -#if XL_DEBUG - printk(KERN_INFO "Read from PMBAR = %04x\n", readw(xl_mmio + MMIO_MACDATA)); -#endif - - if ( readw( (xl_mmio + MMIO_MACDATA)) & PMB_CPHOLD ) { - - /* Set PmBar, privateMemoryBase bits (8:2) to 0 */ - - writel( (IO_WORD_READ | PMBAR),xl_mmio + MMIO_MAC_ACCESS_CMD); - result_16 = readw(xl_mmio + MMIO_MACDATA) ; - result_16 = result_16 & ~((0x7F) << 2) ; - writel( (IO_WORD_WRITE | PMBAR), xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writew(result_16,xl_mmio + MMIO_MACDATA) ; - - /* Set CPAttention, memWrEn bit */ - - writel( (IO_BYTE_READ | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; - result_8 = readb(xl_mmio + MMIO_MACDATA) ; - result_8 = result_8 | CPA_MEMWREN ; - writel( (IO_BYTE_WRITE | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(result_8, xl_mmio + MMIO_MACDATA) ; - - /* - * Now to write the microcode into the shared ram - * The microcode must finish at position 0xFFFF, - * so we must subtract to get the start position for the code - * - * Looks strange but ensures compiler only uses - * 16 bit unsigned int - */ - start = (0xFFFF - (xl_priv->fw->size) + 1) ; - - printk(KERN_INFO "3C359: Uploading Microcode: "); - - for (i = start, j = 0; j < xl_priv->fw->size; i++, j++) { - writel(MEM_BYTE_WRITE | 0XD0000 | i, - xl_mmio + MMIO_MAC_ACCESS_CMD); - writeb(xl_priv->fw->data[j], xl_mmio + MMIO_MACDATA); - if (j % 1024 == 0) - printk("."); - } - printk("\n") ; - - for (i = 0; i < 16; i++) { - writel((MEM_BYTE_WRITE | 0xDFFF0) + i, - xl_mmio + MMIO_MAC_ACCESS_CMD); - writeb(xl_priv->fw->data[xl_priv->fw->size - 16 + i], - xl_mmio + MMIO_MACDATA); - } - - /* - * Have to write the start address of the upload to FFF4, but - * the address must be >> 4. You do not want to know how long - * it took me to discover this. - */ - - writel(MEM_WORD_WRITE | 0xDFFF4, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writew(start >> 4, xl_mmio + MMIO_MACDATA); - - /* Clear the CPAttention, memWrEn Bit */ - - writel( (IO_BYTE_READ | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; - result_8 = readb(xl_mmio + MMIO_MACDATA) ; - result_8 = result_8 & ~CPA_MEMWREN ; - writel( (IO_BYTE_WRITE | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(result_8, xl_mmio + MMIO_MACDATA) ; - - /* Clear the cpHold bit in pmbar */ - - writel( (IO_WORD_READ | PMBAR),xl_mmio + MMIO_MAC_ACCESS_CMD); - result_16 = readw(xl_mmio + MMIO_MACDATA) ; - result_16 = result_16 & ~PMB_CPHOLD ; - writel( (IO_WORD_WRITE | PMBAR), xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writew(result_16,xl_mmio + MMIO_MACDATA) ; - - - } /* If microcode upload required */ - - /* - * The card should now go though a self test procedure and get itself ready - * to be opened, we must wait for an srb response with the initialization - * information. - */ - -#if XL_DEBUG - printk(KERN_INFO "%s: Microcode uploaded, must wait for the self test to complete\n", dev->name); -#endif - - writew(SETINDENABLE | 0xFFF, xl_mmio + MMIO_COMMAND) ; - - t=jiffies; - while ( !(readw(xl_mmio + MMIO_INTSTATUS_AUTO) & INTSTAT_SRB) ) { - schedule(); - if (time_after(jiffies, t + 15 * HZ)) { - printk(KERN_ERR "3COM 3C359 Velocity XL card not responding.\n"); - return -ENODEV; - } - } - - /* - * Write the RxBufArea with D000, RxEarlyThresh, TxStartThresh, - * DnPriReqThresh, read the tech docs if you want to know what - * values they need to be. - */ - - writel(MMIO_WORD_WRITE | RXBUFAREA, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writew(0xD000, xl_mmio + MMIO_MACDATA) ; - - writel(MMIO_WORD_WRITE | RXEARLYTHRESH, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writew(0X0020, xl_mmio + MMIO_MACDATA) ; - - writew( SETTXSTARTTHRESH | 0x40 , xl_mmio + MMIO_COMMAND) ; - - writeb(0x04, xl_mmio + MMIO_DNBURSTTHRESH) ; - writeb(0x04, xl_mmio + DNPRIREQTHRESH) ; - - /* - * Read WRBR to provide the location of the srb block, have to use byte reads not word reads. - * Tech docs have this wrong !!!! - */ - - writel(MMIO_BYTE_READ | WRBR, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - xl_priv->srb = readb(xl_mmio + MMIO_MACDATA) << 8 ; - writel( (MMIO_BYTE_READ | WRBR) + 1, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - xl_priv->srb = xl_priv->srb | readb(xl_mmio + MMIO_MACDATA) ; - -#if XL_DEBUG - writel(IO_WORD_READ | SWITCHSETTINGS, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - if ( readw(xl_mmio + MMIO_MACDATA) & 2) { - printk(KERN_INFO "Default ring speed 4 mbps\n"); - } else { - printk(KERN_INFO "Default ring speed 16 mbps\n"); - } - printk(KERN_INFO "%s: xl_priv->srb = %04x\n",xl_priv->xl_card_name, xl_priv->srb); -#endif - - return 0; -} - -static int xl_open(struct net_device *dev) -{ - struct xl_private *xl_priv=netdev_priv(dev); - u8 __iomem *xl_mmio = xl_priv->xl_mmio ; - u8 i ; - __le16 hwaddr[3] ; /* Should be u8[6] but we get word return values */ - int open_err ; - - u16 switchsettings, switchsettings_eeprom ; - - if (request_irq(dev->irq, xl_interrupt, IRQF_SHARED , "3c359", dev)) - return -EAGAIN; - - /* - * Read the information from the EEPROM that we need. - */ - - hwaddr[0] = cpu_to_le16(xl_ee_read(dev,0x10)); - hwaddr[1] = cpu_to_le16(xl_ee_read(dev,0x11)); - hwaddr[2] = cpu_to_le16(xl_ee_read(dev,0x12)); - - /* Ring speed */ - - switchsettings_eeprom = xl_ee_read(dev,0x08) ; - switchsettings = switchsettings_eeprom ; - - if (xl_priv->xl_ring_speed != 0) { - if (xl_priv->xl_ring_speed == 4) - switchsettings = switchsettings | 0x02 ; - else - switchsettings = switchsettings & ~0x02 ; - } - - /* Only write EEProm if there has been a change */ - if (switchsettings != switchsettings_eeprom) { - xl_ee_write(dev,0x08,switchsettings) ; - /* Hardware reset after changing EEProm */ - xl_hw_reset(dev) ; - } - - memcpy(dev->dev_addr,hwaddr,dev->addr_len) ; - - open_err = xl_open_hw(dev) ; - - /* - * This really needs to be cleaned up with better error reporting. - */ - - if (open_err != 0) { /* Something went wrong with the open command */ - if (open_err & 0x07) { /* Wrong speed, retry at different speed */ - printk(KERN_WARNING "%s: Open Error, retrying at different ringspeed\n", dev->name); - switchsettings = switchsettings ^ 2 ; - xl_ee_write(dev,0x08,switchsettings) ; - xl_hw_reset(dev) ; - open_err = xl_open_hw(dev) ; - if (open_err != 0) { - printk(KERN_WARNING "%s: Open error returned a second time, we're bombing out now\n", dev->name); - free_irq(dev->irq,dev) ; - return -ENODEV ; - } - } else { - printk(KERN_WARNING "%s: Open Error = %04x\n", dev->name, open_err) ; - free_irq(dev->irq,dev) ; - return -ENODEV ; - } - } - - /* - * Now to set up the Rx and Tx buffer structures - */ - /* These MUST be on 8 byte boundaries */ - xl_priv->xl_tx_ring = kzalloc((sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE) + 7, GFP_DMA | GFP_KERNEL); - if (xl_priv->xl_tx_ring == NULL) { - free_irq(dev->irq,dev); - return -ENOMEM; - } - xl_priv->xl_rx_ring = kzalloc((sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE) +7, GFP_DMA | GFP_KERNEL); - if (xl_priv->xl_rx_ring == NULL) { - free_irq(dev->irq,dev); - kfree(xl_priv->xl_tx_ring); - return -ENOMEM; - } - - /* Setup Rx Ring */ - for (i=0 ; i < XL_RX_RING_SIZE ; i++) { - struct sk_buff *skb ; - - skb = dev_alloc_skb(xl_priv->pkt_buf_sz) ; - if (skb==NULL) - break ; - - skb->dev = dev ; - xl_priv->xl_rx_ring[i].upfragaddr = cpu_to_le32(pci_map_single(xl_priv->pdev, skb->data,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)); - xl_priv->xl_rx_ring[i].upfraglen = cpu_to_le32(xl_priv->pkt_buf_sz) | RXUPLASTFRAG; - xl_priv->rx_ring_skb[i] = skb ; - } - - if (i==0) { - printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n",dev->name); - free_irq(dev->irq,dev) ; - kfree(xl_priv->xl_tx_ring); - kfree(xl_priv->xl_rx_ring); - return -EIO ; - } - - xl_priv->rx_ring_no = i ; - xl_priv->rx_ring_tail = 0 ; - xl_priv->rx_ring_dma_addr = pci_map_single(xl_priv->pdev,xl_priv->xl_rx_ring, sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, PCI_DMA_TODEVICE) ; - for (i=0;i<(xl_priv->rx_ring_no-1);i++) { - xl_priv->xl_rx_ring[i].upnextptr = cpu_to_le32(xl_priv->rx_ring_dma_addr + (sizeof (struct xl_rx_desc) * (i+1))); - } - xl_priv->xl_rx_ring[i].upnextptr = 0 ; - - writel(xl_priv->rx_ring_dma_addr, xl_mmio + MMIO_UPLISTPTR) ; - - /* Setup Tx Ring */ - - xl_priv->tx_ring_dma_addr = pci_map_single(xl_priv->pdev,xl_priv->xl_tx_ring, sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE,PCI_DMA_TODEVICE) ; - - xl_priv->tx_ring_head = 1 ; - xl_priv->tx_ring_tail = 255 ; /* Special marker for first packet */ - xl_priv->free_ring_entries = XL_TX_RING_SIZE ; - - /* - * Setup the first dummy DPD entry for polling to start working. - */ - - xl_priv->xl_tx_ring[0].framestartheader = TXDPDEMPTY; - xl_priv->xl_tx_ring[0].buffer = 0 ; - xl_priv->xl_tx_ring[0].buffer_length = 0 ; - xl_priv->xl_tx_ring[0].dnnextptr = 0 ; - - writel(xl_priv->tx_ring_dma_addr, xl_mmio + MMIO_DNLISTPTR) ; - writel(DNUNSTALL, xl_mmio + MMIO_COMMAND) ; - writel(UPUNSTALL, xl_mmio + MMIO_COMMAND) ; - writel(DNENABLE, xl_mmio + MMIO_COMMAND) ; - writeb(0x40, xl_mmio + MMIO_DNPOLL) ; - - /* - * Enable interrupts on the card - */ - - writel(SETINTENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ; - writel(SETINDENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ; - - netif_start_queue(dev) ; - return 0; - -} - -static int xl_open_hw(struct net_device *dev) -{ - struct xl_private *xl_priv=netdev_priv(dev); - u8 __iomem *xl_mmio = xl_priv->xl_mmio ; - u16 vsoff ; - char ver_str[33]; - int open_err ; - int i ; - unsigned long t ; - - /* - * Okay, let's build up the Open.NIC srb command - * - */ - - writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb), xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(OPEN_NIC, xl_mmio + MMIO_MACDATA) ; - - /* - * Use this as a test byte, if it comes back with the same value, the command didn't work - */ - - writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb)+ 2, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(0xff,xl_mmio + MMIO_MACDATA) ; - - /* Open options */ - writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + 8, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(0x00, xl_mmio + MMIO_MACDATA) ; - writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + 9, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(0x00, xl_mmio + MMIO_MACDATA) ; - - /* - * Node address, be careful here, the docs say you can just put zeros here and it will use - * the hardware address, it doesn't, you must include the node address in the open command. - */ - - if (xl_priv->xl_laa[0]) { /* If using a LAA address */ - for (i=10;i<16;i++) { - writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(xl_priv->xl_laa[i-10],xl_mmio + MMIO_MACDATA) ; - } - memcpy(dev->dev_addr,xl_priv->xl_laa,dev->addr_len) ; - } else { /* Regular hardware address */ - for (i=10;i<16;i++) { - writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(dev->dev_addr[i-10], xl_mmio + MMIO_MACDATA) ; - } - } - - /* Default everything else to 0 */ - for (i = 16; i < 34; i++) { - writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(0x00,xl_mmio + MMIO_MACDATA) ; - } - - /* - * Set the csrb bit in the MISR register - */ - - xl_wait_misr_flags(dev) ; - writel(MEM_BYTE_WRITE | MF_CSRB, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(0xFF, xl_mmio + MMIO_MACDATA) ; - writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(MISR_CSRB , xl_mmio + MMIO_MACDATA) ; - - /* - * Now wait for the command to run - */ - - t=jiffies; - while (! (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_SRB)) { - schedule(); - if (time_after(jiffies, t + 40 * HZ)) { - printk(KERN_ERR "3COM 3C359 Velocity XL card not responding.\n"); - break ; - } - } - - /* - * Let's interpret the open response - */ - - writel( (MEM_BYTE_READ | 0xD0000 | xl_priv->srb)+2, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - if (readb(xl_mmio + MMIO_MACDATA)!=0) { - open_err = readb(xl_mmio + MMIO_MACDATA) << 8 ; - writel( (MEM_BYTE_READ | 0xD0000 | xl_priv->srb) + 7, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - open_err |= readb(xl_mmio + MMIO_MACDATA) ; - return open_err ; - } else { - writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 8, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - xl_priv->asb = swab16(readw(xl_mmio + MMIO_MACDATA)) ; - printk(KERN_INFO "%s: Adapter Opened Details: ",dev->name) ; - printk("ASB: %04x",xl_priv->asb ) ; - writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 10, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - printk(", SRB: %04x",swab16(readw(xl_mmio + MMIO_MACDATA)) ) ; - - writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 12, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - xl_priv->arb = swab16(readw(xl_mmio + MMIO_MACDATA)) ; - printk(", ARB: %04x\n",xl_priv->arb ); - writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 14, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - vsoff = swab16(readw(xl_mmio + MMIO_MACDATA)) ; - - /* - * Interesting, sending the individual characters directly to printk was causing klogd to use - * use 100% of processor time, so we build up the string and print that instead. - */ - - for (i=0;i<0x20;i++) { - writel( (MEM_BYTE_READ | 0xD0000 | vsoff) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - ver_str[i] = readb(xl_mmio + MMIO_MACDATA) ; - } - ver_str[i] = '\0' ; - printk(KERN_INFO "%s: Microcode version String: %s\n",dev->name,ver_str); - } - - /* - * Issue the AckInterrupt - */ - writew(ACK_INTERRUPT | SRBRACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; - - return 0 ; -} - -/* - * There are two ways of implementing rx on the 359 NIC, either - * interrupt driven or polling. We are going to uses interrupts, - * it is the easier way of doing things. - * - * The Rx works with a ring of Rx descriptors. At initialise time the ring - * entries point to the next entry except for the last entry in the ring - * which points to 0. The card is programmed with the location of the first - * available descriptor and keeps reading the next_ptr until next_ptr is set - * to 0. Hopefully with a ring size of 16 the card will never get to read a next_ptr - * of 0. As the Rx interrupt is received we copy the frame up to the protocol layers - * and then point the end of the ring to our current position and point our current - * position to 0, therefore making the current position the last position on the ring. - * The last position on the ring therefore loops continually loops around the rx ring. - * - * rx_ring_tail is the position on the ring to process next. (Think of a snake, the head - * expands as the card adds new packets and we go around eating the tail processing the - * packets.) - * - * Undoubtably it could be streamlined and improved upon, but at the moment it works - * and the fast path through the routine is fine. - * - * adv_rx_ring could be inlined to increase performance, but its called a *lot* of times - * in xl_rx so would increase the size of the function significantly. - */ - -static void adv_rx_ring(struct net_device *dev) /* Advance rx_ring, cut down on bloat in xl_rx */ -{ - struct xl_private *xl_priv=netdev_priv(dev); - int n = xl_priv->rx_ring_tail; - int prev_ring_loc; - - prev_ring_loc = (n + XL_RX_RING_SIZE - 1) & (XL_RX_RING_SIZE - 1); - xl_priv->xl_rx_ring[prev_ring_loc].upnextptr = cpu_to_le32(xl_priv->rx_ring_dma_addr + (sizeof (struct xl_rx_desc) * n)); - xl_priv->xl_rx_ring[n].framestatus = 0; - xl_priv->xl_rx_ring[n].upnextptr = 0; - xl_priv->rx_ring_tail++; - xl_priv->rx_ring_tail &= (XL_RX_RING_SIZE-1); -} - -static void xl_rx(struct net_device *dev) -{ - struct xl_private *xl_priv=netdev_priv(dev); - u8 __iomem * xl_mmio = xl_priv->xl_mmio ; - struct sk_buff *skb, *skb2 ; - int frame_length = 0, copy_len = 0 ; - int temp_ring_loc ; - - /* - * Receive the next frame, loop around the ring until all frames - * have been received. - */ - - while (xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus & (RXUPDCOMPLETE | RXUPDFULL) ) { /* Descriptor to process */ - - if (xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus & RXUPDFULL ) { /* UpdFull, Multiple Descriptors used for the frame */ - - /* - * This is a pain, you need to go through all the descriptors until the last one - * for this frame to find the framelength - */ - - temp_ring_loc = xl_priv->rx_ring_tail ; - - while (xl_priv->xl_rx_ring[temp_ring_loc].framestatus & RXUPDFULL ) { - temp_ring_loc++ ; - temp_ring_loc &= (XL_RX_RING_SIZE-1) ; - } - - frame_length = le32_to_cpu(xl_priv->xl_rx_ring[temp_ring_loc].framestatus) & 0x7FFF; - - skb = dev_alloc_skb(frame_length) ; - - if (skb==NULL) { /* No memory for frame, still need to roll forward the rx ring */ - printk(KERN_WARNING "%s: dev_alloc_skb failed - multi buffer !\n", dev->name) ; - while (xl_priv->rx_ring_tail != temp_ring_loc) - adv_rx_ring(dev) ; - - adv_rx_ring(dev) ; /* One more time just for luck :) */ - dev->stats.rx_dropped++ ; - - writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; - return ; - } - - while (xl_priv->rx_ring_tail != temp_ring_loc) { - copy_len = le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen) & 0x7FFF; - frame_length -= copy_len ; - pci_dma_sync_single_for_cpu(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE); - skb_copy_from_linear_data(xl_priv->rx_ring_skb[xl_priv->rx_ring_tail], - skb_put(skb, copy_len), - copy_len); - pci_dma_sync_single_for_device(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE); - adv_rx_ring(dev) ; - } - - /* Now we have found the last fragment */ - pci_dma_sync_single_for_cpu(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE); - skb_copy_from_linear_data(xl_priv->rx_ring_skb[xl_priv->rx_ring_tail], - skb_put(skb,copy_len), frame_length); -/* memcpy(skb_put(skb,frame_length), bus_to_virt(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr), frame_length) ; */ - pci_dma_sync_single_for_device(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE); - adv_rx_ring(dev) ; - skb->protocol = tr_type_trans(skb,dev) ; - netif_rx(skb) ; - - } else { /* Single Descriptor Used, simply swap buffers over, fast path */ - - frame_length = le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus) & 0x7FFF; - - skb = dev_alloc_skb(xl_priv->pkt_buf_sz) ; - - if (skb==NULL) { /* Still need to fix the rx ring */ - printk(KERN_WARNING "%s: dev_alloc_skb failed in rx, single buffer\n",dev->name); - adv_rx_ring(dev) ; - dev->stats.rx_dropped++ ; - writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; - return ; - } - - skb2 = xl_priv->rx_ring_skb[xl_priv->rx_ring_tail] ; - pci_unmap_single(xl_priv->pdev, le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr), xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; - skb_put(skb2, frame_length) ; - skb2->protocol = tr_type_trans(skb2,dev) ; - - xl_priv->rx_ring_skb[xl_priv->rx_ring_tail] = skb ; - xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr = cpu_to_le32(pci_map_single(xl_priv->pdev,skb->data,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)); - xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen = cpu_to_le32(xl_priv->pkt_buf_sz) | RXUPLASTFRAG; - adv_rx_ring(dev) ; - dev->stats.rx_packets++ ; - dev->stats.rx_bytes += frame_length ; - - netif_rx(skb2) ; - } /* if multiple buffers */ - } /* while packet to do */ - - /* Clear the updComplete interrupt */ - writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; - return ; -} - -/* - * This is ruthless, it doesn't care what state the card is in it will - * completely reset the adapter. - */ - -static void xl_reset(struct net_device *dev) -{ - struct xl_private *xl_priv=netdev_priv(dev); - u8 __iomem * xl_mmio = xl_priv->xl_mmio ; - unsigned long t; - - writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ; - - /* - * Must wait for cmdInProgress bit (12) to clear before continuing with - * card configuration. - */ - - t=jiffies; - while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { - if (time_after(jiffies, t + 40 * HZ)) { - printk(KERN_ERR "3COM 3C359 Velocity XL card not responding.\n"); - break ; - } - } - -} - -static void xl_freemem(struct net_device *dev) -{ - struct xl_private *xl_priv=netdev_priv(dev); - int i ; - - for (i=0;i<XL_RX_RING_SIZE;i++) { - dev_kfree_skb_irq(xl_priv->rx_ring_skb[xl_priv->rx_ring_tail]) ; - pci_unmap_single(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE); - xl_priv->rx_ring_tail++ ; - xl_priv->rx_ring_tail &= XL_RX_RING_SIZE-1; - } - - /* unmap ring */ - pci_unmap_single(xl_priv->pdev,xl_priv->rx_ring_dma_addr, sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, PCI_DMA_FROMDEVICE) ; - - pci_unmap_single(xl_priv->pdev,xl_priv->tx_ring_dma_addr, sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE, PCI_DMA_TODEVICE) ; - - kfree(xl_priv->xl_rx_ring) ; - kfree(xl_priv->xl_tx_ring) ; - - return ; -} - -static irqreturn_t xl_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = (struct net_device *)dev_id; - struct xl_private *xl_priv =netdev_priv(dev); - u8 __iomem * xl_mmio = xl_priv->xl_mmio ; - u16 intstatus, macstatus ; - - intstatus = readw(xl_mmio + MMIO_INTSTATUS) ; - - if (!(intstatus & 1)) /* We didn't generate the interrupt */ - return IRQ_NONE; - - spin_lock(&xl_priv->xl_lock) ; - - /* - * Process the interrupt - */ - /* - * Something fishy going on here, we shouldn't get 0001 ints, not fatal though. - */ - if (intstatus == 0x0001) { - writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; - printk(KERN_INFO "%s: 00001 int received\n",dev->name); - } else { - if (intstatus & (HOSTERRINT | SRBRINT | ARBCINT | UPCOMPINT | DNCOMPINT | HARDERRINT | (1<<8) | TXUNDERRUN | ASBFINT)) { - - /* - * Host Error. - * It may be possible to recover from this, but usually it means something - * is seriously fubar, so we just close the adapter. - */ - - if (intstatus & HOSTERRINT) { - printk(KERN_WARNING "%s: Host Error, performing global reset, intstatus = %04x\n",dev->name,intstatus); - writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ; - printk(KERN_WARNING "%s: Resetting hardware:\n", dev->name); - netif_stop_queue(dev) ; - xl_freemem(dev) ; - free_irq(dev->irq,dev); - xl_reset(dev) ; - writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; - spin_unlock(&xl_priv->xl_lock) ; - return IRQ_HANDLED; - } /* Host Error */ - - if (intstatus & SRBRINT ) { /* Srbc interrupt */ - writel(ACK_INTERRUPT | SRBRACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; - if (xl_priv->srb_queued) - xl_srb_bh(dev) ; - } /* SRBR Interrupt */ - - if (intstatus & TXUNDERRUN) { /* Issue DnReset command */ - writel(DNRESET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { /* Wait for command to run */ - /* !!! FIX-ME !!!! - Must put a timeout check here ! */ - /* Empty Loop */ - } - printk(KERN_WARNING "%s: TX Underrun received\n",dev->name); - writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; - } /* TxUnderRun */ - - if (intstatus & ARBCINT ) { /* Arbc interrupt */ - xl_arb_cmd(dev) ; - } /* Arbc */ - - if (intstatus & ASBFINT) { - if (xl_priv->asb_queued == 1) { - xl_asb_cmd(dev) ; - } else if (xl_priv->asb_queued == 2) { - xl_asb_bh(dev) ; - } else { - writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ; - } - } /* Asbf */ - - if (intstatus & UPCOMPINT ) /* UpComplete */ - xl_rx(dev) ; - - if (intstatus & DNCOMPINT ) /* DnComplete */ - xl_dn_comp(dev) ; - - if (intstatus & HARDERRINT ) { /* Hardware error */ - writel(MMIO_WORD_READ | MACSTATUS, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - macstatus = readw(xl_mmio + MMIO_MACDATA) ; - printk(KERN_WARNING "%s: MacStatusError, details: ", dev->name); - if (macstatus & (1<<14)) - printk(KERN_WARNING "tchk error: Unrecoverable error\n"); - if (macstatus & (1<<3)) - printk(KERN_WARNING "eint error: Internal watchdog timer expired\n"); - if (macstatus & (1<<2)) - printk(KERN_WARNING "aint error: Host tried to perform invalid operation\n"); - printk(KERN_WARNING "Instatus = %02x, macstatus = %02x\n",intstatus,macstatus) ; - printk(KERN_WARNING "%s: Resetting hardware:\n", dev->name); - netif_stop_queue(dev) ; - xl_freemem(dev) ; - free_irq(dev->irq,dev); - unregister_netdev(dev) ; - free_netdev(dev) ; - xl_reset(dev) ; - writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; - spin_unlock(&xl_priv->xl_lock) ; - return IRQ_HANDLED; - } - } else { - printk(KERN_WARNING "%s: Received Unknown interrupt : %04x\n", dev->name, intstatus); - writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; - } - } - - /* Turn interrupts back on */ - - writel( SETINDENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ; - writel( SETINTENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ; - - spin_unlock(&xl_priv->xl_lock) ; - return IRQ_HANDLED; -} - -/* - * Tx - Polling configuration - */ - -static netdev_tx_t xl_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct xl_private *xl_priv=netdev_priv(dev); - struct xl_tx_desc *txd ; - int tx_head, tx_tail, tx_prev ; - unsigned long flags ; - - spin_lock_irqsave(&xl_priv->xl_lock,flags) ; - - netif_stop_queue(dev) ; - - if (xl_priv->free_ring_entries > 1 ) { - /* - * Set up the descriptor for the packet - */ - tx_head = xl_priv->tx_ring_head ; - tx_tail = xl_priv->tx_ring_tail ; - - txd = &(xl_priv->xl_tx_ring[tx_head]) ; - txd->dnnextptr = 0 ; - txd->framestartheader = cpu_to_le32(skb->len) | TXDNINDICATE; - txd->buffer = cpu_to_le32(pci_map_single(xl_priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE)); - txd->buffer_length = cpu_to_le32(skb->len) | TXDNFRAGLAST; - xl_priv->tx_ring_skb[tx_head] = skb ; - dev->stats.tx_packets++ ; - dev->stats.tx_bytes += skb->len ; - - /* - * Set the nextptr of the previous descriptor equal to this descriptor, add XL_TX_RING_SIZE -1 - * to ensure no negative numbers in unsigned locations. - */ - - tx_prev = (xl_priv->tx_ring_head + XL_TX_RING_SIZE - 1) & (XL_TX_RING_SIZE - 1) ; - - xl_priv->tx_ring_head++ ; - xl_priv->tx_ring_head &= (XL_TX_RING_SIZE - 1) ; - xl_priv->free_ring_entries-- ; - - xl_priv->xl_tx_ring[tx_prev].dnnextptr = cpu_to_le32(xl_priv->tx_ring_dma_addr + (sizeof (struct xl_tx_desc) * tx_head)); - - /* Sneaky, by doing a read on DnListPtr we can force the card to poll on the DnNextPtr */ - /* readl(xl_mmio + MMIO_DNLISTPTR) ; */ - - netif_wake_queue(dev) ; - - spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ; - - return NETDEV_TX_OK; - } else { - spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ; - return NETDEV_TX_BUSY; - } - -} - -/* - * The NIC has told us that a packet has been downloaded onto the card, we must - * find out which packet it has done, clear the skb and information for the packet - * then advance around the ring for all transmitted packets - */ - -static void xl_dn_comp(struct net_device *dev) -{ - struct xl_private *xl_priv=netdev_priv(dev); - u8 __iomem * xl_mmio = xl_priv->xl_mmio ; - struct xl_tx_desc *txd ; - - - if (xl_priv->tx_ring_tail == 255) {/* First time */ - xl_priv->xl_tx_ring[0].framestartheader = 0 ; - xl_priv->xl_tx_ring[0].dnnextptr = 0 ; - xl_priv->tx_ring_tail = 1 ; - } - - while (xl_priv->xl_tx_ring[xl_priv->tx_ring_tail].framestartheader & TXDNCOMPLETE ) { - txd = &(xl_priv->xl_tx_ring[xl_priv->tx_ring_tail]) ; - pci_unmap_single(xl_priv->pdev, le32_to_cpu(txd->buffer), xl_priv->tx_ring_skb[xl_priv->tx_ring_tail]->len, PCI_DMA_TODEVICE); - txd->framestartheader = 0 ; - txd->buffer = cpu_to_le32(0xdeadbeef); - txd->buffer_length = 0 ; - dev_kfree_skb_irq(xl_priv->tx_ring_skb[xl_priv->tx_ring_tail]) ; - xl_priv->tx_ring_tail++ ; - xl_priv->tx_ring_tail &= (XL_TX_RING_SIZE - 1) ; - xl_priv->free_ring_entries++ ; - } - - netif_wake_queue(dev) ; - - writel(ACK_INTERRUPT | DNCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; -} - -/* - * Close the adapter properly. - * This srb reply cannot be handled from interrupt context as we have - * to free the interrupt from the driver. - */ - -static int xl_close(struct net_device *dev) -{ - struct xl_private *xl_priv = netdev_priv(dev); - u8 __iomem * xl_mmio = xl_priv->xl_mmio ; - unsigned long t ; - - netif_stop_queue(dev) ; - - /* - * Close the adapter, need to stall the rx and tx queues. - */ - - writew(DNSTALL, xl_mmio + MMIO_COMMAND) ; - t=jiffies; - while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { - schedule(); - if (time_after(jiffies, t + 10 * HZ)) { - printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNSTALL not responding.\n", dev->name); - break ; - } - } - writew(DNDISABLE, xl_mmio + MMIO_COMMAND) ; - t=jiffies; - while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { - schedule(); - if (time_after(jiffies, t + 10 * HZ)) { - printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNDISABLE not responding.\n", dev->name); - break ; - } - } - writew(UPSTALL, xl_mmio + MMIO_COMMAND) ; - t=jiffies; - while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { - schedule(); - if (time_after(jiffies, t + 10 * HZ)) { - printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-UPSTALL not responding.\n", dev->name); - break ; - } - } - - /* Turn off interrupts, we will still get the indication though - * so we can trap it - */ - - writel(SETINTENABLE, xl_mmio + MMIO_COMMAND) ; - - xl_srb_cmd(dev,CLOSE_NIC) ; - - t=jiffies; - while (!(readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_SRB)) { - schedule(); - if (time_after(jiffies, t + 10 * HZ)) { - printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-CLOSENIC not responding.\n", dev->name); - break ; - } - } - /* Read the srb response from the adapter */ - - writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD); - if (readb(xl_mmio + MMIO_MACDATA) != CLOSE_NIC) { - printk(KERN_INFO "%s: CLOSE_NIC did not get a CLOSE_NIC response\n",dev->name); - } else { - writel((MEM_BYTE_READ | 0xd0000 | xl_priv->srb) +2, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - if (readb(xl_mmio + MMIO_MACDATA)==0) { - printk(KERN_INFO "%s: Adapter has been closed\n",dev->name); - writew(ACK_INTERRUPT | SRBRACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; - - xl_freemem(dev) ; - free_irq(dev->irq,dev) ; - } else { - printk(KERN_INFO "%s: Close nic command returned error code %02x\n",dev->name, readb(xl_mmio + MMIO_MACDATA)) ; - } - } - - /* Reset the upload and download logic */ - - writew(UPRESET, xl_mmio + MMIO_COMMAND) ; - t=jiffies; - while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { - schedule(); - if (time_after(jiffies, t + 10 * HZ)) { - printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-UPRESET not responding.\n", dev->name); - break ; - } - } - writew(DNRESET, xl_mmio + MMIO_COMMAND) ; - t=jiffies; - while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { - schedule(); - if (time_after(jiffies, t + 10 * HZ)) { - printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNRESET not responding.\n", dev->name); - break ; - } - } - xl_hw_reset(dev) ; - return 0 ; -} - -static void xl_set_rx_mode(struct net_device *dev) -{ - struct xl_private *xl_priv = netdev_priv(dev); - struct netdev_hw_addr *ha; - unsigned char dev_mc_address[4] ; - u16 options ; - - if (dev->flags & IFF_PROMISC) - options = 0x0004 ; - else - options = 0x0000 ; - - if (options ^ xl_priv->xl_copy_all_options) { /* Changed, must send command */ - xl_priv->xl_copy_all_options = options ; - xl_srb_cmd(dev, SET_RECEIVE_MODE) ; - return ; - } - - dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ; - - netdev_for_each_mc_addr(ha, dev) { - dev_mc_address[0] |= ha->addr[2]; - dev_mc_address[1] |= ha->addr[3]; - dev_mc_address[2] |= ha->addr[4]; - dev_mc_address[3] |= ha->addr[5]; - } - - if (memcmp(xl_priv->xl_functional_addr,dev_mc_address,4) != 0) { /* Options have changed, run the command */ - memcpy(xl_priv->xl_functional_addr, dev_mc_address,4) ; - xl_srb_cmd(dev, SET_FUNC_ADDRESS) ; - } - return ; -} - - -/* - * We issued an srb command and now we must read - * the response from the completed command. - */ - -static void xl_srb_bh(struct net_device *dev) -{ - struct xl_private *xl_priv = netdev_priv(dev); - u8 __iomem * xl_mmio = xl_priv->xl_mmio ; - u8 srb_cmd, ret_code ; - int i ; - - writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - srb_cmd = readb(xl_mmio + MMIO_MACDATA) ; - writel((MEM_BYTE_READ | 0xd0000 | xl_priv->srb) +2, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - ret_code = readb(xl_mmio + MMIO_MACDATA) ; - - /* Ret_code is standard across all commands */ - - switch (ret_code) { - case 1: - printk(KERN_INFO "%s: Command: %d - Invalid Command code\n",dev->name,srb_cmd) ; - break ; - case 4: - printk(KERN_INFO "%s: Command: %d - Adapter is closed, must be open for this command\n",dev->name,srb_cmd); - break ; - - case 6: - printk(KERN_INFO "%s: Command: %d - Options Invalid for command\n",dev->name,srb_cmd); - break ; - - case 0: /* Successful command execution */ - switch (srb_cmd) { - case READ_LOG: /* Returns 14 bytes of data from the NIC */ - if(xl_priv->xl_message_level) - printk(KERN_INFO "%s: READ.LOG 14 bytes of data ",dev->name) ; - /* - * We still have to read the log even if message_level = 0 and we don't want - * to see it - */ - for (i=0;i<14;i++) { - writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - if(xl_priv->xl_message_level) - printk("%02x:",readb(xl_mmio + MMIO_MACDATA)) ; - } - printk("\n") ; - break ; - case SET_FUNC_ADDRESS: - if(xl_priv->xl_message_level) - printk(KERN_INFO "%s: Functional Address Set\n",dev->name); - break ; - case CLOSE_NIC: - if(xl_priv->xl_message_level) - printk(KERN_INFO "%s: Received CLOSE_NIC interrupt in interrupt handler\n",dev->name); - break ; - case SET_MULTICAST_MODE: - if(xl_priv->xl_message_level) - printk(KERN_INFO "%s: Multicast options successfully changed\n",dev->name) ; - break ; - case SET_RECEIVE_MODE: - if(xl_priv->xl_message_level) { - if (xl_priv->xl_copy_all_options == 0x0004) - printk(KERN_INFO "%s: Entering promiscuous mode\n", dev->name); - else - printk(KERN_INFO "%s: Entering normal receive mode\n",dev->name); - } - break ; - - } /* switch */ - break ; - } /* switch */ - return ; -} - -static int xl_set_mac_address (struct net_device *dev, void *addr) -{ - struct sockaddr *saddr = addr ; - struct xl_private *xl_priv = netdev_priv(dev); - - if (netif_running(dev)) { - printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name) ; - return -EIO ; - } - - memcpy(xl_priv->xl_laa, saddr->sa_data,dev->addr_len) ; - - if (xl_priv->xl_message_level) { - printk(KERN_INFO "%s: MAC/LAA Set to = %x.%x.%x.%x.%x.%x\n",dev->name, xl_priv->xl_laa[0], - xl_priv->xl_laa[1], xl_priv->xl_laa[2], - xl_priv->xl_laa[3], xl_priv->xl_laa[4], - xl_priv->xl_laa[5]); - } - - return 0 ; -} - -static void xl_arb_cmd(struct net_device *dev) -{ - struct xl_private *xl_priv = netdev_priv(dev); - u8 __iomem * xl_mmio = xl_priv->xl_mmio ; - u8 arb_cmd ; - u16 lan_status, lan_status_diff ; - - writel( ( MEM_BYTE_READ | 0xD0000 | xl_priv->arb), xl_mmio + MMIO_MAC_ACCESS_CMD) ; - arb_cmd = readb(xl_mmio + MMIO_MACDATA) ; - - if (arb_cmd == RING_STATUS_CHANGE) { /* Ring.Status.Change */ - writel( ( (MEM_WORD_READ | 0xD0000 | xl_priv->arb) + 6), xl_mmio + MMIO_MAC_ACCESS_CMD) ; - - printk(KERN_INFO "%s: Ring Status Change: New Status = %04x\n", dev->name, swab16(readw(xl_mmio + MMIO_MACDATA) )) ; - - lan_status = swab16(readw(xl_mmio + MMIO_MACDATA)); - - /* Acknowledge interrupt, this tells nic we are done with the arb */ - writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; - - lan_status_diff = xl_priv->xl_lan_status ^ lan_status ; - - if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR) ) { - if (lan_status_diff & LSC_LWF) - printk(KERN_WARNING "%s: Short circuit detected on the lobe\n",dev->name); - if (lan_status_diff & LSC_ARW) - printk(KERN_WARNING "%s: Auto removal error\n",dev->name); - if (lan_status_diff & LSC_FPE) - printk(KERN_WARNING "%s: FDX Protocol Error\n",dev->name); - if (lan_status_diff & LSC_RR) - printk(KERN_WARNING "%s: Force remove MAC frame received\n",dev->name); - - /* Adapter has been closed by the hardware */ - - netif_stop_queue(dev); - xl_freemem(dev) ; - free_irq(dev->irq,dev); - - printk(KERN_WARNING "%s: Adapter has been closed\n", dev->name); - } /* If serious error */ - - if (xl_priv->xl_message_level) { - if (lan_status_diff & LSC_SIG_LOSS) - printk(KERN_WARNING "%s: No receive signal detected\n", dev->name); - if (lan_status_diff & LSC_HARD_ERR) - printk(KERN_INFO "%s: Beaconing\n",dev->name); - if (lan_status_diff & LSC_SOFT_ERR) - printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame\n",dev->name); - if (lan_status_diff & LSC_TRAN_BCN) - printk(KERN_INFO "%s: We are transmitting the beacon, aaah\n",dev->name); - if (lan_status_diff & LSC_SS) - printk(KERN_INFO "%s: Single Station on the ring\n", dev->name); - if (lan_status_diff & LSC_RING_REC) - printk(KERN_INFO "%s: Ring recovery ongoing\n",dev->name); - if (lan_status_diff & LSC_FDX_MODE) - printk(KERN_INFO "%s: Operating in FDX mode\n",dev->name); - } - - if (lan_status_diff & LSC_CO) { - if (xl_priv->xl_message_level) - printk(KERN_INFO "%s: Counter Overflow\n", dev->name); - /* Issue READ.LOG command */ - xl_srb_cmd(dev, READ_LOG) ; - } - - /* There is no command in the tech docs to issue the read_sr_counters */ - if (lan_status_diff & LSC_SR_CO) { - if (xl_priv->xl_message_level) - printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name); - } - - xl_priv->xl_lan_status = lan_status ; - - } /* Lan.change.status */ - else if ( arb_cmd == RECEIVE_DATA) { /* Received.Data */ -#if XL_DEBUG - printk(KERN_INFO "Received.Data\n"); -#endif - writel( ((MEM_WORD_READ | 0xD0000 | xl_priv->arb) + 6), xl_mmio + MMIO_MAC_ACCESS_CMD) ; - xl_priv->mac_buffer = swab16(readw(xl_mmio + MMIO_MACDATA)) ; - - /* Now we are going to be really basic here and not do anything - * with the data at all. The tech docs do not give me enough - * information to calculate the buffers properly so we're - * just going to tell the nic that we've dealt with the frame - * anyway. - */ - - /* Acknowledge interrupt, this tells nic we are done with the arb */ - writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; - - /* Is the ASB free ? */ - - xl_priv->asb_queued = 0 ; - writel( ((MEM_BYTE_READ | 0xD0000 | xl_priv->asb) + 2), xl_mmio + MMIO_MAC_ACCESS_CMD) ; - if (readb(xl_mmio + MMIO_MACDATA) != 0xff) { - xl_priv->asb_queued = 1 ; - - xl_wait_misr_flags(dev) ; - - writel(MEM_BYTE_WRITE | MF_ASBFR, xl_mmio + MMIO_MAC_ACCESS_CMD); - writeb(0xff, xl_mmio + MMIO_MACDATA) ; - writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(MISR_ASBFR, xl_mmio + MMIO_MACDATA) ; - return ; - /* Drop out and wait for the bottom half to be run */ - } - - xl_asb_cmd(dev) ; - - } else { - printk(KERN_WARNING "%s: Received unknown arb (xl_priv) command: %02x\n",dev->name,arb_cmd); - } - - /* Acknowledge the arb interrupt */ - - writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; - - return ; -} - - -/* - * There is only one asb command, but we can get called from different - * places. - */ - -static void xl_asb_cmd(struct net_device *dev) -{ - struct xl_private *xl_priv = netdev_priv(dev); - u8 __iomem * xl_mmio = xl_priv->xl_mmio ; - - if (xl_priv->asb_queued == 1) - writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ; - - writel(MEM_BYTE_WRITE | 0xd0000 | xl_priv->asb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(0x81, xl_mmio + MMIO_MACDATA) ; - - writel(MEM_WORD_WRITE | 0xd0000 | xl_priv->asb | 6, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writew(swab16(xl_priv->mac_buffer), xl_mmio + MMIO_MACDATA) ; - - xl_wait_misr_flags(dev) ; - - writel(MEM_BYTE_WRITE | MF_RASB, xl_mmio + MMIO_MAC_ACCESS_CMD); - writeb(0xff, xl_mmio + MMIO_MACDATA) ; - - writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(MISR_RASB, xl_mmio + MMIO_MACDATA) ; - - xl_priv->asb_queued = 2 ; - - return ; -} - -/* - * This will only get called if there was an error - * from the asb cmd. - */ -static void xl_asb_bh(struct net_device *dev) -{ - struct xl_private *xl_priv = netdev_priv(dev); - u8 __iomem * xl_mmio = xl_priv->xl_mmio ; - u8 ret_code ; - - writel(MMIO_BYTE_READ | 0xd0000 | xl_priv->asb | 2, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - ret_code = readb(xl_mmio + MMIO_MACDATA) ; - switch (ret_code) { - case 0x01: - printk(KERN_INFO "%s: ASB Command, unrecognized command code\n",dev->name); - break ; - case 0x26: - printk(KERN_INFO "%s: ASB Command, unexpected receive buffer\n", dev->name); - break ; - case 0x40: - printk(KERN_INFO "%s: ASB Command, Invalid Station ID\n", dev->name); - break ; - } - xl_priv->asb_queued = 0 ; - writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ; - return ; -} - -/* - * Issue srb commands to the nic - */ - -static void xl_srb_cmd(struct net_device *dev, int srb_cmd) -{ - struct xl_private *xl_priv = netdev_priv(dev); - u8 __iomem * xl_mmio = xl_priv->xl_mmio ; - - switch (srb_cmd) { - case READ_LOG: - writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(READ_LOG, xl_mmio + MMIO_MACDATA) ; - break; - - case CLOSE_NIC: - writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(CLOSE_NIC, xl_mmio + MMIO_MACDATA) ; - break ; - - case SET_RECEIVE_MODE: - writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(SET_RECEIVE_MODE, xl_mmio + MMIO_MACDATA) ; - writel(MEM_WORD_WRITE | 0xD0000 | xl_priv->srb | 4, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writew(xl_priv->xl_copy_all_options, xl_mmio + MMIO_MACDATA) ; - break ; - - case SET_FUNC_ADDRESS: - writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(SET_FUNC_ADDRESS, xl_mmio + MMIO_MACDATA) ; - writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 6 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(xl_priv->xl_functional_addr[0], xl_mmio + MMIO_MACDATA) ; - writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 7 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(xl_priv->xl_functional_addr[1], xl_mmio + MMIO_MACDATA) ; - writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 8 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(xl_priv->xl_functional_addr[2], xl_mmio + MMIO_MACDATA) ; - writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 9 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(xl_priv->xl_functional_addr[3], xl_mmio + MMIO_MACDATA) ; - break ; - } /* switch */ - - - xl_wait_misr_flags(dev) ; - - /* Write 0xff to the CSRB flag */ - writel(MEM_BYTE_WRITE | MF_CSRB , xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(0xFF, xl_mmio + MMIO_MACDATA) ; - /* Set csrb bit in MISR register to process command */ - writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(MISR_CSRB, xl_mmio + MMIO_MACDATA) ; - xl_priv->srb_queued = 1 ; - - return ; -} - -/* - * This is nasty, to use the MISR command you have to wait for 6 memory locations - * to be zero. This is the way the driver does on other OS'es so we should be ok with - * the empty loop. - */ - -static void xl_wait_misr_flags(struct net_device *dev) -{ - struct xl_private *xl_priv = netdev_priv(dev); - u8 __iomem * xl_mmio = xl_priv->xl_mmio ; - - int i ; - - writel(MMIO_BYTE_READ | MISR_RW, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - if (readb(xl_mmio + MMIO_MACDATA) != 0) { /* Misr not clear */ - for (i=0; i<6; i++) { - writel(MEM_BYTE_READ | 0xDFFE0 | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - while (readb(xl_mmio + MMIO_MACDATA) != 0) { - ; /* Empty Loop */ - } - } - } - - writel(MMIO_BYTE_WRITE | MISR_AND, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writeb(0x80, xl_mmio + MMIO_MACDATA) ; - - return ; -} - -/* - * Change mtu size, this should work the same as olympic - */ - -static int xl_change_mtu(struct net_device *dev, int mtu) -{ - struct xl_private *xl_priv = netdev_priv(dev); - u16 max_mtu ; - - if (xl_priv->xl_ring_speed == 4) - max_mtu = 4500 ; - else - max_mtu = 18000 ; - - if (mtu > max_mtu) - return -EINVAL ; - if (mtu < 100) - return -EINVAL ; - - dev->mtu = mtu ; - xl_priv->pkt_buf_sz = mtu + TR_HLEN ; - - return 0 ; -} - -static void __devexit xl_remove_one (struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct xl_private *xl_priv=netdev_priv(dev); - - release_firmware(xl_priv->fw); - unregister_netdev(dev); - iounmap(xl_priv->xl_mmio) ; - pci_release_regions(pdev) ; - pci_set_drvdata(pdev,NULL) ; - free_netdev(dev); - return ; -} - -static struct pci_driver xl_3c359_driver = { - .name = "3c359", - .id_table = xl_pci_tbl, - .probe = xl_probe, - .remove = __devexit_p(xl_remove_one), -}; - -module_pci_driver(xl_3c359_driver); - -MODULE_LICENSE("GPL") ;
diff --git a/drivers/net/tokenring/3c359.h b/drivers/net/tokenring/3c359.h deleted file mode 100644 index bcb1a6b..0000000 --- a/drivers/net/tokenring/3c359.h +++ /dev/null
@@ -1,291 +0,0 @@ -/* - * 3c359.h (c) 2000 Mike Phillips (mikep@linuxtr.net) All Rights Reserved - * - * Linux driver for 3Com 3C359 Token Link PCI XL cards. - * - * This software may be used and distributed according to the terms - * of the GNU General Public License Version 2 or (at your option) - * any later verion, incorporated herein by reference. - */ - -/* Memory Access Commands */ -#define IO_BYTE_READ 0x28 << 24 -#define IO_BYTE_WRITE 0x18 << 24 -#define IO_WORD_READ 0x20 << 24 -#define IO_WORD_WRITE 0x10 << 24 -#define MMIO_BYTE_READ 0x88 << 24 -#define MMIO_BYTE_WRITE 0x48 << 24 -#define MMIO_WORD_READ 0x80 << 24 -#define MMIO_WORD_WRITE 0x40 << 24 -#define MEM_BYTE_READ 0x8C << 24 -#define MEM_BYTE_WRITE 0x4C << 24 -#define MEM_WORD_READ 0x84 << 24 -#define MEM_WORD_WRITE 0x44 << 24 - -#define PMBAR 0x1C80 -#define PMB_CPHOLD (1<<10) - -#define CPATTENTION 0x180D -#define CPA_PMBARVIS (1<<7) -#define CPA_MEMWREN (1<<6) - -#define SWITCHSETTINGS 0x1C88 -#define EECONTROL 0x1C8A -#define EEDATA 0x1C8C -#define EEREAD 0x0080 -#define EEWRITE 0x0040 -#define EEERASE 0x0060 -#define EE_ENABLE_WRITE 0x0030 -#define EEBUSY (1<<15) - -#define WRBR 0xCDE02 -#define WWOR 0xCDE04 -#define WWCR 0xCDE06 -#define MACSTATUS 0xCDE08 -#define MISR_RW 0xCDE0B -#define MISR_AND 0xCDE2B -#define MISR_SET 0xCDE4B -#define RXBUFAREA 0xCDE10 -#define RXEARLYTHRESH 0xCDE12 -#define TXSTARTTHRESH 0x58 -#define DNPRIREQTHRESH 0x2C - -#define MISR_CSRB (1<<5) -#define MISR_RASB (1<<4) -#define MISR_SRBFR (1<<3) -#define MISR_ASBFR (1<<2) -#define MISR_ARBF (1<<1) - -/* MISR Flags memory locations */ -#define MF_SSBF 0xDFFE0 -#define MF_ARBF 0xDFFE1 -#define MF_ASBFR 0xDFFE2 -#define MF_SRBFR 0xDFFE3 -#define MF_RASB 0xDFFE4 -#define MF_CSRB 0xDFFE5 - -#define MMIO_MACDATA 0x10 -#define MMIO_MAC_ACCESS_CMD 0x14 -#define MMIO_TIMER 0x1A -#define MMIO_DMA_CTRL 0x20 -#define MMIO_DNLISTPTR 0x24 -#define MMIO_HASHFILTER 0x28 -#define MMIO_CONFIG 0x29 -#define MMIO_DNPRIREQTHRESH 0x2C -#define MMIO_DNPOLL 0x2D -#define MMIO_UPPKTSTATUS 0x30 -#define MMIO_FREETIMER 0x34 -#define MMIO_COUNTDOWN 0x36 -#define MMIO_UPLISTPTR 0x38 -#define MMIO_UPPOLL 0x3C -#define MMIO_UPBURSTTHRESH 0x40 -#define MMIO_DNBURSTTHRESH 0x41 -#define MMIO_INTSTATUS_AUTO 0x56 -#define MMIO_TXSTARTTHRESH 0x58 -#define MMIO_INTERRUPTENABLE 0x5A -#define MMIO_INDICATIONENABLE 0x5C -#define MMIO_COMMAND 0x5E /* These two are meant to be the same */ -#define MMIO_INTSTATUS 0x5E /* Makes the code more readable this way */ -#define INTSTAT_CMD_IN_PROGRESS (1<<12) -#define INTSTAT_SRB (1<<14) -#define INTSTAT_INTLATCH (1<<0) - -/* Indication / Interrupt Mask - * Annoyingly the bits to be set in the indication and interrupt enable - * do not match with the actual bits received in the interrupt, although - * they are in the same order. - * The mapping for the indication / interrupt are: - * Bit Indication / Interrupt - * 0 HostError - * 1 txcomplete - * 2 updneeded - * 3 rxcomplete - * 4 intrequested - * 5 macerror - * 6 dncomplete - * 7 upcomplete - * 8 txunderrun - * 9 asbf - * 10 srbr - * 11 arbc - * - * The only ones we don't want to receive are txcomplete and rxcomplete - * we use dncomplete and upcomplete instead. - */ - -#define INT_MASK 0xFF5 - -/* Note the subtle difference here, IND and INT */ - -#define SETINDENABLE (8<<12) -#define SETINTENABLE (7<<12) -#define SRBBIT (1<<10) -#define ASBBIT (1<<9) -#define ARBBIT (1<<11) - -#define SRB 0xDFE90 -#define ASB 0xDFED0 -#define ARB 0xD0000 -#define SCRATCH 0xDFEF0 - -#define INT_REQUEST 0x6000 /* (6 << 12) */ -#define ACK_INTERRUPT 0x6800 /* (13 <<11) */ -#define GLOBAL_RESET 0x00 -#define DNDISABLE 0x5000 -#define DNENABLE 0x4800 -#define DNSTALL 0x3002 -#define DNRESET 0x5800 -#define DNUNSTALL 0x3003 -#define UPRESET 0x2800 -#define UPSTALL 0x3000 -#define UPUNSTALL 0x3001 -#define SETCONFIG 0x4000 -#define SETTXSTARTTHRESH 0x9800 - -/* Received Interrupts */ -#define ASBFINT (1<<13) -#define SRBRINT (1<<14) -#define ARBCINT (1<<15) -#define TXUNDERRUN (1<<11) - -#define UPCOMPINT (1<<10) -#define DNCOMPINT (1<<9) -#define HARDERRINT (1<<7) -#define RXCOMPLETE (1<<4) -#define TXCOMPINT (1<<2) -#define HOSTERRINT (1<<1) - -/* Receive descriptor bits */ -#define RXOVERRUN cpu_to_le32(1<<19) -#define RXFC cpu_to_le32(1<<21) -#define RXAR cpu_to_le32(1<<22) -#define RXUPDCOMPLETE cpu_to_le32(1<<23) -#define RXUPDFULL cpu_to_le32(1<<24) -#define RXUPLASTFRAG cpu_to_le32(1<<31) - -/* Transmit descriptor bits */ -#define TXDNCOMPLETE cpu_to_le32(1<<16) -#define TXTXINDICATE cpu_to_le32(1<<27) -#define TXDPDEMPTY cpu_to_le32(1<<29) -#define TXDNINDICATE cpu_to_le32(1<<31) -#define TXDNFRAGLAST cpu_to_le32(1<<31) - -/* Interrupts to Acknowledge */ -#define LATCH_ACK 1 -#define TXCOMPACK (1<<1) -#define INTREQACK (1<<2) -#define DNCOMPACK (1<<3) -#define UPCOMPACK (1<<4) -#define ASBFACK (1<<5) -#define SRBRACK (1<<6) -#define ARBCACK (1<<7) - -#define XL_IO_SPACE 128 -#define SRB_COMMAND_SIZE 50 - -/* Adapter Commands */ -#define REQUEST_INT 0x00 -#define MODIFY_OPEN_PARMS 0x01 -#define RESTORE_OPEN_PARMS 0x02 -#define OPEN_NIC 0x03 -#define CLOSE_NIC 0x04 -#define SET_SLEEP_MODE 0x05 -#define SET_GROUP_ADDRESS 0x06 -#define SET_FUNC_ADDRESS 0x07 -#define READ_LOG 0x08 -#define SET_MULTICAST_MODE 0x0C -#define CHANGE_WAKEUP_PATTERN 0x0D -#define GET_STATISTICS 0x13 -#define SET_RECEIVE_MODE 0x1F - -/* ARB Commands */ -#define RECEIVE_DATA 0x81 -#define RING_STATUS_CHANGE 0x84 - -/* ASB Commands */ -#define ASB_RECEIVE_DATE 0x81 - -/* Defines for LAN STATUS CHANGE reports */ -#define LSC_SIG_LOSS 0x8000 -#define LSC_HARD_ERR 0x4000 -#define LSC_SOFT_ERR 0x2000 -#define LSC_TRAN_BCN 0x1000 -#define LSC_LWF 0x0800 -#define LSC_ARW 0x0400 -#define LSC_FPE 0x0200 -#define LSC_RR 0x0100 -#define LSC_CO 0x0080 -#define LSC_SS 0x0040 -#define LSC_RING_REC 0x0020 -#define LSC_SR_CO 0x0010 -#define LSC_FDX_MODE 0x0004 - -#define XL_MAX_ADAPTERS 8 /* 0x08 __MODULE_STRING can't hand 0xnn */ - -/* 3c359 defaults for buffers */ - -#define XL_RX_RING_SIZE 16 /* must be a power of 2 */ -#define XL_TX_RING_SIZE 16 /* must be a power of 2 */ - -#define PKT_BUF_SZ 4096 /* Default packet size */ - -/* 3c359 data structures */ - -struct xl_tx_desc { - __le32 dnnextptr; - __le32 framestartheader; - __le32 buffer; - __le32 buffer_length; -}; - -struct xl_rx_desc { - __le32 upnextptr; - __le32 framestatus; - __le32 upfragaddr; - __le32 upfraglen; -}; - -struct xl_private { - - - /* These two structures must be aligned on 8 byte boundaries */ - - /* struct xl_rx_desc xl_rx_ring[XL_RX_RING_SIZE]; */ - /* struct xl_tx_desc xl_tx_ring[XL_TX_RING_SIZE]; */ - struct xl_rx_desc *xl_rx_ring ; - struct xl_tx_desc *xl_tx_ring ; - struct sk_buff *tx_ring_skb[XL_TX_RING_SIZE], *rx_ring_skb[XL_RX_RING_SIZE]; - int tx_ring_head, tx_ring_tail ; - int rx_ring_tail, rx_ring_no ; - int free_ring_entries ; - - u16 srb; - u16 arb; - u16 asb; - - u8 __iomem *xl_mmio; - const char *xl_card_name; - struct pci_dev *pdev ; - - spinlock_t xl_lock ; - - volatile int srb_queued; - struct wait_queue *srb_wait; - volatile int asb_queued; - - u16 mac_buffer ; - u16 xl_lan_status ; - u8 xl_ring_speed ; - u16 pkt_buf_sz ; - u8 xl_message_level; - u16 xl_copy_all_options ; - unsigned char xl_functional_addr[4] ; - u16 xl_addr_table_addr, xl_parms_addr ; - u8 xl_laa[6] ; - u32 rx_ring_dma_addr ; - u32 tx_ring_dma_addr ; - - /* firmware section */ - const struct firmware *fw; -}; -
diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig deleted file mode 100644 index ef3bb13..0000000 --- a/drivers/net/tokenring/Kconfig +++ /dev/null
@@ -1,199 +0,0 @@ -# -# Token Ring driver configuration -# - -# So far, we only have PCI, ISA, and MCA token ring devices -menuconfig TR - bool "Token Ring driver support" - depends on NETDEVICES && !UML - depends on (PCI || ISA || MCA || CCW || PCMCIA) - help - Token Ring is IBM's way of communication on a local network; the - rest of the world uses Ethernet. To participate on a Token Ring - network, you need a special Token ring network card. If you are - connected to such a Token Ring network and want to use your Token - Ring card under Linux, say Y here and to the driver for your - particular card below and read the Token-Ring mini-HOWTO, available - from <http://www.tldp.org/docs.html#howto>. Most people can - say N here. - -if TR - -config WANT_LLC - def_bool y - select LLC - -config PCMCIA_IBMTR - tristate "IBM PCMCIA tokenring adapter support" - depends on IBMTR!=y && PCMCIA - ---help--- - Say Y here if you intend to attach this type of Token Ring PCMCIA - card to your computer. You then also need to say Y to "Token Ring - driver support". - - To compile this driver as a module, choose M here: the module will be - called ibmtr_cs. - -config IBMTR - tristate "IBM Tropic chipset based adapter support" - depends on ISA || MCA - ---help--- - This is support for all IBM Token Ring cards that don't use DMA. If - you have such a beast, say Y and read the Token-Ring mini-HOWTO, - available from <http://www.tldp.org/docs.html#howto>. - - Warning: this driver will almost definitely fail if more than one - active Token Ring card is present. - - To compile this driver as a module, choose M here: the module will be - called ibmtr. - -config IBMOL - tristate "IBM Olympic chipset PCI adapter support" - depends on PCI - ---help--- - This is support for all non-Lanstreamer IBM PCI Token Ring Cards. - Specifically this is all IBM PCI, PCI Wake On Lan, PCI II, PCI II - Wake On Lan, and PCI 100/16/4 adapters. - - If you have such an adapter, say Y and read the Token-Ring - mini-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 olympic. - - Also read <file:Documentation/networking/olympic.txt> or check the - Linux Token Ring Project site for the latest information at - <http://www.linuxtr.net/>. - -config IBMLS - tristate "IBM Lanstreamer chipset PCI adapter support" - depends on PCI && !64BIT - help - This is support for IBM Lanstreamer PCI Token Ring Cards. - - If you have such an adapter, say Y and read the Token-Ring - mini-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 lanstreamer. - -config 3C359 - tristate "3Com 3C359 Token Link Velocity XL adapter support" - depends on PCI - ---help--- - This is support for the 3Com PCI Velocity XL cards, specifically - the 3Com 3C359, please note this is not for the 3C339 cards, you - should use the tms380 driver instead. - - If you have such an adapter, say Y and read the Token-Ring - mini-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 3c359. - - Also read the file <file:Documentation/networking/3c359.txt> or check the - Linux Token Ring Project site for the latest information at - <http://www.linuxtr.net> - -config TMS380TR - tristate "Generic TMS380 Token Ring ISA/PCI adapter support" - depends on PCI || ISA || MCA - select FW_LOADER - ---help--- - This driver provides generic support for token ring adapters - based on the Texas Instruments TMS380 series chipsets. This - includes the SysKonnect TR4/16(+) ISA (SK-4190), SysKonnect - TR4/16(+) PCI (SK-4590), SysKonnect TR4/16 PCI (SK-4591), - Compaq 4/16 PCI, Thomas-Conrad TC4048 4/16 PCI, and several - Madge adapters. If you say Y here, you will be asked to select - which cards to support below. If you're using modules, each - class of card will be supported by a separate module. - - If you have such an adapter and would like to use it, say Y and - read the Token-Ring mini-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. - - Also read the file <file:Documentation/networking/tms380tr.txt> or - check <http://www.auk.cx/tms380tr/>. - - To compile this driver as a module, choose M here: the module will be - called tms380tr. - -config TMSPCI - tristate "Generic TMS380 PCI support" - depends on TMS380TR && PCI - ---help--- - This tms380 module supports generic TMS380-based PCI cards. - - These cards are known to work: - - Compaq 4/16 TR PCI - - SysKonnect TR4/16 PCI (SK-4590/SK-4591) - - Thomas-Conrad TC4048 PCI 4/16 - - 3Com Token Link Velocity - - To compile this driver as a module, choose M here: the module will be - called tmspci. - -config SKISA - tristate "SysKonnect TR4/16 ISA support" - depends on TMS380TR && ISA && ISA_DMA_API - help - This tms380 module supports SysKonnect TR4/16 ISA cards. - - These cards are known to work: - - SysKonnect TR4/16 ISA (SK-4190) - - To compile this driver as a module, choose M here: the module will be - called skisa. - -config PROTEON - tristate "Proteon ISA support" - depends on TMS380TR && ISA && ISA_DMA_API - help - This tms380 module supports Proteon ISA cards. - - These cards are known to work: - - Proteon 1392 - - Proteon 1392 plus - - To compile this driver as a module, choose M here: the module will be - called proteon. - -config ABYSS - tristate "Madge Smart 16/4 PCI Mk2 support" - depends on TMS380TR && PCI - help - This tms380 module supports the Madge Smart 16/4 PCI Mk2 - cards (51-02). - - To compile this driver as a module, choose M here: the module will be - called abyss. - -config MADGEMC - tristate "Madge Smart 16/4 Ringnode MicroChannel" - depends on TMS380TR && MCA - help - This tms380 module supports the Madge Smart 16/4 MC16 and MC32 - MicroChannel adapters. - - To compile this driver as a module, choose M here: the module will be - called madgemc. - -config SMCTR - tristate "SMC ISA/MCA adapter support" - depends on (ISA || MCA_LEGACY) && (BROKEN || !64BIT) - ---help--- - This is support for the ISA and MCA SMC Token Ring cards, - specifically SMC TokenCard Elite (8115T) and SMC TokenCard Elite/A - (8115T/A) adapters. - - If you have such an adapter and would like to use it, say Y or M and - read the Token-Ring mini-HOWTO, available from - <http://www.tldp.org/docs.html#howto> and the file - <file:Documentation/networking/smctr.txt>. - - To compile this driver as a module, choose M here: the module will be - called smctr. - -endif # TR
diff --git a/drivers/net/tokenring/Makefile b/drivers/net/tokenring/Makefile deleted file mode 100644 index f1be8d9..0000000 --- a/drivers/net/tokenring/Makefile +++ /dev/null
@@ -1,16 +0,0 @@ -# -# Makefile for drivers/net/tokenring -# - -obj-$(CONFIG_PCMCIA_IBMTR) += ibmtr_cs.o -obj-$(CONFIG_IBMTR) += ibmtr.o -obj-$(CONFIG_IBMOL) += olympic.o -obj-$(CONFIG_IBMLS) += lanstreamer.o -obj-$(CONFIG_TMS380TR) += tms380tr.o -obj-$(CONFIG_ABYSS) += abyss.o -obj-$(CONFIG_MADGEMC) += madgemc.o -obj-$(CONFIG_PROTEON) += proteon.o -obj-$(CONFIG_TMSPCI) += tmspci.o -obj-$(CONFIG_SKISA) += skisa.o -obj-$(CONFIG_SMCTR) += smctr.o -obj-$(CONFIG_3C359) += 3c359.o
diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c deleted file mode 100644 index b715e6b..0000000 --- a/drivers/net/tokenring/abyss.c +++ /dev/null
@@ -1,468 +0,0 @@ -/* - * abyss.c: Network driver for the Madge Smart 16/4 PCI Mk2 token ring card. - * - * Written 1999-2000 by Adam Fritzler - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * This driver module supports the following cards: - * - Madge Smart 16/4 PCI Mk2 - * - * Maintainer(s): - * AF Adam Fritzler - * - * Modification History: - * 30-Dec-99 AF Split off from the tms380tr driver. - * 22-Jan-00 AF Updated to use indirect read/writes - * 23-Nov-00 JG New PCI API, cleanups - * - * - * TODO: - * 1. See if we can use MMIO instead of inb/outb/inw/outw - * 2. Add support for Mk1 (has AT24 attached to the PCI - * config registers) - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/netdevice.h> -#include <linux/trdevice.h> - -#include <asm/io.h> -#include <asm/irq.h> - -#include "tms380tr.h" -#include "abyss.h" /* Madge-specific constants */ - -static char version[] __devinitdata = -"abyss.c: v1.02 23/11/2000 by Adam Fritzler\n"; - -#define ABYSS_IO_EXTENT 64 - -static DEFINE_PCI_DEVICE_TABLE(abyss_pci_tbl) = { - { PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_MK2, - PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_TOKEN_RING << 8, 0x00ffffff, }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(pci, abyss_pci_tbl); - -MODULE_LICENSE("GPL"); - -static int abyss_open(struct net_device *dev); -static int abyss_close(struct net_device *dev); -static void abyss_enable(struct net_device *dev); -static int abyss_chipset_init(struct net_device *dev); -static void abyss_read_eeprom(struct net_device *dev); -static unsigned short abyss_setnselout_pins(struct net_device *dev); - -static void at24_writedatabyte(unsigned long regaddr, unsigned char byte); -static int at24_sendfullcmd(unsigned long regaddr, unsigned char cmd, unsigned char addr); -static int at24_sendcmd(unsigned long regaddr, unsigned char cmd); -static unsigned char at24_readdatabit(unsigned long regaddr); -static unsigned char at24_readdatabyte(unsigned long regaddr); -static int at24_waitforack(unsigned long regaddr); -static int at24_waitfornack(unsigned long regaddr); -static void at24_setlines(unsigned long regaddr, unsigned char clock, unsigned char data); -static void at24_start(unsigned long regaddr); -static unsigned char at24_readb(unsigned long regaddr, unsigned char addr); - -static unsigned short abyss_sifreadb(struct net_device *dev, unsigned short reg) -{ - return inb(dev->base_addr + reg); -} - -static unsigned short abyss_sifreadw(struct net_device *dev, unsigned short reg) -{ - return inw(dev->base_addr + reg); -} - -static void abyss_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg) -{ - outb(val, dev->base_addr + reg); -} - -static void abyss_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg) -{ - outw(val, dev->base_addr + reg); -} - -static struct net_device_ops abyss_netdev_ops; - -static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - static int versionprinted; - struct net_device *dev; - struct net_local *tp; - int ret, pci_irq_line; - unsigned long pci_ioaddr; - - if (versionprinted++ == 0) - printk("%s", version); - - if (pci_enable_device(pdev)) - return -EIO; - - /* Remove I/O space marker in bit 0. */ - pci_irq_line = pdev->irq; - pci_ioaddr = pci_resource_start (pdev, 0); - - /* At this point we have found a valid card. */ - - dev = alloc_trdev(sizeof(struct net_local)); - if (!dev) - return -ENOMEM; - - if (!request_region(pci_ioaddr, ABYSS_IO_EXTENT, dev->name)) { - ret = -EBUSY; - goto err_out_trdev; - } - - ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED, - dev->name, dev); - if (ret) - goto err_out_region; - - dev->base_addr = pci_ioaddr; - dev->irq = pci_irq_line; - - printk("%s: Madge Smart 16/4 PCI Mk2 (Abyss)\n", dev->name); - printk("%s: IO: %#4lx IRQ: %d\n", - dev->name, pci_ioaddr, dev->irq); - /* - * The TMS SIF registers lay 0x10 above the card base address. - */ - dev->base_addr += 0x10; - - ret = tmsdev_init(dev, &pdev->dev); - if (ret) { - printk("%s: unable to get memory for dev->priv.\n", - dev->name); - goto err_out_irq; - } - - abyss_read_eeprom(dev); - - printk("%s: Ring Station Address: %pM\n", dev->name, dev->dev_addr); - - tp = netdev_priv(dev); - tp->setnselout = abyss_setnselout_pins; - tp->sifreadb = abyss_sifreadb; - tp->sifreadw = abyss_sifreadw; - tp->sifwriteb = abyss_sifwriteb; - tp->sifwritew = abyss_sifwritew; - - memcpy(tp->ProductID, "Madge PCI 16/4 Mk2", PROD_ID_SIZE + 1); - - dev->netdev_ops = &abyss_netdev_ops; - - pci_set_drvdata(pdev, dev); - SET_NETDEV_DEV(dev, &pdev->dev); - - ret = register_netdev(dev); - if (ret) - goto err_out_tmsdev; - return 0; - -err_out_tmsdev: - pci_set_drvdata(pdev, NULL); - tmsdev_term(dev); -err_out_irq: - free_irq(pdev->irq, dev); -err_out_region: - release_region(pci_ioaddr, ABYSS_IO_EXTENT); -err_out_trdev: - free_netdev(dev); - return ret; -} - -static unsigned short abyss_setnselout_pins(struct net_device *dev) -{ - unsigned short val = 0; - struct net_local *tp = netdev_priv(dev); - - if(tp->DataRate == SPEED_4) - val |= 0x01; /* Set 4Mbps */ - else - val |= 0x00; /* Set 16Mbps */ - - return val; -} - -/* - * The following Madge boards should use this code: - * - Smart 16/4 PCI Mk2 (Abyss) - * - Smart 16/4 PCI Mk1 (PCI T) - * - Smart 16/4 Client Plus PnP (Big Apple) - * - Smart 16/4 Cardbus Mk2 - * - * These access an Atmel AT24 SEEPROM using their glue chip registers. - * - */ -static void at24_writedatabyte(unsigned long regaddr, unsigned char byte) -{ - int i; - - for (i = 0; i < 8; i++) { - at24_setlines(regaddr, 0, (byte >> (7-i))&0x01); - at24_setlines(regaddr, 1, (byte >> (7-i))&0x01); - at24_setlines(regaddr, 0, (byte >> (7-i))&0x01); - } -} - -static int at24_sendfullcmd(unsigned long regaddr, unsigned char cmd, unsigned char addr) -{ - if (at24_sendcmd(regaddr, cmd)) { - at24_writedatabyte(regaddr, addr); - return at24_waitforack(regaddr); - } - return 0; -} - -static int at24_sendcmd(unsigned long regaddr, unsigned char cmd) -{ - int i; - - for (i = 0; i < 10; i++) { - at24_start(regaddr); - at24_writedatabyte(regaddr, cmd); - if (at24_waitforack(regaddr)) - return 1; - } - return 0; -} - -static unsigned char at24_readdatabit(unsigned long regaddr) -{ - unsigned char val; - - at24_setlines(regaddr, 0, 1); - at24_setlines(regaddr, 1, 1); - val = (inb(regaddr) & AT24_DATA)?1:0; - at24_setlines(regaddr, 1, 1); - at24_setlines(regaddr, 0, 1); - return val; -} - -static unsigned char at24_readdatabyte(unsigned long regaddr) -{ - unsigned char data = 0; - int i; - - for (i = 0; i < 8; i++) { - data <<= 1; - data |= at24_readdatabit(regaddr); - } - - return data; -} - -static int at24_waitforack(unsigned long regaddr) -{ - int i; - - for (i = 0; i < 10; i++) { - if ((at24_readdatabit(regaddr) & 0x01) == 0x00) - return 1; - } - return 0; -} - -static int at24_waitfornack(unsigned long regaddr) -{ - int i; - for (i = 0; i < 10; i++) { - if ((at24_readdatabit(regaddr) & 0x01) == 0x01) - return 1; - } - return 0; -} - -static void at24_setlines(unsigned long regaddr, unsigned char clock, unsigned char data) -{ - unsigned char val = AT24_ENABLE; - if (clock) - val |= AT24_CLOCK; - if (data) - val |= AT24_DATA; - - outb(val, regaddr); - tms380tr_wait(20); /* Very necessary. */ -} - -static void at24_start(unsigned long regaddr) -{ - at24_setlines(regaddr, 0, 1); - at24_setlines(regaddr, 1, 1); - at24_setlines(regaddr, 1, 0); - at24_setlines(regaddr, 0, 1); -} - -static unsigned char at24_readb(unsigned long regaddr, unsigned char addr) -{ - unsigned char data = 0xff; - - if (at24_sendfullcmd(regaddr, AT24_WRITE, addr)) { - if (at24_sendcmd(regaddr, AT24_READ)) { - data = at24_readdatabyte(regaddr); - if (!at24_waitfornack(regaddr)) - data = 0xff; - } - } - return data; -} - - -/* - * Enable basic functions of the Madge chipset needed - * for initialization. - */ -static void abyss_enable(struct net_device *dev) -{ - unsigned char reset_reg; - unsigned long ioaddr; - - ioaddr = dev->base_addr; - reset_reg = inb(ioaddr + PCIBM2_RESET_REG); - reset_reg |= PCIBM2_RESET_REG_CHIP_NRES; - outb(reset_reg, ioaddr + PCIBM2_RESET_REG); - tms380tr_wait(100); -} - -/* - * Enable the functions of the Madge chipset needed for - * full working order. - */ -static int abyss_chipset_init(struct net_device *dev) -{ - unsigned char reset_reg; - unsigned long ioaddr; - - ioaddr = dev->base_addr; - - reset_reg = inb(ioaddr + PCIBM2_RESET_REG); - - reset_reg |= PCIBM2_RESET_REG_CHIP_NRES; - outb(reset_reg, ioaddr + PCIBM2_RESET_REG); - - reset_reg &= ~(PCIBM2_RESET_REG_CHIP_NRES | - PCIBM2_RESET_REG_FIFO_NRES | - PCIBM2_RESET_REG_SIF_NRES); - outb(reset_reg, ioaddr + PCIBM2_RESET_REG); - - tms380tr_wait(100); - - reset_reg |= PCIBM2_RESET_REG_CHIP_NRES; - outb(reset_reg, ioaddr + PCIBM2_RESET_REG); - - reset_reg |= PCIBM2_RESET_REG_SIF_NRES; - outb(reset_reg, ioaddr + PCIBM2_RESET_REG); - - reset_reg |= PCIBM2_RESET_REG_FIFO_NRES; - outb(reset_reg, ioaddr + PCIBM2_RESET_REG); - - outb(PCIBM2_INT_CONTROL_REG_SINTEN | - PCIBM2_INT_CONTROL_REG_PCI_ERR_ENABLE, - ioaddr + PCIBM2_INT_CONTROL_REG); - - outb(30, ioaddr + PCIBM2_FIFO_THRESHOLD); - - return 0; -} - -static inline void abyss_chipset_close(struct net_device *dev) -{ - unsigned long ioaddr; - - ioaddr = dev->base_addr; - outb(0, ioaddr + PCIBM2_RESET_REG); -} - -/* - * Read configuration data from the AT24 SEEPROM on Madge cards. - * - */ -static void abyss_read_eeprom(struct net_device *dev) -{ - struct net_local *tp; - unsigned long ioaddr; - unsigned short val; - int i; - - tp = netdev_priv(dev); - ioaddr = dev->base_addr; - - /* Must enable glue chip first */ - abyss_enable(dev); - - val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, - PCIBM2_SEEPROM_RING_SPEED); - tp->DataRate = val?SPEED_4:SPEED_16; /* set open speed */ - printk("%s: SEEPROM: ring speed: %dMb/sec\n", dev->name, tp->DataRate); - - val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, - PCIBM2_SEEPROM_RAM_SIZE) * 128; - printk("%s: SEEPROM: adapter RAM: %dkb\n", dev->name, val); - - dev->addr_len = 6; - for (i = 0; i < 6; i++) - dev->dev_addr[i] = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, - PCIBM2_SEEPROM_BIA+i); -} - -static int abyss_open(struct net_device *dev) -{ - abyss_chipset_init(dev); - tms380tr_open(dev); - return 0; -} - -static int abyss_close(struct net_device *dev) -{ - tms380tr_close(dev); - abyss_chipset_close(dev); - return 0; -} - -static void __devexit abyss_detach (struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - BUG_ON(!dev); - unregister_netdev(dev); - release_region(dev->base_addr-0x10, ABYSS_IO_EXTENT); - free_irq(dev->irq, dev); - tmsdev_term(dev); - free_netdev(dev); - pci_set_drvdata(pdev, NULL); -} - -static struct pci_driver abyss_driver = { - .name = "abyss", - .id_table = abyss_pci_tbl, - .probe = abyss_attach, - .remove = __devexit_p(abyss_detach), -}; - -static int __init abyss_init (void) -{ - abyss_netdev_ops = tms380tr_netdev_ops; - - abyss_netdev_ops.ndo_open = abyss_open; - abyss_netdev_ops.ndo_stop = abyss_close; - - return pci_register_driver(&abyss_driver); -} - -static void __exit abyss_rmmod (void) -{ - pci_unregister_driver (&abyss_driver); -} - -module_init(abyss_init); -module_exit(abyss_rmmod); -
diff --git a/drivers/net/tokenring/abyss.h b/drivers/net/tokenring/abyss.h deleted file mode 100644 index b0a473b..0000000 --- a/drivers/net/tokenring/abyss.h +++ /dev/null
@@ -1,58 +0,0 @@ -/* - * abyss.h: Header for the abyss tms380tr module - * - * Authors: - * - Adam Fritzler - */ - -#ifndef __LINUX_MADGETR_H -#define __LINUX_MADGETR_H - -#ifdef __KERNEL__ - -/* - * For Madge Smart 16/4 PCI Mk2. Since we increment the base address - * to get everything correct for the TMS SIF, we do these as negatives - * as they fall below the SIF in addressing. - */ -#define PCIBM2_INT_STATUS_REG ((short)-15)/* 0x01 */ -#define PCIBM2_INT_CONTROL_REG ((short)-14)/* 0x02 */ -#define PCIBM2_RESET_REG ((short)-12)/* 0x04 */ -#define PCIBM2_SEEPROM_REG ((short)-9) /* 0x07 */ - -#define PCIBM2_INT_CONTROL_REG_SINTEN 0x02 -#define PCIBM2_INT_CONTROL_REG_PCI_ERR_ENABLE 0x80 -#define PCIBM2_INT_STATUS_REG_PCI_ERR 0x80 - -#define PCIBM2_RESET_REG_CHIP_NRES 0x01 -#define PCIBM2_RESET_REG_FIFO_NRES 0x02 -#define PCIBM2_RESET_REG_SIF_NRES 0x04 - -#define PCIBM2_FIFO_THRESHOLD 0x21 -#define PCIBM2_BURST_LENGTH 0x22 - -/* - * Bits in PCIBM2_SEEPROM_REG. - */ -#define AT24_ENABLE 0x04 -#define AT24_DATA 0x02 -#define AT24_CLOCK 0x01 - -/* - * AT24 Commands. - */ -#define AT24_WRITE 0xA0 -#define AT24_READ 0xA1 - -/* - * Addresses in AT24 SEEPROM. - */ -#define PCIBM2_SEEPROM_BIA 0x12 -#define PCIBM2_SEEPROM_RING_SPEED 0x18 -#define PCIBM2_SEEPROM_RAM_SIZE 0x1A -#define PCIBM2_SEEPROM_HWF1 0x1C -#define PCIBM2_SEEPROM_HWF2 0x1E - - -#endif /* __KERNEL__ */ -#endif /* __LINUX_MADGETR_H */
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c deleted file mode 100644 index b5c8c18..0000000 --- a/drivers/net/tokenring/ibmtr.c +++ /dev/null
@@ -1,1964 +0,0 @@ -/* ibmtr.c: A shared-memory IBM Token Ring 16/4 driver for linux - * - * Written 1993 by Mark Swanson and Peter De Schrijver. - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * This device driver should work with Any IBM Token Ring Card that does - * not use DMA. - * - * I used Donald Becker's (becker@scyld.com) device driver work - * as a base for most of my initial work. - * - * Changes by Peter De Schrijver - * (Peter.Deschrijver@linux.cc.kuleuven.ac.be) : - * - * + changed name to ibmtr.c in anticipation of other tr boards. - * + changed reset code and adapter open code. - * + added SAP open code. - * + a first attempt to write interrupt, transmit and receive routines. - * - * Changes by David W. Morris (dwm@shell.portal.com) : - * 941003 dwm: - Restructure tok_probe for multiple adapters, devices. - * + Add comments, misc reorg for clarity. - * + Flatten interrupt handler levels. - * - * Changes by Farzad Farid (farzy@zen.via.ecp.fr) - * and Pascal Andre (andre@chimay.via.ecp.fr) (March 9 1995) : - * + multi ring support clean up. - * + RFC1042 compliance enhanced. - * - * Changes by Pascal Andre (andre@chimay.via.ecp.fr) (September 7 1995) : - * + bug correction in tr_tx - * + removed redundant information display - * + some code reworking - * - * Changes by Michel Lespinasse (walken@via.ecp.fr), - * Yann Doussot (doussot@via.ecp.fr) and Pascal Andre (andre@via.ecp.fr) - * (February 18, 1996) : - * + modified shared memory and mmio access port the driver to - * alpha platform (structure access -> readb/writeb) - * - * Changes by Steve Kipisz (bungy@ibm.net or kipisz@vnet.ibm.com) - * (January 18 1996): - * + swapped WWOR and WWCR in ibmtr.h - * + moved some init code from tok_probe into trdev_init. The - * PCMCIA code can call trdev_init to complete initializing - * the driver. - * + added -DPCMCIA to support PCMCIA - * + detecting PCMCIA Card Removal in interrupt handler. If - * ISRP is FF, then a PCMCIA card has been removed - * 10/2000 Burt needed a new method to avoid crashing the OS - * - * Changes by Paul Norton (pnorton@cts.com) : - * + restructured the READ.LOG logic to prevent the transmit SRB - * from being rudely overwritten before the transmit cycle is - * complete. (August 15 1996) - * + completed multiple adapter support. (November 20 1996) - * + implemented csum_partial_copy in tr_rx and increased receive - * buffer size and count. Minor fixes. (March 15, 1997) - * - * Changes by Christopher Turcksin <wabbit@rtfc.demon.co.uk> - * + Now compiles ok as a module again. - * - * Changes by Paul Norton (pnorton@ieee.org) : - * + moved the header manipulation code in tr_tx and tr_rx to - * net/802/tr.c. (July 12 1997) - * + add retry and timeout on open if cable disconnected. (May 5 1998) - * + lifted 2000 byte mtu limit. now depends on shared-RAM size. - * May 25 1998) - * + can't allocate 2k recv buff at 8k shared-RAM. (20 October 1998) - * - * Changes by Joel Sloan (jjs@c-me.com) : - * + disable verbose debug messages by default - to enable verbose - * debugging, edit the IBMTR_DEBUG_MESSAGES define below - * - * Changes by Mike Phillips <phillim@amtrak.com> : - * + Added extra #ifdef's to work with new PCMCIA Token Ring Code. - * The PCMCIA code now just sets up the card so it can be recognized - * by ibmtr_probe. Also checks allocated memory vs. on-board memory - * for correct figure to use. - * - * Changes by Tim Hockin (thockin@isunix.it.ilstu.edu) : - * + added spinlocks for SMP sanity (10 March 1999) - * - * Changes by Jochen Friedrich to enable RFC1469 Option 2 multicasting - * i.e. using functional address C0 00 00 04 00 00 to transmit and - * receive multicast packets. - * - * Changes by Mike Sullivan (based on original sram patch by Dave Grothe - * to support windowing into on adapter shared ram. - * i.e. Use LANAID to setup a PnP configuration with 16K RAM. Paging - * will shift this 16K window over the entire available shared RAM. - * - * Changes by Peter De Schrijver (p2@mind.be) : - * + fixed a problem with PCMCIA card removal - * - * Change by Mike Sullivan et al.: - * + added turbo card support. No need to use lanaid to configure - * the adapter into isa compatibility mode. - * - * Changes by Burt Silverman to allow the computer to behave nicely when - * a cable is pulled or not in place, or a PCMCIA card is removed hot. - */ - -/* change the define of IBMTR_DEBUG_MESSAGES to a nonzero value -in the event that chatty debug messages are desired - jjs 12/30/98 */ - -#define IBMTR_DEBUG_MESSAGES 0 - -#include <linux/module.h> -#include <linux/sched.h> - -#ifdef PCMCIA /* required for ibmtr_cs.c to build */ -#undef MODULE /* yes, really */ -#undef ENABLE_PAGING -#else -#define ENABLE_PAGING 1 -#endif - -/* changes the output format of driver initialization */ -#define TR_VERBOSE 0 - -/* some 95 OS send many non UI frame; this allow removing the warning */ -#define TR_FILTERNONUI 1 - -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/netdevice.h> -#include <linux/ip.h> -#include <linux/trdevice.h> -#include <linux/ibmtr.h> - -#include <net/checksum.h> - -#include <asm/io.h> - -#define DPRINTK(format, args...) printk("%s: " format, dev->name , ## args) -#define DPRINTD(format, args...) DummyCall("%s: " format, dev->name , ## args) - -/* version and credits */ -#ifndef PCMCIA -static char version[] __devinitdata = - "\nibmtr.c: v1.3.57 8/ 7/94 Peter De Schrijver and Mark Swanson\n" - " v2.1.125 10/20/98 Paul Norton <pnorton@ieee.org>\n" - " v2.2.0 12/30/98 Joel Sloan <jjs@c-me.com>\n" - " v2.2.1 02/08/00 Mike Sullivan <sullivam@us.ibm.com>\n" - " v2.2.2 07/27/00 Burt Silverman <burts@us.ibm.com>\n" - " v2.4.0 03/01/01 Mike Sullivan <sullivan@us.ibm.com>\n"; -#endif - -/* this allows displaying full adapter information */ - -static char *channel_def[] __devinitdata = { "ISA", "MCA", "ISA P&P" }; - -static char pcchannelid[] __devinitdata = { - 0x05, 0x00, 0x04, 0x09, - 0x04, 0x03, 0x04, 0x0f, - 0x03, 0x06, 0x03, 0x01, - 0x03, 0x01, 0x03, 0x00, - 0x03, 0x09, 0x03, 0x09, - 0x03, 0x00, 0x02, 0x00 -}; - -static char mcchannelid[] __devinitdata = { - 0x04, 0x0d, 0x04, 0x01, - 0x05, 0x02, 0x05, 0x03, - 0x03, 0x06, 0x03, 0x03, - 0x05, 0x08, 0x03, 0x04, - 0x03, 0x05, 0x03, 0x01, - 0x03, 0x08, 0x02, 0x00 -}; - -static char __devinit *adapter_def(char type) -{ - switch (type) { - case 0xF: return "PC Adapter | PC Adapter II | Adapter/A"; - case 0xE: return "16/4 Adapter | 16/4 Adapter/A (long)"; - case 0xD: return "16/4 Adapter/A (short) | 16/4 ISA-16 Adapter"; - case 0xC: return "Auto 16/4 Adapter"; - default: return "adapter (unknown type)"; - } -}; - -#define TRC_INIT 0x01 /* Trace initialization & PROBEs */ -#define TRC_INITV 0x02 /* verbose init trace points */ -static unsigned char ibmtr_debug_trace = 0; - -static int ibmtr_probe1(struct net_device *dev, int ioaddr); -static unsigned char get_sram_size(struct tok_info *adapt_info); -static int trdev_init(struct net_device *dev); -static int tok_open(struct net_device *dev); -static int tok_init_card(struct net_device *dev); -static void tok_open_adapter(unsigned long dev_addr); -static void open_sap(unsigned char type, struct net_device *dev); -static void tok_set_multicast_list(struct net_device *dev); -static netdev_tx_t tok_send_packet(struct sk_buff *skb, - struct net_device *dev); -static int tok_close(struct net_device *dev); -static irqreturn_t tok_interrupt(int irq, void *dev_id); -static void initial_tok_int(struct net_device *dev); -static void tr_tx(struct net_device *dev); -static void tr_rx(struct net_device *dev); -static void ibmtr_reset_timer(struct timer_list*tmr,struct net_device *dev); -static void tok_rerun(unsigned long dev_addr); -static void ibmtr_readlog(struct net_device *dev); -static int ibmtr_change_mtu(struct net_device *dev, int mtu); -static void find_turbo_adapters(int *iolist); - -static int ibmtr_portlist[IBMTR_MAX_ADAPTERS+1] __devinitdata = { - 0xa20, 0xa24, 0, 0, 0 -}; -static int __devinitdata turbo_io[IBMTR_MAX_ADAPTERS] = {0}; -static int __devinitdata turbo_irq[IBMTR_MAX_ADAPTERS] = {0}; -static int __devinitdata turbo_searched = 0; - -#ifndef PCMCIA -static __u32 ibmtr_mem_base __devinitdata = 0xd0000; -#endif - -static void __devinit PrtChanID(char *pcid, short stride) -{ - short i, j; - for (i = 0, j = 0; i < 24; i++, j += stride) - printk("%1x", ((int) pcid[j]) & 0x0f); - printk("\n"); -} - -static void __devinit HWPrtChanID(void __iomem *pcid, short stride) -{ - short i, j; - for (i = 0, j = 0; i < 24; i++, j += stride) - printk("%1x", ((int) readb(pcid + j)) & 0x0f); - printk("\n"); -} - -/* We have to ioremap every checked address, because isa_readb is - * going away. - */ - -static void __devinit find_turbo_adapters(int *iolist) -{ - int ram_addr; - int index=0; - void __iomem *chanid; - int found_turbo=0; - unsigned char *tchanid, ctemp; - int i, j; - unsigned long jif; - void __iomem *ram_mapped ; - - if (turbo_searched == 1) return; - turbo_searched=1; - for (ram_addr=0xC0000; ram_addr < 0xE0000; ram_addr+=0x2000) { - - __u32 intf_tbl=0; - - found_turbo=1; - ram_mapped = ioremap((u32)ram_addr,0x1fff) ; - if (ram_mapped==NULL) - continue ; - chanid=(CHANNEL_ID + ram_mapped); - tchanid=pcchannelid; - ctemp=readb(chanid) & 0x0f; - if (ctemp != *tchanid) continue; - for (i=2,j=1; i<=46; i=i+2,j++) { - if ((readb(chanid+i) & 0x0f) != tchanid[j]){ - found_turbo=0; - break; - } - } - if (!found_turbo) continue; - - writeb(0x90, ram_mapped+0x1E01); - for(i=2; i<0x0f; i++) { - writeb(0x00, ram_mapped+0x1E01+i); - } - writeb(0x00, ram_mapped+0x1E01); - for(jif=jiffies+TR_BUSY_INTERVAL; time_before_eq(jiffies,jif);); - intf_tbl=ntohs(readw(ram_mapped+ACA_OFFSET+ACA_RW+WRBR_EVEN)); - if (intf_tbl) { -#if IBMTR_DEBUG_MESSAGES - printk("ibmtr::find_turbo_adapters, Turbo found at " - "ram_addr %x\n",ram_addr); - printk("ibmtr::find_turbo_adapters, interface_table "); - for(i=0; i<6; i++) { - printk("%x:",readb(ram_addr+intf_tbl+i)); - } - printk("\n"); -#endif - turbo_io[index]=ntohs(readw(ram_mapped+intf_tbl+4)); - turbo_irq[index]=readb(ram_mapped+intf_tbl+3); - outb(0, turbo_io[index] + ADAPTRESET); - for(jif=jiffies+TR_RST_TIME;time_before_eq(jiffies,jif);); - outb(0, turbo_io[index] + ADAPTRESETREL); - index++; - continue; - } -#if IBMTR_DEBUG_MESSAGES - printk("ibmtr::find_turbo_adapters, ibmtr card found at" - " %x but not a Turbo model\n",ram_addr); -#endif - iounmap(ram_mapped) ; - } /* for */ - for(i=0; i<IBMTR_MAX_ADAPTERS; i++) { - if(!turbo_io[i]) break; - for (j=0; j<IBMTR_MAX_ADAPTERS; j++) { - if ( iolist[j] && iolist[j] != turbo_io[i]) continue; - iolist[j]=turbo_io[i]; - break; - } - } -} - -static void ibmtr_cleanup_card(struct net_device *dev) -{ - if (dev->base_addr) { - outb(0,dev->base_addr+ADAPTRESET); - - schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */ - - outb(0,dev->base_addr+ADAPTRESETREL); - } - -#ifndef PCMCIA - free_irq(dev->irq, dev); - release_region(dev->base_addr, IBMTR_IO_EXTENT); - - { - struct tok_info *ti = netdev_priv(dev); - iounmap(ti->mmio); - iounmap(ti->sram_virt); - } -#endif -} - -/**************************************************************************** - * ibmtr_probe(): Routine specified in the network device structure - * to probe for an IBM Token Ring Adapter. Routine outline: - * I. Interrogate hardware to determine if an adapter exists - * and what the speeds and feeds are - * II. Setup data structures to control execution based upon - * adapter characteristics. - * - * We expect ibmtr_probe to be called once for each device entry - * which references it. - ****************************************************************************/ - -static int __devinit ibmtr_probe(struct net_device *dev) -{ - int i; - int base_addr = dev->base_addr; - - if (base_addr && base_addr <= 0x1ff) /* Don't probe at all. */ - return -ENXIO; - if (base_addr > 0x1ff) { /* Check a single specified location. */ - if (!ibmtr_probe1(dev, base_addr)) return 0; - return -ENODEV; - } - find_turbo_adapters(ibmtr_portlist); - for (i = 0; ibmtr_portlist[i]; i++) { - int ioaddr = ibmtr_portlist[i]; - - if (!ibmtr_probe1(dev, ioaddr)) return 0; - } - return -ENODEV; -} - -int __devinit ibmtr_probe_card(struct net_device *dev) -{ - int err = ibmtr_probe(dev); - if (!err) { - err = register_netdev(dev); - if (err) - ibmtr_cleanup_card(dev); - } - return err; -} - -/*****************************************************************************/ - -static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr) -{ - - unsigned char segment, intr=0, irq=0, i, j, cardpresent=NOTOK, temp=0; - void __iomem * t_mmio = NULL; - struct tok_info *ti = netdev_priv(dev); - void __iomem *cd_chanid; - unsigned char *tchanid, ctemp; -#ifndef PCMCIA - unsigned char t_irq=0; - unsigned long timeout; - static int version_printed; -#endif - - /* Query the adapter PIO base port which will return - * indication of where MMIO was placed. We also have a - * coded interrupt number. - */ - segment = inb(PIOaddr); - if (segment < 0x40 || segment > 0xe0) { - /* Out of range values so we'll assume non-existent IO device - * but this is not necessarily a problem, esp if a turbo - * adapter is being used. */ -#if IBMTR_DEBUG_MESSAGES - DPRINTK("ibmtr_probe1(): unhappy that inb(0x%X) == 0x%X, " - "Hardware Problem?\n",PIOaddr,segment); -#endif - return -ENODEV; - } - /* - * Compute the linear base address of the MMIO area - * as LINUX doesn't care about segments - */ - t_mmio = ioremap(((__u32) (segment & 0xfc) << 11) + 0x80000,2048); - if (!t_mmio) { - DPRINTK("Cannot remap mmiobase memory area") ; - return -ENODEV ; - } - intr = segment & 0x03; /* low bits is coded interrupt # */ - if (ibmtr_debug_trace & TRC_INIT) - DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %p intr: %d\n" - , PIOaddr, (int) segment, t_mmio, (int) intr); - - /* - * Now we will compare expected 'channelid' strings with - * what we is there to learn of ISA/MCA or not TR card - */ -#ifdef PCMCIA - iounmap(t_mmio); - t_mmio = ti->mmio; /*BMS to get virtual address */ - irq = ti->irq; /*BMS to display the irq! */ -#endif - cd_chanid = (CHANNEL_ID + t_mmio); /* for efficiency */ - tchanid = pcchannelid; - cardpresent = TR_ISA; /* try ISA */ - - /* Suboptimize knowing first byte different */ - ctemp = readb(cd_chanid) & 0x0f; - if (ctemp != *tchanid) { /* NOT ISA card, try MCA */ - tchanid = mcchannelid; - cardpresent = TR_MCA; - if (ctemp != *tchanid) /* Neither ISA nor MCA */ - cardpresent = NOTOK; - } - if (cardpresent != NOTOK) { - /* Know presumed type, try rest of ID */ - for (i = 2, j = 1; i <= 46; i = i + 2, j++) { - if( (readb(cd_chanid+i)&0x0f) == tchanid[j]) continue; - /* match failed, not TR card */ - cardpresent = NOTOK; - break; - } - } - /* - * If we have an ISA board check for the ISA P&P version, - * as it has different IRQ settings - */ - if (cardpresent == TR_ISA && (readb(AIPFID + t_mmio) == 0x0e)) - cardpresent = TR_ISAPNP; - if (cardpresent == NOTOK) { /* "channel_id" did not match, report */ - if (!(ibmtr_debug_trace & TRC_INIT)) { -#ifndef PCMCIA - iounmap(t_mmio); -#endif - return -ENODEV; - } - DPRINTK( "Channel ID string not found for PIOaddr: %4hx\n", - PIOaddr); - DPRINTK("Expected for ISA: "); - PrtChanID(pcchannelid, 1); - DPRINTK(" found: "); -/* BMS Note that this can be misleading, when hardware is flaky, because you - are reading it a second time here. So with my flaky hardware, I'll see my- - self in this block, with the HW ID matching the ISA ID exactly! */ - HWPrtChanID(cd_chanid, 2); - DPRINTK("Expected for MCA: "); - PrtChanID(mcchannelid, 1); - } - /* Now, setup some of the pl0 buffers for this driver.. */ - /* If called from PCMCIA, it is already set up, so no need to - waste the memory, just use the existing structure */ -#ifndef PCMCIA - ti->mmio = t_mmio; - for (i = 0; i < IBMTR_MAX_ADAPTERS; i++) { - if (turbo_io[i] != PIOaddr) - continue; -#if IBMTR_DEBUG_MESSAGES - printk("ibmtr::tr_probe1, setting PIOaddr %x to Turbo\n", - PIOaddr); -#endif - ti->turbo = 1; - t_irq = turbo_irq[i]; - } -#endif /* !PCMCIA */ - ti->readlog_pending = 0; - init_waitqueue_head(&ti->wait_for_reset); - - /* if PCMCIA, the card can be recognized as either TR_ISA or TR_ISAPNP - * depending which card is inserted. */ - -#ifndef PCMCIA - switch (cardpresent) { - case TR_ISA: - if (intr == 0) irq = 9; /* irq2 really is irq9 */ - if (intr == 1) irq = 3; - if (intr == 2) irq = 6; - if (intr == 3) irq = 7; - ti->adapter_int_enable = PIOaddr + ADAPTINTREL; - break; - case TR_MCA: - if (intr == 0) irq = 9; - if (intr == 1) irq = 3; - if (intr == 2) irq = 10; - if (intr == 3) irq = 11; - ti->global_int_enable = 0; - ti->adapter_int_enable = 0; - ti->sram_phys=(__u32)(inb(PIOaddr+ADAPTRESETREL) & 0xfe) << 12; - break; - case TR_ISAPNP: - if (!t_irq) { - if (intr == 0) irq = 9; - if (intr == 1) irq = 3; - if (intr == 2) irq = 10; - if (intr == 3) irq = 11; - } else - irq=t_irq; - timeout = jiffies + TR_SPIN_INTERVAL; - while (!readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)){ - if (!time_after(jiffies, timeout)) continue; - DPRINTK( "Hardware timeout during initialization.\n"); - iounmap(t_mmio); - return -ENODEV; - } - ti->sram_phys = - ((__u32)readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_EVEN)<<12); - ti->adapter_int_enable = PIOaddr + ADAPTINTREL; - break; - } /*end switch (cardpresent) */ -#endif /*not PCMCIA */ - - if (ibmtr_debug_trace & TRC_INIT) { /* just report int */ - DPRINTK("irq=%d", irq); - printk(", sram_phys=0x%x", ti->sram_phys); - if(ibmtr_debug_trace&TRC_INITV){ /* full chat in verbose only */ - DPRINTK(", ti->mmio=%p", ti->mmio); - printk(", segment=%02X", segment); - } - printk(".\n"); - } - - /* Get hw address of token ring card */ - j = 0; - for (i = 0; i < 0x18; i = i + 2) { - /* technical reference states to do this */ - temp = readb(ti->mmio + AIP + i) & 0x0f; - ti->hw_address[j] = temp; - if (j & 1) - dev->dev_addr[(j / 2)] = - ti->hw_address[j]+ (ti->hw_address[j - 1] << 4); - ++j; - } - /* get Adapter type: 'F' = Adapter/A, 'E' = 16/4 Adapter II,... */ - ti->adapter_type = readb(ti->mmio + AIPADAPTYPE); - - /* get Data Rate: F=4Mb, E=16Mb, D=4Mb & 16Mb ?? */ - ti->data_rate = readb(ti->mmio + AIPDATARATE); - - /* Get Early Token Release support?: F=no, E=4Mb, D=16Mb, C=4&16Mb */ - ti->token_release = readb(ti->mmio + AIPEARLYTOKEN); - - /* How much shared RAM is on adapter ? */ - if (ti->turbo) { - ti->avail_shared_ram=127; - } else { - ti->avail_shared_ram = get_sram_size(ti);/*in 512 byte units */ - } - /* We need to set or do a bunch of work here based on previous results*/ - /* Support paging? What sizes?: F=no, E=16k, D=32k, C=16 & 32k */ - ti->shared_ram_paging = readb(ti->mmio + AIPSHRAMPAGE); - - /* Available DHB 4Mb size: F=2048, E=4096, D=4464 */ - switch (readb(ti->mmio + AIP4MBDHB)) { - case 0xe: ti->dhb_size4mb = 4096; break; - case 0xd: ti->dhb_size4mb = 4464; break; - default: ti->dhb_size4mb = 2048; break; - } - - /* Available DHB 16Mb size: F=2048, E=4096, D=8192, C=16384, B=17960 */ - switch (readb(ti->mmio + AIP16MBDHB)) { - case 0xe: ti->dhb_size16mb = 4096; break; - case 0xd: ti->dhb_size16mb = 8192; break; - case 0xc: ti->dhb_size16mb = 16384; break; - case 0xb: ti->dhb_size16mb = 17960; break; - default: ti->dhb_size16mb = 2048; break; - } - - /* We must figure out how much shared memory space this adapter - * will occupy so that if there are two adapters we can fit both - * in. Given a choice, we will limit this adapter to 32K. The - * maximum space will will use for two adapters is 64K so if the - * adapter we are working on demands 64K (it also doesn't support - * paging), then only one adapter can be supported. - */ - - /* - * determine how much of total RAM is mapped into PC space - */ - ti->mapped_ram_size= /*sixteen to onehundredtwentyeight 512byte blocks*/ - 1<< ((readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_ODD) >> 2 & 0x03) + 4); - ti->page_mask = 0; - if (ti->turbo) ti->page_mask=0xf0; - else if (ti->shared_ram_paging == 0xf); /* No paging in adapter */ - else { -#ifdef ENABLE_PAGING - unsigned char pg_size = 0; - /* BMS: page size: PCMCIA, use configuration register; - ISAPNP, use LANAIDC config tool from www.ibm.com */ - switch (ti->shared_ram_paging) { - case 0xf: - break; - case 0xe: - ti->page_mask = (ti->mapped_ram_size == 32) ? 0xc0 : 0; - pg_size = 32; /* 16KB page size */ - break; - case 0xd: - ti->page_mask = (ti->mapped_ram_size == 64) ? 0x80 : 0; - pg_size = 64; /* 32KB page size */ - break; - case 0xc: - switch (ti->mapped_ram_size) { - case 32: - ti->page_mask = 0xc0; - pg_size = 32; - break; - case 64: - ti->page_mask = 0x80; - pg_size = 64; - break; - } - break; - default: - DPRINTK("Unknown shared ram paging info %01X\n", - ti->shared_ram_paging); - iounmap(t_mmio); - return -ENODEV; - break; - } /*end switch shared_ram_paging */ - - if (ibmtr_debug_trace & TRC_INIT) - DPRINTK("Shared RAM paging code: %02X, " - "mapped RAM size: %dK, shared RAM size: %dK, " - "page mask: %02X\n:", - ti->shared_ram_paging, ti->mapped_ram_size / 2, - ti->avail_shared_ram / 2, ti->page_mask); -#endif /*ENABLE_PAGING */ - } - -#ifndef PCMCIA - /* finish figuring the shared RAM address */ - if (cardpresent == TR_ISA) { - static const __u32 ram_bndry_mask[] = { - 0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000 - }; - __u32 new_base, rrr_32, chk_base, rbm; - - rrr_32=readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_ODD) >> 2 & 0x03; - rbm = ram_bndry_mask[rrr_32]; - new_base = (ibmtr_mem_base + (~rbm)) & rbm;/* up to boundary */ - chk_base = new_base + (ti->mapped_ram_size << 9); - if (chk_base > (ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE)) { - DPRINTK("Shared RAM for this adapter (%05x) exceeds " - "driver limit (%05x), adapter not started.\n", - chk_base, ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE); - iounmap(t_mmio); - return -ENODEV; - } else { /* seems cool, record what we have figured out */ - ti->sram_base = new_base >> 12; - ibmtr_mem_base = chk_base; - } - } - else ti->sram_base = ti->sram_phys >> 12; - - /* The PCMCIA has already got the interrupt line and the io port, - so no chance of anybody else getting it - MLP */ - if (request_irq(dev->irq = irq, tok_interrupt, 0, "ibmtr", dev) != 0) { - DPRINTK("Could not grab irq %d. Halting Token Ring driver.\n", - irq); - iounmap(t_mmio); - return -ENODEV; - } - /*?? Now, allocate some of the PIO PORTs for this driver.. */ - /* record PIOaddr range as busy */ - if (!request_region(PIOaddr, IBMTR_IO_EXTENT, "ibmtr")) { - DPRINTK("Could not grab PIO range. Halting driver.\n"); - free_irq(dev->irq, dev); - iounmap(t_mmio); - return -EBUSY; - } - - if (!version_printed++) { - printk(version); - } -#endif /* !PCMCIA */ - DPRINTK("%s %s found\n", - channel_def[cardpresent - 1], adapter_def(ti->adapter_type)); - DPRINTK("using irq %d, PIOaddr %hx, %dK shared RAM.\n", - irq, PIOaddr, ti->mapped_ram_size / 2); - DPRINTK("Hardware address : %pM\n", dev->dev_addr); - if (ti->page_mask) - DPRINTK("Shared RAM paging enabled. " - "Page size: %uK Shared Ram size %dK\n", - ((ti->page_mask^0xff)+1) >>2, ti->avail_shared_ram / 2); - else - DPRINTK("Shared RAM paging disabled. ti->page_mask %x\n", - ti->page_mask); - - /* Calculate the maximum DHB we can use */ - /* two cases where avail_shared_ram doesn't equal mapped_ram_size: - 1. avail_shared_ram is 127 but mapped_ram_size is 128 (typical) - 2. user has configured adapter for less than avail_shared_ram - but is not using paging (she should use paging, I believe) - */ - if (!ti->page_mask) { - ti->avail_shared_ram= - min(ti->mapped_ram_size,ti->avail_shared_ram); - } - - switch (ti->avail_shared_ram) { - case 16: /* 8KB shared RAM */ - ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)2048); - ti->rbuf_len4 = 1032; - ti->rbuf_cnt4=2; - ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)2048); - ti->rbuf_len16 = 1032; - ti->rbuf_cnt16=2; - break; - case 32: /* 16KB shared RAM */ - ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464); - ti->rbuf_len4 = 1032; - ti->rbuf_cnt4=4; - ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)4096); - ti->rbuf_len16 = 1032; /*1024 usable */ - ti->rbuf_cnt16=4; - break; - case 64: /* 32KB shared RAM */ - ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464); - ti->rbuf_len4 = 1032; - ti->rbuf_cnt4=6; - ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)10240); - ti->rbuf_len16 = 1032; - ti->rbuf_cnt16=6; - break; - case 127: /* 63.5KB shared RAM */ - ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464); - ti->rbuf_len4 = 1032; - ti->rbuf_cnt4=6; - ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)16384); - ti->rbuf_len16 = 1032; - ti->rbuf_cnt16=16; - break; - case 128: /* 64KB shared RAM */ - ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464); - ti->rbuf_len4 = 1032; - ti->rbuf_cnt4=6; - ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)17960); - ti->rbuf_len16 = 1032; - ti->rbuf_cnt16=16; - break; - default: - ti->dhb_size4mb = 2048; - ti->rbuf_len4 = 1032; - ti->rbuf_cnt4=2; - ti->dhb_size16mb = 2048; - ti->rbuf_len16 = 1032; - ti->rbuf_cnt16=2; - break; - } - /* this formula is not smart enough for the paging case - ti->rbuf_cnt<x> = (ti->avail_shared_ram * BLOCKSZ - ADAPT_PRIVATE - - ARBLENGTH - SSBLENGTH - DLC_MAX_SAP * SAPLENGTH - - DLC_MAX_STA * STALENGTH - ti->dhb_size<x>mb * NUM_DHB - - SRBLENGTH - ASBLENGTH) / ti->rbuf_len<x>; - */ - ti->maxmtu16 = (ti->rbuf_len16 - 8) * ti->rbuf_cnt16 - TR_HLEN; - ti->maxmtu4 = (ti->rbuf_len4 - 8) * ti->rbuf_cnt4 - TR_HLEN; - /*BMS assuming 18 bytes of Routing Information (usually works) */ - DPRINTK("Maximum Receive Internet Protocol MTU 16Mbps: %d, 4Mbps: %d\n", - ti->maxmtu16, ti->maxmtu4); - - dev->base_addr = PIOaddr; /* set the value for device */ - dev->mem_start = ti->sram_base << 12; - dev->mem_end = dev->mem_start + (ti->mapped_ram_size << 9) - 1; - trdev_init(dev); - return 0; /* Return 0 to indicate we have found a Token Ring card. */ -} /*ibmtr_probe1() */ - -/*****************************************************************************/ - -/* query the adapter for the size of shared RAM */ -/* the function returns the RAM size in units of 512 bytes */ - -static unsigned char __devinit get_sram_size(struct tok_info *adapt_info) -{ - unsigned char avail_sram_code; - static unsigned char size_code[] = { 0, 16, 32, 64, 127, 128 }; - /* Adapter gives - 'F' -- use RRR bits 3,2 - 'E' -- 8kb 'D' -- 16kb - 'C' -- 32kb 'A' -- 64KB - 'B' - 64KB less 512 bytes at top - (WARNING ... must zero top bytes in INIT */ - - avail_sram_code = 0xf - readb(adapt_info->mmio + AIPAVAILSHRAM); - if (avail_sram_code) return size_code[avail_sram_code]; - else /* for code 'F', must compute size from RRR(3,2) bits */ - return 1 << - ((readb(adapt_info->mmio+ACA_OFFSET+ACA_RW+RRR_ODD)>>2&3)+4); -} - -/*****************************************************************************/ - -static const struct net_device_ops trdev_netdev_ops = { - .ndo_open = tok_open, - .ndo_stop = tok_close, - .ndo_start_xmit = tok_send_packet, - .ndo_set_rx_mode = tok_set_multicast_list, - .ndo_change_mtu = ibmtr_change_mtu, -}; - -static int __devinit trdev_init(struct net_device *dev) -{ - struct tok_info *ti = netdev_priv(dev); - - SET_PAGE(ti->srb_page); - ti->open_failure = NO ; - dev->netdev_ops = &trdev_netdev_ops; - - return 0; -} - -/*****************************************************************************/ - -static int tok_init_card(struct net_device *dev) -{ - struct tok_info *ti; - short PIOaddr; - unsigned long i; - - PIOaddr = dev->base_addr; - ti = netdev_priv(dev); - /* Special processing for first interrupt after reset */ - ti->do_tok_int = FIRST_INT; - /* Reset adapter */ - writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN); - outb(0, PIOaddr + ADAPTRESET); - - schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */ - - outb(0, PIOaddr + ADAPTRESETREL); -#ifdef ENABLE_PAGING - if (ti->page_mask) - writeb(SRPR_ENABLE_PAGING,ti->mmio+ACA_OFFSET+ACA_RW+SRPR_EVEN); -#endif - writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); - i = sleep_on_timeout(&ti->wait_for_reset, 4 * HZ); - return i? 0 : -EAGAIN; -} - -/*****************************************************************************/ -static int tok_open(struct net_device *dev) -{ - struct tok_info *ti = netdev_priv(dev); - int i; - - /*the case we were left in a failure state during a previous open */ - if (ti->open_failure == YES) { - DPRINTK("Last time you were disconnected, how about now?\n"); - printk("You can't insert with an ICS connector half-cocked.\n"); - } - - ti->open_status = CLOSED; /* CLOSED or OPEN */ - ti->sap_status = CLOSED; /* CLOSED or OPEN */ - ti->open_failure = NO; /* NO or YES */ - ti->open_mode = MANUAL; /* MANUAL or AUTOMATIC */ - - ti->sram_phys &= ~1; /* to reverse what we do in tok_close */ - /* init the spinlock */ - spin_lock_init(&ti->lock); - init_timer(&ti->tr_timer); - - i = tok_init_card(dev); - if (i) return i; - - while (1){ - tok_open_adapter((unsigned long) dev); - i= interruptible_sleep_on_timeout(&ti->wait_for_reset, 25 * HZ); - /* sig catch: estimate opening adapter takes more than .5 sec*/ - if (i>(245*HZ)/10) break; /* fancier than if (i==25*HZ) */ - if (i==0) break; - if (ti->open_status == OPEN && ti->sap_status==OPEN) { - netif_start_queue(dev); - DPRINTK("Adapter is up and running\n"); - return 0; - } - i=schedule_timeout_interruptible(TR_RETRY_INTERVAL); - /* wait 30 seconds */ - if(i!=0) break; /*prob. a signal, like the i>24*HZ case above */ - } - outb(0, dev->base_addr + ADAPTRESET);/* kill pending interrupts*/ - DPRINTK("TERMINATED via signal\n"); /*BMS useful */ - return -EAGAIN; -} - -/*****************************************************************************/ - -#define COMMAND_OFST 0 -#define OPEN_OPTIONS_OFST 8 -#define NUM_RCV_BUF_OFST 24 -#define RCV_BUF_LEN_OFST 26 -#define DHB_LENGTH_OFST 28 -#define NUM_DHB_OFST 30 -#define DLC_MAX_SAP_OFST 32 -#define DLC_MAX_STA_OFST 33 - -static void tok_open_adapter(unsigned long dev_addr) -{ - struct net_device *dev = (struct net_device *) dev_addr; - struct tok_info *ti; - int i; - - ti = netdev_priv(dev); - SET_PAGE(ti->init_srb_page); - writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD); - for (i = 0; i < sizeof(struct dir_open_adapter); i++) - writeb(0, ti->init_srb + i); - writeb(DIR_OPEN_ADAPTER, ti->init_srb + COMMAND_OFST); - writew(htons(OPEN_PASS_BCON_MAC), ti->init_srb + OPEN_OPTIONS_OFST); - if (ti->ring_speed == 16) { - writew(htons(ti->dhb_size16mb), ti->init_srb + DHB_LENGTH_OFST); - writew(htons(ti->rbuf_cnt16), ti->init_srb + NUM_RCV_BUF_OFST); - writew(htons(ti->rbuf_len16), ti->init_srb + RCV_BUF_LEN_OFST); - } else { - writew(htons(ti->dhb_size4mb), ti->init_srb + DHB_LENGTH_OFST); - writew(htons(ti->rbuf_cnt4), ti->init_srb + NUM_RCV_BUF_OFST); - writew(htons(ti->rbuf_len4), ti->init_srb + RCV_BUF_LEN_OFST); - } - writeb(NUM_DHB, /* always 2 */ ti->init_srb + NUM_DHB_OFST); - writeb(DLC_MAX_SAP, ti->init_srb + DLC_MAX_SAP_OFST); - writeb(DLC_MAX_STA, ti->init_srb + DLC_MAX_STA_OFST); - ti->srb = ti->init_srb; /* We use this one in the interrupt handler */ - ti->srb_page = ti->init_srb_page; - DPRINTK("Opening adapter: Xmit bfrs: %d X %d, Rcv bfrs: %d X %d\n", - readb(ti->init_srb + NUM_DHB_OFST), - ntohs(readw(ti->init_srb + DHB_LENGTH_OFST)), - ntohs(readw(ti->init_srb + NUM_RCV_BUF_OFST)), - ntohs(readw(ti->init_srb + RCV_BUF_LEN_OFST))); - writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); - writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); -} - -/*****************************************************************************/ - -static void open_sap(unsigned char type, struct net_device *dev) -{ - int i; - struct tok_info *ti = netdev_priv(dev); - - SET_PAGE(ti->srb_page); - for (i = 0; i < sizeof(struct dlc_open_sap); i++) - writeb(0, ti->srb + i); - -#define MAX_I_FIELD_OFST 14 -#define SAP_VALUE_OFST 16 -#define SAP_OPTIONS_OFST 17 -#define STATION_COUNT_OFST 18 - - writeb(DLC_OPEN_SAP, ti->srb + COMMAND_OFST); - writew(htons(MAX_I_FIELD), ti->srb + MAX_I_FIELD_OFST); - writeb(SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY, ti->srb+ SAP_OPTIONS_OFST); - writeb(SAP_OPEN_STATION_CNT, ti->srb + STATION_COUNT_OFST); - writeb(type, ti->srb + SAP_VALUE_OFST); - writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); -} - - -/*****************************************************************************/ - -static void tok_set_multicast_list(struct net_device *dev) -{ - struct tok_info *ti = netdev_priv(dev); - struct netdev_hw_addr *ha; - unsigned char address[4]; - - int i; - - /*BMS the next line is CRUCIAL or you may be sad when you */ - /*BMS ifconfig tr down or hot unplug a PCMCIA card ??hownowbrowncow*/ - if (/*BMSHELPdev->start == 0 ||*/ ti->open_status != OPEN) return; - address[0] = address[1] = address[2] = address[3] = 0; - netdev_for_each_mc_addr(ha, dev) { - address[0] |= ha->addr[2]; - address[1] |= ha->addr[3]; - address[2] |= ha->addr[4]; - address[3] |= ha->addr[5]; - } - SET_PAGE(ti->srb_page); - for (i = 0; i < sizeof(struct srb_set_funct_addr); i++) - writeb(0, ti->srb + i); - -#define FUNCT_ADDRESS_OFST 6 - - writeb(DIR_SET_FUNC_ADDR, ti->srb + COMMAND_OFST); - for (i = 0; i < 4; i++) - writeb(address[i], ti->srb + FUNCT_ADDRESS_OFST + i); - writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); -#if TR_VERBOSE - DPRINTK("Setting functional address: "); - for (i=0;i<4;i++) printk("%02X ", address[i]); - printk("\n"); -#endif -} - -/*****************************************************************************/ - -#define STATION_ID_OFST 4 - -static netdev_tx_t tok_send_packet(struct sk_buff *skb, - struct net_device *dev) -{ - struct tok_info *ti; - unsigned long flags; - ti = netdev_priv(dev); - - netif_stop_queue(dev); - - /* lock against other CPUs */ - spin_lock_irqsave(&(ti->lock), flags); - - /* Save skb; we'll need it when the adapter asks for the data */ - ti->current_skb = skb; - SET_PAGE(ti->srb_page); - writeb(XMIT_UI_FRAME, ti->srb + COMMAND_OFST); - writew(ti->exsap_station_id, ti->srb + STATION_ID_OFST); - writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); - spin_unlock_irqrestore(&(ti->lock), flags); - return NETDEV_TX_OK; -} - -/*****************************************************************************/ - -static int tok_close(struct net_device *dev) -{ - struct tok_info *ti = netdev_priv(dev); - - /* Important for PCMCIA hot unplug, otherwise, we'll pull the card, */ - /* unloading the module from memory, and then if a timer pops, ouch */ - del_timer_sync(&ti->tr_timer); - outb(0, dev->base_addr + ADAPTRESET); - ti->sram_phys |= 1; - ti->open_status = CLOSED; - - netif_stop_queue(dev); - DPRINTK("Adapter is closed.\n"); - return 0; -} - -/*****************************************************************************/ - -#define RETCODE_OFST 2 -#define OPEN_ERROR_CODE_OFST 6 -#define ASB_ADDRESS_OFST 8 -#define SRB_ADDRESS_OFST 10 -#define ARB_ADDRESS_OFST 12 -#define SSB_ADDRESS_OFST 14 - -static char *printphase[]= {"Lobe media test","Physical insertion", - "Address verification","Roll call poll","Request Parameters"}; -static char *printerror[]={"Function failure","Signal loss","Reserved", - "Frequency error","Timeout","Ring failure","Ring beaconing", - "Duplicate node address", - "Parameter request-retry count exceeded","Remove received", - "IMPL force received","Duplicate modifier", - "No monitor detected","Monitor contention failed for RPL"}; - -static void __iomem *map_address(struct tok_info *ti, unsigned index, __u8 *page) -{ - if (ti->page_mask) { - *page = (index >> 8) & ti->page_mask; - index &= ~(ti->page_mask << 8); - } - return ti->sram_virt + index; -} - -static void dir_open_adapter (struct net_device *dev) -{ - struct tok_info *ti = netdev_priv(dev); - unsigned char ret_code; - __u16 err; - - ti->srb = map_address(ti, - ntohs(readw(ti->init_srb + SRB_ADDRESS_OFST)), - &ti->srb_page); - ti->ssb = map_address(ti, - ntohs(readw(ti->init_srb + SSB_ADDRESS_OFST)), - &ti->ssb_page); - ti->arb = map_address(ti, - ntohs(readw(ti->init_srb + ARB_ADDRESS_OFST)), - &ti->arb_page); - ti->asb = map_address(ti, - ntohs(readw(ti->init_srb + ASB_ADDRESS_OFST)), - &ti->asb_page); - ti->current_skb = NULL; - ret_code = readb(ti->init_srb + RETCODE_OFST); - err = ntohs(readw(ti->init_srb + OPEN_ERROR_CODE_OFST)); - if (!ret_code) { - ti->open_status = OPEN; /* TR adapter is now available */ - if (ti->open_mode == AUTOMATIC) { - DPRINTK("Adapter reopened.\n"); - } - writeb(~SRB_RESP_INT, ti->mmio+ACA_OFFSET+ACA_RESET+ISRP_ODD); - open_sap(EXTENDED_SAP, dev); - return; - } - ti->open_failure = YES; - if (ret_code == 7){ - if (err == 0x24) { - if (!ti->auto_speedsave) { - DPRINTK("Open failed: Adapter speed must match " - "ring speed if Automatic Ring Speed Save is " - "disabled.\n"); - ti->open_action = FAIL; - }else - DPRINTK("Retrying open to adjust to " - "ring speed, "); - } else if (err == 0x2d) { - DPRINTK("Physical Insertion: No Monitor Detected, "); - printk("retrying after %ds delay...\n", - TR_RETRY_INTERVAL/HZ); - } else if (err == 0x11) { - DPRINTK("Lobe Media Function Failure (0x11), "); - printk(" retrying after %ds delay...\n", - TR_RETRY_INTERVAL/HZ); - } else { - char **prphase = printphase; - char **prerror = printerror; - int pnr = err / 16 - 1; - int enr = err % 16 - 1; - DPRINTK("TR Adapter misc open failure, error code = "); - if (pnr < 0 || pnr >= ARRAY_SIZE(printphase) || - enr < 0 || - enr >= ARRAY_SIZE(printerror)) - printk("0x%x, invalid Phase/Error.", err); - else - printk("0x%x, Phase: %s, Error: %s\n", err, - prphase[pnr], prerror[enr]); - printk(" retrying after %ds delay...\n", - TR_RETRY_INTERVAL/HZ); - } - } else DPRINTK("open failed: ret_code = %02X..., ", ret_code); - if (ti->open_action != FAIL) { - if (ti->open_mode==AUTOMATIC){ - ti->open_action = REOPEN; - ibmtr_reset_timer(&(ti->tr_timer), dev); - return; - } - wake_up(&ti->wait_for_reset); - return; - } - DPRINTK("FAILURE, CAPUT\n"); -} - -/******************************************************************************/ - -static irqreturn_t tok_interrupt(int irq, void *dev_id) -{ - unsigned char status; - /* unsigned char status_even ; */ - struct tok_info *ti; - struct net_device *dev; -#ifdef ENABLE_PAGING - unsigned char save_srpr; -#endif - - dev = dev_id; -#if TR_VERBOSE - DPRINTK("Int from tok_driver, dev : %p irq%d\n", dev,irq); -#endif - ti = netdev_priv(dev); - if (ti->sram_phys & 1) - return IRQ_NONE; /* PCMCIA card extraction flag */ - spin_lock(&(ti->lock)); -#ifdef ENABLE_PAGING - save_srpr = readb(ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN); -#endif - - /* Disable interrupts till processing is finished */ - writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN); - - /* Reset interrupt for ISA boards */ - if (ti->adapter_int_enable) - outb(0, ti->adapter_int_enable); - else /* used for PCMCIA cards */ - outb(0, ti->global_int_enable); - if (ti->do_tok_int == FIRST_INT){ - initial_tok_int(dev); -#ifdef ENABLE_PAGING - writeb(save_srpr, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN); -#endif - spin_unlock(&(ti->lock)); - return IRQ_HANDLED; - } - /* Begin interrupt handler HERE inline to avoid the extra - levels of logic and call depth for the original solution. */ - status = readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD); - /*BMSstatus_even = readb (ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) */ - /*BMSdebugprintk("tok_interrupt: ISRP_ODD = 0x%x ISRP_EVEN = 0x%x\n", */ - /*BMS status,status_even); */ - - if (status & ADAP_CHK_INT) { - int i; - void __iomem *check_reason; - __u8 check_reason_page = 0; - check_reason = map_address(ti, - ntohs(readw(ti->mmio+ ACA_OFFSET+ACA_RW + WWCR_EVEN)), - &check_reason_page); - SET_PAGE(check_reason_page); - - DPRINTK("Adapter check interrupt\n"); - DPRINTK("8 reason bytes follow: "); - for (i = 0; i < 8; i++, check_reason++) - printk("%02X ", (int) readb(check_reason)); - printk("\n"); - writeb(~ADAP_CHK_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD); - status = readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRA_EVEN); - DPRINTK("ISRA_EVEN == 0x02%x\n",status); - ti->open_status = CLOSED; - ti->sap_status = CLOSED; - ti->open_mode = AUTOMATIC; - netif_carrier_off(dev); - netif_stop_queue(dev); - ti->open_action = RESTART; - outb(0, dev->base_addr + ADAPTRESET); - ibmtr_reset_timer(&(ti->tr_timer), dev);/*BMS try to reopen*/ - spin_unlock(&(ti->lock)); - return IRQ_HANDLED; - } - if (readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) - & (TCR_INT | ERR_INT | ACCESS_INT)) { - DPRINTK("adapter error: ISRP_EVEN : %02x\n", - (int)readb(ti->mmio+ ACA_OFFSET + ACA_RW + ISRP_EVEN)); - writeb(~(TCR_INT | ERR_INT | ACCESS_INT), - ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN); - status= readb(ti->mmio+ ACA_OFFSET + ACA_RW + ISRA_EVEN);/*BMS*/ - DPRINTK("ISRA_EVEN == 0x02%x\n",status);/*BMS*/ - writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); -#ifdef ENABLE_PAGING - writeb(save_srpr, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN); -#endif - spin_unlock(&(ti->lock)); - return IRQ_HANDLED; - } - if (status & SRB_RESP_INT) { /* SRB response */ - SET_PAGE(ti->srb_page); -#if TR_VERBOSE - DPRINTK("SRB resp: cmd=%02X rsp=%02X\n", - readb(ti->srb), readb(ti->srb + RETCODE_OFST)); -#endif - switch (readb(ti->srb)) { /* SRB command check */ - case XMIT_DIR_FRAME:{ - unsigned char xmit_ret_code; - xmit_ret_code = readb(ti->srb + RETCODE_OFST); - if (xmit_ret_code == 0xff) break; - DPRINTK("error on xmit_dir_frame request: %02X\n", - xmit_ret_code); - if (ti->current_skb) { - dev_kfree_skb_irq(ti->current_skb); - ti->current_skb = NULL; - } - /*dev->tbusy = 0;*/ - netif_wake_queue(dev); - if (ti->readlog_pending) - ibmtr_readlog(dev); - break; - } - case XMIT_UI_FRAME:{ - unsigned char xmit_ret_code; - - xmit_ret_code = readb(ti->srb + RETCODE_OFST); - if (xmit_ret_code == 0xff) break; - DPRINTK("error on xmit_ui_frame request: %02X\n", - xmit_ret_code); - if (ti->current_skb) { - dev_kfree_skb_irq(ti->current_skb); - ti->current_skb = NULL; - } - netif_wake_queue(dev); - if (ti->readlog_pending) - ibmtr_readlog(dev); - break; - } - case DIR_OPEN_ADAPTER: - dir_open_adapter(dev); - break; - case DLC_OPEN_SAP: - if (readb(ti->srb + RETCODE_OFST)) { - DPRINTK("open_sap failed: ret_code = %02X, " - "retrying\n", - (int) readb(ti->srb + RETCODE_OFST)); - ti->open_action = REOPEN; - ibmtr_reset_timer(&(ti->tr_timer), dev); - break; - } - ti->exsap_station_id = readw(ti->srb + STATION_ID_OFST); - ti->sap_status = OPEN;/* TR adapter is now available */ - if (ti->open_mode==MANUAL){ - wake_up(&ti->wait_for_reset); - break; - } - netif_wake_queue(dev); - netif_carrier_on(dev); - break; - case DIR_INTERRUPT: - case DIR_MOD_OPEN_PARAMS: - case DIR_SET_GRP_ADDR: - case DIR_SET_FUNC_ADDR: - case DLC_CLOSE_SAP: - if (readb(ti->srb + RETCODE_OFST)) - DPRINTK("error on %02X: %02X\n", - (int) readb(ti->srb + COMMAND_OFST), - (int) readb(ti->srb + RETCODE_OFST)); - break; - case DIR_READ_LOG: - if (readb(ti->srb + RETCODE_OFST)){ - DPRINTK("error on dir_read_log: %02X\n", - (int) readb(ti->srb + RETCODE_OFST)); - netif_wake_queue(dev); - break; - } -#if IBMTR_DEBUG_MESSAGES - -#define LINE_ERRORS_OFST 0 -#define INTERNAL_ERRORS_OFST 1 -#define BURST_ERRORS_OFST 2 -#define AC_ERRORS_OFST 3 -#define ABORT_DELIMITERS_OFST 4 -#define LOST_FRAMES_OFST 6 -#define RECV_CONGEST_COUNT_OFST 7 -#define FRAME_COPIED_ERRORS_OFST 8 -#define FREQUENCY_ERRORS_OFST 9 -#define TOKEN_ERRORS_OFST 10 - - DPRINTK("Line errors %02X, Internal errors %02X, " - "Burst errors %02X\n" "A/C errors %02X, " - "Abort delimiters %02X, Lost frames %02X\n" - "Receive congestion count %02X, " - "Frame copied errors %02X\nFrequency errors %02X, " - "Token errors %02X\n", - (int) readb(ti->srb + LINE_ERRORS_OFST), - (int) readb(ti->srb + INTERNAL_ERRORS_OFST), - (int) readb(ti->srb + BURST_ERRORS_OFST), - (int) readb(ti->srb + AC_ERRORS_OFST), - (int) readb(ti->srb + ABORT_DELIMITERS_OFST), - (int) readb(ti->srb + LOST_FRAMES_OFST), - (int) readb(ti->srb + RECV_CONGEST_COUNT_OFST), - (int) readb(ti->srb + FRAME_COPIED_ERRORS_OFST), - (int) readb(ti->srb + FREQUENCY_ERRORS_OFST), - (int) readb(ti->srb + TOKEN_ERRORS_OFST)); -#endif - netif_wake_queue(dev); - break; - default: - DPRINTK("Unknown command %02X encountered\n", - (int) readb(ti->srb)); - } /* end switch SRB command check */ - writeb(~SRB_RESP_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD); - } /* if SRB response */ - if (status & ASB_FREE_INT) { /* ASB response */ - SET_PAGE(ti->asb_page); -#if TR_VERBOSE - DPRINTK("ASB resp: cmd=%02X\n", readb(ti->asb)); -#endif - - switch (readb(ti->asb)) { /* ASB command check */ - case REC_DATA: - case XMIT_UI_FRAME: - case XMIT_DIR_FRAME: - break; - default: - DPRINTK("unknown command in asb %02X\n", - (int) readb(ti->asb)); - } /* switch ASB command check */ - if (readb(ti->asb + 2) != 0xff) /* checks ret_code */ - DPRINTK("ASB error %02X in cmd %02X\n", - (int) readb(ti->asb + 2), (int) readb(ti->asb)); - writeb(~ASB_FREE_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD); - } /* if ASB response */ - -#define STATUS_OFST 6 -#define NETW_STATUS_OFST 6 - - if (status & ARB_CMD_INT) { /* ARB response */ - SET_PAGE(ti->arb_page); -#if TR_VERBOSE - DPRINTK("ARB resp: cmd=%02X\n", readb(ti->arb)); -#endif - - switch (readb(ti->arb)) { /* ARB command check */ - case DLC_STATUS: - DPRINTK("DLC_STATUS new status: %02X on station %02X\n", - ntohs(readw(ti->arb + STATUS_OFST)), - ntohs(readw(ti->arb+ STATION_ID_OFST))); - break; - case REC_DATA: - tr_rx(dev); - break; - case RING_STAT_CHANGE:{ - unsigned short ring_status; - ring_status= ntohs(readw(ti->arb + NETW_STATUS_OFST)); - if (ibmtr_debug_trace & TRC_INIT) - DPRINTK("Ring Status Change...(0x%x)\n", - ring_status); - if(ring_status& (REMOVE_RECV|AUTO_REMOVAL|LOBE_FAULT)){ - netif_stop_queue(dev); - netif_carrier_off(dev); - DPRINTK("Remove received, or Auto-removal error" - ", or Lobe fault\n"); - DPRINTK("We'll try to reopen the closed adapter" - " after a %d second delay.\n", - TR_RETRY_INTERVAL/HZ); - /*I was confused: I saw the TR reopening but */ - /*forgot:with an RJ45 in an RJ45/ICS adapter */ - /*but adapter not in the ring, the TR will */ - /* open, and then soon close and come here. */ - ti->open_mode = AUTOMATIC; - ti->open_status = CLOSED; /*12/2000 BMS*/ - ti->open_action = REOPEN; - ibmtr_reset_timer(&(ti->tr_timer), dev); - } else if (ring_status & LOG_OVERFLOW) { - if(netif_queue_stopped(dev)) - ti->readlog_pending = 1; - else - ibmtr_readlog(dev); - } - break; - } - case XMIT_DATA_REQ: - tr_tx(dev); - break; - default: - DPRINTK("Unknown command %02X in arb\n", - (int) readb(ti->arb)); - break; - } /* switch ARB command check */ - writeb(~ARB_CMD_INT, ti->mmio+ ACA_OFFSET+ACA_RESET + ISRP_ODD); - writeb(ARB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); - } /* if ARB response */ - if (status & SSB_RESP_INT) { /* SSB response */ - unsigned char retcode; - SET_PAGE(ti->ssb_page); -#if TR_VERBOSE - DPRINTK("SSB resp: cmd=%02X rsp=%02X\n", - readb(ti->ssb), readb(ti->ssb + 2)); -#endif - - switch (readb(ti->ssb)) { /* SSB command check */ - case XMIT_DIR_FRAME: - case XMIT_UI_FRAME: - retcode = readb(ti->ssb + 2); - if (retcode && (retcode != 0x22))/* checks ret_code */ - DPRINTK("xmit ret_code: %02X xmit error code: " - "%02X\n", - (int)retcode, (int)readb(ti->ssb + 6)); - else - dev->stats.tx_packets++; - break; - case XMIT_XID_CMD: - DPRINTK("xmit xid ret_code: %02X\n", - (int) readb(ti->ssb + 2)); - default: - DPRINTK("Unknown command %02X in ssb\n", - (int) readb(ti->ssb)); - } /* SSB command check */ - writeb(~SSB_RESP_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD); - writeb(SSB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); - } /* if SSB response */ -#ifdef ENABLE_PAGING - writeb(save_srpr, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN); -#endif - writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); - spin_unlock(&(ti->lock)); - return IRQ_HANDLED; -} /*tok_interrupt */ - -/*****************************************************************************/ - -#define INIT_STATUS_OFST 1 -#define INIT_STATUS_2_OFST 2 -#define ENCODED_ADDRESS_OFST 8 - -static void initial_tok_int(struct net_device *dev) -{ - - __u32 encoded_addr, hw_encoded_addr; - struct tok_info *ti; - unsigned char init_status; /*BMS 12/2000*/ - - ti = netdev_priv(dev); - - ti->do_tok_int = NOT_FIRST; - - /* we assign the shared-ram address for ISA devices */ - writeb(ti->sram_base, ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN); -#ifndef PCMCIA - ti->sram_virt = ioremap(((__u32)ti->sram_base << 12), ti->avail_shared_ram); -#endif - ti->init_srb = map_address(ti, - ntohs(readw(ti->mmio + ACA_OFFSET + WRBR_EVEN)), - &ti->init_srb_page); - if (ti->page_mask && ti->avail_shared_ram == 127) { - void __iomem *last_512; - __u8 last_512_page=0; - int i; - last_512 = map_address(ti, 0xfe00, &last_512_page); - /* initialize high section of ram (if necessary) */ - SET_PAGE(last_512_page); - for (i = 0; i < 512; i++) - writeb(0, last_512 + i); - } - SET_PAGE(ti->init_srb_page); - -#if TR_VERBOSE - { - int i; - - DPRINTK("ti->init_srb_page=0x%x\n", ti->init_srb_page); - DPRINTK("init_srb(%p):", ti->init_srb ); - for (i = 0; i < 20; i++) - printk("%02X ", (int) readb(ti->init_srb + i)); - printk("\n"); - } -#endif - - hw_encoded_addr = readw(ti->init_srb + ENCODED_ADDRESS_OFST); - encoded_addr = ntohs(hw_encoded_addr); - init_status= /*BMS 12/2000 check for shallow mode possibility (Turbo)*/ - readb(ti->init_srb+offsetof(struct srb_init_response,init_status)); - /*printk("Initial interrupt: init_status= 0x%02x\n",init_status);*/ - ti->ring_speed = init_status & 0x01 ? 16 : 4; - DPRINTK("Initial interrupt : %d Mbps, shared RAM base %08x.\n", - ti->ring_speed, (unsigned int)dev->mem_start); - ti->auto_speedsave = (readb(ti->init_srb+INIT_STATUS_2_OFST) & 4) != 0; - - if (ti->open_mode == MANUAL) wake_up(&ti->wait_for_reset); - else tok_open_adapter((unsigned long)dev); - -} /*initial_tok_int() */ - -/*****************************************************************************/ - -#define CMD_CORRELATE_OFST 1 -#define DHB_ADDRESS_OFST 6 - -#define FRAME_LENGTH_OFST 6 -#define HEADER_LENGTH_OFST 8 -#define RSAP_VALUE_OFST 9 - -static void tr_tx(struct net_device *dev) -{ - struct tok_info *ti = netdev_priv(dev); - struct trh_hdr *trhdr = (struct trh_hdr *) ti->current_skb->data; - unsigned int hdr_len; - __u32 dhb=0,dhb_base; - void __iomem *dhbuf = NULL; - unsigned char xmit_command; - int i,dhb_len=0x4000,src_len,src_offset; - struct trllc *llc; - struct srb_xmit xsrb; - __u8 dhb_page = 0; - __u8 llc_ssap; - - SET_PAGE(ti->asb_page); - - if (readb(ti->asb+RETCODE_OFST) != 0xFF) DPRINTK("ASB not free !!!\n"); - - /* in providing the transmit interrupts, is telling us it is ready for - data and providing a shared memory address for us to stuff with data. - Here we compute the effective address where we will place data. - */ - SET_PAGE(ti->arb_page); - dhb=dhb_base=ntohs(readw(ti->arb + DHB_ADDRESS_OFST)); - if (ti->page_mask) { - dhb_page = (dhb_base >> 8) & ti->page_mask; - dhb=dhb_base & ~(ti->page_mask << 8); - } - dhbuf = ti->sram_virt + dhb; - - /* Figure out the size of the 802.5 header */ - if (!(trhdr->saddr[0] & 0x80)) /* RIF present? */ - hdr_len = sizeof(struct trh_hdr) - TR_MAXRIFLEN; - else - hdr_len = ((ntohs(trhdr->rcf) & TR_RCF_LEN_MASK) >> 8) - + sizeof(struct trh_hdr) - TR_MAXRIFLEN; - - llc = (struct trllc *) (ti->current_skb->data + hdr_len); - - llc_ssap = llc->ssap; - SET_PAGE(ti->srb_page); - memcpy_fromio(&xsrb, ti->srb, sizeof(xsrb)); - SET_PAGE(ti->asb_page); - xmit_command = xsrb.command; - - writeb(xmit_command, ti->asb + COMMAND_OFST); - writew(xsrb.station_id, ti->asb + STATION_ID_OFST); - writeb(llc_ssap, ti->asb + RSAP_VALUE_OFST); - writeb(xsrb.cmd_corr, ti->asb + CMD_CORRELATE_OFST); - writeb(0, ti->asb + RETCODE_OFST); - if ((xmit_command == XMIT_XID_CMD) || (xmit_command == XMIT_TEST_CMD)) { - writew(htons(0x11), ti->asb + FRAME_LENGTH_OFST); - writeb(0x0e, ti->asb + HEADER_LENGTH_OFST); - SET_PAGE(dhb_page); - writeb(AC, dhbuf); - writeb(LLC_FRAME, dhbuf + 1); - for (i = 0; i < TR_ALEN; i++) - writeb((int) 0x0FF, dhbuf + i + 2); - for (i = 0; i < TR_ALEN; i++) - writeb(0, dhbuf + i + TR_ALEN + 2); - writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); - return; - } - /* - * the token ring packet is copied from sk_buff to the adapter - * buffer identified in the command data received with the interrupt. - */ - writeb(hdr_len, ti->asb + HEADER_LENGTH_OFST); - writew(htons(ti->current_skb->len), ti->asb + FRAME_LENGTH_OFST); - src_len=ti->current_skb->len; - src_offset=0; - dhb=dhb_base; - while(1) { - if (ti->page_mask) { - dhb_page=(dhb >> 8) & ti->page_mask; - dhb=dhb & ~(ti->page_mask << 8); - dhb_len=0x4000-dhb; /* remaining size of this page */ - } - dhbuf = ti->sram_virt + dhb; - SET_PAGE(dhb_page); - if (src_len > dhb_len) { - memcpy_toio(dhbuf,&ti->current_skb->data[src_offset], - dhb_len); - src_len -= dhb_len; - src_offset += dhb_len; - dhb_base+=dhb_len; - dhb=dhb_base; - continue; - } - memcpy_toio(dhbuf, &ti->current_skb->data[src_offset], src_len); - break; - } - writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); - dev->stats.tx_bytes += ti->current_skb->len; - dev_kfree_skb_irq(ti->current_skb); - ti->current_skb = NULL; - netif_wake_queue(dev); - if (ti->readlog_pending) - ibmtr_readlog(dev); -} /*tr_tx */ - -/*****************************************************************************/ - - -#define RECEIVE_BUFFER_OFST 6 -#define LAN_HDR_LENGTH_OFST 8 -#define DLC_HDR_LENGTH_OFST 9 - -#define DSAP_OFST 0 -#define SSAP_OFST 1 -#define LLC_OFST 2 -#define PROTID_OFST 3 -#define ETHERTYPE_OFST 6 - -static void tr_rx(struct net_device *dev) -{ - struct tok_info *ti = netdev_priv(dev); - __u32 rbuffer; - void __iomem *rbuf, *rbufdata, *llc; - __u8 rbuffer_page = 0; - unsigned char *data; - unsigned int rbuffer_len, lan_hdr_len, hdr_len, ip_len, length; - unsigned char dlc_hdr_len; - struct sk_buff *skb; - unsigned int skb_size = 0; - int IPv4_p = 0; - unsigned int chksum = 0; - struct iphdr *iph; - struct arb_rec_req rarb; - - SET_PAGE(ti->arb_page); - memcpy_fromio(&rarb, ti->arb, sizeof(rarb)); - rbuffer = ntohs(rarb.rec_buf_addr) ; - rbuf = map_address(ti, rbuffer, &rbuffer_page); - - SET_PAGE(ti->asb_page); - - if (readb(ti->asb + RETCODE_OFST) !=0xFF) DPRINTK("ASB not free !!!\n"); - - writeb(REC_DATA, ti->asb + COMMAND_OFST); - writew(rarb.station_id, ti->asb + STATION_ID_OFST); - writew(rarb.rec_buf_addr, ti->asb + RECEIVE_BUFFER_OFST); - - lan_hdr_len = rarb.lan_hdr_len; - if (lan_hdr_len > sizeof(struct trh_hdr)) { - DPRINTK("Linux cannot handle greater than 18 bytes RIF\n"); - return; - } /*BMS I added this above just to be very safe */ - dlc_hdr_len = readb(ti->arb + DLC_HDR_LENGTH_OFST); - hdr_len = lan_hdr_len + sizeof(struct trllc) + sizeof(struct iphdr); - - SET_PAGE(rbuffer_page); - llc = rbuf + offsetof(struct rec_buf, data) + lan_hdr_len; - -#if TR_VERBOSE - DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n", - (__u32) offsetof(struct rec_buf, data), (unsigned int) lan_hdr_len); - DPRINTK("llc: %08X rec_buf_addr: %04X dev->mem_start: %lX\n", - llc, ntohs(rarb.rec_buf_addr), dev->mem_start); - DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, " - "ethertype: %04X\n", - (int) readb(llc + DSAP_OFST), (int) readb(llc + SSAP_OFST), - (int) readb(llc + LLC_OFST), (int) readb(llc + PROTID_OFST), - (int) readb(llc+PROTID_OFST+1),(int)readb(llc+PROTID_OFST + 2), - (int) ntohs(readw(llc + ETHERTYPE_OFST))); -#endif - if (readb(llc + offsetof(struct trllc, llc)) != UI_CMD) { - SET_PAGE(ti->asb_page); - writeb(DATA_LOST, ti->asb + RETCODE_OFST); - dev->stats.rx_dropped++; - writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); - return; - } - length = ntohs(rarb.frame_len); - if (readb(llc + DSAP_OFST) == EXTENDED_SAP && - readb(llc + SSAP_OFST) == EXTENDED_SAP && - length >= hdr_len) IPv4_p = 1; -#if TR_VERBOSE -#define SADDR_OFST 8 -#define DADDR_OFST 2 - - if (!IPv4_p) { - - void __iomem *trhhdr = rbuf + offsetof(struct rec_buf, data); - u8 saddr[6]; - u8 daddr[6]; - int i; - for (i = 0 ; i < 6 ; i++) - saddr[i] = readb(trhhdr + SADDR_OFST + i); - for (i = 0 ; i < 6 ; i++) - daddr[i] = readb(trhhdr + DADDR_OFST + i); - DPRINTK("Probably non-IP frame received.\n"); - DPRINTK("ssap: %02X dsap: %02X " - "saddr: %pM daddr: %pM\n", - readb(llc + SSAP_OFST), readb(llc + DSAP_OFST), - saddr, daddr); - } -#endif - - /*BMS handle the case she comes in with few hops but leaves with many */ - skb_size=length-lan_hdr_len+sizeof(struct trh_hdr)+sizeof(struct trllc); - - if (!(skb = dev_alloc_skb(skb_size))) { - DPRINTK("out of memory. frame dropped.\n"); - dev->stats.rx_dropped++; - SET_PAGE(ti->asb_page); - writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code)); - writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); - return; - } - /*BMS again, if she comes in with few but leaves with many */ - skb_reserve(skb, sizeof(struct trh_hdr) - lan_hdr_len); - skb_put(skb, length); - data = skb->data; - rbuffer_len = ntohs(readw(rbuf + offsetof(struct rec_buf, buf_len))); - rbufdata = rbuf + offsetof(struct rec_buf, data); - - if (IPv4_p) { - /* Copy the headers without checksumming */ - memcpy_fromio(data, rbufdata, hdr_len); - - /* Watch for padded packets and bogons */ - iph= (struct iphdr *)(data+ lan_hdr_len + sizeof(struct trllc)); - ip_len = ntohs(iph->tot_len) - sizeof(struct iphdr); - length -= hdr_len; - if ((ip_len <= length) && (ip_len > 7)) - length = ip_len; - data += hdr_len; - rbuffer_len -= hdr_len; - rbufdata += hdr_len; - } - /* Copy the payload... */ -#define BUFFER_POINTER_OFST 2 -#define BUFFER_LENGTH_OFST 6 - for (;;) { - if (ibmtr_debug_trace&TRC_INITV && length < rbuffer_len) - DPRINTK("CURIOUS, length=%d < rbuffer_len=%d\n", - length,rbuffer_len); - if (IPv4_p) - chksum=csum_partial_copy_nocheck((void*)rbufdata, - data,length<rbuffer_len?length:rbuffer_len,chksum); - else - memcpy_fromio(data, rbufdata, rbuffer_len); - rbuffer = ntohs(readw(rbuf+BUFFER_POINTER_OFST)) ; - if (!rbuffer) - break; - rbuffer -= 2; - length -= rbuffer_len; - data += rbuffer_len; - rbuf = map_address(ti, rbuffer, &rbuffer_page); - SET_PAGE(rbuffer_page); - rbuffer_len = ntohs(readw(rbuf + BUFFER_LENGTH_OFST)); - rbufdata = rbuf + offsetof(struct rec_buf, data); - } - - SET_PAGE(ti->asb_page); - writeb(0, ti->asb + offsetof(struct asb_rec, ret_code)); - - writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); - - dev->stats.rx_bytes += skb->len; - dev->stats.rx_packets++; - - skb->protocol = tr_type_trans(skb, dev); - if (IPv4_p) { - skb->csum = chksum; - skb->ip_summed = CHECKSUM_COMPLETE; - } - netif_rx(skb); -} /*tr_rx */ - -/*****************************************************************************/ - -static void ibmtr_reset_timer(struct timer_list *tmr, struct net_device *dev) -{ - tmr->expires = jiffies + TR_RETRY_INTERVAL; - tmr->data = (unsigned long) dev; - tmr->function = tok_rerun; - init_timer(tmr); - add_timer(tmr); -} - -/*****************************************************************************/ - -static void tok_rerun(unsigned long dev_addr) -{ - struct net_device *dev = (struct net_device *)dev_addr; - struct tok_info *ti = netdev_priv(dev); - - if ( ti->open_action == RESTART){ - ti->do_tok_int = FIRST_INT; - outb(0, dev->base_addr + ADAPTRESETREL); -#ifdef ENABLE_PAGING - if (ti->page_mask) - writeb(SRPR_ENABLE_PAGING, - ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN); -#endif - - writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); - } else - tok_open_adapter(dev_addr); -} - -/*****************************************************************************/ - -static void ibmtr_readlog(struct net_device *dev) -{ - struct tok_info *ti; - - ti = netdev_priv(dev); - - ti->readlog_pending = 0; - SET_PAGE(ti->srb_page); - writeb(DIR_READ_LOG, ti->srb); - writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); - writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); - - netif_stop_queue(dev); - -} - -/*****************************************************************************/ - -static int ibmtr_change_mtu(struct net_device *dev, int mtu) -{ - struct tok_info *ti = netdev_priv(dev); - - if (ti->ring_speed == 16 && mtu > ti->maxmtu16) - return -EINVAL; - if (ti->ring_speed == 4 && mtu > ti->maxmtu4) - return -EINVAL; - dev->mtu = mtu; - return 0; -} - -/*****************************************************************************/ -#ifdef MODULE - -/* 3COM 3C619C supports 8 interrupts, 32 I/O ports */ -static struct net_device *dev_ibmtr[IBMTR_MAX_ADAPTERS]; -static int io[IBMTR_MAX_ADAPTERS] = { 0xa20, 0xa24 }; -static int irq[IBMTR_MAX_ADAPTERS]; -static int mem[IBMTR_MAX_ADAPTERS]; - -MODULE_LICENSE("GPL"); - -module_param_array(io, int, NULL, 0); -module_param_array(irq, int, NULL, 0); -module_param_array(mem, int, NULL, 0); - -static int __init ibmtr_init(void) -{ - int i; - int count=0; - - find_turbo_adapters(io); - - for (i = 0; i < IBMTR_MAX_ADAPTERS && io[i]; i++) { - struct net_device *dev; - irq[i] = 0; - mem[i] = 0; - dev = alloc_trdev(sizeof(struct tok_info)); - if (dev == NULL) { - if (i == 0) - return -ENOMEM; - break; - } - dev->base_addr = io[i]; - dev->irq = irq[i]; - dev->mem_start = mem[i]; - - if (ibmtr_probe_card(dev)) { - free_netdev(dev); - continue; - } - dev_ibmtr[i] = dev; - count++; - } - if (count) return 0; - printk("ibmtr: register_netdev() returned non-zero.\n"); - return -EIO; -} -module_init(ibmtr_init); - -static void __exit ibmtr_cleanup(void) -{ - int i; - - for (i = 0; i < IBMTR_MAX_ADAPTERS; i++){ - if (!dev_ibmtr[i]) - continue; - unregister_netdev(dev_ibmtr[i]); - ibmtr_cleanup_card(dev_ibmtr[i]); - free_netdev(dev_ibmtr[i]); - } -} -module_exit(ibmtr_cleanup); -#endif
diff --git a/drivers/net/tokenring/ibmtr_cs.c b/drivers/net/tokenring/ibmtr_cs.c deleted file mode 100644 index 356e28e..0000000 --- a/drivers/net/tokenring/ibmtr_cs.c +++ /dev/null
@@ -1,370 +0,0 @@ -/*====================================================================== - - A PCMCIA token-ring driver for IBM-based cards - - This driver supports the IBM PCMCIA Token-Ring Card. - Written by Steve Kipisz, kipisz@vnet.ibm.com or - bungy@ibm.net - - Written 1995,1996. - - This code is based on pcnet_cs.c from David Hinds. - - V2.2.0 February 1999 - Mike Phillips phillim@amtrak.com - - Linux V2.2.x presented significant changes to the underlying - ibmtr.c code. Mainly the code became a lot more organized and - modular. - - This caused the old PCMCIA Token Ring driver to give up and go - home early. Instead of just patching the old code to make it - work, the PCMCIA code has been streamlined, updated and possibly - improved. - - This code now only contains code required for the Card Services. - All we do here is set the card up enough so that the real ibmtr.c - driver can find it and work with it properly. - - i.e. We set up the io port, irq, mmio memory and shared ram - memory. This enables ibmtr_probe in ibmtr.c to find the card and - configure it as though it was a normal ISA and/or PnP card. - - CHANGES - - v2.2.5 April 1999 Mike Phillips (phillim@amtrak.com) - Obscure bug fix, required changed to ibmtr.c not ibmtr_cs.c - - v2.2.7 May 1999 Mike Phillips (phillim@amtrak.com) - Updated to version 2.2.7 to match the first version of the kernel - that the modification to ibmtr.c were incorporated into. - - v2.2.17 July 2000 Burt Silverman (burts@us.ibm.com) - Address translation feature of PCMCIA controller is usable so - memory windows can be placed in High memory (meaning above - 0xFFFFF.) - -======================================================================*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/ptrace.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/timer.h> -#include <linux/module.h> -#include <linux/netdevice.h> -#include <linux/trdevice.h> -#include <linux/ibmtr.h> - -#include <pcmcia/cistpl.h> -#include <pcmcia/ds.h> - -#include <asm/uaccess.h> -#include <asm/io.h> - -#define PCMCIA -#include "ibmtr.c" - - -/*====================================================================*/ - -/* Parameters that can be set with 'insmod' */ - -/* MMIO base address */ -static u_long mmiobase = 0xce000; - -/* SRAM base address */ -static u_long srambase = 0xd0000; - -/* SRAM size 8,16,32,64 */ -static u_long sramsize = 64; - -/* Ringspeed 4,16 */ -static int ringspeed = 16; - -module_param(mmiobase, ulong, 0); -module_param(srambase, ulong, 0); -module_param(sramsize, ulong, 0); -module_param(ringspeed, int, 0); -MODULE_LICENSE("GPL"); - -/*====================================================================*/ - -static int ibmtr_config(struct pcmcia_device *link); -static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase); -static void ibmtr_release(struct pcmcia_device *link); -static void ibmtr_detach(struct pcmcia_device *p_dev); - -/*====================================================================*/ - -typedef struct ibmtr_dev_t { - struct pcmcia_device *p_dev; - struct net_device *dev; - struct tok_info *ti; -} ibmtr_dev_t; - -static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) { - ibmtr_dev_t *info = dev_id; - struct net_device *dev = info->dev; - return tok_interrupt(irq, dev); -}; - -static int __devinit ibmtr_attach(struct pcmcia_device *link) -{ - ibmtr_dev_t *info; - struct net_device *dev; - - dev_dbg(&link->dev, "ibmtr_attach()\n"); - - /* Create new token-ring device */ - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) return -ENOMEM; - dev = alloc_trdev(sizeof(struct tok_info)); - if (!dev) { - kfree(info); - return -ENOMEM; - } - - info->p_dev = link; - link->priv = info; - info->ti = netdev_priv(dev); - - link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; - link->resource[0]->end = 4; - link->config_flags |= CONF_ENABLE_IRQ; - link->config_regs = PRESENT_OPTION; - - info->dev = dev; - - return ibmtr_config(link); -} /* ibmtr_attach */ - -static void ibmtr_detach(struct pcmcia_device *link) -{ - struct ibmtr_dev_t *info = link->priv; - struct net_device *dev = info->dev; - struct tok_info *ti = netdev_priv(dev); - - dev_dbg(&link->dev, "ibmtr_detach\n"); - - /* - * When the card removal interrupt hits tok_interrupt(), - * bail out early, so we don't crash the machine - */ - ti->sram_phys |= 1; - - unregister_netdev(dev); - - del_timer_sync(&(ti->tr_timer)); - - ibmtr_release(link); - - free_netdev(dev); - kfree(info); -} /* ibmtr_detach */ - -static int __devinit ibmtr_config(struct pcmcia_device *link) -{ - ibmtr_dev_t *info = link->priv; - struct net_device *dev = info->dev; - struct tok_info *ti = netdev_priv(dev); - int i, ret; - - dev_dbg(&link->dev, "ibmtr_config\n"); - - link->io_lines = 16; - link->config_index = 0x61; - - /* Determine if this is PRIMARY or ALTERNATE. */ - - /* Try PRIMARY card at 0xA20-0xA23 */ - link->resource[0]->start = 0xA20; - i = pcmcia_request_io(link); - if (i != 0) { - /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */ - link->resource[0]->start = 0xA24; - ret = pcmcia_request_io(link); - if (ret) - goto failed; - } - dev->base_addr = link->resource[0]->start; - - ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt); - if (ret) - goto failed; - dev->irq = link->irq; - ti->irq = link->irq; - ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq); - - /* Allocate the MMIO memory window */ - link->resource[2]->flags |= WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE; - link->resource[2]->flags |= WIN_USE_WAIT; - link->resource[2]->start = 0; - link->resource[2]->end = 0x2000; - ret = pcmcia_request_window(link, link->resource[2], 250); - if (ret) - goto failed; - - ret = pcmcia_map_mem_page(link, link->resource[2], mmiobase); - if (ret) - goto failed; - ti->mmio = ioremap(link->resource[2]->start, - resource_size(link->resource[2])); - - /* Allocate the SRAM memory window */ - 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 = sramsize * 1024; - ret = pcmcia_request_window(link, link->resource[3], 250); - if (ret) - goto failed; - - ret = pcmcia_map_mem_page(link, link->resource[3], srambase); - if (ret) - goto failed; - - ti->sram_base = srambase >> 12; - ti->sram_virt = ioremap(link->resource[3]->start, - resource_size(link->resource[3])); - ti->sram_phys = link->resource[3]->start; - - ret = pcmcia_enable_device(link); - if (ret) - goto failed; - - /* Set up the Token-Ring Controller Configuration Register and - turn on the card. Check the "Local Area Network Credit Card - Adapters Technical Reference" SC30-3585 for this info. */ - ibmtr_hw_setup(dev, mmiobase); - - SET_NETDEV_DEV(dev, &link->dev); - - i = ibmtr_probe_card(dev); - if (i != 0) { - pr_notice("register_netdev() failed\n"); - goto failed; - } - - netdev_info(dev, "port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n", - dev->base_addr, dev->irq, - (u_long)ti->mmio, (u_long)(ti->sram_base << 12), - dev->dev_addr); - return 0; - -failed: - ibmtr_release(link); - return -ENODEV; -} /* ibmtr_config */ - -static void ibmtr_release(struct pcmcia_device *link) -{ - ibmtr_dev_t *info = link->priv; - struct net_device *dev = info->dev; - - dev_dbg(&link->dev, "ibmtr_release\n"); - - if (link->resource[2]->end) { - struct tok_info *ti = netdev_priv(dev); - iounmap(ti->mmio); - } - pcmcia_disable_device(link); -} - -static int ibmtr_suspend(struct pcmcia_device *link) -{ - ibmtr_dev_t *info = link->priv; - struct net_device *dev = info->dev; - - if (link->open) - netif_device_detach(dev); - - return 0; -} - -static int __devinit ibmtr_resume(struct pcmcia_device *link) -{ - ibmtr_dev_t *info = link->priv; - struct net_device *dev = info->dev; - - if (link->open) { - ibmtr_probe(dev); /* really? */ - netif_device_attach(dev); - } - - return 0; -} - - -/*====================================================================*/ - -static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase) -{ - int i; - - /* Bizarre IBM behavior, there are 16 bits of information we - need to set, but the card only allows us to send 4 bits at a - time. For each byte sent to base_addr, bits 7-4 tell the - card which part of the 16 bits we are setting, bits 3-0 contain - the actual information */ - - /* First nibble provides 4 bits of mmio */ - i = (mmiobase >> 16) & 0x0F; - outb(i, dev->base_addr); - - /* Second nibble provides 3 bits of mmio */ - i = 0x10 | ((mmiobase >> 12) & 0x0E); - outb(i, dev->base_addr); - - /* Third nibble, hard-coded values */ - i = 0x26; - outb(i, dev->base_addr); - - /* Fourth nibble sets shared ram page size */ - - /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */ - i = (sramsize >> 4) & 0x07; - i = ((i == 4) ? 3 : i) << 2; - i |= 0x30; - - if (ringspeed == 16) - i |= 2; - if (dev->base_addr == 0xA24) - i |= 1; - outb(i, dev->base_addr); - - /* 0x40 will release the card for use */ - outb(0x40, dev->base_addr); -} - -static const struct pcmcia_device_id ibmtr_ids[] = { - PCMCIA_DEVICE_PROD_ID12("3Com", "TokenLink Velocity PC Card", 0x41240e5b, 0x82c3734e), - PCMCIA_DEVICE_PROD_ID12("IBM", "TOKEN RING", 0xb569a6e5, 0xbf8eed47), - PCMCIA_DEVICE_NULL, -}; -MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids); - -static struct pcmcia_driver ibmtr_cs_driver = { - .owner = THIS_MODULE, - .name = "ibmtr_cs", - .probe = ibmtr_attach, - .remove = ibmtr_detach, - .id_table = ibmtr_ids, - .suspend = ibmtr_suspend, - .resume = ibmtr_resume, -}; - -static int __init init_ibmtr_cs(void) -{ - return pcmcia_register_driver(&ibmtr_cs_driver); -} - -static void __exit exit_ibmtr_cs(void) -{ - pcmcia_unregister_driver(&ibmtr_cs_driver); -} - -module_init(init_ibmtr_cs); -module_exit(exit_ibmtr_cs);
diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c deleted file mode 100644 index 97e4c65..0000000 --- a/drivers/net/tokenring/lanstreamer.c +++ /dev/null
@@ -1,1909 +0,0 @@ -/* - * lanstreamer.c -- driver for the IBM Auto LANStreamer PCI Adapter - * - * Written By: Mike Sullivan, IBM Corporation - * - * Copyright (C) 1999 IBM Corporation - * - * Linux driver for IBM PCI tokenring cards based on the LanStreamer MPC - * chipset. - * - * This driver is based on the olympic driver for IBM PCI TokenRing cards (Pit/Pit-Phy/Olympic - * chipsets) written by: - * 1999 Peter De Schrijver All Rights Reserved - * 1999 Mike Phillips (phillim@amtrak.com) - * - * Base Driver Skeleton: - * Written 1993-94 by Donald Becker. - * - * Copyright 1993 United States Government as represented by the - * Director, National Security Agency. - * - * 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. - * - * NO WARRANTY - * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT - * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is - * solely responsible for determining the appropriateness of using and - * distributing the Program and assumes all risks associated with its - * exercise of rights under this Agreement, including but not limited to - * the risks and costs of program errors, damage to or loss of data, - * programs or equipment, and unavailability or interruption of operations. - * - * DISCLAIMER OF LIABILITY - * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED - * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES - * - * 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 - * - * - * 12/10/99 - Alpha Release 0.1.0 - * First release to the public - * 03/03/00 - Merged to kernel, indented -kr -i8 -bri0, fixed some missing - * malloc free checks, reviewed code. <alan@redhat.com> - * 03/13/00 - Added spinlocks for smp - * 03/08/01 - Added support for module_init() and module_exit() - * 08/15/01 - Added ioctl() functionality for debugging, changed netif_*_queue - * calls and other incorrectness - Kent Yoder <yoder1@us.ibm.com> - * 11/05/01 - Restructured the interrupt function, added delays, reduced the - * the number of TX descriptors to 1, which together can prevent - * the card from locking up the box - <yoder1@us.ibm.com> - * 09/27/02 - New PCI interface + bug fix. - <yoder1@us.ibm.com> - * 11/13/02 - Removed free_irq calls which could cause a hang, added - * netif_carrier_{on|off} - <yoder1@us.ibm.com> - * - * To Do: - * - * - * If Problems do Occur - * Most problems can be rectified by either closing and opening the interface - * (ifconfig down and up) or rmmod and insmod'ing the driver (a bit difficult - * if compiled into the kernel). - */ - -/* Change STREAMER_DEBUG to 1 to get verbose, and I mean really verbose, messages */ - -#define STREAMER_DEBUG 0 -#define STREAMER_DEBUG_PACKETS 0 - -/* Change STREAMER_NETWORK_MONITOR to receive mac frames through the arb channel. - * Will also create a /proc/net/streamer_tr entry if proc_fs is compiled into the - * kernel. - * Intended to be used to create a ring-error reporting network module - * i.e. it will give you the source address of beaconers on the ring - */ - -#define STREAMER_NETWORK_MONITOR 0 - -/* #define CONFIG_PROC_FS */ - -/* - * Allow or disallow ioctl's for debugging - */ - -#define STREAMER_IOCTL 0 - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/timer.h> -#include <linux/in.h> -#include <linux/ioport.h> -#include <linux/string.h> -#include <linux/proc_fs.h> -#include <linux/ptrace.h> -#include <linux/skbuff.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/trdevice.h> -#include <linux/stddef.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/dma-mapping.h> -#include <linux/spinlock.h> -#include <linux/bitops.h> -#include <linux/jiffies.h> -#include <linux/slab.h> - -#include <net/net_namespace.h> -#include <net/checksum.h> - -#include <asm/io.h> - -#include "lanstreamer.h" - -#if (BITS_PER_LONG == 64) -#error broken on 64-bit: stores pointer to rx_ring->buffer in 32-bit int -#endif - - -/* I've got to put some intelligence into the version number so that Peter and I know - * which version of the code somebody has got. - * Version Number = a.b.c.d where a.b.c is the level of code and d is the latest author. - * So 0.0.1.pds = Peter, 0.0.1.mlp = Mike - * - * Official releases will only have an a.b.c version number format. - */ - -static char version[] = "LanStreamer.c v0.4.0 03/08/01 - Mike Sullivan\n" - " v0.5.3 11/13/02 - Kent Yoder"; - -static DEFINE_PCI_DEVICE_TABLE(streamer_pci_tbl) = { - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR, PCI_ANY_ID, PCI_ANY_ID,}, - {} /* terminating entry */ -}; -MODULE_DEVICE_TABLE(pci,streamer_pci_tbl); - - -static char *open_maj_error[] = { - "No error", "Lobe Media Test", "Physical Insertion", - "Address Verification", "Neighbor Notification (Ring Poll)", - "Request Parameters", "FDX Registration Request", - "FDX Lobe Media Test", "FDX Duplicate Address Check", - "Unknown stage" -}; - -static char *open_min_error[] = { - "No error", "Function Failure", "Signal Lost", "Wire Fault", - "Ring Speed Mismatch", "Timeout", "Ring Failure", "Ring Beaconing", - "Duplicate Node Address", "Request Parameters", "Remove Received", - "Reserved", "Reserved", "No Monitor Detected for RPL", - "Monitor Contention failer for RPL", "FDX Protocol Error" -}; - -/* Module parameters */ - -/* Ring Speed 0,4,16 - * 0 = Autosense - * 4,16 = Selected speed only, no autosense - * This allows the card to be the first on the ring - * and become the active monitor. - * - * WARNING: Some hubs will allow you to insert - * at the wrong speed - */ - -static int ringspeed[STREAMER_MAX_ADAPTERS] = { 0, }; - -module_param_array(ringspeed, int, NULL, 0); - -/* Packet buffer size */ - -static int pkt_buf_sz[STREAMER_MAX_ADAPTERS] = { 0, }; - -module_param_array(pkt_buf_sz, int, NULL, 0); - -/* Message Level */ - -static int message_level[STREAMER_MAX_ADAPTERS] = { 1, }; - -module_param_array(message_level, int, NULL, 0); - -#if STREAMER_IOCTL -static int streamer_ioctl(struct net_device *, struct ifreq *, int); -#endif - -static int streamer_reset(struct net_device *dev); -static int streamer_open(struct net_device *dev); -static netdev_tx_t streamer_xmit(struct sk_buff *skb, - struct net_device *dev); -static int streamer_close(struct net_device *dev); -static void streamer_set_rx_mode(struct net_device *dev); -static irqreturn_t streamer_interrupt(int irq, void *dev_id); -static int streamer_set_mac_address(struct net_device *dev, void *addr); -static void streamer_arb_cmd(struct net_device *dev); -static int streamer_change_mtu(struct net_device *dev, int mtu); -static void streamer_srb_bh(struct net_device *dev); -static void streamer_asb_bh(struct net_device *dev); -#if STREAMER_NETWORK_MONITOR -#ifdef CONFIG_PROC_FS -static int streamer_proc_info(char *buffer, char **start, off_t offset, - int length, int *eof, void *data); -static int sprintf_info(char *buffer, struct net_device *dev); -struct streamer_private *dev_streamer=NULL; -#endif -#endif - -static const struct net_device_ops streamer_netdev_ops = { - .ndo_open = streamer_open, - .ndo_stop = streamer_close, - .ndo_start_xmit = streamer_xmit, - .ndo_change_mtu = streamer_change_mtu, -#if STREAMER_IOCTL - .ndo_do_ioctl = streamer_ioctl, -#endif - .ndo_set_rx_mode = streamer_set_rx_mode, - .ndo_set_mac_address = streamer_set_mac_address, -}; - -static int __devinit streamer_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct net_device *dev; - struct streamer_private *streamer_priv; - unsigned long pio_start, pio_end, pio_flags, pio_len; - unsigned long mmio_start, mmio_end, mmio_flags, mmio_len; - int rc = 0; - static int card_no=-1; - u16 pcr; - -#if STREAMER_DEBUG - printk("lanstreamer::streamer_init_one, entry pdev %p\n",pdev); -#endif - - card_no++; - dev = alloc_trdev(sizeof(*streamer_priv)); - if (dev==NULL) { - printk(KERN_ERR "lanstreamer: out of memory.\n"); - return -ENOMEM; - } - - streamer_priv = netdev_priv(dev); - -#if STREAMER_NETWORK_MONITOR -#ifdef CONFIG_PROC_FS - if (!dev_streamer) - create_proc_read_entry("streamer_tr", 0, init_net.proc_net, - streamer_proc_info, NULL); - streamer_priv->next = dev_streamer; - dev_streamer = streamer_priv; -#endif -#endif - - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (rc) { - printk(KERN_ERR "%s: No suitable PCI mapping available.\n", - dev->name); - rc = -ENODEV; - goto err_out; - } - - rc = pci_enable_device(pdev); - if (rc) { - printk(KERN_ERR "lanstreamer: unable to enable pci device\n"); - rc=-EIO; - goto err_out; - } - - pci_set_master(pdev); - - rc = pci_set_mwi(pdev); - if (rc) { - printk(KERN_ERR "lanstreamer: unable to enable MWI on pci device\n"); - goto err_out_disable; - } - - pio_start = pci_resource_start(pdev, 0); - pio_end = pci_resource_end(pdev, 0); - pio_flags = pci_resource_flags(pdev, 0); - pio_len = pci_resource_len(pdev, 0); - - mmio_start = pci_resource_start(pdev, 1); - mmio_end = pci_resource_end(pdev, 1); - mmio_flags = pci_resource_flags(pdev, 1); - mmio_len = pci_resource_len(pdev, 1); - -#if STREAMER_DEBUG - printk("lanstreamer: pio_start %x pio_end %x pio_len %x pio_flags %x\n", - pio_start, pio_end, pio_len, pio_flags); - printk("lanstreamer: mmio_start %x mmio_end %x mmio_len %x mmio_flags %x\n", - mmio_start, mmio_end, mmio_flags, mmio_len); -#endif - - if (!request_region(pio_start, pio_len, "lanstreamer")) { - printk(KERN_ERR "lanstreamer: unable to get pci io addr %lx\n", - pio_start); - rc= -EBUSY; - goto err_out_mwi; - } - - if (!request_mem_region(mmio_start, mmio_len, "lanstreamer")) { - printk(KERN_ERR "lanstreamer: unable to get pci mmio addr %lx\n", - mmio_start); - rc= -EBUSY; - goto err_out_free_pio; - } - - streamer_priv->streamer_mmio=ioremap(mmio_start, mmio_len); - if (streamer_priv->streamer_mmio == NULL) { - printk(KERN_ERR "lanstreamer: unable to remap MMIO %lx\n", - mmio_start); - rc= -EIO; - goto err_out_free_mmio; - } - - init_waitqueue_head(&streamer_priv->srb_wait); - init_waitqueue_head(&streamer_priv->trb_wait); - - dev->netdev_ops = &streamer_netdev_ops; - dev->irq = pdev->irq; - dev->base_addr=pio_start; - SET_NETDEV_DEV(dev, &pdev->dev); - - streamer_priv->streamer_card_name = (char *)pdev->resource[0].name; - streamer_priv->pci_dev = pdev; - - if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000)) - streamer_priv->pkt_buf_sz = PKT_BUF_SZ; - else - streamer_priv->pkt_buf_sz = pkt_buf_sz[card_no]; - - streamer_priv->streamer_ring_speed = ringspeed[card_no]; - streamer_priv->streamer_message_level = message_level[card_no]; - - pci_set_drvdata(pdev, dev); - - spin_lock_init(&streamer_priv->streamer_lock); - - pci_read_config_word (pdev, PCI_COMMAND, &pcr); - pcr |= PCI_COMMAND_SERR; - pci_write_config_word (pdev, PCI_COMMAND, pcr); - - printk("%s\n", version); - printk("%s: %s. I/O at %hx, MMIO at %p, using irq %d\n",dev->name, - streamer_priv->streamer_card_name, - (unsigned int) dev->base_addr, - streamer_priv->streamer_mmio, - dev->irq); - - if (streamer_reset(dev)) - goto err_out_unmap; - - rc = register_netdev(dev); - if (rc) - goto err_out_unmap; - return 0; - -err_out_unmap: - iounmap(streamer_priv->streamer_mmio); -err_out_free_mmio: - release_mem_region(mmio_start, mmio_len); -err_out_free_pio: - release_region(pio_start, pio_len); -err_out_mwi: - pci_clear_mwi(pdev); -err_out_disable: - pci_disable_device(pdev); -err_out: - free_netdev(dev); -#if STREAMER_DEBUG - printk("lanstreamer: Exit error %x\n",rc); -#endif - return rc; -} - -static void __devexit streamer_remove_one(struct pci_dev *pdev) -{ - struct net_device *dev=pci_get_drvdata(pdev); - struct streamer_private *streamer_priv; - -#if STREAMER_DEBUG - printk("lanstreamer::streamer_remove_one entry pdev %p\n",pdev); -#endif - - if (dev == NULL) { - printk(KERN_ERR "lanstreamer::streamer_remove_one, ERROR dev is NULL\n"); - return; - } - - streamer_priv=netdev_priv(dev); - if (streamer_priv == NULL) { - printk(KERN_ERR "lanstreamer::streamer_remove_one, ERROR dev->priv is NULL\n"); - return; - } - -#if STREAMER_NETWORK_MONITOR -#ifdef CONFIG_PROC_FS - { - struct streamer_private **p, **next; - - for (p = &dev_streamer; *p; p = next) { - next = &(*p)->next; - if (*p == streamer_priv) { - *p = *next; - break; - } - } - if (!dev_streamer) - remove_proc_entry("streamer_tr", init_net.proc_net); - } -#endif -#endif - - unregister_netdev(dev); - iounmap(streamer_priv->streamer_mmio); - release_mem_region(pci_resource_start(pdev, 1), pci_resource_len(pdev,1)); - release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev,0)); - pci_clear_mwi(pdev); - pci_disable_device(pdev); - free_netdev(dev); - pci_set_drvdata(pdev, NULL); -} - - -static int streamer_reset(struct net_device *dev) -{ - struct streamer_private *streamer_priv; - __u8 __iomem *streamer_mmio; - unsigned long t; - unsigned int uaa_addr; - struct sk_buff *skb = NULL; - __u16 misr; - - streamer_priv = netdev_priv(dev); - streamer_mmio = streamer_priv->streamer_mmio; - - writew(readw(streamer_mmio + BCTL) | BCTL_SOFTRESET, streamer_mmio + BCTL); - t = jiffies; - /* Hold soft reset bit for a while */ - ssleep(1); - - writew(readw(streamer_mmio + BCTL) & ~BCTL_SOFTRESET, - streamer_mmio + BCTL); - -#if STREAMER_DEBUG - printk("BCTL: %x\n", readw(streamer_mmio + BCTL)); - printk("GPR: %x\n", readw(streamer_mmio + GPR)); - printk("SISRMASK: %x\n", readw(streamer_mmio + SISR_MASK)); -#endif - writew(readw(streamer_mmio + BCTL) | (BCTL_RX_FIFO_8 | BCTL_TX_FIFO_8), streamer_mmio + BCTL ); - - if (streamer_priv->streamer_ring_speed == 0) { /* Autosense */ - writew(readw(streamer_mmio + GPR) | GPR_AUTOSENSE, - streamer_mmio + GPR); - if (streamer_priv->streamer_message_level) - printk(KERN_INFO "%s: Ringspeed autosense mode on\n", - dev->name); - } else if (streamer_priv->streamer_ring_speed == 16) { - if (streamer_priv->streamer_message_level) - printk(KERN_INFO "%s: Trying to open at 16 Mbps as requested\n", - dev->name); - writew(GPR_16MBPS, streamer_mmio + GPR); - } else if (streamer_priv->streamer_ring_speed == 4) { - if (streamer_priv->streamer_message_level) - printk(KERN_INFO "%s: Trying to open at 4 Mbps as requested\n", - dev->name); - writew(0, streamer_mmio + GPR); - } - - skb = dev_alloc_skb(streamer_priv->pkt_buf_sz); - if (!skb) { - printk(KERN_INFO "%s: skb allocation for diagnostics failed...proceeding\n", - dev->name); - } else { - struct streamer_rx_desc *rx_ring; - u8 *data; - - rx_ring=(struct streamer_rx_desc *)skb->data; - data=((u8 *)skb->data)+sizeof(struct streamer_rx_desc); - rx_ring->forward=0; - rx_ring->status=0; - rx_ring->buffer=cpu_to_le32(pci_map_single(streamer_priv->pci_dev, data, - 512, PCI_DMA_FROMDEVICE)); - rx_ring->framelen_buflen=512; - writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, rx_ring, 512, PCI_DMA_FROMDEVICE)), - streamer_mmio+RXBDA); - } - -#if STREAMER_DEBUG - printk("GPR = %x\n", readw(streamer_mmio + GPR)); -#endif - /* start solo init */ - writew(SISR_MI, streamer_mmio + SISR_MASK_SUM); - - while (!((readw(streamer_mmio + SISR)) & SISR_SRB_REPLY)) { - msleep_interruptible(100); - if (time_after(jiffies, t + 40 * HZ)) { - printk(KERN_ERR - "IBM PCI tokenring card not responding\n"); - release_region(dev->base_addr, STREAMER_IO_SPACE); - if (skb) - dev_kfree_skb(skb); - return -1; - } - } - writew(~SISR_SRB_REPLY, streamer_mmio + SISR_RUM); - misr = readw(streamer_mmio + MISR_RUM); - writew(~misr, streamer_mmio + MISR_RUM); - - if (skb) - dev_kfree_skb(skb); /* release skb used for diagnostics */ - -#if STREAMER_DEBUG - printk("LAPWWO: %x, LAPA: %x LAPE: %x\n", - readw(streamer_mmio + LAPWWO), readw(streamer_mmio + LAPA), - readw(streamer_mmio + LAPE)); -#endif - -#if STREAMER_DEBUG - { - int i; - writew(readw(streamer_mmio + LAPWWO), - streamer_mmio + LAPA); - printk("initialization response srb dump: "); - for (i = 0; i < 10; i++) - printk("%x:", - ntohs(readw(streamer_mmio + LAPDINC))); - printk("\n"); - } -#endif - - writew(readw(streamer_mmio + LAPWWO) + 6, streamer_mmio + LAPA); - if (readw(streamer_mmio + LAPD)) { - printk(KERN_INFO "tokenring card initialization failed. errorcode : %x\n", - ntohs(readw(streamer_mmio + LAPD))); - release_region(dev->base_addr, STREAMER_IO_SPACE); - return -1; - } - - writew(readw(streamer_mmio + LAPWWO) + 8, streamer_mmio + LAPA); - uaa_addr = ntohs(readw(streamer_mmio + LAPDINC)); - readw(streamer_mmio + LAPDINC); /* skip over Level.Addr field */ - streamer_priv->streamer_addr_table_addr = ntohs(readw(streamer_mmio + LAPDINC)); - streamer_priv->streamer_parms_addr = ntohs(readw(streamer_mmio + LAPDINC)); - -#if STREAMER_DEBUG - printk("UAA resides at %x\n", uaa_addr); -#endif - - /* setup uaa area for access with LAPD */ - { - int i; - __u16 addr; - writew(uaa_addr, streamer_mmio + LAPA); - for (i = 0; i < 6; i += 2) { - addr=ntohs(readw(streamer_mmio+LAPDINC)); - dev->dev_addr[i]= (addr >> 8) & 0xff; - dev->dev_addr[i+1]= addr & 0xff; - } -#if STREAMER_DEBUG - printk("Adapter address: %pM\n", dev->dev_addr); -#endif - } - return 0; -} - -static int streamer_open(struct net_device *dev) -{ - struct streamer_private *streamer_priv = netdev_priv(dev); - __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; - unsigned long flags; - char open_error[255]; - int i, open_finished = 1; - __u16 srb_word; - __u16 srb_open; - int rc; - - if (readw(streamer_mmio+BMCTL_SUM) & BMCTL_RX_ENABLED) { - rc=streamer_reset(dev); - } - - if (request_irq(dev->irq, streamer_interrupt, IRQF_SHARED, "lanstreamer", dev)) { - return -EAGAIN; - } -#if STREAMER_DEBUG - printk("BMCTL: %x\n", readw(streamer_mmio + BMCTL_SUM)); - printk("pending ints: %x\n", readw(streamer_mmio + SISR)); -#endif - - writew(SISR_MI | SISR_SRB_REPLY, streamer_mmio + SISR_MASK); /* more ints later, doesn't stop arb cmd interrupt */ - writew(LISR_LIE, streamer_mmio + LISR); /* more ints later */ - - /* adapter is closed, so SRB is pointed to by LAPWWO */ - writew(readw(streamer_mmio + LAPWWO), streamer_mmio + LAPA); - -#if STREAMER_DEBUG - printk("LAPWWO: %x, LAPA: %x\n", readw(streamer_mmio + LAPWWO), - readw(streamer_mmio + LAPA)); - printk("LAPE: %x\n", readw(streamer_mmio + LAPE)); - printk("SISR Mask = %04x\n", readw(streamer_mmio + SISR_MASK)); -#endif - do { - for (i = 0; i < SRB_COMMAND_SIZE; i += 2) { - writew(0, streamer_mmio + LAPDINC); - } - - writew(readw(streamer_mmio+LAPWWO),streamer_mmio+LAPA); - writew(htons(SRB_OPEN_ADAPTER<<8),streamer_mmio+LAPDINC) ; /* open */ - writew(htons(STREAMER_CLEAR_RET_CODE<<8),streamer_mmio+LAPDINC); - writew(STREAMER_CLEAR_RET_CODE, streamer_mmio + LAPDINC); - - writew(readw(streamer_mmio + LAPWWO) + 8, streamer_mmio + LAPA); -#if STREAMER_NETWORK_MONITOR - /* If Network Monitor, instruct card to copy MAC frames through the ARB */ - writew(htons(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON), streamer_mmio + LAPDINC); /* offset 8 word contains open options */ -#else - writew(htons(OPEN_ADAPTER_ENABLE_FDX), streamer_mmio + LAPDINC); /* Offset 8 word contains Open.Options */ -#endif - - if (streamer_priv->streamer_laa[0]) { - writew(readw(streamer_mmio + LAPWWO) + 12, streamer_mmio + LAPA); - writew(htons((streamer_priv->streamer_laa[0] << 8) | - streamer_priv->streamer_laa[1]),streamer_mmio+LAPDINC); - writew(htons((streamer_priv->streamer_laa[2] << 8) | - streamer_priv->streamer_laa[3]),streamer_mmio+LAPDINC); - writew(htons((streamer_priv->streamer_laa[4] << 8) | - streamer_priv->streamer_laa[5]),streamer_mmio+LAPDINC); - memcpy(dev->dev_addr, streamer_priv->streamer_laa, dev->addr_len); - } - - /* save off srb open offset */ - srb_open = readw(streamer_mmio + LAPWWO); -#if STREAMER_DEBUG - writew(readw(streamer_mmio + LAPWWO), - streamer_mmio + LAPA); - printk("srb open request:\n"); - for (i = 0; i < 16; i++) { - printk("%x:", ntohs(readw(streamer_mmio + LAPDINC))); - } - printk("\n"); -#endif - spin_lock_irqsave(&streamer_priv->streamer_lock, flags); - streamer_priv->srb_queued = 1; - - /* signal solo that SRB command has been issued */ - writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM); - spin_unlock_irqrestore(&streamer_priv->streamer_lock, flags); - - while (streamer_priv->srb_queued) { - interruptible_sleep_on_timeout(&streamer_priv->srb_wait, 5 * HZ); - if (signal_pending(current)) { - printk(KERN_WARNING "%s: SRB timed out.\n", dev->name); - printk(KERN_WARNING "SISR=%x MISR=%x, LISR=%x\n", - readw(streamer_mmio + SISR), - readw(streamer_mmio + MISR_RUM), - readw(streamer_mmio + LISR)); - streamer_priv->srb_queued = 0; - break; - } - } - -#if STREAMER_DEBUG - printk("SISR_MASK: %x\n", readw(streamer_mmio + SISR_MASK)); - printk("srb open response:\n"); - writew(srb_open, streamer_mmio + LAPA); - for (i = 0; i < 10; i++) { - printk("%x:", - ntohs(readw(streamer_mmio + LAPDINC))); - } -#endif - - /* If we get the same return response as we set, the interrupt wasn't raised and the open - * timed out. - */ - writew(srb_open + 2, streamer_mmio + LAPA); - srb_word = ntohs(readw(streamer_mmio + LAPD)) >> 8; - if (srb_word == STREAMER_CLEAR_RET_CODE) { - printk(KERN_WARNING "%s: Adapter Open time out or error.\n", - dev->name); - return -EIO; - } - - if (srb_word != 0) { - if (srb_word == 0x07) { - if (!streamer_priv->streamer_ring_speed && open_finished) { /* Autosense , first time around */ - printk(KERN_WARNING "%s: Retrying at different ring speed\n", - dev->name); - open_finished = 0; - } else { - __u16 error_code; - - writew(srb_open + 6, streamer_mmio + LAPA); - error_code = ntohs(readw(streamer_mmio + LAPD)); - strcpy(open_error, open_maj_error[(error_code & 0xf0) >> 4]); - strcat(open_error, " - "); - strcat(open_error, open_min_error[(error_code & 0x0f)]); - - if (!streamer_priv->streamer_ring_speed && - ((error_code & 0x0f) == 0x0d)) - { - printk(KERN_WARNING "%s: Tried to autosense ring speed with no monitors present\n", dev->name); - printk(KERN_WARNING "%s: Please try again with a specified ring speed\n", dev->name); - free_irq(dev->irq, dev); - return -EIO; - } - - printk(KERN_WARNING "%s: %s\n", - dev->name, open_error); - free_irq(dev->irq, dev); - return -EIO; - - } /* if autosense && open_finished */ - } else { - printk(KERN_WARNING "%s: Bad OPEN response: %x\n", - dev->name, srb_word); - free_irq(dev->irq, dev); - return -EIO; - } - } else - open_finished = 1; - } while (!(open_finished)); /* Will only loop if ring speed mismatch re-open attempted && autosense is on */ - - writew(srb_open + 18, streamer_mmio + LAPA); - srb_word=ntohs(readw(streamer_mmio+LAPD)) >> 8; - if (srb_word & (1 << 3)) - if (streamer_priv->streamer_message_level) - printk(KERN_INFO "%s: Opened in FDX Mode\n", dev->name); - - if (srb_word & 1) - streamer_priv->streamer_ring_speed = 16; - else - streamer_priv->streamer_ring_speed = 4; - - if (streamer_priv->streamer_message_level) - printk(KERN_INFO "%s: Opened in %d Mbps mode\n", - dev->name, - streamer_priv->streamer_ring_speed); - - writew(srb_open + 8, streamer_mmio + LAPA); - streamer_priv->asb = ntohs(readw(streamer_mmio + LAPDINC)); - streamer_priv->srb = ntohs(readw(streamer_mmio + LAPDINC)); - streamer_priv->arb = ntohs(readw(streamer_mmio + LAPDINC)); - readw(streamer_mmio + LAPDINC); /* offset 14 word is rsvd */ - streamer_priv->trb = ntohs(readw(streamer_mmio + LAPDINC)); - - streamer_priv->streamer_receive_options = 0x00; - streamer_priv->streamer_copy_all_options = 0; - - /* setup rx ring */ - /* enable rx channel */ - writew(~BMCTL_RX_DIS, streamer_mmio + BMCTL_RUM); - - /* setup rx descriptors */ - streamer_priv->streamer_rx_ring= - kmalloc( sizeof(struct streamer_rx_desc)* - STREAMER_RX_RING_SIZE,GFP_KERNEL); - if (!streamer_priv->streamer_rx_ring) { - printk(KERN_WARNING "%s ALLOC of streamer rx ring FAILED!!\n",dev->name); - return -EIO; - } - - for (i = 0; i < STREAMER_RX_RING_SIZE; i++) { - struct sk_buff *skb; - - skb = dev_alloc_skb(streamer_priv->pkt_buf_sz); - if (skb == NULL) - break; - - skb->dev = dev; - - streamer_priv->streamer_rx_ring[i].forward = - cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[i + 1], - sizeof(struct streamer_rx_desc), PCI_DMA_FROMDEVICE)); - streamer_priv->streamer_rx_ring[i].status = 0; - streamer_priv->streamer_rx_ring[i].buffer = - cpu_to_le32(pci_map_single(streamer_priv->pci_dev, skb->data, - streamer_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)); - streamer_priv->streamer_rx_ring[i].framelen_buflen = streamer_priv->pkt_buf_sz; - streamer_priv->rx_ring_skb[i] = skb; - } - streamer_priv->streamer_rx_ring[STREAMER_RX_RING_SIZE - 1].forward = - cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[0], - sizeof(struct streamer_rx_desc), PCI_DMA_FROMDEVICE)); - - if (i == 0) { - printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n", dev->name); - free_irq(dev->irq, dev); - return -EIO; - } - - streamer_priv->rx_ring_last_received = STREAMER_RX_RING_SIZE - 1; /* last processed rx status */ - - writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[0], - sizeof(struct streamer_rx_desc), PCI_DMA_TODEVICE)), - streamer_mmio + RXBDA); - writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[STREAMER_RX_RING_SIZE - 1], - sizeof(struct streamer_rx_desc), PCI_DMA_TODEVICE)), - streamer_mmio + RXLBDA); - - /* set bus master interrupt event mask */ - writew(MISR_RX_NOBUF | MISR_RX_EOF, streamer_mmio + MISR_MASK); - - - /* setup tx ring */ - streamer_priv->streamer_tx_ring=kmalloc(sizeof(struct streamer_tx_desc)* - STREAMER_TX_RING_SIZE,GFP_KERNEL); - if (!streamer_priv->streamer_tx_ring) { - printk(KERN_WARNING "%s ALLOC of streamer_tx_ring FAILED\n",dev->name); - return -EIO; - } - - writew(~BMCTL_TX2_DIS, streamer_mmio + BMCTL_RUM); /* Enables TX channel 2 */ - for (i = 0; i < STREAMER_TX_RING_SIZE; i++) { - streamer_priv->streamer_tx_ring[i].forward = cpu_to_le32(pci_map_single(streamer_priv->pci_dev, - &streamer_priv->streamer_tx_ring[i + 1], - sizeof(struct streamer_tx_desc), - PCI_DMA_TODEVICE)); - streamer_priv->streamer_tx_ring[i].status = 0; - streamer_priv->streamer_tx_ring[i].bufcnt_framelen = 0; - streamer_priv->streamer_tx_ring[i].buffer = 0; - streamer_priv->streamer_tx_ring[i].buflen = 0; - streamer_priv->streamer_tx_ring[i].rsvd1 = 0; - streamer_priv->streamer_tx_ring[i].rsvd2 = 0; - streamer_priv->streamer_tx_ring[i].rsvd3 = 0; - } - streamer_priv->streamer_tx_ring[STREAMER_TX_RING_SIZE - 1].forward = - cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_tx_ring[0], - sizeof(struct streamer_tx_desc), PCI_DMA_TODEVICE)); - - streamer_priv->free_tx_ring_entries = STREAMER_TX_RING_SIZE; - streamer_priv->tx_ring_free = 0; /* next entry in tx ring to use */ - streamer_priv->tx_ring_last_status = STREAMER_TX_RING_SIZE - 1; - - /* set Busmaster interrupt event mask (handle receives on interrupt only */ - writew(MISR_TX2_EOF | MISR_RX_NOBUF | MISR_RX_EOF, streamer_mmio + MISR_MASK); - /* set system event interrupt mask */ - writew(SISR_ADAPTER_CHECK | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_ASB_FREE, streamer_mmio + SISR_MASK_SUM); - -#if STREAMER_DEBUG - printk("BMCTL: %x\n", readw(streamer_mmio + BMCTL_SUM)); - printk("SISR MASK: %x\n", readw(streamer_mmio + SISR_MASK)); -#endif - -#if STREAMER_NETWORK_MONITOR - - writew(streamer_priv->streamer_addr_table_addr, streamer_mmio + LAPA); - printk("%s: Node Address: %04x:%04x:%04x\n", dev->name, - ntohs(readw(streamer_mmio + LAPDINC)), - ntohs(readw(streamer_mmio + LAPDINC)), - ntohs(readw(streamer_mmio + LAPDINC))); - readw(streamer_mmio + LAPDINC); - readw(streamer_mmio + LAPDINC); - printk("%s: Functional Address: %04x:%04x\n", dev->name, - ntohs(readw(streamer_mmio + LAPDINC)), - ntohs(readw(streamer_mmio + LAPDINC))); - - writew(streamer_priv->streamer_parms_addr + 4, - streamer_mmio + LAPA); - printk("%s: NAUN Address: %04x:%04x:%04x\n", dev->name, - ntohs(readw(streamer_mmio + LAPDINC)), - ntohs(readw(streamer_mmio + LAPDINC)), - ntohs(readw(streamer_mmio + LAPDINC))); -#endif - - netif_start_queue(dev); - netif_carrier_on(dev); - return 0; -} - -/* - * When we enter the rx routine we do not know how many frames have been - * queued on the rx channel. Therefore we start at the next rx status - * position and travel around the receive ring until we have completed - * all the frames. - * - * This means that we may process the frame before we receive the end - * of frame interrupt. This is why we always test the status instead - * of blindly processing the next frame. - * - */ -static void streamer_rx(struct net_device *dev) -{ - struct streamer_private *streamer_priv = - netdev_priv(dev); - __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; - struct streamer_rx_desc *rx_desc; - int rx_ring_last_received, length, frame_length, buffer_cnt = 0; - struct sk_buff *skb, *skb2; - - /* setup the next rx descriptor to be received */ - rx_desc = &streamer_priv->streamer_rx_ring[(streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1)]; - rx_ring_last_received = streamer_priv->rx_ring_last_received; - - while (rx_desc->status & 0x01000000) { /* While processed descriptors are available */ - if (rx_ring_last_received != streamer_priv->rx_ring_last_received) - { - printk(KERN_WARNING "RX Error 1 rx_ring_last_received not the same %x %x\n", - rx_ring_last_received, streamer_priv->rx_ring_last_received); - } - streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1); - rx_ring_last_received = streamer_priv->rx_ring_last_received; - - length = rx_desc->framelen_buflen & 0xffff; /* buffer length */ - frame_length = (rx_desc->framelen_buflen >> 16) & 0xffff; - - if (rx_desc->status & 0x7E830000) { /* errors */ - if (streamer_priv->streamer_message_level) { - printk(KERN_WARNING "%s: Rx Error %x\n", - dev->name, rx_desc->status); - } - } else { /* received without errors */ - if (rx_desc->status & 0x80000000) { /* frame complete */ - buffer_cnt = 1; - skb = dev_alloc_skb(streamer_priv->pkt_buf_sz); - } else { - skb = dev_alloc_skb(frame_length); - } - - if (skb == NULL) - { - printk(KERN_WARNING "%s: Not enough memory to copy packet to upper layers.\n", dev->name); - dev->stats.rx_dropped++; - } else { /* we allocated an skb OK */ - if (buffer_cnt == 1) { - /* release the DMA mapping */ - pci_unmap_single(streamer_priv->pci_dev, - le32_to_cpu(streamer_priv->streamer_rx_ring[rx_ring_last_received].buffer), - streamer_priv->pkt_buf_sz, - PCI_DMA_FROMDEVICE); - skb2 = streamer_priv->rx_ring_skb[rx_ring_last_received]; -#if STREAMER_DEBUG_PACKETS - { - int i; - printk("streamer_rx packet print: skb->data2 %p skb->head %p\n", skb2->data, skb2->head); - for (i = 0; i < frame_length; i++) - { - printk("%x:", skb2->data[i]); - if (((i + 1) % 16) == 0) - printk("\n"); - } - printk("\n"); - } -#endif - skb_put(skb2, length); - skb2->protocol = tr_type_trans(skb2, dev); - /* recycle this descriptor */ - streamer_priv->streamer_rx_ring[rx_ring_last_received].status = 0; - streamer_priv->streamer_rx_ring[rx_ring_last_received].framelen_buflen = streamer_priv->pkt_buf_sz; - streamer_priv->streamer_rx_ring[rx_ring_last_received].buffer = - cpu_to_le32(pci_map_single(streamer_priv->pci_dev, skb->data, streamer_priv->pkt_buf_sz, - PCI_DMA_FROMDEVICE)); - streamer_priv->rx_ring_skb[rx_ring_last_received] = skb; - /* place recycled descriptor back on the adapter */ - writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, - &streamer_priv->streamer_rx_ring[rx_ring_last_received], - sizeof(struct streamer_rx_desc), PCI_DMA_FROMDEVICE)), - streamer_mmio + RXLBDA); - /* pass the received skb up to the protocol */ - netif_rx(skb2); - } else { - do { /* Walk the buffers */ - pci_unmap_single(streamer_priv->pci_dev, le32_to_cpu(rx_desc->buffer), length, PCI_DMA_FROMDEVICE), - memcpy(skb_put(skb, length), (void *)rx_desc->buffer, length); /* copy this fragment */ - streamer_priv->streamer_rx_ring[rx_ring_last_received].status = 0; - streamer_priv->streamer_rx_ring[rx_ring_last_received].framelen_buflen = streamer_priv->pkt_buf_sz; - - /* give descriptor back to the adapter */ - writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, - &streamer_priv->streamer_rx_ring[rx_ring_last_received], - length, PCI_DMA_FROMDEVICE)), - streamer_mmio + RXLBDA); - - if (rx_desc->status & 0x80000000) - break; /* this descriptor completes the frame */ - - /* else get the next pending descriptor */ - if (rx_ring_last_received!= streamer_priv->rx_ring_last_received) - { - printk("RX Error rx_ring_last_received not the same %x %x\n", - rx_ring_last_received, - streamer_priv->rx_ring_last_received); - } - rx_desc = &streamer_priv->streamer_rx_ring[(streamer_priv->rx_ring_last_received+1) & (STREAMER_RX_RING_SIZE-1)]; - - length = rx_desc->framelen_buflen & 0xffff; /* buffer length */ - streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received+1) & (STREAMER_RX_RING_SIZE - 1); - rx_ring_last_received = streamer_priv->rx_ring_last_received; - } while (1); - - skb->protocol = tr_type_trans(skb, dev); - /* send up to the protocol */ - netif_rx(skb); - } - dev->stats.rx_packets++; - dev->stats.rx_bytes += length; - } /* if skb == null */ - } /* end received without errors */ - - /* try the next one */ - rx_desc = &streamer_priv->streamer_rx_ring[(rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1)]; - } /* end for all completed rx descriptors */ -} - -static irqreturn_t streamer_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = (struct net_device *) dev_id; - struct streamer_private *streamer_priv = - netdev_priv(dev); - __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; - __u16 sisr; - __u16 misr; - u8 max_intr = MAX_INTR; - - spin_lock(&streamer_priv->streamer_lock); - sisr = readw(streamer_mmio + SISR); - - while((sisr & (SISR_MI | SISR_SRB_REPLY | SISR_ADAPTER_CHECK | SISR_ASB_FREE | - SISR_ARB_CMD | SISR_TRB_REPLY | SISR_PAR_ERR | SISR_SERR_ERR)) && - (max_intr > 0)) { - - if(sisr & SISR_PAR_ERR) { - writew(~SISR_PAR_ERR, streamer_mmio + SISR_RUM); - (void)readw(streamer_mmio + SISR_RUM); - } - - else if(sisr & SISR_SERR_ERR) { - writew(~SISR_SERR_ERR, streamer_mmio + SISR_RUM); - (void)readw(streamer_mmio + SISR_RUM); - } - - else if(sisr & SISR_MI) { - misr = readw(streamer_mmio + MISR_RUM); - - if (misr & MISR_TX2_EOF) { - while(streamer_priv->streamer_tx_ring[(streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1)].status) { - streamer_priv->tx_ring_last_status = (streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1); - streamer_priv->free_tx_ring_entries++; - dev->stats.tx_bytes += streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]->len; - dev->stats.tx_packets++; - dev_kfree_skb_irq(streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]); - streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].buffer = 0xdeadbeef; - streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].status = 0; - streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].bufcnt_framelen = 0; - streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].buflen = 0; - streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].rsvd1 = 0; - streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].rsvd2 = 0; - streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].rsvd3 = 0; - } - netif_wake_queue(dev); - } - - if (misr & MISR_RX_EOF) { - streamer_rx(dev); - } - /* MISR_RX_EOF */ - - if (misr & MISR_RX_NOBUF) { - /* According to the documentation, we don't have to do anything, - * but trapping it keeps it out of /var/log/messages. - */ - } /* SISR_RX_NOBUF */ - - writew(~misr, streamer_mmio + MISR_RUM); - (void)readw(streamer_mmio + MISR_RUM); - } - - else if (sisr & SISR_SRB_REPLY) { - if (streamer_priv->srb_queued == 1) { - wake_up_interruptible(&streamer_priv->srb_wait); - } else if (streamer_priv->srb_queued == 2) { - streamer_srb_bh(dev); - } - streamer_priv->srb_queued = 0; - - writew(~SISR_SRB_REPLY, streamer_mmio + SISR_RUM); - (void)readw(streamer_mmio + SISR_RUM); - } - - else if (sisr & SISR_ADAPTER_CHECK) { - printk(KERN_WARNING "%s: Adapter Check Interrupt Raised, 8 bytes of information follow:\n", dev->name); - writel(readl(streamer_mmio + LAPWWO), streamer_mmio + LAPA); - printk(KERN_WARNING "%s: Words %x:%x:%x:%x:\n", - dev->name, readw(streamer_mmio + LAPDINC), - ntohs(readw(streamer_mmio + LAPDINC)), - ntohs(readw(streamer_mmio + LAPDINC)), - ntohs(readw(streamer_mmio + LAPDINC))); - netif_stop_queue(dev); - netif_carrier_off(dev); - printk(KERN_WARNING "%s: Adapter must be manually reset.\n", dev->name); - } - - /* SISR_ADAPTER_CHECK */ - else if (sisr & SISR_ASB_FREE) { - /* Wake up anything that is waiting for the asb response */ - if (streamer_priv->asb_queued) { - streamer_asb_bh(dev); - } - writew(~SISR_ASB_FREE, streamer_mmio + SISR_RUM); - (void)readw(streamer_mmio + SISR_RUM); - } - /* SISR_ASB_FREE */ - else if (sisr & SISR_ARB_CMD) { - streamer_arb_cmd(dev); - writew(~SISR_ARB_CMD, streamer_mmio + SISR_RUM); - (void)readw(streamer_mmio + SISR_RUM); - } - /* SISR_ARB_CMD */ - else if (sisr & SISR_TRB_REPLY) { - /* Wake up anything that is waiting for the trb response */ - if (streamer_priv->trb_queued) { - wake_up_interruptible(&streamer_priv-> - trb_wait); - } - streamer_priv->trb_queued = 0; - writew(~SISR_TRB_REPLY, streamer_mmio + SISR_RUM); - (void)readw(streamer_mmio + SISR_RUM); - } - /* SISR_TRB_REPLY */ - - sisr = readw(streamer_mmio + SISR); - max_intr--; - } /* while() */ - - spin_unlock(&streamer_priv->streamer_lock) ; - return IRQ_HANDLED; -} - -static netdev_tx_t streamer_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - struct streamer_private *streamer_priv = - netdev_priv(dev); - __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; - unsigned long flags ; - - spin_lock_irqsave(&streamer_priv->streamer_lock, flags); - - if (streamer_priv->free_tx_ring_entries) { - streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].status = 0; - streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].bufcnt_framelen = 0x00020000 | skb->len; - streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buffer = - cpu_to_le32(pci_map_single(streamer_priv->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE)); - streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd1 = skb->len; - streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd2 = 0; - streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd3 = 0; - streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buflen = skb->len; - - streamer_priv->tx_ring_skb[streamer_priv->tx_ring_free] = skb; - streamer_priv->free_tx_ring_entries--; -#if STREAMER_DEBUG_PACKETS - { - int i; - printk("streamer_xmit packet print:\n"); - for (i = 0; i < skb->len; i++) { - printk("%x:", skb->data[i]); - if (((i + 1) % 16) == 0) - printk("\n"); - } - printk("\n"); - } -#endif - - writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, - &streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free], - sizeof(struct streamer_tx_desc), PCI_DMA_TODEVICE)), - streamer_mmio + TX2LFDA); - (void)readl(streamer_mmio + TX2LFDA); - - streamer_priv->tx_ring_free = (streamer_priv->tx_ring_free + 1) & (STREAMER_TX_RING_SIZE - 1); - spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags); - return NETDEV_TX_OK; - } else { - netif_stop_queue(dev); - spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags); - return NETDEV_TX_BUSY; - } -} - - -static int streamer_close(struct net_device *dev) -{ - struct streamer_private *streamer_priv = - netdev_priv(dev); - __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; - unsigned long flags; - int i; - - netif_stop_queue(dev); - netif_carrier_off(dev); - writew(streamer_priv->srb, streamer_mmio + LAPA); - writew(htons(SRB_CLOSE_ADAPTER << 8),streamer_mmio+LAPDINC); - writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); - - spin_lock_irqsave(&streamer_priv->streamer_lock, flags); - - streamer_priv->srb_queued = 1; - writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM); - - spin_unlock_irqrestore(&streamer_priv->streamer_lock, flags); - - while (streamer_priv->srb_queued) - { - interruptible_sleep_on_timeout(&streamer_priv->srb_wait, - jiffies + 60 * HZ); - if (signal_pending(current)) - { - printk(KERN_WARNING "%s: SRB timed out.\n", dev->name); - printk(KERN_WARNING "SISR=%x MISR=%x LISR=%x\n", - readw(streamer_mmio + SISR), - readw(streamer_mmio + MISR_RUM), - readw(streamer_mmio + LISR)); - streamer_priv->srb_queued = 0; - break; - } - } - - streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1); - - for (i = 0; i < STREAMER_RX_RING_SIZE; i++) { - if (streamer_priv->rx_ring_skb[streamer_priv->rx_ring_last_received]) { - dev_kfree_skb(streamer_priv->rx_ring_skb[streamer_priv->rx_ring_last_received]); - } - streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1); - } - - /* reset tx/rx fifo's and busmaster logic */ - - /* TBD. Add graceful way to reset the LLC channel without doing a soft reset. - writel(readl(streamer_mmio+BCTL)|(3<<13),streamer_mmio+BCTL); - udelay(1); - writel(readl(streamer_mmio+BCTL)&~(3<<13),streamer_mmio+BCTL); - */ - -#if STREAMER_DEBUG - writew(streamer_priv->srb, streamer_mmio + LAPA); - printk("srb): "); - for (i = 0; i < 2; i++) { - printk("%x ", ntohs(readw(streamer_mmio + LAPDINC))); - } - printk("\n"); -#endif - free_irq(dev->irq, dev); - return 0; -} - -static void streamer_set_rx_mode(struct net_device *dev) -{ - struct streamer_private *streamer_priv = - netdev_priv(dev); - __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; - __u8 options = 0; - struct netdev_hw_addr *ha; - unsigned char dev_mc_address[5]; - - writel(streamer_priv->srb, streamer_mmio + LAPA); - options = streamer_priv->streamer_copy_all_options; - - if (dev->flags & IFF_PROMISC) - options |= (3 << 5); /* All LLC and MAC frames, all through the main rx channel */ - else - options &= ~(3 << 5); - - /* Only issue the srb if there is a change in options */ - - if ((options ^ streamer_priv->streamer_copy_all_options)) - { - /* Now to issue the srb command to alter the copy.all.options */ - writew(htons(SRB_MODIFY_RECEIVE_OPTIONS << 8), streamer_mmio+LAPDINC); - writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); - writew(htons((streamer_priv->streamer_receive_options << 8) | options),streamer_mmio+LAPDINC); - writew(htons(0x4a41),streamer_mmio+LAPDINC); - writew(htons(0x4d45),streamer_mmio+LAPDINC); - writew(htons(0x5320),streamer_mmio+LAPDINC); - writew(0x2020, streamer_mmio + LAPDINC); - - streamer_priv->srb_queued = 2; /* Can't sleep, use srb_bh */ - - writel(LISR_SRB_CMD, streamer_mmio + LISR_SUM); - - streamer_priv->streamer_copy_all_options = options; - return; - } - - /* Set the functional addresses we need for multicast */ - writel(streamer_priv->srb,streamer_mmio+LAPA); - dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ; - - netdev_for_each_mc_addr(ha, dev) { - dev_mc_address[0] |= ha->addr[2]; - dev_mc_address[1] |= ha->addr[3]; - dev_mc_address[2] |= ha->addr[4]; - dev_mc_address[3] |= ha->addr[5]; - } - - writew(htons(SRB_SET_FUNC_ADDRESS << 8),streamer_mmio+LAPDINC); - writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); - writew(0,streamer_mmio+LAPDINC); - writew(htons( (dev_mc_address[0] << 8) | dev_mc_address[1]),streamer_mmio+LAPDINC); - writew(htons( (dev_mc_address[2] << 8) | dev_mc_address[3]),streamer_mmio+LAPDINC); - streamer_priv->srb_queued = 2 ; - writel(LISR_SRB_CMD,streamer_mmio+LISR_SUM); -} - -static void streamer_srb_bh(struct net_device *dev) -{ - struct streamer_private *streamer_priv = netdev_priv(dev); - __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; - __u16 srb_word; - - writew(streamer_priv->srb, streamer_mmio + LAPA); - srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; - - switch (srb_word) { - - /* SRB_MODIFY_RECEIVE_OPTIONS i.e. set_multicast_list options (promiscuous) - * At some point we should do something if we get an error, such as - * resetting the IFF_PROMISC flag in dev - */ - - case SRB_MODIFY_RECEIVE_OPTIONS: - srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; - - switch (srb_word) { - case 0x01: - printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name); - break; - case 0x04: - printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); - break; - default: - if (streamer_priv->streamer_message_level) - printk(KERN_WARNING "%s: Receive Options Modified to %x,%x\n", - dev->name, - streamer_priv->streamer_copy_all_options, - streamer_priv->streamer_receive_options); - break; - } /* switch srb[2] */ - break; - - - /* SRB_SET_GROUP_ADDRESS - Multicast group setting - */ - case SRB_SET_GROUP_ADDRESS: - srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; - switch (srb_word) { - case 0x00: - break; - case 0x01: - printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name); - break; - case 0x04: - printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); - break; - case 0x3c: - printk(KERN_WARNING "%s: Group/Functional address indicator bits not set correctly\n", dev->name); - break; - case 0x3e: /* If we ever implement individual multicast addresses, will need to deal with this */ - printk(KERN_WARNING "%s: Group address registers full\n", dev->name); - break; - case 0x55: - printk(KERN_INFO "%s: Group Address already set.\n", dev->name); - break; - default: - break; - } /* switch srb[2] */ - break; - - - /* SRB_RESET_GROUP_ADDRESS - Remove a multicast address from group list - */ - case SRB_RESET_GROUP_ADDRESS: - srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; - switch (srb_word) { - case 0x00: - break; - case 0x01: - printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name); - break; - case 0x04: - printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); - break; - case 0x39: /* Must deal with this if individual multicast addresses used */ - printk(KERN_INFO "%s: Group address not found\n", dev->name); - break; - default: - break; - } /* switch srb[2] */ - break; - - - /* SRB_SET_FUNC_ADDRESS - Called by the set_rx_mode - */ - - case SRB_SET_FUNC_ADDRESS: - srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; - switch (srb_word) { - case 0x00: - if (streamer_priv->streamer_message_level) - printk(KERN_INFO "%s: Functional Address Mask Set\n", dev->name); - break; - case 0x01: - printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name); - break; - case 0x04: - printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); - break; - default: - break; - } /* switch srb[2] */ - break; - - /* SRB_READ_LOG - Read and reset the adapter error counters - */ - - case SRB_READ_LOG: - srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; - switch (srb_word) { - case 0x00: - { - int i; - if (streamer_priv->streamer_message_level) - printk(KERN_INFO "%s: Read Log command complete\n", dev->name); - printk("Read Log statistics: "); - writew(streamer_priv->srb + 6, - streamer_mmio + LAPA); - for (i = 0; i < 5; i++) { - printk("%x:", ntohs(readw(streamer_mmio + LAPDINC))); - } - printk("\n"); - } - break; - case 0x01: - printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name); - break; - case 0x04: - printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); - break; - - } /* switch srb[2] */ - break; - - /* SRB_READ_SR_COUNTERS - Read and reset the source routing bridge related counters */ - - case SRB_READ_SR_COUNTERS: - srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; - switch (srb_word) { - case 0x00: - if (streamer_priv->streamer_message_level) - printk(KERN_INFO "%s: Read Source Routing Counters issued\n", dev->name); - break; - case 0x01: - printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name); - break; - case 0x04: - printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); - break; - default: - break; - } /* switch srb[2] */ - break; - - default: - printk(KERN_WARNING "%s: Unrecognized srb bh return value.\n", dev->name); - break; - } /* switch srb[0] */ -} - -static int streamer_set_mac_address(struct net_device *dev, void *addr) -{ - struct sockaddr *saddr = addr; - struct streamer_private *streamer_priv = netdev_priv(dev); - - if (netif_running(dev)) - { - printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name); - return -EIO; - } - - memcpy(streamer_priv->streamer_laa, saddr->sa_data, dev->addr_len); - - if (streamer_priv->streamer_message_level) { - printk(KERN_INFO "%s: MAC/LAA Set to = %x.%x.%x.%x.%x.%x\n", - dev->name, streamer_priv->streamer_laa[0], - streamer_priv->streamer_laa[1], - streamer_priv->streamer_laa[2], - streamer_priv->streamer_laa[3], - streamer_priv->streamer_laa[4], - streamer_priv->streamer_laa[5]); - } - return 0; -} - -static void streamer_arb_cmd(struct net_device *dev) -{ - struct streamer_private *streamer_priv = - netdev_priv(dev); - __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; - __u8 header_len; - __u16 frame_len, buffer_len; - struct sk_buff *mac_frame; - __u8 frame_data[256]; - __u16 buff_off; - __u16 lan_status = 0, lan_status_diff; /* Initialize to stop compiler warning */ - __u8 fdx_prot_error; - __u16 next_ptr; - __u16 arb_word; - -#if STREAMER_NETWORK_MONITOR - struct trh_hdr *mac_hdr; -#endif - - writew(streamer_priv->arb, streamer_mmio + LAPA); - arb_word=ntohs(readw(streamer_mmio+LAPD)) >> 8; - - if (arb_word == ARB_RECEIVE_DATA) { /* Receive.data, MAC frames */ - writew(streamer_priv->arb + 6, streamer_mmio + LAPA); - streamer_priv->mac_rx_buffer = buff_off = ntohs(readw(streamer_mmio + LAPDINC)); - header_len=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; /* 802.5 Token-Ring Header Length */ - frame_len = ntohs(readw(streamer_mmio + LAPDINC)); - -#if STREAMER_DEBUG - { - int i; - __u16 next; - __u8 status; - __u16 len; - - writew(ntohs(buff_off), streamer_mmio + LAPA); /*setup window to frame data */ - next = htons(readw(streamer_mmio + LAPDINC)); - status = - ntohs(readw(streamer_mmio + LAPDINC)) & 0xff; - len = ntohs(readw(streamer_mmio + LAPDINC)); - - /* print out 1st 14 bytes of frame data */ - for (i = 0; i < 7; i++) { - printk("Loc %d = %04x\n", i, - ntohs(readw - (streamer_mmio + LAPDINC))); - } - - printk("next %04x, fs %02x, len %04x\n", next, - status, len); - } -#endif - if (!(mac_frame = dev_alloc_skb(frame_len))) { - printk(KERN_WARNING "%s: Memory squeeze, dropping frame.\n", - dev->name); - goto drop_frame; - } - /* Walk the buffer chain, creating the frame */ - - do { - int i; - __u16 rx_word; - - writew(htons(buff_off), streamer_mmio + LAPA); /* setup window to frame data */ - next_ptr = ntohs(readw(streamer_mmio + LAPDINC)); - readw(streamer_mmio + LAPDINC); /* read thru status word */ - buffer_len = ntohs(readw(streamer_mmio + LAPDINC)); - - if (buffer_len > 256) - break; - - i = 0; - while (i < buffer_len) { - rx_word=ntohs(readw(streamer_mmio+LAPDINC)); - frame_data[i]=rx_word >> 8; - frame_data[i+1]=rx_word & 0xff; - i += 2; - } - - memcpy(skb_put(mac_frame, buffer_len), - frame_data, buffer_len); - } while (next_ptr && (buff_off = next_ptr)); - - mac_frame->protocol = tr_type_trans(mac_frame, dev); -#if STREAMER_NETWORK_MONITOR - printk(KERN_WARNING "%s: Received MAC Frame, details:\n", - dev->name); - mac_hdr = tr_hdr(mac_frame); - printk(KERN_WARNING - "%s: MAC Frame Dest. Addr: %pM\n", - dev->name, mac_hdr->daddr); - printk(KERN_WARNING - "%s: MAC Frame Srce. Addr: %pM\n", - dev->name, mac_hdr->saddr); -#endif - netif_rx(mac_frame); - - /* Now tell the card we have dealt with the received frame */ -drop_frame: - /* Set LISR Bit 1 */ - writel(LISR_ARB_FREE, streamer_priv->streamer_mmio + LISR_SUM); - - /* Is the ASB free ? */ - - if (!(readl(streamer_priv->streamer_mmio + SISR) & SISR_ASB_FREE)) - { - streamer_priv->asb_queued = 1; - writel(LISR_ASB_FREE_REQ, streamer_priv->streamer_mmio + LISR_SUM); - return; - /* Drop out and wait for the bottom half to be run */ - } - - - writew(streamer_priv->asb, streamer_mmio + LAPA); - writew(htons(ASB_RECEIVE_DATA << 8), streamer_mmio+LAPDINC); - writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); - writew(0, streamer_mmio + LAPDINC); - writew(htons(streamer_priv->mac_rx_buffer), streamer_mmio + LAPD); - - writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ, streamer_priv->streamer_mmio + LISR_SUM); - - streamer_priv->asb_queued = 2; - return; - - } else if (arb_word == ARB_LAN_CHANGE_STATUS) { /* Lan.change.status */ - writew(streamer_priv->arb + 6, streamer_mmio + LAPA); - lan_status = ntohs(readw(streamer_mmio + LAPDINC)); - fdx_prot_error = ntohs(readw(streamer_mmio+LAPD)) >> 8; - - /* Issue ARB Free */ - writew(LISR_ARB_FREE, streamer_priv->streamer_mmio + LISR_SUM); - - lan_status_diff = (streamer_priv->streamer_lan_status ^ lan_status) & - lan_status; - - if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR)) - { - if (lan_status_diff & LSC_LWF) - printk(KERN_WARNING "%s: Short circuit detected on the lobe\n", dev->name); - if (lan_status_diff & LSC_ARW) - printk(KERN_WARNING "%s: Auto removal error\n", dev->name); - if (lan_status_diff & LSC_FPE) - printk(KERN_WARNING "%s: FDX Protocol Error\n", dev->name); - if (lan_status_diff & LSC_RR) - printk(KERN_WARNING "%s: Force remove MAC frame received\n", dev->name); - - /* Adapter has been closed by the hardware */ - - /* reset tx/rx fifo's and busmaster logic */ - - /* @TBD. no llc reset on autostreamer writel(readl(streamer_mmio+BCTL)|(3<<13),streamer_mmio+BCTL); - udelay(1); - writel(readl(streamer_mmio+BCTL)&~(3<<13),streamer_mmio+BCTL); */ - - netif_stop_queue(dev); - netif_carrier_off(dev); - printk(KERN_WARNING "%s: Adapter must be manually reset.\n", dev->name); - } - /* If serious error */ - if (streamer_priv->streamer_message_level) { - if (lan_status_diff & LSC_SIG_LOSS) - printk(KERN_WARNING "%s: No receive signal detected\n", dev->name); - if (lan_status_diff & LSC_HARD_ERR) - printk(KERN_INFO "%s: Beaconing\n", dev->name); - if (lan_status_diff & LSC_SOFT_ERR) - printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame\n", dev->name); - if (lan_status_diff & LSC_TRAN_BCN) - printk(KERN_INFO "%s: We are transmitting the beacon, aaah\n", dev->name); - if (lan_status_diff & LSC_SS) - printk(KERN_INFO "%s: Single Station on the ring\n", dev->name); - if (lan_status_diff & LSC_RING_REC) - printk(KERN_INFO "%s: Ring recovery ongoing\n", dev->name); - if (lan_status_diff & LSC_FDX_MODE) - printk(KERN_INFO "%s: Operating in FDX mode\n", dev->name); - } - - if (lan_status_diff & LSC_CO) { - if (streamer_priv->streamer_message_level) - printk(KERN_INFO "%s: Counter Overflow\n", dev->name); - - /* Issue READ.LOG command */ - - writew(streamer_priv->srb, streamer_mmio + LAPA); - writew(htons(SRB_READ_LOG << 8),streamer_mmio+LAPDINC); - writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); - writew(0, streamer_mmio + LAPDINC); - streamer_priv->srb_queued = 2; /* Can't sleep, use srb_bh */ - - writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM); - } - - if (lan_status_diff & LSC_SR_CO) { - if (streamer_priv->streamer_message_level) - printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name); - - /* Issue a READ.SR.COUNTERS */ - writew(streamer_priv->srb, streamer_mmio + LAPA); - writew(htons(SRB_READ_SR_COUNTERS << 8), - streamer_mmio+LAPDINC); - writew(htons(STREAMER_CLEAR_RET_CODE << 8), - streamer_mmio+LAPDINC); - streamer_priv->srb_queued = 2; /* Can't sleep, use srb_bh */ - writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM); - - } - streamer_priv->streamer_lan_status = lan_status; - } /* Lan.change.status */ - else - printk(KERN_WARNING "%s: Unknown arb command\n", dev->name); -} - -static void streamer_asb_bh(struct net_device *dev) -{ - struct streamer_private *streamer_priv = - netdev_priv(dev); - __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; - - if (streamer_priv->asb_queued == 1) - { - /* Dropped through the first time */ - - writew(streamer_priv->asb, streamer_mmio + LAPA); - writew(htons(ASB_RECEIVE_DATA << 8),streamer_mmio+LAPDINC); - writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); - writew(0, streamer_mmio + LAPDINC); - writew(htons(streamer_priv->mac_rx_buffer), streamer_mmio + LAPD); - - writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ, streamer_priv->streamer_mmio + LISR_SUM); - streamer_priv->asb_queued = 2; - - return; - } - - if (streamer_priv->asb_queued == 2) { - __u8 rc; - writew(streamer_priv->asb + 2, streamer_mmio + LAPA); - rc=ntohs(readw(streamer_mmio+LAPD)) >> 8; - switch (rc) { - case 0x01: - printk(KERN_WARNING "%s: Unrecognized command code\n", dev->name); - break; - case 0x26: - printk(KERN_WARNING "%s: Unrecognized buffer address\n", dev->name); - break; - case 0xFF: - /* Valid response, everything should be ok again */ - break; - default: - printk(KERN_WARNING "%s: Invalid return code in asb\n", dev->name); - break; - } - } - streamer_priv->asb_queued = 0; -} - -static int streamer_change_mtu(struct net_device *dev, int mtu) -{ - struct streamer_private *streamer_priv = - netdev_priv(dev); - __u16 max_mtu; - - if (streamer_priv->streamer_ring_speed == 4) - max_mtu = 4500; - else - max_mtu = 18000; - - if (mtu > max_mtu) - return -EINVAL; - if (mtu < 100) - return -EINVAL; - - dev->mtu = mtu; - streamer_priv->pkt_buf_sz = mtu + TR_HLEN; - - return 0; -} - -#if STREAMER_NETWORK_MONITOR -#ifdef CONFIG_PROC_FS -static int streamer_proc_info(char *buffer, char **start, off_t offset, - int length, int *eof, void *data) -{ - struct streamer_private *sdev=NULL; - struct pci_dev *pci_device = NULL; - int len = 0; - off_t begin = 0; - off_t pos = 0; - int size; - - struct net_device *dev; - - size = sprintf(buffer, "IBM LanStreamer/MPC Chipset Token Ring Adapters\n"); - - pos += size; - len += size; - - for(sdev=dev_streamer; sdev; sdev=sdev->next) { - pci_device=sdev->pci_dev; - dev=pci_get_drvdata(pci_device); - - size = sprintf_info(buffer + len, dev); - len += size; - pos = begin + len; - - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) - break; - } /* for */ - - *start = buffer + (offset - begin); /* Start of wanted data */ - len -= (offset - begin); /* Start slop */ - if (len > length) - len = length; /* Ending slop */ - return len; -} - -static int sprintf_info(char *buffer, struct net_device *dev) -{ - struct streamer_private *streamer_priv = - netdev_priv(dev); - __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; - struct streamer_adapter_addr_table sat; - struct streamer_parameters_table spt; - int size = 0; - int i; - - writew(streamer_priv->streamer_addr_table_addr, streamer_mmio + LAPA); - for (i = 0; i < 14; i += 2) { - __u16 io_word; - __u8 *datap = (__u8 *) & sat; - io_word=ntohs(readw(streamer_mmio+LAPDINC)); - datap[size]=io_word >> 8; - datap[size+1]=io_word & 0xff; - } - writew(streamer_priv->streamer_parms_addr, streamer_mmio + LAPA); - for (i = 0; i < 68; i += 2) { - __u16 io_word; - __u8 *datap = (__u8 *) & spt; - io_word=ntohs(readw(streamer_mmio+LAPDINC)); - datap[size]=io_word >> 8; - datap[size+1]=io_word & 0xff; - } - - size = sprintf(buffer, "\n%6s: Adapter Address : Node Address : Functional Addr\n", dev->name); - - size += sprintf(buffer + size, - "%6s: %pM : %pM : %02x:%02x:%02x:%02x\n", - dev->name, dev->dev_addr, sat.node_addr, - sat.func_addr[0], sat.func_addr[1], - sat.func_addr[2], sat.func_addr[3]); - - size += sprintf(buffer + size, "\n%6s: Token Ring Parameters Table:\n", dev->name); - - size += sprintf(buffer + size, "%6s: Physical Addr : Up Node Address : Poll Address : AccPri : Auth Src : Att Code :\n", dev->name); - - size += sprintf(buffer + size, - "%6s: %02x:%02x:%02x:%02x : %pM : %pM : %04x : %04x : %04x :\n", - dev->name, spt.phys_addr[0], spt.phys_addr[1], - spt.phys_addr[2], spt.phys_addr[3], - spt.up_node_addr, spt.poll_addr, - ntohs(spt.acc_priority), ntohs(spt.auth_source_class), - ntohs(spt.att_code)); - - size += sprintf(buffer + size, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n", dev->name); - - size += sprintf(buffer + size, - "%6s: %pM : %04x : %04x : %04x : %04x : %04x : %04x : \n", - dev->name, spt.source_addr, - ntohs(spt.beacon_type), ntohs(spt.major_vector), - ntohs(spt.lan_status), ntohs(spt.local_ring), - ntohs(spt.mon_error), ntohs(spt.frame_correl)); - - size += sprintf(buffer + size, "%6s: Beacon Details : Tx : Rx : NAUN Node Address : NAUN Node Phys : \n", - dev->name); - - size += sprintf(buffer + size, - "%6s: : %02x : %02x : %pM : %02x:%02x:%02x:%02x : \n", - dev->name, ntohs(spt.beacon_transmit), - ntohs(spt.beacon_receive), - spt.beacon_naun, - spt.beacon_phys[0], spt.beacon_phys[1], - spt.beacon_phys[2], spt.beacon_phys[3]); - return size; -} -#endif -#endif - -static struct pci_driver streamer_pci_driver = { - .name = "lanstreamer", - .id_table = streamer_pci_tbl, - .probe = streamer_init_one, - .remove = __devexit_p(streamer_remove_one), -}; - -module_pci_driver(streamer_pci_driver); - -MODULE_LICENSE("GPL");
diff --git a/drivers/net/tokenring/lanstreamer.h b/drivers/net/tokenring/lanstreamer.h deleted file mode 100644 index 3c58d6a..0000000 --- a/drivers/net/tokenring/lanstreamer.h +++ /dev/null
@@ -1,343 +0,0 @@ -/* - * lanstreamer.h -- driver for the IBM Auto LANStreamer PCI Adapter - * - * Written By: Mike Sullivan, IBM Corporation - * - * Copyright (C) 1999 IBM Corporation - * - * Linux driver for IBM PCI tokenring cards based on the LanStreamer MPC - * chipset. - * - * This driver is based on the olympic driver for IBM PCI TokenRing cards (Pit/Pit-Phy/Olympic - * chipsets) written by: - * 1999 Peter De Schrijver All Rights Reserved - * 1999 Mike Phillips (phillim@amtrak.com) - * - * Base Driver Skeleton: - * Written 1993-94 by Donald Becker. - * - * Copyright 1993 United States Government as represented by the - * Director, National Security Agency. - * - * 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. - * - * NO WARRANTY - * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT - * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is - * solely responsible for determining the appropriateness of using and - * distributing the Program and assumes all risks associated with its - * exercise of rights under this Agreement, including but not limited to - * the risks and costs of program errors, damage to or loss of data, - * programs or equipment, and unavailability or interruption of operations. - * - * DISCLAIMER OF LIABILITY - * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED - * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES - * - * 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 - * - * - * 12/10/99 - Alpha Release 0.1.0 - * First release to the public - * 08/15/01 - Added ioctl() definitions and others - Kent Yoder <yoder1@us.ibm.com> - * - */ - -/* MAX_INTR - the maximum number of times we can loop - * inside the interrupt function before returning - * control to the OS (maximum value is 256) - */ -#define MAX_INTR 5 - -#define CLS 0x0C -#define MLR 0x86 -#define LTR 0x0D - -#define BCTL 0x60 -#define BCTL_SOFTRESET (1<<15) -#define BCTL_RX_FIFO_8 (1<<1) -#define BCTL_TX_FIFO_8 (1<<3) - -#define GPR 0x4a -#define GPR_AUTOSENSE (1<<2) -#define GPR_16MBPS (1<<3) - -#define LISR 0x10 -#define LISR_SUM 0x12 -#define LISR_RUM 0x14 - -#define LISR_LIE (1<<15) -#define LISR_SLIM (1<<13) -#define LISR_SLI (1<<12) -#define LISR_BPEI (1<<9) -#define LISR_BPE (1<<8) -#define LISR_SRB_CMD (1<<5) -#define LISR_ASB_REPLY (1<<4) -#define LISR_ASB_FREE_REQ (1<<2) -#define LISR_ARB_FREE (1<<1) -#define LISR_TRB_FRAME (1<<0) - -#define SISR 0x16 -#define SISR_SUM 0x18 -#define SISR_RUM 0x1A -#define SISR_MASK 0x54 -#define SISR_MASK_SUM 0x56 -#define SISR_MASK_RUM 0x58 - -#define SISR_MI (1<<15) -#define SISR_SERR_ERR (1<<14) -#define SISR_TIMER (1<<11) -#define SISR_LAP_PAR_ERR (1<<10) -#define SISR_LAP_ACC_ERR (1<<9) -#define SISR_PAR_ERR (1<<8) -#define SISR_ADAPTER_CHECK (1<<6) -#define SISR_SRB_REPLY (1<<5) -#define SISR_ASB_FREE (1<<4) -#define SISR_ARB_CMD (1<<3) -#define SISR_TRB_REPLY (1<<2) - -#define MISR_RUM 0x5A -#define MISR_MASK 0x5C -#define MISR_MASK_RUM 0x5E - -#define MISR_TX2_IDLE (1<<15) -#define MISR_TX2_NO_STATUS (1<<14) -#define MISR_TX2_HALT (1<<13) -#define MISR_TX2_EOF (1<<12) -#define MISR_TX1_IDLE (1<<11) -#define MISR_TX1_NO_STATUS (1<<10) -#define MISR_TX1_HALT (1<<9) -#define MISR_TX1_EOF (1<<8) -#define MISR_RX_NOBUF (1<<5) -#define MISR_RX_EOB (1<<4) -#define MISR_RX_NO_STATUS (1<<2) -#define MISR_RX_HALT (1<<1) -#define MISR_RX_EOF (1<<0) - -#define LAPA 0x62 -#define LAPE 0x64 -#define LAPD 0x66 -#define LAPDINC 0x68 -#define LAPWWO 0x6A -#define LAPWWC 0x6C -#define LAPCTL 0x6E - -#define TIMER 0x4E4 - -#define BMCTL_SUM 0x50 -#define BMCTL_RUM 0x52 -#define BMCTL_TX1_DIS (1<<14) -#define BMCTL_TX2_DIS (1<<10) -#define BMCTL_RX_DIS (1<<6) -#define BMCTL_RX_ENABLED (1<<5) - -#define RXLBDA 0x90 -#define RXBDA 0x94 -#define RXSTAT 0x98 -#define RXDBA 0x9C - -#define TX1LFDA 0xA0 -#define TX1FDA 0xA4 -#define TX1STAT 0xA8 -#define TX1DBA 0xAC -#define TX2LFDA 0xB0 -#define TX2FDA 0xB4 -#define TX2STAT 0xB8 -#define TX2DBA 0xBC - -#define STREAMER_IO_SPACE 256 - -#define SRB_COMMAND_SIZE 50 - -#define STREAMER_MAX_ADAPTERS 8 /* 0x08 __MODULE_STRING can't hand 0xnn */ - -/* Defines for LAN STATUS CHANGE reports */ -#define LSC_SIG_LOSS 0x8000 -#define LSC_HARD_ERR 0x4000 -#define LSC_SOFT_ERR 0x2000 -#define LSC_TRAN_BCN 0x1000 -#define LSC_LWF 0x0800 -#define LSC_ARW 0x0400 -#define LSC_FPE 0x0200 -#define LSC_RR 0x0100 -#define LSC_CO 0x0080 -#define LSC_SS 0x0040 -#define LSC_RING_REC 0x0020 -#define LSC_SR_CO 0x0010 -#define LSC_FDX_MODE 0x0004 - -/* Defines for OPEN ADAPTER command */ - -#define OPEN_ADAPTER_EXT_WRAP (1<<15) -#define OPEN_ADAPTER_DIS_HARDEE (1<<14) -#define OPEN_ADAPTER_DIS_SOFTERR (1<<13) -#define OPEN_ADAPTER_PASS_ADC_MAC (1<<12) -#define OPEN_ADAPTER_PASS_ATT_MAC (1<<11) -#define OPEN_ADAPTER_ENABLE_EC (1<<10) -#define OPEN_ADAPTER_CONTENDER (1<<8) -#define OPEN_ADAPTER_PASS_BEACON (1<<7) -#define OPEN_ADAPTER_ENABLE_FDX (1<<6) -#define OPEN_ADAPTER_ENABLE_RPL (1<<5) -#define OPEN_ADAPTER_INHIBIT_ETR (1<<4) -#define OPEN_ADAPTER_INTERNAL_WRAP (1<<3) - - -/* Defines for SRB Commands */ -#define SRB_CLOSE_ADAPTER 0x04 -#define SRB_CONFIGURE_BRIDGE 0x0c -#define SRB_CONFIGURE_HP_CHANNEL 0x13 -#define SRB_MODIFY_BRIDGE_PARMS 0x15 -#define SRB_MODIFY_OPEN_OPTIONS 0x01 -#define SRB_MODIFY_RECEIVE_OPTIONS 0x17 -#define SRB_NO_OPERATION 0x00 -#define SRB_OPEN_ADAPTER 0x03 -#define SRB_READ_LOG 0x08 -#define SRB_READ_SR_COUNTERS 0x16 -#define SRB_RESET_GROUP_ADDRESS 0x02 -#define SRB_RESET_TARGET_SEGMETN 0x14 -#define SRB_SAVE_CONFIGURATION 0x1b -#define SRB_SET_BRIDGE_PARMS 0x09 -#define SRB_SET_FUNC_ADDRESS 0x07 -#define SRB_SET_GROUP_ADDRESS 0x06 -#define SRB_SET_TARGET_SEGMENT 0x05 - -/* Clear return code */ -#define STREAMER_CLEAR_RET_CODE 0xfe - -/* ARB Commands */ -#define ARB_RECEIVE_DATA 0x81 -#define ARB_LAN_CHANGE_STATUS 0x84 - -/* ASB Response commands */ -#define ASB_RECEIVE_DATA 0x81 - - -/* Streamer defaults for buffers */ - -#define STREAMER_RX_RING_SIZE 16 /* should be a power of 2 */ -/* Setting the number of TX descriptors to 1 is a workaround for an - * undocumented hardware problem with the lanstreamer board. Setting - * this to something higher may slightly increase the throughput you - * can get from the card, but at the risk of locking up the box. - - * <yoder1@us.ibm.com> - */ -#define STREAMER_TX_RING_SIZE 1 /* should be a power of 2 */ - -#define PKT_BUF_SZ 4096 /* Default packet size */ - -/* Streamer data structures */ - -struct streamer_tx_desc { - __u32 forward; - __u32 status; - __u32 bufcnt_framelen; - __u32 buffer; - __u32 buflen; - __u32 rsvd1; - __u32 rsvd2; - __u32 rsvd3; -}; - -struct streamer_rx_desc { - __u32 forward; - __u32 status; - __u32 buffer; - __u32 framelen_buflen; -}; - -struct mac_receive_buffer { - __u16 next; - __u8 padding; - __u8 frame_status; - __u16 buffer_length; - __u8 frame_data; -}; - -struct streamer_private { - - __u16 srb; - __u16 trb; - __u16 arb; - __u16 asb; - - struct streamer_private *next; - struct pci_dev *pci_dev; - __u8 __iomem *streamer_mmio; - char *streamer_card_name; - - spinlock_t streamer_lock; - - volatile int srb_queued; /* True if an SRB is still posted */ - wait_queue_head_t srb_wait; - - volatile int asb_queued; /* True if an ASB is posted */ - - volatile int trb_queued; /* True if a TRB is posted */ - wait_queue_head_t trb_wait; - - struct streamer_rx_desc *streamer_rx_ring; - struct streamer_tx_desc *streamer_tx_ring; - struct sk_buff *tx_ring_skb[STREAMER_TX_RING_SIZE], - *rx_ring_skb[STREAMER_RX_RING_SIZE]; - int tx_ring_free, tx_ring_last_status, rx_ring_last_received, - free_tx_ring_entries; - - __u16 streamer_lan_status; - __u8 streamer_ring_speed; - __u16 pkt_buf_sz; - __u8 streamer_receive_options, streamer_copy_all_options, - streamer_message_level; - __u16 streamer_addr_table_addr, streamer_parms_addr; - __u16 mac_rx_buffer; - __u8 streamer_laa[6]; -}; - -struct streamer_adapter_addr_table { - - __u8 node_addr[6]; - __u8 reserved[4]; - __u8 func_addr[4]; -}; - -struct streamer_parameters_table { - - __u8 phys_addr[4]; - __u8 up_node_addr[6]; - __u8 up_phys_addr[4]; - __u8 poll_addr[6]; - __u16 reserved; - __u16 acc_priority; - __u16 auth_source_class; - __u16 att_code; - __u8 source_addr[6]; - __u16 beacon_type; - __u16 major_vector; - __u16 lan_status; - __u16 soft_error_time; - __u16 reserved1; - __u16 local_ring; - __u16 mon_error; - __u16 beacon_transmit; - __u16 beacon_receive; - __u16 frame_correl; - __u8 beacon_naun[6]; - __u32 reserved2; - __u8 beacon_phys[4]; -};
diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c deleted file mode 100644 index 28adcdf..0000000 --- a/drivers/net/tokenring/madgemc.c +++ /dev/null
@@ -1,761 +0,0 @@ -/* - * madgemc.c: Driver for the Madge Smart 16/4 MC16 MCA token ring card. - * - * Written 2000 by Adam Fritzler - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * This driver module supports the following cards: - * - Madge Smart 16/4 Ringnode MC16 - * - Madge Smart 16/4 Ringnode MC32 (??) - * - * Maintainer(s): - * AF Adam Fritzler - * - * Modification History: - * 16-Jan-00 AF Created - * - */ -static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n"; - -#include <linux/module.h> -#include <linux/mca.h> -#include <linux/slab.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/netdevice.h> -#include <linux/trdevice.h> - -#include <asm/io.h> -#include <asm/irq.h> - -#include "tms380tr.h" -#include "madgemc.h" /* Madge-specific constants */ - -#define MADGEMC_IO_EXTENT 32 -#define MADGEMC_SIF_OFFSET 0x08 - -struct card_info { - /* - * These are read from the BIA ROM. - */ - unsigned int manid; - unsigned int cardtype; - unsigned int cardrev; - unsigned int ramsize; - - /* - * These are read from the MCA POS registers. - */ - unsigned int burstmode:2; - unsigned int fairness:1; /* 0 = Fair, 1 = Unfair */ - unsigned int arblevel:4; - unsigned int ringspeed:2; /* 0 = 4mb, 1 = 16, 2 = Auto/none */ - unsigned int cabletype:1; /* 0 = RJ45, 1 = DB9 */ -}; - -static int madgemc_open(struct net_device *dev); -static int madgemc_close(struct net_device *dev); -static int madgemc_chipset_init(struct net_device *dev); -static void madgemc_read_rom(struct net_device *dev, struct card_info *card); -static unsigned short madgemc_setnselout_pins(struct net_device *dev); -static void madgemc_setcabletype(struct net_device *dev, int type); - -static int madgemc_mcaproc(char *buf, int slot, void *d); - -static void madgemc_setregpage(struct net_device *dev, int page); -static void madgemc_setsifsel(struct net_device *dev, int val); -static void madgemc_setint(struct net_device *dev, int val); - -static irqreturn_t madgemc_interrupt(int irq, void *dev_id); - -/* - * These work around paging, however they don't guarantee you're on the - * right page. - */ -#define SIFREADB(reg) (inb(dev->base_addr + ((reg<0x8)?reg:reg-0x8))) -#define SIFWRITEB(val, reg) (outb(val, dev->base_addr + ((reg<0x8)?reg:reg-0x8))) -#define SIFREADW(reg) (inw(dev->base_addr + ((reg<0x8)?reg:reg-0x8))) -#define SIFWRITEW(val, reg) (outw(val, dev->base_addr + ((reg<0x8)?reg:reg-0x8))) - -/* - * Read a byte-length value from the register. - */ -static unsigned short madgemc_sifreadb(struct net_device *dev, unsigned short reg) -{ - unsigned short ret; - if (reg<0x8) - ret = SIFREADB(reg); - else { - madgemc_setregpage(dev, 1); - ret = SIFREADB(reg); - madgemc_setregpage(dev, 0); - } - return ret; -} - -/* - * Write a byte-length value to a register. - */ -static void madgemc_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg) -{ - if (reg<0x8) - SIFWRITEB(val, reg); - else { - madgemc_setregpage(dev, 1); - SIFWRITEB(val, reg); - madgemc_setregpage(dev, 0); - } -} - -/* - * Read a word-length value from a register - */ -static unsigned short madgemc_sifreadw(struct net_device *dev, unsigned short reg) -{ - unsigned short ret; - if (reg<0x8) - ret = SIFREADW(reg); - else { - madgemc_setregpage(dev, 1); - ret = SIFREADW(reg); - madgemc_setregpage(dev, 0); - } - return ret; -} - -/* - * Write a word-length value to a register. - */ -static void madgemc_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg) -{ - if (reg<0x8) - SIFWRITEW(val, reg); - else { - madgemc_setregpage(dev, 1); - SIFWRITEW(val, reg); - madgemc_setregpage(dev, 0); - } -} - -static struct net_device_ops madgemc_netdev_ops __read_mostly; - -static int __devinit madgemc_probe(struct device *device) -{ - static int versionprinted; - struct net_device *dev; - struct net_local *tp; - struct card_info *card; - struct mca_device *mdev = to_mca_device(device); - int ret = 0; - - if (versionprinted++ == 0) - printk("%s", version); - - if(mca_device_claimed(mdev)) - return -EBUSY; - mca_device_set_claim(mdev, 1); - - dev = alloc_trdev(sizeof(struct net_local)); - if (!dev) { - printk("madgemc: unable to allocate dev space\n"); - mca_device_set_claim(mdev, 0); - ret = -ENOMEM; - goto getout; - } - - dev->netdev_ops = &madgemc_netdev_ops; - - card = kmalloc(sizeof(struct card_info), GFP_KERNEL); - if (card==NULL) { - ret = -ENOMEM; - goto getout1; - } - - /* - * Parse configuration information. This all comes - * directly from the publicly available @002d.ADF. - * Get it from Madge or your local ADF library. - */ - - /* - * Base address - */ - dev->base_addr = 0x0a20 + - ((mdev->pos[2] & MC16_POS2_ADDR2)?0x0400:0) + - ((mdev->pos[0] & MC16_POS0_ADDR1)?0x1000:0) + - ((mdev->pos[3] & MC16_POS3_ADDR3)?0x2000:0); - - /* - * Interrupt line - */ - switch(mdev->pos[0] >> 6) { /* upper two bits */ - case 0x1: dev->irq = 3; break; - case 0x2: dev->irq = 9; break; /* IRQ 2 = IRQ 9 */ - case 0x3: dev->irq = 10; break; - default: dev->irq = 0; break; - } - - if (dev->irq == 0) { - printk("%s: invalid IRQ\n", dev->name); - ret = -EBUSY; - goto getout2; - } - - if (!request_region(dev->base_addr, MADGEMC_IO_EXTENT, - "madgemc")) { - printk(KERN_INFO "madgemc: unable to setup Smart MC in slot %d because of I/O base conflict at 0x%04lx\n", mdev->slot, dev->base_addr); - dev->base_addr += MADGEMC_SIF_OFFSET; - ret = -EBUSY; - goto getout2; - } - dev->base_addr += MADGEMC_SIF_OFFSET; - - /* - * Arbitration Level - */ - card->arblevel = ((mdev->pos[0] >> 1) & 0x7) + 8; - - /* - * Burst mode and Fairness - */ - card->burstmode = ((mdev->pos[2] >> 6) & 0x3); - card->fairness = ((mdev->pos[2] >> 4) & 0x1); - - /* - * Ring Speed - */ - if ((mdev->pos[1] >> 2)&0x1) - card->ringspeed = 2; /* not selected */ - else if ((mdev->pos[2] >> 5) & 0x1) - card->ringspeed = 1; /* 16Mb */ - else - card->ringspeed = 0; /* 4Mb */ - - /* - * Cable type - */ - if ((mdev->pos[1] >> 6)&0x1) - card->cabletype = 1; /* STP/DB9 */ - else - card->cabletype = 0; /* UTP/RJ-45 */ - - - /* - * ROM Info. This requires us to actually twiddle - * bits on the card, so we must ensure above that - * the base address is free of conflict (request_region above). - */ - madgemc_read_rom(dev, card); - - if (card->manid != 0x4d) { /* something went wrong */ - printk(KERN_INFO "%s: Madge MC ROM read failed (unknown manufacturer ID %02x)\n", dev->name, card->manid); - goto getout3; - } - - if ((card->cardtype != 0x08) && (card->cardtype != 0x0d)) { - printk(KERN_INFO "%s: Madge MC ROM read failed (unknown card ID %02x)\n", dev->name, card->cardtype); - ret = -EIO; - goto getout3; - } - - /* All cards except Rev 0 and 1 MC16's have 256kb of RAM */ - if ((card->cardtype == 0x08) && (card->cardrev <= 0x01)) - card->ramsize = 128; - else - card->ramsize = 256; - - printk("%s: %s Rev %d at 0x%04lx IRQ %d\n", - dev->name, - (card->cardtype == 0x08)?MADGEMC16_CARDNAME: - MADGEMC32_CARDNAME, card->cardrev, - dev->base_addr, dev->irq); - - if (card->cardtype == 0x0d) - printk("%s: Warning: MC32 support is experimental and highly untested\n", dev->name); - - if (card->ringspeed==2) { /* Unknown */ - printk("%s: Warning: Ring speed not set in POS -- Please run the reference disk and set it!\n", dev->name); - card->ringspeed = 1; /* default to 16mb */ - } - - printk("%s: RAM Size: %dKB\n", dev->name, card->ramsize); - - printk("%s: Ring Speed: %dMb/sec on %s\n", dev->name, - (card->ringspeed)?16:4, - card->cabletype?"STP/DB9":"UTP/RJ-45"); - printk("%s: Arbitration Level: %d\n", dev->name, - card->arblevel); - - printk("%s: Burst Mode: ", dev->name); - switch(card->burstmode) { - case 0: printk("Cycle steal"); break; - case 1: printk("Limited burst"); break; - case 2: printk("Delayed release"); break; - case 3: printk("Immediate release"); break; - } - printk(" (%s)\n", (card->fairness)?"Unfair":"Fair"); - - - /* - * Enable SIF before we assign the interrupt handler, - * just in case we get spurious interrupts that need - * handling. - */ - outb(0, dev->base_addr + MC_CONTROL_REG0); /* sanity */ - madgemc_setsifsel(dev, 1); - if (request_irq(dev->irq, madgemc_interrupt, IRQF_SHARED, - "madgemc", dev)) { - ret = -EBUSY; - goto getout3; - } - - madgemc_chipset_init(dev); /* enables interrupts! */ - madgemc_setcabletype(dev, card->cabletype); - - /* Setup MCA structures */ - mca_device_set_name(mdev, (card->cardtype == 0x08)?MADGEMC16_CARDNAME:MADGEMC32_CARDNAME); - mca_set_adapter_procfn(mdev->slot, madgemc_mcaproc, dev); - - printk("%s: Ring Station Address: %pM\n", - dev->name, dev->dev_addr); - - if (tmsdev_init(dev, device)) { - printk("%s: unable to get memory for dev->priv.\n", - dev->name); - ret = -ENOMEM; - goto getout4; - } - tp = netdev_priv(dev); - - /* - * The MC16 is physically a 32bit card. However, Madge - * insists on calling it 16bit, so I'll assume here that - * they know what they're talking about. Cut off DMA - * at 16mb. - */ - tp->setnselout = madgemc_setnselout_pins; - tp->sifwriteb = madgemc_sifwriteb; - tp->sifreadb = madgemc_sifreadb; - tp->sifwritew = madgemc_sifwritew; - tp->sifreadw = madgemc_sifreadw; - tp->DataRate = (card->ringspeed)?SPEED_16:SPEED_4; - - memcpy(tp->ProductID, "Madge MCA 16/4 ", PROD_ID_SIZE + 1); - - tp->tmspriv = card; - dev_set_drvdata(device, dev); - - if (register_netdev(dev) == 0) - return 0; - - dev_set_drvdata(device, NULL); - ret = -ENOMEM; -getout4: - free_irq(dev->irq, dev); -getout3: - release_region(dev->base_addr-MADGEMC_SIF_OFFSET, - MADGEMC_IO_EXTENT); -getout2: - kfree(card); -getout1: - free_netdev(dev); -getout: - mca_device_set_claim(mdev, 0); - return ret; -} - -/* - * Handle interrupts generated by the card - * - * The MicroChannel Madge cards need slightly more handling - * after an interrupt than other TMS380 cards do. - * - * First we must make sure it was this card that generated the - * interrupt (since interrupt sharing is allowed). Then, - * because we're using level-triggered interrupts (as is - * standard on MCA), we must toggle the interrupt line - * on the card in order to claim and acknowledge the interrupt. - * Once that is done, the interrupt should be handlable in - * the normal tms380tr_interrupt() routine. - * - * There's two ways we can check to see if the interrupt is ours, - * both with their own disadvantages... - * - * 1) Read in the SIFSTS register from the TMS controller. This - * is guaranteed to be accurate, however, there's a fairly - * large performance penalty for doing so: the Madge chips - * must request the register from the Eagle, the Eagle must - * read them from its internal bus, and then take the route - * back out again, for a 16bit read. - * - * 2) Use the MC_CONTROL_REG0_SINTR bit from the Madge ASICs. - * The major disadvantage here is that the accuracy of the - * bit is in question. However, it cuts out the extra read - * cycles it takes to read the Eagle's SIF, as its only an - * 8bit read, and theoretically the Madge bit is directly - * connected to the interrupt latch coming out of the Eagle - * hardware (that statement is not verified). - * - * I can't determine which of these methods has the best win. For now, - * we make a compromise. Use the Madge way for the first interrupt, - * which should be the fast-path, and then once we hit the first - * interrupt, keep on trying using the SIF method until we've - * exhausted all contiguous interrupts. - * - */ -static irqreturn_t madgemc_interrupt(int irq, void *dev_id) -{ - int pending,reg1; - struct net_device *dev; - - if (!dev_id) { - printk("madgemc_interrupt: was not passed a dev_id!\n"); - return IRQ_NONE; - } - - dev = dev_id; - - /* Make sure its really us. -- the Madge way */ - pending = inb(dev->base_addr + MC_CONTROL_REG0); - if (!(pending & MC_CONTROL_REG0_SINTR)) - return IRQ_NONE; /* not our interrupt */ - - /* - * Since we're level-triggered, we may miss the rising edge - * of the next interrupt while we're off handling this one, - * so keep checking until the SIF verifies that it has nothing - * left for us to do. - */ - pending = STS_SYSTEM_IRQ; - do { - if (pending & STS_SYSTEM_IRQ) { - - /* Toggle the interrupt to reset the latch on card */ - reg1 = inb(dev->base_addr + MC_CONTROL_REG1); - outb(reg1 ^ MC_CONTROL_REG1_SINTEN, - dev->base_addr + MC_CONTROL_REG1); - outb(reg1, dev->base_addr + MC_CONTROL_REG1); - - /* Continue handling as normal */ - tms380tr_interrupt(irq, dev_id); - - pending = SIFREADW(SIFSTS); /* restart - the SIF way */ - - } else - return IRQ_HANDLED; - } while (1); - - return IRQ_HANDLED; /* not reachable */ -} - -/* - * Set the card to the preferred ring speed. - * - * Unlike newer cards, the MC16/32 have their speed selection - * circuit connected to the Madge ASICs and not to the TMS380 - * NSELOUT pins. Set the ASIC bits correctly here, and return - * zero to leave the TMS NSELOUT bits unaffected. - * - */ -static unsigned short madgemc_setnselout_pins(struct net_device *dev) -{ - unsigned char reg1; - struct net_local *tp = netdev_priv(dev); - - reg1 = inb(dev->base_addr + MC_CONTROL_REG1); - - if(tp->DataRate == SPEED_16) - reg1 |= MC_CONTROL_REG1_SPEED_SEL; /* add for 16mb */ - else if (reg1 & MC_CONTROL_REG1_SPEED_SEL) - reg1 ^= MC_CONTROL_REG1_SPEED_SEL; /* remove for 4mb */ - outb(reg1, dev->base_addr + MC_CONTROL_REG1); - - return 0; /* no change */ -} - -/* - * Set the register page. This equates to the SRSX line - * on the TMS380Cx6. - * - * Register selection is normally done via three contiguous - * bits. However, some boards (such as the MC16/32) use only - * two bits, plus a separate bit in the glue chip. This - * sets the SRSX bit (the top bit). See page 4-17 in the - * Yellow Book for which registers are affected. - * - */ -static void madgemc_setregpage(struct net_device *dev, int page) -{ - static int reg1; - - reg1 = inb(dev->base_addr + MC_CONTROL_REG1); - if ((page == 0) && (reg1 & MC_CONTROL_REG1_SRSX)) { - outb(reg1 ^ MC_CONTROL_REG1_SRSX, - dev->base_addr + MC_CONTROL_REG1); - } - else if (page == 1) { - outb(reg1 | MC_CONTROL_REG1_SRSX, - dev->base_addr + MC_CONTROL_REG1); - } - reg1 = inb(dev->base_addr + MC_CONTROL_REG1); -} - -/* - * The SIF registers are not mapped into register space by default - * Set this to 1 to map them, 0 to map the BIA ROM. - * - */ -static void madgemc_setsifsel(struct net_device *dev, int val) -{ - unsigned int reg0; - - reg0 = inb(dev->base_addr + MC_CONTROL_REG0); - if ((val == 0) && (reg0 & MC_CONTROL_REG0_SIFSEL)) { - outb(reg0 ^ MC_CONTROL_REG0_SIFSEL, - dev->base_addr + MC_CONTROL_REG0); - } else if (val == 1) { - outb(reg0 | MC_CONTROL_REG0_SIFSEL, - dev->base_addr + MC_CONTROL_REG0); - } - reg0 = inb(dev->base_addr + MC_CONTROL_REG0); -} - -/* - * Enable SIF interrupts - * - * This does not enable interrupts in the SIF, but rather - * enables SIF interrupts to be passed onto the host. - * - */ -static void madgemc_setint(struct net_device *dev, int val) -{ - unsigned int reg1; - - reg1 = inb(dev->base_addr + MC_CONTROL_REG1); - if ((val == 0) && (reg1 & MC_CONTROL_REG1_SINTEN)) { - outb(reg1 ^ MC_CONTROL_REG1_SINTEN, - dev->base_addr + MC_CONTROL_REG1); - } else if (val == 1) { - outb(reg1 | MC_CONTROL_REG1_SINTEN, - dev->base_addr + MC_CONTROL_REG1); - } -} - -/* - * Cable type is set via control register 7. Bit zero high - * for UTP, low for STP. - */ -static void madgemc_setcabletype(struct net_device *dev, int type) -{ - outb((type==0)?MC_CONTROL_REG7_CABLEUTP:MC_CONTROL_REG7_CABLESTP, - dev->base_addr + MC_CONTROL_REG7); -} - -/* - * Enable the functions of the Madge chipset needed for - * full working order. - */ -static int madgemc_chipset_init(struct net_device *dev) -{ - outb(0, dev->base_addr + MC_CONTROL_REG1); /* pull SRESET low */ - tms380tr_wait(100); /* wait for card to reset */ - - /* bring back into normal operating mode */ - outb(MC_CONTROL_REG1_NSRESET, dev->base_addr + MC_CONTROL_REG1); - - /* map SIF registers */ - madgemc_setsifsel(dev, 1); - - /* enable SIF interrupts */ - madgemc_setint(dev, 1); - - return 0; -} - -/* - * Disable the board, and put back into power-up state. - */ -static void madgemc_chipset_close(struct net_device *dev) -{ - /* disable interrupts */ - madgemc_setint(dev, 0); - /* unmap SIF registers */ - madgemc_setsifsel(dev, 0); -} - -/* - * Read the card type (MC16 or MC32) from the card. - * - * The configuration registers are stored in two separate - * pages. Pages are flipped by clearing bit 3 of CONTROL_REG0 (PAGE) - * for page zero, or setting bit 3 for page one. - * - * Page zero contains the following data: - * Byte 0: Manufacturer ID (0x4D -- ASCII "M") - * Byte 1: Card type: - * 0x08 for MC16 - * 0x0D for MC32 - * Byte 2: Card revision - * Byte 3: Mirror of POS config register 0 - * Byte 4: Mirror of POS 1 - * Byte 5: Mirror of POS 2 - * - * Page one contains the following data: - * Byte 0: Unused - * Byte 1-6: BIA, MSB to LSB. - * - * Note that to read the BIA, we must unmap the SIF registers - * by clearing bit 2 of CONTROL_REG0 (SIFSEL), as the data - * will reside in the same logical location. For this reason, - * _never_ read the BIA while the Eagle processor is running! - * The SIF will be completely inaccessible until the BIA operation - * is complete. - * - */ -static void madgemc_read_rom(struct net_device *dev, struct card_info *card) -{ - unsigned long ioaddr; - unsigned char reg0, reg1, tmpreg0, i; - - ioaddr = dev->base_addr; - - reg0 = inb(ioaddr + MC_CONTROL_REG0); - reg1 = inb(ioaddr + MC_CONTROL_REG1); - - /* Switch to page zero and unmap SIF */ - tmpreg0 = reg0 & ~(MC_CONTROL_REG0_PAGE + MC_CONTROL_REG0_SIFSEL); - outb(tmpreg0, ioaddr + MC_CONTROL_REG0); - - card->manid = inb(ioaddr + MC_ROM_MANUFACTURERID); - card->cardtype = inb(ioaddr + MC_ROM_ADAPTERID); - card->cardrev = inb(ioaddr + MC_ROM_REVISION); - - /* Switch to rom page one */ - outb(tmpreg0 | MC_CONTROL_REG0_PAGE, ioaddr + MC_CONTROL_REG0); - - /* Read BIA */ - dev->addr_len = 6; - for (i = 0; i < 6; i++) - dev->dev_addr[i] = inb(ioaddr + MC_ROM_BIA_START + i); - - /* Restore original register values */ - outb(reg0, ioaddr + MC_CONTROL_REG0); - outb(reg1, ioaddr + MC_CONTROL_REG1); -} - -static int madgemc_open(struct net_device *dev) -{ - /* - * Go ahead and reinitialize the chipset again, just to - * make sure we didn't get left in a bad state. - */ - madgemc_chipset_init(dev); - tms380tr_open(dev); - return 0; -} - -static int madgemc_close(struct net_device *dev) -{ - tms380tr_close(dev); - madgemc_chipset_close(dev); - return 0; -} - -/* - * Give some details available from /proc/mca/slotX - */ -static int madgemc_mcaproc(char *buf, int slot, void *d) -{ - struct net_device *dev = (struct net_device *)d; - struct net_local *tp = netdev_priv(dev); - struct card_info *curcard = tp->tmspriv; - int len = 0; - - len += sprintf(buf+len, "-------\n"); - if (curcard) { - len += sprintf(buf+len, "Card Revision: %d\n", curcard->cardrev); - len += sprintf(buf+len, "RAM Size: %dkb\n", curcard->ramsize); - len += sprintf(buf+len, "Cable type: %s\n", (curcard->cabletype)?"STP/DB9":"UTP/RJ-45"); - len += sprintf(buf+len, "Configured ring speed: %dMb/sec\n", (curcard->ringspeed)?16:4); - len += sprintf(buf+len, "Running ring speed: %dMb/sec\n", (tp->DataRate==SPEED_16)?16:4); - len += sprintf(buf+len, "Device: %s\n", dev->name); - len += sprintf(buf+len, "IO Port: 0x%04lx\n", dev->base_addr); - len += sprintf(buf+len, "IRQ: %d\n", dev->irq); - len += sprintf(buf+len, "Arbitration Level: %d\n", curcard->arblevel); - len += sprintf(buf+len, "Burst Mode: "); - switch(curcard->burstmode) { - case 0: len += sprintf(buf+len, "Cycle steal"); break; - case 1: len += sprintf(buf+len, "Limited burst"); break; - case 2: len += sprintf(buf+len, "Delayed release"); break; - case 3: len += sprintf(buf+len, "Immediate release"); break; - } - len += sprintf(buf+len, " (%s)\n", (curcard->fairness)?"Unfair":"Fair"); - - len += sprintf(buf+len, "Ring Station Address: %pM\n", - dev->dev_addr); - } else - len += sprintf(buf+len, "Card not configured\n"); - - return len; -} - -static int __devexit madgemc_remove(struct device *device) -{ - struct net_device *dev = dev_get_drvdata(device); - struct net_local *tp; - struct card_info *card; - - BUG_ON(!dev); - - tp = netdev_priv(dev); - card = tp->tmspriv; - kfree(card); - tp->tmspriv = NULL; - - unregister_netdev(dev); - release_region(dev->base_addr-MADGEMC_SIF_OFFSET, MADGEMC_IO_EXTENT); - free_irq(dev->irq, dev); - tmsdev_term(dev); - free_netdev(dev); - dev_set_drvdata(device, NULL); - - return 0; -} - -static short madgemc_adapter_ids[] __initdata = { - 0x002d, - 0x0000 -}; - -static struct mca_driver madgemc_driver = { - .id_table = madgemc_adapter_ids, - .driver = { - .name = "madgemc", - .bus = &mca_bus_type, - .probe = madgemc_probe, - .remove = __devexit_p(madgemc_remove), - }, -}; - -static int __init madgemc_init (void) -{ - madgemc_netdev_ops = tms380tr_netdev_ops; - madgemc_netdev_ops.ndo_open = madgemc_open; - madgemc_netdev_ops.ndo_stop = madgemc_close; - - return mca_register_driver (&madgemc_driver); -} - -static void __exit madgemc_exit (void) -{ - mca_unregister_driver (&madgemc_driver); -} - -module_init(madgemc_init); -module_exit(madgemc_exit); - -MODULE_LICENSE("GPL"); -
diff --git a/drivers/net/tokenring/madgemc.h b/drivers/net/tokenring/madgemc.h deleted file mode 100644 index fe88e27..0000000 --- a/drivers/net/tokenring/madgemc.h +++ /dev/null
@@ -1,70 +0,0 @@ -/* - * madgemc.h: Header for the madgemc tms380tr module - * - * Authors: - * - Adam Fritzler - */ - -#ifndef __LINUX_MADGEMC_H -#define __LINUX_MADGEMC_H - -#ifdef __KERNEL__ - -#define MADGEMC16_CARDNAME "Madge Smart 16/4 MC16 Ringnode" -#define MADGEMC32_CARDNAME "Madge Smart 16/4 MC32 Ringnode" - -/* - * Bit definitions for the POS config registers - */ -#define MC16_POS0_ADDR1 0x20 -#define MC16_POS2_ADDR2 0x04 -#define MC16_POS3_ADDR3 0x20 - -#define MC_CONTROL_REG0 ((long)-8) /* 0x00 */ -#define MC_CONTROL_REG1 ((long)-7) /* 0x01 */ -#define MC_ADAPTER_POS_REG0 ((long)-6) /* 0x02 */ -#define MC_ADAPTER_POS_REG1 ((long)-5) /* 0x03 */ -#define MC_ADAPTER_POS_REG2 ((long)-4) /* 0x04 */ -#define MC_ADAPTER_REG5_UNUSED ((long)-3) /* 0x05 */ -#define MC_ADAPTER_REG6_UNUSED ((long)-2) /* 0x06 */ -#define MC_CONTROL_REG7 ((long)-1) /* 0x07 */ - -#define MC_CONTROL_REG0_UNKNOWN1 0x01 -#define MC_CONTROL_REG0_UNKNOWN2 0x02 -#define MC_CONTROL_REG0_SIFSEL 0x04 -#define MC_CONTROL_REG0_PAGE 0x08 -#define MC_CONTROL_REG0_TESTINTERRUPT 0x10 -#define MC_CONTROL_REG0_UNKNOWN20 0x20 -#define MC_CONTROL_REG0_SINTR 0x40 -#define MC_CONTROL_REG0_UNKNOWN80 0x80 - -#define MC_CONTROL_REG1_SINTEN 0x01 -#define MC_CONTROL_REG1_BITOFDEATH 0x02 -#define MC_CONTROL_REG1_NSRESET 0x04 -#define MC_CONTROL_REG1_UNKNOWN8 0x08 -#define MC_CONTROL_REG1_UNKNOWN10 0x10 -#define MC_CONTROL_REG1_UNKNOWN20 0x20 -#define MC_CONTROL_REG1_SRSX 0x40 -#define MC_CONTROL_REG1_SPEED_SEL 0x80 - -#define MC_CONTROL_REG7_CABLESTP 0x00 -#define MC_CONTROL_REG7_CABLEUTP 0x01 - -/* - * ROM Page Zero - */ -#define MC_ROM_MANUFACTURERID 0x00 -#define MC_ROM_ADAPTERID 0x01 -#define MC_ROM_REVISION 0x02 -#define MC_ROM_CONFIG0 0x03 -#define MC_ROM_CONFIG1 0x04 -#define MC_ROM_CONFIG2 0x05 - -/* - * ROM Page One - */ -#define MC_ROM_UNUSED_BYTE 0x00 -#define MC_ROM_BIA_START 0x01 - -#endif /* __KERNEL__ */ -#endif /* __LINUX_MADGEMC_H */
diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c deleted file mode 100644 index 4d45fe8..0000000 --- a/drivers/net/tokenring/olympic.c +++ /dev/null
@@ -1,1737 +0,0 @@ -/* - * olympic.c (c) 1999 Peter De Schrijver All Rights Reserved - * 1999/2000 Mike Phillips (mikep@linuxtr.net) - * - * Linux driver for IBM PCI tokenring cards based on the Pit/Pit-Phy/Olympic - * chipset. - * - * Base Driver Skeleton: - * Written 1993-94 by Donald Becker. - * - * Copyright 1993 United States Government as represented by the - * Director, National Security Agency. - * - * Thanks to Erik De Cock, Adrian Bridgett and Frank Fiene for their - * assistance and perserverance with the testing of this driver. - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * 4/27/99 - Alpha Release 0.1.0 - * First release to the public - * - * 6/8/99 - Official Release 0.2.0 - * Merged into the kernel code - * 8/18/99 - Updated driver for 2.3.13 kernel to use new pci - * resource. Driver also reports the card name returned by - * the pci resource. - * 1/11/00 - Added spinlocks for smp - * 2/23/00 - Updated to dev_kfree_irq - * 3/10/00 - Fixed FDX enable which triggered other bugs also - * squashed. - * 5/20/00 - Changes to handle Olympic on LinuxPPC. Endian changes. - * The odd thing about the changes is that the fix for - * endian issues with the big-endian data in the arb, asb... - * was to always swab() the bytes, no matter what CPU. - * That's because the read[wl]() functions always swap the - * bytes on the way in on PPC. - * Fixing the hardware descriptors was another matter, - * because they weren't going through read[wl](), there all - * the results had to be in memory in le32 values. kdaaker - * - * 12/23/00 - Added minimal Cardbus support (Thanks Donald). - * - * 03/09/01 - Add new pci api, dev_base_lock, general clean up. - * - * 03/27/01 - Add new dma pci (Thanks to Kyle Lucke) and alloc_trdev - * Change proc_fs behaviour, now one entry per adapter. - * - * 04/09/01 - Couple of bug fixes to the dma unmaps and ejecting the - * adapter when live does not take the system down with it. - * - * 06/02/01 - Clean up, copy skb for small packets - * - * 06/22/01 - Add EISR error handling routines - * - * 07/19/01 - Improve bad LAA reporting, strip out freemem - * into a separate function, its called from 3 - * different places now. - * 02/09/02 - Replaced sleep_on. - * 03/01/02 - Replace access to several registers from 32 bit to - * 16 bit. Fixes alignment errors on PPC 64 bit machines. - * Thanks to Al Trautman for this one. - * 03/10/02 - Fix BUG in arb_cmd. Bug was there all along but was - * silently ignored until the error checking code - * went into version 1.0.0 - * 06/04/02 - Add correct start up sequence for the cardbus adapters. - * Required for strict compliance with pci power mgmt specs. - * To Do: - * - * Wake on lan - * - * If Problems do Occur - * Most problems can be rectified by either closing and opening the interface - * (ifconfig down and up) or rmmod and insmod'ing the driver (a bit difficult - * if compiled into the kernel). - */ - -/* Change OLYMPIC_DEBUG to 1 to get verbose, and I mean really verbose, messages */ - -#define OLYMPIC_DEBUG 0 - - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/timer.h> -#include <linux/in.h> -#include <linux/ioport.h> -#include <linux/seq_file.h> -#include <linux/string.h> -#include <linux/proc_fs.h> -#include <linux/ptrace.h> -#include <linux/skbuff.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/trdevice.h> -#include <linux/stddef.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/spinlock.h> -#include <linux/bitops.h> -#include <linux/jiffies.h> - -#include <net/checksum.h> -#include <net/net_namespace.h> - -#include <asm/io.h> - -#include "olympic.h" - -/* I've got to put some intelligence into the version number so that Peter and I know - * which version of the code somebody has got. - * Version Number = a.b.c.d where a.b.c is the level of code and d is the latest author. - * So 0.0.1.pds = Peter, 0.0.1.mlp = Mike - * - * Official releases will only have an a.b.c version number format. - */ - -static char version[] = -"Olympic.c v1.0.5 6/04/02 - Peter De Schrijver & Mike Phillips" ; - -static char *open_maj_error[] = {"No error", "Lobe Media Test", "Physical Insertion", - "Address Verification", "Neighbor Notification (Ring Poll)", - "Request Parameters","FDX Registration Request", - "FDX Duplicate Address Check", "Station registration Query Wait", - "Unknown stage"}; - -static char *open_min_error[] = {"No error", "Function Failure", "Signal Lost", "Wire Fault", - "Ring Speed Mismatch", "Timeout","Ring Failure","Ring Beaconing", - "Duplicate Node Address","Request Parameters","Remove Received", - "Reserved", "Reserved", "No Monitor Detected for RPL", - "Monitor Contention failer for RPL", "FDX Protocol Error"}; - -/* Module parameters */ - -MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ; -MODULE_DESCRIPTION("Olympic PCI/Cardbus Chipset Driver") ; - -/* Ring Speed 0,4,16,100 - * 0 = Autosense - * 4,16 = Selected speed only, no autosense - * This allows the card to be the first on the ring - * and become the active monitor. - * 100 = Nothing at present, 100mbps is autodetected - * if FDX is turned on. May be implemented in the future to - * fail if 100mpbs is not detected. - * - * WARNING: Some hubs will allow you to insert - * at the wrong speed - */ - -static int ringspeed[OLYMPIC_MAX_ADAPTERS] = {0,} ; -module_param_array(ringspeed, int, NULL, 0); - -/* Packet buffer size */ - -static int pkt_buf_sz[OLYMPIC_MAX_ADAPTERS] = {0,} ; -module_param_array(pkt_buf_sz, int, NULL, 0) ; - -/* Message Level */ - -static int message_level[OLYMPIC_MAX_ADAPTERS] = {0,} ; -module_param_array(message_level, int, NULL, 0) ; - -/* Change network_monitor to receive mac frames through the arb channel. - * Will also create a /proc/net/olympic_tr%d entry, where %d is the tr - * device, i.e. tr0, tr1 etc. - * Intended to be used to create a ring-error reporting network module - * i.e. it will give you the source address of beaconers on the ring - */ -static int network_monitor[OLYMPIC_MAX_ADAPTERS] = {0,}; -module_param_array(network_monitor, int, NULL, 0); - -static DEFINE_PCI_DEVICE_TABLE(olympic_pci_tbl) = { - {PCI_VENDOR_ID_IBM,PCI_DEVICE_ID_IBM_TR_WAKE,PCI_ANY_ID,PCI_ANY_ID,}, - { } /* Terminating Entry */ -}; -MODULE_DEVICE_TABLE(pci,olympic_pci_tbl) ; - - -static int olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -static int olympic_init(struct net_device *dev); -static int olympic_open(struct net_device *dev); -static netdev_tx_t olympic_xmit(struct sk_buff *skb, - struct net_device *dev); -static int olympic_close(struct net_device *dev); -static void olympic_set_rx_mode(struct net_device *dev); -static void olympic_freemem(struct net_device *dev) ; -static irqreturn_t olympic_interrupt(int irq, void *dev_id); -static int olympic_set_mac_address(struct net_device *dev, void *addr) ; -static void olympic_arb_cmd(struct net_device *dev); -static int olympic_change_mtu(struct net_device *dev, int mtu); -static void olympic_srb_bh(struct net_device *dev) ; -static void olympic_asb_bh(struct net_device *dev) ; -static const struct file_operations olympic_proc_ops; - -static const struct net_device_ops olympic_netdev_ops = { - .ndo_open = olympic_open, - .ndo_stop = olympic_close, - .ndo_start_xmit = olympic_xmit, - .ndo_change_mtu = olympic_change_mtu, - .ndo_set_rx_mode = olympic_set_rx_mode, - .ndo_set_mac_address = olympic_set_mac_address, -}; - -static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - struct net_device *dev ; - struct olympic_private *olympic_priv; - static int card_no = -1 ; - int i ; - - card_no++ ; - - if ((i = pci_enable_device(pdev))) { - return i ; - } - - pci_set_master(pdev); - - if ((i = pci_request_regions(pdev,"olympic"))) { - goto op_disable_dev; - } - - dev = alloc_trdev(sizeof(struct olympic_private)) ; - if (!dev) { - i = -ENOMEM; - goto op_release_dev; - } - - olympic_priv = netdev_priv(dev) ; - - spin_lock_init(&olympic_priv->olympic_lock) ; - - init_waitqueue_head(&olympic_priv->srb_wait); - init_waitqueue_head(&olympic_priv->trb_wait); -#if OLYMPIC_DEBUG - printk(KERN_INFO "pci_device: %p, dev:%p, dev->priv: %p\n", pdev, dev, netdev_priv(dev)); -#endif - dev->irq=pdev->irq; - dev->base_addr=pci_resource_start(pdev, 0); - olympic_priv->olympic_card_name = pci_name(pdev); - olympic_priv->pdev = pdev; - olympic_priv->olympic_mmio = ioremap(pci_resource_start(pdev,1),256); - olympic_priv->olympic_lap = ioremap(pci_resource_start(pdev,2),2048); - if (!olympic_priv->olympic_mmio || !olympic_priv->olympic_lap) { - goto op_free_iomap; - } - - if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) ) - olympic_priv->pkt_buf_sz = PKT_BUF_SZ ; - else - olympic_priv->pkt_buf_sz = pkt_buf_sz[card_no] ; - - dev->mtu = olympic_priv->pkt_buf_sz - TR_HLEN ; - olympic_priv->olympic_ring_speed = ringspeed[card_no] ; - olympic_priv->olympic_message_level = message_level[card_no] ; - olympic_priv->olympic_network_monitor = network_monitor[card_no]; - - if ((i = olympic_init(dev))) { - goto op_free_iomap; - } - - dev->netdev_ops = &olympic_netdev_ops; - SET_NETDEV_DEV(dev, &pdev->dev); - - pci_set_drvdata(pdev,dev) ; - register_netdev(dev) ; - printk("Olympic: %s registered as: %s\n",olympic_priv->olympic_card_name,dev->name); - if (olympic_priv->olympic_network_monitor) { /* Must go after register_netdev as we need the device name */ - char proc_name[20] ; - strcpy(proc_name,"olympic_") ; - strcat(proc_name,dev->name) ; - proc_create_data(proc_name, 0, init_net.proc_net, &olympic_proc_ops, dev); - printk("Olympic: Network Monitor information: /proc/%s\n",proc_name); - } - return 0 ; - -op_free_iomap: - if (olympic_priv->olympic_mmio) - iounmap(olympic_priv->olympic_mmio); - if (olympic_priv->olympic_lap) - iounmap(olympic_priv->olympic_lap); - - free_netdev(dev); -op_release_dev: - pci_release_regions(pdev); - -op_disable_dev: - pci_disable_device(pdev); - return i; -} - -static int olympic_init(struct net_device *dev) -{ - struct olympic_private *olympic_priv; - u8 __iomem *olympic_mmio, *init_srb,*adapter_addr; - unsigned long t; - unsigned int uaa_addr; - - olympic_priv=netdev_priv(dev); - olympic_mmio=olympic_priv->olympic_mmio; - - printk("%s\n", version); - printk("%s. I/O at %hx, MMIO at %p, LAP at %p, using irq %d\n", olympic_priv->olympic_card_name, (unsigned int) dev->base_addr,olympic_priv->olympic_mmio, olympic_priv->olympic_lap, dev->irq); - - writel(readl(olympic_mmio+BCTL) | BCTL_SOFTRESET,olympic_mmio+BCTL); - t=jiffies; - while((readl(olympic_mmio+BCTL)) & BCTL_SOFTRESET) { - schedule(); - if(time_after(jiffies, t + 40*HZ)) { - printk(KERN_ERR "IBM PCI tokenring card not responding.\n"); - return -ENODEV; - } - } - - - /* Needed for cardbus */ - if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) { - writel(readl(olympic_priv->olympic_mmio+FERMASK)|FERMASK_INT_BIT, olympic_mmio+FERMASK); - } - -#if OLYMPIC_DEBUG - printk("BCTL: %x\n",readl(olympic_mmio+BCTL)); - printk("GPR: %x\n",readw(olympic_mmio+GPR)); - printk("SISRMASK: %x\n",readl(olympic_mmio+SISR_MASK)); -#endif - /* Aaaahhh, You have got to be real careful setting GPR, the card - holds the previous values from flash memory, including autosense - and ring speed */ - - writel(readl(olympic_mmio+BCTL)|BCTL_MIMREB,olympic_mmio+BCTL); - - if (olympic_priv->olympic_ring_speed == 0) { /* Autosense */ - writew(readw(olympic_mmio+GPR)|GPR_AUTOSENSE,olympic_mmio+GPR); - if (olympic_priv->olympic_message_level) - printk(KERN_INFO "%s: Ringspeed autosense mode on\n",olympic_priv->olympic_card_name); - } else if (olympic_priv->olympic_ring_speed == 16) { - if (olympic_priv->olympic_message_level) - printk(KERN_INFO "%s: Trying to open at 16 Mbps as requested\n", olympic_priv->olympic_card_name); - writew(GPR_16MBPS, olympic_mmio+GPR); - } else if (olympic_priv->olympic_ring_speed == 4) { - if (olympic_priv->olympic_message_level) - printk(KERN_INFO "%s: Trying to open at 4 Mbps as requested\n", olympic_priv->olympic_card_name) ; - writew(0, olympic_mmio+GPR); - } - - writew(readw(olympic_mmio+GPR)|GPR_NEPTUNE_BF,olympic_mmio+GPR); - -#if OLYMPIC_DEBUG - printk("GPR = %x\n",readw(olympic_mmio + GPR) ) ; -#endif - /* Solo has been paused to meet the Cardbus power - * specs if the adapter is cardbus. Check to - * see its been paused and then restart solo. The - * adapter should set the pause bit within 1 second. - */ - - if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) { - t=jiffies; - while (!(readl(olympic_mmio+CLKCTL) & CLKCTL_PAUSE)) { - schedule() ; - if(time_after(jiffies, t + 2*HZ)) { - printk(KERN_ERR "IBM Cardbus tokenring adapter not responsing.\n") ; - return -ENODEV; - } - } - writel(readl(olympic_mmio+CLKCTL) & ~CLKCTL_PAUSE, olympic_mmio+CLKCTL) ; - } - - /* start solo init */ - writel((1<<15),olympic_mmio+SISR_MASK_SUM); - - t=jiffies; - while(!((readl(olympic_mmio+SISR_RR)) & SISR_SRB_REPLY)) { - schedule(); - if(time_after(jiffies, t + 15*HZ)) { - printk(KERN_ERR "IBM PCI tokenring card not responding.\n"); - return -ENODEV; - } - } - - writel(readw(olympic_mmio+LAPWWO),olympic_mmio+LAPA); - -#if OLYMPIC_DEBUG - printk("LAPWWO: %x, LAPA: %x\n",readl(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA)); -#endif - - init_srb=olympic_priv->olympic_lap + ((readw(olympic_mmio+LAPWWO)) & (~0xf800)); - -#if OLYMPIC_DEBUG -{ - int i; - printk("init_srb(%p): ",init_srb); - for(i=0;i<20;i++) - printk("%x ",readb(init_srb+i)); - printk("\n"); -} -#endif - if(readw(init_srb+6)) { - printk(KERN_INFO "tokenring card initialization failed. errorcode : %x\n",readw(init_srb+6)); - return -ENODEV; - } - - if (olympic_priv->olympic_message_level) { - if ( readb(init_srb +2) & 0x40) { - printk(KERN_INFO "Olympic: Adapter is FDX capable.\n") ; - } else { - printk(KERN_INFO "Olympic: Adapter cannot do FDX.\n"); - } - } - - uaa_addr=swab16(readw(init_srb+8)); - -#if OLYMPIC_DEBUG - printk("UAA resides at %x\n",uaa_addr); -#endif - - writel(uaa_addr,olympic_mmio+LAPA); - adapter_addr=olympic_priv->olympic_lap + (uaa_addr & (~0xf800)); - - memcpy_fromio(&dev->dev_addr[0], adapter_addr,6); - -#if OLYMPIC_DEBUG - printk("adapter address: %pM\n", dev->dev_addr); -#endif - - olympic_priv->olympic_addr_table_addr = swab16(readw(init_srb + 12)); - olympic_priv->olympic_parms_addr = swab16(readw(init_srb + 14)); - - return 0; - -} - -static int olympic_open(struct net_device *dev) -{ - struct olympic_private *olympic_priv=netdev_priv(dev); - u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio,*init_srb; - unsigned long flags, t; - int i, open_finished = 1 ; - u8 resp, err; - - DECLARE_WAITQUEUE(wait,current) ; - - olympic_init(dev); - - if (request_irq(dev->irq, olympic_interrupt, IRQF_SHARED , "olympic", - dev)) - return -EAGAIN; - -#if OLYMPIC_DEBUG - printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM)); - printk("pending ints: %x\n",readl(olympic_mmio+SISR_RR)); -#endif - - writel(SISR_MI,olympic_mmio+SISR_MASK_SUM); - - writel(SISR_MI | SISR_SRB_REPLY, olympic_mmio+SISR_MASK); /* more ints later, doesn't stop arb cmd interrupt */ - - writel(LISR_LIE,olympic_mmio+LISR); /* more ints later */ - - /* adapter is closed, so SRB is pointed to by LAPWWO */ - - writel(readw(olympic_mmio+LAPWWO),olympic_mmio+LAPA); - init_srb=olympic_priv->olympic_lap + ((readw(olympic_mmio+LAPWWO)) & (~0xf800)); - -#if OLYMPIC_DEBUG - printk("LAPWWO: %x, LAPA: %x\n",readw(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA)); - printk("SISR Mask = %04x\n", readl(olympic_mmio+SISR_MASK)); - printk("Before the open command\n"); -#endif - do { - memset_io(init_srb,0,SRB_COMMAND_SIZE); - - writeb(SRB_OPEN_ADAPTER,init_srb) ; /* open */ - writeb(OLYMPIC_CLEAR_RET_CODE,init_srb+2); - - /* If Network Monitor, instruct card to copy MAC frames through the ARB */ - if (olympic_priv->olympic_network_monitor) - writew(swab16(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON), init_srb+8); - else - writew(swab16(OPEN_ADAPTER_ENABLE_FDX), init_srb+8); - - /* Test OR of first 3 bytes as its totally possible for - * someone to set the first 2 bytes to be zero, although this - * is an error, the first byte must have bit 6 set to 1 */ - - if (olympic_priv->olympic_laa[0] | olympic_priv->olympic_laa[1] | olympic_priv->olympic_laa[2]) { - writeb(olympic_priv->olympic_laa[0],init_srb+12); - writeb(olympic_priv->olympic_laa[1],init_srb+13); - writeb(olympic_priv->olympic_laa[2],init_srb+14); - writeb(olympic_priv->olympic_laa[3],init_srb+15); - writeb(olympic_priv->olympic_laa[4],init_srb+16); - writeb(olympic_priv->olympic_laa[5],init_srb+17); - memcpy(dev->dev_addr,olympic_priv->olympic_laa,dev->addr_len) ; - } - writeb(1,init_srb+30); - - spin_lock_irqsave(&olympic_priv->olympic_lock,flags); - olympic_priv->srb_queued=1; - - writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM); - spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags); - - t = jiffies ; - - add_wait_queue(&olympic_priv->srb_wait,&wait) ; - set_current_state(TASK_INTERRUPTIBLE) ; - - while(olympic_priv->srb_queued) { - schedule() ; - if(signal_pending(current)) { - printk(KERN_WARNING "%s: Signal received in open.\n", - dev->name); - printk(KERN_WARNING "SISR=%x LISR=%x\n", - readl(olympic_mmio+SISR), - readl(olympic_mmio+LISR)); - olympic_priv->srb_queued=0; - break; - } - if (time_after(jiffies, t + 10*HZ)) { - printk(KERN_WARNING "%s: SRB timed out.\n",dev->name); - olympic_priv->srb_queued=0; - break ; - } - set_current_state(TASK_INTERRUPTIBLE) ; - } - remove_wait_queue(&olympic_priv->srb_wait,&wait) ; - set_current_state(TASK_RUNNING) ; - olympic_priv->srb_queued = 0 ; -#if OLYMPIC_DEBUG - printk("init_srb(%p): ",init_srb); - for(i=0;i<20;i++) - printk("%02x ",readb(init_srb+i)); - printk("\n"); -#endif - - /* If we get the same return response as we set, the interrupt wasn't raised and the open - * timed out. - */ - - switch (resp = readb(init_srb+2)) { - case OLYMPIC_CLEAR_RET_CODE: - printk(KERN_WARNING "%s: Adapter Open time out or error.\n", dev->name) ; - goto out; - case 0: - open_finished = 1; - break; - case 0x07: - if (!olympic_priv->olympic_ring_speed && open_finished) { /* Autosense , first time around */ - printk(KERN_WARNING "%s: Retrying at different ring speed\n", dev->name); - open_finished = 0 ; - continue; - } - - err = readb(init_srb+7); - - if (!olympic_priv->olympic_ring_speed && ((err & 0x0f) == 0x0d)) { - printk(KERN_WARNING "%s: Tried to autosense ring speed with no monitors present\n",dev->name); - printk(KERN_WARNING "%s: Please try again with a specified ring speed\n",dev->name); - } else { - printk(KERN_WARNING "%s: %s - %s\n", dev->name, - open_maj_error[(err & 0xf0) >> 4], - open_min_error[(err & 0x0f)]); - } - goto out; - - case 0x32: - printk(KERN_WARNING "%s: Invalid LAA: %pM\n", - dev->name, olympic_priv->olympic_laa); - goto out; - - default: - printk(KERN_WARNING "%s: Bad OPEN response: %x\n", dev->name, resp); - goto out; - - } - } while (!(open_finished)) ; /* Will only loop if ring speed mismatch re-open attempted && autosense is on */ - - if (readb(init_srb+18) & (1<<3)) - if (olympic_priv->olympic_message_level) - printk(KERN_INFO "%s: Opened in FDX Mode\n",dev->name); - - if (readb(init_srb+18) & (1<<1)) - olympic_priv->olympic_ring_speed = 100 ; - else if (readb(init_srb+18) & 1) - olympic_priv->olympic_ring_speed = 16 ; - else - olympic_priv->olympic_ring_speed = 4 ; - - if (olympic_priv->olympic_message_level) - printk(KERN_INFO "%s: Opened in %d Mbps mode\n",dev->name, olympic_priv->olympic_ring_speed); - - olympic_priv->asb = swab16(readw(init_srb+8)); - olympic_priv->srb = swab16(readw(init_srb+10)); - olympic_priv->arb = swab16(readw(init_srb+12)); - olympic_priv->trb = swab16(readw(init_srb+16)); - - olympic_priv->olympic_receive_options = 0x01 ; - olympic_priv->olympic_copy_all_options = 0 ; - - /* setup rx ring */ - - writel((3<<16),olympic_mmio+BMCTL_RWM); /* Ensure end of frame generated interrupts */ - - writel(BMCTL_RX_DIS|3,olympic_mmio+BMCTL_RWM); /* Yes, this the enables RX channel */ - - for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) { - - struct sk_buff *skb; - - skb=dev_alloc_skb(olympic_priv->pkt_buf_sz); - if(skb == NULL) - break; - - skb->dev = dev; - - olympic_priv->olympic_rx_ring[i].buffer = cpu_to_le32(pci_map_single(olympic_priv->pdev, - skb->data,olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)) ; - olympic_priv->olympic_rx_ring[i].res_length = cpu_to_le32(olympic_priv->pkt_buf_sz); - olympic_priv->rx_ring_skb[i]=skb; - } - - if (i==0) { - printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n",dev->name); - goto out; - } - - olympic_priv->rx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_rx_ring, - sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE); - writel(olympic_priv->rx_ring_dma_addr, olympic_mmio+RXDESCQ); - writel(olympic_priv->rx_ring_dma_addr, olympic_mmio+RXCDA); - writew(i, olympic_mmio+RXDESCQCNT); - - olympic_priv->rx_status_ring_dma_addr = pci_map_single(olympic_priv->pdev, olympic_priv->olympic_rx_status_ring, - sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE); - writel(olympic_priv->rx_status_ring_dma_addr, olympic_mmio+RXSTATQ); - writel(olympic_priv->rx_status_ring_dma_addr, olympic_mmio+RXCSA); - - olympic_priv->rx_ring_last_received = OLYMPIC_RX_RING_SIZE - 1; /* last processed rx status */ - olympic_priv->rx_status_last_received = OLYMPIC_RX_RING_SIZE - 1; - - writew(i, olympic_mmio+RXSTATQCNT); - -#if OLYMPIC_DEBUG - printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ)); - printk("RXCSA: %x, rx_status_ring[0]: %p\n",readl(olympic_mmio+RXCSA),&olympic_priv->olympic_rx_status_ring[0]); - printk(" stat_ring[1]: %p, stat_ring[2]: %p, stat_ring[3]: %p\n", &(olympic_priv->olympic_rx_status_ring[1]), &(olympic_priv->olympic_rx_status_ring[2]), &(olympic_priv->olympic_rx_status_ring[3]) ); - printk(" stat_ring[4]: %p, stat_ring[5]: %p, stat_ring[6]: %p\n", &(olympic_priv->olympic_rx_status_ring[4]), &(olympic_priv->olympic_rx_status_ring[5]), &(olympic_priv->olympic_rx_status_ring[6]) ); - printk(" stat_ring[7]: %p\n", &(olympic_priv->olympic_rx_status_ring[7]) ); - - printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]); - printk("Rx_ring_dma_addr = %08x, rx_status_dma_addr = %08x\n", - olympic_priv->rx_ring_dma_addr,olympic_priv->rx_status_ring_dma_addr) ; -#endif - - writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | i,olympic_mmio+RXENQ); - -#if OLYMPIC_DEBUG - printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ)); - printk("RXCSA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCSA),&olympic_priv->olympic_rx_status_ring[0]); - printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]); -#endif - - writel(SISR_RX_STATUS | SISR_RX_NOBUF,olympic_mmio+SISR_MASK_SUM); - - /* setup tx ring */ - - writel(BMCTL_TX1_DIS,olympic_mmio+BMCTL_RWM); /* Yes, this enables TX channel 1 */ - for(i=0;i<OLYMPIC_TX_RING_SIZE;i++) - olympic_priv->olympic_tx_ring[i].buffer=cpu_to_le32(0xdeadbeef); - - olympic_priv->free_tx_ring_entries=OLYMPIC_TX_RING_SIZE; - olympic_priv->tx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_tx_ring, - sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE,PCI_DMA_TODEVICE) ; - writel(olympic_priv->tx_ring_dma_addr, olympic_mmio+TXDESCQ_1); - writel(olympic_priv->tx_ring_dma_addr, olympic_mmio+TXCDA_1); - writew(OLYMPIC_TX_RING_SIZE, olympic_mmio+TXDESCQCNT_1); - - olympic_priv->tx_status_ring_dma_addr = pci_map_single(olympic_priv->pdev, olympic_priv->olympic_tx_status_ring, - sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE); - writel(olympic_priv->tx_status_ring_dma_addr,olympic_mmio+TXSTATQ_1); - writel(olympic_priv->tx_status_ring_dma_addr,olympic_mmio+TXCSA_1); - writew(OLYMPIC_TX_RING_SIZE,olympic_mmio+TXSTATQCNT_1); - - olympic_priv->tx_ring_free=0; /* next entry in tx ring to use */ - olympic_priv->tx_ring_last_status=OLYMPIC_TX_RING_SIZE-1; /* last processed tx status */ - - writel(0xffffffff, olympic_mmio+EISR_RWM) ; /* clean the eisr */ - writel(0,olympic_mmio+EISR) ; - writel(EISR_MASK_OPTIONS,olympic_mmio+EISR_MASK) ; /* enables most of the TX error interrupts */ - writel(SISR_TX1_EOF | SISR_ADAPTER_CHECK | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_ASB_FREE | SISR_ERR,olympic_mmio+SISR_MASK_SUM); - -#if OLYMPIC_DEBUG - printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM)); - printk("SISR MASK: %x\n",readl(olympic_mmio+SISR_MASK)); -#endif - - if (olympic_priv->olympic_network_monitor) { - u8 __iomem *oat; - u8 __iomem *opt; - u8 addr[6]; - oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr); - opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr); - - for (i = 0; i < 6; i++) - addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+i); - printk("%s: Node Address: %pM\n", dev->name, addr); - printk("%s: Functional Address: %02x:%02x:%02x:%02x\n",dev->name, - readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)), - readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1), - readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2), - readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3)); - - for (i = 0; i < 6; i++) - addr[i] = readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+i); - printk("%s: NAUN Address: %pM\n", dev->name, addr); - } - - netif_start_queue(dev); - return 0; - -out: - free_irq(dev->irq, dev); - return -EIO; -} - -/* - * When we enter the rx routine we do not know how many frames have been - * queued on the rx channel. Therefore we start at the next rx status - * position and travel around the receive ring until we have completed - * all the frames. - * - * This means that we may process the frame before we receive the end - * of frame interrupt. This is why we always test the status instead - * of blindly processing the next frame. - * - * We also remove the last 4 bytes from the packet as well, these are - * just token ring trailer info and upset protocols that don't check - * their own length, i.e. SNA. - * - */ -static void olympic_rx(struct net_device *dev) -{ - struct olympic_private *olympic_priv=netdev_priv(dev); - u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio; - struct olympic_rx_status *rx_status; - struct olympic_rx_desc *rx_desc ; - int rx_ring_last_received,length, buffer_cnt, cpy_length, frag_len; - struct sk_buff *skb, *skb2; - int i; - - rx_status=&(olympic_priv->olympic_rx_status_ring[(olympic_priv->rx_status_last_received + 1) & (OLYMPIC_RX_RING_SIZE - 1)]) ; - - while (rx_status->status_buffercnt) { - u32 l_status_buffercnt; - - olympic_priv->rx_status_last_received++ ; - olympic_priv->rx_status_last_received &= (OLYMPIC_RX_RING_SIZE -1); -#if OLYMPIC_DEBUG - printk("rx status: %x rx len: %x\n", le32_to_cpu(rx_status->status_buffercnt), le32_to_cpu(rx_status->fragmentcnt_framelen)); -#endif - length = le32_to_cpu(rx_status->fragmentcnt_framelen) & 0xffff; - buffer_cnt = le32_to_cpu(rx_status->status_buffercnt) & 0xffff; - i = buffer_cnt ; /* Need buffer_cnt later for rxenq update */ - frag_len = le32_to_cpu(rx_status->fragmentcnt_framelen) >> 16; - -#if OLYMPIC_DEBUG - printk("length: %x, frag_len: %x, buffer_cnt: %x\n", length, frag_len, buffer_cnt); -#endif - l_status_buffercnt = le32_to_cpu(rx_status->status_buffercnt); - if(l_status_buffercnt & 0xC0000000) { - if (l_status_buffercnt & 0x3B000000) { - if (olympic_priv->olympic_message_level) { - if (l_status_buffercnt & (1<<29)) /* Rx Frame Truncated */ - printk(KERN_WARNING "%s: Rx Frame Truncated\n",dev->name); - if (l_status_buffercnt & (1<<28)) /*Rx receive overrun */ - printk(KERN_WARNING "%s: Rx Frame Receive overrun\n",dev->name); - if (l_status_buffercnt & (1<<27)) /* No receive buffers */ - printk(KERN_WARNING "%s: No receive buffers\n",dev->name); - if (l_status_buffercnt & (1<<25)) /* Receive frame error detect */ - printk(KERN_WARNING "%s: Receive frame error detect\n",dev->name); - if (l_status_buffercnt & (1<<24)) /* Received Error Detect */ - printk(KERN_WARNING "%s: Received Error Detect\n",dev->name); - } - olympic_priv->rx_ring_last_received += i ; - olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ; - dev->stats.rx_errors++; - } else { - - if (buffer_cnt == 1) { - skb = dev_alloc_skb(max_t(int, olympic_priv->pkt_buf_sz,length)) ; - } else { - skb = dev_alloc_skb(length) ; - } - - if (skb == NULL) { - printk(KERN_WARNING "%s: Not enough memory to copy packet to upper layers.\n",dev->name) ; - dev->stats.rx_dropped++; - /* Update counters even though we don't transfer the frame */ - olympic_priv->rx_ring_last_received += i ; - olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ; - } else { - /* Optimise based upon number of buffers used. - If only one buffer is used we can simply swap the buffers around. - If more than one then we must use the new buffer and copy the information - first. Ideally all frames would be in a single buffer, this can be tuned by - altering the buffer size. If the length of the packet is less than - 1500 bytes we're going to copy it over anyway to stop packets getting - dropped from sockets with buffers smaller than our pkt_buf_sz. */ - - if (buffer_cnt==1) { - olympic_priv->rx_ring_last_received++ ; - olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1); - rx_ring_last_received = olympic_priv->rx_ring_last_received ; - if (length > 1500) { - skb2=olympic_priv->rx_ring_skb[rx_ring_last_received] ; - /* unmap buffer */ - pci_unmap_single(olympic_priv->pdev, - le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), - olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; - skb_put(skb2,length-4); - skb2->protocol = tr_type_trans(skb2,dev); - olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer = - cpu_to_le32(pci_map_single(olympic_priv->pdev, skb->data, - olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)); - olympic_priv->olympic_rx_ring[rx_ring_last_received].res_length = - cpu_to_le32(olympic_priv->pkt_buf_sz); - olympic_priv->rx_ring_skb[rx_ring_last_received] = skb ; - netif_rx(skb2) ; - } else { - pci_dma_sync_single_for_cpu(olympic_priv->pdev, - le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), - olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; - skb_copy_from_linear_data(olympic_priv->rx_ring_skb[rx_ring_last_received], - skb_put(skb,length - 4), - length - 4); - pci_dma_sync_single_for_device(olympic_priv->pdev, - le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), - olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; - skb->protocol = tr_type_trans(skb,dev) ; - netif_rx(skb) ; - } - } else { - do { /* Walk the buffers */ - olympic_priv->rx_ring_last_received++ ; - olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1); - rx_ring_last_received = olympic_priv->rx_ring_last_received ; - pci_dma_sync_single_for_cpu(olympic_priv->pdev, - le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), - olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; - rx_desc = &(olympic_priv->olympic_rx_ring[rx_ring_last_received]); - cpy_length = (i == 1 ? frag_len : le32_to_cpu(rx_desc->res_length)); - skb_copy_from_linear_data(olympic_priv->rx_ring_skb[rx_ring_last_received], - skb_put(skb, cpy_length), - cpy_length); - pci_dma_sync_single_for_device(olympic_priv->pdev, - le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), - olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; - } while (--i) ; - skb_trim(skb,skb->len-4) ; - skb->protocol = tr_type_trans(skb,dev); - netif_rx(skb) ; - } - dev->stats.rx_packets++ ; - dev->stats.rx_bytes += length ; - } /* if skb == null */ - } /* If status & 0x3b */ - - } else { /*if buffercnt & 0xC */ - olympic_priv->rx_ring_last_received += i ; - olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE - 1) ; - } - - rx_status->fragmentcnt_framelen = 0 ; - rx_status->status_buffercnt = 0 ; - rx_status = &(olympic_priv->olympic_rx_status_ring[(olympic_priv->rx_status_last_received+1) & (OLYMPIC_RX_RING_SIZE -1) ]); - - writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | buffer_cnt , olympic_mmio+RXENQ); - } /* while */ - -} - -static void olympic_freemem(struct net_device *dev) -{ - struct olympic_private *olympic_priv=netdev_priv(dev); - int i; - - for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) { - if (olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received] != NULL) { - dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]); - olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received] = NULL; - } - if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != cpu_to_le32(0xdeadbeef)) { - pci_unmap_single(olympic_priv->pdev, - le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer), - olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE); - } - olympic_priv->rx_status_last_received++; - olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1; - } - /* unmap rings */ - pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_status_ring_dma_addr, - sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE); - pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_ring_dma_addr, - sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE); - - pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_status_ring_dma_addr, - sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE); - pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_ring_dma_addr, - sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE); - - return ; -} - -static irqreturn_t olympic_interrupt(int irq, void *dev_id) -{ - struct net_device *dev= (struct net_device *)dev_id; - struct olympic_private *olympic_priv=netdev_priv(dev); - u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio; - u32 sisr; - u8 __iomem *adapter_check_area ; - - /* - * Read sisr but don't reset it yet. - * The indication bit may have been set but the interrupt latch - * bit may not be set, so we'd lose the interrupt later. - */ - sisr=readl(olympic_mmio+SISR) ; - if (!(sisr & SISR_MI)) /* Interrupt isn't for us */ - return IRQ_NONE; - sisr=readl(olympic_mmio+SISR_RR) ; /* Read & Reset sisr */ - - spin_lock(&olympic_priv->olympic_lock); - - /* Hotswap gives us this on removal */ - if (sisr == 0xffffffff) { - printk(KERN_WARNING "%s: Hotswap adapter removal.\n",dev->name) ; - spin_unlock(&olympic_priv->olympic_lock) ; - return IRQ_NONE; - } - - if (sisr & (SISR_SRB_REPLY | SISR_TX1_EOF | SISR_RX_STATUS | SISR_ADAPTER_CHECK | - SISR_ASB_FREE | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_RX_NOBUF | SISR_ERR)) { - - /* If we ever get this the adapter is seriously dead. Only a reset is going to - * bring it back to life. We're talking pci bus errors and such like :( */ - if((sisr & SISR_ERR) && (readl(olympic_mmio+EISR) & EISR_MASK_OPTIONS)) { - printk(KERN_ERR "Olympic: EISR Error, EISR=%08x\n",readl(olympic_mmio+EISR)) ; - printk(KERN_ERR "The adapter must be reset to clear this condition.\n") ; - printk(KERN_ERR "Please report this error to the driver maintainer and/\n") ; - printk(KERN_ERR "or the linux-tr mailing list.\n") ; - wake_up_interruptible(&olympic_priv->srb_wait); - spin_unlock(&olympic_priv->olympic_lock) ; - return IRQ_HANDLED; - } /* SISR_ERR */ - - if(sisr & SISR_SRB_REPLY) { - if(olympic_priv->srb_queued==1) { - wake_up_interruptible(&olympic_priv->srb_wait); - } else if (olympic_priv->srb_queued==2) { - olympic_srb_bh(dev) ; - } - olympic_priv->srb_queued=0; - } /* SISR_SRB_REPLY */ - - /* We shouldn't ever miss the Tx interrupt, but the you never know, hence the loop to ensure - we get all tx completions. */ - if (sisr & SISR_TX1_EOF) { - while(olympic_priv->olympic_tx_status_ring[(olympic_priv->tx_ring_last_status + 1) & (OLYMPIC_TX_RING_SIZE-1)].status) { - olympic_priv->tx_ring_last_status++; - olympic_priv->tx_ring_last_status &= (OLYMPIC_TX_RING_SIZE-1); - olympic_priv->free_tx_ring_entries++; - dev->stats.tx_bytes += olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len; - dev->stats.tx_packets++ ; - pci_unmap_single(olympic_priv->pdev, - le32_to_cpu(olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer), - olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len,PCI_DMA_TODEVICE); - dev_kfree_skb_irq(olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]); - olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer=cpu_to_le32(0xdeadbeef); - olympic_priv->olympic_tx_status_ring[olympic_priv->tx_ring_last_status].status=0; - } - netif_wake_queue(dev); - } /* SISR_TX1_EOF */ - - if (sisr & SISR_RX_STATUS) { - olympic_rx(dev); - } /* SISR_RX_STATUS */ - - if (sisr & SISR_ADAPTER_CHECK) { - netif_stop_queue(dev); - printk(KERN_WARNING "%s: Adapter Check Interrupt Raised, 8 bytes of information follow:\n", dev->name); - writel(readl(olympic_mmio+LAPWWC),olympic_mmio+LAPA); - adapter_check_area = olympic_priv->olympic_lap + ((readl(olympic_mmio+LAPWWC)) & (~0xf800)) ; - printk(KERN_WARNING "%s: Bytes %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, readb(adapter_check_area+0), readb(adapter_check_area+1), readb(adapter_check_area+2), readb(adapter_check_area+3), readb(adapter_check_area+4), readb(adapter_check_area+5), readb(adapter_check_area+6), readb(adapter_check_area+7)) ; - spin_unlock(&olympic_priv->olympic_lock) ; - return IRQ_HANDLED; - } /* SISR_ADAPTER_CHECK */ - - if (sisr & SISR_ASB_FREE) { - /* Wake up anything that is waiting for the asb response */ - if (olympic_priv->asb_queued) { - olympic_asb_bh(dev) ; - } - } /* SISR_ASB_FREE */ - - if (sisr & SISR_ARB_CMD) { - olympic_arb_cmd(dev) ; - } /* SISR_ARB_CMD */ - - if (sisr & SISR_TRB_REPLY) { - /* Wake up anything that is waiting for the trb response */ - if (olympic_priv->trb_queued) { - wake_up_interruptible(&olympic_priv->trb_wait); - } - olympic_priv->trb_queued = 0 ; - } /* SISR_TRB_REPLY */ - - if (sisr & SISR_RX_NOBUF) { - /* According to the documentation, we don't have to do anything, but trapping it keeps it out of - /var/log/messages. */ - } /* SISR_RX_NOBUF */ - } else { - printk(KERN_WARNING "%s: Unexpected interrupt: %x\n",dev->name, sisr); - printk(KERN_WARNING "%s: SISR_MASK: %x\n",dev->name, readl(olympic_mmio+SISR_MASK)) ; - } /* One if the interrupts we want */ - writel(SISR_MI,olympic_mmio+SISR_MASK_SUM); - - spin_unlock(&olympic_priv->olympic_lock) ; - return IRQ_HANDLED; -} - -static netdev_tx_t olympic_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - struct olympic_private *olympic_priv=netdev_priv(dev); - u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio; - unsigned long flags ; - - spin_lock_irqsave(&olympic_priv->olympic_lock, flags); - - netif_stop_queue(dev); - - if(olympic_priv->free_tx_ring_entries) { - olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].buffer = - cpu_to_le32(pci_map_single(olympic_priv->pdev, skb->data, skb->len,PCI_DMA_TODEVICE)); - olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].status_length = cpu_to_le32(skb->len | (0x80000000)); - olympic_priv->tx_ring_skb[olympic_priv->tx_ring_free]=skb; - olympic_priv->free_tx_ring_entries--; - - olympic_priv->tx_ring_free++; - olympic_priv->tx_ring_free &= (OLYMPIC_TX_RING_SIZE-1); - writew((((readw(olympic_mmio+TXENQ_1)) & 0x8000) ^ 0x8000) | 1,olympic_mmio+TXENQ_1); - netif_wake_queue(dev); - spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags); - return NETDEV_TX_OK; - } else { - spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags); - return NETDEV_TX_BUSY; - } - -} - - -static int olympic_close(struct net_device *dev) -{ - struct olympic_private *olympic_priv=netdev_priv(dev); - u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio,*srb; - unsigned long t,flags; - - DECLARE_WAITQUEUE(wait,current) ; - - netif_stop_queue(dev); - - writel(olympic_priv->srb,olympic_mmio+LAPA); - srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800)); - - writeb(SRB_CLOSE_ADAPTER,srb+0); - writeb(0,srb+1); - writeb(OLYMPIC_CLEAR_RET_CODE,srb+2); - - add_wait_queue(&olympic_priv->srb_wait,&wait) ; - set_current_state(TASK_INTERRUPTIBLE) ; - - spin_lock_irqsave(&olympic_priv->olympic_lock,flags); - olympic_priv->srb_queued=1; - - writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM); - spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags); - - while(olympic_priv->srb_queued) { - - t = schedule_timeout_interruptible(60*HZ); - - if(signal_pending(current)) { - printk(KERN_WARNING "%s: SRB timed out.\n",dev->name); - printk(KERN_WARNING "SISR=%x MISR=%x\n",readl(olympic_mmio+SISR),readl(olympic_mmio+LISR)); - olympic_priv->srb_queued=0; - break; - } - - if (t == 0) { - printk(KERN_WARNING "%s: SRB timed out. May not be fatal.\n",dev->name); - } - olympic_priv->srb_queued=0; - } - remove_wait_queue(&olympic_priv->srb_wait,&wait) ; - - olympic_priv->rx_status_last_received++; - olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1; - - olympic_freemem(dev) ; - - /* reset tx/rx fifo's and busmaster logic */ - - writel(readl(olympic_mmio+BCTL)|(3<<13),olympic_mmio+BCTL); - udelay(1); - writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL); - -#if OLYMPIC_DEBUG - { - int i ; - printk("srb(%p): ",srb); - for(i=0;i<4;i++) - printk("%x ",readb(srb+i)); - printk("\n"); - } -#endif - free_irq(dev->irq,dev); - - return 0; - -} - -static void olympic_set_rx_mode(struct net_device *dev) -{ - struct olympic_private *olympic_priv = netdev_priv(dev); - u8 __iomem *olympic_mmio = olympic_priv->olympic_mmio ; - u8 options = 0; - u8 __iomem *srb; - struct netdev_hw_addr *ha; - unsigned char dev_mc_address[4] ; - - writel(olympic_priv->srb,olympic_mmio+LAPA); - srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800)); - options = olympic_priv->olympic_copy_all_options; - - if (dev->flags&IFF_PROMISC) - options |= 0x61 ; - else - options &= ~0x61 ; - - /* Only issue the srb if there is a change in options */ - - if ((options ^ olympic_priv->olympic_copy_all_options)) { - - /* Now to issue the srb command to alter the copy.all.options */ - - writeb(SRB_MODIFY_RECEIVE_OPTIONS,srb); - writeb(0,srb+1); - writeb(OLYMPIC_CLEAR_RET_CODE,srb+2); - writeb(0,srb+3); - writeb(olympic_priv->olympic_receive_options,srb+4); - writeb(options,srb+5); - - olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */ - - writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM); - - olympic_priv->olympic_copy_all_options = options ; - - return ; - } - - /* Set the functional addresses we need for multicast */ - - dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ; - - netdev_for_each_mc_addr(ha, dev) { - dev_mc_address[0] |= ha->addr[2]; - dev_mc_address[1] |= ha->addr[3]; - dev_mc_address[2] |= ha->addr[4]; - dev_mc_address[3] |= ha->addr[5]; - } - - writeb(SRB_SET_FUNC_ADDRESS,srb+0); - writeb(0,srb+1); - writeb(OLYMPIC_CLEAR_RET_CODE,srb+2); - writeb(0,srb+3); - writeb(0,srb+4); - writeb(0,srb+5); - writeb(dev_mc_address[0],srb+6); - writeb(dev_mc_address[1],srb+7); - writeb(dev_mc_address[2],srb+8); - writeb(dev_mc_address[3],srb+9); - - olympic_priv->srb_queued = 2 ; - writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM); - -} - -static void olympic_srb_bh(struct net_device *dev) -{ - struct olympic_private *olympic_priv = netdev_priv(dev); - u8 __iomem *olympic_mmio = olympic_priv->olympic_mmio ; - u8 __iomem *srb; - - writel(olympic_priv->srb,olympic_mmio+LAPA); - srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800)); - - switch (readb(srb)) { - - /* SRB_MODIFY_RECEIVE_OPTIONS i.e. set_multicast_list options (promiscuous) - * At some point we should do something if we get an error, such as - * resetting the IFF_PROMISC flag in dev - */ - - case SRB_MODIFY_RECEIVE_OPTIONS: - switch (readb(srb+2)) { - case 0x01: - printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name) ; - break ; - case 0x04: - printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name); - break ; - default: - if (olympic_priv->olympic_message_level) - printk(KERN_WARNING "%s: Receive Options Modified to %x,%x\n",dev->name,olympic_priv->olympic_copy_all_options, olympic_priv->olympic_receive_options) ; - break ; - } /* switch srb[2] */ - break ; - - /* SRB_SET_GROUP_ADDRESS - Multicast group setting - */ - - case SRB_SET_GROUP_ADDRESS: - switch (readb(srb+2)) { - case 0x00: - break ; - case 0x01: - printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name); - break ; - case 0x04: - printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name); - break ; - case 0x3c: - printk(KERN_WARNING "%s: Group/Functional address indicator bits not set correctly\n",dev->name) ; - break ; - case 0x3e: /* If we ever implement individual multicast addresses, will need to deal with this */ - printk(KERN_WARNING "%s: Group address registers full\n",dev->name) ; - break ; - case 0x55: - printk(KERN_INFO "%s: Group Address already set.\n",dev->name) ; - break ; - default: - break ; - } /* switch srb[2] */ - break ; - - /* SRB_RESET_GROUP_ADDRESS - Remove a multicast address from group list - */ - - case SRB_RESET_GROUP_ADDRESS: - switch (readb(srb+2)) { - case 0x00: - break ; - case 0x01: - printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name); - break ; - case 0x04: - printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; - break ; - case 0x39: /* Must deal with this if individual multicast addresses used */ - printk(KERN_INFO "%s: Group address not found\n",dev->name); - break ; - default: - break ; - } /* switch srb[2] */ - break ; - - - /* SRB_SET_FUNC_ADDRESS - Called by the set_rx_mode - */ - - case SRB_SET_FUNC_ADDRESS: - switch (readb(srb+2)) { - case 0x00: - if (olympic_priv->olympic_message_level) - printk(KERN_INFO "%s: Functional Address Mask Set\n",dev->name); - break ; - case 0x01: - printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name); - break ; - case 0x04: - printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; - break ; - default: - break ; - } /* switch srb[2] */ - break ; - - /* SRB_READ_LOG - Read and reset the adapter error counters - */ - - case SRB_READ_LOG: - switch (readb(srb+2)) { - case 0x00: - if (olympic_priv->olympic_message_level) - printk(KERN_INFO "%s: Read Log issued\n",dev->name) ; - break ; - case 0x01: - printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name); - break ; - case 0x04: - printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; - break ; - - } /* switch srb[2] */ - break ; - - /* SRB_READ_SR_COUNTERS - Read and reset the source routing bridge related counters */ - - case SRB_READ_SR_COUNTERS: - switch (readb(srb+2)) { - case 0x00: - if (olympic_priv->olympic_message_level) - printk(KERN_INFO "%s: Read Source Routing Counters issued\n",dev->name) ; - break ; - case 0x01: - printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name); - break ; - case 0x04: - printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; - break ; - default: - break ; - } /* switch srb[2] */ - break ; - - default: - printk(KERN_WARNING "%s: Unrecognized srb bh return value.\n",dev->name); - break ; - } /* switch srb[0] */ - -} - -static int olympic_set_mac_address (struct net_device *dev, void *addr) -{ - struct sockaddr *saddr = addr ; - struct olympic_private *olympic_priv = netdev_priv(dev); - - if (netif_running(dev)) { - printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name) ; - return -EIO ; - } - - memcpy(olympic_priv->olympic_laa, saddr->sa_data,dev->addr_len) ; - - if (olympic_priv->olympic_message_level) { - printk(KERN_INFO "%s: MAC/LAA Set to = %x.%x.%x.%x.%x.%x\n",dev->name, olympic_priv->olympic_laa[0], - olympic_priv->olympic_laa[1], olympic_priv->olympic_laa[2], - olympic_priv->olympic_laa[3], olympic_priv->olympic_laa[4], - olympic_priv->olympic_laa[5]); - } - - return 0 ; -} - -static void olympic_arb_cmd(struct net_device *dev) -{ - struct olympic_private *olympic_priv = netdev_priv(dev); - u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio; - u8 __iomem *arb_block, *asb_block, *srb ; - u8 header_len ; - u16 frame_len, buffer_len ; - struct sk_buff *mac_frame ; - u8 __iomem *buf_ptr ; - u8 __iomem *frame_data ; - u16 buff_off ; - u16 lan_status = 0, lan_status_diff ; /* Initialize to stop compiler warning */ - u8 fdx_prot_error ; - u16 next_ptr; - - arb_block = (olympic_priv->olympic_lap + olympic_priv->arb) ; - asb_block = (olympic_priv->olympic_lap + olympic_priv->asb) ; - srb = (olympic_priv->olympic_lap + olympic_priv->srb) ; - - if (readb(arb_block+0) == ARB_RECEIVE_DATA) { /* Receive.data, MAC frames */ - - header_len = readb(arb_block+8) ; /* 802.5 Token-Ring Header Length */ - frame_len = swab16(readw(arb_block + 10)) ; - - buff_off = swab16(readw(arb_block + 6)) ; - - buf_ptr = olympic_priv->olympic_lap + buff_off ; - -#if OLYMPIC_DEBUG -{ - int i; - frame_data = buf_ptr+offsetof(struct mac_receive_buffer,frame_data) ; - - for (i=0 ; i < 14 ; i++) { - printk("Loc %d = %02x\n",i,readb(frame_data + i)); - } - - printk("next %04x, fs %02x, len %04x\n",readw(buf_ptr+offsetof(struct mac_receive_buffer,next)), readb(buf_ptr+offsetof(struct mac_receive_buffer,frame_status)), readw(buf_ptr+offsetof(struct mac_receive_buffer,buffer_length))); -} -#endif - mac_frame = dev_alloc_skb(frame_len) ; - if (!mac_frame) { - printk(KERN_WARNING "%s: Memory squeeze, dropping frame.\n", dev->name); - goto drop_frame; - } - - /* Walk the buffer chain, creating the frame */ - - do { - frame_data = buf_ptr+offsetof(struct mac_receive_buffer,frame_data) ; - buffer_len = swab16(readw(buf_ptr+offsetof(struct mac_receive_buffer,buffer_length))); - memcpy_fromio(skb_put(mac_frame, buffer_len), frame_data , buffer_len ) ; - next_ptr=readw(buf_ptr+offsetof(struct mac_receive_buffer,next)); - } while (next_ptr && (buf_ptr=olympic_priv->olympic_lap + swab16(next_ptr))); - - mac_frame->protocol = tr_type_trans(mac_frame, dev); - - if (olympic_priv->olympic_network_monitor) { - struct trh_hdr *mac_hdr; - printk(KERN_WARNING "%s: Received MAC Frame, details:\n",dev->name); - mac_hdr = tr_hdr(mac_frame); - printk(KERN_WARNING "%s: MAC Frame Dest. Addr: %pM\n", - dev->name, mac_hdr->daddr); - printk(KERN_WARNING "%s: MAC Frame Srce. Addr: %pM\n", - dev->name, mac_hdr->saddr); - } - netif_rx(mac_frame); - -drop_frame: - /* Now tell the card we have dealt with the received frame */ - - /* Set LISR Bit 1 */ - writel(LISR_ARB_FREE,olympic_priv->olympic_mmio + LISR_SUM); - - /* Is the ASB free ? */ - - if (readb(asb_block + 2) != 0xff) { - olympic_priv->asb_queued = 1 ; - writel(LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM); - return ; - /* Drop out and wait for the bottom half to be run */ - } - - writeb(ASB_RECEIVE_DATA,asb_block); /* Receive data */ - writeb(OLYMPIC_CLEAR_RET_CODE,asb_block+2); /* Necessary ?? */ - writeb(readb(arb_block+6),asb_block+6); /* Must send the address back to the adapter */ - writeb(readb(arb_block+7),asb_block+7); /* To let it know we have dealt with the data */ - - writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM); - - olympic_priv->asb_queued = 2 ; - - return ; - - } else if (readb(arb_block) == ARB_LAN_CHANGE_STATUS) { /* Lan.change.status */ - lan_status = swab16(readw(arb_block+6)); - fdx_prot_error = readb(arb_block+8) ; - - /* Issue ARB Free */ - writel(LISR_ARB_FREE,olympic_priv->olympic_mmio+LISR_SUM); - - lan_status_diff = olympic_priv->olympic_lan_status ^ lan_status ; - - if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR) ) { - if (lan_status_diff & LSC_LWF) - printk(KERN_WARNING "%s: Short circuit detected on the lobe\n",dev->name); - if (lan_status_diff & LSC_ARW) - printk(KERN_WARNING "%s: Auto removal error\n",dev->name); - if (lan_status_diff & LSC_FPE) - printk(KERN_WARNING "%s: FDX Protocol Error\n",dev->name); - if (lan_status_diff & LSC_RR) - printk(KERN_WARNING "%s: Force remove MAC frame received\n",dev->name); - - /* Adapter has been closed by the hardware */ - - /* reset tx/rx fifo's and busmaster logic */ - - writel(readl(olympic_mmio+BCTL)|(3<<13),olympic_mmio+BCTL); - udelay(1); - writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL); - netif_stop_queue(dev); - olympic_priv->srb = readw(olympic_priv->olympic_lap + LAPWWO) ; - printk(KERN_WARNING "%s: Adapter has been closed\n", dev->name); - } /* If serious error */ - - if (olympic_priv->olympic_message_level) { - if (lan_status_diff & LSC_SIG_LOSS) - printk(KERN_WARNING "%s: No receive signal detected\n", dev->name); - if (lan_status_diff & LSC_HARD_ERR) - printk(KERN_INFO "%s: Beaconing\n",dev->name); - if (lan_status_diff & LSC_SOFT_ERR) - printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame\n",dev->name); - if (lan_status_diff & LSC_TRAN_BCN) - printk(KERN_INFO "%s: We are transmitting the beacon, aaah\n",dev->name); - if (lan_status_diff & LSC_SS) - printk(KERN_INFO "%s: Single Station on the ring\n", dev->name); - if (lan_status_diff & LSC_RING_REC) - printk(KERN_INFO "%s: Ring recovery ongoing\n",dev->name); - if (lan_status_diff & LSC_FDX_MODE) - printk(KERN_INFO "%s: Operating in FDX mode\n",dev->name); - } - - if (lan_status_diff & LSC_CO) { - - if (olympic_priv->olympic_message_level) - printk(KERN_INFO "%s: Counter Overflow\n", dev->name); - - /* Issue READ.LOG command */ - - writeb(SRB_READ_LOG, srb); - writeb(0,srb+1); - writeb(OLYMPIC_CLEAR_RET_CODE,srb+2); - writeb(0,srb+3); - writeb(0,srb+4); - writeb(0,srb+5); - - olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */ - - writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM); - - } - - if (lan_status_diff & LSC_SR_CO) { - - if (olympic_priv->olympic_message_level) - printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name); - - /* Issue a READ.SR.COUNTERS */ - - writeb(SRB_READ_SR_COUNTERS,srb); - writeb(0,srb+1); - writeb(OLYMPIC_CLEAR_RET_CODE,srb+2); - writeb(0,srb+3); - - olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */ - - writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM); - - } - - olympic_priv->olympic_lan_status = lan_status ; - - } /* Lan.change.status */ - else - printk(KERN_WARNING "%s: Unknown arb command\n", dev->name); -} - -static void olympic_asb_bh(struct net_device *dev) -{ - struct olympic_private *olympic_priv = netdev_priv(dev); - u8 __iomem *arb_block, *asb_block ; - - arb_block = (olympic_priv->olympic_lap + olympic_priv->arb) ; - asb_block = (olympic_priv->olympic_lap + olympic_priv->asb) ; - - if (olympic_priv->asb_queued == 1) { /* Dropped through the first time */ - - writeb(ASB_RECEIVE_DATA,asb_block); /* Receive data */ - writeb(OLYMPIC_CLEAR_RET_CODE,asb_block+2); /* Necessary ?? */ - writeb(readb(arb_block+6),asb_block+6); /* Must send the address back to the adapter */ - writeb(readb(arb_block+7),asb_block+7); /* To let it know we have dealt with the data */ - - writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM); - olympic_priv->asb_queued = 2 ; - - return ; - } - - if (olympic_priv->asb_queued == 2) { - switch (readb(asb_block+2)) { - case 0x01: - printk(KERN_WARNING "%s: Unrecognized command code\n", dev->name); - break ; - case 0x26: - printk(KERN_WARNING "%s: Unrecognized buffer address\n", dev->name); - break ; - case 0xFF: - /* Valid response, everything should be ok again */ - break ; - default: - printk(KERN_WARNING "%s: Invalid return code in asb\n",dev->name); - break ; - } - } - olympic_priv->asb_queued = 0 ; -} - -static int olympic_change_mtu(struct net_device *dev, int mtu) -{ - struct olympic_private *olympic_priv = netdev_priv(dev); - u16 max_mtu ; - - if (olympic_priv->olympic_ring_speed == 4) - max_mtu = 4500 ; - else - max_mtu = 18000 ; - - if (mtu > max_mtu) - return -EINVAL ; - if (mtu < 100) - return -EINVAL ; - - dev->mtu = mtu ; - olympic_priv->pkt_buf_sz = mtu + TR_HLEN ; - - return 0 ; -} - -static int olympic_proc_show(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct olympic_private *olympic_priv=netdev_priv(dev); - u8 __iomem *oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; - u8 __iomem *opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ; - u8 addr[6]; - u8 addr2[6]; - int i; - - seq_printf(m, - "IBM Pit/Pit-Phy/Olympic Chipset Token Ring Adapter %s\n",dev->name); - seq_printf(m, "\n%6s: Adapter Address : Node Address : Functional Addr\n", - dev->name); - - for (i = 0 ; i < 6 ; i++) - addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr) + i); - - seq_printf(m, "%6s: %pM : %pM : %02x:%02x:%02x:%02x\n", - dev->name, - dev->dev_addr, addr, - readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)), - readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1), - readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2), - readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3)); - - seq_printf(m, "\n%6s: Token Ring Parameters Table:\n", dev->name); - - seq_printf(m, "%6s: Physical Addr : Up Node Address : Poll Address : AccPri : Auth Src : Att Code :\n", - dev->name) ; - - for (i = 0 ; i < 6 ; i++) - addr[i] = readb(opt+offsetof(struct olympic_parameters_table, up_node_addr) + i); - for (i = 0 ; i < 6 ; i++) - addr2[i] = readb(opt+offsetof(struct olympic_parameters_table, poll_addr) + i); - - seq_printf(m, "%6s: %02x:%02x:%02x:%02x : %pM : %pM : %04x : %04x : %04x :\n", - dev->name, - readb(opt+offsetof(struct olympic_parameters_table, phys_addr)), - readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+1), - readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+2), - readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+3), - addr, addr2, - swab16(readw(opt+offsetof(struct olympic_parameters_table, acc_priority))), - swab16(readw(opt+offsetof(struct olympic_parameters_table, auth_source_class))), - swab16(readw(opt+offsetof(struct olympic_parameters_table, att_code)))); - - seq_printf(m, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n", - dev->name) ; - - for (i = 0 ; i < 6 ; i++) - addr[i] = readb(opt+offsetof(struct olympic_parameters_table, source_addr) + i); - seq_printf(m, "%6s: %pM : %04x : %04x : %04x : %04x : %04x : %04x : \n", - dev->name, addr, - swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_type))), - swab16(readw(opt+offsetof(struct olympic_parameters_table, major_vector))), - swab16(readw(opt+offsetof(struct olympic_parameters_table, lan_status))), - swab16(readw(opt+offsetof(struct olympic_parameters_table, local_ring))), - swab16(readw(opt+offsetof(struct olympic_parameters_table, mon_error))), - swab16(readw(opt+offsetof(struct olympic_parameters_table, frame_correl)))); - - seq_printf(m, "%6s: Beacon Details : Tx : Rx : NAUN Node Address : NAUN Node Phys : \n", - dev->name) ; - - for (i = 0 ; i < 6 ; i++) - addr[i] = readb(opt+offsetof(struct olympic_parameters_table, beacon_naun) + i); - seq_printf(m, "%6s: : %02x : %02x : %pM : %02x:%02x:%02x:%02x : \n", - dev->name, - swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_transmit))), - swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_receive))), - addr, - readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)), - readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+1), - readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+2), - readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+3)); - - return 0; -} - -static int olympic_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, olympic_proc_show, PDE(inode)->data); -} - -static const struct file_operations olympic_proc_ops = { - .open = olympic_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static void __devexit olympic_remove_one(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev) ; - struct olympic_private *olympic_priv=netdev_priv(dev); - - if (olympic_priv->olympic_network_monitor) { - char proc_name[20] ; - strcpy(proc_name,"olympic_") ; - strcat(proc_name,dev->name) ; - remove_proc_entry(proc_name,init_net.proc_net); - } - unregister_netdev(dev) ; - iounmap(olympic_priv->olympic_mmio) ; - iounmap(olympic_priv->olympic_lap) ; - pci_release_regions(pdev) ; - pci_set_drvdata(pdev,NULL) ; - free_netdev(dev) ; -} - -static struct pci_driver olympic_driver = { - .name = "olympic", - .id_table = olympic_pci_tbl, - .probe = olympic_probe, - .remove = __devexit_p(olympic_remove_one), -}; - -module_pci_driver(olympic_driver); - -MODULE_LICENSE("GPL");
diff --git a/drivers/net/tokenring/olympic.h b/drivers/net/tokenring/olympic.h deleted file mode 100644 index 30631ba..0000000 --- a/drivers/net/tokenring/olympic.h +++ /dev/null
@@ -1,321 +0,0 @@ -/* - * olympic.h (c) 1999 Peter De Schrijver All Rights Reserved - * 1999,2000 Mike Phillips (mikep@linuxtr.net) - * - * Linux driver for IBM PCI tokenring cards based on the olympic and the PIT/PHY chipset. - * - * Base Driver Skeleton: - * Written 1993-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. - */ - -#define CID 0x4e - -#define BCTL 0x70 -#define BCTL_SOFTRESET (1<<15) -#define BCTL_MIMREB (1<<6) -#define BCTL_MODE_INDICATOR (1<<5) - -#define GPR 0x4a -#define GPR_OPTI_BF (1<<6) -#define GPR_NEPTUNE_BF (1<<4) -#define GPR_AUTOSENSE (1<<2) -#define GPR_16MBPS (1<<3) - -#define PAG 0x85 -#define LBC 0x8e - -#define LISR 0x10 -#define LISR_SUM 0x14 -#define LISR_RWM 0x18 - -#define LISR_LIE (1<<15) -#define LISR_SLIM (1<<13) -#define LISR_SLI (1<<12) -#define LISR_PCMSRMASK (1<<11) -#define LISR_PCMSRINT (1<<10) -#define LISR_WOLMASK (1<<9) -#define LISR_WOL (1<<8) -#define LISR_SRB_CMD (1<<5) -#define LISR_ASB_REPLY (1<<4) -#define LISR_ASB_FREE_REQ (1<<2) -#define LISR_ARB_FREE (1<<1) -#define LISR_TRB_FRAME (1<<0) - -#define SISR 0x20 -#define SISR_SUM 0x24 -#define SISR_RWM 0x28 -#define SISR_RR 0x2C -#define SISR_RESMASK 0x30 -#define SISR_MASK 0x54 -#define SISR_MASK_SUM 0x58 -#define SISR_MASK_RWM 0x5C - -#define SISR_TX2_IDLE (1<<31) -#define SISR_TX2_HALT (1<<29) -#define SISR_TX2_EOF (1<<28) -#define SISR_TX1_IDLE (1<<27) -#define SISR_TX1_HALT (1<<25) -#define SISR_TX1_EOF (1<<24) -#define SISR_TIMEOUT (1<<23) -#define SISR_RX_NOBUF (1<<22) -#define SISR_RX_STATUS (1<<21) -#define SISR_RX_HALT (1<<18) -#define SISR_RX_EOF_EARLY (1<<16) -#define SISR_MI (1<<15) -#define SISR_PI (1<<13) -#define SISR_ERR (1<<9) -#define SISR_ADAPTER_CHECK (1<<6) -#define SISR_SRB_REPLY (1<<5) -#define SISR_ASB_FREE (1<<4) -#define SISR_ARB_CMD (1<<3) -#define SISR_TRB_REPLY (1<<2) - -#define EISR 0x34 -#define EISR_RWM 0x38 -#define EISR_MASK 0x3c -#define EISR_MASK_OPTIONS 0x001FFF7F - -#define LAPA 0x60 -#define LAPWWO 0x64 -#define LAPWWC 0x68 -#define LAPCTL 0x6C -#define LAIPD 0x78 -#define LAIPDDINC 0x7C - -#define TIMER 0x50 - -#define CLKCTL 0x74 -#define CLKCTL_PAUSE (1<<15) - -#define PM_CON 0x4 - -#define BMCTL_SUM 0x40 -#define BMCTL_RWM 0x44 -#define BMCTL_TX2_DIS (1<<30) -#define BMCTL_TX1_DIS (1<<26) -#define BMCTL_RX_DIS (1<<22) - -#define BMASR 0xcc - -#define RXDESCQ 0x90 -#define RXDESCQCNT 0x94 -#define RXCDA 0x98 -#define RXENQ 0x9C -#define RXSTATQ 0xA0 -#define RXSTATQCNT 0xA4 -#define RXCSA 0xA8 -#define RXCLEN 0xAC -#define RXHLEN 0xAE - -#define TXDESCQ_1 0xb0 -#define TXDESCQ_2 0xd0 -#define TXDESCQCNT_1 0xb4 -#define TXDESCQCNT_2 0xd4 -#define TXCDA_1 0xb8 -#define TXCDA_2 0xd8 -#define TXENQ_1 0xbc -#define TXENQ_2 0xdc -#define TXSTATQ_1 0xc0 -#define TXSTATQ_2 0xe0 -#define TXSTATQCNT_1 0xc4 -#define TXSTATQCNT_2 0xe4 -#define TXCSA_1 0xc8 -#define TXCSA_2 0xe8 -/* Cardbus */ -#define FERMASK 0xf4 -#define FERMASK_INT_BIT (1<<15) - -#define OLYMPIC_IO_SPACE 256 - -#define SRB_COMMAND_SIZE 50 - -#define OLYMPIC_MAX_ADAPTERS 8 /* 0x08 __MODULE_STRING can't hand 0xnn */ - -/* Defines for LAN STATUS CHANGE reports */ -#define LSC_SIG_LOSS 0x8000 -#define LSC_HARD_ERR 0x4000 -#define LSC_SOFT_ERR 0x2000 -#define LSC_TRAN_BCN 0x1000 -#define LSC_LWF 0x0800 -#define LSC_ARW 0x0400 -#define LSC_FPE 0x0200 -#define LSC_RR 0x0100 -#define LSC_CO 0x0080 -#define LSC_SS 0x0040 -#define LSC_RING_REC 0x0020 -#define LSC_SR_CO 0x0010 -#define LSC_FDX_MODE 0x0004 - -/* Defines for OPEN ADAPTER command */ - -#define OPEN_ADAPTER_EXT_WRAP (1<<15) -#define OPEN_ADAPTER_DIS_HARDEE (1<<14) -#define OPEN_ADAPTER_DIS_SOFTERR (1<<13) -#define OPEN_ADAPTER_PASS_ADC_MAC (1<<12) -#define OPEN_ADAPTER_PASS_ATT_MAC (1<<11) -#define OPEN_ADAPTER_ENABLE_EC (1<<10) -#define OPEN_ADAPTER_CONTENDER (1<<8) -#define OPEN_ADAPTER_PASS_BEACON (1<<7) -#define OPEN_ADAPTER_ENABLE_FDX (1<<6) -#define OPEN_ADAPTER_ENABLE_RPL (1<<5) -#define OPEN_ADAPTER_INHIBIT_ETR (1<<4) -#define OPEN_ADAPTER_INTERNAL_WRAP (1<<3) -#define OPEN_ADAPTER_USE_OPTS2 (1<<0) - -#define OPEN_ADAPTER_2_ENABLE_ONNOW (1<<15) - -/* Defines for SRB Commands */ - -#define SRB_ACCESS_REGISTER 0x1f -#define SRB_CLOSE_ADAPTER 0x04 -#define SRB_CONFIGURE_BRIDGE 0x0c -#define SRB_CONFIGURE_WAKEUP_EVENT 0x1a -#define SRB_MODIFY_BRIDGE_PARMS 0x15 -#define SRB_MODIFY_OPEN_OPTIONS 0x01 -#define SRB_MODIFY_RECEIVE_OPTIONS 0x17 -#define SRB_NO_OPERATION 0x00 -#define SRB_OPEN_ADAPTER 0x03 -#define SRB_READ_LOG 0x08 -#define SRB_READ_SR_COUNTERS 0x16 -#define SRB_RESET_GROUP_ADDRESS 0x02 -#define SRB_SAVE_CONFIGURATION 0x1b -#define SRB_SET_BRIDGE_PARMS 0x09 -#define SRB_SET_BRIDGE_TARGETS 0x10 -#define SRB_SET_FUNC_ADDRESS 0x07 -#define SRB_SET_GROUP_ADDRESS 0x06 -#define SRB_SET_GROUP_ADDR_OPTIONS 0x11 -#define SRB_UPDATE_WAKEUP_PATTERN 0x19 - -/* Clear return code */ - -#define OLYMPIC_CLEAR_RET_CODE 0xfe - -/* ARB Commands */ -#define ARB_RECEIVE_DATA 0x81 -#define ARB_LAN_CHANGE_STATUS 0x84 -/* ASB Response commands */ - -#define ASB_RECEIVE_DATA 0x81 - - -/* Olympic defaults for buffers */ - -#define OLYMPIC_RX_RING_SIZE 16 /* should be a power of 2 */ -#define OLYMPIC_TX_RING_SIZE 8 /* should be a power of 2 */ - -#define PKT_BUF_SZ 4096 /* Default packet size */ - -/* Olympic data structures */ - -/* xxxx These structures are all little endian in hardware. */ - -struct olympic_tx_desc { - __le32 buffer; - __le32 status_length; -}; - -struct olympic_tx_status { - __le32 status; -}; - -struct olympic_rx_desc { - __le32 buffer; - __le32 res_length; -}; - -struct olympic_rx_status { - __le32 fragmentcnt_framelen; - __le32 status_buffercnt; -}; -/* xxxx END These structures are all little endian in hardware. */ -/* xxxx There may be more, but I'm pretty sure about these */ - -struct mac_receive_buffer { - __le16 next ; - u8 padding ; - u8 frame_status ; - __le16 buffer_length ; - u8 frame_data ; -}; - -struct olympic_private { - - u16 srb; /* be16 */ - u16 trb; /* be16 */ - u16 arb; /* be16 */ - u16 asb; /* be16 */ - - u8 __iomem *olympic_mmio; - u8 __iomem *olympic_lap; - struct pci_dev *pdev ; - const char *olympic_card_name; - - spinlock_t olympic_lock ; - - volatile int srb_queued; /* True if an SRB is still posted */ - wait_queue_head_t srb_wait; - - volatile int asb_queued; /* True if an ASB is posted */ - - volatile int trb_queued; /* True if a TRB is posted */ - wait_queue_head_t trb_wait ; - - /* These must be on a 4 byte boundary. */ - struct olympic_rx_desc olympic_rx_ring[OLYMPIC_RX_RING_SIZE]; - struct olympic_tx_desc olympic_tx_ring[OLYMPIC_TX_RING_SIZE]; - struct olympic_rx_status olympic_rx_status_ring[OLYMPIC_RX_RING_SIZE]; - struct olympic_tx_status olympic_tx_status_ring[OLYMPIC_TX_RING_SIZE]; - - struct sk_buff *tx_ring_skb[OLYMPIC_TX_RING_SIZE], *rx_ring_skb[OLYMPIC_RX_RING_SIZE]; - int tx_ring_free, tx_ring_last_status, rx_ring_last_received,rx_status_last_received, free_tx_ring_entries; - - u16 olympic_lan_status ; - u8 olympic_ring_speed ; - u16 pkt_buf_sz ; - u8 olympic_receive_options, olympic_copy_all_options,olympic_message_level, olympic_network_monitor; - u16 olympic_addr_table_addr, olympic_parms_addr ; - u8 olympic_laa[6] ; - u32 rx_ring_dma_addr; - u32 rx_status_ring_dma_addr; - u32 tx_ring_dma_addr; - u32 tx_status_ring_dma_addr; -}; - -struct olympic_adapter_addr_table { - - u8 node_addr[6] ; - u8 reserved[4] ; - u8 func_addr[4] ; -} ; - -struct olympic_parameters_table { - - u8 phys_addr[4] ; - u8 up_node_addr[6] ; - u8 up_phys_addr[4] ; - u8 poll_addr[6] ; - u16 reserved ; - u16 acc_priority ; - u16 auth_source_class ; - u16 att_code ; - u8 source_addr[6] ; - u16 beacon_type ; - u16 major_vector ; - u16 lan_status ; - u16 soft_error_time ; - u16 reserved1 ; - u16 local_ring ; - u16 mon_error ; - u16 beacon_transmit ; - u16 beacon_receive ; - u16 frame_correl ; - u8 beacon_naun[6] ; - u32 reserved2 ; - u8 beacon_phys[4] ; -};
diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c deleted file mode 100644 index 62d90e4..0000000 --- a/drivers/net/tokenring/proteon.c +++ /dev/null
@@ -1,422 +0,0 @@ -/* - * proteon.c: A network driver for Proteon ISA token ring cards. - * - * Based on tmspci written 1999 by Adam Fritzler - * - * Written 2003 by Jochen Friedrich - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * This driver module supports the following cards: - * - Proteon 1392, 1392+ - * - * Maintainer(s): - * AF Adam Fritzler - * JF Jochen Friedrich jochen@scram.de - * - * Modification History: - * 02-Jan-03 JF Created - * - */ -static const char version[] = "proteon.c: v1.00 02/01/2003 by Jochen Friedrich\n"; - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/netdevice.h> -#include <linux/trdevice.h> -#include <linux/platform_device.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/pci.h> -#include <asm/dma.h> - -#include "tms380tr.h" - -#define PROTEON_IO_EXTENT 32 - -/* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int portlist[] __initdata = { - 0x0A20, 0x0E20, 0x1A20, 0x1E20, 0x2A20, 0x2E20, 0x3A20, 0x3E20,// Prot. - 0x4A20, 0x4E20, 0x5A20, 0x5E20, 0x6A20, 0x6E20, 0x7A20, 0x7E20,// Prot. - 0x8A20, 0x8E20, 0x9A20, 0x9E20, 0xAA20, 0xAE20, 0xBA20, 0xBE20,// Prot. - 0xCA20, 0xCE20, 0xDA20, 0xDE20, 0xEA20, 0xEE20, 0xFA20, 0xFE20,// Prot. - 0 -}; - -/* A zero-terminated list of IRQs to be probed. */ -static unsigned short irqlist[] = { - 7, 6, 5, 4, 3, 12, 11, 10, 9, - 0 -}; - -/* A zero-terminated list of DMAs to be probed. */ -static int dmalist[] __initdata = { - 5, 6, 7, - 0 -}; - -static char cardname[] = "Proteon 1392\0"; -static u64 dma_mask = ISA_MAX_ADDRESS; -static int proteon_open(struct net_device *dev); -static void proteon_read_eeprom(struct net_device *dev); -static unsigned short proteon_setnselout_pins(struct net_device *dev); - -static unsigned short proteon_sifreadb(struct net_device *dev, unsigned short reg) -{ - return inb(dev->base_addr + reg); -} - -static unsigned short proteon_sifreadw(struct net_device *dev, unsigned short reg) -{ - return inw(dev->base_addr + reg); -} - -static void proteon_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg) -{ - outb(val, dev->base_addr + reg); -} - -static void proteon_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg) -{ - outw(val, dev->base_addr + reg); -} - -static int __init proteon_probe1(struct net_device *dev, int ioaddr) -{ - unsigned char chk1, chk2; - int i; - - if (!request_region(ioaddr, PROTEON_IO_EXTENT, cardname)) - return -ENODEV; - - - chk1 = inb(ioaddr + 0x1f); /* Get Proteon ID reg 1 */ - if (chk1 != 0x1f) - goto nodev; - - chk1 = inb(ioaddr + 0x1e) & 0x07; /* Get Proteon ID reg 0 */ - for (i=0; i<16; i++) { - chk2 = inb(ioaddr + 0x1e) & 0x07; - if (((chk1 + 1) & 0x07) != chk2) - goto nodev; - chk1 = chk2; - } - - dev->base_addr = ioaddr; - return 0; -nodev: - release_region(ioaddr, PROTEON_IO_EXTENT); - return -ENODEV; -} - -static struct net_device_ops proteon_netdev_ops __read_mostly; - -static int __init setup_card(struct net_device *dev, struct device *pdev) -{ - struct net_local *tp; - static int versionprinted; - const unsigned *port; - int j,err = 0; - - if (!dev) - return -ENOMEM; - - if (dev->base_addr) /* probe specific location */ - err = proteon_probe1(dev, dev->base_addr); - else { - for (port = portlist; *port; port++) { - err = proteon_probe1(dev, *port); - if (!err) - break; - } - } - if (err) - goto out5; - - /* At this point we have found a valid card. */ - - if (versionprinted++ == 0) - printk(KERN_DEBUG "%s", version); - - err = -EIO; - pdev->dma_mask = &dma_mask; - if (tmsdev_init(dev, pdev)) - goto out4; - - dev->base_addr &= ~3; - - proteon_read_eeprom(dev); - - printk(KERN_DEBUG "proteon.c: Ring Station Address: %pM\n", - dev->dev_addr); - - tp = netdev_priv(dev); - tp->setnselout = proteon_setnselout_pins; - - tp->sifreadb = proteon_sifreadb; - tp->sifreadw = proteon_sifreadw; - tp->sifwriteb = proteon_sifwriteb; - tp->sifwritew = proteon_sifwritew; - - memcpy(tp->ProductID, cardname, PROD_ID_SIZE + 1); - - tp->tmspriv = NULL; - - dev->netdev_ops = &proteon_netdev_ops; - - if (dev->irq == 0) - { - for(j = 0; irqlist[j] != 0; j++) - { - dev->irq = irqlist[j]; - if (!request_irq(dev->irq, tms380tr_interrupt, 0, - cardname, dev)) - break; - } - - if(irqlist[j] == 0) - { - printk(KERN_INFO "proteon.c: AutoSelect no IRQ available\n"); - goto out3; - } - } - else - { - for(j = 0; irqlist[j] != 0; j++) - if (irqlist[j] == dev->irq) - break; - if (irqlist[j] == 0) - { - printk(KERN_INFO "proteon.c: Illegal IRQ %d specified\n", - dev->irq); - goto out3; - } - if (request_irq(dev->irq, tms380tr_interrupt, 0, - cardname, dev)) - { - printk(KERN_INFO "proteon.c: Selected IRQ %d not available\n", - dev->irq); - goto out3; - } - } - - if (dev->dma == 0) - { - for(j = 0; dmalist[j] != 0; j++) - { - dev->dma = dmalist[j]; - if (!request_dma(dev->dma, cardname)) - break; - } - - if(dmalist[j] == 0) - { - printk(KERN_INFO "proteon.c: AutoSelect no DMA available\n"); - goto out2; - } - } - else - { - for(j = 0; dmalist[j] != 0; j++) - if (dmalist[j] == dev->dma) - break; - if (dmalist[j] == 0) - { - printk(KERN_INFO "proteon.c: Illegal DMA %d specified\n", - dev->dma); - goto out2; - } - if (request_dma(dev->dma, cardname)) - { - printk(KERN_INFO "proteon.c: Selected DMA %d not available\n", - dev->dma); - goto out2; - } - } - - err = register_netdev(dev); - if (err) - goto out; - - printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n", - dev->name, dev->base_addr, dev->irq, dev->dma); - - return 0; -out: - free_dma(dev->dma); -out2: - free_irq(dev->irq, dev); -out3: - tmsdev_term(dev); -out4: - release_region(dev->base_addr, PROTEON_IO_EXTENT); -out5: - return err; -} - -/* - * Reads MAC address from adapter RAM, which should've read it from - * the onboard ROM. - * - * Calling this on a board that does not support it can be a very - * dangerous thing. The Madge board, for instance, will lock your - * machine hard when this is called. Luckily, its supported in a - * separate driver. --ASF - */ -static void proteon_read_eeprom(struct net_device *dev) -{ - int i; - - /* Address: 0000:0000 */ - proteon_sifwritew(dev, 0, SIFADX); - proteon_sifwritew(dev, 0, SIFADR); - - /* Read six byte MAC address data */ - dev->addr_len = 6; - for(i = 0; i < 6; i++) - dev->dev_addr[i] = proteon_sifreadw(dev, SIFINC) >> 8; -} - -static unsigned short proteon_setnselout_pins(struct net_device *dev) -{ - return 0; -} - -static int proteon_open(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned short val = 0; - int i; - - /* Proteon reset sequence */ - outb(0, dev->base_addr + 0x11); - mdelay(20); - outb(0x04, dev->base_addr + 0x11); - mdelay(20); - outb(0, dev->base_addr + 0x11); - mdelay(100); - - /* set control/status reg */ - val = inb(dev->base_addr + 0x11); - val |= 0x78; - val &= 0xf9; - if(tp->DataRate == SPEED_4) - val |= 0x20; - else - val &= ~0x20; - - outb(val, dev->base_addr + 0x11); - outb(0xff, dev->base_addr + 0x12); - for(i = 0; irqlist[i] != 0; i++) - { - if(irqlist[i] == dev->irq) - break; - } - val = i; - i = (7 - dev->dma) << 4; - val |= i; - outb(val, dev->base_addr + 0x13); - - return tms380tr_open(dev); -} - -#define ISATR_MAX_ADAPTERS 3 - -static int io[ISATR_MAX_ADAPTERS]; -static int irq[ISATR_MAX_ADAPTERS]; -static int dma[ISATR_MAX_ADAPTERS]; - -MODULE_LICENSE("GPL"); - -module_param_array(io, int, NULL, 0); -module_param_array(irq, int, NULL, 0); -module_param_array(dma, int, NULL, 0); - -static struct platform_device *proteon_dev[ISATR_MAX_ADAPTERS]; - -static struct platform_driver proteon_driver = { - .driver = { - .name = "proteon", - }, -}; - -static int __init proteon_init(void) -{ - struct net_device *dev; - struct platform_device *pdev; - int i, num = 0, err = 0; - - proteon_netdev_ops = tms380tr_netdev_ops; - proteon_netdev_ops.ndo_open = proteon_open; - proteon_netdev_ops.ndo_stop = tms380tr_close; - - err = platform_driver_register(&proteon_driver); - if (err) - return err; - - for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { - dev = alloc_trdev(sizeof(struct net_local)); - if (!dev) - continue; - - dev->base_addr = io[i]; - dev->irq = irq[i]; - dev->dma = dma[i]; - pdev = platform_device_register_simple("proteon", - i, NULL, 0); - if (IS_ERR(pdev)) { - free_netdev(dev); - continue; - } - err = setup_card(dev, &pdev->dev); - if (!err) { - proteon_dev[i] = pdev; - platform_set_drvdata(pdev, dev); - ++num; - } else { - platform_device_unregister(pdev); - free_netdev(dev); - } - } - - printk(KERN_NOTICE "proteon.c: %d cards found.\n", num); - /* Probe for cards. */ - if (num == 0) { - printk(KERN_NOTICE "proteon.c: No cards found.\n"); - platform_driver_unregister(&proteon_driver); - return -ENODEV; - } - return 0; -} - -static void __exit proteon_cleanup(void) -{ - struct net_device *dev; - int i; - - for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { - struct platform_device *pdev = proteon_dev[i]; - - if (!pdev) - continue; - dev = platform_get_drvdata(pdev); - unregister_netdev(dev); - release_region(dev->base_addr, PROTEON_IO_EXTENT); - free_irq(dev->irq, dev); - free_dma(dev->dma); - tmsdev_term(dev); - free_netdev(dev); - platform_set_drvdata(pdev, NULL); - platform_device_unregister(pdev); - } - platform_driver_unregister(&proteon_driver); -} - -module_init(proteon_init); -module_exit(proteon_cleanup);
diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c deleted file mode 100644 index ee11e93..0000000 --- a/drivers/net/tokenring/skisa.c +++ /dev/null
@@ -1,432 +0,0 @@ -/* - * skisa.c: A network driver for SK-NET TMS380-based ISA token ring cards. - * - * Based on tmspci written 1999 by Adam Fritzler - * - * Written 2000 by Jochen Friedrich - * Dedicated to my girlfriend Steffi Bopp - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * This driver module supports the following cards: - * - SysKonnect TR4/16(+) ISA (SK-4190) - * - * Maintainer(s): - * AF Adam Fritzler - * JF Jochen Friedrich jochen@scram.de - * - * Modification History: - * 14-Jan-01 JF Created - * 28-Oct-02 JF Fixed probe of card for static compilation. - * Fixed module init to not make hotplug go wild. - * 09-Nov-02 JF Fixed early bail out on out of memory - * situations if multiple cards are found. - * Cleaned up some unnecessary console SPAM. - * 09-Dec-02 JF Fixed module reference counting. - * 02-Jan-03 JF Renamed to skisa.c - * - */ -static const char version[] = "skisa.c: v1.03 09/12/2002 by Jochen Friedrich\n"; - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/netdevice.h> -#include <linux/trdevice.h> -#include <linux/platform_device.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/pci.h> -#include <asm/dma.h> - -#include "tms380tr.h" - -#define SK_ISA_IO_EXTENT 32 - -/* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int portlist[] __initdata = { - 0x0A20, 0x1A20, 0x0B20, 0x1B20, 0x0980, 0x1980, 0x0900, 0x1900,// SK - 0 -}; - -/* A zero-terminated list of IRQs to be probed. - * Used again after initial probe for sktr_chipset_init, called from sktr_open. - */ -static const unsigned short irqlist[] = { - 3, 5, 9, 10, 11, 12, 15, - 0 -}; - -/* A zero-terminated list of DMAs to be probed. */ -static int dmalist[] __initdata = { - 5, 6, 7, - 0 -}; - -static char isa_cardname[] = "SK NET TR 4/16 ISA\0"; -static u64 dma_mask = ISA_MAX_ADDRESS; -static int sk_isa_open(struct net_device *dev); -static void sk_isa_read_eeprom(struct net_device *dev); -static unsigned short sk_isa_setnselout_pins(struct net_device *dev); - -static unsigned short sk_isa_sifreadb(struct net_device *dev, unsigned short reg) -{ - return inb(dev->base_addr + reg); -} - -static unsigned short sk_isa_sifreadw(struct net_device *dev, unsigned short reg) -{ - return inw(dev->base_addr + reg); -} - -static void sk_isa_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg) -{ - outb(val, dev->base_addr + reg); -} - -static void sk_isa_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg) -{ - outw(val, dev->base_addr + reg); -} - - -static int __init sk_isa_probe1(struct net_device *dev, int ioaddr) -{ - unsigned char old, chk1, chk2; - - if (!request_region(ioaddr, SK_ISA_IO_EXTENT, isa_cardname)) - return -ENODEV; - - old = inb(ioaddr + SIFADR); /* Get the old SIFADR value */ - - chk1 = 0; /* Begin with check value 0 */ - do { - /* Write new SIFADR value */ - outb(chk1, ioaddr + SIFADR); - - /* Read, invert and write */ - chk2 = inb(ioaddr + SIFADD); - chk2 ^= 0x0FE; - outb(chk2, ioaddr + SIFADR); - - /* Read, invert and compare */ - chk2 = inb(ioaddr + SIFADD); - chk2 ^= 0x0FE; - - if(chk1 != chk2) { - release_region(ioaddr, SK_ISA_IO_EXTENT); - return -ENODEV; - } - - chk1 -= 2; - } while(chk1 != 0); /* Repeat 128 times (all byte values) */ - - /* Restore the SIFADR value */ - outb(old, ioaddr + SIFADR); - - dev->base_addr = ioaddr; - return 0; -} - -static struct net_device_ops sk_isa_netdev_ops __read_mostly; - -static int __init setup_card(struct net_device *dev, struct device *pdev) -{ - struct net_local *tp; - static int versionprinted; - const unsigned *port; - int j, err = 0; - - if (!dev) - return -ENOMEM; - - if (dev->base_addr) /* probe specific location */ - err = sk_isa_probe1(dev, dev->base_addr); - else { - for (port = portlist; *port; port++) { - err = sk_isa_probe1(dev, *port); - if (!err) - break; - } - } - if (err) - goto out5; - - /* At this point we have found a valid card. */ - - if (versionprinted++ == 0) - printk(KERN_DEBUG "%s", version); - - err = -EIO; - pdev->dma_mask = &dma_mask; - if (tmsdev_init(dev, pdev)) - goto out4; - - dev->base_addr &= ~3; - - sk_isa_read_eeprom(dev); - - printk(KERN_DEBUG "skisa.c: Ring Station Address: %pM\n", - dev->dev_addr); - - tp = netdev_priv(dev); - tp->setnselout = sk_isa_setnselout_pins; - - tp->sifreadb = sk_isa_sifreadb; - tp->sifreadw = sk_isa_sifreadw; - tp->sifwriteb = sk_isa_sifwriteb; - tp->sifwritew = sk_isa_sifwritew; - - memcpy(tp->ProductID, isa_cardname, PROD_ID_SIZE + 1); - - tp->tmspriv = NULL; - - dev->netdev_ops = &sk_isa_netdev_ops; - - if (dev->irq == 0) - { - for(j = 0; irqlist[j] != 0; j++) - { - dev->irq = irqlist[j]; - if (!request_irq(dev->irq, tms380tr_interrupt, 0, - isa_cardname, dev)) - break; - } - - if(irqlist[j] == 0) - { - printk(KERN_INFO "skisa.c: AutoSelect no IRQ available\n"); - goto out3; - } - } - else - { - for(j = 0; irqlist[j] != 0; j++) - if (irqlist[j] == dev->irq) - break; - if (irqlist[j] == 0) - { - printk(KERN_INFO "skisa.c: Illegal IRQ %d specified\n", - dev->irq); - goto out3; - } - if (request_irq(dev->irq, tms380tr_interrupt, 0, - isa_cardname, dev)) - { - printk(KERN_INFO "skisa.c: Selected IRQ %d not available\n", - dev->irq); - goto out3; - } - } - - if (dev->dma == 0) - { - for(j = 0; dmalist[j] != 0; j++) - { - dev->dma = dmalist[j]; - if (!request_dma(dev->dma, isa_cardname)) - break; - } - - if(dmalist[j] == 0) - { - printk(KERN_INFO "skisa.c: AutoSelect no DMA available\n"); - goto out2; - } - } - else - { - for(j = 0; dmalist[j] != 0; j++) - if (dmalist[j] == dev->dma) - break; - if (dmalist[j] == 0) - { - printk(KERN_INFO "skisa.c: Illegal DMA %d specified\n", - dev->dma); - goto out2; - } - if (request_dma(dev->dma, isa_cardname)) - { - printk(KERN_INFO "skisa.c: Selected DMA %d not available\n", - dev->dma); - goto out2; - } - } - - err = register_netdev(dev); - if (err) - goto out; - - printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n", - dev->name, dev->base_addr, dev->irq, dev->dma); - - return 0; -out: - free_dma(dev->dma); -out2: - free_irq(dev->irq, dev); -out3: - tmsdev_term(dev); -out4: - release_region(dev->base_addr, SK_ISA_IO_EXTENT); -out5: - return err; -} - -/* - * Reads MAC address from adapter RAM, which should've read it from - * the onboard ROM. - * - * Calling this on a board that does not support it can be a very - * dangerous thing. The Madge board, for instance, will lock your - * machine hard when this is called. Luckily, its supported in a - * separate driver. --ASF - */ -static void sk_isa_read_eeprom(struct net_device *dev) -{ - int i; - - /* Address: 0000:0000 */ - sk_isa_sifwritew(dev, 0, SIFADX); - sk_isa_sifwritew(dev, 0, SIFADR); - - /* Read six byte MAC address data */ - dev->addr_len = 6; - for(i = 0; i < 6; i++) - dev->dev_addr[i] = sk_isa_sifreadw(dev, SIFINC) >> 8; -} - -static unsigned short sk_isa_setnselout_pins(struct net_device *dev) -{ - return 0; -} - -static int sk_isa_open(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned short val = 0; - unsigned short oldval; - int i; - - val = 0; - for(i = 0; irqlist[i] != 0; i++) - { - if(irqlist[i] == dev->irq) - break; - } - - val |= CYCLE_TIME << 2; - val |= i << 4; - i = dev->dma - 5; - val |= i; - if(tp->DataRate == SPEED_4) - val |= LINE_SPEED_BIT; - else - val &= ~LINE_SPEED_BIT; - oldval = sk_isa_sifreadb(dev, POSREG); - /* Leave cycle bits alone */ - oldval |= 0xf3; - val &= oldval; - sk_isa_sifwriteb(dev, val, POSREG); - - return tms380tr_open(dev); -} - -#define ISATR_MAX_ADAPTERS 3 - -static int io[ISATR_MAX_ADAPTERS]; -static int irq[ISATR_MAX_ADAPTERS]; -static int dma[ISATR_MAX_ADAPTERS]; - -MODULE_LICENSE("GPL"); - -module_param_array(io, int, NULL, 0); -module_param_array(irq, int, NULL, 0); -module_param_array(dma, int, NULL, 0); - -static struct platform_device *sk_isa_dev[ISATR_MAX_ADAPTERS]; - -static struct platform_driver sk_isa_driver = { - .driver = { - .name = "skisa", - }, -}; - -static int __init sk_isa_init(void) -{ - struct net_device *dev; - struct platform_device *pdev; - int i, num = 0, err = 0; - - sk_isa_netdev_ops = tms380tr_netdev_ops; - sk_isa_netdev_ops.ndo_open = sk_isa_open; - sk_isa_netdev_ops.ndo_stop = tms380tr_close; - - err = platform_driver_register(&sk_isa_driver); - if (err) - return err; - - for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { - dev = alloc_trdev(sizeof(struct net_local)); - if (!dev) - continue; - - dev->base_addr = io[i]; - dev->irq = irq[i]; - dev->dma = dma[i]; - pdev = platform_device_register_simple("skisa", - i, NULL, 0); - if (IS_ERR(pdev)) { - free_netdev(dev); - continue; - } - err = setup_card(dev, &pdev->dev); - if (!err) { - sk_isa_dev[i] = pdev; - platform_set_drvdata(sk_isa_dev[i], dev); - ++num; - } else { - platform_device_unregister(pdev); - free_netdev(dev); - } - } - - printk(KERN_NOTICE "skisa.c: %d cards found.\n", num); - /* Probe for cards. */ - if (num == 0) { - printk(KERN_NOTICE "skisa.c: No cards found.\n"); - platform_driver_unregister(&sk_isa_driver); - return -ENODEV; - } - return 0; -} - -static void __exit sk_isa_cleanup(void) -{ - struct net_device *dev; - int i; - - for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { - struct platform_device *pdev = sk_isa_dev[i]; - - if (!pdev) - continue; - dev = platform_get_drvdata(pdev); - unregister_netdev(dev); - release_region(dev->base_addr, SK_ISA_IO_EXTENT); - free_irq(dev->irq, dev); - free_dma(dev->dma); - tmsdev_term(dev); - free_netdev(dev); - platform_set_drvdata(pdev, NULL); - platform_device_unregister(pdev); - } - platform_driver_unregister(&sk_isa_driver); -} - -module_init(sk_isa_init); -module_exit(sk_isa_cleanup);
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c deleted file mode 100644 index cb35fb7..0000000 --- a/drivers/net/tokenring/smctr.c +++ /dev/null
@@ -1,5717 +0,0 @@ -/* - * smctr.c: A network driver for the SMC Token Ring Adapters. - * - * Written by Jay Schulist <jschlst@samba.org> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * This device driver works with the following SMC adapters: - * - SMC TokenCard Elite (8115T, chips 825/584) - * - SMC TokenCard Elite/A MCA (8115T/A, chips 825/594) - * - * Source(s): - * - SMC TokenCard SDK. - * - * Maintainer(s): - * JS Jay Schulist <jschlst@samba.org> - * - * Changes: - * 07102000 JS Fixed a timing problem in smctr_wait_cmd(); - * Also added a bit more discriptive error msgs. - * 07122000 JS Fixed problem with detecting a card with - * module io/irq/mem specified. - * - * To do: - * 1. Multicast support. - * - * Initial 2.5 cleanup Alan Cox <alan@lxorguk.ukuu.org.uk> 2002/10/28 - */ - -#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/in.h> -#include <linux/string.h> -#include <linux/time.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/mca-legacy.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/trdevice.h> -#include <linux/bitops.h> -#include <linux/firmware.h> - -#include <asm/io.h> -#include <asm/dma.h> -#include <asm/irq.h> - -#if BITS_PER_LONG == 64 -#error FIXME: driver does not support 64-bit platforms -#endif - -#include "smctr.h" /* Our Stuff */ - -static const char version[] __initdata = - KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n"; -static const char cardname[] = "smctr"; - - -#define SMCTR_IO_EXTENT 20 - -#ifdef CONFIG_MCA_LEGACY -static unsigned int smctr_posid = 0x6ec6; -#endif - -static int ringspeed; - -/* SMC Name of the Adapter. */ -static char smctr_name[] = "SMC TokenCard"; -static char *smctr_model = "Unknown"; - -/* Use 0 for production, 1 for verification, 2 for debug, and - * 3 for very verbose debug. - */ -#ifndef SMCTR_DEBUG -#define SMCTR_DEBUG 1 -#endif -static unsigned int smctr_debug = SMCTR_DEBUG; - -/* smctr.c prototypes and functions are arranged alphabeticly - * for clearity, maintainability and pure old fashion fun. - */ -/* A */ -static int smctr_alloc_shared_memory(struct net_device *dev); - -/* B */ -static int smctr_bypass_state(struct net_device *dev); - -/* C */ -static int smctr_checksum_firmware(struct net_device *dev); -static int __init smctr_chk_isa(struct net_device *dev); -static int smctr_chg_rx_mask(struct net_device *dev); -static int smctr_clear_int(struct net_device *dev); -static int smctr_clear_trc_reset(int ioaddr); -static int smctr_close(struct net_device *dev); - -/* D */ -static int smctr_decode_firmware(struct net_device *dev, - const struct firmware *fw); -static int smctr_disable_16bit(struct net_device *dev); -static int smctr_disable_adapter_ctrl_store(struct net_device *dev); -static int smctr_disable_bic_int(struct net_device *dev); - -/* E */ -static int smctr_enable_16bit(struct net_device *dev); -static int smctr_enable_adapter_ctrl_store(struct net_device *dev); -static int smctr_enable_adapter_ram(struct net_device *dev); -static int smctr_enable_bic_int(struct net_device *dev); - -/* G */ -static int __init smctr_get_boardid(struct net_device *dev, int mca); -static int smctr_get_group_address(struct net_device *dev); -static int smctr_get_functional_address(struct net_device *dev); -static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev); -static int smctr_get_physical_drop_number(struct net_device *dev); -static __u8 *smctr_get_rx_pointer(struct net_device *dev, short queue); -static int smctr_get_station_id(struct net_device *dev); -static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, - __u16 bytes_count); -static int smctr_get_upstream_neighbor_addr(struct net_device *dev); - -/* H */ -static int smctr_hardware_send_packet(struct net_device *dev, - struct net_local *tp); -/* I */ -static int smctr_init_acbs(struct net_device *dev); -static int smctr_init_adapter(struct net_device *dev); -static int smctr_init_card_real(struct net_device *dev); -static int smctr_init_rx_bdbs(struct net_device *dev); -static int smctr_init_rx_fcbs(struct net_device *dev); -static int smctr_init_shared_memory(struct net_device *dev); -static int smctr_init_tx_bdbs(struct net_device *dev); -static int smctr_init_tx_fcbs(struct net_device *dev); -static int smctr_internal_self_test(struct net_device *dev); -static irqreturn_t smctr_interrupt(int irq, void *dev_id); -static int smctr_issue_enable_int_cmd(struct net_device *dev, - __u16 interrupt_enable_mask); -static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, - __u16 ibits); -static int smctr_issue_init_timers_cmd(struct net_device *dev); -static int smctr_issue_init_txrx_cmd(struct net_device *dev); -static int smctr_issue_insert_cmd(struct net_device *dev); -static int smctr_issue_read_ring_status_cmd(struct net_device *dev); -static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt); -static int smctr_issue_remove_cmd(struct net_device *dev); -static int smctr_issue_resume_acb_cmd(struct net_device *dev); -static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue); -static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue); -static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue); -static int smctr_issue_test_internal_rom_cmd(struct net_device *dev); -static int smctr_issue_test_hic_cmd(struct net_device *dev); -static int smctr_issue_test_mac_reg_cmd(struct net_device *dev); -static int smctr_issue_trc_loopback_cmd(struct net_device *dev); -static int smctr_issue_tri_loopback_cmd(struct net_device *dev); -static int smctr_issue_write_byte_cmd(struct net_device *dev, - short aword_cnt, void *byte); -static int smctr_issue_write_word_cmd(struct net_device *dev, - short aword_cnt, void *word); - -/* J */ -static int smctr_join_complete_state(struct net_device *dev); - -/* L */ -static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev); -static int smctr_load_firmware(struct net_device *dev); -static int smctr_load_node_addr(struct net_device *dev); -static int smctr_lobe_media_test(struct net_device *dev); -static int smctr_lobe_media_test_cmd(struct net_device *dev); -static int smctr_lobe_media_test_state(struct net_device *dev); - -/* M */ -static int smctr_make_8025_hdr(struct net_device *dev, - MAC_HEADER *rmf, MAC_HEADER *tmf, __u16 ac_fc); -static int smctr_make_access_pri(struct net_device *dev, - MAC_SUB_VECTOR *tsv); -static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv); -static int smctr_make_auth_funct_class(struct net_device *dev, - MAC_SUB_VECTOR *tsv); -static int smctr_make_corr(struct net_device *dev, - MAC_SUB_VECTOR *tsv, __u16 correlator); -static int smctr_make_funct_addr(struct net_device *dev, - MAC_SUB_VECTOR *tsv); -static int smctr_make_group_addr(struct net_device *dev, - MAC_SUB_VECTOR *tsv); -static int smctr_make_phy_drop_num(struct net_device *dev, - MAC_SUB_VECTOR *tsv); -static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv); -static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv); -static int smctr_make_ring_station_status(struct net_device *dev, - MAC_SUB_VECTOR *tsv); -static int smctr_make_ring_station_version(struct net_device *dev, - MAC_SUB_VECTOR *tsv); -static int smctr_make_tx_status_code(struct net_device *dev, - MAC_SUB_VECTOR *tsv, __u16 tx_fstatus); -static int smctr_make_upstream_neighbor_addr(struct net_device *dev, - MAC_SUB_VECTOR *tsv); -static int smctr_make_wrap_data(struct net_device *dev, - MAC_SUB_VECTOR *tsv); - -/* O */ -static int smctr_open(struct net_device *dev); -static int smctr_open_tr(struct net_device *dev); - -/* P */ -struct net_device *smctr_probe(int unit); -static int __init smctr_probe1(struct net_device *dev, int ioaddr); -static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, - struct net_device *dev, __u16 rx_status); - -/* R */ -static int smctr_ram_memory_test(struct net_device *dev); -static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf, - __u16 *correlator); -static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf, - __u16 *correlator); -static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf); -static int smctr_rcv_rq_addr_state_attch(struct net_device *dev, - MAC_HEADER *rmf, __u16 *correlator); -static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf, - __u16 *correlator); -static int smctr_reset_adapter(struct net_device *dev); -static int smctr_restart_tx_chain(struct net_device *dev, short queue); -static int smctr_ring_status_chg(struct net_device *dev); -static int smctr_rx_frame(struct net_device *dev); - -/* S */ -static int smctr_send_dat(struct net_device *dev); -static netdev_tx_t smctr_send_packet(struct sk_buff *skb, - struct net_device *dev); -static int smctr_send_lobe_media_test(struct net_device *dev); -static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf, - __u16 correlator); -static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf, - __u16 correlator); -static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf, - __u16 correlator); -static int smctr_send_rpt_tx_forward(struct net_device *dev, - MAC_HEADER *rmf, __u16 tx_fstatus); -static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf, - __u16 rcode, __u16 correlator); -static int smctr_send_rq_init(struct net_device *dev); -static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, - __u16 *tx_fstatus); -static int smctr_set_auth_access_pri(struct net_device *dev, - MAC_SUB_VECTOR *rsv); -static int smctr_set_auth_funct_class(struct net_device *dev, - MAC_SUB_VECTOR *rsv); -static int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv, - __u16 *correlator); -static int smctr_set_error_timer_value(struct net_device *dev, - MAC_SUB_VECTOR *rsv); -static int smctr_set_frame_forward(struct net_device *dev, - MAC_SUB_VECTOR *rsv, __u8 dc_sc); -static int smctr_set_local_ring_num(struct net_device *dev, - MAC_SUB_VECTOR *rsv); -static unsigned short smctr_set_ctrl_attention(struct net_device *dev); -static void smctr_set_multicast_list(struct net_device *dev); -static int smctr_set_page(struct net_device *dev, __u8 *buf); -static int smctr_set_phy_drop(struct net_device *dev, - MAC_SUB_VECTOR *rsv); -static int smctr_set_ring_speed(struct net_device *dev); -static int smctr_set_rx_look_ahead(struct net_device *dev); -static int smctr_set_trc_reset(int ioaddr); -static int smctr_setup_single_cmd(struct net_device *dev, - __u16 command, __u16 subcommand); -static int smctr_setup_single_cmd_w_data(struct net_device *dev, - __u16 command, __u16 subcommand); -static char *smctr_malloc(struct net_device *dev, __u16 size); -static int smctr_status_chg(struct net_device *dev); - -/* T */ -static void smctr_timeout(struct net_device *dev); -static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb, - __u16 queue); -static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue); -static unsigned short smctr_tx_move_frame(struct net_device *dev, - struct sk_buff *skb, __u8 *pbuff, unsigned int bytes); - -/* U */ -static int smctr_update_err_stats(struct net_device *dev); -static int smctr_update_rx_chain(struct net_device *dev, __u16 queue); -static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, - __u16 queue); - -/* W */ -static int smctr_wait_cmd(struct net_device *dev); -static int smctr_wait_while_cbusy(struct net_device *dev); - -#define TO_256_BYTE_BOUNDRY(X) (((X + 0xff) & 0xff00) - X) -#define TO_PARAGRAPH_BOUNDRY(X) (((X + 0x0f) & 0xfff0) - X) -#define PARAGRAPH_BOUNDRY(X) smctr_malloc(dev, TO_PARAGRAPH_BOUNDRY(X)) - -/* Allocate Adapter Shared Memory. - * IMPORTANT NOTE: Any changes to this function MUST be mirrored in the - * function "get_num_rx_bdbs" below!!! - * - * Order of memory allocation: - * - * 0. Initial System Configuration Block Pointer - * 1. System Configuration Block - * 2. System Control Block - * 3. Action Command Block - * 4. Interrupt Status Block - * - * 5. MAC TX FCB'S - * 6. NON-MAC TX FCB'S - * 7. MAC TX BDB'S - * 8. NON-MAC TX BDB'S - * 9. MAC RX FCB'S - * 10. NON-MAC RX FCB'S - * 11. MAC RX BDB'S - * 12. NON-MAC RX BDB'S - * 13. MAC TX Data Buffer( 1, 256 byte buffer) - * 14. MAC RX Data Buffer( 1, 256 byte buffer) - * - * 15. NON-MAC TX Data Buffer - * 16. NON-MAC RX Data Buffer - */ -static int smctr_alloc_shared_memory(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_alloc_shared_memory\n", dev->name); - - /* Allocate initial System Control Block pointer. - * This pointer is located in the last page, last offset - 4. - */ - tp->iscpb_ptr = (ISCPBlock *)(tp->ram_access + ((__u32)64 * 0x400) - - (long)ISCP_BLOCK_SIZE); - - /* Allocate System Control Blocks. */ - tp->scgb_ptr = (SCGBlock *)smctr_malloc(dev, sizeof(SCGBlock)); - PARAGRAPH_BOUNDRY(tp->sh_mem_used); - - tp->sclb_ptr = (SCLBlock *)smctr_malloc(dev, sizeof(SCLBlock)); - PARAGRAPH_BOUNDRY(tp->sh_mem_used); - - tp->acb_head = (ACBlock *)smctr_malloc(dev, - sizeof(ACBlock)*tp->num_acbs); - PARAGRAPH_BOUNDRY(tp->sh_mem_used); - - tp->isb_ptr = (ISBlock *)smctr_malloc(dev, sizeof(ISBlock)); - PARAGRAPH_BOUNDRY(tp->sh_mem_used); - - tp->misc_command_data = (__u16 *)smctr_malloc(dev, MISC_DATA_SIZE); - PARAGRAPH_BOUNDRY(tp->sh_mem_used); - - /* Allocate transmit FCBs. */ - tp->tx_fcb_head[MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, - sizeof(FCBlock) * tp->num_tx_fcbs[MAC_QUEUE]); - - tp->tx_fcb_head[NON_MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, - sizeof(FCBlock) * tp->num_tx_fcbs[NON_MAC_QUEUE]); - - tp->tx_fcb_head[BUG_QUEUE] = (FCBlock *)smctr_malloc(dev, - sizeof(FCBlock) * tp->num_tx_fcbs[BUG_QUEUE]); - - /* Allocate transmit BDBs. */ - tp->tx_bdb_head[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, - sizeof(BDBlock) * tp->num_tx_bdbs[MAC_QUEUE]); - - tp->tx_bdb_head[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, - sizeof(BDBlock) * tp->num_tx_bdbs[NON_MAC_QUEUE]); - - tp->tx_bdb_head[BUG_QUEUE] = (BDBlock *)smctr_malloc(dev, - sizeof(BDBlock) * tp->num_tx_bdbs[BUG_QUEUE]); - - /* Allocate receive FCBs. */ - tp->rx_fcb_head[MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, - sizeof(FCBlock) * tp->num_rx_fcbs[MAC_QUEUE]); - - tp->rx_fcb_head[NON_MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, - sizeof(FCBlock) * tp->num_rx_fcbs[NON_MAC_QUEUE]); - - /* Allocate receive BDBs. */ - tp->rx_bdb_head[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, - sizeof(BDBlock) * tp->num_rx_bdbs[MAC_QUEUE]); - - tp->rx_bdb_end[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 0); - - tp->rx_bdb_head[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, - sizeof(BDBlock) * tp->num_rx_bdbs[NON_MAC_QUEUE]); - - tp->rx_bdb_end[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 0); - - /* Allocate MAC transmit buffers. - * MAC Tx Buffers doen't have to be on an ODD Boundary. - */ - tp->tx_buff_head[MAC_QUEUE] - = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[MAC_QUEUE]); - tp->tx_buff_curr[MAC_QUEUE] = tp->tx_buff_head[MAC_QUEUE]; - tp->tx_buff_end [MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); - - /* Allocate BUG transmit buffers. */ - tp->tx_buff_head[BUG_QUEUE] - = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[BUG_QUEUE]); - tp->tx_buff_curr[BUG_QUEUE] = tp->tx_buff_head[BUG_QUEUE]; - tp->tx_buff_end[BUG_QUEUE] = (__u16 *)smctr_malloc(dev, 0); - - /* Allocate MAC receive data buffers. - * MAC Rx buffer doesn't have to be on a 256 byte boundary. - */ - tp->rx_buff_head[MAC_QUEUE] = (__u16 *)smctr_malloc(dev, - RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[MAC_QUEUE]); - tp->rx_buff_end[MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); - - /* Allocate Non-MAC transmit buffers. - * ?? For maximum Netware performance, put Tx Buffers on - * ODD Boundary and then restore malloc to Even Boundrys. - */ - smctr_malloc(dev, 1L); - tp->tx_buff_head[NON_MAC_QUEUE] - = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[NON_MAC_QUEUE]); - tp->tx_buff_curr[NON_MAC_QUEUE] = tp->tx_buff_head[NON_MAC_QUEUE]; - tp->tx_buff_end [NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); - smctr_malloc(dev, 1L); - - /* Allocate Non-MAC receive data buffers. - * To guarantee a minimum of 256 contiguous memory to - * UM_Receive_Packet's lookahead pointer, before a page - * change or ring end is encountered, place each rx buffer on - * a 256 byte boundary. - */ - smctr_malloc(dev, TO_256_BYTE_BOUNDRY(tp->sh_mem_used)); - tp->rx_buff_head[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, - RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[NON_MAC_QUEUE]); - tp->rx_buff_end[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); - - return 0; -} - -/* Enter Bypass state. */ -static int smctr_bypass_state(struct net_device *dev) -{ - int err; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_bypass_state\n", dev->name); - - err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, JS_BYPASS_STATE); - - return err; -} - -static int smctr_checksum_firmware(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - __u16 i, checksum = 0; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_checksum_firmware\n", dev->name); - - smctr_enable_adapter_ctrl_store(dev); - - for(i = 0; i < CS_RAM_SIZE; i += 2) - checksum += *((__u16 *)(tp->ram_access + i)); - - tp->microcode_version = *(__u16 *)(tp->ram_access - + CS_RAM_VERSION_OFFSET); - tp->microcode_version >>= 8; - - smctr_disable_adapter_ctrl_store(dev); - - if(checksum) - return checksum; - - return 0; -} - -static int __init smctr_chk_mca(struct net_device *dev) -{ -#ifdef CONFIG_MCA_LEGACY - struct net_local *tp = netdev_priv(dev); - int current_slot; - __u8 r1, r2, r3, r4, r5; - - current_slot = mca_find_unused_adapter(smctr_posid, 0); - if(current_slot == MCA_NOTFOUND) - return -ENODEV; - - mca_set_adapter_name(current_slot, smctr_name); - mca_mark_as_used(current_slot); - tp->slot_num = current_slot; - - r1 = mca_read_stored_pos(tp->slot_num, 2); - r2 = mca_read_stored_pos(tp->slot_num, 3); - - if(tp->slot_num) - outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num - 1) | CNFG_SLOT_ENABLE_BIT)); - else - outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num) | CNFG_SLOT_ENABLE_BIT)); - - r1 = inb(CNFG_POS_REG1); - r2 = inb(CNFG_POS_REG0); - - tp->bic_type = BIC_594_CHIP; - - /* IO */ - r2 = mca_read_stored_pos(tp->slot_num, 2); - r2 &= 0xF0; - dev->base_addr = ((__u16)r2 << 8) + (__u16)0x800; - request_region(dev->base_addr, SMCTR_IO_EXTENT, smctr_name); - - /* IRQ */ - r5 = mca_read_stored_pos(tp->slot_num, 5); - r5 &= 0xC; - switch(r5) - { - case 0: - dev->irq = 3; - break; - - case 0x4: - dev->irq = 4; - break; - - case 0x8: - dev->irq = 10; - break; - - default: - dev->irq = 15; - break; - } - if (request_irq(dev->irq, smctr_interrupt, IRQF_SHARED, smctr_name, dev)) { - release_region(dev->base_addr, SMCTR_IO_EXTENT); - return -ENODEV; - } - - /* Get RAM base */ - r3 = mca_read_stored_pos(tp->slot_num, 3); - tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0x0C0000; - if (r3 & 0x8) - tp->ram_base += 0x010000; - if (r3 & 0x80) - tp->ram_base += 0xF00000; - - /* Get Ram Size */ - r3 &= 0x30; - r3 >>= 4; - - tp->ram_usable = (__u16)CNFG_SIZE_8KB << r3; - tp->ram_size = (__u16)CNFG_SIZE_64KB; - tp->board_id |= TOKEN_MEDIA; - - r4 = mca_read_stored_pos(tp->slot_num, 4); - tp->rom_base = ((__u32)(r4 & 0x7) << 13) + 0x0C0000; - if (r4 & 0x8) - tp->rom_base += 0x010000; - - /* Get ROM size. */ - r4 >>= 4; - switch (r4) { - case 0: - tp->rom_size = CNFG_SIZE_8KB; - break; - case 1: - tp->rom_size = CNFG_SIZE_16KB; - break; - case 2: - tp->rom_size = CNFG_SIZE_32KB; - break; - default: - tp->rom_size = ROM_DISABLE; - } - - /* Get Media Type. */ - r5 = mca_read_stored_pos(tp->slot_num, 5); - r5 &= CNFG_MEDIA_TYPE_MASK; - switch(r5) - { - case (0): - tp->media_type = MEDIA_STP_4; - break; - - case (1): - tp->media_type = MEDIA_STP_16; - break; - - case (3): - tp->media_type = MEDIA_UTP_16; - break; - - default: - tp->media_type = MEDIA_UTP_4; - break; - } - tp->media_menu = 14; - - r2 = mca_read_stored_pos(tp->slot_num, 2); - if(!(r2 & 0x02)) - tp->mode_bits |= EARLY_TOKEN_REL; - - /* Disable slot */ - outb(CNFG_POS_CONTROL_REG, 0); - - tp->board_id = smctr_get_boardid(dev, 1); - switch(tp->board_id & 0xffff) - { - case WD8115TA: - smctr_model = "8115T/A"; - break; - - case WD8115T: - if(tp->extra_info & CHIP_REV_MASK) - smctr_model = "8115T rev XE"; - else - smctr_model = "8115T rev XD"; - break; - - default: - smctr_model = "Unknown"; - break; - } - - return 0; -#else - return -1; -#endif /* CONFIG_MCA_LEGACY */ -} - -static int smctr_chg_rx_mask(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int err = 0; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_chg_rx_mask\n", dev->name); - - smctr_enable_16bit(dev); - smctr_set_page(dev, (__u8 *)tp->ram_access); - - if(tp->mode_bits & LOOPING_MODE_MASK) - tp->config_word0 |= RX_OWN_BIT; - else - tp->config_word0 &= ~RX_OWN_BIT; - - if(tp->receive_mask & PROMISCUOUS_MODE) - tp->config_word0 |= PROMISCUOUS_BIT; - else - tp->config_word0 &= ~PROMISCUOUS_BIT; - - if(tp->receive_mask & ACCEPT_ERR_PACKETS) - tp->config_word0 |= SAVBAD_BIT; - else - tp->config_word0 &= ~SAVBAD_BIT; - - if(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES) - tp->config_word0 |= RXATMAC; - else - tp->config_word0 &= ~RXATMAC; - - if(tp->receive_mask & ACCEPT_MULTI_PROM) - tp->config_word1 |= MULTICAST_ADDRESS_BIT; - else - tp->config_word1 &= ~MULTICAST_ADDRESS_BIT; - - if(tp->receive_mask & ACCEPT_SOURCE_ROUTING_SPANNING) - tp->config_word1 |= SOURCE_ROUTING_SPANNING_BITS; - else - { - if(tp->receive_mask & ACCEPT_SOURCE_ROUTING) - tp->config_word1 |= SOURCE_ROUTING_EXPLORER_BIT; - else - tp->config_word1 &= ~SOURCE_ROUTING_SPANNING_BITS; - } - - if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_0, - &tp->config_word0))) - { - return err; - } - - if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_1, - &tp->config_word1))) - { - return err; - } - - smctr_disable_16bit(dev); - - return 0; -} - -static int smctr_clear_int(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - - outb((tp->trc_mask | CSR_CLRTINT), dev->base_addr + CSR); - - return 0; -} - -static int smctr_clear_trc_reset(int ioaddr) -{ - __u8 r; - - r = inb(ioaddr + MSR); - outb(~MSR_RST & r, ioaddr + MSR); - - return 0; -} - -/* - * The inverse routine to smctr_open(). - */ -static int smctr_close(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - struct sk_buff *skb; - int err; - - netif_stop_queue(dev); - - tp->cleanup = 1; - - /* Check to see if adapter is already in a closed state. */ - if(tp->status != OPEN) - return 0; - - smctr_enable_16bit(dev); - smctr_set_page(dev, (__u8 *)tp->ram_access); - - if((err = smctr_issue_remove_cmd(dev))) - { - smctr_disable_16bit(dev); - return err; - } - - for(;;) - { - skb = skb_dequeue(&tp->SendSkbQueue); - if(skb == NULL) - break; - tp->QueueSkb++; - dev_kfree_skb(skb); - } - - - return 0; -} - -static int smctr_decode_firmware(struct net_device *dev, - const struct firmware *fw) -{ - struct net_local *tp = netdev_priv(dev); - short bit = 0x80, shift = 12; - DECODE_TREE_NODE *tree; - short branch, tsize; - __u16 buff = 0; - long weight; - __u8 *ucode; - __u16 *mem; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_decode_firmware\n", dev->name); - - weight = *(long *)(fw->data + WEIGHT_OFFSET); - tsize = *(__u8 *)(fw->data + TREE_SIZE_OFFSET); - tree = (DECODE_TREE_NODE *)(fw->data + TREE_OFFSET); - ucode = (__u8 *)(fw->data + TREE_OFFSET - + (tsize * sizeof(DECODE_TREE_NODE))); - mem = (__u16 *)(tp->ram_access); - - while(weight) - { - branch = ROOT; - while((tree + branch)->tag != LEAF && weight) - { - branch = *ucode & bit ? (tree + branch)->llink - : (tree + branch)->rlink; - - bit >>= 1; - weight--; - - if(bit == 0) - { - bit = 0x80; - ucode++; - } - } - - buff |= (tree + branch)->info << shift; - shift -= 4; - - if(shift < 0) - { - *(mem++) = SWAP_BYTES(buff); - buff = 0; - shift = 12; - } - } - - /* The following assumes the Control Store Memory has - * been initialized to zero. If the last partial word - * is zero, it will not be written. - */ - if(buff) - *(mem++) = SWAP_BYTES(buff); - - return 0; -} - -static int smctr_disable_16bit(struct net_device *dev) -{ - return 0; -} - -/* - * On Exit, Adapter is: - * 1. TRC is in a reset state and un-initialized. - * 2. Adapter memory is enabled. - * 3. Control Store memory is out of context (-WCSS is 1). - */ -static int smctr_disable_adapter_ctrl_store(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int ioaddr = dev->base_addr; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_disable_adapter_ctrl_store\n", dev->name); - - tp->trc_mask |= CSR_WCSS; - outb(tp->trc_mask, ioaddr + CSR); - - return 0; -} - -static int smctr_disable_bic_int(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int ioaddr = dev->base_addr; - - tp->trc_mask = CSR_MSK_ALL | CSR_MSKCBUSY - | CSR_MSKTINT | CSR_WCSS; - outb(tp->trc_mask, ioaddr + CSR); - - return 0; -} - -static int smctr_enable_16bit(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - __u8 r; - - if(tp->adapter_bus == BUS_ISA16_TYPE) - { - r = inb(dev->base_addr + LAAR); - outb((r | LAAR_MEM16ENB), dev->base_addr + LAAR); - } - - return 0; -} - -/* - * To enable the adapter control store memory: - * 1. Adapter must be in a RESET state. - * 2. Adapter memory must be enabled. - * 3. Control Store Memory is in context (-WCSS is 0). - */ -static int smctr_enable_adapter_ctrl_store(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int ioaddr = dev->base_addr; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_enable_adapter_ctrl_store\n", dev->name); - - smctr_set_trc_reset(ioaddr); - smctr_enable_adapter_ram(dev); - - tp->trc_mask &= ~CSR_WCSS; - outb(tp->trc_mask, ioaddr + CSR); - - return 0; -} - -static int smctr_enable_adapter_ram(struct net_device *dev) -{ - int ioaddr = dev->base_addr; - __u8 r; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_enable_adapter_ram\n", dev->name); - - r = inb(ioaddr + MSR); - outb(MSR_MEMB | r, ioaddr + MSR); - - return 0; -} - -static int smctr_enable_bic_int(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int ioaddr = dev->base_addr; - __u8 r; - - switch(tp->bic_type) - { - case (BIC_584_CHIP): - tp->trc_mask = CSR_MSKCBUSY | CSR_WCSS; - outb(tp->trc_mask, ioaddr + CSR); - r = inb(ioaddr + IRR); - outb(r | IRR_IEN, ioaddr + IRR); - break; - - case (BIC_594_CHIP): - tp->trc_mask = CSR_MSKCBUSY | CSR_WCSS; - outb(tp->trc_mask, ioaddr + CSR); - r = inb(ioaddr + IMCCR); - outb(r | IMCCR_EIL, ioaddr + IMCCR); - break; - } - - return 0; -} - -static int __init smctr_chk_isa(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int ioaddr = dev->base_addr; - __u8 r1, r2, b, chksum = 0; - __u16 r; - int i; - int err = -ENODEV; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_chk_isa %#4x\n", dev->name, ioaddr); - - if((ioaddr & 0x1F) != 0) - goto out; - - /* Grab the region so that no one else tries to probe our ioports. */ - if (!request_region(ioaddr, SMCTR_IO_EXTENT, smctr_name)) { - err = -EBUSY; - goto out; - } - - /* Checksum SMC node address */ - for(i = 0; i < 8; i++) - { - b = inb(ioaddr + LAR0 + i); - chksum += b; - } - - if (chksum != NODE_ADDR_CKSUM) - goto out2; - - b = inb(ioaddr + BDID); - if(b != BRD_ID_8115T) - { - printk(KERN_ERR "%s: The adapter found is not supported\n", dev->name); - goto out2; - } - - /* Check for 8115T Board ID */ - r2 = 0; - for(r = 0; r < 8; r++) - { - r1 = inb(ioaddr + 0x8 + r); - r2 += r1; - } - - /* value of RegF adds up the sum to 0xFF */ - if((r2 != 0xFF) && (r2 != 0xEE)) - goto out2; - - /* Get adapter ID */ - tp->board_id = smctr_get_boardid(dev, 0); - switch(tp->board_id & 0xffff) - { - case WD8115TA: - smctr_model = "8115T/A"; - break; - - case WD8115T: - if(tp->extra_info & CHIP_REV_MASK) - smctr_model = "8115T rev XE"; - else - smctr_model = "8115T rev XD"; - break; - - default: - smctr_model = "Unknown"; - break; - } - - /* Store BIC type. */ - tp->bic_type = BIC_584_CHIP; - tp->nic_type = NIC_825_CHIP; - - /* Copy Ram Size */ - tp->ram_usable = CNFG_SIZE_16KB; - tp->ram_size = CNFG_SIZE_64KB; - - /* Get 58x Ram Base */ - r1 = inb(ioaddr); - r1 &= 0x3F; - - r2 = inb(ioaddr + CNFG_LAAR_584); - r2 &= CNFG_LAAR_MASK; - r2 <<= 3; - r2 |= ((r1 & 0x38) >> 3); - - tp->ram_base = ((__u32)r2 << 16) + (((__u32)(r1 & 0x7)) << 13); - - /* Get 584 Irq */ - r1 = 0; - r1 = inb(ioaddr + CNFG_ICR_583); - r1 &= CNFG_ICR_IR2_584; - - r2 = inb(ioaddr + CNFG_IRR_583); - r2 &= CNFG_IRR_IRQS; /* 0x60 */ - r2 >>= 5; - - switch(r2) - { - case 0: - if(r1 == 0) - dev->irq = 2; - else - dev->irq = 10; - break; - - case 1: - if(r1 == 0) - dev->irq = 3; - else - dev->irq = 11; - break; - - case 2: - if(r1 == 0) - { - if(tp->extra_info & ALTERNATE_IRQ_BIT) - dev->irq = 5; - else - dev->irq = 4; - } - else - dev->irq = 15; - break; - - case 3: - if(r1 == 0) - dev->irq = 7; - else - dev->irq = 4; - break; - - default: - printk(KERN_ERR "%s: No IRQ found aborting\n", dev->name); - goto out2; - } - - if (request_irq(dev->irq, smctr_interrupt, IRQF_SHARED, smctr_name, dev)) - goto out2; - - /* Get 58x Rom Base */ - r1 = inb(ioaddr + CNFG_BIO_583); - r1 &= 0x3E; - r1 |= 0x40; - - tp->rom_base = (__u32)r1 << 13; - - /* Get 58x Rom Size */ - r1 = inb(ioaddr + CNFG_BIO_583); - r1 &= 0xC0; - if(r1 == 0) - tp->rom_size = ROM_DISABLE; - else - { - r1 >>= 6; - tp->rom_size = (__u16)CNFG_SIZE_8KB << r1; - } - - /* Get 58x Boot Status */ - r1 = inb(ioaddr + CNFG_GP2); - - tp->mode_bits &= (~BOOT_STATUS_MASK); - - if(r1 & CNFG_GP2_BOOT_NIBBLE) - tp->mode_bits |= BOOT_TYPE_1; - - /* Get 58x Zero Wait State */ - tp->mode_bits &= (~ZERO_WAIT_STATE_MASK); - - r1 = inb(ioaddr + CNFG_IRR_583); - - if(r1 & CNFG_IRR_ZWS) - tp->mode_bits |= ZERO_WAIT_STATE_8_BIT; - - if(tp->board_id & BOARD_16BIT) - { - r1 = inb(ioaddr + CNFG_LAAR_584); - - if(r1 & CNFG_LAAR_ZWS) - tp->mode_bits |= ZERO_WAIT_STATE_16_BIT; - } - - /* Get 584 Media Menu */ - tp->media_menu = 14; - r1 = inb(ioaddr + CNFG_IRR_583); - - tp->mode_bits &= 0xf8ff; /* (~CNFG_INTERFACE_TYPE_MASK) */ - if((tp->board_id & TOKEN_MEDIA) == TOKEN_MEDIA) - { - /* Get Advanced Features */ - if(((r1 & 0x6) >> 1) == 0x3) - tp->media_type |= MEDIA_UTP_16; - else - { - if(((r1 & 0x6) >> 1) == 0x2) - tp->media_type |= MEDIA_STP_16; - else - { - if(((r1 & 0x6) >> 1) == 0x1) - tp->media_type |= MEDIA_UTP_4; - - else - tp->media_type |= MEDIA_STP_4; - } - } - - r1 = inb(ioaddr + CNFG_GP2); - if(!(r1 & 0x2) ) /* GP2_ETRD */ - tp->mode_bits |= EARLY_TOKEN_REL; - - /* see if the chip is corrupted - if(smctr_read_584_chksum(ioaddr)) - { - printk(KERN_ERR "%s: EEPROM Checksum Failure\n", dev->name); - free_irq(dev->irq, dev); - goto out2; - } - */ - } - - return 0; - -out2: - release_region(ioaddr, SMCTR_IO_EXTENT); -out: - return err; -} - -static int __init smctr_get_boardid(struct net_device *dev, int mca) -{ - struct net_local *tp = netdev_priv(dev); - int ioaddr = dev->base_addr; - __u8 r, r1, IdByte; - __u16 BoardIdMask; - - tp->board_id = BoardIdMask = 0; - - if(mca) - { - BoardIdMask |= (MICROCHANNEL+INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT); - tp->extra_info |= (INTERFACE_594_CHIP+RAM_SIZE_64K+NIC_825_BIT+ALTERNATE_IRQ_BIT+SLOT_16BIT); - } - else - { - BoardIdMask|=(INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT); - tp->extra_info |= (INTERFACE_584_CHIP + RAM_SIZE_64K - + NIC_825_BIT + ALTERNATE_IRQ_BIT); - } - - if(!mca) - { - r = inb(ioaddr + BID_REG_1); - r &= 0x0c; - outb(r, ioaddr + BID_REG_1); - r = inb(ioaddr + BID_REG_1); - - if(r & BID_SIXTEEN_BIT_BIT) - { - tp->extra_info |= SLOT_16BIT; - tp->adapter_bus = BUS_ISA16_TYPE; - } - else - tp->adapter_bus = BUS_ISA8_TYPE; - } - else - tp->adapter_bus = BUS_MCA_TYPE; - - /* Get Board Id Byte */ - IdByte = inb(ioaddr + BID_BOARD_ID_BYTE); - - /* if Major version > 1.0 then - * return; - */ - if(IdByte & 0xF8) - return -1; - - r1 = inb(ioaddr + BID_REG_1); - r1 &= BID_ICR_MASK; - r1 |= BID_OTHER_BIT; - - outb(r1, ioaddr + BID_REG_1); - r1 = inb(ioaddr + BID_REG_3); - - r1 &= BID_EAR_MASK; - r1 |= BID_ENGR_PAGE; - - outb(r1, ioaddr + BID_REG_3); - r1 = inb(ioaddr + BID_REG_1); - r1 &= BID_ICR_MASK; - r1 |= (BID_RLA | BID_OTHER_BIT); - - outb(r1, ioaddr + BID_REG_1); - - r1 = inb(ioaddr + BID_REG_1); - while(r1 & BID_RECALL_DONE_MASK) - r1 = inb(ioaddr + BID_REG_1); - - r = inb(ioaddr + BID_LAR_0 + BID_REG_6); - - /* clear chip rev bits */ - tp->extra_info &= ~CHIP_REV_MASK; - tp->extra_info |= ((r & BID_EEPROM_CHIP_REV_MASK) << 6); - - r1 = inb(ioaddr + BID_REG_1); - r1 &= BID_ICR_MASK; - r1 |= BID_OTHER_BIT; - - outb(r1, ioaddr + BID_REG_1); - r1 = inb(ioaddr + BID_REG_3); - - r1 &= BID_EAR_MASK; - r1 |= BID_EA6; - - outb(r1, ioaddr + BID_REG_3); - r1 = inb(ioaddr + BID_REG_1); - - r1 &= BID_ICR_MASK; - r1 |= BID_RLA; - - outb(r1, ioaddr + BID_REG_1); - r1 = inb(ioaddr + BID_REG_1); - - while(r1 & BID_RECALL_DONE_MASK) - r1 = inb(ioaddr + BID_REG_1); - - return BoardIdMask; -} - -static int smctr_get_group_address(struct net_device *dev) -{ - smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_GROUP_ADDR); - - return smctr_wait_cmd(dev); -} - -static int smctr_get_functional_address(struct net_device *dev) -{ - smctr_issue_read_word_cmd(dev, RW_FUNCTIONAL_ADDR); - - return smctr_wait_cmd(dev); -} - -/* Calculate number of Non-MAC receive BDB's and data buffers. - * This function must simulate allocateing shared memory exactly - * as the allocate_shared_memory function above. - */ -static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int mem_used = 0; - - /* Allocate System Control Blocks. */ - mem_used += sizeof(SCGBlock); - - mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); - mem_used += sizeof(SCLBlock); - - mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); - mem_used += sizeof(ACBlock) * tp->num_acbs; - - mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); - mem_used += sizeof(ISBlock); - - mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); - mem_used += MISC_DATA_SIZE; - - /* Allocate transmit FCB's. */ - mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); - - mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[MAC_QUEUE]; - mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[NON_MAC_QUEUE]; - mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[BUG_QUEUE]; - - /* Allocate transmit BDBs. */ - mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[MAC_QUEUE]; - mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[NON_MAC_QUEUE]; - mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[BUG_QUEUE]; - - /* Allocate receive FCBs. */ - mem_used += sizeof(FCBlock) * tp->num_rx_fcbs[MAC_QUEUE]; - mem_used += sizeof(FCBlock) * tp->num_rx_fcbs[NON_MAC_QUEUE]; - - /* Allocate receive BDBs. */ - mem_used += sizeof(BDBlock) * tp->num_rx_bdbs[MAC_QUEUE]; - - /* Allocate MAC transmit buffers. - * MAC transmit buffers don't have to be on an ODD Boundary. - */ - mem_used += tp->tx_buff_size[MAC_QUEUE]; - - /* Allocate BUG transmit buffers. */ - mem_used += tp->tx_buff_size[BUG_QUEUE]; - - /* Allocate MAC receive data buffers. - * MAC receive buffers don't have to be on a 256 byte boundary. - */ - mem_used += RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[MAC_QUEUE]; - - /* Allocate Non-MAC transmit buffers. - * For maximum Netware performance, put Tx Buffers on - * ODD Boundary,and then restore malloc to Even Boundrys. - */ - mem_used += 1L; - mem_used += tp->tx_buff_size[NON_MAC_QUEUE]; - mem_used += 1L; - - /* CALCULATE NUMBER OF NON-MAC RX BDB'S - * AND NON-MAC RX DATA BUFFERS - * - * Make sure the mem_used offset at this point is the - * same as in allocate_shared memory or the following - * boundary adjustment will be incorrect (i.e. not allocating - * the non-mac receive buffers above cannot change the 256 - * byte offset). - * - * Since this cannot be guaranteed, adding the full 256 bytes - * to the amount of shared memory used at this point will guaranteed - * that the rx data buffers do not overflow shared memory. - */ - mem_used += 0x100; - - return (0xffff - mem_used) / (RX_DATA_BUFFER_SIZE + sizeof(BDBlock)); -} - -static int smctr_get_physical_drop_number(struct net_device *dev) -{ - smctr_issue_read_word_cmd(dev, RW_PHYSICAL_DROP_NUMBER); - - return smctr_wait_cmd(dev); -} - -static __u8 * smctr_get_rx_pointer(struct net_device *dev, short queue) -{ - struct net_local *tp = netdev_priv(dev); - BDBlock *bdb; - - bdb = (BDBlock *)((__u32)tp->ram_access - + (__u32)(tp->rx_fcb_curr[queue]->trc_bdb_ptr)); - - tp->rx_fcb_curr[queue]->bdb_ptr = bdb; - - return (__u8 *)bdb->data_block_ptr; -} - -static int smctr_get_station_id(struct net_device *dev) -{ - smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_MAC_ADDRESS); - - return smctr_wait_cmd(dev); -} - -/* - * Get the current statistics. This may be called with the card open - * or closed. - */ -static struct net_device_stats *smctr_get_stats(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - - return (struct net_device_stats *)&tp->MacStat; -} - -static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, - __u16 bytes_count) -{ - struct net_local *tp = netdev_priv(dev); - FCBlock *pFCB; - BDBlock *pbdb; - unsigned short alloc_size; - unsigned short *temp; - - if(smctr_debug > 20) - printk(KERN_DEBUG "smctr_get_tx_fcb\n"); - - /* check if there is enough FCB blocks */ - if(tp->num_tx_fcbs_used[queue] >= tp->num_tx_fcbs[queue]) - return (FCBlock *)(-1L); - - /* round off the input pkt size to the nearest even number */ - alloc_size = (bytes_count + 1) & 0xfffe; - - /* check if enough mem */ - if((tp->tx_buff_used[queue] + alloc_size) > tp->tx_buff_size[queue]) - return (FCBlock *)(-1L); - - /* check if past the end ; - * if exactly enough mem to end of ring, alloc from front. - * this avoids update of curr when curr = end - */ - if(((unsigned long)(tp->tx_buff_curr[queue]) + alloc_size) - >= (unsigned long)(tp->tx_buff_end[queue])) - { - /* check if enough memory from ring head */ - alloc_size = alloc_size + - (__u16)((__u32)tp->tx_buff_end[queue] - - (__u32)tp->tx_buff_curr[queue]); - - if((tp->tx_buff_used[queue] + alloc_size) - > tp->tx_buff_size[queue]) - { - return (FCBlock *)(-1L); - } - - /* ring wrap */ - tp->tx_buff_curr[queue] = tp->tx_buff_head[queue]; - } - - tp->tx_buff_used[queue] += alloc_size; - tp->num_tx_fcbs_used[queue]++; - tp->tx_fcb_curr[queue]->frame_length = bytes_count; - tp->tx_fcb_curr[queue]->memory_alloc = alloc_size; - temp = tp->tx_buff_curr[queue]; - tp->tx_buff_curr[queue] - = (__u16 *)((__u32)temp + (__u32)((bytes_count + 1) & 0xfffe)); - - pbdb = tp->tx_fcb_curr[queue]->bdb_ptr; - pbdb->buffer_length = bytes_count; - pbdb->data_block_ptr = temp; - pbdb->trc_data_block_ptr = TRC_POINTER(temp); - - pFCB = tp->tx_fcb_curr[queue]; - tp->tx_fcb_curr[queue] = tp->tx_fcb_curr[queue]->next_ptr; - - return pFCB; -} - -static int smctr_get_upstream_neighbor_addr(struct net_device *dev) -{ - smctr_issue_read_word_cmd(dev, RW_UPSTREAM_NEIGHBOR_ADDRESS); - - return smctr_wait_cmd(dev); -} - -static int smctr_hardware_send_packet(struct net_device *dev, - struct net_local *tp) -{ - struct tr_statistics *tstat = &tp->MacStat; - struct sk_buff *skb; - FCBlock *fcb; - - if(smctr_debug > 10) - printk(KERN_DEBUG"%s: smctr_hardware_send_packet\n", dev->name); - - if(tp->status != OPEN) - return -1; - - if(tp->monitor_state_ready != 1) - return -1; - - for(;;) - { - /* Send first buffer from queue */ - skb = skb_dequeue(&tp->SendSkbQueue); - if(skb == NULL) - return -1; - - tp->QueueSkb++; - - if(skb->len < SMC_HEADER_SIZE || skb->len > tp->max_packet_size) - return -1; - - smctr_enable_16bit(dev); - smctr_set_page(dev, (__u8 *)tp->ram_access); - - if((fcb = smctr_get_tx_fcb(dev, NON_MAC_QUEUE, skb->len)) - == (FCBlock *)(-1L)) - { - smctr_disable_16bit(dev); - return -1; - } - - smctr_tx_move_frame(dev, skb, - (__u8 *)fcb->bdb_ptr->data_block_ptr, skb->len); - - smctr_set_page(dev, (__u8 *)fcb); - - smctr_trc_send_packet(dev, fcb, NON_MAC_QUEUE); - dev_kfree_skb(skb); - - tstat->tx_packets++; - - smctr_disable_16bit(dev); - } - - return 0; -} - -static int smctr_init_acbs(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int i; - ACBlock *acb; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_init_acbs\n", dev->name); - - acb = tp->acb_head; - acb->cmd_done_status = (ACB_COMMAND_DONE | ACB_COMMAND_SUCCESSFUL); - acb->cmd_info = ACB_CHAIN_END; - acb->cmd = 0; - acb->subcmd = 0; - acb->data_offset_lo = 0; - acb->data_offset_hi = 0; - acb->next_ptr - = (ACBlock *)(((char *)acb) + sizeof(ACBlock)); - acb->trc_next_ptr = TRC_POINTER(acb->next_ptr); - - for(i = 1; i < tp->num_acbs; i++) - { - acb = acb->next_ptr; - acb->cmd_done_status - = (ACB_COMMAND_DONE | ACB_COMMAND_SUCCESSFUL); - acb->cmd_info = ACB_CHAIN_END; - acb->cmd = 0; - acb->subcmd = 0; - acb->data_offset_lo = 0; - acb->data_offset_hi = 0; - acb->next_ptr - = (ACBlock *)(((char *)acb) + sizeof(ACBlock)); - acb->trc_next_ptr = TRC_POINTER(acb->next_ptr); - } - - acb->next_ptr = tp->acb_head; - acb->trc_next_ptr = TRC_POINTER(tp->acb_head); - tp->acb_next = tp->acb_head->next_ptr; - tp->acb_curr = tp->acb_head->next_ptr; - tp->num_acbs_used = 0; - - return 0; -} - -static int smctr_init_adapter(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int err; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_init_adapter\n", dev->name); - - tp->status = CLOSED; - tp->page_offset_mask = (tp->ram_usable * 1024) - 1; - skb_queue_head_init(&tp->SendSkbQueue); - tp->QueueSkb = MAX_TX_QUEUE; - - if(!(tp->group_address_0 & 0x0080)) - tp->group_address_0 |= 0x00C0; - - if(!(tp->functional_address_0 & 0x00C0)) - tp->functional_address_0 |= 0x00C0; - - tp->functional_address[0] &= 0xFF7F; - - if(tp->authorized_function_classes == 0) - tp->authorized_function_classes = 0x7FFF; - - if(tp->authorized_access_priority == 0) - tp->authorized_access_priority = 0x06; - - smctr_disable_bic_int(dev); - smctr_set_trc_reset(dev->base_addr); - - smctr_enable_16bit(dev); - smctr_set_page(dev, (__u8 *)tp->ram_access); - - if(smctr_checksum_firmware(dev)) - { - printk(KERN_ERR "%s: Previously loaded firmware is missing\n",dev->name); - return -ENOENT; - } - - if((err = smctr_ram_memory_test(dev))) - { - printk(KERN_ERR "%s: RAM memory test failed.\n", dev->name); - return -EIO; - } - - smctr_set_rx_look_ahead(dev); - smctr_load_node_addr(dev); - - /* Initialize adapter for Internal Self Test. */ - smctr_reset_adapter(dev); - if((err = smctr_init_card_real(dev))) - { - printk(KERN_ERR "%s: Initialization of card failed (%d)\n", - dev->name, err); - return -EINVAL; - } - - /* This routine clobbers the TRC's internal registers. */ - if((err = smctr_internal_self_test(dev))) - { - printk(KERN_ERR "%s: Card failed internal self test (%d)\n", - dev->name, err); - return -EINVAL; - } - - /* Re-Initialize adapter's internal registers */ - smctr_reset_adapter(dev); - if((err = smctr_init_card_real(dev))) - { - printk(KERN_ERR "%s: Initialization of card failed (%d)\n", - dev->name, err); - return -EINVAL; - } - - smctr_enable_bic_int(dev); - - if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK))) - return err; - - smctr_disable_16bit(dev); - - return 0; -} - -static int smctr_init_card_real(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int err = 0; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_init_card_real\n", dev->name); - - tp->sh_mem_used = 0; - tp->num_acbs = NUM_OF_ACBS; - - /* Range Check Max Packet Size */ - if(tp->max_packet_size < 256) - tp->max_packet_size = 256; - else - { - if(tp->max_packet_size > NON_MAC_TX_BUFFER_MEMORY) - tp->max_packet_size = NON_MAC_TX_BUFFER_MEMORY; - } - - tp->num_of_tx_buffs = (NON_MAC_TX_BUFFER_MEMORY - / tp->max_packet_size) - 1; - - if(tp->num_of_tx_buffs > NUM_NON_MAC_TX_FCBS) - tp->num_of_tx_buffs = NUM_NON_MAC_TX_FCBS; - else - { - if(tp->num_of_tx_buffs == 0) - tp->num_of_tx_buffs = 1; - } - - /* Tx queue constants */ - tp->num_tx_fcbs [BUG_QUEUE] = NUM_BUG_TX_FCBS; - tp->num_tx_bdbs [BUG_QUEUE] = NUM_BUG_TX_BDBS; - tp->tx_buff_size [BUG_QUEUE] = BUG_TX_BUFFER_MEMORY; - tp->tx_buff_used [BUG_QUEUE] = 0; - tp->tx_queue_status [BUG_QUEUE] = NOT_TRANSMITING; - - tp->num_tx_fcbs [MAC_QUEUE] = NUM_MAC_TX_FCBS; - tp->num_tx_bdbs [MAC_QUEUE] = NUM_MAC_TX_BDBS; - tp->tx_buff_size [MAC_QUEUE] = MAC_TX_BUFFER_MEMORY; - tp->tx_buff_used [MAC_QUEUE] = 0; - tp->tx_queue_status [MAC_QUEUE] = NOT_TRANSMITING; - - tp->num_tx_fcbs [NON_MAC_QUEUE] = NUM_NON_MAC_TX_FCBS; - tp->num_tx_bdbs [NON_MAC_QUEUE] = NUM_NON_MAC_TX_BDBS; - tp->tx_buff_size [NON_MAC_QUEUE] = NON_MAC_TX_BUFFER_MEMORY; - tp->tx_buff_used [NON_MAC_QUEUE] = 0; - tp->tx_queue_status [NON_MAC_QUEUE] = NOT_TRANSMITING; - - /* Receive Queue Constants */ - tp->num_rx_fcbs[MAC_QUEUE] = NUM_MAC_RX_FCBS; - tp->num_rx_bdbs[MAC_QUEUE] = NUM_MAC_RX_BDBS; - - if(tp->extra_info & CHIP_REV_MASK) - tp->num_rx_fcbs[NON_MAC_QUEUE] = 78; /* 825 Rev. XE */ - else - tp->num_rx_fcbs[NON_MAC_QUEUE] = 7; /* 825 Rev. XD */ - - tp->num_rx_bdbs[NON_MAC_QUEUE] = smctr_get_num_rx_bdbs(dev); - - smctr_alloc_shared_memory(dev); - smctr_init_shared_memory(dev); - - if((err = smctr_issue_init_timers_cmd(dev))) - return err; - - if((err = smctr_issue_init_txrx_cmd(dev))) - { - printk(KERN_ERR "%s: Hardware failure\n", dev->name); - return err; - } - - return 0; -} - -static int smctr_init_rx_bdbs(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int i, j; - BDBlock *bdb; - __u16 *buf; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_init_rx_bdbs\n", dev->name); - - for(i = 0; i < NUM_RX_QS_USED; i++) - { - bdb = tp->rx_bdb_head[i]; - buf = tp->rx_buff_head[i]; - bdb->info = (BDB_CHAIN_END | BDB_NO_WARNING); - bdb->buffer_length = RX_DATA_BUFFER_SIZE; - bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock)); - bdb->data_block_ptr = buf; - bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); - - if(i == NON_MAC_QUEUE) - bdb->trc_data_block_ptr = RX_BUFF_TRC_POINTER(buf); - else - bdb->trc_data_block_ptr = TRC_POINTER(buf); - - for(j = 1; j < tp->num_rx_bdbs[i]; j++) - { - bdb->next_ptr->back_ptr = bdb; - bdb = bdb->next_ptr; - buf = (__u16 *)((char *)buf + RX_DATA_BUFFER_SIZE); - bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING); - bdb->buffer_length = RX_DATA_BUFFER_SIZE; - bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock)); - bdb->data_block_ptr = buf; - bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); - - if(i == NON_MAC_QUEUE) - bdb->trc_data_block_ptr = RX_BUFF_TRC_POINTER(buf); - else - bdb->trc_data_block_ptr = TRC_POINTER(buf); - } - - bdb->next_ptr = tp->rx_bdb_head[i]; - bdb->trc_next_ptr = TRC_POINTER(tp->rx_bdb_head[i]); - - tp->rx_bdb_head[i]->back_ptr = bdb; - tp->rx_bdb_curr[i] = tp->rx_bdb_head[i]->next_ptr; - } - - return 0; -} - -static int smctr_init_rx_fcbs(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int i, j; - FCBlock *fcb; - - for(i = 0; i < NUM_RX_QS_USED; i++) - { - fcb = tp->rx_fcb_head[i]; - fcb->frame_status = 0; - fcb->frame_length = 0; - fcb->info = FCB_CHAIN_END; - fcb->next_ptr = (FCBlock *)(((char*)fcb) + sizeof(FCBlock)); - if(i == NON_MAC_QUEUE) - fcb->trc_next_ptr = RX_FCB_TRC_POINTER(fcb->next_ptr); - else - fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); - - for(j = 1; j < tp->num_rx_fcbs[i]; j++) - { - fcb->next_ptr->back_ptr = fcb; - fcb = fcb->next_ptr; - fcb->frame_status = 0; - fcb->frame_length = 0; - fcb->info = FCB_WARNING; - fcb->next_ptr - = (FCBlock *)(((char *)fcb) + sizeof(FCBlock)); - - if(i == NON_MAC_QUEUE) - fcb->trc_next_ptr - = RX_FCB_TRC_POINTER(fcb->next_ptr); - else - fcb->trc_next_ptr - = TRC_POINTER(fcb->next_ptr); - } - - fcb->next_ptr = tp->rx_fcb_head[i]; - - if(i == NON_MAC_QUEUE) - fcb->trc_next_ptr = RX_FCB_TRC_POINTER(fcb->next_ptr); - else - fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); - - tp->rx_fcb_head[i]->back_ptr = fcb; - tp->rx_fcb_curr[i] = tp->rx_fcb_head[i]->next_ptr; - } - - return 0; -} - -static int smctr_init_shared_memory(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int i; - __u32 *iscpb; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_init_shared_memory\n", dev->name); - - smctr_set_page(dev, (__u8 *)(unsigned int)tp->iscpb_ptr); - - /* Initialize Initial System Configuration Point. (ISCP) */ - iscpb = (__u32 *)PAGE_POINTER(&tp->iscpb_ptr->trc_scgb_ptr); - *iscpb = (__u32)(SWAP_WORDS(TRC_POINTER(tp->scgb_ptr))); - - smctr_set_page(dev, (__u8 *)tp->ram_access); - - /* Initialize System Configuration Pointers. (SCP) */ - tp->scgb_ptr->config = (SCGB_ADDRESS_POINTER_FORMAT - | SCGB_MULTI_WORD_CONTROL | SCGB_DATA_FORMAT - | SCGB_BURST_LENGTH); - - tp->scgb_ptr->trc_sclb_ptr = TRC_POINTER(tp->sclb_ptr); - tp->scgb_ptr->trc_acb_ptr = TRC_POINTER(tp->acb_head); - tp->scgb_ptr->trc_isb_ptr = TRC_POINTER(tp->isb_ptr); - tp->scgb_ptr->isbsiz = (sizeof(ISBlock)) - 2; - - /* Initialize System Control Block. (SCB) */ - tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_NOP; - tp->sclb_ptr->iack_code = 0; - tp->sclb_ptr->resume_control = 0; - tp->sclb_ptr->int_mask_control = 0; - tp->sclb_ptr->int_mask_state = 0; - - /* Initialize Interrupt Status Block. (ISB) */ - for(i = 0; i < NUM_OF_INTERRUPTS; i++) - { - tp->isb_ptr->IStatus[i].IType = 0xf0; - tp->isb_ptr->IStatus[i].ISubtype = 0; - } - - tp->current_isb_index = 0; - - /* Initialize Action Command Block. (ACB) */ - smctr_init_acbs(dev); - - /* Initialize transmit FCB's and BDB's. */ - smctr_link_tx_fcbs_to_bdbs(dev); - smctr_init_tx_bdbs(dev); - smctr_init_tx_fcbs(dev); - - /* Initialize receive FCB's and BDB's. */ - smctr_init_rx_bdbs(dev); - smctr_init_rx_fcbs(dev); - - return 0; -} - -static int smctr_init_tx_bdbs(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int i, j; - BDBlock *bdb; - - for(i = 0; i < NUM_TX_QS_USED; i++) - { - bdb = tp->tx_bdb_head[i]; - bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING); - bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock)); - bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); - - for(j = 1; j < tp->num_tx_bdbs[i]; j++) - { - bdb->next_ptr->back_ptr = bdb; - bdb = bdb->next_ptr; - bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING); - bdb->next_ptr - = (BDBlock *)(((char *)bdb) + sizeof( BDBlock)); bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); - } - - bdb->next_ptr = tp->tx_bdb_head[i]; - bdb->trc_next_ptr = TRC_POINTER(tp->tx_bdb_head[i]); - tp->tx_bdb_head[i]->back_ptr = bdb; - } - - return 0; -} - -static int smctr_init_tx_fcbs(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int i, j; - FCBlock *fcb; - - for(i = 0; i < NUM_TX_QS_USED; i++) - { - fcb = tp->tx_fcb_head[i]; - fcb->frame_status = 0; - fcb->frame_length = 0; - fcb->info = FCB_CHAIN_END; - fcb->next_ptr = (FCBlock *)(((char *)fcb) + sizeof(FCBlock)); - fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); - - for(j = 1; j < tp->num_tx_fcbs[i]; j++) - { - fcb->next_ptr->back_ptr = fcb; - fcb = fcb->next_ptr; - fcb->frame_status = 0; - fcb->frame_length = 0; - fcb->info = FCB_CHAIN_END; - fcb->next_ptr - = (FCBlock *)(((char *)fcb) + sizeof(FCBlock)); - fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); - } - - fcb->next_ptr = tp->tx_fcb_head[i]; - fcb->trc_next_ptr = TRC_POINTER(tp->tx_fcb_head[i]); - - tp->tx_fcb_head[i]->back_ptr = fcb; - tp->tx_fcb_end[i] = tp->tx_fcb_head[i]->next_ptr; - tp->tx_fcb_curr[i] = tp->tx_fcb_head[i]->next_ptr; - tp->num_tx_fcbs_used[i] = 0; - } - - return 0; -} - -static int smctr_internal_self_test(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int err; - - if((err = smctr_issue_test_internal_rom_cmd(dev))) - return err; - - if((err = smctr_wait_cmd(dev))) - return err; - - if(tp->acb_head->cmd_done_status & 0xff) - return -1; - - if((err = smctr_issue_test_hic_cmd(dev))) - return err; - - if((err = smctr_wait_cmd(dev))) - return err; - - if(tp->acb_head->cmd_done_status & 0xff) - return -1; - - if((err = smctr_issue_test_mac_reg_cmd(dev))) - return err; - - if((err = smctr_wait_cmd(dev))) - return err; - - if(tp->acb_head->cmd_done_status & 0xff) - return -1; - - return 0; -} - -/* - * The typical workload of the driver: Handle the network interface interrupts. - */ -static irqreturn_t smctr_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct net_local *tp; - int ioaddr; - __u16 interrupt_unmask_bits = 0, interrupt_ack_code = 0xff00; - __u16 err1, err = NOT_MY_INTERRUPT; - __u8 isb_type, isb_subtype; - __u16 isb_index; - - ioaddr = dev->base_addr; - tp = netdev_priv(dev); - - if(tp->status == NOT_INITIALIZED) - return IRQ_NONE; - - spin_lock(&tp->lock); - - smctr_disable_bic_int(dev); - smctr_enable_16bit(dev); - - smctr_clear_int(dev); - - /* First read the LSB */ - while((tp->isb_ptr->IStatus[tp->current_isb_index].IType & 0xf0) == 0) - { - isb_index = tp->current_isb_index; - isb_type = tp->isb_ptr->IStatus[isb_index].IType; - isb_subtype = tp->isb_ptr->IStatus[isb_index].ISubtype; - - (tp->current_isb_index)++; - if(tp->current_isb_index == NUM_OF_INTERRUPTS) - tp->current_isb_index = 0; - - if(isb_type >= 0x10) - { - smctr_disable_16bit(dev); - spin_unlock(&tp->lock); - return IRQ_HANDLED; - } - - err = HARDWARE_FAILED; - interrupt_ack_code = isb_index; - tp->isb_ptr->IStatus[isb_index].IType |= 0xf0; - - interrupt_unmask_bits |= (1 << (__u16)isb_type); - - switch(isb_type) - { - case ISB_IMC_MAC_TYPE_3: - smctr_disable_16bit(dev); - - switch(isb_subtype) - { - case 0: - tp->monitor_state = MS_MONITOR_FSM_INACTIVE; - break; - - case 1: - tp->monitor_state = MS_REPEAT_BEACON_STATE; - break; - - case 2: - tp->monitor_state = MS_REPEAT_CLAIM_TOKEN_STATE; - break; - - case 3: - tp->monitor_state = MS_TRANSMIT_CLAIM_TOKEN_STATE; break; - - case 4: - tp->monitor_state = MS_STANDBY_MONITOR_STATE; - break; - - case 5: - tp->monitor_state = MS_TRANSMIT_BEACON_STATE; - break; - - case 6: - tp->monitor_state = MS_ACTIVE_MONITOR_STATE; - break; - - case 7: - tp->monitor_state = MS_TRANSMIT_RING_PURGE_STATE; - break; - - case 8: /* diagnostic state */ - break; - - case 9: - tp->monitor_state = MS_BEACON_TEST_STATE; - if(smctr_lobe_media_test(dev)) - { - tp->ring_status_flags = RING_STATUS_CHANGED; - tp->ring_status = AUTO_REMOVAL_ERROR; - smctr_ring_status_chg(dev); - smctr_bypass_state(dev); - } - else - smctr_issue_insert_cmd(dev); - break; - - /* case 0x0a-0xff, illegal states */ - default: - break; - } - - tp->ring_status_flags = MONITOR_STATE_CHANGED; - err = smctr_ring_status_chg(dev); - - smctr_enable_16bit(dev); - break; - - /* Type 0x02 - MAC Error Counters Interrupt - * One or more MAC Error Counter is half full - * MAC Error Counters - * Lost_FR_Error_Counter - * RCV_Congestion_Counter - * FR_copied_Error_Counter - * FREQ_Error_Counter - * Token_Error_Counter - * Line_Error_Counter - * Internal_Error_Count - */ - case ISB_IMC_MAC_ERROR_COUNTERS: - /* Read 802.5 Error Counters */ - err = smctr_issue_read_ring_status_cmd(dev); - break; - - /* Type 0x04 - MAC Type 2 Interrupt - * HOST needs to enqueue MAC Frame for transmission - * SubType Bit 15 - RQ_INIT_PDU( Request Initialization) * Changed from RQ_INIT_PDU to - * TRC_Status_Changed_Indicate - */ - case ISB_IMC_MAC_TYPE_2: - err = smctr_issue_read_ring_status_cmd(dev); - break; - - - /* Type 0x05 - TX Frame Interrupt (FI). */ - case ISB_IMC_TX_FRAME: - /* BUG QUEUE for TRC stuck receive BUG */ - if(isb_subtype & TX_PENDING_PRIORITY_2) - { - if((err = smctr_tx_complete(dev, BUG_QUEUE)) != SUCCESS) - break; - } - - /* NON-MAC frames only */ - if(isb_subtype & TX_PENDING_PRIORITY_1) - { - if((err = smctr_tx_complete(dev, NON_MAC_QUEUE)) != SUCCESS) - break; - } - - /* MAC frames only */ - if(isb_subtype & TX_PENDING_PRIORITY_0) - err = smctr_tx_complete(dev, MAC_QUEUE); break; - - /* Type 0x06 - TX END OF QUEUE (FE) */ - case ISB_IMC_END_OF_TX_QUEUE: - /* BUG queue */ - if(isb_subtype & TX_PENDING_PRIORITY_2) - { - /* ok to clear Receive FIFO overrun - * imask send_BUG now completes. - */ - interrupt_unmask_bits |= 0x800; - - tp->tx_queue_status[BUG_QUEUE] = NOT_TRANSMITING; - if((err = smctr_tx_complete(dev, BUG_QUEUE)) != SUCCESS) - break; - if((err = smctr_restart_tx_chain(dev, BUG_QUEUE)) != SUCCESS) - break; - } - - /* NON-MAC queue only */ - if(isb_subtype & TX_PENDING_PRIORITY_1) - { - tp->tx_queue_status[NON_MAC_QUEUE] = NOT_TRANSMITING; - if((err = smctr_tx_complete(dev, NON_MAC_QUEUE)) != SUCCESS) - break; - if((err = smctr_restart_tx_chain(dev, NON_MAC_QUEUE)) != SUCCESS) - break; - } - - /* MAC queue only */ - if(isb_subtype & TX_PENDING_PRIORITY_0) - { - tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; - if((err = smctr_tx_complete(dev, MAC_QUEUE)) != SUCCESS) - break; - - err = smctr_restart_tx_chain(dev, MAC_QUEUE); - } - break; - - /* Type 0x07 - NON-MAC RX Resource Interrupt - * Subtype bit 12 - (BW) BDB warning - * Subtype bit 13 - (FW) FCB warning - * Subtype bit 14 - (BE) BDB End of chain - * Subtype bit 15 - (FE) FCB End of chain - */ - case ISB_IMC_NON_MAC_RX_RESOURCE: - tp->rx_fifo_overrun_count = 0; - tp->receive_queue_number = NON_MAC_QUEUE; - err1 = smctr_rx_frame(dev); - - if(isb_subtype & NON_MAC_RX_RESOURCE_FE) - { - if((err = smctr_issue_resume_rx_fcb_cmd( dev, NON_MAC_QUEUE)) != SUCCESS) break; - - if(tp->ptr_rx_fcb_overruns) - (*tp->ptr_rx_fcb_overruns)++; - } - - if(isb_subtype & NON_MAC_RX_RESOURCE_BE) - { - if((err = smctr_issue_resume_rx_bdb_cmd( dev, NON_MAC_QUEUE)) != SUCCESS) break; - - if(tp->ptr_rx_bdb_overruns) - (*tp->ptr_rx_bdb_overruns)++; - } - err = err1; - break; - - /* Type 0x08 - MAC RX Resource Interrupt - * Subtype bit 12 - (BW) BDB warning - * Subtype bit 13 - (FW) FCB warning - * Subtype bit 14 - (BE) BDB End of chain - * Subtype bit 15 - (FE) FCB End of chain - */ - case ISB_IMC_MAC_RX_RESOURCE: - tp->receive_queue_number = MAC_QUEUE; - err1 = smctr_rx_frame(dev); - - if(isb_subtype & MAC_RX_RESOURCE_FE) - { - if((err = smctr_issue_resume_rx_fcb_cmd( dev, MAC_QUEUE)) != SUCCESS) - break; - - if(tp->ptr_rx_fcb_overruns) - (*tp->ptr_rx_fcb_overruns)++; - } - - if(isb_subtype & MAC_RX_RESOURCE_BE) - { - if((err = smctr_issue_resume_rx_bdb_cmd( dev, MAC_QUEUE)) != SUCCESS) - break; - - if(tp->ptr_rx_bdb_overruns) - (*tp->ptr_rx_bdb_overruns)++; - } - err = err1; - break; - - /* Type 0x09 - NON_MAC RX Frame Interrupt */ - case ISB_IMC_NON_MAC_RX_FRAME: - tp->rx_fifo_overrun_count = 0; - tp->receive_queue_number = NON_MAC_QUEUE; - err = smctr_rx_frame(dev); - break; - - /* Type 0x0A - MAC RX Frame Interrupt */ - case ISB_IMC_MAC_RX_FRAME: - tp->receive_queue_number = MAC_QUEUE; - err = smctr_rx_frame(dev); - break; - - /* Type 0x0B - TRC status - * TRC has encountered an error condition - * subtype bit 14 - transmit FIFO underrun - * subtype bit 15 - receive FIFO overrun - */ - case ISB_IMC_TRC_FIFO_STATUS: - if(isb_subtype & TRC_FIFO_STATUS_TX_UNDERRUN) - { - if(tp->ptr_tx_fifo_underruns) - (*tp->ptr_tx_fifo_underruns)++; - } - - if(isb_subtype & TRC_FIFO_STATUS_RX_OVERRUN) - { - /* update overrun stuck receive counter - * if >= 3, has to clear it by sending - * back to back frames. We pick - * DAT(duplicate address MAC frame) - */ - tp->rx_fifo_overrun_count++; - - if(tp->rx_fifo_overrun_count >= 3) - { - tp->rx_fifo_overrun_count = 0; - - /* delay clearing fifo overrun - * imask till send_BUG tx - * complete posted - */ - interrupt_unmask_bits &= (~0x800); - printk(KERN_CRIT "Jay please send bug\n");// smctr_send_bug(dev); - } - - if(tp->ptr_rx_fifo_overruns) - (*tp->ptr_rx_fifo_overruns)++; - } - - err = SUCCESS; - break; - - /* Type 0x0C - Action Command Status Interrupt - * Subtype bit 14 - CB end of command chain (CE) - * Subtype bit 15 - CB command interrupt (CI) - */ - case ISB_IMC_COMMAND_STATUS: - err = SUCCESS; - if(tp->acb_head->cmd == ACB_CMD_HIC_NOP) - { - printk(KERN_ERR "i1\n"); - smctr_disable_16bit(dev); - - /* XXXXXXXXXXXXXXXXX */ - /* err = UM_Interrupt(dev); */ - - smctr_enable_16bit(dev); - } - else - { - if((tp->acb_head->cmd - == ACB_CMD_READ_TRC_STATUS) && - (tp->acb_head->subcmd - == RW_TRC_STATUS_BLOCK)) - { - if(tp->ptr_bcn_type) - { - *(tp->ptr_bcn_type) - = (__u32)((SBlock *)tp->misc_command_data)->BCN_Type; - } - - if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & ERROR_COUNTERS_CHANGED) - { - smctr_update_err_stats(dev); - } - - if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & TI_NDIS_RING_STATUS_CHANGED) - { - tp->ring_status - = ((SBlock*)tp->misc_command_data)->TI_NDIS_Ring_Status; - smctr_disable_16bit(dev); - err = smctr_ring_status_chg(dev); - smctr_enable_16bit(dev); - if((tp->ring_status & REMOVE_RECEIVED) && - (tp->config_word0 & NO_AUTOREMOVE)) - { - smctr_issue_remove_cmd(dev); - } - - if(err != SUCCESS) - { - tp->acb_pending = 0; - break; - } - } - - if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & UNA_CHANGED) - { - if(tp->ptr_una) - { - tp->ptr_una[0] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[0]); - tp->ptr_una[1] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[1]); - tp->ptr_una[2] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[2]); - } - - } - - if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & READY_TO_SEND_RQ_INIT) { - err = smctr_send_rq_init(dev); - } - } - } - - tp->acb_pending = 0; - break; - - /* Type 0x0D - MAC Type 1 interrupt - * Subtype -- 00 FR_BCN received at S12 - * 01 FR_BCN received at S21 - * 02 FR_DAT(DA=MA, A<>0) received at S21 - * 03 TSM_EXP at S21 - * 04 FR_REMOVE received at S42 - * 05 TBR_EXP, BR_FLAG_SET at S42 - * 06 TBT_EXP at S53 - */ - case ISB_IMC_MAC_TYPE_1: - if(isb_subtype > 8) - { - err = HARDWARE_FAILED; - break; - } - - err = SUCCESS; - switch(isb_subtype) - { - case 0: - tp->join_state = JS_BYPASS_STATE; - if(tp->status != CLOSED) - { - tp->status = CLOSED; - err = smctr_status_chg(dev); - } - break; - - case 1: - tp->join_state = JS_LOBE_TEST_STATE; - break; - - case 2: - tp->join_state = JS_DETECT_MONITOR_PRESENT_STATE; - break; - - case 3: - tp->join_state = JS_AWAIT_NEW_MONITOR_STATE; - break; - - case 4: - tp->join_state = JS_DUPLICATE_ADDRESS_TEST_STATE; - break; - - case 5: - tp->join_state = JS_NEIGHBOR_NOTIFICATION_STATE; - break; - - case 6: - tp->join_state = JS_REQUEST_INITIALIZATION_STATE; - break; - - case 7: - tp->join_state = JS_JOIN_COMPLETE_STATE; - tp->status = OPEN; - err = smctr_status_chg(dev); - break; - - case 8: - tp->join_state = JS_BYPASS_WAIT_STATE; - break; - } - break ; - - /* Type 0x0E - TRC Initialization Sequence Interrupt - * Subtype -- 00-FF Initializatin sequence complete - */ - case ISB_IMC_TRC_INTRNL_TST_STATUS: - tp->status = INITIALIZED; - smctr_disable_16bit(dev); - err = smctr_status_chg(dev); - smctr_enable_16bit(dev); - break; - - /* other interrupt types, illegal */ - default: - break; - } - - if(err != SUCCESS) - break; - } - - /* Checking the ack code instead of the unmask bits here is because : - * while fixing the stuck receive, DAT frame are sent and mask off - * FIFO overrun interrupt temporarily (interrupt_unmask_bits = 0) - * but we still want to issue ack to ISB - */ - if(!(interrupt_ack_code & 0xff00)) - smctr_issue_int_ack(dev, interrupt_ack_code, interrupt_unmask_bits); - - smctr_disable_16bit(dev); - smctr_enable_bic_int(dev); - spin_unlock(&tp->lock); - - return IRQ_HANDLED; -} - -static int smctr_issue_enable_int_cmd(struct net_device *dev, - __u16 interrupt_enable_mask) -{ - struct net_local *tp = netdev_priv(dev); - int err; - - if((err = smctr_wait_while_cbusy(dev))) - return err; - - tp->sclb_ptr->int_mask_control = interrupt_enable_mask; - tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_CLEAR_INTERRUPT_MASK; - - smctr_set_ctrl_attention(dev); - - return 0; -} - -static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ibits) -{ - struct net_local *tp = netdev_priv(dev); - - if(smctr_wait_while_cbusy(dev)) - return -1; - - tp->sclb_ptr->int_mask_control = ibits; - tp->sclb_ptr->iack_code = iack_code << 1; /* use the offset from base */ tp->sclb_ptr->resume_control = 0; - tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_IACK_CODE_VALID | SCLB_CMD_CLEAR_INTERRUPT_MASK; - - smctr_set_ctrl_attention(dev); - - return 0; -} - -static int smctr_issue_init_timers_cmd(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int i; - int err; - __u16 *pTimer_Struc = (__u16 *)tp->misc_command_data; - - if((err = smctr_wait_while_cbusy(dev))) - return err; - - if((err = smctr_wait_cmd(dev))) - return err; - - tp->config_word0 = THDREN | DMA_TRIGGER | USETPT | NO_AUTOREMOVE; - tp->config_word1 = 0; - - if((tp->media_type == MEDIA_STP_16) || - (tp->media_type == MEDIA_UTP_16) || - (tp->media_type == MEDIA_STP_16_UTP_16)) - { - tp->config_word0 |= FREQ_16MB_BIT; - } - - if(tp->mode_bits & EARLY_TOKEN_REL) - tp->config_word0 |= ETREN; - - if(tp->mode_bits & LOOPING_MODE_MASK) - tp->config_word0 |= RX_OWN_BIT; - else - tp->config_word0 &= ~RX_OWN_BIT; - - if(tp->receive_mask & PROMISCUOUS_MODE) - tp->config_word0 |= PROMISCUOUS_BIT; - else - tp->config_word0 &= ~PROMISCUOUS_BIT; - - if(tp->receive_mask & ACCEPT_ERR_PACKETS) - tp->config_word0 |= SAVBAD_BIT; - else - tp->config_word0 &= ~SAVBAD_BIT; - - if(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES) - tp->config_word0 |= RXATMAC; - else - tp->config_word0 &= ~RXATMAC; - - if(tp->receive_mask & ACCEPT_MULTI_PROM) - tp->config_word1 |= MULTICAST_ADDRESS_BIT; - else - tp->config_word1 &= ~MULTICAST_ADDRESS_BIT; - - if(tp->receive_mask & ACCEPT_SOURCE_ROUTING_SPANNING) - tp->config_word1 |= SOURCE_ROUTING_SPANNING_BITS; - else - { - if(tp->receive_mask & ACCEPT_SOURCE_ROUTING) - tp->config_word1 |= SOURCE_ROUTING_EXPLORER_BIT; - else - tp->config_word1 &= ~SOURCE_ROUTING_SPANNING_BITS; - } - - if((tp->media_type == MEDIA_STP_16) || - (tp->media_type == MEDIA_UTP_16) || - (tp->media_type == MEDIA_STP_16_UTP_16)) - { - tp->config_word1 |= INTERFRAME_SPACING_16; - } - else - tp->config_word1 |= INTERFRAME_SPACING_4; - - *pTimer_Struc++ = tp->config_word0; - *pTimer_Struc++ = tp->config_word1; - - if((tp->media_type == MEDIA_STP_4) || - (tp->media_type == MEDIA_UTP_4) || - (tp->media_type == MEDIA_STP_4_UTP_4)) - { - *pTimer_Struc++ = 0x00FA; /* prescale */ - *pTimer_Struc++ = 0x2710; /* TPT_limit */ - *pTimer_Struc++ = 0x2710; /* TQP_limit */ - *pTimer_Struc++ = 0x0A28; /* TNT_limit */ - *pTimer_Struc++ = 0x3E80; /* TBT_limit */ - *pTimer_Struc++ = 0x3A98; /* TSM_limit */ - *pTimer_Struc++ = 0x1B58; /* TAM_limit */ - *pTimer_Struc++ = 0x00C8; /* TBR_limit */ - *pTimer_Struc++ = 0x07D0; /* TER_limit */ - *pTimer_Struc++ = 0x000A; /* TGT_limit */ - *pTimer_Struc++ = 0x1162; /* THT_limit */ - *pTimer_Struc++ = 0x07D0; /* TRR_limit */ - *pTimer_Struc++ = 0x1388; /* TVX_limit */ - *pTimer_Struc++ = 0x0000; /* reserved */ - } - else - { - *pTimer_Struc++ = 0x03E8; /* prescale */ - *pTimer_Struc++ = 0x9C40; /* TPT_limit */ - *pTimer_Struc++ = 0x9C40; /* TQP_limit */ - *pTimer_Struc++ = 0x0A28; /* TNT_limit */ - *pTimer_Struc++ = 0x3E80; /* TBT_limit */ - *pTimer_Struc++ = 0x3A98; /* TSM_limit */ - *pTimer_Struc++ = 0x1B58; /* TAM_limit */ - *pTimer_Struc++ = 0x00C8; /* TBR_limit */ - *pTimer_Struc++ = 0x07D0; /* TER_limit */ - *pTimer_Struc++ = 0x000A; /* TGT_limit */ - *pTimer_Struc++ = 0x4588; /* THT_limit */ - *pTimer_Struc++ = 0x1F40; /* TRR_limit */ - *pTimer_Struc++ = 0x4E20; /* TVX_limit */ - *pTimer_Struc++ = 0x0000; /* reserved */ - } - - /* Set node address. */ - *pTimer_Struc++ = dev->dev_addr[0] << 8 - | (dev->dev_addr[1] & 0xFF); - *pTimer_Struc++ = dev->dev_addr[2] << 8 - | (dev->dev_addr[3] & 0xFF); - *pTimer_Struc++ = dev->dev_addr[4] << 8 - | (dev->dev_addr[5] & 0xFF); - - /* Set group address. */ - *pTimer_Struc++ = tp->group_address_0 << 8 - | tp->group_address_0 >> 8; - *pTimer_Struc++ = tp->group_address[0] << 8 - | tp->group_address[0] >> 8; - *pTimer_Struc++ = tp->group_address[1] << 8 - | tp->group_address[1] >> 8; - - /* Set functional address. */ - *pTimer_Struc++ = tp->functional_address_0 << 8 - | tp->functional_address_0 >> 8; - *pTimer_Struc++ = tp->functional_address[0] << 8 - | tp->functional_address[0] >> 8; - *pTimer_Struc++ = tp->functional_address[1] << 8 - | tp->functional_address[1] >> 8; - - /* Set Bit-Wise group address. */ - *pTimer_Struc++ = tp->bitwise_group_address[0] << 8 - | tp->bitwise_group_address[0] >> 8; - *pTimer_Struc++ = tp->bitwise_group_address[1] << 8 - | tp->bitwise_group_address[1] >> 8; - - /* Set ring number address. */ - *pTimer_Struc++ = tp->source_ring_number; - *pTimer_Struc++ = tp->target_ring_number; - - /* Physical drop number. */ - *pTimer_Struc++ = (unsigned short)0; - *pTimer_Struc++ = (unsigned short)0; - - /* Product instance ID. */ - for(i = 0; i < 9; i++) - *pTimer_Struc++ = (unsigned short)0; - - err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TRC_TIMERS, 0); - - return err; -} - -static int smctr_issue_init_txrx_cmd(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int i; - int err; - void **txrx_ptrs = (void *)tp->misc_command_data; - - if((err = smctr_wait_while_cbusy(dev))) - return err; - - if((err = smctr_wait_cmd(dev))) - { - printk(KERN_ERR "%s: Hardware failure\n", dev->name); - return err; - } - - /* Initialize Transmit Queue Pointers that are used, to point to - * a single FCB. - */ - for(i = 0; i < NUM_TX_QS_USED; i++) - *txrx_ptrs++ = (void *)TRC_POINTER(tp->tx_fcb_head[i]); - - /* Initialize Transmit Queue Pointers that are NOT used to ZERO. */ - for(; i < MAX_TX_QS; i++) - *txrx_ptrs++ = (void *)0; - - /* Initialize Receive Queue Pointers (MAC and Non-MAC) that are - * used, to point to a single FCB and a BDB chain of buffers. - */ - for(i = 0; i < NUM_RX_QS_USED; i++) - { - *txrx_ptrs++ = (void *)TRC_POINTER(tp->rx_fcb_head[i]); - *txrx_ptrs++ = (void *)TRC_POINTER(tp->rx_bdb_head[i]); - } - - /* Initialize Receive Queue Pointers that are NOT used to ZERO. */ - for(; i < MAX_RX_QS; i++) - { - *txrx_ptrs++ = (void *)0; - *txrx_ptrs++ = (void *)0; - } - - err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TX_RX, 0); - - return err; -} - -static int smctr_issue_insert_cmd(struct net_device *dev) -{ - int err; - - err = smctr_setup_single_cmd(dev, ACB_CMD_INSERT, ACB_SUB_CMD_NOP); - - return err; -} - -static int smctr_issue_read_ring_status_cmd(struct net_device *dev) -{ - int err; - - if((err = smctr_wait_while_cbusy(dev))) - return err; - - if((err = smctr_wait_cmd(dev))) - return err; - - err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_READ_TRC_STATUS, - RW_TRC_STATUS_BLOCK); - - return err; -} - -static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt) -{ - int err; - - if((err = smctr_wait_while_cbusy(dev))) - return err; - - if((err = smctr_wait_cmd(dev))) - return err; - - err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_READ_VALUE, - aword_cnt); - - return err; -} - -static int smctr_issue_remove_cmd(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int err; - - if((err = smctr_wait_while_cbusy(dev))) - return err; - - tp->sclb_ptr->resume_control = 0; - tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_REMOVE; - - smctr_set_ctrl_attention(dev); - - return 0; -} - -static int smctr_issue_resume_acb_cmd(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int err; - - if((err = smctr_wait_while_cbusy(dev))) - return err; - - tp->sclb_ptr->resume_control = SCLB_RC_ACB; - tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID; - - tp->acb_pending = 1; - - smctr_set_ctrl_attention(dev); - - return 0; -} - -static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue) -{ - struct net_local *tp = netdev_priv(dev); - int err; - - if((err = smctr_wait_while_cbusy(dev))) - return err; - - if(queue == MAC_QUEUE) - tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_BDB; - else - tp->sclb_ptr->resume_control = SCLB_RC_RX_NON_MAC_BDB; - - tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID; - - smctr_set_ctrl_attention(dev); - - return 0; -} - -static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue) -{ - struct net_local *tp = netdev_priv(dev); - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_issue_resume_rx_fcb_cmd\n", dev->name); - - if(smctr_wait_while_cbusy(dev)) - return -1; - - if(queue == MAC_QUEUE) - tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_FCB; - else - tp->sclb_ptr->resume_control = SCLB_RC_RX_NON_MAC_FCB; - - tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID; - - smctr_set_ctrl_attention(dev); - - return 0; -} - -static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue) -{ - struct net_local *tp = netdev_priv(dev); - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_issue_resume_tx_fcb_cmd\n", dev->name); - - if(smctr_wait_while_cbusy(dev)) - return -1; - - tp->sclb_ptr->resume_control = (SCLB_RC_TFCB0 << queue); - tp->sclb_ptr->valid_command = SCLB_RESUME_CONTROL_VALID | SCLB_VALID; - - smctr_set_ctrl_attention(dev); - - return 0; -} - -static int smctr_issue_test_internal_rom_cmd(struct net_device *dev) -{ - int err; - - err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, - TRC_INTERNAL_ROM_TEST); - - return err; -} - -static int smctr_issue_test_hic_cmd(struct net_device *dev) -{ - int err; - - err = smctr_setup_single_cmd(dev, ACB_CMD_HIC_TEST, - TRC_HOST_INTERFACE_REG_TEST); - - return err; -} - -static int smctr_issue_test_mac_reg_cmd(struct net_device *dev) -{ - int err; - - err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, - TRC_MAC_REGISTERS_TEST); - - return err; -} - -static int smctr_issue_trc_loopback_cmd(struct net_device *dev) -{ - int err; - - err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, - TRC_INTERNAL_LOOPBACK); - - return err; -} - -static int smctr_issue_tri_loopback_cmd(struct net_device *dev) -{ - int err; - - err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, - TRC_TRI_LOOPBACK); - - return err; -} - -static int smctr_issue_write_byte_cmd(struct net_device *dev, - short aword_cnt, void *byte) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int iword, ibyte; - int err; - - if((err = smctr_wait_while_cbusy(dev))) - return err; - - if((err = smctr_wait_cmd(dev))) - return err; - - for(iword = 0, ibyte = 0; iword < (unsigned int)(aword_cnt & 0xff); - iword++, ibyte += 2) - { - tp->misc_command_data[iword] = (*((__u8 *)byte + ibyte) << 8) - | (*((__u8 *)byte + ibyte + 1)); - } - - return smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE, - aword_cnt); -} - -static int smctr_issue_write_word_cmd(struct net_device *dev, - short aword_cnt, void *word) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int i, err; - - if((err = smctr_wait_while_cbusy(dev))) - return err; - - if((err = smctr_wait_cmd(dev))) - return err; - - for(i = 0; i < (unsigned int)(aword_cnt & 0xff); i++) - tp->misc_command_data[i] = *((__u16 *)word + i); - - err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE, - aword_cnt); - - return err; -} - -static int smctr_join_complete_state(struct net_device *dev) -{ - int err; - - err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, - JS_JOIN_COMPLETE_STATE); - - return err; -} - -static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int i, j; - FCBlock *fcb; - BDBlock *bdb; - - for(i = 0; i < NUM_TX_QS_USED; i++) - { - fcb = tp->tx_fcb_head[i]; - bdb = tp->tx_bdb_head[i]; - - for(j = 0; j < tp->num_tx_fcbs[i]; j++) - { - fcb->bdb_ptr = bdb; - fcb->trc_bdb_ptr = TRC_POINTER(bdb); - fcb = (FCBlock *)((char *)fcb + sizeof(FCBlock)); - bdb = (BDBlock *)((char *)bdb + sizeof(BDBlock)); - } - } - - return 0; -} - -static int smctr_load_firmware(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - const struct firmware *fw; - __u16 i, checksum = 0; - int err = 0; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_load_firmware\n", dev->name); - - if (request_firmware(&fw, "tr_smctr.bin", &dev->dev)) { - printk(KERN_ERR "%s: firmware not found\n", dev->name); - return UCODE_NOT_PRESENT; - } - - tp->num_of_tx_buffs = 4; - tp->mode_bits |= UMAC; - tp->receive_mask = 0; - tp->max_packet_size = 4177; - - /* Can only upload the firmware once per adapter reset. */ - if (tp->microcode_version != 0) { - err = (UCODE_PRESENT); - goto out; - } - - /* Verify the firmware exists and is there in the right amount. */ - if (!fw->data || - (*(fw->data + UCODE_VERSION_OFFSET) < UCODE_VERSION)) - { - err = (UCODE_NOT_PRESENT); - goto out; - } - - /* UCODE_SIZE is not included in Checksum. */ - for(i = 0; i < *((__u16 *)(fw->data + UCODE_SIZE_OFFSET)); i += 2) - checksum += *((__u16 *)(fw->data + 2 + i)); - if (checksum) { - err = (UCODE_NOT_PRESENT); - goto out; - } - - /* At this point we have a valid firmware image, lets kick it on up. */ - smctr_enable_adapter_ram(dev); - smctr_enable_16bit(dev); - smctr_set_page(dev, (__u8 *)tp->ram_access); - - if((smctr_checksum_firmware(dev)) || - (*(fw->data + UCODE_VERSION_OFFSET) > tp->microcode_version)) - { - smctr_enable_adapter_ctrl_store(dev); - - /* Zero out ram space for firmware. */ - for(i = 0; i < CS_RAM_SIZE; i += 2) - *((__u16 *)(tp->ram_access + i)) = 0; - - smctr_decode_firmware(dev, fw); - - tp->microcode_version = *(fw->data + UCODE_VERSION_OFFSET); *((__u16 *)(tp->ram_access + CS_RAM_VERSION_OFFSET)) - = (tp->microcode_version << 8); - *((__u16 *)(tp->ram_access + CS_RAM_CHECKSUM_OFFSET)) - = ~(tp->microcode_version << 8) + 1; - - smctr_disable_adapter_ctrl_store(dev); - - if(smctr_checksum_firmware(dev)) - err = HARDWARE_FAILED; - } - else - err = UCODE_PRESENT; - - smctr_disable_16bit(dev); - out: - release_firmware(fw); - return err; -} - -static int smctr_load_node_addr(struct net_device *dev) -{ - int ioaddr = dev->base_addr; - unsigned int i; - __u8 r; - - for(i = 0; i < 6; i++) - { - r = inb(ioaddr + LAR0 + i); - dev->dev_addr[i] = (char)r; - } - dev->addr_len = 6; - - return 0; -} - -/* Lobe Media Test. - * During the transmission of the initial 1500 lobe media MAC frames, - * the phase lock loop in the 805 chip may lock, and then un-lock, causing - * the 825 to go into a PURGE state. When performing a PURGE, the MCT - * microcode will not transmit any frames given to it by the host, and - * will consequently cause a timeout. - * - * NOTE 1: If the monitor_state is MS_BEACON_TEST_STATE, all transmit - * queues other than the one used for the lobe_media_test should be - * disabled.!? - * - * NOTE 2: If the monitor_state is MS_BEACON_TEST_STATE and the receive_mask - * has any multi-cast or promiscuous bits set, the receive_mask needs to - * be changed to clear the multi-cast or promiscuous mode bits, the lobe_test - * run, and then the receive mask set back to its original value if the test - * is successful. - */ -static int smctr_lobe_media_test(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int i, perror = 0; - unsigned short saved_rcv_mask; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_lobe_media_test\n", dev->name); - - /* Clear receive mask for lobe test. */ - saved_rcv_mask = tp->receive_mask; - tp->receive_mask = 0; - - smctr_chg_rx_mask(dev); - - /* Setup the lobe media test. */ - smctr_lobe_media_test_cmd(dev); - if(smctr_wait_cmd(dev)) - goto err; - - /* Tx lobe media test frames. */ - for(i = 0; i < 1500; ++i) - { - if(smctr_send_lobe_media_test(dev)) - { - if(perror) - goto err; - else - { - perror = 1; - if(smctr_lobe_media_test_cmd(dev)) - goto err; - } - } - } - - if(smctr_send_dat(dev)) - { - if(smctr_send_dat(dev)) - goto err; - } - - /* Check if any frames received during test. */ - if((tp->rx_fcb_curr[MAC_QUEUE]->frame_status) || - (tp->rx_fcb_curr[NON_MAC_QUEUE]->frame_status)) - goto err; - - /* Set receive mask to "Promisc" mode. */ - tp->receive_mask = saved_rcv_mask; - - smctr_chg_rx_mask(dev); - - return 0; -err: - smctr_reset_adapter(dev); - tp->status = CLOSED; - return LOBE_MEDIA_TEST_FAILED; -} - -static int smctr_lobe_media_test_cmd(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int err; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_lobe_media_test_cmd\n", dev->name); - - /* Change to lobe media test state. */ - if(tp->monitor_state != MS_BEACON_TEST_STATE) - { - smctr_lobe_media_test_state(dev); - if(smctr_wait_cmd(dev)) - { - printk(KERN_ERR "Lobe Failed test state\n"); - return LOBE_MEDIA_TEST_FAILED; - } - } - - err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, - TRC_LOBE_MEDIA_TEST); - - return err; -} - -static int smctr_lobe_media_test_state(struct net_device *dev) -{ - int err; - - err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, - JS_LOBE_TEST_STATE); - - return err; -} - -static int smctr_make_8025_hdr(struct net_device *dev, - MAC_HEADER *rmf, MAC_HEADER *tmf, __u16 ac_fc) -{ - tmf->ac = MSB(ac_fc); /* msb is access control */ - tmf->fc = LSB(ac_fc); /* lsb is frame control */ - - tmf->sa[0] = dev->dev_addr[0]; - tmf->sa[1] = dev->dev_addr[1]; - tmf->sa[2] = dev->dev_addr[2]; - tmf->sa[3] = dev->dev_addr[3]; - tmf->sa[4] = dev->dev_addr[4]; - tmf->sa[5] = dev->dev_addr[5]; - - switch(tmf->vc) - { - /* Send RQ_INIT to RPS */ - case RQ_INIT: - tmf->da[0] = 0xc0; - tmf->da[1] = 0x00; - tmf->da[2] = 0x00; - tmf->da[3] = 0x00; - tmf->da[4] = 0x00; - tmf->da[5] = 0x02; - break; - - /* Send RPT_TX_FORWARD to CRS */ - case RPT_TX_FORWARD: - tmf->da[0] = 0xc0; - tmf->da[1] = 0x00; - tmf->da[2] = 0x00; - tmf->da[3] = 0x00; - tmf->da[4] = 0x00; - tmf->da[5] = 0x10; - break; - - /* Everything else goes to sender */ - default: - tmf->da[0] = rmf->sa[0]; - tmf->da[1] = rmf->sa[1]; - tmf->da[2] = rmf->sa[2]; - tmf->da[3] = rmf->sa[3]; - tmf->da[4] = rmf->sa[4]; - tmf->da[5] = rmf->sa[5]; - break; - } - - return 0; -} - -static int smctr_make_access_pri(struct net_device *dev, MAC_SUB_VECTOR *tsv) -{ - struct net_local *tp = netdev_priv(dev); - - tsv->svi = AUTHORIZED_ACCESS_PRIORITY; - tsv->svl = S_AUTHORIZED_ACCESS_PRIORITY; - - tsv->svv[0] = MSB(tp->authorized_access_priority); - tsv->svv[1] = LSB(tp->authorized_access_priority); - - return 0; -} - -static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv) -{ - tsv->svi = ADDRESS_MODIFER; - tsv->svl = S_ADDRESS_MODIFER; - - tsv->svv[0] = 0; - tsv->svv[1] = 0; - - return 0; -} - -static int smctr_make_auth_funct_class(struct net_device *dev, - MAC_SUB_VECTOR *tsv) -{ - struct net_local *tp = netdev_priv(dev); - - tsv->svi = AUTHORIZED_FUNCTION_CLASS; - tsv->svl = S_AUTHORIZED_FUNCTION_CLASS; - - tsv->svv[0] = MSB(tp->authorized_function_classes); - tsv->svv[1] = LSB(tp->authorized_function_classes); - - return 0; -} - -static int smctr_make_corr(struct net_device *dev, - MAC_SUB_VECTOR *tsv, __u16 correlator) -{ - tsv->svi = CORRELATOR; - tsv->svl = S_CORRELATOR; - - tsv->svv[0] = MSB(correlator); - tsv->svv[1] = LSB(correlator); - - return 0; -} - -static int smctr_make_funct_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) -{ - struct net_local *tp = netdev_priv(dev); - - smctr_get_functional_address(dev); - - tsv->svi = FUNCTIONAL_ADDRESS; - tsv->svl = S_FUNCTIONAL_ADDRESS; - - tsv->svv[0] = MSB(tp->misc_command_data[0]); - tsv->svv[1] = LSB(tp->misc_command_data[0]); - - tsv->svv[2] = MSB(tp->misc_command_data[1]); - tsv->svv[3] = LSB(tp->misc_command_data[1]); - - return 0; -} - -static int smctr_make_group_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) -{ - struct net_local *tp = netdev_priv(dev); - - smctr_get_group_address(dev); - - tsv->svi = GROUP_ADDRESS; - tsv->svl = S_GROUP_ADDRESS; - - tsv->svv[0] = MSB(tp->misc_command_data[0]); - tsv->svv[1] = LSB(tp->misc_command_data[0]); - - tsv->svv[2] = MSB(tp->misc_command_data[1]); - tsv->svv[3] = LSB(tp->misc_command_data[1]); - - /* Set Group Address Sub-vector to all zeros if only the - * Group Address/Functional Address Indicator is set. - */ - if(tsv->svv[0] == 0x80 && tsv->svv[1] == 0x00 && - tsv->svv[2] == 0x00 && tsv->svv[3] == 0x00) - tsv->svv[0] = 0x00; - - return 0; -} - -static int smctr_make_phy_drop_num(struct net_device *dev, - MAC_SUB_VECTOR *tsv) -{ - struct net_local *tp = netdev_priv(dev); - - smctr_get_physical_drop_number(dev); - - tsv->svi = PHYSICAL_DROP; - tsv->svl = S_PHYSICAL_DROP; - - tsv->svv[0] = MSB(tp->misc_command_data[0]); - tsv->svv[1] = LSB(tp->misc_command_data[0]); - - tsv->svv[2] = MSB(tp->misc_command_data[1]); - tsv->svv[3] = LSB(tp->misc_command_data[1]); - - return 0; -} - -static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) -{ - int i; - - tsv->svi = PRODUCT_INSTANCE_ID; - tsv->svl = S_PRODUCT_INSTANCE_ID; - - for(i = 0; i < 18; i++) - tsv->svv[i] = 0xF0; - - return 0; -} - -static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) -{ - struct net_local *tp = netdev_priv(dev); - - smctr_get_station_id(dev); - - tsv->svi = STATION_IDENTIFER; - tsv->svl = S_STATION_IDENTIFER; - - tsv->svv[0] = MSB(tp->misc_command_data[0]); - tsv->svv[1] = LSB(tp->misc_command_data[0]); - - tsv->svv[2] = MSB(tp->misc_command_data[1]); - tsv->svv[3] = LSB(tp->misc_command_data[1]); - - tsv->svv[4] = MSB(tp->misc_command_data[2]); - tsv->svv[5] = LSB(tp->misc_command_data[2]); - - return 0; -} - -static int smctr_make_ring_station_status(struct net_device *dev, - MAC_SUB_VECTOR * tsv) -{ - tsv->svi = RING_STATION_STATUS; - tsv->svl = S_RING_STATION_STATUS; - - tsv->svv[0] = 0; - tsv->svv[1] = 0; - tsv->svv[2] = 0; - tsv->svv[3] = 0; - tsv->svv[4] = 0; - tsv->svv[5] = 0; - - return 0; -} - -static int smctr_make_ring_station_version(struct net_device *dev, - MAC_SUB_VECTOR *tsv) -{ - struct net_local *tp = netdev_priv(dev); - - tsv->svi = RING_STATION_VERSION_NUMBER; - tsv->svl = S_RING_STATION_VERSION_NUMBER; - - tsv->svv[0] = 0xe2; /* EBCDIC - S */ - tsv->svv[1] = 0xd4; /* EBCDIC - M */ - tsv->svv[2] = 0xc3; /* EBCDIC - C */ - tsv->svv[3] = 0x40; /* EBCDIC - */ - tsv->svv[4] = 0xe5; /* EBCDIC - V */ - tsv->svv[5] = 0xF0 + (tp->microcode_version >> 4); - tsv->svv[6] = 0xF0 + (tp->microcode_version & 0x0f); - tsv->svv[7] = 0x40; /* EBCDIC - */ - tsv->svv[8] = 0xe7; /* EBCDIC - X */ - - if(tp->extra_info & CHIP_REV_MASK) - tsv->svv[9] = 0xc5; /* EBCDIC - E */ - else - tsv->svv[9] = 0xc4; /* EBCDIC - D */ - - return 0; -} - -static int smctr_make_tx_status_code(struct net_device *dev, - MAC_SUB_VECTOR *tsv, __u16 tx_fstatus) -{ - tsv->svi = TRANSMIT_STATUS_CODE; - tsv->svl = S_TRANSMIT_STATUS_CODE; - - tsv->svv[0] = ((tx_fstatus & 0x0100 >> 6) | IBM_PASS_SOURCE_ADDR); - - /* Stripped frame status of Transmitted Frame */ - tsv->svv[1] = tx_fstatus & 0xff; - - return 0; -} - -static int smctr_make_upstream_neighbor_addr(struct net_device *dev, - MAC_SUB_VECTOR *tsv) -{ - struct net_local *tp = netdev_priv(dev); - - smctr_get_upstream_neighbor_addr(dev); - - tsv->svi = UPSTREAM_NEIGHBOR_ADDRESS; - tsv->svl = S_UPSTREAM_NEIGHBOR_ADDRESS; - - tsv->svv[0] = MSB(tp->misc_command_data[0]); - tsv->svv[1] = LSB(tp->misc_command_data[0]); - - tsv->svv[2] = MSB(tp->misc_command_data[1]); - tsv->svv[3] = LSB(tp->misc_command_data[1]); - - tsv->svv[4] = MSB(tp->misc_command_data[2]); - tsv->svv[5] = LSB(tp->misc_command_data[2]); - - return 0; -} - -static int smctr_make_wrap_data(struct net_device *dev, MAC_SUB_VECTOR *tsv) -{ - tsv->svi = WRAP_DATA; - tsv->svl = S_WRAP_DATA; - - return 0; -} - -/* - * Open/initialize the board. This is called 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 int smctr_open(struct net_device *dev) -{ - int err; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_open\n", dev->name); - - err = smctr_init_adapter(dev); - if(err < 0) - return err; - - return err; -} - -/* Interrupt driven open of Token card. */ -static int smctr_open_tr(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned long flags; - int err; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_open_tr\n", dev->name); - - /* Now we can actually open the adapter. */ - if(tp->status == OPEN) - return 0; - if(tp->status != INITIALIZED) - return -1; - - /* FIXME: it would work a lot better if we masked the irq sources - on the card here, then we could skip the locking and poll nicely */ - spin_lock_irqsave(&tp->lock, flags); - - smctr_set_page(dev, (__u8 *)tp->ram_access); - - if((err = smctr_issue_resume_rx_fcb_cmd(dev, (short)MAC_QUEUE))) - goto out; - - if((err = smctr_issue_resume_rx_bdb_cmd(dev, (short)MAC_QUEUE))) - goto out; - - if((err = smctr_issue_resume_rx_fcb_cmd(dev, (short)NON_MAC_QUEUE))) - goto out; - - if((err = smctr_issue_resume_rx_bdb_cmd(dev, (short)NON_MAC_QUEUE))) - goto out; - - tp->status = CLOSED; - - /* Insert into the Ring or Enter Loopback Mode. */ - if((tp->mode_bits & LOOPING_MODE_MASK) == LOOPBACK_MODE_1) - { - tp->status = CLOSED; - - if(!(err = smctr_issue_trc_loopback_cmd(dev))) - { - if(!(err = smctr_wait_cmd(dev))) - tp->status = OPEN; - } - - smctr_status_chg(dev); - } - else - { - if((tp->mode_bits & LOOPING_MODE_MASK) == LOOPBACK_MODE_2) - { - tp->status = CLOSED; - if(!(err = smctr_issue_tri_loopback_cmd(dev))) - { - if(!(err = smctr_wait_cmd(dev))) - tp->status = OPEN; - } - - smctr_status_chg(dev); - } - else - { - if((tp->mode_bits & LOOPING_MODE_MASK) - == LOOPBACK_MODE_3) - { - tp->status = CLOSED; - if(!(err = smctr_lobe_media_test_cmd(dev))) - { - if(!(err = smctr_wait_cmd(dev))) - tp->status = OPEN; - } - smctr_status_chg(dev); - } - else - { - if(!(err = smctr_lobe_media_test(dev))) - err = smctr_issue_insert_cmd(dev); - else - { - if(err == LOBE_MEDIA_TEST_FAILED) - printk(KERN_WARNING "%s: Lobe Media Test Failure - Check cable?\n", dev->name); - } - } - } - } - -out: - spin_unlock_irqrestore(&tp->lock, flags); - - return err; -} - -/* Check for a network adapter of this type, - * and return device structure if one exists. - */ -struct net_device __init *smctr_probe(int unit) -{ - struct net_device *dev = alloc_trdev(sizeof(struct net_local)); - static const unsigned ports[] = { - 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300, - 0x320, 0x340, 0x360, 0x380, 0 - }; - const unsigned *port; - int err = 0; - - if (!dev) - return ERR_PTR(-ENOMEM); - - if (unit >= 0) { - sprintf(dev->name, "tr%d", unit); - netdev_boot_setup_check(dev); - } - - if (dev->base_addr > 0x1ff) /* Check a single specified location. */ - err = smctr_probe1(dev, dev->base_addr); - else if(dev->base_addr != 0) /* Don't probe at all. */ - err =-ENXIO; - else { - for (port = ports; *port; port++) { - err = smctr_probe1(dev, *port); - if (!err) - break; - } - } - if (err) - goto out; - err = register_netdev(dev); - if (err) - goto out1; - return dev; -out1: -#ifdef CONFIG_MCA_LEGACY - { struct net_local *tp = netdev_priv(dev); - if (tp->slot_num) - mca_mark_as_unused(tp->slot_num); - } -#endif - release_region(dev->base_addr, SMCTR_IO_EXTENT); - free_irq(dev->irq, dev); -out: - free_netdev(dev); - return ERR_PTR(err); -} - -static const struct net_device_ops smctr_netdev_ops = { - .ndo_open = smctr_open, - .ndo_stop = smctr_close, - .ndo_start_xmit = smctr_send_packet, - .ndo_tx_timeout = smctr_timeout, - .ndo_get_stats = smctr_get_stats, - .ndo_set_rx_mode = smctr_set_multicast_list, -}; - -static int __init smctr_probe1(struct net_device *dev, int ioaddr) -{ - static unsigned version_printed; - struct net_local *tp = netdev_priv(dev); - int err; - __u32 *ram; - - if(smctr_debug && version_printed++ == 0) - printk(version); - - spin_lock_init(&tp->lock); - dev->base_addr = ioaddr; - - /* Actually detect an adapter now. */ - err = smctr_chk_isa(dev); - if(err < 0) - { - if ((err = smctr_chk_mca(dev)) < 0) { - err = -ENODEV; - goto out; - } - } - - tp = netdev_priv(dev); - dev->mem_start = tp->ram_base; - dev->mem_end = dev->mem_start + 0x10000; - ram = (__u32 *)phys_to_virt(dev->mem_start); - tp->ram_access = *(__u32 *)&ram; - tp->status = NOT_INITIALIZED; - - err = smctr_load_firmware(dev); - if(err != UCODE_PRESENT && err != SUCCESS) - { - printk(KERN_ERR "%s: Firmware load failed (%d)\n", dev->name, err); - err = -EIO; - goto out; - } - - /* Allow user to specify ring speed on module insert. */ - if(ringspeed == 4) - tp->media_type = MEDIA_UTP_4; - else - tp->media_type = MEDIA_UTP_16; - - printk(KERN_INFO "%s: %s %s at Io %#4x, Irq %d, Rom %#4x, Ram %#4x.\n", - dev->name, smctr_name, smctr_model, - (unsigned int)dev->base_addr, - dev->irq, tp->rom_base, tp->ram_base); - - dev->netdev_ops = &smctr_netdev_ops; - dev->watchdog_timeo = HZ; - return 0; - -out: - return err; -} - -static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, - struct net_device *dev, __u16 rx_status) -{ - struct net_local *tp = netdev_priv(dev); - struct sk_buff *skb; - __u16 rcode, correlator; - int err = 0; - __u8 xframe = 1; - - rmf->vl = SWAP_BYTES(rmf->vl); - if(rx_status & FCB_RX_STATUS_DA_MATCHED) - { - switch(rmf->vc) - { - /* Received MAC Frames Processed by RS. */ - case INIT: - if((rcode = smctr_rcv_init(dev, rmf, &correlator)) == HARDWARE_FAILED) - { - return rcode; - } - - if((err = smctr_send_rsp(dev, rmf, rcode, - correlator))) - { - return err; - } - break; - - case CHG_PARM: - if((rcode = smctr_rcv_chg_param(dev, rmf, - &correlator)) ==HARDWARE_FAILED) - { - return rcode; - } - - if((err = smctr_send_rsp(dev, rmf, rcode, - correlator))) - { - return err; - } - break; - - case RQ_ADDR: - if((rcode = smctr_rcv_rq_addr_state_attch(dev, - rmf, &correlator)) != POSITIVE_ACK) - { - if(rcode == HARDWARE_FAILED) - return rcode; - else - return smctr_send_rsp(dev, rmf, - rcode, correlator); - } - - if((err = smctr_send_rpt_addr(dev, rmf, - correlator))) - { - return err; - } - break; - - case RQ_ATTCH: - if((rcode = smctr_rcv_rq_addr_state_attch(dev, - rmf, &correlator)) != POSITIVE_ACK) - { - if(rcode == HARDWARE_FAILED) - return rcode; - else - return smctr_send_rsp(dev, rmf, - rcode, - correlator); - } - - if((err = smctr_send_rpt_attch(dev, rmf, - correlator))) - { - return err; - } - break; - - case RQ_STATE: - if((rcode = smctr_rcv_rq_addr_state_attch(dev, - rmf, &correlator)) != POSITIVE_ACK) - { - if(rcode == HARDWARE_FAILED) - return rcode; - else - return smctr_send_rsp(dev, rmf, - rcode, - correlator); - } - - if((err = smctr_send_rpt_state(dev, rmf, - correlator))) - { - return err; - } - break; - - case TX_FORWARD: { - __u16 uninitialized_var(tx_fstatus); - - if((rcode = smctr_rcv_tx_forward(dev, rmf)) - != POSITIVE_ACK) - { - if(rcode == HARDWARE_FAILED) - return rcode; - else - return smctr_send_rsp(dev, rmf, - rcode, - correlator); - } - - if((err = smctr_send_tx_forward(dev, rmf, - &tx_fstatus)) == HARDWARE_FAILED) - { - return err; - } - - if(err == A_FRAME_WAS_FORWARDED) - { - if((err = smctr_send_rpt_tx_forward(dev, - rmf, tx_fstatus)) - == HARDWARE_FAILED) - { - return err; - } - } - break; - } - - /* Received MAC Frames Processed by CRS/REM/RPS. */ - case RSP: - case RQ_INIT: - case RPT_NEW_MON: - case RPT_SUA_CHG: - case RPT_ACTIVE_ERR: - case RPT_NN_INCMP: - case RPT_ERROR: - case RPT_ATTCH: - case RPT_STATE: - case RPT_ADDR: - break; - - /* Rcvd Att. MAC Frame (if RXATMAC set) or UNKNOWN */ - default: - xframe = 0; - if(!(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES)) - { - rcode = smctr_rcv_unknown(dev, rmf, - &correlator); - if((err = smctr_send_rsp(dev, rmf,rcode, - correlator))) - { - return err; - } - } - - break; - } - } - else - { - /* 1. DA doesn't match (Promiscuous Mode). - * 2. Parse for Extended MAC Frame Type. - */ - switch(rmf->vc) - { - case RSP: - case INIT: - case RQ_INIT: - case RQ_ADDR: - case RQ_ATTCH: - case RQ_STATE: - case CHG_PARM: - case RPT_ADDR: - case RPT_ERROR: - case RPT_ATTCH: - case RPT_STATE: - case RPT_NEW_MON: - case RPT_SUA_CHG: - case RPT_NN_INCMP: - case RPT_ACTIVE_ERR: - break; - - default: - xframe = 0; - break; - } - } - - /* NOTE: UNKNOWN MAC frames will NOT be passed up unless - * ACCEPT_ATT_MAC_FRAMES is set. - */ - if(((tp->receive_mask & ACCEPT_ATT_MAC_FRAMES) && - (xframe == (__u8)0)) || - ((tp->receive_mask & ACCEPT_EXT_MAC_FRAMES) && - (xframe == (__u8)1))) - { - rmf->vl = SWAP_BYTES(rmf->vl); - - if (!(skb = dev_alloc_skb(size))) - return -ENOMEM; - skb->len = size; - - /* Slide data into a sleek skb. */ - skb_put(skb, skb->len); - skb_copy_to_linear_data(skb, rmf, skb->len); - - /* Update Counters */ - tp->MacStat.rx_packets++; - tp->MacStat.rx_bytes += skb->len; - - /* Kick the packet on up. */ - skb->protocol = tr_type_trans(skb, dev); - netif_rx(skb); - err = 0; - } - - return err; -} - -/* Adapter RAM test. Incremental word ODD boundary data test. */ -static int smctr_ram_memory_test(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - __u16 page, pages_of_ram, start_pattern = 0, word_pattern = 0, - word_read = 0, err_word = 0, err_pattern = 0; - unsigned int err_offset; - __u32 j, pword; - __u8 err = 0; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_ram_memory_test\n", dev->name); - - start_pattern = 0x0001; - pages_of_ram = tp->ram_size / tp->ram_usable; - pword = tp->ram_access; - - /* Incremental word ODD boundary test. */ - for(page = 0; (page < pages_of_ram) && (~err); - page++, start_pattern += 0x8000) - { - smctr_set_page(dev, (__u8 *)(tp->ram_access - + (page * tp->ram_usable * 1024) + 1)); - word_pattern = start_pattern; - - for(j = 1; j < (__u32)(tp->ram_usable * 1024) - 1; j += 2) - *(__u16 *)(pword + j) = word_pattern++; - - word_pattern = start_pattern; - - for(j = 1; j < (__u32)(tp->ram_usable * 1024) - 1 && (~err); - j += 2, word_pattern++) - { - word_read = *(__u16 *)(pword + j); - if(word_read != word_pattern) - { - err = (__u8)1; - err_offset = j; - err_word = word_read; - err_pattern = word_pattern; - return RAM_TEST_FAILED; - } - } - } - - /* Zero out memory. */ - for(page = 0; page < pages_of_ram && (~err); page++) - { - smctr_set_page(dev, (__u8 *)(tp->ram_access - + (page * tp->ram_usable * 1024))); - word_pattern = 0; - - for(j = 0; j < (__u32)tp->ram_usable * 1024; j +=2) - *(__u16 *)(pword + j) = word_pattern; - - for(j =0; j < (__u32)tp->ram_usable * 1024 && (~err); j += 2) - { - word_read = *(__u16 *)(pword + j); - if(word_read != word_pattern) - { - err = (__u8)1; - err_offset = j; - err_word = word_read; - err_pattern = word_pattern; - return RAM_TEST_FAILED; - } - } - } - - smctr_set_page(dev, (__u8 *)tp->ram_access); - - return 0; -} - -static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf, - __u16 *correlator) -{ - MAC_SUB_VECTOR *rsv; - signed short vlen; - __u16 rcode = POSITIVE_ACK; - unsigned int svectors = F_NO_SUB_VECTORS_FOUND; - - /* This Frame can only come from a CRS */ - if((rmf->dc_sc & SC_MASK) != SC_CRS) - return E_INAPPROPRIATE_SOURCE_CLASS; - - /* Remove MVID Length from total length. */ - vlen = (signed short)rmf->vl - 4; - - /* Point to First SVID */ - rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); - - /* Search for Appropriate SVID's. */ - while((vlen > 0) && (rcode == POSITIVE_ACK)) - { - switch(rsv->svi) - { - case CORRELATOR: - svectors |= F_CORRELATOR; - rcode = smctr_set_corr(dev, rsv, correlator); - break; - - case LOCAL_RING_NUMBER: - svectors |= F_LOCAL_RING_NUMBER; - rcode = smctr_set_local_ring_num(dev, rsv); - break; - - case ASSIGN_PHYSICAL_DROP: - svectors |= F_ASSIGN_PHYSICAL_DROP; - rcode = smctr_set_phy_drop(dev, rsv); - break; - - case ERROR_TIMER_VALUE: - svectors |= F_ERROR_TIMER_VALUE; - rcode = smctr_set_error_timer_value(dev, rsv); - break; - - case AUTHORIZED_FUNCTION_CLASS: - svectors |= F_AUTHORIZED_FUNCTION_CLASS; - rcode = smctr_set_auth_funct_class(dev, rsv); - break; - - case AUTHORIZED_ACCESS_PRIORITY: - svectors |= F_AUTHORIZED_ACCESS_PRIORITY; - rcode = smctr_set_auth_access_pri(dev, rsv); - break; - - default: - rcode = E_SUB_VECTOR_UNKNOWN; - break; - } - - /* Let Sender Know if SUM of SV length's is - * larger then length in MVID length field - */ - if((vlen -= rsv->svl) < 0) - rcode = E_VECTOR_LENGTH_ERROR; - - rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); - } - - if(rcode == POSITIVE_ACK) - { - /* Let Sender Know if MVID length field - * is larger then SUM of SV length's - */ - if(vlen != 0) - rcode = E_VECTOR_LENGTH_ERROR; - else - { - /* Let Sender Know if Expected SVID Missing */ - if((svectors & R_CHG_PARM) ^ R_CHG_PARM) - rcode = E_MISSING_SUB_VECTOR; - } - } - - return rcode; -} - -static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf, - __u16 *correlator) -{ - MAC_SUB_VECTOR *rsv; - signed short vlen; - __u16 rcode = POSITIVE_ACK; - unsigned int svectors = F_NO_SUB_VECTORS_FOUND; - - /* This Frame can only come from a RPS */ - if((rmf->dc_sc & SC_MASK) != SC_RPS) - return E_INAPPROPRIATE_SOURCE_CLASS; - - /* Remove MVID Length from total length. */ - vlen = (signed short)rmf->vl - 4; - - /* Point to First SVID */ - rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); - - /* Search for Appropriate SVID's */ - while((vlen > 0) && (rcode == POSITIVE_ACK)) - { - switch(rsv->svi) - { - case CORRELATOR: - svectors |= F_CORRELATOR; - rcode = smctr_set_corr(dev, rsv, correlator); - break; - - case LOCAL_RING_NUMBER: - svectors |= F_LOCAL_RING_NUMBER; - rcode = smctr_set_local_ring_num(dev, rsv); - break; - - case ASSIGN_PHYSICAL_DROP: - svectors |= F_ASSIGN_PHYSICAL_DROP; - rcode = smctr_set_phy_drop(dev, rsv); - break; - - case ERROR_TIMER_VALUE: - svectors |= F_ERROR_TIMER_VALUE; - rcode = smctr_set_error_timer_value(dev, rsv); - break; - - default: - rcode = E_SUB_VECTOR_UNKNOWN; - break; - } - - /* Let Sender Know if SUM of SV length's is - * larger then length in MVID length field - */ - if((vlen -= rsv->svl) < 0) - rcode = E_VECTOR_LENGTH_ERROR; - - rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); - } - - if(rcode == POSITIVE_ACK) - { - /* Let Sender Know if MVID length field - * is larger then SUM of SV length's - */ - if(vlen != 0) - rcode = E_VECTOR_LENGTH_ERROR; - else - { - /* Let Sender Know if Expected SV Missing */ - if((svectors & R_INIT) ^ R_INIT) - rcode = E_MISSING_SUB_VECTOR; - } - } - - return rcode; -} - -static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf) -{ - MAC_SUB_VECTOR *rsv; - signed short vlen; - __u16 rcode = POSITIVE_ACK; - unsigned int svectors = F_NO_SUB_VECTORS_FOUND; - - /* This Frame can only come from a CRS */ - if((rmf->dc_sc & SC_MASK) != SC_CRS) - return E_INAPPROPRIATE_SOURCE_CLASS; - - /* Remove MVID Length from total length */ - vlen = (signed short)rmf->vl - 4; - - /* Point to First SVID */ - rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); - - /* Search for Appropriate SVID's */ - while((vlen > 0) && (rcode == POSITIVE_ACK)) - { - switch(rsv->svi) - { - case FRAME_FORWARD: - svectors |= F_FRAME_FORWARD; - rcode = smctr_set_frame_forward(dev, rsv, - rmf->dc_sc); - break; - - default: - rcode = E_SUB_VECTOR_UNKNOWN; - break; - } - - /* Let Sender Know if SUM of SV length's is - * larger then length in MVID length field - */ - if((vlen -= rsv->svl) < 0) - rcode = E_VECTOR_LENGTH_ERROR; - - rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); - } - - if(rcode == POSITIVE_ACK) - { - /* Let Sender Know if MVID length field - * is larger then SUM of SV length's - */ - if(vlen != 0) - rcode = E_VECTOR_LENGTH_ERROR; - else - { - /* Let Sender Know if Expected SV Missing */ - if((svectors & R_TX_FORWARD) ^ R_TX_FORWARD) - rcode = E_MISSING_SUB_VECTOR; - } - } - - return rcode; -} - -static int smctr_rcv_rq_addr_state_attch(struct net_device *dev, - MAC_HEADER *rmf, __u16 *correlator) -{ - MAC_SUB_VECTOR *rsv; - signed short vlen; - __u16 rcode = POSITIVE_ACK; - unsigned int svectors = F_NO_SUB_VECTORS_FOUND; - - /* Remove MVID Length from total length */ - vlen = (signed short)rmf->vl - 4; - - /* Point to First SVID */ - rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); - - /* Search for Appropriate SVID's */ - while((vlen > 0) && (rcode == POSITIVE_ACK)) - { - switch(rsv->svi) - { - case CORRELATOR: - svectors |= F_CORRELATOR; - rcode = smctr_set_corr(dev, rsv, correlator); - break; - - default: - rcode = E_SUB_VECTOR_UNKNOWN; - break; - } - - /* Let Sender Know if SUM of SV length's is - * larger then length in MVID length field - */ - if((vlen -= rsv->svl) < 0) - rcode = E_VECTOR_LENGTH_ERROR; - - rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); - } - - if(rcode == POSITIVE_ACK) - { - /* Let Sender Know if MVID length field - * is larger then SUM of SV length's - */ - if(vlen != 0) - rcode = E_VECTOR_LENGTH_ERROR; - else - { - /* Let Sender Know if Expected SVID Missing */ - if((svectors & R_RQ_ATTCH_STATE_ADDR) - ^ R_RQ_ATTCH_STATE_ADDR) - rcode = E_MISSING_SUB_VECTOR; - } - } - - return rcode; -} - -static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf, - __u16 *correlator) -{ - MAC_SUB_VECTOR *rsv; - signed short vlen; - - *correlator = 0; - - /* Remove MVID Length from total length */ - vlen = (signed short)rmf->vl - 4; - - /* Point to First SVID */ - rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); - - /* Search for CORRELATOR for RSP to UNKNOWN */ - while((vlen > 0) && (*correlator == 0)) - { - switch(rsv->svi) - { - case CORRELATOR: - smctr_set_corr(dev, rsv, correlator); - break; - - default: - break; - } - - vlen -= rsv->svl; - rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); - } - - return E_UNRECOGNIZED_VECTOR_ID; -} - -/* - * Reset the 825 NIC and exit w: - * 1. The NIC reset cleared (non-reset state), halted and un-initialized. - * 2. TINT masked. - * 3. CBUSY masked. - * 4. TINT clear. - * 5. CBUSY clear. - */ -static int smctr_reset_adapter(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int ioaddr = dev->base_addr; - - /* Reseting the NIC will put it in a halted and un-initialized state. */ smctr_set_trc_reset(ioaddr); - mdelay(200); /* ~2 ms */ - - smctr_clear_trc_reset(ioaddr); - mdelay(200); /* ~2 ms */ - - /* Remove any latched interrupts that occurred prior to reseting the - * adapter or possibily caused by line glitches due to the reset. - */ - outb(tp->trc_mask | CSR_CLRTINT | CSR_CLRCBUSY, ioaddr + CSR); - - return 0; -} - -static int smctr_restart_tx_chain(struct net_device *dev, short queue) -{ - struct net_local *tp = netdev_priv(dev); - int err = 0; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_restart_tx_chain\n", dev->name); - - if(tp->num_tx_fcbs_used[queue] != 0 && - tp->tx_queue_status[queue] == NOT_TRANSMITING) - { - tp->tx_queue_status[queue] = TRANSMITING; - err = smctr_issue_resume_tx_fcb_cmd(dev, queue); - } - - return err; -} - -static int smctr_ring_status_chg(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_ring_status_chg\n", dev->name); - - /* Check for ring_status_flag: whenever MONITOR_STATE_BIT - * Bit is set, check value of monitor_state, only then we - * enable and start transmit/receive timeout (if and only - * if it is MS_ACTIVE_MONITOR_STATE or MS_STANDBY_MONITOR_STATE) - */ - if(tp->ring_status_flags == MONITOR_STATE_CHANGED) - { - if((tp->monitor_state == MS_ACTIVE_MONITOR_STATE) || - (tp->monitor_state == MS_STANDBY_MONITOR_STATE)) - { - tp->monitor_state_ready = 1; - } - else - { - /* if adapter is NOT in either active monitor - * or standby monitor state => Disable - * transmit/receive timeout. - */ - tp->monitor_state_ready = 0; - - /* Ring speed problem, switching to auto mode. */ - if(tp->monitor_state == MS_MONITOR_FSM_INACTIVE && - !tp->cleanup) - { - printk(KERN_INFO "%s: Incorrect ring speed switching.\n", - dev->name); - smctr_set_ring_speed(dev); - } - } - } - - if(!(tp->ring_status_flags & RING_STATUS_CHANGED)) - return 0; - - switch(tp->ring_status) - { - case RING_RECOVERY: - printk(KERN_INFO "%s: Ring Recovery\n", dev->name); - break; - - case SINGLE_STATION: - printk(KERN_INFO "%s: Single Statinon\n", dev->name); - break; - - case COUNTER_OVERFLOW: - printk(KERN_INFO "%s: Counter Overflow\n", dev->name); - break; - - case REMOVE_RECEIVED: - printk(KERN_INFO "%s: Remove Received\n", dev->name); - break; - - case AUTO_REMOVAL_ERROR: - printk(KERN_INFO "%s: Auto Remove Error\n", dev->name); - break; - - case LOBE_WIRE_FAULT: - printk(KERN_INFO "%s: Lobe Wire Fault\n", dev->name); - break; - - case TRANSMIT_BEACON: - printk(KERN_INFO "%s: Transmit Beacon\n", dev->name); - break; - - case SOFT_ERROR: - printk(KERN_INFO "%s: Soft Error\n", dev->name); - break; - - case HARD_ERROR: - printk(KERN_INFO "%s: Hard Error\n", dev->name); - break; - - case SIGNAL_LOSS: - printk(KERN_INFO "%s: Signal Loss\n", dev->name); - break; - - default: - printk(KERN_INFO "%s: Unknown ring status change\n", - dev->name); - break; - } - - return 0; -} - -static int smctr_rx_frame(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - __u16 queue, status, rx_size, err = 0; - __u8 *pbuff; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_rx_frame\n", dev->name); - - queue = tp->receive_queue_number; - - while((status = tp->rx_fcb_curr[queue]->frame_status) != SUCCESS) - { - err = HARDWARE_FAILED; - - if(((status & 0x007f) == 0) || - ((tp->receive_mask & ACCEPT_ERR_PACKETS) != 0)) - { - /* frame length less the CRC (4 bytes) + FS (1 byte) */ - rx_size = tp->rx_fcb_curr[queue]->frame_length - 5; - - pbuff = smctr_get_rx_pointer(dev, queue); - - smctr_set_page(dev, pbuff); - smctr_disable_16bit(dev); - - /* pbuff points to addr within one page */ - pbuff = (__u8 *)PAGE_POINTER(pbuff); - - if(queue == NON_MAC_QUEUE) - { - struct sk_buff *skb; - - skb = dev_alloc_skb(rx_size); - if (skb) { - skb_put(skb, rx_size); - - skb_copy_to_linear_data(skb, pbuff, rx_size); - - /* Update Counters */ - tp->MacStat.rx_packets++; - tp->MacStat.rx_bytes += skb->len; - - /* Kick the packet on up. */ - skb->protocol = tr_type_trans(skb, dev); - netif_rx(skb); - } else { - } - } - else - smctr_process_rx_packet((MAC_HEADER *)pbuff, - rx_size, dev, status); - } - - smctr_enable_16bit(dev); - smctr_set_page(dev, (__u8 *)tp->ram_access); - smctr_update_rx_chain(dev, queue); - - if(err != SUCCESS) - break; - } - - return err; -} - -static int smctr_send_dat(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int i, err; - MAC_HEADER *tmf; - FCBlock *fcb; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_send_dat\n", dev->name); - - if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, - sizeof(MAC_HEADER))) == (FCBlock *)(-1L)) - { - return OUT_OF_RESOURCES; - } - - /* Initialize DAT Data Fields. */ - tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; - tmf->ac = MSB(AC_FC_DAT); - tmf->fc = LSB(AC_FC_DAT); - - for(i = 0; i < 6; i++) - { - tmf->sa[i] = dev->dev_addr[i]; - tmf->da[i] = dev->dev_addr[i]; - - } - - tmf->vc = DAT; - tmf->dc_sc = DC_RS | SC_RS; - tmf->vl = 4; - tmf->vl = SWAP_BYTES(tmf->vl); - - /* Start Transmit. */ - if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) - return err; - - /* Wait for Transmit to Complete */ - for(i = 0; i < 10000; i++) - { - if(fcb->frame_status & FCB_COMMAND_DONE) - break; - mdelay(1); - } - - /* Check if GOOD frame Tx'ed. */ - if(!(fcb->frame_status & FCB_COMMAND_DONE) || - fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS)) - { - return INITIALIZE_FAILED; - } - - /* De-allocated Tx FCB and Frame Buffer - * The FCB must be de-allocated manually if executing with - * interrupts disabled, other wise the ISR (LM_Service_Events) - * will de-allocate it when the interrupt occurs. - */ - tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; - smctr_update_tx_chain(dev, fcb, MAC_QUEUE); - - return 0; -} - -static void smctr_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. - * - * Resetting the token ring adapter takes a long time so just - * fake transmission time and go on trying. Our own timeout - * routine is in sktr_timer_chk() - */ - dev->trans_start = jiffies; /* prevent tx timeout */ - netif_wake_queue(dev); -} - -/* - * Gets skb from system, queues it and checks if it can be sent - */ -static netdev_tx_t smctr_send_packet(struct sk_buff *skb, - struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_send_packet\n", dev->name); - - /* - * Block a transmit overlap - */ - - netif_stop_queue(dev); - - if(tp->QueueSkb == 0) - return NETDEV_TX_BUSY; /* Return with tbusy set: queue full */ - - tp->QueueSkb--; - skb_queue_tail(&tp->SendSkbQueue, skb); - smctr_hardware_send_packet(dev, tp); - if(tp->QueueSkb > 0) - netif_wake_queue(dev); - - return NETDEV_TX_OK; -} - -static int smctr_send_lobe_media_test(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - MAC_SUB_VECTOR *tsv; - MAC_HEADER *tmf; - FCBlock *fcb; - __u32 i; - int err; - - if(smctr_debug > 15) - printk(KERN_DEBUG "%s: smctr_send_lobe_media_test\n", dev->name); - - if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(struct trh_hdr) - + S_WRAP_DATA + S_WRAP_DATA)) == (FCBlock *)(-1L)) - { - return OUT_OF_RESOURCES; - } - - /* Initialize DAT Data Fields. */ - tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; - tmf->ac = MSB(AC_FC_LOBE_MEDIA_TEST); - tmf->fc = LSB(AC_FC_LOBE_MEDIA_TEST); - - for(i = 0; i < 6; i++) - { - tmf->da[i] = 0; - tmf->sa[i] = dev->dev_addr[i]; - } - - tmf->vc = LOBE_MEDIA_TEST; - tmf->dc_sc = DC_RS | SC_RS; - tmf->vl = 4; - - tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); - smctr_make_wrap_data(dev, tsv); - tmf->vl += tsv->svl; - - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_wrap_data(dev, tsv); - tmf->vl += tsv->svl; - - /* Start Transmit. */ - tmf->vl = SWAP_BYTES(tmf->vl); - if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) - return err; - - /* Wait for Transmit to Complete. (10 ms). */ - for(i=0; i < 10000; i++) - { - if(fcb->frame_status & FCB_COMMAND_DONE) - break; - mdelay(1); - } - - /* Check if GOOD frame Tx'ed */ - if(!(fcb->frame_status & FCB_COMMAND_DONE) || - fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS)) - { - return LOBE_MEDIA_TEST_FAILED; - } - - /* De-allocated Tx FCB and Frame Buffer - * The FCB must be de-allocated manually if executing with - * interrupts disabled, other wise the ISR (LM_Service_Events) - * will de-allocate it when the interrupt occurs. - */ - tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; - smctr_update_tx_chain(dev, fcb, MAC_QUEUE); - - return 0; -} - -static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf, - __u16 correlator) -{ - MAC_HEADER *tmf; - MAC_SUB_VECTOR *tsv; - FCBlock *fcb; - - if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) - + S_CORRELATOR + S_PHYSICAL_DROP + S_UPSTREAM_NEIGHBOR_ADDRESS - + S_ADDRESS_MODIFER + S_GROUP_ADDRESS + S_FUNCTIONAL_ADDRESS)) - == (FCBlock *)(-1L)) - { - return 0; - } - - tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; - tmf->vc = RPT_ADDR; - tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; - tmf->vl = 4; - - smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_ADDR); - - tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); - smctr_make_corr(dev, tsv, correlator); - - tmf->vl += tsv->svl; - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_phy_drop_num(dev, tsv); - - tmf->vl += tsv->svl; - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_upstream_neighbor_addr(dev, tsv); - - tmf->vl += tsv->svl; - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_addr_mod(dev, tsv); - - tmf->vl += tsv->svl; - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_group_addr(dev, tsv); - - tmf->vl += tsv->svl; - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_funct_addr(dev, tsv); - - tmf->vl += tsv->svl; - - /* Subtract out MVID and MVL which is - * include in both vl and MAC_HEADER - */ -/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; - fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; -*/ - tmf->vl = SWAP_BYTES(tmf->vl); - - return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); -} - -static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf, - __u16 correlator) -{ - MAC_HEADER *tmf; - MAC_SUB_VECTOR *tsv; - FCBlock *fcb; - - if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) - + S_CORRELATOR + S_PRODUCT_INSTANCE_ID + S_FUNCTIONAL_ADDRESS - + S_AUTHORIZED_FUNCTION_CLASS + S_AUTHORIZED_ACCESS_PRIORITY)) - == (FCBlock *)(-1L)) - { - return 0; - } - - tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; - tmf->vc = RPT_ATTCH; - tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; - tmf->vl = 4; - - smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_ATTCH); - - tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); - smctr_make_corr(dev, tsv, correlator); - - tmf->vl += tsv->svl; - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_product_id(dev, tsv); - - tmf->vl += tsv->svl; - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_funct_addr(dev, tsv); - - tmf->vl += tsv->svl; - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_auth_funct_class(dev, tsv); - - tmf->vl += tsv->svl; - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_access_pri(dev, tsv); - - tmf->vl += tsv->svl; - - /* Subtract out MVID and MVL which is - * include in both vl and MAC_HEADER - */ -/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; - fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; -*/ - tmf->vl = SWAP_BYTES(tmf->vl); - - return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); -} - -static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf, - __u16 correlator) -{ - MAC_HEADER *tmf; - MAC_SUB_VECTOR *tsv; - FCBlock *fcb; - - if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) - + S_CORRELATOR + S_RING_STATION_VERSION_NUMBER - + S_RING_STATION_STATUS + S_STATION_IDENTIFER)) - == (FCBlock *)(-1L)) - { - return 0; - } - - tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; - tmf->vc = RPT_STATE; - tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; - tmf->vl = 4; - - smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_STATE); - - tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); - smctr_make_corr(dev, tsv, correlator); - - tmf->vl += tsv->svl; - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_ring_station_version(dev, tsv); - - tmf->vl += tsv->svl; - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_ring_station_status(dev, tsv); - - tmf->vl += tsv->svl; - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_station_id(dev, tsv); - - tmf->vl += tsv->svl; - - /* Subtract out MVID and MVL which is - * include in both vl and MAC_HEADER - */ -/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; - fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; -*/ - tmf->vl = SWAP_BYTES(tmf->vl); - - return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); -} - -static int smctr_send_rpt_tx_forward(struct net_device *dev, - MAC_HEADER *rmf, __u16 tx_fstatus) -{ - MAC_HEADER *tmf; - MAC_SUB_VECTOR *tsv; - FCBlock *fcb; - - if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) - + S_TRANSMIT_STATUS_CODE)) == (FCBlock *)(-1L)) - { - return 0; - } - - tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; - tmf->vc = RPT_TX_FORWARD; - tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; - tmf->vl = 4; - - smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_TX_FORWARD); - - tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); - smctr_make_tx_status_code(dev, tsv, tx_fstatus); - - tmf->vl += tsv->svl; - - /* Subtract out MVID and MVL which is - * include in both vl and MAC_HEADER - */ -/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; - fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; -*/ - tmf->vl = SWAP_BYTES(tmf->vl); - - return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); -} - -static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf, - __u16 rcode, __u16 correlator) -{ - MAC_HEADER *tmf; - MAC_SUB_VECTOR *tsv; - FCBlock *fcb; - - if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) - + S_CORRELATOR + S_RESPONSE_CODE)) == (FCBlock *)(-1L)) - { - return 0; - } - - tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; - tmf->vc = RSP; - tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; - tmf->vl = 4; - - smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RSP); - - tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); - smctr_make_corr(dev, tsv, correlator); - - return 0; -} - -static int smctr_send_rq_init(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - MAC_HEADER *tmf; - MAC_SUB_VECTOR *tsv; - FCBlock *fcb; - unsigned int i, count = 0; - __u16 fstatus; - int err; - - do { - if(((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) - + S_PRODUCT_INSTANCE_ID + S_UPSTREAM_NEIGHBOR_ADDRESS - + S_RING_STATION_VERSION_NUMBER + S_ADDRESS_MODIFER)) - == (FCBlock *)(-1L))) - { - return 0; - } - - tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; - tmf->vc = RQ_INIT; - tmf->dc_sc = DC_RPS | SC_RS; - tmf->vl = 4; - - smctr_make_8025_hdr(dev, NULL, tmf, AC_FC_RQ_INIT); - - tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); - smctr_make_product_id(dev, tsv); - - tmf->vl += tsv->svl; - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_upstream_neighbor_addr(dev, tsv); - - tmf->vl += tsv->svl; - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_ring_station_version(dev, tsv); - - tmf->vl += tsv->svl; - tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); - smctr_make_addr_mod(dev, tsv); - - tmf->vl += tsv->svl; - - /* Subtract out MVID and MVL which is - * include in both vl and MAC_HEADER - */ -/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; - fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; -*/ - tmf->vl = SWAP_BYTES(tmf->vl); - - if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) - return err; - - /* Wait for Transmit to Complete */ - for(i = 0; i < 10000; i++) - { - if(fcb->frame_status & FCB_COMMAND_DONE) - break; - mdelay(1); - } - - /* Check if GOOD frame Tx'ed */ - fstatus = fcb->frame_status; - - if(!(fstatus & FCB_COMMAND_DONE)) - return HARDWARE_FAILED; - - if(!(fstatus & FCB_TX_STATUS_E)) - count++; - - /* De-allocated Tx FCB and Frame Buffer - * The FCB must be de-allocated manually if executing with - * interrupts disabled, other wise the ISR (LM_Service_Events) - * will de-allocate it when the interrupt occurs. - */ - tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; - smctr_update_tx_chain(dev, fcb, MAC_QUEUE); - } while(count < 4 && ((fstatus & FCB_TX_AC_BITS) ^ FCB_TX_AC_BITS)); - - return smctr_join_complete_state(dev); -} - -static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, - __u16 *tx_fstatus) -{ - struct net_local *tp = netdev_priv(dev); - FCBlock *fcb; - unsigned int i; - int err; - - /* Check if this is the END POINT of the Transmit Forward Chain. */ - if(rmf->vl <= 18) - return 0; - - /* Allocate Transmit FCB only by requesting 0 bytes - * of data buffer. - */ - if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, 0)) == (FCBlock *)(-1L)) - return 0; - - /* Set pointer to Transmit Frame Buffer to the data - * portion of the received TX Forward frame, making - * sure to skip over the Vector Code (vc) and Vector - * length (vl). - */ - fcb->bdb_ptr->trc_data_block_ptr = TRC_POINTER((__u32)rmf - + sizeof(MAC_HEADER) + 2); - fcb->bdb_ptr->data_block_ptr = (__u16 *)((__u32)rmf - + sizeof(MAC_HEADER) + 2); - - fcb->frame_length = rmf->vl - 4 - 2; - fcb->bdb_ptr->buffer_length = rmf->vl - 4 - 2; - - if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) - return err; - - /* Wait for Transmit to Complete */ - for(i = 0; i < 10000; i++) - { - if(fcb->frame_status & FCB_COMMAND_DONE) - break; - mdelay(1); - } - - /* Check if GOOD frame Tx'ed */ - if(!(fcb->frame_status & FCB_COMMAND_DONE)) - { - if((err = smctr_issue_resume_tx_fcb_cmd(dev, MAC_QUEUE))) - return err; - - for(i = 0; i < 10000; i++) - { - if(fcb->frame_status & FCB_COMMAND_DONE) - break; - mdelay(1); - } - - if(!(fcb->frame_status & FCB_COMMAND_DONE)) - return HARDWARE_FAILED; - } - - *tx_fstatus = fcb->frame_status; - - return A_FRAME_WAS_FORWARDED; -} - -static int smctr_set_auth_access_pri(struct net_device *dev, - MAC_SUB_VECTOR *rsv) -{ - struct net_local *tp = netdev_priv(dev); - - if(rsv->svl != S_AUTHORIZED_ACCESS_PRIORITY) - return E_SUB_VECTOR_LENGTH_ERROR; - - tp->authorized_access_priority = (rsv->svv[0] << 8 | rsv->svv[1]); - - return POSITIVE_ACK; -} - -static int smctr_set_auth_funct_class(struct net_device *dev, - MAC_SUB_VECTOR *rsv) -{ - struct net_local *tp = netdev_priv(dev); - - if(rsv->svl != S_AUTHORIZED_FUNCTION_CLASS) - return E_SUB_VECTOR_LENGTH_ERROR; - - tp->authorized_function_classes = (rsv->svv[0] << 8 | rsv->svv[1]); - - return POSITIVE_ACK; -} - -static int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv, - __u16 *correlator) -{ - if(rsv->svl != S_CORRELATOR) - return E_SUB_VECTOR_LENGTH_ERROR; - - *correlator = (rsv->svv[0] << 8 | rsv->svv[1]); - - return POSITIVE_ACK; -} - -static int smctr_set_error_timer_value(struct net_device *dev, - MAC_SUB_VECTOR *rsv) -{ - __u16 err_tval; - int err; - - if(rsv->svl != S_ERROR_TIMER_VALUE) - return E_SUB_VECTOR_LENGTH_ERROR; - - err_tval = (rsv->svv[0] << 8 | rsv->svv[1])*10; - - smctr_issue_write_word_cmd(dev, RW_TER_THRESHOLD, &err_tval); - - if((err = smctr_wait_cmd(dev))) - return err; - - return POSITIVE_ACK; -} - -static int smctr_set_frame_forward(struct net_device *dev, - MAC_SUB_VECTOR *rsv, __u8 dc_sc) -{ - if((rsv->svl < 2) || (rsv->svl > S_FRAME_FORWARD)) - return E_SUB_VECTOR_LENGTH_ERROR; - - if((dc_sc & DC_MASK) != DC_CRS) - { - if(rsv->svl >= 2 && rsv->svl < 20) - return E_TRANSMIT_FORWARD_INVALID; - - if((rsv->svv[0] != 0) || (rsv->svv[1] != 0)) - return E_TRANSMIT_FORWARD_INVALID; - } - - return POSITIVE_ACK; -} - -static int smctr_set_local_ring_num(struct net_device *dev, - MAC_SUB_VECTOR *rsv) -{ - struct net_local *tp = netdev_priv(dev); - - if(rsv->svl != S_LOCAL_RING_NUMBER) - return E_SUB_VECTOR_LENGTH_ERROR; - - if(tp->ptr_local_ring_num) - *(__u16 *)(tp->ptr_local_ring_num) - = (rsv->svv[0] << 8 | rsv->svv[1]); - - return POSITIVE_ACK; -} - -static unsigned short smctr_set_ctrl_attention(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int ioaddr = dev->base_addr; - - if(tp->bic_type == BIC_585_CHIP) - outb((tp->trc_mask | HWR_CA), ioaddr + HWR); - else - { - outb((tp->trc_mask | CSR_CA), ioaddr + CSR); - outb(tp->trc_mask, ioaddr + CSR); - } - - return 0; -} - -static void smctr_set_multicast_list(struct net_device *dev) -{ - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_set_multicast_list\n", dev->name); -} - -static int smctr_set_page(struct net_device *dev, __u8 *buf) -{ - struct net_local *tp = netdev_priv(dev); - __u8 amask; - __u32 tptr; - - tptr = (__u32)buf - (__u32)tp->ram_access; - amask = (__u8)((tptr & PR_PAGE_MASK) >> 8); - outb(amask, dev->base_addr + PR); - - return 0; -} - -static int smctr_set_phy_drop(struct net_device *dev, MAC_SUB_VECTOR *rsv) -{ - int err; - - if(rsv->svl != S_PHYSICAL_DROP) - return E_SUB_VECTOR_LENGTH_ERROR; - - smctr_issue_write_byte_cmd(dev, RW_PHYSICAL_DROP_NUMBER, &rsv->svv[0]); - if((err = smctr_wait_cmd(dev))) - return err; - - return POSITIVE_ACK; -} - -/* Reset the ring speed to the opposite of what it was. This auto-pilot - * mode requires a complete reset and re-init of the adapter. - */ -static int smctr_set_ring_speed(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int err; - - if(tp->media_type == MEDIA_UTP_16) - tp->media_type = MEDIA_UTP_4; - else - tp->media_type = MEDIA_UTP_16; - - smctr_enable_16bit(dev); - - /* Re-Initialize adapter's internal registers */ - smctr_reset_adapter(dev); - - if((err = smctr_init_card_real(dev))) - return err; - - smctr_enable_bic_int(dev); - - if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK))) - return err; - - smctr_disable_16bit(dev); - - return 0; -} - -static int smctr_set_rx_look_ahead(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - __u16 sword, rword; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_set_rx_look_ahead_flag\n", dev->name); - - tp->adapter_flags &= ~(FORCED_16BIT_MODE); - tp->adapter_flags |= RX_VALID_LOOKAHEAD; - - if(tp->adapter_bus == BUS_ISA16_TYPE) - { - sword = *((__u16 *)(tp->ram_access)); - *((__u16 *)(tp->ram_access)) = 0x1234; - - smctr_disable_16bit(dev); - rword = *((__u16 *)(tp->ram_access)); - smctr_enable_16bit(dev); - - if(rword != 0x1234) - tp->adapter_flags |= FORCED_16BIT_MODE; - - *((__u16 *)(tp->ram_access)) = sword; - } - - return 0; -} - -static int smctr_set_trc_reset(int ioaddr) -{ - __u8 r; - - r = inb(ioaddr + MSR); - outb(MSR_RST | r, ioaddr + MSR); - - return 0; -} - -/* - * This function can be called if the adapter is busy or not. - */ -static int smctr_setup_single_cmd(struct net_device *dev, - __u16 command, __u16 subcommand) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int err; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_setup_single_cmd\n", dev->name); - - if((err = smctr_wait_while_cbusy(dev))) - return err; - - if((err = (unsigned int)smctr_wait_cmd(dev))) - return err; - - tp->acb_head->cmd_done_status = 0; - tp->acb_head->cmd = command; - tp->acb_head->subcmd = subcommand; - - err = smctr_issue_resume_acb_cmd(dev); - - return err; -} - -/* - * This function can not be called with the adapter busy. - */ -static int smctr_setup_single_cmd_w_data(struct net_device *dev, - __u16 command, __u16 subcommand) -{ - struct net_local *tp = netdev_priv(dev); - - tp->acb_head->cmd_done_status = ACB_COMMAND_NOT_DONE; - tp->acb_head->cmd = command; - tp->acb_head->subcmd = subcommand; - tp->acb_head->data_offset_lo - = (__u16)TRC_POINTER(tp->misc_command_data); - - return smctr_issue_resume_acb_cmd(dev); -} - -static char *smctr_malloc(struct net_device *dev, __u16 size) -{ - struct net_local *tp = netdev_priv(dev); - char *m; - - m = (char *)(tp->ram_access + tp->sh_mem_used); - tp->sh_mem_used += (__u32)size; - - return m; -} - -static int smctr_status_chg(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_status_chg\n", dev->name); - - switch(tp->status) - { - case OPEN: - break; - - case CLOSED: - break; - - /* Interrupt driven open() completion. XXX */ - case INITIALIZED: - tp->group_address_0 = 0; - tp->group_address[0] = 0; - tp->group_address[1] = 0; - tp->functional_address_0 = 0; - tp->functional_address[0] = 0; - tp->functional_address[1] = 0; - smctr_open_tr(dev); - break; - - default: - printk(KERN_INFO "%s: status change unknown %x\n", - dev->name, tp->status); - break; - } - - return 0; -} - -static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb, - __u16 queue) -{ - struct net_local *tp = netdev_priv(dev); - int err = 0; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_trc_send_packet\n", dev->name); - - fcb->info = FCB_CHAIN_END | FCB_ENABLE_TFS; - if(tp->num_tx_fcbs[queue] != 1) - fcb->back_ptr->info = FCB_INTERRUPT_ENABLE | FCB_ENABLE_TFS; - - if(tp->tx_queue_status[queue] == NOT_TRANSMITING) - { - tp->tx_queue_status[queue] = TRANSMITING; - err = smctr_issue_resume_tx_fcb_cmd(dev, queue); - } - - return err; -} - -static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue) -{ - struct net_local *tp = netdev_priv(dev); - __u16 status, err = 0; - int cstatus; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_tx_complete\n", dev->name); - - while((status = tp->tx_fcb_end[queue]->frame_status) != SUCCESS) - { - if(status & 0x7e00 ) - { - err = HARDWARE_FAILED; - break; - } - - if((err = smctr_update_tx_chain(dev, tp->tx_fcb_end[queue], - queue)) != SUCCESS) - break; - - smctr_disable_16bit(dev); - - if(tp->mode_bits & UMAC) - { - if(!(status & (FCB_TX_STATUS_AR1 | FCB_TX_STATUS_AR2))) - cstatus = NO_SUCH_DESTINATION; - else - { - if(!(status & (FCB_TX_STATUS_CR1 | FCB_TX_STATUS_CR2))) - cstatus = DEST_OUT_OF_RESOURCES; - else - { - if(status & FCB_TX_STATUS_E) - cstatus = MAX_COLLISIONS; - else - cstatus = SUCCESS; - } - } - } - else - cstatus = SUCCESS; - - if(queue == BUG_QUEUE) - err = SUCCESS; - - smctr_enable_16bit(dev); - if(err != SUCCESS) - break; - } - - return err; -} - -static unsigned short smctr_tx_move_frame(struct net_device *dev, - struct sk_buff *skb, __u8 *pbuff, unsigned int bytes) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int ram_usable; - __u32 flen, len, offset = 0; - __u8 *frag, *page; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_tx_move_frame\n", dev->name); - - ram_usable = ((unsigned int)tp->ram_usable) << 10; - frag = skb->data; - flen = skb->len; - - while(flen > 0 && bytes > 0) - { - smctr_set_page(dev, pbuff); - - offset = SMC_PAGE_OFFSET(pbuff); - - if(offset + flen > ram_usable) - len = ram_usable - offset; - else - len = flen; - - if(len > bytes) - len = bytes; - - page = (char *) (offset + tp->ram_access); - memcpy(page, frag, len); - - flen -=len; - bytes -= len; - frag += len; - pbuff += len; - } - - return 0; -} - -/* Update the error statistic counters for this adapter. */ -static int smctr_update_err_stats(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - struct tr_statistics *tstat = &tp->MacStat; - - if(tstat->internal_errors) - tstat->internal_errors - += *(tp->misc_command_data + 0) & 0x00ff; - - if(tstat->line_errors) - tstat->line_errors += *(tp->misc_command_data + 0) >> 8; - - if(tstat->A_C_errors) - tstat->A_C_errors += *(tp->misc_command_data + 1) & 0x00ff; - - if(tstat->burst_errors) - tstat->burst_errors += *(tp->misc_command_data + 1) >> 8; - - if(tstat->abort_delimiters) - tstat->abort_delimiters += *(tp->misc_command_data + 2) >> 8; - - if(tstat->recv_congest_count) - tstat->recv_congest_count - += *(tp->misc_command_data + 3) & 0x00ff; - - if(tstat->lost_frames) - tstat->lost_frames - += *(tp->misc_command_data + 3) >> 8; - - if(tstat->frequency_errors) - tstat->frequency_errors += *(tp->misc_command_data + 4) & 0x00ff; - - if(tstat->frame_copied_errors) - tstat->frame_copied_errors - += *(tp->misc_command_data + 4) >> 8; - - if(tstat->token_errors) - tstat->token_errors += *(tp->misc_command_data + 5) >> 8; - - return 0; -} - -static int smctr_update_rx_chain(struct net_device *dev, __u16 queue) -{ - struct net_local *tp = netdev_priv(dev); - FCBlock *fcb; - BDBlock *bdb; - __u16 size, len; - - fcb = tp->rx_fcb_curr[queue]; - len = fcb->frame_length; - - fcb->frame_status = 0; - fcb->info = FCB_CHAIN_END; - fcb->back_ptr->info = FCB_WARNING; - - tp->rx_fcb_curr[queue] = tp->rx_fcb_curr[queue]->next_ptr; - - /* update RX BDBs */ - size = (len >> RX_BDB_SIZE_SHIFT); - if(len & RX_DATA_BUFFER_SIZE_MASK) - size += sizeof(BDBlock); - size &= (~RX_BDB_SIZE_MASK); - - /* check if wrap around */ - bdb = (BDBlock *)((__u32)(tp->rx_bdb_curr[queue]) + (__u32)(size)); - if((__u32)bdb >= (__u32)tp->rx_bdb_end[queue]) - { - bdb = (BDBlock *)((__u32)(tp->rx_bdb_head[queue]) - + (__u32)(bdb) - (__u32)(tp->rx_bdb_end[queue])); - } - - bdb->back_ptr->info = BDB_CHAIN_END; - tp->rx_bdb_curr[queue]->back_ptr->info = BDB_NOT_CHAIN_END; - tp->rx_bdb_curr[queue] = bdb; - - return 0; -} - -static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, - __u16 queue) -{ - struct net_local *tp = netdev_priv(dev); - - if(smctr_debug > 20) - printk(KERN_DEBUG "smctr_update_tx_chain\n"); - - if(tp->num_tx_fcbs_used[queue] <= 0) - return HARDWARE_FAILED; - else - { - if(tp->tx_buff_used[queue] < fcb->memory_alloc) - { - tp->tx_buff_used[queue] = 0; - return HARDWARE_FAILED; - } - - tp->tx_buff_used[queue] -= fcb->memory_alloc; - - /* if all transmit buffer are cleared - * need to set the tx_buff_curr[] to tx_buff_head[] - * otherwise, tx buffer will be segregate and cannot - * accommodate and buffer greater than (curr - head) and - * (end - curr) since we do not allow wrap around allocation. - */ - if(tp->tx_buff_used[queue] == 0) - tp->tx_buff_curr[queue] = tp->tx_buff_head[queue]; - - tp->num_tx_fcbs_used[queue]--; - fcb->frame_status = 0; - tp->tx_fcb_end[queue] = fcb->next_ptr; - netif_wake_queue(dev); - return 0; - } -} - -static int smctr_wait_cmd(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int loop_count = 0x20000; - - if(smctr_debug > 10) - printk(KERN_DEBUG "%s: smctr_wait_cmd\n", dev->name); - - while(loop_count) - { - if(tp->acb_head->cmd_done_status & ACB_COMMAND_DONE) - break; - udelay(1); - loop_count--; - } - - if(loop_count == 0) - return HARDWARE_FAILED; - - if(tp->acb_head->cmd_done_status & 0xff) - return HARDWARE_FAILED; - - return 0; -} - -static int smctr_wait_while_cbusy(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int timeout = 0x20000; - int ioaddr = dev->base_addr; - __u8 r; - - if(tp->bic_type == BIC_585_CHIP) - { - while(timeout) - { - r = inb(ioaddr + HWR); - if((r & HWR_CBUSY) == 0) - break; - timeout--; - } - } - else - { - while(timeout) - { - r = inb(ioaddr + CSR); - if((r & CSR_CBUSY) == 0) - break; - timeout--; - } - } - - if(timeout) - return 0; - else - return HARDWARE_FAILED; -} - -#ifdef MODULE - -static struct net_device* dev_smctr[SMCTR_MAX_ADAPTERS]; -static int io[SMCTR_MAX_ADAPTERS]; -static int irq[SMCTR_MAX_ADAPTERS]; - -MODULE_LICENSE("GPL"); -MODULE_FIRMWARE("tr_smctr.bin"); - -module_param_array(io, int, NULL, 0); -module_param_array(irq, int, NULL, 0); -module_param(ringspeed, int, 0); - -static struct net_device * __init setup_card(int n) -{ - struct net_device *dev = alloc_trdev(sizeof(struct net_local)); - int err; - - if (!dev) - return ERR_PTR(-ENOMEM); - - dev->irq = irq[n]; - err = smctr_probe1(dev, io[n]); - if (err) - goto out; - - err = register_netdev(dev); - if (err) - goto out1; - return dev; - out1: -#ifdef CONFIG_MCA_LEGACY - { struct net_local *tp = netdev_priv(dev); - if (tp->slot_num) - mca_mark_as_unused(tp->slot_num); - } -#endif - release_region(dev->base_addr, SMCTR_IO_EXTENT); - free_irq(dev->irq, dev); -out: - free_netdev(dev); - return ERR_PTR(err); -} - -int __init init_module(void) -{ - int i, found = 0; - struct net_device *dev; - - for(i = 0; i < SMCTR_MAX_ADAPTERS; i++) { - dev = io[0]? setup_card(i) : smctr_probe(-1); - if (!IS_ERR(dev)) { - ++found; - dev_smctr[i] = dev; - } - } - - return found ? 0 : -ENODEV; -} - -void __exit cleanup_module(void) -{ - int i; - - for(i = 0; i < SMCTR_MAX_ADAPTERS; i++) { - struct net_device *dev = dev_smctr[i]; - - if (dev) { - - unregister_netdev(dev); -#ifdef CONFIG_MCA_LEGACY - { struct net_local *tp = netdev_priv(dev); - if (tp->slot_num) - mca_mark_as_unused(tp->slot_num); - } -#endif - release_region(dev->base_addr, SMCTR_IO_EXTENT); - if (dev->irq) - free_irq(dev->irq, dev); - - free_netdev(dev); - } - } -} -#endif /* MODULE */
diff --git a/drivers/net/tokenring/smctr.h b/drivers/net/tokenring/smctr.h deleted file mode 100644 index 6e5700a..0000000 --- a/drivers/net/tokenring/smctr.h +++ /dev/null
@@ -1,1585 +0,0 @@ -/* smctr.h: SMC Token Ring driver header for Linux - * - * Authors: - * - Jay Schulist <jschlst@samba.org> - */ - -#ifndef __LINUX_SMCTR_H -#define __LINUX_SMCTR_H - -#ifdef __KERNEL__ - -#define MAX_TX_QUEUE 10 - -#define SMC_HEADER_SIZE 14 - -#define SMC_PAGE_OFFSET(X) (((unsigned long)(X) - tp->ram_access) & tp->page_offset_mask) - -#define INIT 0x0D -#define RQ_ATTCH 0x10 -#define RQ_STATE 0x0F -#define RQ_ADDR 0x0E -#define CHG_PARM 0x0C -#define RSP 0x00 -#define TX_FORWARD 0x09 - -#define AC_FC_DAT ((3<<13) | 1) -#define DAT 0x07 - -#define RPT_NEW_MON 0x25 -#define RPT_SUA_CHG 0x26 -#define RPT_ACTIVE_ERR 0x28 -#define RPT_NN_INCMP 0x27 -#define RPT_ERROR 0x29 - -#define RQ_INIT 0x20 -#define RPT_ATTCH 0x24 -#define RPT_STATE 0x23 -#define RPT_ADDR 0x22 - -#define POSITIVE_ACK 0x0001 -#define A_FRAME_WAS_FORWARDED 0x8888 - -#define GROUP_ADDRESS 0x2B -#define PHYSICAL_DROP 0x0B -#define AUTHORIZED_ACCESS_PRIORITY 0x07 -#define AUTHORIZED_FUNCTION_CLASS 0x06 -#define FUNCTIONAL_ADDRESS 0x2C -#define RING_STATION_STATUS 0x29 -#define TRANSMIT_STATUS_CODE 0x2A -#define IBM_PASS_SOURCE_ADDR 0x01 -#define AC_FC_RPT_TX_FORWARD ((0<<13) | 0) -#define AC_FC_RPT_STATE ((0<<13) | 0) -#define AC_FC_RPT_ADDR ((0<<13) | 0) -#define CORRELATOR 0x09 - -#define POSITIVE_ACK 0x0001 /* */ -#define E_MAC_DATA_INCOMPLETE 0x8001 /* not used */ -#define E_VECTOR_LENGTH_ERROR 0x8002 /* */ -#define E_UNRECOGNIZED_VECTOR_ID 0x8003 /* */ -#define E_INAPPROPRIATE_SOURCE_CLASS 0x8004 /* */ -#define E_SUB_VECTOR_LENGTH_ERROR 0x8005 /* */ -#define E_TRANSMIT_FORWARD_INVALID 0x8006 /* def. by IBM */ -#define E_MISSING_SUB_VECTOR 0x8007 /* */ -#define E_SUB_VECTOR_UNKNOWN 0x8008 /* */ -#define E_MAC_HEADER_TOO_LONG 0x8009 /* */ -#define E_FUNCTION_DISABLED 0x800A /* not used */ - -#define A_FRAME_WAS_FORWARDED 0x8888 /* used by send_TX_FORWARD */ - -#define UPSTREAM_NEIGHBOR_ADDRESS 0x02 -#define LOCAL_RING_NUMBER 0x03 -#define ASSIGN_PHYSICAL_DROP 0x04 -#define ERROR_TIMER_VALUE 0x05 -#define AUTHORIZED_FUNCTION_CLASS 0x06 -#define AUTHORIZED_ACCESS_PRIORITY 0x07 -#define CORRELATOR 0x09 -#define PHYSICAL_DROP 0x0B -#define RESPONSE_CODE 0x20 -#define ADDRESS_MODIFER 0x21 -#define PRODUCT_INSTANCE_ID 0x22 -#define RING_STATION_VERSION_NUMBER 0x23 -#define WRAP_DATA 0x26 -#define FRAME_FORWARD 0x27 -#define STATION_IDENTIFER 0x28 -#define RING_STATION_STATUS 0x29 -#define TRANSMIT_STATUS_CODE 0x2A -#define GROUP_ADDRESS 0x2B -#define FUNCTIONAL_ADDRESS 0x2C - -#define F_NO_SUB_VECTORS_FOUND 0x0000 -#define F_UPSTREAM_NEIGHBOR_ADDRESS 0x0001 -#define F_LOCAL_RING_NUMBER 0x0002 -#define F_ASSIGN_PHYSICAL_DROP 0x0004 -#define F_ERROR_TIMER_VALUE 0x0008 -#define F_AUTHORIZED_FUNCTION_CLASS 0x0010 -#define F_AUTHORIZED_ACCESS_PRIORITY 0x0020 -#define F_CORRELATOR 0x0040 -#define F_PHYSICAL_DROP 0x0080 -#define F_RESPONSE_CODE 0x0100 -#define F_PRODUCT_INSTANCE_ID 0x0200 -#define F_RING_STATION_VERSION_NUMBER 0x0400 -#define F_STATION_IDENTIFER 0x0800 -#define F_RING_STATION_STATUS 0x1000 -#define F_GROUP_ADDRESS 0x2000 -#define F_FUNCTIONAL_ADDRESS 0x4000 -#define F_FRAME_FORWARD 0x8000 - -#define R_INIT 0x00 -#define R_RQ_ATTCH_STATE_ADDR 0x00 -#define R_CHG_PARM 0x00 -#define R_TX_FORWARD F_FRAME_FORWARD - - -#define UPSTREAM_NEIGHBOR_ADDRESS 0x02 -#define ADDRESS_MODIFER 0x21 -#define RING_STATION_VERSION_NUMBER 0x23 -#define PRODUCT_INSTANCE_ID 0x22 - -#define RPT_TX_FORWARD 0x2A - -#define AC_FC_INIT (3<<13) | 0 /* */ -#define AC_FC_RQ_INIT ((3<<13) | 0) /* */ -#define AC_FC_RQ_ATTCH (3<<13) | 0 /* DC = SC of rx frame */ -#define AC_FC_RQ_STATE (3<<13) | 0 /* DC = SC of rx frame */ -#define AC_FC_RQ_ADDR (3<<13) | 0 /* DC = SC of rx frame */ -#define AC_FC_CHG_PARM (3<<13) | 0 /* */ -#define AC_FC_RSP (0<<13) | 0 /* DC = SC of rx frame */ -#define AC_FC_RPT_ATTCH (0<<13) | 0 - -#define S_UPSTREAM_NEIGHBOR_ADDRESS 6 + 2 -#define S_LOCAL_RING_NUMBER 2 + 2 -#define S_ASSIGN_PHYSICAL_DROP 4 + 2 -#define S_ERROR_TIMER_VALUE 2 + 2 -#define S_AUTHORIZED_FUNCTION_CLASS 2 + 2 -#define S_AUTHORIZED_ACCESS_PRIORITY 2 + 2 -#define S_CORRELATOR 2 + 2 -#define S_PHYSICAL_DROP 4 + 2 -#define S_RESPONSE_CODE 4 + 2 -#define S_ADDRESS_MODIFER 2 + 2 -#define S_PRODUCT_INSTANCE_ID 18 + 2 -#define S_RING_STATION_VERSION_NUMBER 10 + 2 -#define S_STATION_IDENTIFER 6 + 2 -#define S_RING_STATION_STATUS 6 + 2 -#define S_GROUP_ADDRESS 4 + 2 -#define S_FUNCTIONAL_ADDRESS 4 + 2 -#define S_FRAME_FORWARD 252 + 2 -#define S_TRANSMIT_STATUS_CODE 2 + 2 - -#define ISB_IMC_RES0 0x0000 /* */ -#define ISB_IMC_MAC_TYPE_3 0x0001 /* MAC_ARC_INDICATE */ -#define ISB_IMC_MAC_ERROR_COUNTERS 0x0002 /* */ -#define ISB_IMC_RES1 0x0003 /* */ -#define ISB_IMC_MAC_TYPE_2 0x0004 /* QUE_MAC_INDICATE */ -#define ISB_IMC_TX_FRAME 0x0005 /* */ -#define ISB_IMC_END_OF_TX_QUEUE 0x0006 /* */ -#define ISB_IMC_NON_MAC_RX_RESOURCE 0x0007 /* */ -#define ISB_IMC_MAC_RX_RESOURCE 0x0008 /* */ -#define ISB_IMC_NON_MAC_RX_FRAME 0x0009 /* */ -#define ISB_IMC_MAC_RX_FRAME 0x000A /* */ -#define ISB_IMC_TRC_FIFO_STATUS 0x000B /* */ -#define ISB_IMC_COMMAND_STATUS 0x000C /* */ -#define ISB_IMC_MAC_TYPE_1 0x000D /* Self Removed */ -#define ISB_IMC_TRC_INTRNL_TST_STATUS 0x000E /* */ -#define ISB_IMC_RES2 0x000F /* */ - -#define NON_MAC_RX_RESOURCE_BW 0x10 /* shifted right 8 bits */ -#define NON_MAC_RX_RESOURCE_FW 0x20 /* shifted right 8 bits */ -#define NON_MAC_RX_RESOURCE_BE 0x40 /* shifted right 8 bits */ -#define NON_MAC_RX_RESOURCE_FE 0x80 /* shifted right 8 bits */ -#define RAW_NON_MAC_RX_RESOURCE_BW 0x1000 /* */ -#define RAW_NON_MAC_RX_RESOURCE_FW 0x2000 /* */ -#define RAW_NON_MAC_RX_RESOURCE_BE 0x4000 /* */ -#define RAW_NON_MAC_RX_RESOURCE_FE 0x8000 /* */ - -#define MAC_RX_RESOURCE_BW 0x10 /* shifted right 8 bits */ -#define MAC_RX_RESOURCE_FW 0x20 /* shifted right 8 bits */ -#define MAC_RX_RESOURCE_BE 0x40 /* shifted right 8 bits */ -#define MAC_RX_RESOURCE_FE 0x80 /* shifted right 8 bits */ -#define RAW_MAC_RX_RESOURCE_BW 0x1000 /* */ -#define RAW_MAC_RX_RESOURCE_FW 0x2000 /* */ -#define RAW_MAC_RX_RESOURCE_BE 0x4000 /* */ -#define RAW_MAC_RX_RESOURCE_FE 0x8000 /* */ - -#define TRC_FIFO_STATUS_TX_UNDERRUN 0x40 /* shifted right 8 bits */ -#define TRC_FIFO_STATUS_RX_OVERRUN 0x80 /* shifted right 8 bits */ -#define RAW_TRC_FIFO_STATUS_TX_UNDERRUN 0x4000 /* */ -#define RAW_TRC_FIFO_STATUS_RX_OVERRUN 0x8000 /* */ - -#define CSR_CLRTINT 0x08 - -#define MSB(X) ((__u8)((__u16) X >> 8)) -#define LSB(X) ((__u8)((__u16) X & 0xff)) - -#define AC_FC_LOBE_MEDIA_TEST ((3<<13) | 0) -#define S_WRAP_DATA 248 + 2 /* 500 + 2 */ -#define WRAP_DATA 0x26 -#define LOBE_MEDIA_TEST 0x08 - -/* Destination Class (dc) */ - -#define DC_MASK 0xF0 -#define DC_RS 0x00 -#define DC_CRS 0x40 -#define DC_RPS 0x50 -#define DC_REM 0x60 - -/* Source Classes (sc) */ - -#define SC_MASK 0x0F -#define SC_RS 0x00 -#define SC_CRS 0x04 -#define SC_RPS 0x05 -#define SC_REM 0x06 - -#define PR 0x11 -#define PR_PAGE_MASK 0x0C000 - -#define MICROCHANNEL 0x0008 -#define INTERFACE_CHIP 0x0010 -#define BOARD_16BIT 0x0040 -#define PAGED_RAM 0x0080 -#define WD8115TA (TOKEN_MEDIA | MICROCHANNEL | INTERFACE_CHIP | PAGED_RAM) -#define WD8115T (TOKEN_MEDIA | INTERFACE_CHIP | BOARD_16BIT | PAGED_RAM) - -#define BRD_ID_8316 0x50 - -#define r587_SER 0x001 -#define SER_DIN 0x80 -#define SER_DOUT 0x40 -#define SER_CLK 0x20 -#define SER_ECS 0x10 -#define SER_E806 0x08 -#define SER_PNP 0x04 -#define SER_BIO 0x02 -#define SER_16B 0x01 - -#define r587_IDR 0x004 -#define IDR_IRQ_MASK 0x0F0 -#define IDR_DCS_MASK 0x007 -#define IDR_RWS 0x008 - - -#define r587_BIO 0x003 -#define BIO_ENB 0x080 -#define BIO_MASK 0x03F - -#define r587_PCR 0x005 -#define PCR_RAMS 0x040 - - - -#define NUM_ADDR_BITS 8 - -#define ISA_MAX_ADDRESS 0x00ffffff - -#define SMCTR_MAX_ADAPTERS 7 - -#define MC_TABLE_ENTRIES 16 - -#define MAXFRAGMENTS 32 - -#define CHIP_REV_MASK 0x3000 - -#define MAX_TX_QS 8 -#define NUM_TX_QS_USED 3 - -#define MAX_RX_QS 2 -#define NUM_RX_QS_USED 2 - -#define INTEL_DATA_FORMAT 0x4000 -#define INTEL_ADDRESS_POINTER_FORMAT 0x8000 -#define PAGE_POINTER(X) ((((unsigned long)(X) - tp->ram_access) & tp->page_offset_mask) + tp->ram_access) -#define SWAP_WORDS(X) (((X & 0xFFFF) << 16) | (X >> 16)) - -#define INTERFACE_CHIP 0x0010 /* Soft Config Adapter */ -#define ADVANCED_FEATURES 0x0020 /* Adv. netw. interface features */ -#define BOARD_16BIT 0x0040 /* 16 bit capability */ -#define PAGED_RAM 0x0080 /* Adapter has paged RAM */ - -#define PAGED_ROM 0x0100 /* Adapter has paged ROM */ - -#define RAM_SIZE_UNKNOWN 0x0000 /* Unknown RAM size */ -#define RAM_SIZE_0K 0x0001 /* 0K RAM */ -#define RAM_SIZE_8K 0x0002 /* 8k RAM */ -#define RAM_SIZE_16K 0x0003 /* 16k RAM */ -#define RAM_SIZE_32K 0x0004 /* 32k RAM */ -#define RAM_SIZE_64K 0x0005 /* 64k RAM */ -#define RAM_SIZE_RESERVED_6 0x0006 /* Reserved RAM size */ -#define RAM_SIZE_RESERVED_7 0x0007 /* Reserved RAM size */ -#define RAM_SIZE_MASK 0x0007 /* Isolates RAM Size */ - -#define TOKEN_MEDIA 0x0005 - -#define BID_REG_0 0x00 -#define BID_REG_1 0x01 -#define BID_REG_2 0x02 -#define BID_REG_3 0x03 -#define BID_REG_4 0x04 -#define BID_REG_5 0x05 -#define BID_REG_6 0x06 -#define BID_REG_7 0x07 -#define BID_LAR_0 0x08 -#define BID_LAR_1 0x09 -#define BID_LAR_2 0x0A -#define BID_LAR_3 0x0B -#define BID_LAR_4 0x0C -#define BID_LAR_5 0x0D - -#define BID_BOARD_ID_BYTE 0x0E -#define BID_CHCKSM_BYTE 0x0F -#define BID_LAR_OFFSET 0x08 - -#define BID_MSZ_583_BIT 0x08 -#define BID_SIXTEEN_BIT_BIT 0x01 - -#define BID_BOARD_REV_MASK 0x1E - -#define BID_MEDIA_TYPE_BIT 0x01 -#define BID_SOFT_CONFIG_BIT 0x20 -#define BID_RAM_SIZE_BIT 0x40 -#define BID_BUS_TYPE_BIT 0x80 - -#define BID_CR 0x10 - -#define BID_TXP 0x04 /* Transmit Packet Command */ - -#define BID_TCR_DIFF 0x0D /* Transmit Configuration Register */ - -#define BID_TCR_VAL 0x18 /* Value to Test 8390 or 690 */ -#define BID_PS0 0x00 /* Register Page Select 0 */ -#define BID_PS1 0x40 /* Register Page Select 1 */ -#define BID_PS2 0x80 /* Register Page Select 2 */ -#define BID_PS_MASK 0x3F /* For Masking Off Page Select Bits */ - -#define BID_EEPROM_0 0x08 -#define BID_EEPROM_1 0x09 -#define BID_EEPROM_2 0x0A -#define BID_EEPROM_3 0x0B -#define BID_EEPROM_4 0x0C -#define BID_EEPROM_5 0x0D -#define BID_EEPROM_6 0x0E -#define BID_EEPROM_7 0x0F - -#define BID_OTHER_BIT 0x02 -#define BID_ICR_MASK 0x0C -#define BID_EAR_MASK 0x0F -#define BID_ENGR_PAGE 0x0A0 -#define BID_RLA 0x10 -#define BID_EA6 0x80 -#define BID_RECALL_DONE_MASK 0x10 -#define BID_BID_EEPROM_OVERRIDE 0xFFB0 -#define BID_EXTRA_EEPROM_OVERRIDE 0xFFD0 -#define BID_EEPROM_MEDIA_MASK 0x07 -#define BID_STARLAN_TYPE 0x00 -#define BID_ETHERNET_TYPE 0x01 -#define BID_TP_TYPE 0x02 -#define BID_EW_TYPE 0x03 -#define BID_TOKEN_RING_TYPE 0x04 -#define BID_UTP2_TYPE 0x05 -#define BID_EEPROM_IRQ_MASK 0x18 -#define BID_PRIMARY_IRQ 0x00 -#define BID_ALTERNATE_IRQ_1 0x08 -#define BID_ALTERNATE_IRQ_2 0x10 -#define BID_ALTERNATE_IRQ_3 0x18 -#define BID_EEPROM_RAM_SIZE_MASK 0xE0 -#define BID_EEPROM_RAM_SIZE_RES1 0x00 -#define BID_EEPROM_RAM_SIZE_RES2 0x20 -#define BID_EEPROM_RAM_SIZE_8K 0x40 -#define BID_EEPROM_RAM_SIZE_16K 0x60 -#define BID_EEPROM_RAM_SIZE_32K 0x80 -#define BID_EEPROM_RAM_SIZE_64K 0xA0 -#define BID_EEPROM_RAM_SIZE_RES3 0xC0 -#define BID_EEPROM_RAM_SIZE_RES4 0xE0 -#define BID_EEPROM_BUS_TYPE_MASK 0x07 -#define BID_EEPROM_BUS_TYPE_AT 0x00 -#define BID_EEPROM_BUS_TYPE_MCA 0x01 -#define BID_EEPROM_BUS_TYPE_EISA 0x02 -#define BID_EEPROM_BUS_TYPE_NEC 0x03 -#define BID_EEPROM_BUS_SIZE_MASK 0x18 -#define BID_EEPROM_BUS_SIZE_8BIT 0x00 -#define BID_EEPROM_BUS_SIZE_16BIT 0x08 -#define BID_EEPROM_BUS_SIZE_32BIT 0x10 -#define BID_EEPROM_BUS_SIZE_64BIT 0x18 -#define BID_EEPROM_BUS_MASTER 0x20 -#define BID_EEPROM_RAM_PAGING 0x40 -#define BID_EEPROM_ROM_PAGING 0x80 -#define BID_EEPROM_PAGING_MASK 0xC0 -#define BID_EEPROM_LOW_COST 0x08 -#define BID_EEPROM_IO_MAPPED 0x10 -#define BID_EEPROM_HMI 0x01 -#define BID_EEPROM_AUTO_MEDIA_DETECT 0x01 -#define BID_EEPROM_CHIP_REV_MASK 0x0C - -#define BID_EEPROM_LAN_ADDR 0x30 - -#define BID_EEPROM_MEDIA_OPTION 0x54 -#define BID_EEPROM_MEDIA_UTP 0x01 -#define BID_EEPROM_4MB_RING 0x08 -#define BID_EEPROM_16MB_RING 0x10 -#define BID_EEPROM_MEDIA_STP 0x40 - -#define BID_EEPROM_MISC_DATA 0x56 -#define BID_EEPROM_EARLY_TOKEN_RELEASE 0x02 - -#define CNFG_ID_8003E 0x6fc0 -#define CNFG_ID_8003S 0x6fc1 -#define CNFG_ID_8003W 0x6fc2 -#define CNFG_ID_8115TRA 0x6ec6 -#define CNFG_ID_8013E 0x61C8 -#define CNFG_ID_8013W 0x61C9 -#define CNFG_ID_BISTRO03E 0xEFE5 -#define CNFG_ID_BISTRO13E 0xEFD5 -#define CNFG_ID_BISTRO13W 0xEFD4 -#define CNFG_MSR_583 0x0 -#define CNFG_ICR_583 0x1 -#define CNFG_IAR_583 0x2 -#define CNFG_BIO_583 0x3 -#define CNFG_EAR_583 0x3 -#define CNFG_IRR_583 0x4 -#define CNFG_LAAR_584 0x5 -#define CNFG_GP2 0x7 -#define CNFG_LAAR_MASK 0x1F -#define CNFG_LAAR_ZWS 0x20 -#define CNFG_LAAR_L16E 0x40 -#define CNFG_ICR_IR2_584 0x04 -#define CNFG_ICR_MASK 0x08 -#define CNFG_ICR_MSZ 0x08 -#define CNFG_ICR_RLA 0x10 -#define CNFG_ICR_STO 0x80 -#define CNFG_IRR_IRQS 0x60 -#define CNFG_IRR_IEN 0x80 -#define CNFG_IRR_ZWS 0x01 -#define CNFG_GP2_BOOT_NIBBLE 0x0F -#define CNFG_IRR_OUT2 0x04 -#define CNFG_IRR_OUT1 0x02 - -#define CNFG_SIZE_8KB 8 -#define CNFG_SIZE_16KB 16 -#define CNFG_SIZE_32KB 32 -#define CNFG_SIZE_64KB 64 -#define CNFG_SIZE_128KB 128 -#define CNFG_SIZE_256KB 256 -#define ROM_DISABLE 0x0 - -#define CNFG_SLOT_ENABLE_BIT 0x08 - -#define CNFG_POS_CONTROL_REG 0x096 -#define CNFG_POS_REG0 0x100 -#define CNFG_POS_REG1 0x101 -#define CNFG_POS_REG2 0x102 -#define CNFG_POS_REG3 0x103 -#define CNFG_POS_REG4 0x104 -#define CNFG_POS_REG5 0x105 - -#define CNFG_ADAPTER_TYPE_MASK 0x0e - -#define SLOT_16BIT 0x0008 -#define INTERFACE_5X3_CHIP 0x0000 /* 0000 = 583 or 593 chips */ -#define NIC_690_BIT 0x0010 /* NIC is 690 */ -#define ALTERNATE_IRQ_BIT 0x0020 /* Alternate IRQ is used */ -#define INTERFACE_584_CHIP 0x0040 /* 0001 = 584 chip */ -#define INTERFACE_594_CHIP 0x0080 /* 0010 = 594 chip */ -#define INTERFACE_585_CHIP 0x0100 /* 0100 = 585/790 chip */ -#define INTERFACE_CHIP_MASK 0x03C0 /* Isolates Intfc Chip Type */ - -#define BOARD_16BIT 0x0040 -#define NODE_ADDR_CKSUM 0xEE -#define BRD_ID_8115T 0x04 - -#define NIC_825_BIT 0x0400 /* TRC 83C825 NIC */ -#define NIC_790_BIT 0x0800 /* NIC is 83C790 Ethernet */ - -#define CHIP_REV_MASK 0x3000 - -#define HWR_CBUSY 0x02 -#define HWR_CA 0x01 - -#define MAC_QUEUE 0 -#define NON_MAC_QUEUE 1 -#define BUG_QUEUE 2 /* NO RECEIVE QUEUE, ONLY TX */ - -#define NUM_MAC_TX_FCBS 8 -#define NUM_MAC_TX_BDBS NUM_MAC_TX_FCBS -#define NUM_MAC_RX_FCBS 7 -#define NUM_MAC_RX_BDBS 8 - -#define NUM_NON_MAC_TX_FCBS 6 -#define NUM_NON_MAC_TX_BDBS NUM_NON_MAC_TX_FCBS - -#define NUM_NON_MAC_RX_BDBS 0 /* CALCULATED DYNAMICALLY */ - -#define NUM_BUG_TX_FCBS 8 -#define NUM_BUG_TX_BDBS NUM_BUG_TX_FCBS - -#define MAC_TX_BUFFER_MEMORY 1024 -#define NON_MAC_TX_BUFFER_MEMORY (20 * 1024) -#define BUG_TX_BUFFER_MEMORY (NUM_BUG_TX_FCBS * 32) - -#define RX_BUFFER_MEMORY 0 /* CALCULATED DYNAMICALLY */ -#define RX_DATA_BUFFER_SIZE 256 -#define RX_BDB_SIZE_SHIFT 3 /* log2(RX_DATA_BUFFER_SIZE)-log2(sizeof(BDBlock)) */ -#define RX_BDB_SIZE_MASK (sizeof(BDBlock) - 1) -#define RX_DATA_BUFFER_SIZE_MASK (RX_DATA_BUFFER_SIZE-1) - -#define NUM_OF_INTERRUPTS 0x20 - -#define NOT_TRANSMITING 0 -#define TRANSMITING 1 - -#define TRC_INTERRUPT_ENABLE_MASK 0x7FF6 - -#define UCODE_VERSION 0x58 - -#define UCODE_SIZE_OFFSET 0x0000 /* WORD */ -#define UCODE_CHECKSUM_OFFSET 0x0002 /* WORD */ -#define UCODE_VERSION_OFFSET 0x0004 /* BYTE */ - -#define CS_RAM_SIZE 0X2000 -#define CS_RAM_CHECKSUM_OFFSET 0x1FFE /* WORD 1FFE(MSB)-1FFF(LSB)*/ -#define CS_RAM_VERSION_OFFSET 0x1FFC /* WORD 1FFC(MSB)-1FFD(LSB)*/ - -#define MISC_DATA_SIZE 128 -#define NUM_OF_ACBS 1 - -#define ACB_COMMAND_NOT_DONE 0x0000 /* Init, command not done */ -#define ACB_COMMAND_DONE 0x8000 /* TRC says command done */ -#define ACB_COMMAND_STATUS_MASK 0x00FF /* low byte is status */ -#define ACB_COMMAND_SUCCESSFUL 0x0000 /* means cmd was successful */ -#define ACB_NOT_CHAIN_END 0x0000 /* tell TRC more CBs in chain */ -#define ACB_CHAIN_END 0x8000 /* tell TRC last CB in chain */ -#define ACB_COMMAND_NO_INTERRUPT 0x0000 /* tell TRC no INT after CB */ -#define ACB_COMMAND_INTERRUPT 0x2000 /* tell TRC to INT after CB */ -#define ACB_SUB_CMD_NOP 0x0000 -#define ACB_CMD_HIC_NOP 0x0080 -#define ACB_CMD_MCT_NOP 0x0000 -#define ACB_CMD_MCT_TEST 0x0001 -#define ACB_CMD_HIC_TEST 0x0081 -#define ACB_CMD_INSERT 0x0002 -#define ACB_CMD_REMOVE 0x0003 -#define ACB_CMD_MCT_WRITE_VALUE 0x0004 -#define ACB_CMD_HIC_WRITE_VALUE 0x0084 -#define ACB_CMD_MCT_READ_VALUE 0x0005 -#define ACB_CMD_HIC_READ_VALUE 0x0085 -#define ACB_CMD_INIT_TX_RX 0x0086 -#define ACB_CMD_INIT_TRC_TIMERS 0x0006 -#define ACB_CMD_READ_TRC_STATUS 0x0007 -#define ACB_CMD_CHANGE_JOIN_STATE 0x0008 -#define ACB_CMD_RESERVED_9 0x0009 -#define ACB_CMD_RESERVED_A 0x000A -#define ACB_CMD_RESERVED_B 0x000B -#define ACB_CMD_RESERVED_C 0x000C -#define ACB_CMD_RESERVED_D 0x000D -#define ACB_CMD_RESERVED_E 0x000E -#define ACB_CMD_RESERVED_F 0x000F - -#define TRC_MAC_REGISTERS_TEST 0x0000 -#define TRC_INTERNAL_LOOPBACK 0x0001 -#define TRC_TRI_LOOPBACK 0x0002 -#define TRC_INTERNAL_ROM_TEST 0x0003 -#define TRC_LOBE_MEDIA_TEST 0x0004 -#define TRC_ANALOG_TEST 0x0005 -#define TRC_HOST_INTERFACE_REG_TEST 0x0003 - -#define TEST_DMA_1 0x0000 -#define TEST_DMA_2 0x0001 -#define TEST_MCT_ROM 0x0002 -#define HIC_INTERNAL_DIAG 0x0003 - -#define ABORT_TRANSMIT_PRIORITY_0 0x0001 -#define ABORT_TRANSMIT_PRIORITY_1 0x0002 -#define ABORT_TRANSMIT_PRIORITY_2 0x0004 -#define ABORT_TRANSMIT_PRIORITY_3 0x0008 -#define ABORT_TRANSMIT_PRIORITY_4 0x0010 -#define ABORT_TRANSMIT_PRIORITY_5 0x0020 -#define ABORT_TRANSMIT_PRIORITY_6 0x0040 -#define ABORT_TRANSMIT_PRIORITY_7 0x0080 - -#define TX_PENDING_PRIORITY_0 0x0001 -#define TX_PENDING_PRIORITY_1 0x0002 -#define TX_PENDING_PRIORITY_2 0x0004 -#define TX_PENDING_PRIORITY_3 0x0008 -#define TX_PENDING_PRIORITY_4 0x0010 -#define TX_PENDING_PRIORITY_5 0x0020 -#define TX_PENDING_PRIORITY_6 0x0040 -#define TX_PENDING_PRIORITY_7 0x0080 - -#define FCB_FRAME_LENGTH 0x100 -#define FCB_COMMAND_DONE 0x8000 /* FCB Word 0 */ -#define FCB_NOT_CHAIN_END 0x0000 /* FCB Word 1 */ -#define FCB_CHAIN_END 0x8000 -#define FCB_NO_WARNING 0x0000 -#define FCB_WARNING 0x4000 -#define FCB_INTERRUPT_DISABLE 0x0000 -#define FCB_INTERRUPT_ENABLE 0x2000 - -#define FCB_ENABLE_IMA 0x0008 -#define FCB_ENABLE_TES 0x0004 /* Guarantee Tx before Int */ -#define FCB_ENABLE_TFS 0x0002 /* Post Tx Frame Status */ -#define FCB_ENABLE_NTC 0x0001 /* No Tx CRC */ - -#define FCB_TX_STATUS_CR2 0x0004 -#define FCB_TX_STATUS_AR2 0x0008 -#define FCB_TX_STATUS_CR1 0x0040 -#define FCB_TX_STATUS_AR1 0x0080 -#define FCB_TX_AC_BITS (FCB_TX_STATUS_AR1+FCB_TX_STATUS_AR2+FCB_TX_STATUS_CR1+FCB_TX_STATUS_CR2) -#define FCB_TX_STATUS_E 0x0100 - -#define FCB_RX_STATUS_ANY_ERROR 0x0001 -#define FCB_RX_STATUS_FCS_ERROR 0x0002 - -#define FCB_RX_STATUS_IA_MATCHED 0x0400 -#define FCB_RX_STATUS_IGA_BSGA_MATCHED 0x0500 -#define FCB_RX_STATUS_FA_MATCHED 0x0600 -#define FCB_RX_STATUS_BA_MATCHED 0x0700 -#define FCB_RX_STATUS_DA_MATCHED 0x0400 -#define FCB_RX_STATUS_SOURCE_ROUTING 0x0800 - -#define BDB_BUFFER_SIZE 0x100 -#define BDB_NOT_CHAIN_END 0x0000 -#define BDB_CHAIN_END 0x8000 -#define BDB_NO_WARNING 0x0000 -#define BDB_WARNING 0x4000 - -#define ERROR_COUNTERS_CHANGED 0x0001 -#define TI_NDIS_RING_STATUS_CHANGED 0x0002 -#define UNA_CHANGED 0x0004 -#define READY_TO_SEND_RQ_INIT 0x0008 - -#define SCGB_ADDRESS_POINTER_FORMAT INTEL_ADDRESS_POINTER_FORMAT -#define SCGB_DATA_FORMAT INTEL_DATA_FORMAT -#define SCGB_MULTI_WORD_CONTROL 0 -#define SCGB_BURST_LENGTH 0x000E /* DMA Burst Length */ - -#define SCGB_CONFIG (INTEL_ADDRESS_POINTER_FORMAT+INTEL_DATA_FORMAT+SCGB_BURST_LENGTH) - -#define ISCP_BLOCK_SIZE 0x0A -#define RAM_SIZE 0x10000 -#define INIT_SYS_CONFIG_PTR_OFFSET (RAM_SIZE-ISCP_BLOCK_SIZE) -#define SCGP_BLOCK_OFFSET 0 - -#define SCLB_NOT_VALID 0x0000 /* Initially, SCLB not valid */ -#define SCLB_VALID 0x8000 /* Host tells TRC SCLB valid */ -#define SCLB_PROCESSED 0x0000 /* TRC says SCLB processed */ -#define SCLB_RESUME_CONTROL_NOT_VALID 0x0000 /* Initially, RC not valid */ -#define SCLB_RESUME_CONTROL_VALID 0x4000 /* Host tells TRC RC valid */ -#define SCLB_IACK_CODE_NOT_VALID 0x0000 /* Initially, IACK not valid */ -#define SCLB_IACK_CODE_VALID 0x2000 /* Host tells TRC IACK valid */ -#define SCLB_CMD_NOP 0x0000 -#define SCLB_CMD_REMOVE 0x0001 -#define SCLB_CMD_SUSPEND_ACB_CHAIN 0x0002 -#define SCLB_CMD_SET_INTERRUPT_MASK 0x0003 -#define SCLB_CMD_CLEAR_INTERRUPT_MASK 0x0004 -#define SCLB_CMD_RESERVED_5 0x0005 -#define SCLB_CMD_RESERVED_6 0x0006 -#define SCLB_CMD_RESERVED_7 0x0007 -#define SCLB_CMD_RESERVED_8 0x0008 -#define SCLB_CMD_RESERVED_9 0x0009 -#define SCLB_CMD_RESERVED_A 0x000A -#define SCLB_CMD_RESERVED_B 0x000B -#define SCLB_CMD_RESERVED_C 0x000C -#define SCLB_CMD_RESERVED_D 0x000D -#define SCLB_CMD_RESERVED_E 0x000E -#define SCLB_CMD_RESERVED_F 0x000F - -#define SCLB_RC_ACB 0x0001 /* Action Command Block Chain */ -#define SCLB_RC_RES0 0x0002 /* Always Zero */ -#define SCLB_RC_RES1 0x0004 /* Always Zero */ -#define SCLB_RC_RES2 0x0008 /* Always Zero */ -#define SCLB_RC_RX_MAC_FCB 0x0010 /* RX_MAC_FCB Chain */ -#define SCLB_RC_RX_MAC_BDB 0x0020 /* RX_MAC_BDB Chain */ -#define SCLB_RC_RX_NON_MAC_FCB 0x0040 /* RX_NON_MAC_FCB Chain */ -#define SCLB_RC_RX_NON_MAC_BDB 0x0080 /* RX_NON_MAC_BDB Chain */ -#define SCLB_RC_TFCB0 0x0100 /* TX Priority 0 FCB Chain */ -#define SCLB_RC_TFCB1 0x0200 /* TX Priority 1 FCB Chain */ -#define SCLB_RC_TFCB2 0x0400 /* TX Priority 2 FCB Chain */ -#define SCLB_RC_TFCB3 0x0800 /* TX Priority 3 FCB Chain */ -#define SCLB_RC_TFCB4 0x1000 /* TX Priority 4 FCB Chain */ -#define SCLB_RC_TFCB5 0x2000 /* TX Priority 5 FCB Chain */ -#define SCLB_RC_TFCB6 0x4000 /* TX Priority 6 FCB Chain */ -#define SCLB_RC_TFCB7 0x8000 /* TX Priority 7 FCB Chain */ - -#define SCLB_IMC_RES0 0x0001 /* */ -#define SCLB_IMC_MAC_TYPE_3 0x0002 /* MAC_ARC_INDICATE */ -#define SCLB_IMC_MAC_ERROR_COUNTERS 0x0004 /* */ -#define SCLB_IMC_RES1 0x0008 /* */ -#define SCLB_IMC_MAC_TYPE_2 0x0010 /* QUE_MAC_INDICATE */ -#define SCLB_IMC_TX_FRAME 0x0020 /* */ -#define SCLB_IMC_END_OF_TX_QUEUE 0x0040 /* */ -#define SCLB_IMC_NON_MAC_RX_RESOURCE 0x0080 /* */ -#define SCLB_IMC_MAC_RX_RESOURCE 0x0100 /* */ -#define SCLB_IMC_NON_MAC_RX_FRAME 0x0200 /* */ -#define SCLB_IMC_MAC_RX_FRAME 0x0400 /* */ -#define SCLB_IMC_TRC_FIFO_STATUS 0x0800 /* */ -#define SCLB_IMC_COMMAND_STATUS 0x1000 /* */ -#define SCLB_IMC_MAC_TYPE_1 0x2000 /* Self Removed */ -#define SCLB_IMC_TRC_INTRNL_TST_STATUS 0x4000 /* */ -#define SCLB_IMC_RES2 0x8000 /* */ - -#define DMA_TRIGGER 0x0004 -#define FREQ_16MB_BIT 0x0010 -#define THDREN 0x0020 -#define CFG0_RSV1 0x0040 -#define CFG0_RSV2 0x0080 -#define ETREN 0x0100 -#define RX_OWN_BIT 0x0200 -#define RXATMAC 0x0400 -#define PROMISCUOUS_BIT 0x0800 -#define USETPT 0x1000 -#define SAVBAD_BIT 0x2000 -#define ONEQUE 0x4000 -#define NO_AUTOREMOVE 0x8000 - -#define RX_FCB_AREA_8316 0x00000000 -#define RX_BUFF_AREA_8316 0x00000000 - -#define TRC_POINTER(X) ((unsigned long)(X) - tp->ram_access) -#define RX_FCB_TRC_POINTER(X) ((unsigned long)(X) - tp->ram_access + RX_FCB_AREA_8316) -#define RX_BUFF_TRC_POINTER(X) ((unsigned long)(X) - tp->ram_access + RX_BUFF_AREA_8316) - -// Offset 0: MSR - Memory Select Register -// -#define r587_MSR 0x000 // Register Offset -//#define MSR_RST 0x080 // LAN Controller Reset -#define MSR_MENB 0x040 // Shared Memory Enable -#define MSR_RA18 0x020 // Ram Address bit 18 (583, 584, 587) -#define MSR_RA17 0x010 // Ram Address bit 17 (583, 584, 585/790) -#define MSR_RA16 0x008 // Ram Address bit 16 (583, 584, 585/790) -#define MSR_RA15 0x004 // Ram Address bit 15 (583, 584, 585/790) -#define MSR_RA14 0x002 // Ram Address bit 14 (583, 584, 585/790) -#define MSR_RA13 0x001 // Ram Address bit 13 (583, 584, 585/790) - -#define MSR_MASK 0x03F // Mask for Address bits RA18-RA13 (583, 584, 587) - -#define MSR 0x00 -#define IRR 0x04 -#define HWR 0x04 -#define LAAR 0x05 -#define IMCCR 0x05 -#define LAR0 0x08 -#define BDID 0x0E // Adapter ID byte register offset -#define CSR 0x10 -#define PR 0x11 - -#define MSR_RST 0x80 -#define MSR_MEMB 0x40 -#define MSR_0WS 0x20 - -#define FORCED_16BIT_MODE 0x0002 - -#define INTERFRAME_SPACING_16 0x0003 /* 6 bytes */ -#define INTERFRAME_SPACING_4 0x0001 /* 2 bytes */ -#define MULTICAST_ADDRESS_BIT 0x0010 -#define NON_SRC_ROUTING_BIT 0x0020 - -#define LOOPING_MODE_MASK 0x0007 - -/* - * Decode firmware defines. - */ -#define SWAP_BYTES(X) ((X & 0xff) << 8) | (X >> 8) -#define WEIGHT_OFFSET 5 -#define TREE_SIZE_OFFSET 9 -#define TREE_OFFSET 11 - -/* The Huffman Encoding Tree is constructed of these nodes. */ -typedef struct { - __u8 llink; /* Short version of above node. */ - __u8 tag; - __u8 info; /* This node is used on decodes. */ - __u8 rlink; -} DECODE_TREE_NODE; - -#define ROOT 0 /* Branch value. */ -#define LEAF 0 /* Tag field value. */ -#define BRANCH 1 /* Tag field value. */ - -/* - * Multicast Table Structure - */ -typedef struct { - __u8 address[6]; - __u8 instance_count; -} McTable; - -/* - * Fragment Descriptor Definition - */ -typedef struct { - __u8 *fragment_ptr; - __u32 fragment_length; -} FragmentStructure; - -/* - * Data Buffer Structure Definition - */ -typedef struct { - __u32 fragment_count; - FragmentStructure fragment_list[MAXFRAGMENTS]; -} DataBufferStructure; - -#pragma pack(1) -typedef struct { - __u8 IType; - __u8 ISubtype; -} Interrupt_Status_Word; - -#pragma pack(1) -typedef struct BDBlockType { - __u16 info; /* 02 */ - __u32 trc_next_ptr; /* 06 */ - __u32 trc_data_block_ptr; /* 10 */ - __u16 buffer_length; /* 12 */ - - __u16 *data_block_ptr; /* 16 */ - struct BDBlockType *next_ptr; /* 20 */ - struct BDBlockType *back_ptr; /* 24 */ - __u8 filler[8]; /* 32 */ -} BDBlock; - -#pragma pack(1) -typedef struct FCBlockType { - __u16 frame_status; /* 02 */ - __u16 info; /* 04 */ - __u32 trc_next_ptr; /* 08 */ - __u32 trc_bdb_ptr; /* 12 */ - __u16 frame_length; /* 14 */ - - BDBlock *bdb_ptr; /* 18 */ - struct FCBlockType *next_ptr; /* 22 */ - struct FCBlockType *back_ptr; /* 26 */ - __u16 memory_alloc; /* 28 */ - __u8 filler[4]; /* 32 */ - -} FCBlock; - -#pragma pack(1) -typedef struct SBlockType{ - __u8 Internal_Error_Count; - __u8 Line_Error_Count; - __u8 AC_Error_Count; - __u8 Burst_Error_Count; - __u8 RESERVED_COUNTER_0; - __u8 AD_TRANS_Count; - __u8 RCV_Congestion_Count; - __u8 Lost_FR_Error_Count; - __u8 FREQ_Error_Count; - __u8 FR_Copied_Error_Count; - __u8 RESERVED_COUNTER_1; - __u8 Token_Error_Count; - - __u16 TI_NDIS_Ring_Status; - __u16 BCN_Type; - __u16 Error_Code; - __u16 SA_of_Last_AMP_SMP[3]; - __u16 UNA[3]; - __u16 Ucode_Version_Number; - __u16 Status_CHG_Indicate; - __u16 RESERVED_STATUS_0; -} SBlock; - -#pragma pack(1) -typedef struct ACBlockType { - __u16 cmd_done_status; /* 02 */ - __u16 cmd_info; /* 04 */ - __u32 trc_next_ptr; /* 08 */ - __u16 cmd; /* 10 */ - __u16 subcmd; /* 12 */ - __u16 data_offset_lo; /* 14 */ - __u16 data_offset_hi; /* 16 */ - - struct ACBlockType *next_ptr; /* 20 */ - - __u8 filler[12]; /* 32 */ -} ACBlock; - -#define NUM_OF_INTERRUPTS 0x20 - -#pragma pack(1) -typedef struct { - Interrupt_Status_Word IStatus[NUM_OF_INTERRUPTS]; -} ISBlock; - -#pragma pack(1) -typedef struct { - __u16 valid_command; /* 02 */ - __u16 iack_code; /* 04 */ - __u16 resume_control; /* 06 */ - __u16 int_mask_control; /* 08 */ - __u16 int_mask_state; /* 10 */ - - __u8 filler[6]; /* 16 */ -} SCLBlock; - -#pragma pack(1) -typedef struct -{ - __u16 config; /* 02 */ - __u32 trc_sclb_ptr; /* 06 */ - __u32 trc_acb_ptr; /* 10 */ - __u32 trc_isb_ptr; /* 14 */ - __u16 isbsiz; /* 16 */ - - SCLBlock *sclb_ptr; /* 20 */ - ACBlock *acb_ptr; /* 24 */ - ISBlock *isb_ptr; /* 28 */ - - __u16 Non_Mac_Rx_Bdbs; /* 30 DEBUG */ - __u8 filler[2]; /* 32 */ - -} SCGBlock; - -#pragma pack(1) -typedef struct -{ - __u32 trc_scgb_ptr; - SCGBlock *scgb_ptr; -} ISCPBlock; -#pragma pack() - -typedef struct net_local { - ISCPBlock *iscpb_ptr; - SCGBlock *scgb_ptr; - SCLBlock *sclb_ptr; - ISBlock *isb_ptr; - - ACBlock *acb_head; - ACBlock *acb_curr; - ACBlock *acb_next; - - __u8 adapter_name[12]; - - __u16 num_rx_bdbs [NUM_RX_QS_USED]; - __u16 num_rx_fcbs [NUM_RX_QS_USED]; - - __u16 num_tx_bdbs [NUM_TX_QS_USED]; - __u16 num_tx_fcbs [NUM_TX_QS_USED]; - - __u16 num_of_tx_buffs; - - __u16 tx_buff_size [NUM_TX_QS_USED]; - __u16 tx_buff_used [NUM_TX_QS_USED]; - __u16 tx_queue_status [NUM_TX_QS_USED]; - - FCBlock *tx_fcb_head[NUM_TX_QS_USED]; - FCBlock *tx_fcb_curr[NUM_TX_QS_USED]; - FCBlock *tx_fcb_end[NUM_TX_QS_USED]; - BDBlock *tx_bdb_head[NUM_TX_QS_USED]; - __u16 *tx_buff_head[NUM_TX_QS_USED]; - __u16 *tx_buff_end[NUM_TX_QS_USED]; - __u16 *tx_buff_curr[NUM_TX_QS_USED]; - __u16 num_tx_fcbs_used[NUM_TX_QS_USED]; - - FCBlock *rx_fcb_head[NUM_RX_QS_USED]; - FCBlock *rx_fcb_curr[NUM_RX_QS_USED]; - BDBlock *rx_bdb_head[NUM_RX_QS_USED]; - BDBlock *rx_bdb_curr[NUM_RX_QS_USED]; - BDBlock *rx_bdb_end[NUM_RX_QS_USED]; - __u16 *rx_buff_head[NUM_RX_QS_USED]; - __u16 *rx_buff_end[NUM_RX_QS_USED]; - - __u32 *ptr_local_ring_num; - - __u32 sh_mem_used; - - __u16 page_offset_mask; - - __u16 authorized_function_classes; - __u16 authorized_access_priority; - - __u16 num_acbs; - __u16 num_acbs_used; - __u16 acb_pending; - - __u16 current_isb_index; - - __u8 monitor_state; - __u8 monitor_state_ready; - __u16 ring_status; - __u8 ring_status_flags; - __u8 state; - - __u8 join_state; - - __u8 slot_num; - __u16 pos_id; - - __u32 *ptr_una; - __u32 *ptr_bcn_type; - __u32 *ptr_tx_fifo_underruns; - __u32 *ptr_rx_fifo_underruns; - __u32 *ptr_rx_fifo_overruns; - __u32 *ptr_tx_fifo_overruns; - __u32 *ptr_tx_fcb_overruns; - __u32 *ptr_rx_fcb_overruns; - __u32 *ptr_tx_bdb_overruns; - __u32 *ptr_rx_bdb_overruns; - - __u16 receive_queue_number; - - __u8 rx_fifo_overrun_count; - __u8 tx_fifo_overrun_count; - - __u16 adapter_flags; - __u16 adapter_flags1; - __u16 *misc_command_data; - __u16 max_packet_size; - - __u16 config_word0; - __u16 config_word1; - - __u8 trc_mask; - - __u16 source_ring_number; - __u16 target_ring_number; - - __u16 microcode_version; - - __u16 bic_type; - __u16 nic_type; - __u16 board_id; - - __u16 rom_size; - __u32 rom_base; - __u16 ram_size; - __u16 ram_usable; - __u32 ram_base; - __u32 ram_access; - - __u16 extra_info; - __u16 mode_bits; - __u16 media_menu; - __u16 media_type; - __u16 adapter_bus; - - __u16 status; - __u16 receive_mask; - - __u16 group_address_0; - __u16 group_address[2]; - __u16 functional_address_0; - __u16 functional_address[2]; - __u16 bitwise_group_address[2]; - - __u8 cleanup; - - struct sk_buff_head SendSkbQueue; - __u16 QueueSkb; - - struct tr_statistics MacStat; /* MAC statistics structure */ - - spinlock_t lock; -} NET_LOCAL; - -/************************************ - * SNMP-ON-BOARD Agent Link Structure - ************************************/ - -typedef struct { - __u8 LnkSigStr[12]; /* signature string "SmcLinkTable" */ - __u8 LnkDrvTyp; /* 1=Redbox ODI, 2=ODI DOS, 3=ODI OS/2, 4=NDIS DOS */ - __u8 LnkFlg; /* 0 if no agent linked, 1 if agent linked */ - void *LnkNfo; /* routine which returns pointer to NIC info */ - void *LnkAgtRcv; /* pointer to agent receive trap entry */ - void *LnkAgtXmt; /* pointer to agent transmit trap -entry */ -void *LnkGet; /* pointer to NIC receive data -copy routine */ - void *LnkSnd; /* pointer to NIC send routine -*/ - void *LnkRst; /* pointer to NIC driver reset -routine */ - void *LnkMib; /* pointer to MIB data base */ - void *LnkMibAct; /* pointer to MIB action routine list */ - __u16 LnkCntOffset; /* offset to error counters */ - __u16 LnkCntNum; /* number of error counters */ - __u16 LnkCntSize; /* size of error counters i.e. 32 = 32 bits */ - void *LnkISR; /* pointer to interrupt vector */ - __u8 LnkFrmTyp; /* 1=Ethernet, 2=Token Ring */ - __u8 LnkDrvVer1 ; /* driver major version */ - __u8 LnkDrvVer2 ; /* driver minor version */ -} AgentLink; - -/* - * Definitions for pcm_card_flags(bit_mapped) - */ -#define REG_COMPLETE 0x0001 -#define INSERTED 0x0002 -#define PCC_INSERTED 0x0004 /* 1=currently inserted, 0=cur removed */ - -/* - * Adapter RAM test patterns - */ -#define RAM_PATTERN_1 0x55AA -#define RAM_PATTERN_2 0x9249 -#define RAM_PATTERN_3 0xDB6D - -/* - * definitions for RAM test - */ -#define ROM_SIGNATURE 0xAA55 -#define MIN_ROM_SIZE 0x2000 - -/* - * Return Codes - */ -#define SUCCESS 0x0000 -#define ADAPTER_AND_CONFIG 0x0001 -#define ADAPTER_NO_CONFIG 0x0002 -#define NOT_MY_INTERRUPT 0x0003 -#define FRAME_REJECTED 0x0004 -#define EVENTS_DISABLED 0x0005 -#define OUT_OF_RESOURCES 0x0006 -#define INVALID_PARAMETER 0x0007 -#define INVALID_FUNCTION 0x0008 -#define INITIALIZE_FAILED 0x0009 -#define CLOSE_FAILED 0x000A -#define MAX_COLLISIONS 0x000B -#define NO_SUCH_DESTINATION 0x000C -#define BUFFER_TOO_SMALL_ERROR 0x000D -#define ADAPTER_CLOSED 0x000E -#define UCODE_NOT_PRESENT 0x000F -#define FIFO_UNDERRUN 0x0010 -#define DEST_OUT_OF_RESOURCES 0x0011 -#define ADAPTER_NOT_INITIALIZED 0x0012 -#define PENDING 0x0013 -#define UCODE_PRESENT 0x0014 -#define NOT_INIT_BY_BRIDGE 0x0015 - -#define OPEN_FAILED 0x0080 -#define HARDWARE_FAILED 0x0081 -#define SELF_TEST_FAILED 0x0082 -#define RAM_TEST_FAILED 0x0083 -#define RAM_CONFLICT 0x0084 -#define ROM_CONFLICT 0x0085 -#define UNKNOWN_ADAPTER 0x0086 -#define CONFIG_ERROR 0x0087 -#define CONFIG_WARNING 0x0088 -#define NO_FIXED_CNFG 0x0089 -#define EEROM_CKSUM_ERROR 0x008A -#define ROM_SIGNATURE_ERROR 0x008B -#define ROM_CHECKSUM_ERROR 0x008C -#define ROM_SIZE_ERROR 0x008D -#define UNSUPPORTED_NIC_CHIP 0x008E -#define NIC_REG_ERROR 0x008F -#define BIC_REG_ERROR 0x0090 -#define MICROCODE_TEST_ERROR 0x0091 -#define LOBE_MEDIA_TEST_FAILED 0x0092 - -#define ADAPTER_FOUND_LAN_CORRUPT 0x009B - -#define ADAPTER_NOT_FOUND 0xFFFF - -#define ILLEGAL_FUNCTION INVALID_FUNCTION - -/* Errors */ -#define IO_BASE_INVALID 0x0001 -#define IO_BASE_RANGE 0x0002 -#define IRQ_INVALID 0x0004 -#define IRQ_RANGE 0x0008 -#define RAM_BASE_INVALID 0x0010 -#define RAM_BASE_RANGE 0x0020 -#define RAM_SIZE_RANGE 0x0040 -#define MEDIA_INVALID 0x0800 - -/* Warnings */ -#define IRQ_MISMATCH 0x0080 -#define RAM_BASE_MISMATCH 0x0100 -#define RAM_SIZE_MISMATCH 0x0200 -#define BUS_MODE_MISMATCH 0x0400 - -#define RX_CRC_ERROR 0x01 -#define RX_ALIGNMENT_ERROR 0x02 -#define RX_HW_FAILED 0x80 - -/* - * Definitions for the field RING_STATUS_FLAGS - */ -#define RING_STATUS_CHANGED 0X01 -#define MONITOR_STATE_CHANGED 0X02 -#define JOIN_STATE_CHANGED 0X04 - -/* - * Definitions for the field JOIN_STATE - */ -#define JS_BYPASS_STATE 0x00 -#define JS_LOBE_TEST_STATE 0x01 -#define JS_DETECT_MONITOR_PRESENT_STATE 0x02 -#define JS_AWAIT_NEW_MONITOR_STATE 0x03 -#define JS_DUPLICATE_ADDRESS_TEST_STATE 0x04 -#define JS_NEIGHBOR_NOTIFICATION_STATE 0x05 -#define JS_REQUEST_INITIALIZATION_STATE 0x06 -#define JS_JOIN_COMPLETE_STATE 0x07 -#define JS_BYPASS_WAIT_STATE 0x08 - -/* - * Definitions for the field MONITOR_STATE - */ -#define MS_MONITOR_FSM_INACTIVE 0x00 -#define MS_REPEAT_BEACON_STATE 0x01 -#define MS_REPEAT_CLAIM_TOKEN_STATE 0x02 -#define MS_TRANSMIT_CLAIM_TOKEN_STATE 0x03 -#define MS_STANDBY_MONITOR_STATE 0x04 -#define MS_TRANSMIT_BEACON_STATE 0x05 -#define MS_ACTIVE_MONITOR_STATE 0x06 -#define MS_TRANSMIT_RING_PURGE_STATE 0x07 -#define MS_BEACON_TEST_STATE 0x09 - -/* - * Definitions for the bit-field RING_STATUS - */ -#define SIGNAL_LOSS 0x8000 -#define HARD_ERROR 0x4000 -#define SOFT_ERROR 0x2000 -#define TRANSMIT_BEACON 0x1000 -#define LOBE_WIRE_FAULT 0x0800 -#define AUTO_REMOVAL_ERROR 0x0400 -#define REMOVE_RECEIVED 0x0100 -#define COUNTER_OVERFLOW 0x0080 -#define SINGLE_STATION 0x0040 -#define RING_RECOVERY 0x0020 - -/* - * Definitions for the field BUS_TYPE - */ -#define AT_BUS 0x00 -#define MCA_BUS 0x01 -#define EISA_BUS 0x02 -#define PCI_BUS 0x03 -#define PCMCIA_BUS 0x04 - -/* - * Definitions for adapter_flags - */ -#define RX_VALID_LOOKAHEAD 0x0001 -#define FORCED_16BIT_MODE 0x0002 -#define ADAPTER_DISABLED 0x0004 -#define TRANSMIT_CHAIN_INT 0x0008 -#define EARLY_RX_FRAME 0x0010 -#define EARLY_TX 0x0020 -#define EARLY_RX_COPY 0x0040 -#define USES_PHYSICAL_ADDR 0x0080 /* Rsvd for DEC PCI and 9232 */ -#define NEEDS_PHYSICAL_ADDR 0x0100 /* Reserved*/ -#define RX_STATUS_PENDING 0x0200 -#define ERX_DISABLED 0x0400 /* EARLY_RX_ENABLE rcv_mask */ -#define ENABLE_TX_PENDING 0x0800 -#define ENABLE_RX_PENDING 0x1000 -#define PERM_CLOSE 0x2000 -#define IO_MAPPED 0x4000 /* IOmapped bus interface 795 */ -#define ETX_DISABLED 0x8000 - - -/* - * Definitions for adapter_flags1 - */ -#define TX_PHY_RX_VIRT 0x0001 -#define NEEDS_HOST_RAM 0x0002 -#define NEEDS_MEDIA_TYPE 0x0004 -#define EARLY_RX_DONE 0x0008 -#define PNP_BOOT_BIT 0x0010 /* activates PnP & config on power-up */ - /* clear => regular PnP operation */ -#define PNP_ENABLE 0x0020 /* regular PnP operation clear => */ - /* no PnP, overrides PNP_BOOT_BIT */ -#define SATURN_ENABLE 0x0040 - -#define ADAPTER_REMOVABLE 0x0080 /* adapter is hot swappable */ -#define TX_PHY 0x0100 /* Uses physical address for tx bufs */ -#define RX_PHY 0x0200 /* Uses physical address for rx bufs */ -#define TX_VIRT 0x0400 /* Uses virtual addr for tx bufs */ -#define RX_VIRT 0x0800 -#define NEEDS_SERVICE 0x1000 - -/* - * Adapter Status Codes - */ -#define OPEN 0x0001 -#define INITIALIZED 0x0002 -#define CLOSED 0x0003 -#define FAILED 0x0005 -#define NOT_INITIALIZED 0x0006 -#define IO_CONFLICT 0x0007 -#define CARD_REMOVED 0x0008 -#define CARD_INSERTED 0x0009 - -/* - * Mode Bit Definitions - */ -#define INTERRUPT_STATUS_BIT 0x8000 /* PC Interrupt Line: 0 = Not Enabled */ -#define BOOT_STATUS_MASK 0x6000 /* Mask to isolate BOOT_STATUS */ -#define BOOT_INHIBIT 0x0000 /* BOOT_STATUS is 'inhibited' */ -#define BOOT_TYPE_1 0x2000 /* Unused BOOT_STATUS value */ -#define BOOT_TYPE_2 0x4000 /* Unused BOOT_STATUS value */ -#define BOOT_TYPE_3 0x6000 /* Unused BOOT_STATUS value */ -#define ZERO_WAIT_STATE_MASK 0x1800 /* Mask to isolate Wait State flags */ -#define ZERO_WAIT_STATE_8_BIT 0x1000 /* 0 = Disabled (Inserts Wait States) */ -#define ZERO_WAIT_STATE_16_BIT 0x0800 /* 0 = Disabled (Inserts Wait States) */ -#define LOOPING_MODE_MASK 0x0007 -#define LOOPBACK_MODE_0 0x0000 -#define LOOPBACK_MODE_1 0x0001 -#define LOOPBACK_MODE_2 0x0002 -#define LOOPBACK_MODE_3 0x0003 -#define LOOPBACK_MODE_4 0x0004 -#define LOOPBACK_MODE_5 0x0005 -#define LOOPBACK_MODE_6 0x0006 -#define LOOPBACK_MODE_7 0x0007 -#define AUTO_MEDIA_DETECT 0x0008 -#define MANUAL_CRC 0x0010 -#define EARLY_TOKEN_REL 0x0020 /* Early Token Release for Token Ring */ -#define UMAC 0x0040 -#define UTP2_PORT 0x0080 /* For 8216T2, 0=port A, 1=Port B. */ -#define BNC_10BT_INTERFACE 0x0600 /* BNC and UTP current media set */ -#define UTP_INTERFACE 0x0500 /* Ethernet UTP Only. */ -#define BNC_INTERFACE 0x0400 -#define AUI_INTERFACE 0x0300 -#define AUI_10BT_INTERFACE 0x0200 -#define STARLAN_10_INTERFACE 0x0100 -#define INTERFACE_TYPE_MASK 0x0700 - -/* - * Media Type Bit Definitions - * - * legend: TP = Twisted Pair - * STP = Shielded twisted pair - * UTP = Unshielded twisted pair - */ - -#define CNFG_MEDIA_TYPE_MASK 0x001e /* POS Register 3 Mask */ - -#define MEDIA_S10 0x0000 /* Ethernet adapter, TP. */ -#define MEDIA_AUI_UTP 0x0001 /* Ethernet adapter, AUI/UTP media */ -#define MEDIA_BNC 0x0002 /* Ethernet adapter, BNC media. */ -#define MEDIA_AUI 0x0003 /* Ethernet Adapter, AUI media. */ -#define MEDIA_STP_16 0x0004 /* TokenRing adap, 16Mbit STP. */ -#define MEDIA_STP_4 0x0005 /* TokenRing adap, 4Mbit STP. */ -#define MEDIA_UTP_16 0x0006 /* TokenRing adap, 16Mbit UTP. */ -#define MEDIA_UTP_4 0x0007 /* TokenRing adap, 4Mbit UTP. */ -#define MEDIA_UTP 0x0008 /* Ethernet adapter, UTP media (no AUI) -*/ -#define MEDIA_BNC_UTP 0x0010 /* Ethernet adapter, BNC/UTP media */ -#define MEDIA_UTPFD 0x0011 /* Ethernet adapter, TP full duplex */ -#define MEDIA_UTPNL 0x0012 /* Ethernet adapter, TP with link integrity test disabled */ -#define MEDIA_AUI_BNC 0x0013 /* Ethernet adapter, AUI/BNC media */ -#define MEDIA_AUI_BNC_UTP 0x0014 /* Ethernet adapter, AUI_BNC/UTP */ -#define MEDIA_UTPA 0x0015 /* Ethernet UTP-10Mbps Ports A */ -#define MEDIA_UTPB 0x0016 /* Ethernet UTP-10Mbps Ports B */ -#define MEDIA_STP_16_UTP_16 0x0017 /* Token Ring STP-16Mbps/UTP-16Mbps */ -#define MEDIA_STP_4_UTP_4 0x0018 /* Token Ring STP-4Mbps/UTP-4Mbps */ - -#define MEDIA_STP100_UTP100 0x0020 /* Ethernet STP-100Mbps/UTP-100Mbps */ -#define MEDIA_UTP100FD 0x0021 /* Ethernet UTP-100Mbps, full duplex */ -#define MEDIA_UTP100 0x0022 /* Ethernet UTP-100Mbps */ - - -#define MEDIA_UNKNOWN 0xFFFF /* Unknown adapter/media type */ - -/* - * Definitions for the field: - * media_type2 - */ -#define MEDIA_TYPE_MII 0x0001 -#define MEDIA_TYPE_UTP 0x0002 -#define MEDIA_TYPE_BNC 0x0004 -#define MEDIA_TYPE_AUI 0x0008 -#define MEDIA_TYPE_S10 0x0010 -#define MEDIA_TYPE_AUTO_SENSE 0x1000 -#define MEDIA_TYPE_AUTO_DETECT 0x4000 -#define MEDIA_TYPE_AUTO_NEGOTIATE 0x8000 - -/* - * Definitions for the field: - * line_speed - */ -#define LINE_SPEED_UNKNOWN 0x0000 -#define LINE_SPEED_4 0x0001 -#define LINE_SPEED_10 0x0002 -#define LINE_SPEED_16 0x0004 -#define LINE_SPEED_100 0x0008 -#define LINE_SPEED_T4 0x0008 /* 100BaseT4 aliased for 9332BVT */ -#define LINE_SPEED_FULL_DUPLEX 0x8000 - -/* - * Definitions for the field: - * bic_type (Bus interface chip type) - */ -#define BIC_NO_CHIP 0x0000 /* Bus interface chip not implemented */ -#define BIC_583_CHIP 0x0001 /* 83C583 bus interface chip */ -#define BIC_584_CHIP 0x0002 /* 83C584 bus interface chip */ -#define BIC_585_CHIP 0x0003 /* 83C585 bus interface chip */ -#define BIC_593_CHIP 0x0004 /* 83C593 bus interface chip */ -#define BIC_594_CHIP 0x0005 /* 83C594 bus interface chip */ -#define BIC_564_CHIP 0x0006 /* PCMCIA Bus interface chip */ -#define BIC_790_CHIP 0x0007 /* 83C790 bus i-face/Ethernet NIC chip */ -#define BIC_571_CHIP 0x0008 /* 83C571 EISA bus master i-face */ -#define BIC_587_CHIP 0x0009 /* Token Ring AT bus master i-face */ -#define BIC_574_CHIP 0x0010 /* FEAST bus interface chip */ -#define BIC_8432_CHIP 0x0011 /* 8432 bus i-face/Ethernet NIC(DEC PCI) */ -#define BIC_9332_CHIP 0x0012 /* 9332 bus i-face/100Mbps Ether NIC(DEC PCI) */ -#define BIC_8432E_CHIP 0x0013 /* 8432 Enhanced bus iface/Ethernet NIC(DEC) */ -#define BIC_EPIC100_CHIP 0x0014 /* EPIC/100 10/100 Mbps Ethernet BIC/NIC */ -#define BIC_C94_CHIP 0x0015 /* 91C94 bus i-face in PCMCIA mode */ -#define BIC_X8020_CHIP 0x0016 /* Xilinx PCMCIA multi-func i-face */ - -/* - * Definitions for the field: - * nic_type (Bus interface chip type) - */ -#define NIC_UNK_CHIP 0x0000 /* Unknown NIC chip */ -#define NIC_8390_CHIP 0x0001 /* DP8390 Ethernet NIC */ -#define NIC_690_CHIP 0x0002 /* 83C690 Ethernet NIC */ -#define NIC_825_CHIP 0x0003 /* 83C825 Token Ring NIC */ -/* #define NIC_???_CHIP 0x0004 */ /* Not used */ -/* #define NIC_???_CHIP 0x0005 */ /* Not used */ -/* #define NIC_???_CHIP 0x0006 */ /* Not used */ -#define NIC_790_CHIP 0x0007 /* 83C790 bus i-face/Ethernet NIC chip */ -#define NIC_C100_CHIP 0x0010 /* FEAST 100Mbps Ethernet NIC */ -#define NIC_8432_CHIP 0x0011 /* 8432 bus i-face/Ethernet NIC(DEC PCI) */ -#define NIC_9332_CHIP 0x0012 /* 9332 bus i-face/100Mbps Ether NIC(DEC PCI) */ -#define NIC_8432E_CHIP 0x0013 /* 8432 enhanced bus iface/Ethernet NIC(DEC) */ -#define NIC_EPIC100_CHIP 0x0014 /* EPIC/100 10/100 Mbps Ethernet BIC/NIC */ -#define NIC_C94_CHIP 0x0015 /* 91C94 PC Card with multi func */ - -/* - * Definitions for the field: - * adapter_type The adapter_type field describes the adapter/bus - * configuration. - */ -#define BUS_ISA16_TYPE 0x0001 /* 16 bit adap in 16 bit (E)ISA slot */ -#define BUS_ISA8_TYPE 0x0002 /* 8/16b adap in 8 bit XT/(E)ISA slot */ -#define BUS_MCA_TYPE 0x0003 /* Micro Channel adapter */ - -/* - * Receive Mask definitions - */ -#define ACCEPT_MULTICAST 0x0001 -#define ACCEPT_BROADCAST 0x0002 -#define PROMISCUOUS_MODE 0x0004 -#define ACCEPT_SOURCE_ROUTING 0x0008 -#define ACCEPT_ERR_PACKETS 0x0010 -#define ACCEPT_ATT_MAC_FRAMES 0x0020 -#define ACCEPT_MULTI_PROM 0x0040 -#define TRANSMIT_ONLY 0x0080 -#define ACCEPT_EXT_MAC_FRAMES 0x0100 -#define EARLY_RX_ENABLE 0x0200 -#define PKT_SIZE_NOT_NEEDED 0x0400 -#define ACCEPT_SOURCE_ROUTING_SPANNING 0x0808 - -#define ACCEPT_ALL_MAC_FRAMES 0x0120 - -/* - * config_mode defs - */ -#define STORE_EEROM 0x0001 /* Store config in EEROM. */ -#define STORE_REGS 0x0002 /* Store config in register set. */ - -/* - * equates for lmac_flags in adapter structure (Ethernet) - */ -#define MEM_DISABLE 0x0001 -#define RX_STATUS_POLL 0x0002 -#define USE_RE_BIT 0x0004 -/*#define RESERVED 0x0008 */ -/*#define RESERVED 0x0010 */ -/*#define RESERVED 0x0020 */ -/*#define RESERVED 0x0040 */ -/*#define RESERVED 0x0080 */ -/*#define RESERVED 0x0100 */ -/*#define RESERVED 0x0200 */ -/*#define RESERVED 0x0400 */ -/*#define RESERVED 0x0800 */ -/*#define RESERVED 0x1000 */ -/*#define RESERVED 0x2000 */ -/*#define RESERVED 0x4000 */ -/*#define RESERVED 0x8000 */ - -/* media_opts & media_set Fields bit defs for Ethernet ... */ -#define MED_OPT_BNC 0x01 -#define MED_OPT_UTP 0x02 -#define MED_OPT_AUI 0x04 -#define MED_OPT_10MB 0x08 -#define MED_OPT_100MB 0x10 -#define MED_OPT_S10 0x20 - -/* media_opts & media_set Fields bit defs for Token Ring ... */ -#define MED_OPT_4MB 0x08 -#define MED_OPT_16MB 0x10 -#define MED_OPT_STP 0x40 - -#define MAX_8023_SIZE 1500 /* Max 802.3 size of frame. */ -#define DEFAULT_ERX_VALUE 4 /* Number of 16-byte blocks for 790B early Rx. */ -#define DEFAULT_ETX_VALUE 32 /* Number of bytes for 790B early Tx. */ -#define DEFAULT_TX_RETRIES 3 /* Number of transmit retries */ -#define LPBK_FRAME_SIZE 1024 /* Default loopback frame for Rx calibration test. */ -#define MAX_LOOKAHEAD_SIZE 252 /* Max lookahead size for ethernet. */ - -#define RW_MAC_STATE 0x1101 -#define RW_SA_OF_LAST_AMP_OR_SMP 0x2803 -#define RW_PHYSICAL_DROP_NUMBER 0x3B02 -#define RW_UPSTREAM_NEIGHBOR_ADDRESS 0x3E03 -#define RW_PRODUCT_INSTANCE_ID 0x4B09 - -#define RW_TRC_STATUS_BLOCK 0x5412 - -#define RW_MAC_ERROR_COUNTERS_NO_CLEAR 0x8006 -#define RW_MAC_ERROR_COUNTER_CLEAR 0x7A06 -#define RW_CONFIG_REGISTER_0 0xA001 -#define RW_CONFIG_REGISTER_1 0xA101 -#define RW_PRESCALE_TIMER_THRESHOLD 0xA201 -#define RW_TPT_THRESHOLD 0xA301 -#define RW_TQP_THRESHOLD 0xA401 -#define RW_TNT_THRESHOLD 0xA501 -#define RW_TBT_THRESHOLD 0xA601 -#define RW_TSM_THRESHOLD 0xA701 -#define RW_TAM_THRESHOLD 0xA801 -#define RW_TBR_THRESHOLD 0xA901 -#define RW_TER_THRESHOLD 0xAA01 -#define RW_TGT_THRESHOLD 0xAB01 -#define RW_THT_THRESHOLD 0xAC01 -#define RW_TRR_THRESHOLD 0xAD01 -#define RW_TVX_THRESHOLD 0xAE01 -#define RW_INDIVIDUAL_MAC_ADDRESS 0xB003 - -#define RW_INDIVIDUAL_GROUP_ADDRESS 0xB303 /* all of group addr */ -#define RW_INDIVIDUAL_GROUP_ADDR_WORD_0 0xB301 /* 1st word of group addr */ -#define RW_INDIVIDUAL_GROUP_ADDR 0xB402 /* 2nd-3rd word of group addr */ -#define RW_FUNCTIONAL_ADDRESS 0xB603 /* all of functional addr */ -#define RW_FUNCTIONAL_ADDR_WORD_0 0xB601 /* 1st word of func addr */ -#define RW_FUNCTIONAL_ADDR 0xB702 /* 2nd-3rd word func addr */ - -#define RW_BIT_SIGNIFICANT_GROUP_ADDR 0xB902 -#define RW_SOURCE_RING_BRIDGE_NUMBER 0xBB01 -#define RW_TARGET_RING_NUMBER 0xBC01 - -#define RW_HIC_INTERRUPT_MASK 0xC601 - -#define SOURCE_ROUTING_SPANNING_BITS 0x00C0 /* Spanning Tree Frames */ -#define SOURCE_ROUTING_EXPLORER_BIT 0x0040 /* Explorer and Single Route */ - - /* write */ - -#define CSR_MSK_ALL 0x80 // Bic 587 Only -#define CSR_MSKTINT 0x20 -#define CSR_MSKCBUSY 0x10 -#define CSR_CLRTINT 0x08 -#define CSR_CLRCBUSY 0x04 -#define CSR_WCSS 0x02 -#define CSR_CA 0x01 - - /* read */ - -#define CSR_TINT 0x20 -#define CSR_CINT 0x10 -#define CSR_TSTAT 0x08 -#define CSR_CSTAT 0x04 -#define CSR_FAULT 0x02 -#define CSR_CBUSY 0x01 - -#define LAAR_MEM16ENB 0x80 -#define Zws16 0x20 - -#define IRR_IEN 0x80 -#define Zws8 0x01 - -#define IMCCR_EIL 0x04 - -typedef struct { - __u8 ac; /* Access Control */ - __u8 fc; /* Frame Control */ - __u8 da[6]; /* Dest Addr */ - __u8 sa[6]; /* Source Addr */ - - __u16 vl; /* Vector Length */ - __u8 dc_sc; /* Dest/Source Class */ - __u8 vc; /* Vector Code */ - } MAC_HEADER; - -#define MAX_SUB_VECTOR_INFO (RX_DATA_BUFFER_SIZE - sizeof(MAC_HEADER) - 2) - -typedef struct - { - __u8 svl; /* Sub-vector Length */ - __u8 svi; /* Sub-vector Code */ - __u8 svv[MAX_SUB_VECTOR_INFO]; /* Sub-vector Info */ - } MAC_SUB_VECTOR; - -#endif /* __KERNEL__ */ -#endif /* __LINUX_SMCTR_H */
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c deleted file mode 100644 index b5e0855..0000000 --- a/drivers/net/tokenring/tms380tr.c +++ /dev/null
@@ -1,2306 +0,0 @@ -/* - * tms380tr.c: A network driver library for Texas Instruments TMS380-based - * Token Ring Adapters. - * - * Originally sktr.c: Written 1997 by Christoph Goos - * - * A fine result of the Linux Systems Network Architecture Project. - * http://www.vanheusden.com/sna/ - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * The following modules are currently available for card support: - * - tmspci (Generic PCI card support) - * - abyss (Madge PCI support) - * - tmsisa (SysKonnect TR4/16 ISA) - * - * Sources: - * - The hardware related parts of this driver are take from - * the SysKonnect Token Ring driver for Windows NT. - * - I used the IBM Token Ring driver 'ibmtr.c' as a base for this - * driver, as well as the 'skeleton.c' driver by Donald Becker. - * - Also various other drivers in the linux source tree were taken - * as samples for some tasks. - * - TI TMS380 Second-Generation Token Ring User's Guide - * - TI datasheets for respective chips - * - David Hein at Texas Instruments - * - Various Madge employees - * - * Maintainer(s): - * JS Jay Schulist jschlst@samba.org - * CG Christoph Goos cgoos@syskonnect.de - * AF Adam Fritzler - * MLP Mike Phillips phillim@amtrak.com - * JF Jochen Friedrich jochen@scram.de - * - * Modification History: - * 29-Aug-97 CG Created - * 04-Apr-98 CG Fixed problems caused by tok_timer_check - * 10-Apr-98 CG Fixed lockups at cable disconnection - * 27-May-98 JS Formated to Linux Kernel Format - * 31-May-98 JS Hacked in PCI support - * 16-Jun-98 JS Modulized for multiple cards with one driver - * Sep-99 AF Renamed to tms380tr (supports more than SK's) - * 23-Sep-99 AF Added Compaq and Thomas-Conrad PCI support - * Fixed a bug causing double copies on PCI - * Fixed for new multicast stuff (2.2/2.3) - * 25-Sep-99 AF Uped TPL_NUM from 3 to 9 - * Removed extraneous 'No free TPL' - * 22-Dec-99 AF Added Madge PCI Mk2 support and generalized - * parts of the initilization procedure. - * 30-Dec-99 AF Turned tms380tr into a library ala 8390. - * Madge support is provided in the abyss module - * Generic PCI support is in the tmspci module. - * 30-Nov-00 JF Updated PCI code to support IO MMU via - * pci_map_static(). Alpha uses this MMU for ISA - * as well. - * 14-Jan-01 JF Fix DMA on ifdown/ifup sequences. Some - * cleanup. - * 13-Jan-02 JF Add spinlock to fix race condition. - * 09-Nov-02 JF Fixed printks to not SPAM the console during - * normal operation. - * 30-Dec-02 JF Removed incorrect __init from - * tms380tr_init_card. - * 22-Jul-05 JF Converted to dma-mapping. - * - * To do: - * 1. Multi/Broadcast packet handling (this may have fixed itself) - * 2. Write a sktrisa module that includes the old ISA support (done) - * 3. Allow modules to load their own microcode - * 4. Speed up the BUD process -- freezing the kernel for 3+sec is - * quite unacceptable. - * 5. Still a few remaining stalls when the cable is unplugged. - */ - -#ifdef MODULE -static const char version[] = "tms380tr.c: v1.10 30/12/2002 by Christoph Goos, Adam Fritzler\n"; -#endif - -#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/in.h> -#include <linux/string.h> -#include <linux/time.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/dma-mapping.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/trdevice.h> -#include <linux/firmware.h> -#include <linux/bitops.h> - -#include <asm/io.h> -#include <asm/dma.h> -#include <asm/irq.h> -#include <asm/uaccess.h> - -#include "tms380tr.h" /* Our Stuff */ - -/* Use 0 for production, 1 for verification, 2 for debug, and - * 3 for very verbose debug. - */ -#ifndef TMS380TR_DEBUG -#define TMS380TR_DEBUG 0 -#endif -static unsigned int tms380tr_debug = TMS380TR_DEBUG; - -/* Index to functions, as function prototypes. - * Alphabetical by function name. - */ - -/* "A" */ -/* "B" */ -static int tms380tr_bringup_diags(struct net_device *dev); -/* "C" */ -static void tms380tr_cancel_tx_queue(struct net_local* tp); -static int tms380tr_chipset_init(struct net_device *dev); -static void tms380tr_chk_irq(struct net_device *dev); -static void tms380tr_chk_outstanding_cmds(struct net_device *dev); -static void tms380tr_chk_src_addr(unsigned char *frame, unsigned char *hw_addr); -static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqType); -int tms380tr_close(struct net_device *dev); -static void tms380tr_cmd_status_irq(struct net_device *dev); -/* "D" */ -static void tms380tr_disable_interrupts(struct net_device *dev); -#if TMS380TR_DEBUG > 0 -static void tms380tr_dump(unsigned char *Data, int length); -#endif -/* "E" */ -static void tms380tr_enable_interrupts(struct net_device *dev); -static void tms380tr_exec_cmd(struct net_device *dev, unsigned short Command); -static void tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue); -/* "F" */ -/* "G" */ -static struct net_device_stats *tms380tr_get_stats(struct net_device *dev); -/* "H" */ -static netdev_tx_t tms380tr_hardware_send_packet(struct sk_buff *skb, - struct net_device *dev); -/* "I" */ -static int tms380tr_init_adapter(struct net_device *dev); -static void tms380tr_init_ipb(struct net_local *tp); -static void tms380tr_init_net_local(struct net_device *dev); -static void tms380tr_init_opb(struct net_device *dev); -/* "M" */ -/* "O" */ -int tms380tr_open(struct net_device *dev); -static void tms380tr_open_adapter(struct net_device *dev); -/* "P" */ -/* "R" */ -static void tms380tr_rcv_status_irq(struct net_device *dev); -static int tms380tr_read_ptr(struct net_device *dev); -static void tms380tr_read_ram(struct net_device *dev, unsigned char *Data, - unsigned short Address, int Length); -static int tms380tr_reset_adapter(struct net_device *dev); -static void tms380tr_reset_interrupt(struct net_device *dev); -static void tms380tr_ring_status_irq(struct net_device *dev); -/* "S" */ -static netdev_tx_t tms380tr_send_packet(struct sk_buff *skb, - struct net_device *dev); -static void tms380tr_set_multicast_list(struct net_device *dev); -static int tms380tr_set_mac_address(struct net_device *dev, void *addr); -/* "T" */ -static void tms380tr_timer_chk(unsigned long data); -static void tms380tr_timer_end_wait(unsigned long data); -static void tms380tr_tx_status_irq(struct net_device *dev); -/* "U" */ -static void tms380tr_update_rcv_stats(struct net_local *tp, - unsigned char DataPtr[], unsigned int Length); -/* "W" */ -void tms380tr_wait(unsigned long time); -static void tms380tr_write_rpl_status(RPL *rpl, unsigned int Status); -static void tms380tr_write_tpl_status(TPL *tpl, unsigned int Status); - -#define SIFREADB(reg) \ - (((struct net_local *)netdev_priv(dev))->sifreadb(dev, reg)) -#define SIFWRITEB(val, reg) \ - (((struct net_local *)netdev_priv(dev))->sifwriteb(dev, val, reg)) -#define SIFREADW(reg) \ - (((struct net_local *)netdev_priv(dev))->sifreadw(dev, reg)) -#define SIFWRITEW(val, reg) \ - (((struct net_local *)netdev_priv(dev))->sifwritew(dev, val, reg)) - - - -#if 0 /* TMS380TR_DEBUG > 0 */ -static int madgemc_sifprobe(struct net_device *dev) -{ - unsigned char old, chk1, chk2; - - old = SIFREADB(SIFADR); /* Get the old SIFADR value */ - - chk1 = 0; /* Begin with check value 0 */ - do { - madgemc_setregpage(dev, 0); - /* Write new SIFADR value */ - SIFWRITEB(chk1, SIFADR); - chk2 = SIFREADB(SIFADR); - if (chk2 != chk1) - return -1; - - madgemc_setregpage(dev, 1); - /* Read, invert and write */ - chk2 = SIFREADB(SIFADD); - if (chk2 != chk1) - return -1; - - madgemc_setregpage(dev, 0); - chk2 ^= 0x0FE; - SIFWRITEB(chk2, SIFADR); - - /* Read, invert and compare */ - madgemc_setregpage(dev, 1); - chk2 = SIFREADB(SIFADD); - madgemc_setregpage(dev, 0); - chk2 ^= 0x0FE; - - if(chk1 != chk2) - return -1; /* No adapter */ - chk1 -= 2; - } while(chk1 != 0); /* Repeat 128 times (all byte values) */ - - madgemc_setregpage(dev, 0); /* sanity */ - /* Restore the SIFADR value */ - SIFWRITEB(old, SIFADR); - - return 0; -} -#endif - -/* - * Open/initialize the board. This is called 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. - */ -int tms380tr_open(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int err; - - /* init the spinlock */ - spin_lock_init(&tp->lock); - init_timer(&tp->timer); - - /* Reset the hardware here. Don't forget to set the station address. */ - -#if defined(CONFIG_ISA) && defined(CONFIG_ISA_DMA_API) - if(dev->dma > 0) - { - unsigned long flags=claim_dma_lock(); - disable_dma(dev->dma); - set_dma_mode(dev->dma, DMA_MODE_CASCADE); - enable_dma(dev->dma); - release_dma_lock(flags); - } -#endif - - err = tms380tr_chipset_init(dev); - if(err) - { - printk(KERN_INFO "%s: Chipset initialization error\n", - dev->name); - return -1; - } - - tp->timer.expires = jiffies + 30*HZ; - tp->timer.function = tms380tr_timer_end_wait; - tp->timer.data = (unsigned long)dev; - add_timer(&tp->timer); - - printk(KERN_DEBUG "%s: Adapter RAM size: %dK\n", - dev->name, tms380tr_read_ptr(dev)); - - tms380tr_enable_interrupts(dev); - tms380tr_open_adapter(dev); - - netif_start_queue(dev); - - /* Wait for interrupt from hardware. If interrupt does not come, - * there will be a timeout from the timer. - */ - tp->Sleeping = 1; - interruptible_sleep_on(&tp->wait_for_tok_int); - del_timer(&tp->timer); - - /* If AdapterVirtOpenFlag is 1, the adapter is now open for use */ - if(tp->AdapterVirtOpenFlag == 0) - { - tms380tr_disable_interrupts(dev); - return -1; - } - - tp->StartTime = jiffies; - - /* Start function control timer */ - tp->timer.expires = jiffies + 2*HZ; - tp->timer.function = tms380tr_timer_chk; - tp->timer.data = (unsigned long)dev; - add_timer(&tp->timer); - - return 0; -} - -/* - * Timeout function while waiting for event - */ -static void tms380tr_timer_end_wait(unsigned long data) -{ - struct net_device *dev = (struct net_device*)data; - struct net_local *tp = netdev_priv(dev); - - if(tp->Sleeping) - { - tp->Sleeping = 0; - wake_up_interruptible(&tp->wait_for_tok_int); - } -} - -/* - * Initialize the chipset - */ -static int tms380tr_chipset_init(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int err; - - tms380tr_init_ipb(tp); - tms380tr_init_opb(dev); - tms380tr_init_net_local(dev); - - if(tms380tr_debug > 3) - printk(KERN_DEBUG "%s: Resetting adapter...\n", dev->name); - err = tms380tr_reset_adapter(dev); - if(err < 0) - return -1; - - if(tms380tr_debug > 3) - printk(KERN_DEBUG "%s: Bringup diags...\n", dev->name); - err = tms380tr_bringup_diags(dev); - if(err < 0) - return -1; - - if(tms380tr_debug > 3) - printk(KERN_DEBUG "%s: Init adapter...\n", dev->name); - err = tms380tr_init_adapter(dev); - if(err < 0) - return -1; - - if(tms380tr_debug > 3) - printk(KERN_DEBUG "%s: Done!\n", dev->name); - return 0; -} - -/* - * Initializes the net_local structure. - */ -static void tms380tr_init_net_local(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - int i; - dma_addr_t dmabuf; - - tp->scb.CMD = 0; - tp->scb.Parm[0] = 0; - tp->scb.Parm[1] = 0; - - tp->ssb.STS = 0; - tp->ssb.Parm[0] = 0; - tp->ssb.Parm[1] = 0; - tp->ssb.Parm[2] = 0; - - tp->CMDqueue = 0; - - tp->AdapterOpenFlag = 0; - tp->AdapterVirtOpenFlag = 0; - tp->ScbInUse = 0; - tp->OpenCommandIssued = 0; - tp->ReOpenInProgress = 0; - tp->HaltInProgress = 0; - tp->TransmitHaltScheduled = 0; - tp->LobeWireFaultLogged = 0; - tp->LastOpenStatus = 0; - tp->MaxPacketSize = DEFAULT_PACKET_SIZE; - - /* Create circular chain of transmit lists */ - for (i = 0; i < TPL_NUM; i++) - { - tp->Tpl[i].NextTPLAddr = htonl(((char *)(&tp->Tpl[(i+1) % TPL_NUM]) - (char *)tp) + tp->dmabuffer); /* DMA buffer may be MMU driven */ - tp->Tpl[i].Status = 0; - tp->Tpl[i].FrameSize = 0; - tp->Tpl[i].FragList[0].DataCount = 0; - tp->Tpl[i].FragList[0].DataAddr = 0; - tp->Tpl[i].NextTPLPtr = &tp->Tpl[(i+1) % TPL_NUM]; - tp->Tpl[i].MData = NULL; - tp->Tpl[i].TPLIndex = i; - tp->Tpl[i].DMABuff = 0; - tp->Tpl[i].BusyFlag = 0; - } - - tp->TplFree = tp->TplBusy = &tp->Tpl[0]; - - /* Create circular chain of receive lists */ - for (i = 0; i < RPL_NUM; i++) - { - tp->Rpl[i].NextRPLAddr = htonl(((char *)(&tp->Rpl[(i+1) % RPL_NUM]) - (char *)tp) + tp->dmabuffer); /* DMA buffer may be MMU driven */ - tp->Rpl[i].Status = (RX_VALID | RX_START_FRAME | RX_END_FRAME | RX_FRAME_IRQ); - tp->Rpl[i].FrameSize = 0; - tp->Rpl[i].FragList[0].DataCount = cpu_to_be16((unsigned short)tp->MaxPacketSize); - - /* Alloc skb and point adapter to data area */ - tp->Rpl[i].Skb = dev_alloc_skb(tp->MaxPacketSize); - tp->Rpl[i].DMABuff = 0; - - /* skb == NULL ? then use local buffer */ - if(tp->Rpl[i].Skb == NULL) - { - tp->Rpl[i].SkbStat = SKB_UNAVAILABLE; - tp->Rpl[i].FragList[0].DataAddr = htonl(((char *)tp->LocalRxBuffers[i] - (char *)tp) + tp->dmabuffer); - tp->Rpl[i].MData = tp->LocalRxBuffers[i]; - } - else /* SKB != NULL */ - { - tp->Rpl[i].Skb->dev = dev; - skb_put(tp->Rpl[i].Skb, tp->MaxPacketSize); - - /* data unreachable for DMA ? then use local buffer */ - dmabuf = dma_map_single(tp->pdev, tp->Rpl[i].Skb->data, tp->MaxPacketSize, DMA_FROM_DEVICE); - if(tp->dmalimit && (dmabuf + tp->MaxPacketSize > tp->dmalimit)) - { - tp->Rpl[i].SkbStat = SKB_DATA_COPY; - tp->Rpl[i].FragList[0].DataAddr = htonl(((char *)tp->LocalRxBuffers[i] - (char *)tp) + tp->dmabuffer); - tp->Rpl[i].MData = tp->LocalRxBuffers[i]; - } - else /* DMA directly in skb->data */ - { - tp->Rpl[i].SkbStat = SKB_DMA_DIRECT; - tp->Rpl[i].FragList[0].DataAddr = htonl(dmabuf); - tp->Rpl[i].MData = tp->Rpl[i].Skb->data; - tp->Rpl[i].DMABuff = dmabuf; - } - } - - tp->Rpl[i].NextRPLPtr = &tp->Rpl[(i+1) % RPL_NUM]; - tp->Rpl[i].RPLIndex = i; - } - - tp->RplHead = &tp->Rpl[0]; - tp->RplTail = &tp->Rpl[RPL_NUM-1]; - tp->RplTail->Status = (RX_START_FRAME | RX_END_FRAME | RX_FRAME_IRQ); -} - -/* - * Initializes the initialisation parameter block. - */ -static void tms380tr_init_ipb(struct net_local *tp) -{ - tp->ipb.Init_Options = BURST_MODE; - tp->ipb.CMD_Status_IV = 0; - tp->ipb.TX_IV = 0; - tp->ipb.RX_IV = 0; - tp->ipb.Ring_Status_IV = 0; - tp->ipb.SCB_Clear_IV = 0; - tp->ipb.Adapter_CHK_IV = 0; - tp->ipb.RX_Burst_Size = BURST_SIZE; - tp->ipb.TX_Burst_Size = BURST_SIZE; - tp->ipb.DMA_Abort_Thrhld = DMA_RETRIES; - tp->ipb.SCB_Addr = 0; - tp->ipb.SSB_Addr = 0; -} - -/* - * Initializes the open parameter block. - */ -static void tms380tr_init_opb(struct net_device *dev) -{ - struct net_local *tp; - unsigned long Addr; - unsigned short RplSize = RPL_SIZE; - unsigned short TplSize = TPL_SIZE; - unsigned short BufferSize = BUFFER_SIZE; - int i; - - tp = netdev_priv(dev); - - tp->ocpl.OPENOptions = 0; - tp->ocpl.OPENOptions |= ENABLE_FULL_DUPLEX_SELECTION; - tp->ocpl.FullDuplex = 0; - tp->ocpl.FullDuplex |= OPEN_FULL_DUPLEX_OFF; - - /* - * Set node address - * - * We go ahead and put it in the OPB even though on - * most of the generic adapters this isn't required. - * Its simpler this way. -- ASF - */ - for (i=0;i<6;i++) - tp->ocpl.NodeAddr[i] = ((unsigned char *)dev->dev_addr)[i]; - - tp->ocpl.GroupAddr = 0; - tp->ocpl.FunctAddr = 0; - tp->ocpl.RxListSize = cpu_to_be16((unsigned short)RplSize); - tp->ocpl.TxListSize = cpu_to_be16((unsigned short)TplSize); - tp->ocpl.BufSize = cpu_to_be16((unsigned short)BufferSize); - tp->ocpl.Reserved = 0; - tp->ocpl.TXBufMin = TX_BUF_MIN; - tp->ocpl.TXBufMax = TX_BUF_MAX; - - Addr = htonl(((char *)tp->ProductID - (char *)tp) + tp->dmabuffer); - - tp->ocpl.ProdIDAddr[0] = LOWORD(Addr); - tp->ocpl.ProdIDAddr[1] = HIWORD(Addr); -} - -/* - * Send OPEN command to adapter - */ -static void tms380tr_open_adapter(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - - if(tp->OpenCommandIssued) - return; - - tp->OpenCommandIssued = 1; - tms380tr_exec_cmd(dev, OC_OPEN); -} - -/* - * Clear the adapter's interrupt flag. Clear system interrupt enable - * (SINTEN): disable adapter to system interrupts. - */ -static void tms380tr_disable_interrupts(struct net_device *dev) -{ - SIFWRITEB(0, SIFACL); -} - -/* - * Set the adapter's interrupt flag. Set system interrupt enable - * (SINTEN): enable adapter to system interrupts. - */ -static void tms380tr_enable_interrupts(struct net_device *dev) -{ - SIFWRITEB(ACL_SINTEN, SIFACL); -} - -/* - * Put command in command queue, try to execute it. - */ -static void tms380tr_exec_cmd(struct net_device *dev, unsigned short Command) -{ - struct net_local *tp = netdev_priv(dev); - - tp->CMDqueue |= Command; - tms380tr_chk_outstanding_cmds(dev); -} - -static void tms380tr_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. - * - * Resetting the token ring adapter takes a long time so just - * fake transmission time and go on trying. Our own timeout - * routine is in tms380tr_timer_chk() - */ - dev->trans_start = jiffies; /* prevent tx timeout */ - netif_wake_queue(dev); -} - -/* - * Gets skb from system, queues it and checks if it can be sent - */ -static netdev_tx_t tms380tr_send_packet(struct sk_buff *skb, - struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - netdev_tx_t rc; - - rc = tms380tr_hardware_send_packet(skb, dev); - if(tp->TplFree->NextTPLPtr->BusyFlag) - netif_stop_queue(dev); - return rc; -} - -/* - * Move frames into adapter tx queue - */ -static netdev_tx_t tms380tr_hardware_send_packet(struct sk_buff *skb, - struct net_device *dev) -{ - TPL *tpl; - short length; - unsigned char *buf; - unsigned long flags; - int i; - dma_addr_t dmabuf, newbuf; - struct net_local *tp = netdev_priv(dev); - - /* Try to get a free TPL from the chain. - * - * NOTE: We *must* always leave one unused TPL in the chain, - * because otherwise the adapter might send frames twice. - */ - spin_lock_irqsave(&tp->lock, flags); - if(tp->TplFree->NextTPLPtr->BusyFlag) { /* No free TPL */ - if (tms380tr_debug > 0) - printk(KERN_DEBUG "%s: No free TPL\n", dev->name); - spin_unlock_irqrestore(&tp->lock, flags); - return NETDEV_TX_BUSY; - } - - dmabuf = 0; - - /* Is buffer reachable for Busmaster-DMA? */ - - length = skb->len; - dmabuf = dma_map_single(tp->pdev, skb->data, length, DMA_TO_DEVICE); - if(tp->dmalimit && (dmabuf + length > tp->dmalimit)) { - /* Copy frame to local buffer */ - dma_unmap_single(tp->pdev, dmabuf, length, DMA_TO_DEVICE); - dmabuf = 0; - i = tp->TplFree->TPLIndex; - buf = tp->LocalTxBuffers[i]; - skb_copy_from_linear_data(skb, buf, length); - newbuf = ((char *)buf - (char *)tp) + tp->dmabuffer; - } - else { - /* Send direct from skb->data */ - newbuf = dmabuf; - buf = skb->data; - } - /* Source address in packet? */ - tms380tr_chk_src_addr(buf, dev->dev_addr); - tp->LastSendTime = jiffies; - tpl = tp->TplFree; /* Get the "free" TPL */ - tpl->BusyFlag = 1; /* Mark TPL as busy */ - tp->TplFree = tpl->NextTPLPtr; - - /* Save the skb for delayed return of skb to system */ - tpl->Skb = skb; - tpl->DMABuff = dmabuf; - tpl->FragList[0].DataCount = cpu_to_be16((unsigned short)length); - tpl->FragList[0].DataAddr = htonl(newbuf); - - /* Write the data length in the transmit list. */ - tpl->FrameSize = cpu_to_be16((unsigned short)length); - tpl->MData = buf; - - /* Transmit the frame and set the status values. */ - tms380tr_write_tpl_status(tpl, TX_VALID | TX_START_FRAME - | TX_END_FRAME | TX_PASS_SRC_ADDR - | TX_FRAME_IRQ); - - /* Let adapter send the frame. */ - tms380tr_exec_sifcmd(dev, CMD_TX_VALID); - spin_unlock_irqrestore(&tp->lock, flags); - - return NETDEV_TX_OK; -} - -/* - * Write the given value to the 'Status' field of the specified TPL. - * NOTE: This function should be used whenever the status of any TPL must be - * modified by the driver, because the compiler may otherwise change the - * order of instructions such that writing the TPL status may be executed at - * an undesirable time. When this function is used, the status is always - * written when the function is called. - */ -static void tms380tr_write_tpl_status(TPL *tpl, unsigned int Status) -{ - tpl->Status = Status; -} - -static void tms380tr_chk_src_addr(unsigned char *frame, unsigned char *hw_addr) -{ - unsigned char SRBit; - - if((((unsigned long)frame[8]) & ~0x80) != 0) /* Compare 4 bytes */ - return; - if((unsigned short)frame[12] != 0) /* Compare 2 bytes */ - return; - - SRBit = frame[8] & 0x80; - memcpy(&frame[8], hw_addr, 6); - frame[8] |= SRBit; -} - -/* - * The timer routine: Check if adapter still open and working, reopen if not. - */ -static void tms380tr_timer_chk(unsigned long data) -{ - struct net_device *dev = (struct net_device*)data; - struct net_local *tp = netdev_priv(dev); - - if(tp->HaltInProgress) - return; - - tms380tr_chk_outstanding_cmds(dev); - if(time_before(tp->LastSendTime + SEND_TIMEOUT, jiffies) && - (tp->TplFree != tp->TplBusy)) - { - /* Anything to send, but stalled too long */ - tp->LastSendTime = jiffies; - tms380tr_exec_cmd(dev, OC_CLOSE); /* Does reopen automatically */ - } - - tp->timer.expires = jiffies + 2*HZ; - add_timer(&tp->timer); - - if(tp->AdapterOpenFlag || tp->ReOpenInProgress) - return; - tp->ReOpenInProgress = 1; - tms380tr_open_adapter(dev); -} - -/* - * The typical workload of the driver: Handle the network interface interrupts. - */ -irqreturn_t tms380tr_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct net_local *tp; - unsigned short irq_type; - int handled = 0; - - tp = netdev_priv(dev); - - irq_type = SIFREADW(SIFSTS); - - while(irq_type & STS_SYSTEM_IRQ) { - handled = 1; - irq_type &= STS_IRQ_MASK; - - if(!tms380tr_chk_ssb(tp, irq_type)) { - printk(KERN_DEBUG "%s: DATA LATE occurred\n", dev->name); - break; - } - - switch(irq_type) { - case STS_IRQ_RECEIVE_STATUS: - tms380tr_reset_interrupt(dev); - tms380tr_rcv_status_irq(dev); - break; - - case STS_IRQ_TRANSMIT_STATUS: - /* Check if TRANSMIT.HALT command is complete */ - if(tp->ssb.Parm[0] & COMMAND_COMPLETE) { - tp->TransmitCommandActive = 0; - tp->TransmitHaltScheduled = 0; - - /* Issue a new transmit command. */ - tms380tr_exec_cmd(dev, OC_TRANSMIT); - } - - tms380tr_reset_interrupt(dev); - tms380tr_tx_status_irq(dev); - break; - - case STS_IRQ_COMMAND_STATUS: - /* The SSB contains status of last command - * other than receive/transmit. - */ - tms380tr_cmd_status_irq(dev); - break; - - case STS_IRQ_SCB_CLEAR: - /* The SCB is free for another command. */ - tp->ScbInUse = 0; - tms380tr_chk_outstanding_cmds(dev); - break; - - case STS_IRQ_RING_STATUS: - tms380tr_ring_status_irq(dev); - break; - - case STS_IRQ_ADAPTER_CHECK: - tms380tr_chk_irq(dev); - break; - - case STS_IRQ_LLC_STATUS: - printk(KERN_DEBUG "tms380tr: unexpected LLC status IRQ\n"); - break; - - case STS_IRQ_TIMER: - printk(KERN_DEBUG "tms380tr: unexpected Timer IRQ\n"); - break; - - case STS_IRQ_RECEIVE_PENDING: - printk(KERN_DEBUG "tms380tr: unexpected Receive Pending IRQ\n"); - break; - - default: - printk(KERN_DEBUG "Unknown Token Ring IRQ (0x%04x)\n", irq_type); - break; - } - - /* Reset system interrupt if not already done. */ - if(irq_type != STS_IRQ_TRANSMIT_STATUS && - irq_type != STS_IRQ_RECEIVE_STATUS) { - tms380tr_reset_interrupt(dev); - } - - irq_type = SIFREADW(SIFSTS); - } - - return IRQ_RETVAL(handled); -} - -/* - * Reset the INTERRUPT SYSTEM bit and issue SSB CLEAR command. - */ -static void tms380tr_reset_interrupt(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - SSB *ssb = &tp->ssb; - - /* - * [Workaround for "Data Late"] - * Set all fields of the SSB to well-defined values so we can - * check if the adapter has written the SSB. - */ - - ssb->STS = (unsigned short) -1; - ssb->Parm[0] = (unsigned short) -1; - ssb->Parm[1] = (unsigned short) -1; - ssb->Parm[2] = (unsigned short) -1; - - /* Free SSB by issuing SSB_CLEAR command after reading IRQ code - * and clear STS_SYSTEM_IRQ bit: enable adapter for further interrupts. - */ - tms380tr_exec_sifcmd(dev, CMD_SSB_CLEAR | CMD_CLEAR_SYSTEM_IRQ); -} - -/* - * Check if the SSB has actually been written by the adapter. - */ -static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqType) -{ - SSB *ssb = &tp->ssb; /* The address of the SSB. */ - - /* C 0 1 2 INTERRUPT CODE - * - - - - -------------- - * 1 1 1 1 TRANSMIT STATUS - * 1 1 1 1 RECEIVE STATUS - * 1 ? ? 0 COMMAND STATUS - * 0 0 0 0 SCB CLEAR - * 1 1 0 0 RING STATUS - * 0 0 0 0 ADAPTER CHECK - * - * 0 = SSB field not affected by interrupt - * 1 = SSB field is affected by interrupt - * - * C = SSB ADDRESS +0: COMMAND - * 0 = SSB ADDRESS +2: STATUS 0 - * 1 = SSB ADDRESS +4: STATUS 1 - * 2 = SSB ADDRESS +6: STATUS 2 - */ - - /* Check if this interrupt does use the SSB. */ - - if(IrqType != STS_IRQ_TRANSMIT_STATUS && - IrqType != STS_IRQ_RECEIVE_STATUS && - IrqType != STS_IRQ_COMMAND_STATUS && - IrqType != STS_IRQ_RING_STATUS) - { - return 1; /* SSB not involved. */ - } - - /* Note: All fields of the SSB have been set to all ones (-1) after it - * has last been used by the software (see DriverIsr()). - * - * Check if the affected SSB fields are still unchanged. - */ - - if(ssb->STS == (unsigned short) -1) - return 0; /* Command field not yet available. */ - if(IrqType == STS_IRQ_COMMAND_STATUS) - return 1; /* Status fields not always affected. */ - if(ssb->Parm[0] == (unsigned short) -1) - return 0; /* Status 1 field not yet available. */ - if(IrqType == STS_IRQ_RING_STATUS) - return 1; /* Status 2 & 3 fields not affected. */ - - /* Note: At this point, the interrupt is either TRANSMIT or RECEIVE. */ - if(ssb->Parm[1] == (unsigned short) -1) - return 0; /* Status 2 field not yet available. */ - if(ssb->Parm[2] == (unsigned short) -1) - return 0; /* Status 3 field not yet available. */ - - return 1; /* All SSB fields have been written by the adapter. */ -} - -/* - * Evaluates the command results status in the SSB status field. - */ -static void tms380tr_cmd_status_irq(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned short ssb_cmd, ssb_parm_0; - unsigned short ssb_parm_1; - char *open_err = "Open error -"; - char *code_err = "Open code -"; - - /* Copy the ssb values to local variables */ - ssb_cmd = tp->ssb.STS; - ssb_parm_0 = tp->ssb.Parm[0]; - ssb_parm_1 = tp->ssb.Parm[1]; - - if(ssb_cmd == OPEN) - { - tp->Sleeping = 0; - if(!tp->ReOpenInProgress) - wake_up_interruptible(&tp->wait_for_tok_int); - - tp->OpenCommandIssued = 0; - tp->ScbInUse = 0; - - if((ssb_parm_0 & 0x00FF) == GOOD_COMPLETION) - { - /* Success, the adapter is open. */ - tp->LobeWireFaultLogged = 0; - tp->AdapterOpenFlag = 1; - tp->AdapterVirtOpenFlag = 1; - tp->TransmitCommandActive = 0; - tms380tr_exec_cmd(dev, OC_TRANSMIT); - tms380tr_exec_cmd(dev, OC_RECEIVE); - - if(tp->ReOpenInProgress) - tp->ReOpenInProgress = 0; - - return; - } - else /* The adapter did not open. */ - { - if(ssb_parm_0 & NODE_ADDR_ERROR) - printk(KERN_INFO "%s: Node address error\n", - dev->name); - if(ssb_parm_0 & LIST_SIZE_ERROR) - printk(KERN_INFO "%s: List size error\n", - dev->name); - if(ssb_parm_0 & BUF_SIZE_ERROR) - printk(KERN_INFO "%s: Buffer size error\n", - dev->name); - if(ssb_parm_0 & TX_BUF_COUNT_ERROR) - printk(KERN_INFO "%s: Tx buffer count error\n", - dev->name); - if(ssb_parm_0 & INVALID_OPEN_OPTION) - printk(KERN_INFO "%s: Invalid open option\n", - dev->name); - if(ssb_parm_0 & OPEN_ERROR) - { - /* Show the open phase. */ - switch(ssb_parm_0 & OPEN_PHASES_MASK) - { - case LOBE_MEDIA_TEST: - if(!tp->LobeWireFaultLogged) - { - tp->LobeWireFaultLogged = 1; - printk(KERN_INFO "%s: %s Lobe wire fault (check cable !).\n", dev->name, open_err); - } - tp->ReOpenInProgress = 1; - tp->AdapterOpenFlag = 0; - tp->AdapterVirtOpenFlag = 1; - tms380tr_open_adapter(dev); - return; - - case PHYSICAL_INSERTION: - printk(KERN_INFO "%s: %s Physical insertion.\n", dev->name, open_err); - break; - - case ADDRESS_VERIFICATION: - printk(KERN_INFO "%s: %s Address verification.\n", dev->name, open_err); - break; - - case PARTICIPATION_IN_RING_POLL: - printk(KERN_INFO "%s: %s Participation in ring poll.\n", dev->name, open_err); - break; - - case REQUEST_INITIALISATION: - printk(KERN_INFO "%s: %s Request initialisation.\n", dev->name, open_err); - break; - - case FULLDUPLEX_CHECK: - printk(KERN_INFO "%s: %s Full duplex check.\n", dev->name, open_err); - break; - - default: - printk(KERN_INFO "%s: %s Unknown open phase\n", dev->name, open_err); - break; - } - - /* Show the open errors. */ - switch(ssb_parm_0 & OPEN_ERROR_CODES_MASK) - { - case OPEN_FUNCTION_FAILURE: - printk(KERN_INFO "%s: %s OPEN_FUNCTION_FAILURE", dev->name, code_err); - tp->LastOpenStatus = - OPEN_FUNCTION_FAILURE; - break; - - case OPEN_SIGNAL_LOSS: - printk(KERN_INFO "%s: %s OPEN_SIGNAL_LOSS\n", dev->name, code_err); - tp->LastOpenStatus = - OPEN_SIGNAL_LOSS; - break; - - case OPEN_TIMEOUT: - printk(KERN_INFO "%s: %s OPEN_TIMEOUT\n", dev->name, code_err); - tp->LastOpenStatus = - OPEN_TIMEOUT; - break; - - case OPEN_RING_FAILURE: - printk(KERN_INFO "%s: %s OPEN_RING_FAILURE\n", dev->name, code_err); - tp->LastOpenStatus = - OPEN_RING_FAILURE; - break; - - case OPEN_RING_BEACONING: - printk(KERN_INFO "%s: %s OPEN_RING_BEACONING\n", dev->name, code_err); - tp->LastOpenStatus = - OPEN_RING_BEACONING; - break; - - case OPEN_DUPLICATE_NODEADDR: - printk(KERN_INFO "%s: %s OPEN_DUPLICATE_NODEADDR\n", dev->name, code_err); - tp->LastOpenStatus = - OPEN_DUPLICATE_NODEADDR; - break; - - case OPEN_REQUEST_INIT: - printk(KERN_INFO "%s: %s OPEN_REQUEST_INIT\n", dev->name, code_err); - tp->LastOpenStatus = - OPEN_REQUEST_INIT; - break; - - case OPEN_REMOVE_RECEIVED: - printk(KERN_INFO "%s: %s OPEN_REMOVE_RECEIVED", dev->name, code_err); - tp->LastOpenStatus = - OPEN_REMOVE_RECEIVED; - break; - - case OPEN_FULLDUPLEX_SET: - printk(KERN_INFO "%s: %s OPEN_FULLDUPLEX_SET\n", dev->name, code_err); - tp->LastOpenStatus = - OPEN_FULLDUPLEX_SET; - break; - - default: - printk(KERN_INFO "%s: %s Unknown open err code", dev->name, code_err); - tp->LastOpenStatus = - OPEN_FUNCTION_FAILURE; - break; - } - } - - tp->AdapterOpenFlag = 0; - tp->AdapterVirtOpenFlag = 0; - - return; - } - } - else - { - if(ssb_cmd != READ_ERROR_LOG) - return; - - /* Add values from the error log table to the MAC - * statistics counters and update the errorlogtable - * memory. - */ - tp->MacStat.line_errors += tp->errorlogtable.Line_Error; - tp->MacStat.burst_errors += tp->errorlogtable.Burst_Error; - tp->MacStat.A_C_errors += tp->errorlogtable.ARI_FCI_Error; - tp->MacStat.lost_frames += tp->errorlogtable.Lost_Frame_Error; - tp->MacStat.recv_congest_count += tp->errorlogtable.Rx_Congest_Error; - tp->MacStat.rx_errors += tp->errorlogtable.Rx_Congest_Error; - tp->MacStat.frame_copied_errors += tp->errorlogtable.Frame_Copied_Error; - tp->MacStat.token_errors += tp->errorlogtable.Token_Error; - tp->MacStat.dummy1 += tp->errorlogtable.DMA_Bus_Error; - tp->MacStat.dummy1 += tp->errorlogtable.DMA_Parity_Error; - tp->MacStat.abort_delimiters += tp->errorlogtable.AbortDelimeters; - tp->MacStat.frequency_errors += tp->errorlogtable.Frequency_Error; - tp->MacStat.internal_errors += tp->errorlogtable.Internal_Error; - } -} - -/* - * The inverse routine to tms380tr_open(). - */ -int tms380tr_close(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - netif_stop_queue(dev); - - del_timer(&tp->timer); - - /* Flush the Tx and disable Rx here. */ - - tp->HaltInProgress = 1; - tms380tr_exec_cmd(dev, OC_CLOSE); - tp->timer.expires = jiffies + 1*HZ; - tp->timer.function = tms380tr_timer_end_wait; - tp->timer.data = (unsigned long)dev; - add_timer(&tp->timer); - - tms380tr_enable_interrupts(dev); - - tp->Sleeping = 1; - interruptible_sleep_on(&tp->wait_for_tok_int); - tp->TransmitCommandActive = 0; - - del_timer(&tp->timer); - tms380tr_disable_interrupts(dev); - -#if defined(CONFIG_ISA) && defined(CONFIG_ISA_DMA_API) - if(dev->dma > 0) - { - unsigned long flags=claim_dma_lock(); - disable_dma(dev->dma); - release_dma_lock(flags); - } -#endif - - SIFWRITEW(0xFF00, SIFCMD); -#if 0 - if(dev->dma > 0) /* what the? */ - SIFWRITEB(0xff, POSREG); -#endif - tms380tr_cancel_tx_queue(tp); - - return 0; -} - -/* - * Get the current statistics. This may be called with the card open - * or closed. - */ -static struct net_device_stats *tms380tr_get_stats(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - - return (struct net_device_stats *)&tp->MacStat; -} - -/* - * Set or clear the multicast filter for this adapter. - */ -static void tms380tr_set_multicast_list(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned int OpenOptions; - - OpenOptions = tp->ocpl.OPENOptions & - ~(PASS_ADAPTER_MAC_FRAMES - | PASS_ATTENTION_FRAMES - | PASS_BEACON_MAC_FRAMES - | COPY_ALL_MAC_FRAMES - | COPY_ALL_NON_MAC_FRAMES); - - tp->ocpl.FunctAddr = 0; - - if(dev->flags & IFF_PROMISC) - /* Enable promiscuous mode */ - OpenOptions |= COPY_ALL_NON_MAC_FRAMES | - COPY_ALL_MAC_FRAMES; - else - { - if(dev->flags & IFF_ALLMULTI) - { - /* Disable promiscuous mode, use normal mode. */ - tp->ocpl.FunctAddr = 0xFFFFFFFF; - } - else - { - struct netdev_hw_addr *ha; - - netdev_for_each_mc_addr(ha, dev) { - ((char *)(&tp->ocpl.FunctAddr))[0] |= - ha->addr[2]; - ((char *)(&tp->ocpl.FunctAddr))[1] |= - ha->addr[3]; - ((char *)(&tp->ocpl.FunctAddr))[2] |= - ha->addr[4]; - ((char *)(&tp->ocpl.FunctAddr))[3] |= - ha->addr[5]; - } - } - tms380tr_exec_cmd(dev, OC_SET_FUNCT_ADDR); - } - - tp->ocpl.OPENOptions = OpenOptions; - tms380tr_exec_cmd(dev, OC_MODIFY_OPEN_PARMS); -} - -/* - * Wait for some time (microseconds) - */ -void tms380tr_wait(unsigned long time) -{ -#if 0 - long tmp; - - tmp = jiffies + time/(1000000/HZ); - do { - tmp = schedule_timeout_interruptible(tmp); - } while(time_after(tmp, jiffies)); -#else - mdelay(time / 1000); -#endif -} - -/* - * Write a command value to the SIFCMD register - */ -static void tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue) -{ - unsigned short cmd; - unsigned short SifStsValue; - unsigned long loop_counter; - - WriteValue = ((WriteValue ^ CMD_SYSTEM_IRQ) | CMD_INTERRUPT_ADAPTER); - cmd = (unsigned short)WriteValue; - loop_counter = 0,5 * 800000; - do { - SifStsValue = SIFREADW(SIFSTS); - } while((SifStsValue & CMD_INTERRUPT_ADAPTER) && loop_counter--); - SIFWRITEW(cmd, SIFCMD); -} - -/* - * Processes adapter hardware reset, halts adapter and downloads firmware, - * clears the halt bit. - */ -static int tms380tr_reset_adapter(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned short *fw_ptr; - unsigned short count, c, count2; - const struct firmware *fw_entry = NULL; - - if (request_firmware(&fw_entry, "tms380tr.bin", tp->pdev) != 0) { - printk(KERN_ALERT "%s: firmware %s is missing, cannot start.\n", - dev->name, "tms380tr.bin"); - return -1; - } - - fw_ptr = (unsigned short *)fw_entry->data; - count2 = fw_entry->size / 2; - - /* Hardware adapter reset */ - SIFWRITEW(ACL_ARESET, SIFACL); - tms380tr_wait(40); - - c = SIFREADW(SIFACL); - tms380tr_wait(20); - - if(dev->dma == 0) /* For PCI adapters */ - { - c &= ~(ACL_NSELOUT0 | ACL_NSELOUT1); /* Clear bits */ - if(tp->setnselout) - c |= (*tp->setnselout)(dev); - } - - /* In case a command is pending - forget it */ - tp->ScbInUse = 0; - - c &= ~ACL_ARESET; /* Clear adapter reset bit */ - c |= ACL_CPHALT; /* Halt adapter CPU, allow download */ - c |= ACL_BOOT; - c |= ACL_SINTEN; - c &= ~ACL_PSDMAEN; /* Clear pseudo dma bit */ - SIFWRITEW(c, SIFACL); - tms380tr_wait(40); - - count = 0; - /* Download firmware via DIO interface: */ - do { - if (count2 < 3) continue; - - /* Download first address part */ - SIFWRITEW(*fw_ptr, SIFADX); - fw_ptr++; - count2--; - /* Download second address part */ - SIFWRITEW(*fw_ptr, SIFADD); - fw_ptr++; - count2--; - - if((count = *fw_ptr) != 0) /* Load loop counter */ - { - fw_ptr++; /* Download block data */ - count2--; - if (count > count2) continue; - - for(; count > 0; count--) - { - SIFWRITEW(*fw_ptr, SIFINC); - fw_ptr++; - count2--; - } - } - else /* Stop, if last block downloaded */ - { - c = SIFREADW(SIFACL); - c &= (~ACL_CPHALT | ACL_SINTEN); - - /* Clear CPHALT and start BUD */ - SIFWRITEW(c, SIFACL); - release_firmware(fw_entry); - return 1; - } - } while(count == 0); - - release_firmware(fw_entry); - printk(KERN_INFO "%s: Adapter Download Failed\n", dev->name); - return -1; -} - -MODULE_FIRMWARE("tms380tr.bin"); - -/* - * Starts bring up diagnostics of token ring adapter and evaluates - * diagnostic results. - */ -static int tms380tr_bringup_diags(struct net_device *dev) -{ - int loop_cnt, retry_cnt; - unsigned short Status; - - tms380tr_wait(HALF_SECOND); - tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET); - tms380tr_wait(HALF_SECOND); - - retry_cnt = BUD_MAX_RETRIES; /* maximal number of retrys */ - - do { - retry_cnt--; - if(tms380tr_debug > 3) - printk(KERN_DEBUG "BUD-Status: "); - loop_cnt = BUD_MAX_LOOPCNT; /* maximum: three seconds*/ - do { /* Inspect BUD results */ - loop_cnt--; - tms380tr_wait(HALF_SECOND); - Status = SIFREADW(SIFSTS); - Status &= STS_MASK; - - if(tms380tr_debug > 3) - printk(KERN_DEBUG " %04X\n", Status); - /* BUD successfully completed */ - if(Status == STS_INITIALIZE) - return 1; - /* Unrecoverable hardware error, BUD not completed? */ - } while((loop_cnt > 0) && ((Status & (STS_ERROR | STS_TEST)) - != (STS_ERROR | STS_TEST))); - - /* Error preventing completion of BUD */ - if(retry_cnt > 0) - { - printk(KERN_INFO "%s: Adapter Software Reset.\n", - dev->name); - tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET); - tms380tr_wait(HALF_SECOND); - } - } while(retry_cnt > 0); - - Status = SIFREADW(SIFSTS); - - printk(KERN_INFO "%s: Hardware error\n", dev->name); - /* Hardware error occurred! */ - Status &= 0x001f; - if (Status & 0x0010) - printk(KERN_INFO "%s: BUD Error: Timeout\n", dev->name); - else if ((Status & 0x000f) > 6) - printk(KERN_INFO "%s: BUD Error: Illegal Failure\n", dev->name); - else - printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n", dev->name, Status & 0x000f); - - return -1; -} - -/* - * Copy initialisation data to adapter memory, beginning at address - * 1:0A00; Starting DMA test and evaluating result bits. - */ -static int tms380tr_init_adapter(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - - const unsigned char SCB_Test[6] = {0x00, 0x00, 0xC1, 0xE2, 0xD4, 0x8B}; - const unsigned char SSB_Test[8] = {0xFF, 0xFF, 0xD1, 0xD7, - 0xC5, 0xD9, 0xC3, 0xD4}; - void *ptr = (void *)&tp->ipb; - unsigned short *ipb_ptr = (unsigned short *)ptr; - unsigned char *cb_ptr = (unsigned char *) &tp->scb; - unsigned char *sb_ptr = (unsigned char *) &tp->ssb; - unsigned short Status; - int i, loop_cnt, retry_cnt; - - /* Normalize: byte order low/high, word order high/low! (only IPB!) */ - tp->ipb.SCB_Addr = SWAPW(((char *)&tp->scb - (char *)tp) + tp->dmabuffer); - tp->ipb.SSB_Addr = SWAPW(((char *)&tp->ssb - (char *)tp) + tp->dmabuffer); - - if(tms380tr_debug > 3) - { - printk(KERN_DEBUG "%s: buffer (real): %lx\n", dev->name, (long) &tp->scb); - printk(KERN_DEBUG "%s: buffer (virt): %lx\n", dev->name, (long) ((char *)&tp->scb - (char *)tp) + (long) tp->dmabuffer); - printk(KERN_DEBUG "%s: buffer (DMA) : %lx\n", dev->name, (long) tp->dmabuffer); - printk(KERN_DEBUG "%s: buffer (tp) : %lx\n", dev->name, (long) tp); - } - /* Maximum: three initialization retries */ - retry_cnt = INIT_MAX_RETRIES; - - do { - retry_cnt--; - - /* Transfer initialization block */ - SIFWRITEW(0x0001, SIFADX); - - /* To address 0001:0A00 of adapter RAM */ - SIFWRITEW(0x0A00, SIFADD); - - /* Write 11 words to adapter RAM */ - for(i = 0; i < 11; i++) - SIFWRITEW(ipb_ptr[i], SIFINC); - - /* Execute SCB adapter command */ - tms380tr_exec_sifcmd(dev, CMD_EXECUTE); - - loop_cnt = INIT_MAX_LOOPCNT; /* Maximum: 11 seconds */ - - /* While remaining retries, no error and not completed */ - do { - Status = 0; - loop_cnt--; - tms380tr_wait(HALF_SECOND); - - /* Mask interesting status bits */ - Status = SIFREADW(SIFSTS); - Status &= STS_MASK; - } while(((Status &(STS_INITIALIZE | STS_ERROR | STS_TEST)) != 0) && - ((Status & STS_ERROR) == 0) && (loop_cnt != 0)); - - if((Status & (STS_INITIALIZE | STS_ERROR | STS_TEST)) == 0) - { - /* Initialization completed without error */ - i = 0; - do { /* Test if contents of SCB is valid */ - if(SCB_Test[i] != *(cb_ptr + i)) - { - printk(KERN_INFO "%s: DMA failed\n", dev->name); - /* DMA data error: wrong data in SCB */ - return -1; - } - i++; - } while(i < 6); - - i = 0; - do { /* Test if contents of SSB is valid */ - if(SSB_Test[i] != *(sb_ptr + i)) - /* DMA data error: wrong data in SSB */ - return -1; - i++; - } while (i < 8); - - return 1; /* Adapter successfully initialized */ - } - else - { - if((Status & STS_ERROR) != 0) - { - /* Initialization error occurred */ - Status = SIFREADW(SIFSTS); - Status &= STS_ERROR_MASK; - /* ShowInitialisationErrorCode(Status); */ - printk(KERN_INFO "%s: Status error: %d\n", dev->name, Status); - return -1; /* Unrecoverable error */ - } - else - { - if(retry_cnt > 0) - { - /* Reset adapter and try init again */ - tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET); - tms380tr_wait(HALF_SECOND); - } - } - } - } while(retry_cnt > 0); - - printk(KERN_INFO "%s: Retry exceeded\n", dev->name); - return -1; -} - -/* - * Check for outstanding commands in command queue and tries to execute - * command immediately. Corresponding command flag in command queue is cleared. - */ -static void tms380tr_chk_outstanding_cmds(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned long Addr = 0; - - if(tp->CMDqueue == 0) - return; /* No command execution */ - - /* If SCB in use: no command */ - if(tp->ScbInUse == 1) - return; - - /* Check if adapter is opened, avoiding COMMAND_REJECT - * interrupt by the adapter! - */ - if (tp->AdapterOpenFlag == 0) { - if (tp->CMDqueue & OC_OPEN) { - /* Execute OPEN command */ - tp->CMDqueue ^= OC_OPEN; - - Addr = htonl(((char *)&tp->ocpl - (char *)tp) + tp->dmabuffer); - tp->scb.Parm[0] = LOWORD(Addr); - tp->scb.Parm[1] = HIWORD(Addr); - tp->scb.CMD = OPEN; - } else - /* No OPEN command queued, but adapter closed. Note: - * We'll try to re-open the adapter in DriverPoll() - */ - return; /* No adapter command issued */ - } else { - /* Adapter is open; evaluate command queue: try to execute - * outstanding commands (depending on priority!) CLOSE - * command queued - */ - if (tp->CMDqueue & OC_CLOSE) { - tp->CMDqueue ^= OC_CLOSE; - tp->AdapterOpenFlag = 0; - tp->scb.Parm[0] = 0; /* Parm[0], Parm[1] are ignored */ - tp->scb.Parm[1] = 0; /* but should be set to zero! */ - tp->scb.CMD = CLOSE; - if(!tp->HaltInProgress) - tp->CMDqueue |= OC_OPEN; /* re-open adapter */ - else - tp->CMDqueue = 0; /* no more commands */ - } else if (tp->CMDqueue & OC_RECEIVE) { - tp->CMDqueue ^= OC_RECEIVE; - Addr = htonl(((char *)tp->RplHead - (char *)tp) + tp->dmabuffer); - tp->scb.Parm[0] = LOWORD(Addr); - tp->scb.Parm[1] = HIWORD(Addr); - tp->scb.CMD = RECEIVE; - } else if (tp->CMDqueue & OC_TRANSMIT_HALT) { - /* NOTE: TRANSMIT.HALT must be checked - * before TRANSMIT. - */ - tp->CMDqueue ^= OC_TRANSMIT_HALT; - tp->scb.CMD = TRANSMIT_HALT; - - /* Parm[0] and Parm[1] are ignored - * but should be set to zero! - */ - tp->scb.Parm[0] = 0; - tp->scb.Parm[1] = 0; - } else if (tp->CMDqueue & OC_TRANSMIT) { - /* NOTE: TRANSMIT must be - * checked after TRANSMIT.HALT - */ - if (tp->TransmitCommandActive) { - if (!tp->TransmitHaltScheduled) { - tp->TransmitHaltScheduled = 1; - tms380tr_exec_cmd(dev, OC_TRANSMIT_HALT); - } - tp->TransmitCommandActive = 0; - return; - } - - tp->CMDqueue ^= OC_TRANSMIT; - tms380tr_cancel_tx_queue(tp); - Addr = htonl(((char *)tp->TplBusy - (char *)tp) + tp->dmabuffer); - tp->scb.Parm[0] = LOWORD(Addr); - tp->scb.Parm[1] = HIWORD(Addr); - tp->scb.CMD = TRANSMIT; - tp->TransmitCommandActive = 1; - } else if (tp->CMDqueue & OC_MODIFY_OPEN_PARMS) { - tp->CMDqueue ^= OC_MODIFY_OPEN_PARMS; - tp->scb.Parm[0] = tp->ocpl.OPENOptions; /* new OPEN options*/ - tp->scb.Parm[0] |= ENABLE_FULL_DUPLEX_SELECTION; - tp->scb.Parm[1] = 0; /* is ignored but should be zero */ - tp->scb.CMD = MODIFY_OPEN_PARMS; - } else if (tp->CMDqueue & OC_SET_FUNCT_ADDR) { - tp->CMDqueue ^= OC_SET_FUNCT_ADDR; - tp->scb.Parm[0] = LOWORD(tp->ocpl.FunctAddr); - tp->scb.Parm[1] = HIWORD(tp->ocpl.FunctAddr); - tp->scb.CMD = SET_FUNCT_ADDR; - } else if (tp->CMDqueue & OC_SET_GROUP_ADDR) { - tp->CMDqueue ^= OC_SET_GROUP_ADDR; - tp->scb.Parm[0] = LOWORD(tp->ocpl.GroupAddr); - tp->scb.Parm[1] = HIWORD(tp->ocpl.GroupAddr); - tp->scb.CMD = SET_GROUP_ADDR; - } else if (tp->CMDqueue & OC_READ_ERROR_LOG) { - tp->CMDqueue ^= OC_READ_ERROR_LOG; - Addr = htonl(((char *)&tp->errorlogtable - (char *)tp) + tp->dmabuffer); - tp->scb.Parm[0] = LOWORD(Addr); - tp->scb.Parm[1] = HIWORD(Addr); - tp->scb.CMD = READ_ERROR_LOG; - } else { - printk(KERN_WARNING "CheckForOutstandingCommand: unknown Command\n"); - tp->CMDqueue = 0; - return; - } - } - - tp->ScbInUse = 1; /* Set semaphore: SCB in use. */ - - /* Execute SCB and generate IRQ when done. */ - tms380tr_exec_sifcmd(dev, CMD_EXECUTE | CMD_SCB_REQUEST); -} - -/* - * IRQ conditions: signal loss on the ring, transmit or receive of beacon - * frames (disabled if bit 1 of OPEN option is set); report error MAC - * frame transmit (disabled if bit 2 of OPEN option is set); open or short - * circuit fault on the lobe is detected; remove MAC frame received; - * error counter overflow (255); opened adapter is the only station in ring. - * After some of the IRQs the adapter is closed! - */ -static void tms380tr_ring_status_irq(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - - tp->CurrentRingStatus = be16_to_cpu((unsigned short)tp->ssb.Parm[0]); - - /* First: fill up statistics */ - if(tp->ssb.Parm[0] & SIGNAL_LOSS) - { - printk(KERN_INFO "%s: Signal Loss\n", dev->name); - tp->MacStat.line_errors++; - } - - /* Adapter is closed, but initialized */ - if(tp->ssb.Parm[0] & LOBE_WIRE_FAULT) - { - printk(KERN_INFO "%s: Lobe Wire Fault, Reopen Adapter\n", - dev->name); - tp->MacStat.line_errors++; - } - - if(tp->ssb.Parm[0] & RING_RECOVERY) - printk(KERN_INFO "%s: Ring Recovery\n", dev->name); - - /* Counter overflow: read error log */ - if(tp->ssb.Parm[0] & COUNTER_OVERFLOW) - { - printk(KERN_INFO "%s: Counter Overflow\n", dev->name); - tms380tr_exec_cmd(dev, OC_READ_ERROR_LOG); - } - - /* Adapter is closed, but initialized */ - if(tp->ssb.Parm[0] & REMOVE_RECEIVED) - printk(KERN_INFO "%s: Remove Received, Reopen Adapter\n", - dev->name); - - /* Adapter is closed, but initialized */ - if(tp->ssb.Parm[0] & AUTO_REMOVAL_ERROR) - printk(KERN_INFO "%s: Auto Removal Error, Reopen Adapter\n", - dev->name); - - if(tp->ssb.Parm[0] & HARD_ERROR) - printk(KERN_INFO "%s: Hard Error\n", dev->name); - - if(tp->ssb.Parm[0] & SOFT_ERROR) - printk(KERN_INFO "%s: Soft Error\n", dev->name); - - if(tp->ssb.Parm[0] & TRANSMIT_BEACON) - printk(KERN_INFO "%s: Transmit Beacon\n", dev->name); - - if(tp->ssb.Parm[0] & SINGLE_STATION) - printk(KERN_INFO "%s: Single Station\n", dev->name); - - /* Check if adapter has been closed */ - if(tp->ssb.Parm[0] & ADAPTER_CLOSED) - { - printk(KERN_INFO "%s: Adapter closed (Reopening)," - "CurrentRingStat %x\n", - dev->name, tp->CurrentRingStatus); - tp->AdapterOpenFlag = 0; - tms380tr_open_adapter(dev); - } -} - -/* - * Issued if adapter has encountered an unrecoverable hardware - * or software error. - */ -static void tms380tr_chk_irq(struct net_device *dev) -{ - int i; - unsigned short AdapterCheckBlock[4]; - struct net_local *tp = netdev_priv(dev); - - tp->AdapterOpenFlag = 0; /* Adapter closed now */ - - /* Page number of adapter memory */ - SIFWRITEW(0x0001, SIFADX); - /* Address offset */ - SIFWRITEW(CHECKADDR, SIFADR); - - /* Reading 8 byte adapter check block. */ - for(i = 0; i < 4; i++) - AdapterCheckBlock[i] = SIFREADW(SIFINC); - - if(tms380tr_debug > 3) - { - printk(KERN_DEBUG "%s: AdapterCheckBlock: ", dev->name); - for (i = 0; i < 4; i++) - printk("%04X", AdapterCheckBlock[i]); - printk("\n"); - } - - switch(AdapterCheckBlock[0]) - { - case DIO_PARITY: - printk(KERN_INFO "%s: DIO parity error\n", dev->name); - break; - - case DMA_READ_ABORT: - printk(KERN_INFO "%s DMA read operation aborted:\n", - dev->name); - switch (AdapterCheckBlock[1]) - { - case 0: - printk(KERN_INFO "Timeout\n"); - printk(KERN_INFO "Address: %04X %04X\n", - AdapterCheckBlock[2], - AdapterCheckBlock[3]); - break; - - case 1: - printk(KERN_INFO "Parity error\n"); - printk(KERN_INFO "Address: %04X %04X\n", - AdapterCheckBlock[2], - AdapterCheckBlock[3]); - break; - - case 2: - printk(KERN_INFO "Bus error\n"); - printk(KERN_INFO "Address: %04X %04X\n", - AdapterCheckBlock[2], - AdapterCheckBlock[3]); - break; - - default: - printk(KERN_INFO "Unknown error.\n"); - break; - } - break; - - case DMA_WRITE_ABORT: - printk(KERN_INFO "%s: DMA write operation aborted:\n", - dev->name); - switch (AdapterCheckBlock[1]) - { - case 0: - printk(KERN_INFO "Timeout\n"); - printk(KERN_INFO "Address: %04X %04X\n", - AdapterCheckBlock[2], - AdapterCheckBlock[3]); - break; - - case 1: - printk(KERN_INFO "Parity error\n"); - printk(KERN_INFO "Address: %04X %04X\n", - AdapterCheckBlock[2], - AdapterCheckBlock[3]); - break; - - case 2: - printk(KERN_INFO "Bus error\n"); - printk(KERN_INFO "Address: %04X %04X\n", - AdapterCheckBlock[2], - AdapterCheckBlock[3]); - break; - - default: - printk(KERN_INFO "Unknown error.\n"); - break; - } - break; - - case ILLEGAL_OP_CODE: - printk(KERN_INFO "%s: Illegal operation code in firmware\n", - dev->name); - /* Parm[0-3]: adapter internal register R13-R15 */ - break; - - case PARITY_ERRORS: - printk(KERN_INFO "%s: Adapter internal bus parity error\n", - dev->name); - /* Parm[0-3]: adapter internal register R13-R15 */ - break; - - case RAM_DATA_ERROR: - printk(KERN_INFO "%s: RAM data error\n", dev->name); - /* Parm[0-1]: MSW/LSW address of RAM location. */ - break; - - case RAM_PARITY_ERROR: - printk(KERN_INFO "%s: RAM parity error\n", dev->name); - /* Parm[0-1]: MSW/LSW address of RAM location. */ - break; - - case RING_UNDERRUN: - printk(KERN_INFO "%s: Internal DMA underrun detected\n", - dev->name); - break; - - case INVALID_IRQ: - printk(KERN_INFO "%s: Unrecognized interrupt detected\n", - dev->name); - /* Parm[0-3]: adapter internal register R13-R15 */ - break; - - case INVALID_ERROR_IRQ: - printk(KERN_INFO "%s: Unrecognized error interrupt detected\n", - dev->name); - /* Parm[0-3]: adapter internal register R13-R15 */ - break; - - case INVALID_XOP: - printk(KERN_INFO "%s: Unrecognized XOP request detected\n", - dev->name); - /* Parm[0-3]: adapter internal register R13-R15 */ - break; - - default: - printk(KERN_INFO "%s: Unknown status", dev->name); - break; - } - - if(tms380tr_chipset_init(dev) == 1) - { - /* Restart of firmware successful */ - tp->AdapterOpenFlag = 1; - } -} - -/* - * Internal adapter pointer to RAM data are copied from adapter into - * host system. - */ -static int tms380tr_read_ptr(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned short adapterram; - - tms380tr_read_ram(dev, (unsigned char *)&tp->intptrs.BurnedInAddrPtr, - ADAPTER_INT_PTRS, 16); - tms380tr_read_ram(dev, (unsigned char *)&adapterram, - cpu_to_be16((unsigned short)tp->intptrs.AdapterRAMPtr), 2); - return be16_to_cpu(adapterram); -} - -/* - * Reads a number of bytes from adapter to system memory. - */ -static void tms380tr_read_ram(struct net_device *dev, unsigned char *Data, - unsigned short Address, int Length) -{ - int i; - unsigned short old_sifadx, old_sifadr, InWord; - - /* Save the current values */ - old_sifadx = SIFREADW(SIFADX); - old_sifadr = SIFREADW(SIFADR); - - /* Page number of adapter memory */ - SIFWRITEW(0x0001, SIFADX); - /* Address offset in adapter RAM */ - SIFWRITEW(Address, SIFADR); - - /* Copy len byte from adapter memory to system data area. */ - i = 0; - for(;;) - { - InWord = SIFREADW(SIFINC); - - *(Data + i) = HIBYTE(InWord); /* Write first byte */ - if(++i == Length) /* All is done break */ - break; - - *(Data + i) = LOBYTE(InWord); /* Write second byte */ - if (++i == Length) /* All is done break */ - break; - } - - /* Restore original values */ - SIFWRITEW(old_sifadx, SIFADX); - SIFWRITEW(old_sifadr, SIFADR); -} - -/* - * Cancel all queued packets in the transmission queue. - */ -static void tms380tr_cancel_tx_queue(struct net_local* tp) -{ - TPL *tpl; - - /* - * NOTE: There must not be an active TRANSMIT command pending, when - * this function is called. - */ - if(tp->TransmitCommandActive) - return; - - for(;;) - { - tpl = tp->TplBusy; - if(!tpl->BusyFlag) - break; - /* "Remove" TPL from busy list. */ - tp->TplBusy = tpl->NextTPLPtr; - tms380tr_write_tpl_status(tpl, 0); /* Clear VALID bit */ - tpl->BusyFlag = 0; /* "free" TPL */ - - printk(KERN_INFO "Cancel tx (%08lXh).\n", (unsigned long)tpl); - if (tpl->DMABuff) - dma_unmap_single(tp->pdev, tpl->DMABuff, tpl->Skb->len, DMA_TO_DEVICE); - dev_kfree_skb_any(tpl->Skb); - } -} - -/* - * This function is called whenever a transmit interrupt is generated by the - * adapter. For a command complete interrupt, it is checked if we have to - * issue a new transmit command or not. - */ -static void tms380tr_tx_status_irq(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned char HighByte, HighAc, LowAc; - TPL *tpl; - - /* NOTE: At this point the SSB from TRANSMIT STATUS is no longer - * available, because the CLEAR SSB command has already been issued. - * - * Process all complete transmissions. - */ - - for(;;) - { - tpl = tp->TplBusy; - if(!tpl->BusyFlag || (tpl->Status - & (TX_VALID | TX_FRAME_COMPLETE)) - != TX_FRAME_COMPLETE) - { - break; - } - - /* "Remove" TPL from busy list. */ - tp->TplBusy = tpl->NextTPLPtr ; - - /* Check the transmit status field only for directed frames*/ - if(DIRECTED_FRAME(tpl) && (tpl->Status & TX_ERROR) == 0) - { - HighByte = GET_TRANSMIT_STATUS_HIGH_BYTE(tpl->Status); - HighAc = GET_FRAME_STATUS_HIGH_AC(HighByte); - LowAc = GET_FRAME_STATUS_LOW_AC(HighByte); - - if((HighAc != LowAc) || (HighAc == AC_NOT_RECOGNIZED)) - { - printk(KERN_DEBUG "%s: (DA=%08lX not recognized)\n", - dev->name, - *(unsigned long *)&tpl->MData[2+2]); - } - else - { - if(tms380tr_debug > 3) - printk(KERN_DEBUG "%s: Directed frame tx'd\n", - dev->name); - } - } - else - { - if(!DIRECTED_FRAME(tpl)) - { - if(tms380tr_debug > 3) - printk(KERN_DEBUG "%s: Broadcast frame tx'd\n", - dev->name); - } - } - - tp->MacStat.tx_packets++; - if (tpl->DMABuff) - dma_unmap_single(tp->pdev, tpl->DMABuff, tpl->Skb->len, DMA_TO_DEVICE); - dev_kfree_skb_irq(tpl->Skb); - tpl->BusyFlag = 0; /* "free" TPL */ - } - - if(!tp->TplFree->NextTPLPtr->BusyFlag) - netif_wake_queue(dev); -} - -/* - * Called if a frame receive interrupt is generated by the adapter. - * Check if the frame is valid and indicate it to system. - */ -static void tms380tr_rcv_status_irq(struct net_device *dev) -{ - struct net_local *tp = netdev_priv(dev); - unsigned char *ReceiveDataPtr; - struct sk_buff *skb; - unsigned int Length, Length2; - RPL *rpl; - RPL *SaveHead; - dma_addr_t dmabuf; - - /* NOTE: At this point the SSB from RECEIVE STATUS is no longer - * available, because the CLEAR SSB command has already been issued. - * - * Process all complete receives. - */ - - for(;;) - { - rpl = tp->RplHead; - if(rpl->Status & RX_VALID) - break; /* RPL still in use by adapter */ - - /* Forward RPLHead pointer to next list. */ - SaveHead = tp->RplHead; - tp->RplHead = rpl->NextRPLPtr; - - /* Get the frame size (Byte swap for Intel). - * Do this early (see workaround comment below) - */ - Length = be16_to_cpu(rpl->FrameSize); - - /* Check if the Frame_Start, Frame_End and - * Frame_Complete bits are set. - */ - if((rpl->Status & VALID_SINGLE_BUFFER_FRAME) - == VALID_SINGLE_BUFFER_FRAME) - { - ReceiveDataPtr = rpl->MData; - - /* Workaround for delayed write of FrameSize on ISA - * (FrameSize is false but valid-bit is reset) - * Frame size is set to zero when the RPL is freed. - * Length2 is there because there have also been - * cases where the FrameSize was partially written - */ - Length2 = be16_to_cpu(rpl->FrameSize); - - if(Length == 0 || Length != Length2) - { - tp->RplHead = SaveHead; - break; /* Return to tms380tr_interrupt */ - } - tms380tr_update_rcv_stats(tp,ReceiveDataPtr,Length); - - if(tms380tr_debug > 3) - printk(KERN_DEBUG "%s: Packet Length %04X (%d)\n", - dev->name, Length, Length); - - /* Indicate the received frame to system the - * adapter does the Source-Routing padding for - * us. See: OpenOptions in tms380tr_init_opb() - */ - skb = rpl->Skb; - if(rpl->SkbStat == SKB_UNAVAILABLE) - { - /* Try again to allocate skb */ - skb = dev_alloc_skb(tp->MaxPacketSize); - if(skb == NULL) - { - /* Update Stats ?? */ - } - else - { - skb_put(skb, tp->MaxPacketSize); - rpl->SkbStat = SKB_DATA_COPY; - ReceiveDataPtr = rpl->MData; - } - } - - if(skb && (rpl->SkbStat == SKB_DATA_COPY || - rpl->SkbStat == SKB_DMA_DIRECT)) - { - if(rpl->SkbStat == SKB_DATA_COPY) - skb_copy_to_linear_data(skb, ReceiveDataPtr, - Length); - - /* Deliver frame to system */ - rpl->Skb = NULL; - skb_trim(skb,Length); - skb->protocol = tr_type_trans(skb,dev); - netif_rx(skb); - } - } - else /* Invalid frame */ - { - if(rpl->Skb != NULL) - dev_kfree_skb_irq(rpl->Skb); - - /* Skip list. */ - if(rpl->Status & RX_START_FRAME) - /* Frame start bit is set -> overflow. */ - tp->MacStat.rx_errors++; - } - if (rpl->DMABuff) - dma_unmap_single(tp->pdev, rpl->DMABuff, tp->MaxPacketSize, DMA_TO_DEVICE); - rpl->DMABuff = 0; - - /* Allocate new skb for rpl */ - rpl->Skb = dev_alloc_skb(tp->MaxPacketSize); - /* skb == NULL ? then use local buffer */ - if(rpl->Skb == NULL) - { - rpl->SkbStat = SKB_UNAVAILABLE; - rpl->FragList[0].DataAddr = htonl(((char *)tp->LocalRxBuffers[rpl->RPLIndex] - (char *)tp) + tp->dmabuffer); - rpl->MData = tp->LocalRxBuffers[rpl->RPLIndex]; - } - else /* skb != NULL */ - { - rpl->Skb->dev = dev; - skb_put(rpl->Skb, tp->MaxPacketSize); - - /* Data unreachable for DMA ? then use local buffer */ - dmabuf = dma_map_single(tp->pdev, rpl->Skb->data, tp->MaxPacketSize, DMA_FROM_DEVICE); - if(tp->dmalimit && (dmabuf + tp->MaxPacketSize > tp->dmalimit)) - { - rpl->SkbStat = SKB_DATA_COPY; - rpl->FragList[0].DataAddr = htonl(((char *)tp->LocalRxBuffers[rpl->RPLIndex] - (char *)tp) + tp->dmabuffer); - rpl->MData = tp->LocalRxBuffers[rpl->RPLIndex]; - } - else - { - /* DMA directly in skb->data */ - rpl->SkbStat = SKB_DMA_DIRECT; - rpl->FragList[0].DataAddr = htonl(dmabuf); - rpl->MData = rpl->Skb->data; - rpl->DMABuff = dmabuf; - } - } - - rpl->FragList[0].DataCount = cpu_to_be16((unsigned short)tp->MaxPacketSize); - rpl->FrameSize = 0; - - /* Pass the last RPL back to the adapter */ - tp->RplTail->FrameSize = 0; - - /* Reset the CSTAT field in the list. */ - tms380tr_write_rpl_status(tp->RplTail, RX_VALID | RX_FRAME_IRQ); - - /* Current RPL becomes last one in list. */ - tp->RplTail = tp->RplTail->NextRPLPtr; - - /* Inform adapter about RPL valid. */ - tms380tr_exec_sifcmd(dev, CMD_RX_VALID); - } -} - -/* - * This function should be used whenever the status of any RPL must be - * modified by the driver, because the compiler may otherwise change the - * order of instructions such that writing the RPL status may be executed - * at an undesirable time. When this function is used, the status is - * always written when the function is called. - */ -static void tms380tr_write_rpl_status(RPL *rpl, unsigned int Status) -{ - rpl->Status = Status; -} - -/* - * The function updates the statistic counters in mac->MacStat. - * It differtiates between directed and broadcast/multicast ( ==functional) - * frames. - */ -static void tms380tr_update_rcv_stats(struct net_local *tp, unsigned char DataPtr[], - unsigned int Length) -{ - tp->MacStat.rx_packets++; - tp->MacStat.rx_bytes += Length; - - /* Test functional bit */ - if(DataPtr[2] & GROUP_BIT) - tp->MacStat.multicast++; -} - -static int tms380tr_set_mac_address(struct net_device *dev, void *addr) -{ - struct net_local *tp = netdev_priv(dev); - struct sockaddr *saddr = addr; - - if (tp->AdapterOpenFlag || tp->AdapterVirtOpenFlag) { - printk(KERN_WARNING "%s: Cannot set MAC/LAA address while card is open\n", dev->name); - return -EIO; - } - memcpy(dev->dev_addr, saddr->sa_data, dev->addr_len); - return 0; -} - -#if TMS380TR_DEBUG > 0 -/* - * Dump Packet (data) - */ -static void tms380tr_dump(unsigned char *Data, int length) -{ - int i, j; - - for (i = 0, j = 0; i < length / 8; i++, j += 8) - { - printk(KERN_DEBUG "%02x %02x %02x %02x %02x %02x %02x %02x\n", - Data[j+0],Data[j+1],Data[j+2],Data[j+3], - Data[j+4],Data[j+5],Data[j+6],Data[j+7]); - } -} -#endif - -void tmsdev_term(struct net_device *dev) -{ - struct net_local *tp; - - tp = netdev_priv(dev); - dma_unmap_single(tp->pdev, tp->dmabuffer, sizeof(struct net_local), - DMA_BIDIRECTIONAL); -} - -const struct net_device_ops tms380tr_netdev_ops = { - .ndo_open = tms380tr_open, - .ndo_stop = tms380tr_close, - .ndo_start_xmit = tms380tr_send_packet, - .ndo_tx_timeout = tms380tr_timeout, - .ndo_get_stats = tms380tr_get_stats, - .ndo_set_rx_mode = tms380tr_set_multicast_list, - .ndo_set_mac_address = tms380tr_set_mac_address, -}; -EXPORT_SYMBOL(tms380tr_netdev_ops); - -int tmsdev_init(struct net_device *dev, struct device *pdev) -{ - struct net_local *tms_local; - - memset(netdev_priv(dev), 0, sizeof(struct net_local)); - tms_local = netdev_priv(dev); - init_waitqueue_head(&tms_local->wait_for_tok_int); - if (pdev->dma_mask) - tms_local->dmalimit = *pdev->dma_mask; - else - return -ENOMEM; - tms_local->pdev = pdev; - tms_local->dmabuffer = dma_map_single(pdev, (void *)tms_local, - sizeof(struct net_local), DMA_BIDIRECTIONAL); - if (tms_local->dmabuffer + sizeof(struct net_local) > - tms_local->dmalimit) - { - printk(KERN_INFO "%s: Memory not accessible for DMA\n", - dev->name); - tmsdev_term(dev); - return -ENOMEM; - } - - dev->netdev_ops = &tms380tr_netdev_ops; - dev->watchdog_timeo = HZ; - - return 0; -} - -EXPORT_SYMBOL(tms380tr_open); -EXPORT_SYMBOL(tms380tr_close); -EXPORT_SYMBOL(tms380tr_interrupt); -EXPORT_SYMBOL(tmsdev_init); -EXPORT_SYMBOL(tmsdev_term); -EXPORT_SYMBOL(tms380tr_wait); - -#ifdef MODULE - -static struct module *TMS380_module = NULL; - -int init_module(void) -{ - printk(KERN_DEBUG "%s", version); - - TMS380_module = &__this_module; - return 0; -} - -void cleanup_module(void) -{ - TMS380_module = NULL; -} -#endif - -MODULE_LICENSE("GPL"); -
diff --git a/drivers/net/tokenring/tms380tr.h b/drivers/net/tokenring/tms380tr.h deleted file mode 100644 index e5a617c..0000000 --- a/drivers/net/tokenring/tms380tr.h +++ /dev/null
@@ -1,1141 +0,0 @@ -/* - * tms380tr.h: TI TMS380 Token Ring driver for Linux - * - * Authors: - * - Christoph Goos <cgoos@syskonnect.de> - * - Adam Fritzler - */ - -#ifndef __LINUX_TMS380TR_H -#define __LINUX_TMS380TR_H - -#ifdef __KERNEL__ - -#include <linux/interrupt.h> - -/* module prototypes */ -extern const struct net_device_ops tms380tr_netdev_ops; -int tms380tr_open(struct net_device *dev); -int tms380tr_close(struct net_device *dev); -irqreturn_t tms380tr_interrupt(int irq, void *dev_id); -int tmsdev_init(struct net_device *dev, struct device *pdev); -void tmsdev_term(struct net_device *dev); -void tms380tr_wait(unsigned long time); - -#define TMS380TR_MAX_ADAPTERS 7 - -#define SEND_TIMEOUT 10*HZ - -#define TR_RCF_LONGEST_FRAME_MASK 0x0070 -#define TR_RCF_FRAME4K 0x0030 - -/*------------------------------------------------------------------*/ -/* Bit order for adapter communication with DMA */ -/* -------------------------------------------------------------- */ -/* Bit 8 | 9| 10| 11|| 12| 13| 14| 15|| 0| 1| 2| 3|| 4| 5| 6| 7| */ -/* -------------------------------------------------------------- */ -/* The bytes in a word must be byte swapped. Also, if a double */ -/* word is used for storage, then the words, as well as the bytes, */ -/* must be swapped. */ -/* Bit order for adapter communication with DIO */ -/* -------------------------------------------------------------- */ -/* Bit 0 | 1| 2| 3|| 4| 5| 6| 7|| 8| 9| 10| 11|| 12| 13| 14| 15| */ -/* -------------------------------------------------------------- */ -/*------------------------------------------------------------------*/ - -/* Swap words of a long. */ -#define SWAPW(x) (((x) << 16) | ((x) >> 16)) - -/* Get the low byte of a word. */ -#define LOBYTE(w) ((unsigned char)(w)) - -/* Get the high byte of a word. */ -#define HIBYTE(w) ((unsigned char)((unsigned short)(w) >> 8)) - -/* Get the low word of a long. */ -#define LOWORD(l) ((unsigned short)(l)) - -/* Get the high word of a long. */ -#define HIWORD(l) ((unsigned short)((unsigned long)(l) >> 16)) - - - -/* Token ring adapter I/O addresses for normal mode. */ - -/* - * The SIF registers. Common to all adapters. - */ -/* Basic SIF (SRSX = 0) */ -#define SIFDAT 0x00 /* SIF/DMA data. */ -#define SIFINC 0x02 /* IO Word data with auto increment. */ -#define SIFINH 0x03 /* IO Byte data with auto increment. */ -#define SIFADR 0x04 /* SIF/DMA Address. */ -#define SIFCMD 0x06 /* SIF Command. */ -#define SIFSTS 0x06 /* SIF Status. */ - -/* "Extended" SIF (SRSX = 1) */ -#define SIFACL 0x08 /* SIF Adapter Control Register. */ -#define SIFADD 0x0a /* SIF/DMA Address. -- 0x0a */ -#define SIFADX 0x0c /* 0x0c */ -#define DMALEN 0x0e /* SIF DMA length. -- 0x0e */ - -/* - * POS Registers. Only for ISA Adapters. - */ -#define POSREG 0x10 /* Adapter Program Option Select (POS) - * Register: base IO address + 16 byte. - */ -#define POSREG_2 24L /* only for TR4/16+ adapter - * base IO address + 24 byte. -- 0x18 - */ - -/* SIFCMD command codes (high-low) */ -#define CMD_INTERRUPT_ADAPTER 0x8000 /* Cause internal adapter interrupt */ -#define CMD_ADAPTER_RESET 0x4000 /* Hardware reset of adapter */ -#define CMD_SSB_CLEAR 0x2000 /* Acknowledge to adapter to - * system interrupts. - */ -#define CMD_EXECUTE 0x1000 /* Execute SCB command */ -#define CMD_SCB_REQUEST 0x0800 /* Request adapter to interrupt - * system when SCB is available for - * another command. - */ -#define CMD_RX_CONTINUE 0x0400 /* Continue receive after odd pointer - * stop. (odd pointer receive method) - */ -#define CMD_RX_VALID 0x0200 /* Now actual RPL is valid. */ -#define CMD_TX_VALID 0x0100 /* Now actual TPL is valid. (valid - * bit receive/transmit method) - */ -#define CMD_SYSTEM_IRQ 0x0080 /* Adapter-to-attached-system - * interrupt is reset. - */ -#define CMD_CLEAR_SYSTEM_IRQ 0x0080 /* Clear SYSTEM_INTERRUPT bit. - * (write: 1=ignore, 0=reset) - */ -#define EXEC_SOFT_RESET 0xFF00 /* adapter soft reset. (restart - * adapter after hardware reset) - */ - - -/* ACL commands (high-low) */ -#define ACL_SWHLDA 0x0800 /* Software hold acknowledge. */ -#define ACL_SWDDIR 0x0400 /* Data transfer direction. */ -#define ACL_SWHRQ 0x0200 /* Pseudo DMA operation. */ -#define ACL_PSDMAEN 0x0100 /* Enable pseudo system DMA. */ -#define ACL_ARESET 0x0080 /* Adapter hardware reset command. - * (held in reset condition as - * long as bit is set) - */ -#define ACL_CPHALT 0x0040 /* Communication processor halt. - * (can only be set while ACL_ARESET - * bit is set; prevents adapter - * processor from executing code while - * downloading firmware) - */ -#define ACL_BOOT 0x0020 -#define ACL_SINTEN 0x0008 /* System interrupt enable/disable - * (1/0): can be written if ACL_ARESET - * is zero. - */ -#define ACL_PEN 0x0004 - -#define ACL_NSELOUT0 0x0002 -#define ACL_NSELOUT1 0x0001 /* NSELOUTx have a card-specific - * meaning for setting ring speed. - */ - -#define PS_DMA_MASK (ACL_SWHRQ | ACL_PSDMAEN) - - -/* SIFSTS register return codes (high-low) */ -#define STS_SYSTEM_IRQ 0x0080 /* Adapter-to-attached-system - * interrupt is valid. - */ -#define STS_INITIALIZE 0x0040 /* INITIALIZE status. (ready to - * initialize) - */ -#define STS_TEST 0x0020 /* TEST status. (BUD not completed) */ -#define STS_ERROR 0x0010 /* ERROR status. (unrecoverable - * HW error occurred) - */ -#define STS_MASK 0x00F0 /* Mask interesting status bits. */ -#define STS_ERROR_MASK 0x000F /* Get Error Code by masking the - * interrupt code bits. - */ -#define ADAPTER_INT_PTRS 0x0A00 /* Address offset of adapter internal - * pointers 01:0a00 (high-low) have to - * be read after init and before open. - */ - - -/* Interrupt Codes (only MAC IRQs) */ -#define STS_IRQ_ADAPTER_CHECK 0x0000 /* unrecoverable hardware or - * software error. - */ -#define STS_IRQ_RING_STATUS 0x0004 /* SSB is updated with ring status. */ -#define STS_IRQ_LLC_STATUS 0x0005 /* Not used in MAC-only microcode */ -#define STS_IRQ_SCB_CLEAR 0x0006 /* SCB clear, following an - * SCB_REQUEST IRQ. - */ -#define STS_IRQ_TIMER 0x0007 /* Not normally used in MAC ucode */ -#define STS_IRQ_COMMAND_STATUS 0x0008 /* SSB is updated with command - * status. - */ -#define STS_IRQ_RECEIVE_STATUS 0x000A /* SSB is updated with receive - * status. - */ -#define STS_IRQ_TRANSMIT_STATUS 0x000C /* SSB is updated with transmit - * status - */ -#define STS_IRQ_RECEIVE_PENDING 0x000E /* Not used in MAC-only microcode */ -#define STS_IRQ_MASK 0x000F /* = STS_ERROR_MASK. */ - - -/* TRANSMIT_STATUS completion code: (SSB.Parm[0]) */ -#define COMMAND_COMPLETE 0x0080 /* TRANSMIT command completed - * (avoid this!) issue another transmit - * to send additional frames. - */ -#define FRAME_COMPLETE 0x0040 /* Frame has been transmitted; - * INTERRUPT_FRAME bit was set in the - * CSTAT request; indication of possibly - * more than one frame transmissions! - * SSB.Parm[0-1]: 32 bit pointer to - * TPL of last frame. - */ -#define LIST_ERROR 0x0020 /* Error in one of the TPLs that - * compose the frame; TRANSMIT - * terminated; Parm[1-2]: 32bit pointer - * to TPL which starts the error - * frame; error details in bits 8-13. - * (14?) - */ -#define FRAME_SIZE_ERROR 0x8000 /* FRAME_SIZE does not equal the sum of - * the valid DATA_COUNT fields; - * FRAME_SIZE less than header plus - * information field. (15 bytes + - * routing field) Or if FRAME_SIZE - * was specified as zero in one list. - */ -#define TX_THRESHOLD 0x4000 /* FRAME_SIZE greater than (BUFFER_SIZE - * - 9) * TX_BUF_MAX. - */ -#define ODD_ADDRESS 0x2000 /* Odd forward pointer value is - * read on a list without END_FRAME - * indication. - */ -#define FRAME_ERROR 0x1000 /* START_FRAME bit (not) anticipated, - * but (not) set. - */ -#define ACCESS_PRIORITY_ERROR 0x0800 /* Access priority requested has not - * been allowed. - */ -#define UNENABLED_MAC_FRAME 0x0400 /* MAC frame has source class of zero - * or MAC frame PCF ATTN field is - * greater than one. - */ -#define ILLEGAL_FRAME_FORMAT 0x0200 /* Bit 0 or FC field was set to one. */ - - -/* - * Since we need to support some functions even if the adapter is in a - * CLOSED state, we have a (pseudo-) command queue which holds commands - * that are outstandig to be executed. - * - * Each time a command completes, an interrupt occurs and the next - * command is executed. The command queue is actually a simple word with - * a bit for each outstandig command. Therefore the commands will not be - * executed in the order they have been queued. - * - * The following defines the command code bits and the command queue: - */ -#define OC_OPEN 0x0001 /* OPEN command */ -#define OC_TRANSMIT 0x0002 /* TRANSMIT command */ -#define OC_TRANSMIT_HALT 0x0004 /* TRANSMIT_HALT command */ -#define OC_RECEIVE 0x0008 /* RECEIVE command */ -#define OC_CLOSE 0x0010 /* CLOSE command */ -#define OC_SET_GROUP_ADDR 0x0020 /* SET_GROUP_ADDR command */ -#define OC_SET_FUNCT_ADDR 0x0040 /* SET_FUNCT_ADDR command */ -#define OC_READ_ERROR_LOG 0x0080 /* READ_ERROR_LOG command */ -#define OC_READ_ADAPTER 0x0100 /* READ_ADAPTER command */ -#define OC_MODIFY_OPEN_PARMS 0x0400 /* MODIFY_OPEN_PARMS command */ -#define OC_RESTORE_OPEN_PARMS 0x0800 /* RESTORE_OPEN_PARMS command */ -#define OC_SET_FIRST_16_GROUP 0x1000 /* SET_FIRST_16_GROUP command */ -#define OC_SET_BRIDGE_PARMS 0x2000 /* SET_BRIDGE_PARMS command */ -#define OC_CONFIG_BRIDGE_PARMS 0x4000 /* CONFIG_BRIDGE_PARMS command */ - -#define OPEN 0x0300 /* C: open command. S: completion. */ -#define TRANSMIT 0x0400 /* C: transmit command. S: completion - * status. (reject: COMMAND_REJECT if - * adapter not opened, TRANSMIT already - * issued or address passed in the SCB - * not word aligned) - */ -#define TRANSMIT_HALT 0x0500 /* C: interrupt TX TPL chain; if no - * TRANSMIT command issued, the command - * is ignored (completion with TRANSMIT - * status (0x0400)!) - */ -#define RECEIVE 0x0600 /* C: receive command. S: completion - * status. (reject: COMMAND_REJECT if - * adapter not opened, RECEIVE already - * issued or address passed in the SCB - * not word aligned) - */ -#define CLOSE 0x0700 /* C: close adapter. S: completion. - * (COMMAND_REJECT if adapter not open) - */ -#define SET_GROUP_ADDR 0x0800 /* C: alter adapter group address after - * OPEN. S: completion. (COMMAND_REJECT - * if adapter not open) - */ -#define SET_FUNCT_ADDR 0x0900 /* C: alter adapter functional address - * after OPEN. S: completion. - * (COMMAND_REJECT if adapter not open) - */ -#define READ_ERROR_LOG 0x0A00 /* C: read adapter error counters. - * S: completion. (command ignored - * if adapter not open!) - */ -#define READ_ADAPTER 0x0B00 /* C: read data from adapter memory. - * (important: after init and before - * open!) S: completion. (ADAPTER_CHECK - * interrupt if undefined storage area - * read) - */ -#define MODIFY_OPEN_PARMS 0x0D00 /* C: modify some adapter operational - * parameters. (bit correspondend to - * WRAP_INTERFACE is ignored) - * S: completion. (reject: - * COMMAND_REJECT) - */ -#define RESTORE_OPEN_PARMS 0x0E00 /* C: modify some adapter operational - * parameters. (bit correspondend - * to WRAP_INTERFACE is ignored) - * S: completion. (reject: - * COMMAND_REJECT) - */ -#define SET_FIRST_16_GROUP 0x0F00 /* C: alter the first two bytes in - * adapter group address. - * S: completion. (reject: - * COMMAND_REJECT) - */ -#define SET_BRIDGE_PARMS 0x1000 /* C: values and conditions for the - * adapter hardware to use when frames - * are copied for forwarding. - * S: completion. (reject: - * COMMAND_REJECT) - */ -#define CONFIG_BRIDGE_PARMS 0x1100 /* C: .. - * S: completion. (reject: - * COMMAND_REJECT) - */ - -#define SPEED_4 4 -#define SPEED_16 16 /* Default transmission speed */ - - -/* Initialization Parameter Block (IPB); word alignment necessary! */ -#define BURST_SIZE 0x0018 /* Default burst size */ -#define BURST_MODE 0x9F00 /* Burst mode enable */ -#define DMA_RETRIES 0x0505 /* Magic DMA retry number... */ - -#define CYCLE_TIME 3 /* Default AT-bus cycle time: 500 ns - * (later adapter version: fix cycle time!) - */ -#define LINE_SPEED_BIT 0x80 - -/* Macro definition for the wait function. */ -#define ONE_SECOND_TICKS 1000000 -#define HALF_SECOND (ONE_SECOND_TICKS / 2) -#define ONE_SECOND (ONE_SECOND_TICKS) -#define TWO_SECONDS (ONE_SECOND_TICKS * 2) -#define THREE_SECONDS (ONE_SECOND_TICKS * 3) -#define FOUR_SECONDS (ONE_SECOND_TICKS * 4) -#define FIVE_SECONDS (ONE_SECOND_TICKS * 5) - -#define BUFFER_SIZE 2048 /* Buffers on Adapter */ - -#pragma pack(1) -typedef struct { - unsigned short Init_Options; /* Initialize with burst mode; - * LLC disabled. (MAC only) - */ - - /* Interrupt vectors the adapter places on attached system bus. */ - u_int8_t CMD_Status_IV; /* Interrupt vector: command status. */ - u_int8_t TX_IV; /* Interrupt vector: transmit. */ - u_int8_t RX_IV; /* Interrupt vector: receive. */ - u_int8_t Ring_Status_IV; /* Interrupt vector: ring status. */ - u_int8_t SCB_Clear_IV; /* Interrupt vector: SCB clear. */ - u_int8_t Adapter_CHK_IV; /* Interrupt vector: adapter check. */ - - u_int16_t RX_Burst_Size; /* Max. number of transfer cycles. */ - u_int16_t TX_Burst_Size; /* During DMA burst; even value! */ - u_int16_t DMA_Abort_Thrhld; /* Number of DMA retries. */ - - u_int32_t SCB_Addr; /* SCB address: even, word aligned, high-low */ - u_int32_t SSB_Addr; /* SSB address: even, word aligned, high-low */ -} IPB, *IPB_Ptr; -#pragma pack() - -/* - * OPEN Command Parameter List (OCPL) (can be reused, if the adapter has to - * be reopened) - */ -#define BUFFER_SIZE 2048 /* Buffers on Adapter. */ -#define TPL_SIZE 8+6*TX_FRAG_NUM /* Depending on fragments per TPL. */ -#define RPL_SIZE 14 /* (with TI firmware v2.26 handling - * up to nine fragments possible) - */ -#define TX_BUF_MIN 20 /* ??? (Stephan: calculation with */ -#define TX_BUF_MAX 40 /* BUFFER_SIZE and MAX_FRAME_SIZE) ??? - */ -#define DISABLE_EARLY_TOKEN_RELEASE 0x1000 - -/* OPEN Options (high-low) */ -#define WRAP_INTERFACE 0x0080 /* Inserting omitted for test - * purposes; transmit data appears - * as receive data. (useful for - * testing; change: CLOSE necessary) - */ -#define DISABLE_HARD_ERROR 0x0040 /* On HARD_ERROR & TRANSMIT_BEACON - * no RING.STATUS interrupt. - */ -#define DISABLE_SOFT_ERROR 0x0020 /* On SOFT_ERROR, no RING.STATUS - * interrupt. - */ -#define PASS_ADAPTER_MAC_FRAMES 0x0010 /* Passing unsupported MAC frames - * to system. - */ -#define PASS_ATTENTION_FRAMES 0x0008 /* All changed attention MAC frames are - * passed to the system. - */ -#define PAD_ROUTING_FIELD 0x0004 /* Routing field is padded to 18 - * bytes. - */ -#define FRAME_HOLD 0x0002 /*Adapter waits for entire frame before - * initiating DMA transfer; otherwise: - * DMA transfer initiation if internal - * buffer filled. - */ -#define CONTENDER 0x0001 /* Adapter participates in the monitor - * contention process. - */ -#define PASS_BEACON_MAC_FRAMES 0x8000 /* Adapter passes beacon MAC frames - * to the system. - */ -#define EARLY_TOKEN_RELEASE 0x1000 /* Only valid in 16 Mbps operation; - * 0 = ETR. (no effect in 4 Mbps - * operation) - */ -#define COPY_ALL_MAC_FRAMES 0x0400 /* All MAC frames are copied to - * the system. (after OPEN: duplicate - * address test (DAT) MAC frame is - * first received frame copied to the - * system) - */ -#define COPY_ALL_NON_MAC_FRAMES 0x0200 /* All non MAC frames are copied to - * the system. - */ -#define PASS_FIRST_BUF_ONLY 0x0100 /* Passes only first internal buffer - * of each received frame; FrameSize - * of RPLs must contain internal - * BUFFER_SIZE bits for promiscuous mode. - */ -#define ENABLE_FULL_DUPLEX_SELECTION 0x2000 - /* Enable the use of full-duplex - * settings with bits in byte 22 in - * ocpl. (new feature in firmware - * version 3.09) - */ - -/* Full-duplex settings */ -#define OPEN_FULL_DUPLEX_OFF 0x0000 -#define OPEN_FULL_DUPLEX_ON 0x00c0 -#define OPEN_FULL_DUPLEX_AUTO 0x0080 - -#define PROD_ID_SIZE 18 /* Length of product ID. */ - -#define TX_FRAG_NUM 3 /* Number of fragments used in one TPL. */ -#define TX_MORE_FRAGMENTS 0x8000 /* Bit set in DataCount to indicate more - * fragments following. - */ - -/* XXX is there some better way to do this? */ -#define ISA_MAX_ADDRESS 0x00ffffff -#define PCI_MAX_ADDRESS 0xffffffff - -#pragma pack(1) -typedef struct { - u_int16_t OPENOptions; - u_int8_t NodeAddr[6]; /* Adapter node address; use ROM - * address - */ - u_int32_t GroupAddr; /* Multicast: high order - * bytes = 0xC000 - */ - u_int32_t FunctAddr; /* High order bytes = 0xC000 */ - __be16 RxListSize; /* RPL size: 0 (=26), 14, 20 or - * 26 bytes read by the adapter. - * (Depending on the number of - * fragments/list) - */ - __be16 TxListSize; /* TPL size */ - __be16 BufSize; /* Is automatically rounded up to the - * nearest nK boundary. - */ - u_int16_t FullDuplex; - u_int16_t Reserved; - u_int8_t TXBufMin; /* Number of adapter buffers reserved - * for transmission a minimum of 2 - * buffers must be allocated. - */ - u_int8_t TXBufMax; /* Maximum number of adapter buffers - * for transmit; a minimum of 2 buffers - * must be available for receive. - * Default: 6 - */ - u_int16_t ProdIDAddr[2];/* Pointer to product ID. */ -} OPB, *OPB_Ptr; -#pragma pack() - -/* - * SCB: adapter commands enabled by the host system started by writing - * CMD_INTERRUPT_ADAPTER | CMD_EXECUTE (|SCB_REQUEST) to the SIFCMD IO - * register. (special case: | CMD_SYSTEM_IRQ for initialization) - */ -#pragma pack(1) -typedef struct { - u_int16_t CMD; /* Command code */ - u_int16_t Parm[2]; /* Pointer to Command Parameter Block */ -} SCB; /* System Command Block (32 bit physical address; big endian)*/ -#pragma pack() - -/* - * SSB: adapter command return status can be evaluated after COMMAND_STATUS - * adapter to system interrupt after reading SSB, the availability of the SSB - * has to be told the adapter by writing CMD_INTERRUPT_ADAPTER | CMD_SSB_CLEAR - * in the SIFCMD IO register. - */ -#pragma pack(1) -typedef struct { - u_int16_t STS; /* Status code */ - u_int16_t Parm[3]; /* Parameter or pointer to Status Parameter - * Block. - */ -} SSB; /* System Status Block (big endian - physical address) */ -#pragma pack() - -typedef struct { - unsigned short BurnedInAddrPtr; /* Pointer to adapter burned in - * address. (BIA) - */ - unsigned short SoftwareLevelPtr;/* Pointer to software level data. */ - unsigned short AdapterAddrPtr; /* Pointer to adapter addresses. */ - unsigned short AdapterParmsPtr; /* Pointer to adapter parameters. */ - unsigned short MACBufferPtr; /* Pointer to MAC buffer. (internal) */ - unsigned short LLCCountersPtr; /* Pointer to LLC counters. */ - unsigned short SpeedFlagPtr; /* Pointer to data rate flag. - * (4/16 Mbps) - */ - unsigned short AdapterRAMPtr; /* Pointer to adapter RAM found. (KB) */ -} INTPTRS; /* Adapter internal pointers */ - -#pragma pack(1) -typedef struct { - u_int8_t Line_Error; /* Line error: code violation in - * frame or in a token, or FCS error. - */ - u_int8_t Internal_Error; /* IBM specific. (Reserved_1) */ - u_int8_t Burst_Error; - u_int8_t ARI_FCI_Error; /* ARI/FCI bit zero in AMP or - * SMP MAC frame. - */ - u_int8_t AbortDelimeters; /* IBM specific. (Reserved_2) */ - u_int8_t Reserved_3; - u_int8_t Lost_Frame_Error; /* Receive of end of transmitted - * frame failed. - */ - u_int8_t Rx_Congest_Error; /* Adapter in repeat mode has not - * enough buffer space to copy incoming - * frame. - */ - u_int8_t Frame_Copied_Error; /* ARI bit not zero in frame - * addressed to adapter. - */ - u_int8_t Frequency_Error; /* IBM specific. (Reserved_4) */ - u_int8_t Token_Error; /* (active only in monitor station) */ - u_int8_t Reserved_5; - u_int8_t DMA_Bus_Error; /* DMA bus errors not exceeding the - * abort thresholds. - */ - u_int8_t DMA_Parity_Error; /* DMA parity errors not exceeding - * the abort thresholds. - */ -} ERRORTAB; /* Adapter error counters */ -#pragma pack() - - -/*--------------------- Send and Receive definitions -------------------*/ -#pragma pack(1) -typedef struct { - __be16 DataCount; /* Value 0, even and odd values are - * permitted; value is unaltered most - * significant bit set: following - * fragments last fragment: most - * significant bit is not evaluated. - * (???) - */ - __be32 DataAddr; /* Pointer to frame data fragment; - * even or odd. - */ -} Fragment; -#pragma pack() - -#define MAX_FRAG_NUMBERS 9 /* Maximal number of fragments possible to use - * in one RPL/TPL. (depending on TI firmware - * version) - */ - -/* - * AC (1), FC (1), Dst (6), Src (6), RIF (18), Data (4472) = 4504 - * The packet size can be one of the follows: 548, 1502, 2084, 4504, 8176, - * 11439, 17832. Refer to TMS380 Second Generation Token Ring User's Guide - * Page 2-27. - */ -#define HEADER_SIZE (1 + 1 + 6 + 6) -#define SRC_SIZE 18 -#define MIN_DATA_SIZE 516 -#define DEFAULT_DATA_SIZE 4472 -#define MAX_DATA_SIZE 17800 - -#define DEFAULT_PACKET_SIZE (HEADER_SIZE + SRC_SIZE + DEFAULT_DATA_SIZE) -#define MIN_PACKET_SIZE (HEADER_SIZE + SRC_SIZE + MIN_DATA_SIZE) -#define MAX_PACKET_SIZE (HEADER_SIZE + SRC_SIZE + MAX_DATA_SIZE) - -/* - * Macros to deal with the frame status field. - */ -#define AC_NOT_RECOGNIZED 0x00 -#define GROUP_BIT 0x80 -#define GET_TRANSMIT_STATUS_HIGH_BYTE(Ts) ((unsigned char)((Ts) >> 8)) -#define GET_FRAME_STATUS_HIGH_AC(Fs) ((unsigned char)(((Fs) & 0xC0) >> 6)) -#define GET_FRAME_STATUS_LOW_AC(Fs) ((unsigned char)(((Fs) & 0x0C) >> 2)) -#define DIRECTED_FRAME(Context) (!((Context)->MData[2] & GROUP_BIT)) - - -/*--------------------- Send Functions ---------------------------------*/ -/* define TX_CSTAT _REQUEST (R) and _COMPLETE (C) values (high-low) */ - -#define TX_VALID 0x0080 /* R: set via TRANSMIT.VALID interrupt. - * C: always reset to zero! - */ -#define TX_FRAME_COMPLETE 0x0040 /* R: must be reset to zero. - * C: set to one. - */ -#define TX_START_FRAME 0x0020 /* R: start of a frame: 1 - * C: unchanged. - */ -#define TX_END_FRAME 0x0010 /* R: end of a frame: 1 - * C: unchanged. - */ -#define TX_FRAME_IRQ 0x0008 /* R: request interrupt generation - * after transmission. - * C: unchanged. - */ -#define TX_ERROR 0x0004 /* R: reserved. - * C: set to one if Error occurred. - */ -#define TX_INTERFRAME_WAIT 0x0004 -#define TX_PASS_CRC 0x0002 /* R: set if CRC value is already - * calculated. (valid only in - * FRAME_START TPL) - * C: unchanged. - */ -#define TX_PASS_SRC_ADDR 0x0001 /* R: adapter uses explicit frame - * source address and does not overwrite - * with the adapter node address. - * (valid only in FRAME_START TPL) - * - * C: unchanged. - */ -#define TX_STRIP_FS 0xFF00 /* R: reserved. - * C: if no Transmission Error, - * field contains copy of FS byte after - * stripping of frame. - */ - -/* - * Structure of Transmit Parameter Lists (TPLs) (only one frame every TPL, - * but possibly multiple TPLs for one frame) the length of the TPLs has to be - * initialized in the OPL. (OPEN parameter list) - */ -#define TPL_NUM 3 /* Number of Transmit Parameter Lists. - * !! MUST BE >= 3 !! - */ - -#pragma pack(1) -typedef struct s_TPL TPL; - -struct s_TPL { /* Transmit Parameter List (align on even word boundaries) */ - __be32 NextTPLAddr; /* Pointer to next TPL in chain; if - * pointer is odd: this is the last - * TPL. Pointing to itself can cause - * problems! - */ - volatile u_int16_t Status; /* Initialized by the adapter: - * CSTAT_REQUEST important: update least - * significant bit first! Set by the - * adapter: CSTAT_COMPLETE status. - */ - __be16 FrameSize; /* Number of bytes to be transmitted - * as a frame including AC/FC, - * Destination, Source, Routing field - * not including CRC, FS, End Delimiter - * (valid only if START_FRAME bit in - * CSTAT nonzero) must not be zero in - * any list; maximum value: (BUFFER_SIZE - * - 8) * TX_BUF_MAX sum of DataCount - * values in FragmentList must equal - * Frame_Size value in START_FRAME TPL! - * frame data fragment list. - */ - - /* TPL/RPL size in OPEN parameter list depending on maximal - * numbers of fragments used in one parameter list. - */ - Fragment FragList[TX_FRAG_NUM]; /* Maximum: nine frame fragments in one - * TPL actual version of firmware: 9 - * fragments possible. - */ -#pragma pack() - - /* Special proprietary data and precalculations */ - - TPL *NextTPLPtr; /* Pointer to next TPL in chain. */ - unsigned char *MData; - struct sk_buff *Skb; - unsigned char TPLIndex; - volatile unsigned char BusyFlag;/* Flag: TPL busy? */ - dma_addr_t DMABuff; /* DMA IO bus address from dma_map */ -}; - -/* ---------------------Receive Functions-------------------------------* - * define RECEIVE_CSTAT_REQUEST (R) and RECEIVE_CSTAT_COMPLETE (C) values. - * (high-low) - */ -#define RX_VALID 0x0080 /* R: set; tell adapter with - * RECEIVE.VALID interrupt. - * C: reset to zero. - */ -#define RX_FRAME_COMPLETE 0x0040 /* R: must be reset to zero, - * C: set to one. - */ -#define RX_START_FRAME 0x0020 /* R: must be reset to zero. - * C: set to one on the list. - */ -#define RX_END_FRAME 0x0010 /* R: must be reset to zero. - * C: set to one on the list - * that ends the frame. - */ -#define RX_FRAME_IRQ 0x0008 /* R: request interrupt generation - * after receive. - * C: unchanged. - */ -#define RX_INTERFRAME_WAIT 0x0004 /* R: after receiving a frame: - * interrupt and wait for a - * RECEIVE.CONTINUE. - * C: unchanged. - */ -#define RX_PASS_CRC 0x0002 /* R: if set, the adapter includes - * the CRC in data passed. (last four - * bytes; valid only if FRAME_START is - * set) - * C: set, if CRC is included in - * received data. - */ -#define RX_PASS_SRC_ADDR 0x0001 /* R: adapter uses explicit frame - * source address and does not - * overwrite with the adapter node - * address. (valid only if FRAME_START - * is set) - * C: unchanged. - */ -#define RX_RECEIVE_FS 0xFC00 /* R: reserved; must be reset to zero. - * C: on lists with START_FRAME, field - * contains frame status field from - * received frame; otherwise cleared. - */ -#define RX_ADDR_MATCH 0x0300 /* R: reserved; must be reset to zero. - * C: address match code mask. - */ -#define RX_STATUS_MASK 0x00FF /* Mask for receive status bits. */ - -#define RX_INTERN_ADDR_MATCH 0x0100 /* C: internally address match. */ -#define RX_EXTERN_ADDR_MATCH 0x0200 /* C: externally matched via - * XMATCH/XFAIL interface. - */ -#define RX_INTEXT_ADDR_MATCH 0x0300 /* C: internally and externally - * matched. - */ -#define RX_READY (RX_VALID | RX_FRAME_IRQ) /* Ready for receive. */ - -/* Constants for Command Status Interrupt. - * COMMAND_REJECT status field bit functions (SSB.Parm[0]) - */ -#define ILLEGAL_COMMAND 0x0080 /* Set if an unknown command - * is issued to the adapter - */ -#define ADDRESS_ERROR 0x0040 /* Set if any address field in - * the SCB is odd. (not word aligned) - */ -#define ADAPTER_OPEN 0x0020 /* Command issued illegal with - * open adapter. - */ -#define ADAPTER_CLOSE 0x0010 /* Command issued illegal with - * closed adapter. - */ -#define SAME_COMMAND 0x0008 /* Command issued with same command - * already executing. - */ - -/* OPEN_COMPLETION values (SSB.Parm[0], MSB) */ -#define NODE_ADDR_ERROR 0x0040 /* Wrong address or BIA read - * zero address. - */ -#define LIST_SIZE_ERROR 0x0020 /* If List_Size value not in 0, - * 14, 20, 26. - */ -#define BUF_SIZE_ERROR 0x0010 /* Not enough available memory for - * two buffers. - */ -#define TX_BUF_COUNT_ERROR 0x0004 /* Remaining receive buffers less than - * two. - */ -#define OPEN_ERROR 0x0002 /* Error during ring insertion; more - * information in bits 8-15. - */ - -/* Standard return codes */ -#define GOOD_COMPLETION 0x0080 /* =OPEN_SUCCESSFULL */ -#define INVALID_OPEN_OPTION 0x0001 /* OPEN options are not supported by - * the adapter. - */ - -/* OPEN phases; details of OPEN_ERROR (SSB.Parm[0], LSB) */ -#define OPEN_PHASES_MASK 0xF000 /* Check only the bits 8-11. */ -#define LOBE_MEDIA_TEST 0x1000 -#define PHYSICAL_INSERTION 0x2000 -#define ADDRESS_VERIFICATION 0x3000 -#define PARTICIPATION_IN_RING_POLL 0x4000 -#define REQUEST_INITIALISATION 0x5000 -#define FULLDUPLEX_CHECK 0x6000 - -/* OPEN error codes; details of OPEN_ERROR (SSB.Parm[0], LSB) */ -#define OPEN_ERROR_CODES_MASK 0x0F00 /* Check only the bits 12-15. */ -#define OPEN_FUNCTION_FAILURE 0x0100 /* Unable to transmit to itself or - * frames received before insertion. - */ -#define OPEN_SIGNAL_LOSS 0x0200 /* Signal loss condition detected at - * receiver. - */ -#define OPEN_TIMEOUT 0x0500 /* Insertion timer expired before - * logical insertion. - */ -#define OPEN_RING_FAILURE 0x0600 /* Unable to receive own ring purge - * MAC frames. - */ -#define OPEN_RING_BEACONING 0x0700 /* Beacon MAC frame received after - * ring insertion. - */ -#define OPEN_DUPLICATE_NODEADDR 0x0800 /* Other station in ring found - * with the same address. - */ -#define OPEN_REQUEST_INIT 0x0900 /* RPS present but does not respond. */ -#define OPEN_REMOVE_RECEIVED 0x0A00 /* Adapter received a remove adapter - * MAC frame. - */ -#define OPEN_FULLDUPLEX_SET 0x0D00 /* Got this with full duplex on when - * trying to connect to a normal ring. - */ - -/* SET_BRIDGE_PARMS return codes: */ -#define BRIDGE_INVALID_MAX_LEN 0x4000 /* MAX_ROUTING_FIELD_LENGTH odd, - * less than 6 or > 30. - */ -#define BRIDGE_INVALID_SRC_RING 0x2000 /* SOURCE_RING number zero, too large - * or = TARGET_RING. - */ -#define BRIDGE_INVALID_TRG_RING 0x1000 /* TARGET_RING number zero, too large - * or = SOURCE_RING. - */ -#define BRIDGE_INVALID_BRDGE_NO 0x0800 /* BRIDGE_NUMBER too large. */ -#define BRIDGE_INVALID_OPTIONS 0x0400 /* Invalid bridge options. */ -#define BRIDGE_DIAGS_FAILED 0x0200 /* Diagnostics of TMS380SRA failed. */ -#define BRIDGE_NO_SRA 0x0100 /* The TMS380SRA does not exist in HW - * configuration. - */ - -/* - * Bring Up Diagnostics error codes. - */ -#define BUD_INITIAL_ERROR 0x0 -#define BUD_CHECKSUM_ERROR 0x1 -#define BUD_ADAPTER_RAM_ERROR 0x2 -#define BUD_INSTRUCTION_ERROR 0x3 -#define BUD_CONTEXT_ERROR 0x4 -#define BUD_PROTOCOL_ERROR 0x5 -#define BUD_INTERFACE_ERROR 0x6 - -/* BUD constants */ -#define BUD_MAX_RETRIES 3 -#define BUD_MAX_LOOPCNT 6 -#define BUD_TIMEOUT 3000 - -/* Initialization constants */ -#define INIT_MAX_RETRIES 3 /* Maximum three retries. */ -#define INIT_MAX_LOOPCNT 22 /* Maximum loop counts. */ - -/* RING STATUS field values (high/low) */ -#define SIGNAL_LOSS 0x0080 /* Loss of signal on the ring - * detected. - */ -#define HARD_ERROR 0x0040 /* Transmitting or receiving beacon - * frames. - */ -#define SOFT_ERROR 0x0020 /* Report error MAC frame - * transmitted. - */ -#define TRANSMIT_BEACON 0x0010 /* Transmitting beacon frames on the - * ring. - */ -#define LOBE_WIRE_FAULT 0x0008 /* Open or short circuit in the - * cable to concentrator; adapter - * closed. - */ -#define AUTO_REMOVAL_ERROR 0x0004 /* Lobe wrap test failed, deinserted; - * adapter closed. - */ -#define REMOVE_RECEIVED 0x0001 /* Received a remove ring station MAC - * MAC frame request; adapter closed. - */ -#define COUNTER_OVERFLOW 0x8000 /* Overflow of one of the adapters - * error counters; READ.ERROR.LOG. - */ -#define SINGLE_STATION 0x4000 /* Adapter is the only station on the - * ring. - */ -#define RING_RECOVERY 0x2000 /* Claim token MAC frames on the ring; - * reset after ring purge frame. - */ - -#define ADAPTER_CLOSED (LOBE_WIRE_FAULT | AUTO_REMOVAL_ERROR |\ - REMOVE_RECEIVED) - -/* Adapter_check_block.Status field bit assignments: */ -#define DIO_PARITY 0x8000 /* Adapter detects bad parity - * through direct I/O access. - */ -#define DMA_READ_ABORT 0x4000 /* Aborting DMA read operation - * from system Parm[0]: 0=timeout, - * 1=parity error, 2=bus error; - * Parm[1]: 32 bit pointer to host - * system address at failure. - */ -#define DMA_WRITE_ABORT 0x2000 /* Aborting DMA write operation - * to system. (parameters analogous to - * DMA_READ_ABORT) - */ -#define ILLEGAL_OP_CODE 0x1000 /* Illegal operation code in the - * the adapters firmware Parm[0]-2: - * communications processor registers - * R13-R15. - */ -#define PARITY_ERRORS 0x0800 /* Adapter detects internal bus - * parity error. - */ -#define RAM_DATA_ERROR 0x0080 /* Valid only during RAM testing; - * RAM data error Parm[0-1]: 32 bit - * pointer to RAM location. - */ -#define RAM_PARITY_ERROR 0x0040 /* Valid only during RAM testing; - * RAM parity error Parm[0-1]: 32 bit - * pointer to RAM location. - */ -#define RING_UNDERRUN 0x0020 /* Internal DMA underrun when - * transmitting onto ring. - */ -#define INVALID_IRQ 0x0008 /* Unrecognized interrupt generated - * internal to adapter Parm[0-2]: - * adapter register R13-R15. - */ -#define INVALID_ERROR_IRQ 0x0004 /* Unrecognized error interrupt - * generated Parm[0-2]: adapter register - * R13-R15. - */ -#define INVALID_XOP 0x0002 /* Unrecognized XOP request in - * communication processor Parm[0-2]: - * adapter register R13-R15. - */ -#define CHECKADDR 0x05E0 /* Adapter check status information - * address offset. - */ -#define ROM_PAGE_0 0x0000 /* Adapter ROM page 0. */ - -/* - * RECEIVE.STATUS interrupt result SSB values: (high-low) - * (RECEIVE_COMPLETE field bit definitions in SSB.Parm[0]) - */ -#define RX_COMPLETE 0x0080 /* SSB.Parm[0]; SSB.Parm[1]: 32 - * bit pointer to last RPL. - */ -#define RX_SUSPENDED 0x0040 /* SSB.Parm[0]; SSB.Parm[1]: 32 - * bit pointer to RPL with odd - * forward pointer. - */ - -/* Valid receive CSTAT: */ -#define RX_FRAME_CONTROL_BITS (RX_VALID | RX_START_FRAME | RX_END_FRAME | \ - RX_FRAME_COMPLETE) -#define VALID_SINGLE_BUFFER_FRAME (RX_START_FRAME | RX_END_FRAME | \ - RX_FRAME_COMPLETE) - -typedef enum SKB_STAT SKB_STAT; -enum SKB_STAT { - SKB_UNAVAILABLE, - SKB_DMA_DIRECT, - SKB_DATA_COPY -}; - -/* Receive Parameter List (RPL) The length of the RPLs has to be initialized - * in the OPL. (OPEN parameter list) - */ -#define RPL_NUM 3 - -#define RX_FRAG_NUM 1 /* Maximal number of used fragments in one RPL. - * (up to firmware v2.24: 3, now: up to 9) - */ - -#pragma pack(1) -typedef struct s_RPL RPL; -struct s_RPL { /* Receive Parameter List */ - __be32 NextRPLAddr; /* Pointer to next RPL in chain - * (normalized = physical 32 bit - * address) if pointer is odd: this - * is last RPL. Pointing to itself can - * cause problems! - */ - volatile u_int16_t Status; /* Set by creation of Receive Parameter - * List RECEIVE_CSTAT_COMPLETE set by - * adapter in lists that start or end - * a frame. - */ - volatile __be16 FrameSize; /* Number of bytes received as a - * frame including AC/FC, Destination, - * Source, Routing field not including - * CRC, FS (Frame Status), End Delimiter - * (valid only if START_FRAME bit in - * CSTAT nonzero) must not be zero in - * any list; maximum value: (BUFFER_SIZE - * - 8) * TX_BUF_MAX sum of DataCount - * values in FragmentList must equal - * Frame_Size value in START_FRAME TPL! - * frame data fragment list - */ - - /* TPL/RPL size in OPEN parameter list depending on maximal numbers - * of fragments used in one parameter list. - */ - Fragment FragList[RX_FRAG_NUM]; /* Maximum: nine frame fragments in - * one TPL. Actual version of firmware: - * 9 fragments possible. - */ -#pragma pack() - - /* Special proprietary data and precalculations. */ - RPL *NextRPLPtr; /* Logical pointer to next RPL in chain. */ - unsigned char *MData; - struct sk_buff *Skb; - SKB_STAT SkbStat; - int RPLIndex; - dma_addr_t DMABuff; /* DMA IO bus address from dma_map */ -}; - -/* Information that need to be kept for each board. */ -typedef struct net_local { -#pragma pack(1) - IPB ipb; /* Initialization Parameter Block. */ - SCB scb; /* System Command Block: system to adapter - * communication. - */ - SSB ssb; /* System Status Block: adapter to system - * communication. - */ - OPB ocpl; /* Open Options Parameter Block. */ - - ERRORTAB errorlogtable; /* Adapter statistic error counters. - * (read from adapter memory) - */ - unsigned char ProductID[PROD_ID_SIZE + 1]; /* Product ID */ -#pragma pack() - - TPL Tpl[TPL_NUM]; - TPL *TplFree; - TPL *TplBusy; - unsigned char LocalTxBuffers[TPL_NUM][DEFAULT_PACKET_SIZE]; - - RPL Rpl[RPL_NUM]; - RPL *RplHead; - RPL *RplTail; - unsigned char LocalRxBuffers[RPL_NUM][DEFAULT_PACKET_SIZE]; - - struct device *pdev; - int DataRate; - unsigned char ScbInUse; - unsigned short CMDqueue; - - unsigned long AdapterOpenFlag:1; - unsigned long AdapterVirtOpenFlag:1; - unsigned long OpenCommandIssued:1; - unsigned long TransmitCommandActive:1; - unsigned long TransmitHaltScheduled:1; - unsigned long HaltInProgress:1; - unsigned long LobeWireFaultLogged:1; - unsigned long ReOpenInProgress:1; - unsigned long Sleeping:1; - - unsigned long LastOpenStatus; - unsigned short CurrentRingStatus; - unsigned long MaxPacketSize; - - unsigned long StartTime; - unsigned long LastSendTime; - - struct tr_statistics MacStat; /* MAC statistics structure */ - - unsigned long dmalimit; /* the max DMA address (ie, ISA) */ - dma_addr_t dmabuffer; /* the DMA bus address corresponding to - priv. Might be different from virt_to_bus() - for architectures with IO MMU (Alpha) */ - - struct timer_list timer; - - wait_queue_head_t wait_for_tok_int; - - INTPTRS intptrs; /* Internal adapter pointer. Must be read - * before OPEN command. - */ - unsigned short (*setnselout)(struct net_device *); - unsigned short (*sifreadb)(struct net_device *, unsigned short); - void (*sifwriteb)(struct net_device *, unsigned short, unsigned short); - unsigned short (*sifreadw)(struct net_device *, unsigned short); - void (*sifwritew)(struct net_device *, unsigned short, unsigned short); - - spinlock_t lock; /* SMP protection */ - void *tmspriv; -} NET_LOCAL; - -#endif /* __KERNEL__ */ -#endif /* __LINUX_TMS380TR_H */
diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c deleted file mode 100644 index 90f3fa4..0000000 --- a/drivers/net/tokenring/tmspci.c +++ /dev/null
@@ -1,236 +0,0 @@ -/* - * tmspci.c: A generic network driver for TMS380-based PCI token ring cards. - * - * Written 1999 by Adam Fritzler - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * This driver module supports the following cards: - * - SysKonnect TR4/16(+) PCI (SK-4590) - * - SysKonnect TR4/16 PCI (SK-4591) - * - Compaq TR 4/16 PCI - * - Thomas-Conrad TC4048 4/16 PCI - * - 3Com 3C339 Token Link Velocity - * - * Maintainer(s): - * AF Adam Fritzler - * - * Modification History: - * 30-Dec-99 AF Split off from the tms380tr driver. - * 22-Jan-00 AF Updated to use indirect read/writes - * 23-Nov-00 JG New PCI API, cleanups - * - * TODO: - * 1. See if we can use MMIO instead of port accesses - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/netdevice.h> -#include <linux/trdevice.h> - -#include <asm/io.h> -#include <asm/irq.h> - -#include "tms380tr.h" - -static char version[] __devinitdata = -"tmspci.c: v1.02 23/11/2000 by Adam Fritzler\n"; - -#define TMS_PCI_IO_EXTENT 32 - -struct card_info { - unsigned char nselout[2]; /* NSELOUT vals for 4mb([0]) and 16mb([1]) */ - char *name; -}; - -static struct card_info card_info_table[] = { - { {0x03, 0x01}, "Compaq 4/16 TR PCI"}, - { {0x03, 0x01}, "SK NET TR 4/16 PCI"}, - { {0x03, 0x01}, "Thomas-Conrad TC4048 PCI 4/16"}, - { {0x03, 0x01}, "3Com Token Link Velocity"}, -}; - -static DEFINE_PCI_DEVICE_TABLE(tmspci_pci_tbl) = { - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TOKENRING, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_TR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, - { PCI_VENDOR_ID_TCONRAD, PCI_DEVICE_ID_TCONRAD_TOKENRING, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C339, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(pci, tmspci_pci_tbl); - -MODULE_LICENSE("GPL"); - -static void tms_pci_read_eeprom(struct net_device *dev); -static unsigned short tms_pci_setnselout_pins(struct net_device *dev); - -static unsigned short tms_pci_sifreadb(struct net_device *dev, unsigned short reg) -{ - return inb(dev->base_addr + reg); -} - -static unsigned short tms_pci_sifreadw(struct net_device *dev, unsigned short reg) -{ - return inw(dev->base_addr + reg); -} - -static void tms_pci_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg) -{ - outb(val, dev->base_addr + reg); -} - -static void tms_pci_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg) -{ - outw(val, dev->base_addr + reg); -} - -static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - static int versionprinted; - struct net_device *dev; - struct net_local *tp; - int ret; - unsigned int pci_irq_line; - unsigned long pci_ioaddr; - struct card_info *cardinfo = &card_info_table[ent->driver_data]; - - if (versionprinted++ == 0) - printk("%s", version); - - if (pci_enable_device(pdev)) - return -EIO; - - /* Remove I/O space marker in bit 0. */ - pci_irq_line = pdev->irq; - pci_ioaddr = pci_resource_start (pdev, 0); - - /* At this point we have found a valid card. */ - dev = alloc_trdev(sizeof(struct net_local)); - if (!dev) - return -ENOMEM; - - if (!request_region(pci_ioaddr, TMS_PCI_IO_EXTENT, dev->name)) { - ret = -EBUSY; - goto err_out_trdev; - } - - dev->base_addr = pci_ioaddr; - dev->irq = pci_irq_line; - dev->dma = 0; - - dev_info(&pdev->dev, "%s\n", cardinfo->name); - dev_info(&pdev->dev, " IO: %#4lx IRQ: %d\n", dev->base_addr, dev->irq); - - tms_pci_read_eeprom(dev); - - dev_info(&pdev->dev, " Ring Station Address: %pM\n", dev->dev_addr); - - ret = tmsdev_init(dev, &pdev->dev); - if (ret) { - dev_info(&pdev->dev, "unable to get memory for dev->priv.\n"); - goto err_out_region; - } - - tp = netdev_priv(dev); - tp->setnselout = tms_pci_setnselout_pins; - - tp->sifreadb = tms_pci_sifreadb; - tp->sifreadw = tms_pci_sifreadw; - tp->sifwriteb = tms_pci_sifwriteb; - tp->sifwritew = tms_pci_sifwritew; - - memcpy(tp->ProductID, cardinfo->name, PROD_ID_SIZE + 1); - - tp->tmspriv = cardinfo; - - dev->netdev_ops = &tms380tr_netdev_ops; - - ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED, - dev->name, dev); - if (ret) - goto err_out_tmsdev; - - pci_set_drvdata(pdev, dev); - SET_NETDEV_DEV(dev, &pdev->dev); - - ret = register_netdev(dev); - if (ret) - goto err_out_irq; - - return 0; - -err_out_irq: - free_irq(pdev->irq, dev); -err_out_tmsdev: - pci_set_drvdata(pdev, NULL); - tmsdev_term(dev); -err_out_region: - release_region(pci_ioaddr, TMS_PCI_IO_EXTENT); -err_out_trdev: - free_netdev(dev); - return ret; -} - -/* - * Reads MAC address from adapter RAM, which should've read it from - * the onboard ROM. - * - * Calling this on a board that does not support it can be a very - * dangerous thing. The Madge board, for instance, will lock your - * machine hard when this is called. Luckily, its supported in a - * separate driver. --ASF - */ -static void tms_pci_read_eeprom(struct net_device *dev) -{ - int i; - - /* Address: 0000:0000 */ - tms_pci_sifwritew(dev, 0, SIFADX); - tms_pci_sifwritew(dev, 0, SIFADR); - - /* Read six byte MAC address data */ - dev->addr_len = 6; - for(i = 0; i < 6; i++) - dev->dev_addr[i] = tms_pci_sifreadw(dev, SIFINC) >> 8; -} - -static unsigned short tms_pci_setnselout_pins(struct net_device *dev) -{ - unsigned short val = 0; - struct net_local *tp = netdev_priv(dev); - struct card_info *cardinfo = tp->tmspriv; - - if(tp->DataRate == SPEED_4) - val |= cardinfo->nselout[0]; /* Set 4Mbps */ - else - val |= cardinfo->nselout[1]; /* Set 16Mbps */ - return val; -} - -static void __devexit tms_pci_detach (struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - BUG_ON(!dev); - unregister_netdev(dev); - release_region(dev->base_addr, TMS_PCI_IO_EXTENT); - free_irq(dev->irq, dev); - tmsdev_term(dev); - free_netdev(dev); - pci_set_drvdata(pdev, NULL); -} - -static struct pci_driver tms_pci_driver = { - .name = "tmspci", - .id_table = tmspci_pci_tbl, - .probe = tms_pci_attach, - .remove = __devexit_p(tms_pci_detach), -}; - -module_pci_driver(tms_pci_driver);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index bb8c72c..987aeef 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c
@@ -313,7 +313,7 @@ /* Exact match */ for (i = 0; i < filter->count; i++) - if (!compare_ether_addr(eh->h_dest, filter->addr[i])) + if (ether_addr_equal(eh->h_dest, filter->addr[i])) return 1; /* Inexact match (multicast only) */
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 00880ed..fffee6a 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c
@@ -485,6 +485,8 @@ /*-------------------------------------------------------------------------*/ #define HUAWEI_VENDOR_ID 0x12D1 +#define NOVATEL_VENDOR_ID 0x1410 +#define ZTE_VENDOR_ID 0x19D2 static const struct usb_device_id products [] = { /* @@ -602,6 +604,76 @@ * because of bugs/quirks in a given product (like Zaurus, above). */ { + /* Novatel USB551L */ + /* This match must come *before* the generic CDC-ETHER match so that + * we get FLAG_WWAN set on the device, since it's descriptors are + * generic CDC-ETHER. + */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = NOVATEL_VENDOR_ID, + .idProduct = 0xB001, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, +}, { + /* ZTE (Vodafone) K3805-Z */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = ZTE_VENDOR_ID, + .idProduct = 0x1003, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, +}, { + /* ZTE (Vodafone) K3806-Z */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = ZTE_VENDOR_ID, + .idProduct = 0x1015, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, +}, { + /* ZTE (Vodafone) K4510-Z */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = ZTE_VENDOR_ID, + .idProduct = 0x1173, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, +}, { + /* ZTE (Vodafone) K3770-Z */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = ZTE_VENDOR_ID, + .idProduct = 0x1177, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, +}, { + /* ZTE (Vodafone) K3772-Z */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = ZTE_VENDOR_ID, + .idProduct = 0x1181, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, +}, { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), .driver_info = (unsigned long) &cdc_info,
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index d316503b..63cfd0b 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c
@@ -356,10 +356,19 @@ }; /* ZTE suck at making USB descriptors */ -static const struct driver_info qmi_wwan_force_int4 = { - .description = "Qualcomm Gobi wwan/QMI device", +static const struct driver_info qmi_wwan_force_int1 = { + .description = "Qualcomm WWAN/QMI device", .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_gobi, + .bind = qmi_wwan_bind_shared, + .unbind = qmi_wwan_unbind_shared, + .manage_power = qmi_wwan_manage_power, + .data = BIT(1), /* interface whitelist bitmap */ +}; + +static const struct driver_info qmi_wwan_force_int4 = { + .description = "Qualcomm WWAN/QMI device", + .flags = FLAG_WWAN, + .bind = qmi_wwan_bind_shared, .unbind = qmi_wwan_unbind_shared, .manage_power = qmi_wwan_manage_power, .data = BIT(4), /* interface whitelist bitmap */ @@ -401,6 +410,14 @@ .bInterfaceProtocol = 8, /* NOTE: This is the *slave* interface of the CDC Union! */ .driver_info = (unsigned long)&qmi_wwan_info, }, + { /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = HUAWEI_VENDOR_ID, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 56, /* NOTE: This is the *slave* interface of the CDC Union! */ + .driver_info = (unsigned long)&qmi_wwan_info, + }, { /* Huawei E392, E398 and possibly others in "Windows mode" * using a combined control and data interface without any CDC * functional descriptors @@ -430,6 +447,15 @@ .bInterfaceProtocol = 0xff, .driver_info = (unsigned long)&qmi_wwan_force_int4, }, + { /* ZTE (Vodafone) K3520-Z */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x19d2, + .idProduct = 0x0055, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0xff, + .driver_info = (unsigned long)&qmi_wwan_force_int1, + }, { /* ZTE (Vodafone) K3565-Z */ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = 0x19d2, @@ -457,6 +483,15 @@ .bInterfaceProtocol = 0xff, .driver_info = (unsigned long)&qmi_wwan_force_int4, }, + { /* ZTE (Vodafone) K3765-Z */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x19d2, + .idProduct = 0x2002, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0xff, + .driver_info = (unsigned long)&qmi_wwan_force_int4, + }, { /* ZTE (Vodafone) K4505-Z */ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = 0x19d2,
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index c8f1b5b..0d746b3 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c
@@ -77,7 +77,9 @@ if (dev->driver_info->indication) { dev->driver_info->indication(dev, msg, buflen); } else { - switch (msg->status) { + u32 status = le32_to_cpu(msg->status); + + switch (status) { case RNDIS_STATUS_MEDIA_CONNECT: dev_info(udev, "rndis media connect\n"); break; @@ -85,8 +87,7 @@ dev_info(udev, "rndis media disconnect\n"); break; default: - dev_info(udev, "rndis indication: 0x%08x\n", - le32_to_cpu(msg->status)); + dev_info(udev, "rndis indication: 0x%08x\n", status); } } } @@ -109,16 +110,17 @@ int retval; int partial; unsigned count; - __le32 rsp; - u32 xid = 0, msg_len, request_id; + u32 xid = 0, msg_len, request_id, msg_type, rsp, + status; /* REVISIT when this gets called from contexts other than probe() or * disconnect(): either serialize, or dispatch responses on xid */ + msg_type = le32_to_cpu(buf->msg_type); + /* Issue the request; xid is unique, don't bother byteswapping it */ - if (likely(buf->msg_type != RNDIS_MSG_HALT && - buf->msg_type != RNDIS_MSG_RESET)) { + if (likely(msg_type != RNDIS_MSG_HALT && msg_type != RNDIS_MSG_RESET)) { xid = dev->xid++; if (!xid) xid = dev->xid++; @@ -149,7 +151,7 @@ } /* Poll the control channel; the request probably completed immediately */ - rsp = buf->msg_type | RNDIS_MSG_COMPLETION; + rsp = le32_to_cpu(buf->msg_type) | RNDIS_MSG_COMPLETION; for (count = 0; count < 10; count++) { memset(buf, 0, CONTROL_BUFFER_SIZE); retval = usb_control_msg(dev->udev, @@ -160,35 +162,36 @@ buf, buflen, RNDIS_CONTROL_TIMEOUT_MS); if (likely(retval >= 8)) { + msg_type = le32_to_cpu(buf->msg_type); msg_len = le32_to_cpu(buf->msg_len); + status = le32_to_cpu(buf->status); request_id = (__force u32) buf->request_id; - if (likely(buf->msg_type == rsp)) { + if (likely(msg_type == rsp)) { if (likely(request_id == xid)) { if (unlikely(rsp == RNDIS_MSG_RESET_C)) return 0; - if (likely(RNDIS_STATUS_SUCCESS - == buf->status)) + if (likely(RNDIS_STATUS_SUCCESS == + status)) return 0; dev_dbg(&info->control->dev, "rndis reply status %08x\n", - le32_to_cpu(buf->status)); + status); return -EL3RST; } dev_dbg(&info->control->dev, "rndis reply id %d expected %d\n", request_id, xid); /* then likely retry */ - } else switch (buf->msg_type) { - case RNDIS_MSG_INDICATE: /* fault/event */ + } else switch (msg_type) { + case RNDIS_MSG_INDICATE: /* fault/event */ rndis_msg_indicate(dev, (void *)buf, buflen); - break; - case RNDIS_MSG_KEEPALIVE: { /* ping */ + case RNDIS_MSG_KEEPALIVE: { /* ping */ struct rndis_keepalive_c *msg = (void *)buf; - msg->msg_type = RNDIS_MSG_KEEPALIVE_C; + msg->msg_type = cpu_to_le32(RNDIS_MSG_KEEPALIVE_C); msg->msg_len = cpu_to_le32(sizeof *msg); - msg->status = RNDIS_STATUS_SUCCESS; + msg->status = cpu_to_le32(RNDIS_STATUS_SUCCESS); retval = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), USB_CDC_SEND_ENCAPSULATED_COMMAND, @@ -236,7 +239,7 @@ * ActiveSync 4.1 Windows driver. */ static int rndis_query(struct usbnet *dev, struct usb_interface *intf, - void *buf, __le32 oid, u32 in_len, + void *buf, u32 oid, u32 in_len, void **reply, int *reply_len) { int retval; @@ -251,9 +254,9 @@ u.buf = buf; memset(u.get, 0, sizeof *u.get + in_len); - u.get->msg_type = RNDIS_MSG_QUERY; + u.get->msg_type = cpu_to_le32(RNDIS_MSG_QUERY); u.get->msg_len = cpu_to_le32(sizeof *u.get + in_len); - u.get->oid = oid; + u.get->oid = cpu_to_le32(oid); u.get->len = cpu_to_le32(in_len); u.get->offset = cpu_to_le32(20); @@ -324,7 +327,7 @@ if (retval < 0) goto fail; - u.init->msg_type = RNDIS_MSG_INIT; + u.init->msg_type = cpu_to_le32(RNDIS_MSG_INIT); u.init->msg_len = cpu_to_le32(sizeof *u.init); u.init->major_version = cpu_to_le32(1); u.init->minor_version = cpu_to_le32(0); @@ -395,22 +398,23 @@ /* Check physical medium */ phym = NULL; reply_len = sizeof *phym; - retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM, - 0, (void **) &phym, &reply_len); + retval = rndis_query(dev, intf, u.buf, + RNDIS_OID_GEN_PHYSICAL_MEDIUM, + 0, (void **) &phym, &reply_len); if (retval != 0 || !phym) { /* OID is optional so don't fail here. */ - phym_unspec = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED; + phym_unspec = cpu_to_le32(RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED); phym = &phym_unspec; } if ((flags & FLAG_RNDIS_PHYM_WIRELESS) && - *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { + le32_to_cpup(phym) != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { netif_dbg(dev, probe, dev->net, "driver requires wireless physical medium, but device is not\n"); retval = -ENODEV; goto halt_fail_and_release; } if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) && - *phym == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { + le32_to_cpup(phym) == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { netif_dbg(dev, probe, dev->net, "driver requires non-wireless physical medium, but device is wireless.\n"); retval = -ENODEV; @@ -419,8 +423,9 @@ /* Get designated host ethernet address */ reply_len = ETH_ALEN; - retval = rndis_query(dev, intf, u.buf, OID_802_3_PERMANENT_ADDRESS, - 48, (void **) &bp, &reply_len); + retval = rndis_query(dev, intf, u.buf, + RNDIS_OID_802_3_PERMANENT_ADDRESS, + 48, (void **) &bp, &reply_len); if (unlikely(retval< 0)) { dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval); goto halt_fail_and_release; @@ -430,12 +435,12 @@ /* set a nonzero filter to enable data transfers */ memset(u.set, 0, sizeof *u.set); - u.set->msg_type = RNDIS_MSG_SET; + u.set->msg_type = cpu_to_le32(RNDIS_MSG_SET); u.set->msg_len = cpu_to_le32(4 + sizeof *u.set); - u.set->oid = OID_GEN_CURRENT_PACKET_FILTER; + u.set->oid = cpu_to_le32(RNDIS_OID_GEN_CURRENT_PACKET_FILTER); u.set->len = cpu_to_le32(4); u.set->offset = cpu_to_le32((sizeof *u.set) - 8); - *(__le32 *)(u.buf + sizeof *u.set) = RNDIS_DEFAULT_FILTER; + *(__le32 *)(u.buf + sizeof *u.set) = cpu_to_le32(RNDIS_DEFAULT_FILTER); retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE); if (unlikely(retval < 0)) { @@ -450,7 +455,7 @@ halt_fail_and_release: memset(u.halt, 0, sizeof *u.halt); - u.halt->msg_type = RNDIS_MSG_HALT; + u.halt->msg_type = cpu_to_le32(RNDIS_MSG_HALT); u.halt->msg_len = cpu_to_le32(sizeof *u.halt); (void) rndis_command(dev, (void *)u.halt, CONTROL_BUFFER_SIZE); fail_and_release: @@ -475,7 +480,7 @@ /* try to clear any rndis state/activity (no i/o from stack!) */ halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL); if (halt) { - halt->msg_type = RNDIS_MSG_HALT; + halt->msg_type = cpu_to_le32(RNDIS_MSG_HALT); halt->msg_len = cpu_to_le32(sizeof *halt); (void) rndis_command(dev, (void *)halt, CONTROL_BUFFER_SIZE); kfree(halt); @@ -494,16 +499,16 @@ while (likely(skb->len)) { struct rndis_data_hdr *hdr = (void *)skb->data; struct sk_buff *skb2; - u32 msg_len, data_offset, data_len; + u32 msg_type, msg_len, data_offset, data_len; + msg_type = le32_to_cpu(hdr->msg_type); msg_len = le32_to_cpu(hdr->msg_len); data_offset = le32_to_cpu(hdr->data_offset); data_len = le32_to_cpu(hdr->data_len); /* don't choke if we see oob, per-packet data, etc */ - if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET || - skb->len < msg_len || - (data_offset + data_len + 8) > msg_len)) { + if (unlikely(msg_type != RNDIS_MSG_PACKET || skb->len < msg_len + || (data_offset + data_len + 8) > msg_len)) { dev->net->stats.rx_frame_errors++; netdev_dbg(dev->net, "bad rndis message %d/%d/%d/%d, len %d\n", le32_to_cpu(hdr->msg_type), @@ -569,7 +574,7 @@ fill: hdr = (void *) __skb_push(skb, sizeof *hdr); memset(hdr, 0, sizeof *hdr); - hdr->msg_type = RNDIS_MSG_PACKET; + hdr->msg_type = cpu_to_le32(RNDIS_MSG_PACKET); hdr->msg_len = cpu_to_le32(skb->len); hdr->data_offset = cpu_to_le32(sizeof(*hdr) - 8); hdr->data_len = cpu_to_le32(len);
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 80b837c..9f58330 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c
@@ -282,17 +282,32 @@ } EXPORT_SYMBOL_GPL(usbnet_change_mtu); +/* The caller must hold list->lock */ +static void __usbnet_queue_skb(struct sk_buff_head *list, + struct sk_buff *newsk, enum skb_state state) +{ + struct skb_data *entry = (struct skb_data *) newsk->cb; + + __skb_queue_tail(list, newsk); + entry->state = state; +} + /*-------------------------------------------------------------------------*/ /* some LK 2.4 HCDs oopsed if we freed or resubmitted urbs from * completion callbacks. 2.5 should have fixed those bugs... */ -static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_head *list) +static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb, + struct sk_buff_head *list, enum skb_state state) { unsigned long flags; + enum skb_state old_state; + struct skb_data *entry = (struct skb_data *) skb->cb; spin_lock_irqsave(&list->lock, flags); + old_state = entry->state; + entry->state = state; __skb_unlink(skb, list); spin_unlock(&list->lock); spin_lock(&dev->done.lock); @@ -300,6 +315,7 @@ if (dev->done.qlen == 1) tasklet_schedule(&dev->bh); spin_unlock_irqrestore(&dev->done.lock, flags); + return old_state; } /* some work can't be done in tasklets, so we use keventd @@ -340,7 +356,6 @@ entry = (struct skb_data *) skb->cb; entry->urb = urb; entry->dev = dev; - entry->state = rx_start; entry->length = 0; usb_fill_bulk_urb (urb, dev->udev, dev->in, @@ -372,7 +387,7 @@ tasklet_schedule (&dev->bh); break; case 0: - __skb_queue_tail (&dev->rxq, skb); + __usbnet_queue_skb(&dev->rxq, skb, rx_start); } } else { netif_dbg(dev, ifdown, dev->net, "rx: stopped\n"); @@ -423,16 +438,17 @@ struct skb_data *entry = (struct skb_data *) skb->cb; struct usbnet *dev = entry->dev; int urb_status = urb->status; + enum skb_state state; skb_put (skb, urb->actual_length); - entry->state = rx_done; + state = rx_done; entry->urb = NULL; switch (urb_status) { /* success */ case 0: if (skb->len < dev->net->hard_header_len) { - entry->state = rx_cleanup; + state = rx_cleanup; dev->net->stats.rx_errors++; dev->net->stats.rx_length_errors++; netif_dbg(dev, rx_err, dev->net, @@ -471,7 +487,7 @@ "rx throttle %d\n", urb_status); } block: - entry->state = rx_cleanup; + state = rx_cleanup; entry->urb = urb; urb = NULL; break; @@ -482,17 +498,18 @@ // FALLTHROUGH default: - entry->state = rx_cleanup; + state = rx_cleanup; dev->net->stats.rx_errors++; netif_dbg(dev, rx_err, dev->net, "rx status %d\n", urb_status); break; } - defer_bh(dev, skb, &dev->rxq); + state = defer_bh(dev, skb, &dev->rxq, state); if (urb) { if (netif_running (dev->net) && - !test_bit (EVENT_RX_HALT, &dev->flags)) { + !test_bit (EVENT_RX_HALT, &dev->flags) && + state != unlink_start) { rx_submit (dev, urb, GFP_ATOMIC); usb_mark_last_busy(dev->udev); return; @@ -579,16 +596,23 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q) { unsigned long flags; - struct sk_buff *skb, *skbnext; + struct sk_buff *skb; int count = 0; spin_lock_irqsave (&q->lock, flags); - skb_queue_walk_safe(q, skb, skbnext) { + while (!skb_queue_empty(q)) { struct skb_data *entry; struct urb *urb; int retval; - entry = (struct skb_data *) skb->cb; + skb_queue_walk(q, skb) { + entry = (struct skb_data *) skb->cb; + if (entry->state != unlink_start) + goto found; + } + break; +found: + entry->state = unlink_start; urb = entry->urb; /* @@ -1040,8 +1064,7 @@ } usb_autopm_put_interface_async(dev->intf); - entry->state = tx_done; - defer_bh(dev, skb, &dev->txq); + (void) defer_bh(dev, skb, &dev->txq, tx_done); } /*-------------------------------------------------------------------------*/ @@ -1097,7 +1120,6 @@ entry = (struct skb_data *) skb->cb; entry->urb = urb; entry->dev = dev; - entry->state = tx_start; entry->length = length; usb_fill_bulk_urb (urb, dev->udev, dev->out, @@ -1156,7 +1178,7 @@ break; case 0: net->trans_start = jiffies; - __skb_queue_tail (&dev->txq, skb); + __usbnet_queue_skb(&dev->txq, skb, tx_start); if (dev->txq.qlen >= TX_QLEN (dev)) netif_stop_queue (net); }
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index fa58c78..9ce6995 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c
@@ -501,7 +501,9 @@ * We synchronize against interrupts via NAPI_STATE_SCHED */ if (napi_schedule_prep(&vi->napi)) { virtqueue_disable_cb(vi->rvq); + local_bh_disable(); __napi_schedule(&vi->napi); + local_bh_enable(); } }
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 3036c0b..3df0146 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1751,7 +1751,7 @@ * following workaround is necessary. If the TX frame is an * authentication frame extract the bssid and send the CMD_JOIN. */ if (mgmt->frame_control & cpu_to_le16(IEEE80211_STYPE_AUTH)) { - if (compare_ether_addr(priv->bssid, mgmt->bssid)) { + if (!ether_addr_equal(priv->bssid, mgmt->bssid)) { memcpy(priv->bssid, mgmt->bssid, ETH_ALEN); ieee80211_queue_work(hw, &priv->work_join_bssid); dev_kfree_skb_any(skb);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 49e3b19..0ba81a6 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -462,7 +462,7 @@ } if (iter_data->need_set_hw_addr && iter_data->hw_macaddr) - if (compare_ether_addr(iter_data->hw_macaddr, mac) == 0) + if (ether_addr_equal(iter_data->hw_macaddr, mac)) iter_data->need_set_hw_addr = false; if (!iter_data->any_assoc) { @@ -1170,7 +1170,7 @@ if (ieee80211_is_beacon(mgmt->frame_control) && le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && - compare_ether_addr(mgmt->bssid, common->curbssid) == 0) { + ether_addr_equal(mgmt->bssid, common->curbssid)) { /* * Received an IBSS beacon with the same BSSID. Hardware *must* * have updated the local TSF. We have to work around various @@ -1234,7 +1234,7 @@ /* only beacons from our BSSID */ if (!ieee80211_is_beacon(mgmt->frame_control) || - compare_ether_addr(mgmt->bssid, common->curbssid) != 0) + !ether_addr_equal(mgmt->bssid, common->curbssid)) return; ewma_add(&ah->ah_beacon_rssi_avg, rssi);
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 544e549..e1fcc68 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1833,7 +1833,7 @@ if (ieee80211_is_beacon(hdr->frame_control)) { RX_STAT_INC(rx_beacons); if (!is_zero_ether_addr(common->curbssid) && - !compare_ether_addr(hdr->addr3, common->curbssid)) + ether_addr_equal(hdr->addr3, common->curbssid)) rs.is_mybeacon = true; else rs.is_mybeacon = false;
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index dc99030..84b22ee 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -538,7 +538,7 @@ return; /* and only beacons from the associated BSSID, please */ - if (compare_ether_addr(hdr->addr3, ar->common.curbssid) || + if (!ether_addr_equal(hdr->addr3, ar->common.curbssid) || !ar->common.curaid) return;
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c index c4955d25..02e0579 100644 --- a/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
@@ -77,8 +77,8 @@ if (entry->skb != NULL && entry->seq == seq && (entry->last_frag + 1 == frag || frag == -1) && - !compare_ether_addr(entry->src_addr, src) && - !compare_ether_addr(entry->dst_addr, dst)) + ether_addr_equal(entry->src_addr, src) && + ether_addr_equal(entry->dst_addr, dst)) return entry; } @@ -245,12 +245,12 @@ /* check that the frame is unicast frame to us */ if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_TODS && - !compare_ether_addr(hdr->addr1, dev->dev_addr) && - !compare_ether_addr(hdr->addr3, dev->dev_addr)) { + ether_addr_equal(hdr->addr1, dev->dev_addr) && + ether_addr_equal(hdr->addr3, dev->dev_addr)) { /* ToDS frame with own addr BSSID and DA */ } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS && - !compare_ether_addr(hdr->addr1, dev->dev_addr)) { + ether_addr_equal(hdr->addr1, dev->dev_addr)) { /* FromDS frame with own addr as DA */ } else return 0; @@ -523,8 +523,8 @@ if (ieee->iw_mode == IW_MODE_MASTER && !wds && (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == - IEEE80211_FCTL_FROMDS && ieee->stadev - && !compare_ether_addr(hdr->addr2, ieee->assoc_ap_addr)) { + IEEE80211_FCTL_FROMDS && ieee->stadev && + ether_addr_equal(hdr->addr2, ieee->assoc_ap_addr)) { /* Frame from BSSID of the AP for which we are a client */ skb->dev = dev = ieee->stadev; stats = hostap_get_stats(dev); @@ -1468,7 +1468,7 @@ * as one network */ return ((src->ssid_len == dst->ssid_len) && (src->channel == dst->channel) && - !compare_ether_addr(src->bssid, dst->bssid) && + ether_addr_equal(src->bssid, dst->bssid) && !memcmp(src->ssid, dst->ssid, src->ssid_len)); }
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index b25c01b..87e5398 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c
@@ -453,10 +453,10 @@ switch (il->iw_mode) { case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */ /* packets to our IBSS update information */ - return !compare_ether_addr(header->addr3, il->bssid); + return ether_addr_equal(header->addr3, il->bssid); case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */ /* packets to our IBSS update information */ - return !compare_ether_addr(header->addr2, il->bssid); + return ether_addr_equal(header->addr2, il->bssid); default: return 1; }
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index f2baf94..509301a 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -2565,7 +2565,7 @@ spin_lock_irqsave(&il->sta_lock, flags); for (i = start; i < il->hw_params.max_stations; i++) if (il->stations[i].used && - (!compare_ether_addr(il->stations[i].sta.sta.addr, addr))) { + ether_addr_equal(il->stations[i].sta.sta.addr, addr)) { ret = i; goto out; }
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index eaf24945..cbf2dc1 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c
@@ -1896,8 +1896,8 @@ sta_id = il->hw_params.bcast_id; else for (i = IL_STA_ID; i < il->hw_params.max_stations; i++) { - if (!compare_ether_addr - (il->stations[i].sta.sta.addr, addr)) { + if (ether_addr_equal(il->stations[i].sta.sta.addr, + addr)) { sta_id = i; break; } @@ -1926,7 +1926,7 @@ if ((il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE) && (il->stations[sta_id].used & IL_STA_UCODE_ACTIVE) && - !compare_ether_addr(il->stations[sta_id].sta.sta.addr, addr)) { + ether_addr_equal(il->stations[sta_id].sta.sta.addr, addr)) { D_ASSOC("STA %d (%pM) already added, not adding again.\n", sta_id, addr); return sta_id; @@ -3744,10 +3744,10 @@ /* These items are only settable from the full RXON command */ CHK(!il_is_associated(il)); - CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr)); - CHK(compare_ether_addr(staging->node_addr, active->node_addr)); - CHK(compare_ether_addr - (staging->wlap_bssid_addr, active->wlap_bssid_addr)); + CHK(!ether_addr_equal(staging->bssid_addr, active->bssid_addr)); + CHK(!ether_addr_equal(staging->node_addr, active->node_addr)); + CHK(!ether_addr_equal(staging->wlap_bssid_addr, + active->wlap_bssid_addr)); CHK_NEQ(staging->dev_type, active->dev_type); CHK_NEQ(staging->channel, active->channel); CHK_NEQ(staging->air_propagation, active->air_propagation);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 5b80467..403de96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -759,7 +759,12 @@ IWL_ERR(priv, "alloc_skb failed\n"); return; } - hdrlen = min_t(unsigned int, len, skb_tailroom(skb)); + /* If frame is small enough to fit in skb->head, pull it completely. + * If not, only pull ieee80211_hdr so that splice() or TCP coalesce + * are more efficient. + */ + hdrlen = (len <= skb_tailroom(skb)) ? len : sizeof(*hdr); + memcpy(skb_put(skb, hdrlen), hdr, hdrlen); fraglen = len - hdrlen; @@ -780,8 +785,8 @@ */ if (unlikely(ieee80211_is_beacon(fc) && priv->passive_no_rx)) { for_each_context(priv, ctx) { - if (compare_ether_addr(hdr->addr3, - ctx->active.bssid_addr)) + if (!ether_addr_equal(hdr->addr3, + ctx->active.bssid_addr)) continue; iwlagn_lift_passive_no_rx(priv); }
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 89ccddc..0a3aa7c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -885,10 +885,10 @@ /* These items are only settable from the full RXON command */ CHK(!iwl_is_associated_ctx(ctx)); - CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr)); - CHK(compare_ether_addr(staging->node_addr, active->node_addr)); - CHK(compare_ether_addr(staging->wlap_bssid_addr, - active->wlap_bssid_addr)); + CHK(!ether_addr_equal(staging->bssid_addr, active->bssid_addr)); + CHK(!ether_addr_equal(staging->node_addr, active->node_addr)); + CHK(!ether_addr_equal(staging->wlap_bssid_addr, + active->wlap_bssid_addr)); CHK_NEQ(staging->dev_type, active->dev_type); CHK_NEQ(staging->channel, active->channel); CHK_NEQ(staging->air_propagation, active->air_propagation);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 67e6f1d..b31584e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -322,8 +322,8 @@ sta_id = ctx->bcast_sta_id; else for (i = IWL_STA_ID; i < IWLAGN_STATION_COUNT; i++) { - if (!compare_ether_addr(priv->stations[i].sta.sta.addr, - addr)) { + if (ether_addr_equal(priv->stations[i].sta.sta.addr, + addr)) { sta_id = i; break; } @@ -353,7 +353,7 @@ if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) && (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) && - !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) { + ether_addr_equal(priv->stations[sta_id].sta.sta.addr, addr)) { IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not " "adding again.\n", sta_id, addr); return sta_id;
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index e30cc32..cf7bdc6 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c
@@ -1235,7 +1235,7 @@ { return priv->capture_beacon && ieee80211_is_beacon(wh->frame_control) && - !compare_ether_addr(wh->addr3, priv->capture_bssid); + ether_addr_equal(wh->addr3, priv->capture_bssid); } static inline void mwl8k_save_beacon(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 7c8f118..82a1cac 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c
@@ -308,7 +308,7 @@ return; /* only consider beacons from the associated BSSID */ - if (compare_ether_addr(hdr->addr3, priv->bssid)) + if (!ether_addr_equal(hdr->addr3, priv->bssid)) return; tim = p54_find_ie(skb, WLAN_EID_TIM);
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 8b22262..f11953b 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c
@@ -88,49 +88,6 @@ MODULE_PARM_DESC(workaround_interval, "set stall workaround interval in msecs (0=disabled) (default: 0)"); - -/* various RNDIS OID defs */ -#define OID_GEN_LINK_SPEED cpu_to_le32(0x00010107) -#define OID_GEN_RNDIS_CONFIG_PARAMETER cpu_to_le32(0x0001021b) - -#define OID_GEN_XMIT_OK cpu_to_le32(0x00020101) -#define OID_GEN_RCV_OK cpu_to_le32(0x00020102) -#define OID_GEN_XMIT_ERROR cpu_to_le32(0x00020103) -#define OID_GEN_RCV_ERROR cpu_to_le32(0x00020104) -#define OID_GEN_RCV_NO_BUFFER cpu_to_le32(0x00020105) - -#define OID_802_3_CURRENT_ADDRESS cpu_to_le32(0x01010102) -#define OID_802_3_MULTICAST_LIST cpu_to_le32(0x01010103) -#define OID_802_3_MAXIMUM_LIST_SIZE cpu_to_le32(0x01010104) - -#define OID_802_11_BSSID cpu_to_le32(0x0d010101) -#define OID_802_11_SSID cpu_to_le32(0x0d010102) -#define OID_802_11_INFRASTRUCTURE_MODE cpu_to_le32(0x0d010108) -#define OID_802_11_ADD_WEP cpu_to_le32(0x0d010113) -#define OID_802_11_REMOVE_WEP cpu_to_le32(0x0d010114) -#define OID_802_11_DISASSOCIATE cpu_to_le32(0x0d010115) -#define OID_802_11_AUTHENTICATION_MODE cpu_to_le32(0x0d010118) -#define OID_802_11_PRIVACY_FILTER cpu_to_le32(0x0d010119) -#define OID_802_11_BSSID_LIST_SCAN cpu_to_le32(0x0d01011a) -#define OID_802_11_ENCRYPTION_STATUS cpu_to_le32(0x0d01011b) -#define OID_802_11_ADD_KEY cpu_to_le32(0x0d01011d) -#define OID_802_11_REMOVE_KEY cpu_to_le32(0x0d01011e) -#define OID_802_11_ASSOCIATION_INFORMATION cpu_to_le32(0x0d01011f) -#define OID_802_11_CAPABILITY cpu_to_le32(0x0d010122) -#define OID_802_11_PMKID cpu_to_le32(0x0d010123) -#define OID_802_11_NETWORK_TYPES_SUPPORTED cpu_to_le32(0x0d010203) -#define OID_802_11_NETWORK_TYPE_IN_USE cpu_to_le32(0x0d010204) -#define OID_802_11_TX_POWER_LEVEL cpu_to_le32(0x0d010205) -#define OID_802_11_RSSI cpu_to_le32(0x0d010206) -#define OID_802_11_RSSI_TRIGGER cpu_to_le32(0x0d010207) -#define OID_802_11_FRAGMENTATION_THRESHOLD cpu_to_le32(0x0d010209) -#define OID_802_11_RTS_THRESHOLD cpu_to_le32(0x0d01020a) -#define OID_802_11_SUPPORTED_RATES cpu_to_le32(0x0d01020e) -#define OID_802_11_CONFIGURATION cpu_to_le32(0x0d010211) -#define OID_802_11_POWER_MODE cpu_to_le32(0x0d010216) -#define OID_802_11_BSSID_LIST cpu_to_le32(0x0d010217) - - /* Typical noise/maximum signal level values taken from ndiswrapper iw_ndis.h */ #define WL_NOISE -96 /* typical noise level in dBm */ #define WL_SIGMAX -32 /* typical maximum signal level in dBm */ @@ -149,12 +106,6 @@ #define BCM4320_DEFAULT_TXPOWER_DBM_50 10 #define BCM4320_DEFAULT_TXPOWER_DBM_25 7 - -/* codes for "status" field of completion messages */ -#define RNDIS_STATUS_ADAPTER_NOT_READY cpu_to_le32(0xc0010011) -#define RNDIS_STATUS_ADAPTER_NOT_OPEN cpu_to_le32(0xc0010012) - - /* Known device types */ #define RNDIS_UNKNOWN 0 #define RNDIS_BCM4320A 1 @@ -515,7 +466,7 @@ int infra_mode; bool connected; u8 bssid[ETH_ALEN]; - __le32 current_command_oid; + u32 current_command_oid; /* encryption stuff */ u8 encr_tx_key_index; @@ -666,63 +617,63 @@ } #ifdef DEBUG -static const char *oid_to_string(__le32 oid) +static const char *oid_to_string(u32 oid) { switch (oid) { #define OID_STR(oid) case oid: return(#oid) /* from rndis_host.h */ - OID_STR(OID_802_3_PERMANENT_ADDRESS); - OID_STR(OID_GEN_MAXIMUM_FRAME_SIZE); - OID_STR(OID_GEN_CURRENT_PACKET_FILTER); - OID_STR(OID_GEN_PHYSICAL_MEDIUM); + OID_STR(RNDIS_OID_802_3_PERMANENT_ADDRESS); + OID_STR(RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE); + OID_STR(RNDIS_OID_GEN_CURRENT_PACKET_FILTER); + OID_STR(RNDIS_OID_GEN_PHYSICAL_MEDIUM); /* from rndis_wlan.c */ - OID_STR(OID_GEN_LINK_SPEED); - OID_STR(OID_GEN_RNDIS_CONFIG_PARAMETER); + OID_STR(RNDIS_OID_GEN_LINK_SPEED); + OID_STR(RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER); - OID_STR(OID_GEN_XMIT_OK); - OID_STR(OID_GEN_RCV_OK); - OID_STR(OID_GEN_XMIT_ERROR); - OID_STR(OID_GEN_RCV_ERROR); - OID_STR(OID_GEN_RCV_NO_BUFFER); + OID_STR(RNDIS_OID_GEN_XMIT_OK); + OID_STR(RNDIS_OID_GEN_RCV_OK); + OID_STR(RNDIS_OID_GEN_XMIT_ERROR); + OID_STR(RNDIS_OID_GEN_RCV_ERROR); + OID_STR(RNDIS_OID_GEN_RCV_NO_BUFFER); - OID_STR(OID_802_3_CURRENT_ADDRESS); - OID_STR(OID_802_3_MULTICAST_LIST); - OID_STR(OID_802_3_MAXIMUM_LIST_SIZE); + OID_STR(RNDIS_OID_802_3_CURRENT_ADDRESS); + OID_STR(RNDIS_OID_802_3_MULTICAST_LIST); + OID_STR(RNDIS_OID_802_3_MAXIMUM_LIST_SIZE); - OID_STR(OID_802_11_BSSID); - OID_STR(OID_802_11_SSID); - OID_STR(OID_802_11_INFRASTRUCTURE_MODE); - OID_STR(OID_802_11_ADD_WEP); - OID_STR(OID_802_11_REMOVE_WEP); - OID_STR(OID_802_11_DISASSOCIATE); - OID_STR(OID_802_11_AUTHENTICATION_MODE); - OID_STR(OID_802_11_PRIVACY_FILTER); - OID_STR(OID_802_11_BSSID_LIST_SCAN); - OID_STR(OID_802_11_ENCRYPTION_STATUS); - OID_STR(OID_802_11_ADD_KEY); - OID_STR(OID_802_11_REMOVE_KEY); - OID_STR(OID_802_11_ASSOCIATION_INFORMATION); - OID_STR(OID_802_11_CAPABILITY); - OID_STR(OID_802_11_PMKID); - OID_STR(OID_802_11_NETWORK_TYPES_SUPPORTED); - OID_STR(OID_802_11_NETWORK_TYPE_IN_USE); - OID_STR(OID_802_11_TX_POWER_LEVEL); - OID_STR(OID_802_11_RSSI); - OID_STR(OID_802_11_RSSI_TRIGGER); - OID_STR(OID_802_11_FRAGMENTATION_THRESHOLD); - OID_STR(OID_802_11_RTS_THRESHOLD); - OID_STR(OID_802_11_SUPPORTED_RATES); - OID_STR(OID_802_11_CONFIGURATION); - OID_STR(OID_802_11_POWER_MODE); - OID_STR(OID_802_11_BSSID_LIST); + OID_STR(RNDIS_OID_802_11_BSSID); + OID_STR(RNDIS_OID_802_11_SSID); + OID_STR(RNDIS_OID_802_11_INFRASTRUCTURE_MODE); + OID_STR(RNDIS_OID_802_11_ADD_WEP); + OID_STR(RNDIS_OID_802_11_REMOVE_WEP); + OID_STR(RNDIS_OID_802_11_DISASSOCIATE); + OID_STR(RNDIS_OID_802_11_AUTHENTICATION_MODE); + OID_STR(RNDIS_OID_802_11_PRIVACY_FILTER); + OID_STR(RNDIS_OID_802_11_BSSID_LIST_SCAN); + OID_STR(RNDIS_OID_802_11_ENCRYPTION_STATUS); + OID_STR(RNDIS_OID_802_11_ADD_KEY); + OID_STR(RNDIS_OID_802_11_REMOVE_KEY); + OID_STR(RNDIS_OID_802_11_ASSOCIATION_INFORMATION); + OID_STR(RNDIS_OID_802_11_CAPABILITY); + OID_STR(RNDIS_OID_802_11_PMKID); + OID_STR(RNDIS_OID_802_11_NETWORK_TYPES_SUPPORTED); + OID_STR(RNDIS_OID_802_11_NETWORK_TYPE_IN_USE); + OID_STR(RNDIS_OID_802_11_TX_POWER_LEVEL); + OID_STR(RNDIS_OID_802_11_RSSI); + OID_STR(RNDIS_OID_802_11_RSSI_TRIGGER); + OID_STR(RNDIS_OID_802_11_FRAGMENTATION_THRESHOLD); + OID_STR(RNDIS_OID_802_11_RTS_THRESHOLD); + OID_STR(RNDIS_OID_802_11_SUPPORTED_RATES); + OID_STR(RNDIS_OID_802_11_CONFIGURATION); + OID_STR(RNDIS_OID_802_11_POWER_MODE); + OID_STR(RNDIS_OID_802_11_BSSID_LIST); #undef OID_STR } return "?"; } #else -static const char *oid_to_string(__le32 oid) +static const char *oid_to_string(u32 oid) { return "?"; } @@ -732,7 +683,7 @@ static int rndis_error_status(__le32 rndis_status) { int ret = -EINVAL; - switch (rndis_status) { + switch (le32_to_cpu(rndis_status)) { case RNDIS_STATUS_SUCCESS: ret = 0; break; @@ -751,7 +702,7 @@ return ret; } -static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) +static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev); union { @@ -778,9 +729,9 @@ mutex_lock(&priv->command_lock); memset(u.get, 0, sizeof *u.get); - u.get->msg_type = RNDIS_MSG_QUERY; + u.get->msg_type = cpu_to_le32(RNDIS_MSG_QUERY); u.get->msg_len = cpu_to_le32(sizeof *u.get); - u.get->oid = oid; + u.get->oid = cpu_to_le32(oid); priv->current_command_oid = oid; ret = rndis_command(dev, u.header, buflen); @@ -835,7 +786,7 @@ return ret; } -static int rndis_set_oid(struct usbnet *dev, __le32 oid, const void *data, +static int rndis_set_oid(struct usbnet *dev, u32 oid, const void *data, int len) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev); @@ -862,9 +813,9 @@ mutex_lock(&priv->command_lock); memset(u.set, 0, sizeof *u.set); - u.set->msg_type = RNDIS_MSG_SET; + u.set->msg_type = cpu_to_le32(RNDIS_MSG_SET); u.set->msg_len = cpu_to_le32(sizeof(*u.set) + len); - u.set->oid = oid; + u.set->oid = cpu_to_le32(oid); u.set->len = cpu_to_le32(len); u.set->offset = cpu_to_le32(sizeof(*u.set) - 8); u.set->handle = cpu_to_le32(0); @@ -904,7 +855,7 @@ reset = (void *)priv->command_buffer; memset(reset, 0, sizeof(*reset)); - reset->msg_type = RNDIS_MSG_RESET; + reset->msg_type = cpu_to_le32(RNDIS_MSG_RESET); reset->msg_len = cpu_to_le32(sizeof(*reset)); priv->current_command_oid = 0; ret = rndis_command(usbdev, (void *)reset, CONTROL_BUFFER_SIZE); @@ -990,7 +941,7 @@ } #endif - ret = rndis_set_oid(dev, OID_GEN_RNDIS_CONFIG_PARAMETER, + ret = rndis_set_oid(dev, RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER, infobuf, info_len); if (ret != 0) netdev_dbg(dev->net, "setting rndis config parameter failed, %d\n", @@ -1027,9 +978,9 @@ { __le32 tmp; - /* Note: OID_802_11_BSSID_LIST_SCAN clears internal BSS list. */ + /* Note: RNDIS_OID_802_11_BSSID_LIST_SCAN clears internal BSS list. */ tmp = cpu_to_le32(1); - return rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp, + return rndis_set_oid(usbdev, RNDIS_OID_802_11_BSSID_LIST_SCAN, &tmp, sizeof(tmp)); } @@ -1038,7 +989,8 @@ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); int ret; - ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid)); + ret = rndis_set_oid(usbdev, RNDIS_OID_802_11_SSID, + ssid, sizeof(*ssid)); if (ret < 0) { netdev_warn(usbdev->net, "setting SSID failed (%08X)\n", ret); return ret; @@ -1055,7 +1007,8 @@ { int ret; - ret = rndis_set_oid(usbdev, OID_802_11_BSSID, bssid, ETH_ALEN); + ret = rndis_set_oid(usbdev, RNDIS_OID_802_11_BSSID, + bssid, ETH_ALEN); if (ret < 0) { netdev_warn(usbdev->net, "setting BSSID[%pM] failed (%08X)\n", bssid, ret); @@ -1079,7 +1032,8 @@ int ret, len; len = ETH_ALEN; - ret = rndis_query_oid(usbdev, OID_802_11_BSSID, bssid, &len); + ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_BSSID, + bssid, &len); if (ret != 0) memset(bssid, 0, ETH_ALEN); @@ -1090,8 +1044,9 @@ static int get_association_info(struct usbnet *usbdev, struct ndis_80211_assoc_info *info, int len) { - return rndis_query_oid(usbdev, OID_802_11_ASSOCIATION_INFORMATION, - info, &len); + return rndis_query_oid(usbdev, + RNDIS_OID_802_11_ASSOCIATION_INFORMATION, + info, &len); } static bool is_associated(struct usbnet *usbdev) @@ -1115,7 +1070,9 @@ int i, ret = 0; if (priv->radio_on) { - ret = rndis_set_oid(usbdev, OID_802_11_DISASSOCIATE, NULL, 0); + ret = rndis_set_oid(usbdev, + RNDIS_OID_802_11_DISASSOCIATE, + NULL, 0); if (ret == 0) { priv->radio_on = false; netdev_dbg(usbdev->net, "%s(): radio_on = false\n", @@ -1177,8 +1134,9 @@ return -ENOTSUPP; tmp = cpu_to_le32(auth_mode); - ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp, - sizeof(tmp)); + ret = rndis_set_oid(usbdev, + RNDIS_OID_802_11_AUTHENTICATION_MODE, + &tmp, sizeof(tmp)); if (ret != 0) { netdev_warn(usbdev->net, "setting auth mode failed (%08X)\n", ret); @@ -1204,8 +1162,9 @@ else tmp = cpu_to_le32(NDIS_80211_PRIV_ACCEPT_ALL); - return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp, - sizeof(tmp)); + return rndis_set_oid(usbdev, + RNDIS_OID_802_11_PRIVACY_FILTER, &tmp, + sizeof(tmp)); } static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) @@ -1230,8 +1189,9 @@ encr_mode = NDIS_80211_ENCR_DISABLED; tmp = cpu_to_le32(encr_mode); - ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp, - sizeof(tmp)); + ret = rndis_set_oid(usbdev, + RNDIS_OID_802_11_ENCRYPTION_STATUS, &tmp, + sizeof(tmp)); if (ret != 0) { netdev_warn(usbdev->net, "setting encr mode failed (%08X)\n", ret); @@ -1251,8 +1211,9 @@ __func__, priv->infra_mode); tmp = cpu_to_le32(mode); - ret = rndis_set_oid(usbdev, OID_802_11_INFRASTRUCTURE_MODE, &tmp, - sizeof(tmp)); + ret = rndis_set_oid(usbdev, + RNDIS_OID_802_11_INFRASTRUCTURE_MODE, + &tmp, sizeof(tmp)); if (ret != 0) { netdev_warn(usbdev->net, "setting infra mode failed (%08X)\n", ret); @@ -1278,8 +1239,9 @@ rts_threshold = 2347; tmp = cpu_to_le32(rts_threshold); - return rndis_set_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp, - sizeof(tmp)); + return rndis_set_oid(usbdev, + RNDIS_OID_802_11_RTS_THRESHOLD, + &tmp, sizeof(tmp)); } static int set_frag_threshold(struct usbnet *usbdev, u32 frag_threshold) @@ -1292,8 +1254,9 @@ frag_threshold = 2346; tmp = cpu_to_le32(frag_threshold); - return rndis_set_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp, - sizeof(tmp)); + return rndis_set_oid(usbdev, + RNDIS_OID_802_11_FRAGMENTATION_THRESHOLD, + &tmp, sizeof(tmp)); } static void set_default_iw_params(struct usbnet *usbdev) @@ -1329,7 +1292,9 @@ dsconfig = ieee80211_dsss_chan_to_freq(channel) * 1000; len = sizeof(config); - ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len); + ret = rndis_query_oid(usbdev, + RNDIS_OID_802_11_CONFIGURATION, + &config, &len); if (ret < 0) { netdev_dbg(usbdev->net, "%s(): querying configuration failed\n", __func__); @@ -1337,8 +1302,9 @@ } config.ds_config = cpu_to_le32(dsconfig); - ret = rndis_set_oid(usbdev, OID_802_11_CONFIGURATION, &config, - sizeof(config)); + ret = rndis_set_oid(usbdev, + RNDIS_OID_802_11_CONFIGURATION, + &config, sizeof(config)); netdev_dbg(usbdev->net, "%s(): %d -> %d\n", __func__, channel, ret); @@ -1355,8 +1321,10 @@ /* Get channel and beacon interval */ len = sizeof(config); - ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len); - netdev_dbg(usbdev->net, "%s(): OID_802_11_CONFIGURATION -> %d\n", + ret = rndis_query_oid(usbdev, + RNDIS_OID_802_11_CONFIGURATION, + &config, &len); + netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_CONFIGURATION -> %d\n", __func__, ret); if (ret < 0) return NULL; @@ -1409,8 +1377,9 @@ ret); } - ret = rndis_set_oid(usbdev, OID_802_11_ADD_WEP, &ndis_key, - sizeof(ndis_key)); + ret = rndis_set_oid(usbdev, + RNDIS_OID_802_11_ADD_WEP, &ndis_key, + sizeof(ndis_key)); if (ret != 0) { netdev_warn(usbdev->net, "adding encryption key %d failed (%08X)\n", index + 1, ret); @@ -1500,9 +1469,10 @@ get_bssid(usbdev, ndis_key.bssid); } - ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key, - le32_to_cpu(ndis_key.size)); - netdev_dbg(usbdev->net, "%s(): OID_802_11_ADD_KEY -> %08X\n", + ret = rndis_set_oid(usbdev, + RNDIS_OID_802_11_ADD_KEY, &ndis_key, + le32_to_cpu(ndis_key.size)); + netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_ADD_KEY -> %08X\n", __func__, ret); if (ret != 0) return ret; @@ -1590,14 +1560,16 @@ memset(remove_key.bssid, 0xff, sizeof(remove_key.bssid)); - ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_KEY, &remove_key, - sizeof(remove_key)); + ret = rndis_set_oid(usbdev, + RNDIS_OID_802_11_REMOVE_KEY, + &remove_key, sizeof(remove_key)); if (ret != 0) return ret; } else { keyindex = cpu_to_le32(index); - ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_WEP, &keyindex, - sizeof(keyindex)); + ret = rndis_set_oid(usbdev, + RNDIS_OID_802_11_REMOVE_WEP, + &keyindex, sizeof(keyindex)); if (ret != 0) { netdev_warn(usbdev->net, "removing encryption key %d failed (%08X)\n", @@ -1622,14 +1594,14 @@ char *mc_addrs = NULL; int mc_count; - basefilter = filter = RNDIS_PACKET_TYPE_DIRECTED | - RNDIS_PACKET_TYPE_BROADCAST; + basefilter = filter = cpu_to_le32(RNDIS_PACKET_TYPE_DIRECTED | + RNDIS_PACKET_TYPE_BROADCAST); if (usbdev->net->flags & IFF_PROMISC) { - filter |= RNDIS_PACKET_TYPE_PROMISCUOUS | - RNDIS_PACKET_TYPE_ALL_LOCAL; + filter |= cpu_to_le32(RNDIS_PACKET_TYPE_PROMISCUOUS | + RNDIS_PACKET_TYPE_ALL_LOCAL); } else if (usbdev->net->flags & IFF_ALLMULTI) { - filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; + filter |= cpu_to_le32(RNDIS_PACKET_TYPE_ALL_MULTICAST); } if (filter != basefilter) @@ -1642,7 +1614,7 @@ netif_addr_lock_bh(usbdev->net); mc_count = netdev_mc_count(usbdev->net); if (mc_count > priv->multicast_size) { - filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; + filter |= cpu_to_le32(RNDIS_PACKET_TYPE_ALL_MULTICAST); } else if (mc_count) { int i = 0; @@ -1665,27 +1637,28 @@ goto set_filter; if (mc_count) { - ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, mc_addrs, - mc_count * ETH_ALEN); + ret = rndis_set_oid(usbdev, + RNDIS_OID_802_3_MULTICAST_LIST, + mc_addrs, mc_count * ETH_ALEN); kfree(mc_addrs); if (ret == 0) - filter |= RNDIS_PACKET_TYPE_MULTICAST; + filter |= cpu_to_le32(RNDIS_PACKET_TYPE_MULTICAST); else - filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; + filter |= cpu_to_le32(RNDIS_PACKET_TYPE_ALL_MULTICAST); - netdev_dbg(usbdev->net, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n", + netdev_dbg(usbdev->net, "RNDIS_OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n", mc_count, priv->multicast_size, ret); } set_filter: - ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter, + ret = rndis_set_oid(usbdev, RNDIS_OID_GEN_CURRENT_PACKET_FILTER, &filter, sizeof(filter)); if (ret < 0) { netdev_warn(usbdev->net, "couldn't set packet filter: %08x\n", le32_to_cpu(filter)); } - netdev_dbg(usbdev->net, "OID_GEN_CURRENT_PACKET_FILTER(%08x) -> %d\n", + netdev_dbg(usbdev->net, "RNDIS_OID_GEN_CURRENT_PACKET_FILTER(%08x) -> %d\n", le32_to_cpu(filter), ret); } @@ -1744,9 +1717,10 @@ pmkids->length = cpu_to_le32(len); pmkids->bssid_info_count = cpu_to_le32(max_pmkids); - ret = rndis_query_oid(usbdev, OID_802_11_PMKID, pmkids, &len); + ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_PMKID, + pmkids, &len); if (ret < 0) { - netdev_dbg(usbdev->net, "%s(): OID_802_11_PMKID(%d, %d)" + netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_PMKID(%d, %d)" " -> %d\n", __func__, len, max_pmkids, ret); kfree(pmkids); @@ -1772,10 +1746,10 @@ debug_print_pmkids(usbdev, pmkids, __func__); - ret = rndis_set_oid(usbdev, OID_802_11_PMKID, pmkids, - le32_to_cpu(pmkids->length)); + ret = rndis_set_oid(usbdev, RNDIS_OID_802_11_PMKID, pmkids, + le32_to_cpu(pmkids->length)); if (ret < 0) { - netdev_dbg(usbdev->net, "%s(): OID_802_11_PMKID(%d, %d) -> %d" + netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_PMKID(%d, %d) -> %d" "\n", __func__, len, num_pmkids, ret); } @@ -1797,8 +1771,8 @@ count = max_pmkids; for (i = 0; i < count; i++) - if (!compare_ether_addr(pmkids->bssid_info[i].bssid, - pmksa->bssid)) + if (ether_addr_equal(pmkids->bssid_info[i].bssid, + pmksa->bssid)) break; /* pmkid not found */ @@ -1839,8 +1813,8 @@ /* update with new pmkid */ for (i = 0; i < count; i++) { - if (compare_ether_addr(pmkids->bssid_info[i].bssid, - pmksa->bssid)) + if (!ether_addr_equal(pmkids->bssid_info[i].bssid, + pmksa->bssid)) continue; memcpy(pmkids->bssid_info[i].pmkid, pmksa->pmkid, @@ -2109,7 +2083,8 @@ * resizing until it won't get any bigger. */ new_len = len; - ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &new_len); + ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_BSSID_LIST, + buf, &new_len); if (ret != 0 || new_len < sizeof(struct ndis_80211_bssid_list_ex)) goto out; @@ -2135,7 +2110,7 @@ while (check_bssid_list_item(bssid, bssid_len, buf, len)) { if (rndis_bss_info_update(usbdev, bssid) && match_bssid && matched) { - if (compare_ether_addr(bssid->mac, match_bssid)) + if (!ether_addr_equal(bssid->mac, match_bssid)) *matched = true; } @@ -2497,14 +2472,15 @@ memset(sinfo, 0, sizeof(*sinfo)); len = sizeof(linkspeed); - ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &linkspeed, &len); + ret = rndis_query_oid(usbdev, RNDIS_OID_GEN_LINK_SPEED, &linkspeed, &len); if (ret == 0) { sinfo->txrate.legacy = le32_to_cpu(linkspeed) / 1000; sinfo->filled |= STATION_INFO_TX_BITRATE; } len = sizeof(rssi); - ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len); + ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_RSSI, + &rssi, &len); if (ret == 0) { sinfo->signal = level_to_qual(le32_to_cpu(rssi)); sinfo->filled |= STATION_INFO_SIGNAL; @@ -2517,7 +2493,7 @@ struct rndis_wlan_private *priv = wiphy_priv(wiphy); struct usbnet *usbdev = priv->usbdev; - if (compare_ether_addr(priv->bssid, mac)) + if (!ether_addr_equal(priv->bssid, mac)) return -ENOENT; rndis_fill_station_info(usbdev, sinfo); @@ -2610,7 +2586,8 @@ pmkid.length = cpu_to_le32(sizeof(pmkid)); pmkid.bssid_info_count = cpu_to_le32(0); - return rndis_set_oid(usbdev, OID_802_11_PMKID, &pmkid, sizeof(pmkid)); + return rndis_set_oid(usbdev, RNDIS_OID_802_11_PMKID, + &pmkid, sizeof(pmkid)); } static int rndis_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, @@ -2640,9 +2617,10 @@ priv->power_mode = power_mode; mode = cpu_to_le32(power_mode); - ret = rndis_set_oid(usbdev, OID_802_11_POWER_MODE, &mode, sizeof(mode)); + ret = rndis_set_oid(usbdev, RNDIS_OID_802_11_POWER_MODE, + &mode, sizeof(mode)); - netdev_dbg(usbdev->net, "%s(): OID_802_11_POWER_MODE -> %d\n", + netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_POWER_MODE -> %d\n", __func__, ret); return ret; @@ -2679,10 +2657,11 @@ /* Get signal quality, in case of error use rssi=0 and ignore error. */ len = sizeof(rssi); rssi = 0; - ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len); + ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_RSSI, + &rssi, &len); signal = level_to_qual(le32_to_cpu(rssi)); - netdev_dbg(usbdev->net, "%s(): OID_802_11_RSSI -> %d, " + netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_RSSI -> %d, " "rssi:%d, qual: %d\n", __func__, ret, le32_to_cpu(rssi), level_to_qual(le32_to_cpu(rssi))); @@ -2706,8 +2685,9 @@ /* Get SSID, in case of error, use zero length SSID and ignore error. */ len = sizeof(ssid); memset(&ssid, 0, sizeof(ssid)); - ret = rndis_query_oid(usbdev, OID_802_11_SSID, &ssid, &len); - netdev_dbg(usbdev->net, "%s(): OID_802_11_SSID -> %d, len: %d, ssid: " + ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_SSID, + &ssid, &len); + netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_SSID -> %d, len: %d, ssid: " "'%.32s'\n", __func__, ret, le32_to_cpu(ssid.length), ssid.essid); @@ -2829,7 +2809,7 @@ * NDIS spec says: "If the device is associated, but the associated * BSSID is not in its BSSID scan list, then the driver must add an * entry for the BSSID at the end of the data that it returns in - * response to query of OID_802_11_BSSID_LIST." + * response to query of RNDIS_OID_802_11_BSSID_LIST." * * NOTE: Seems to be true for BCM4320b variant, but not BCM4320a. */ @@ -3081,15 +3061,15 @@ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); struct rndis_indicate *msg = ind; - switch (msg->status) { + switch (le32_to_cpu(msg->status)) { case RNDIS_STATUS_MEDIA_CONNECT: - if (priv->current_command_oid == OID_802_11_ADD_KEY) { - /* OID_802_11_ADD_KEY causes sometimes extra + if (priv->current_command_oid == RNDIS_OID_802_11_ADD_KEY) { + /* RNDIS_OID_802_11_ADD_KEY causes sometimes extra * "media connect" indications which confuses driver * and userspace to think that device is * roaming/reassociating when it isn't. */ - netdev_dbg(usbdev->net, "ignored OID_802_11_ADD_KEY triggered 'media connect'\n"); + netdev_dbg(usbdev->net, "ignored RNDIS_OID_802_11_ADD_KEY triggered 'media connect'\n"); return; } @@ -3134,8 +3114,9 @@ /* determine supported modes */ len = sizeof(networks_supported); - retval = rndis_query_oid(usbdev, OID_802_11_NETWORK_TYPES_SUPPORTED, - &networks_supported, &len); + retval = rndis_query_oid(usbdev, + RNDIS_OID_802_11_NETWORK_TYPES_SUPPORTED, + &networks_supported, &len); if (retval >= 0) { n = le32_to_cpu(networks_supported.num_items); if (n > 8) @@ -3159,9 +3140,11 @@ /* get device 802.11 capabilities, number of PMKIDs */ caps = (struct ndis_80211_capability *)caps_buf; len = sizeof(caps_buf); - retval = rndis_query_oid(usbdev, OID_802_11_CAPABILITY, caps, &len); + retval = rndis_query_oid(usbdev, + RNDIS_OID_802_11_CAPABILITY, + caps, &len); if (retval >= 0) { - netdev_dbg(usbdev->net, "OID_802_11_CAPABILITY -> len %d, " + netdev_dbg(usbdev->net, "RNDIS_OID_802_11_CAPABILITY -> len %d, " "ver %d, pmkids %d, auth-encr-pairs %d\n", le32_to_cpu(caps->length), le32_to_cpu(caps->version), @@ -3233,13 +3216,14 @@ } len = sizeof(rssi); - ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len); + ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_RSSI, + &rssi, &len); if (ret == 0) { priv->last_qual = level_to_qual(le32_to_cpu(rssi)); rndis_do_cqm(usbdev, le32_to_cpu(rssi)); } - netdev_dbg(usbdev->net, "dev-poller: OID_802_11_RSSI -> %d, rssi:%d, qual: %d\n", + netdev_dbg(usbdev->net, "dev-poller: RNDIS_OID_802_11_RSSI -> %d, rssi:%d, qual: %d\n", ret, le32_to_cpu(rssi), level_to_qual(le32_to_cpu(rssi))); /* Workaround transfer stalls on poor quality links. @@ -3261,15 +3245,18 @@ * working. */ tmp = cpu_to_le32(1); - rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp, - sizeof(tmp)); + rndis_set_oid(usbdev, + RNDIS_OID_802_11_BSSID_LIST_SCAN, + &tmp, sizeof(tmp)); len = CONTROL_BUFFER_SIZE; buf = kmalloc(len, GFP_KERNEL); if (!buf) goto end; - rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len); + rndis_query_oid(usbdev, + RNDIS_OID_802_11_BSSID_LIST, + buf, &len); kfree(buf); } @@ -3451,13 +3438,15 @@ */ usbdev->net->netdev_ops = &rndis_wlan_netdev_ops; - tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; - retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp, - sizeof(tmp)); + tmp = cpu_to_le32(RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST); + retval = rndis_set_oid(usbdev, + RNDIS_OID_GEN_CURRENT_PACKET_FILTER, + &tmp, sizeof(tmp)); len = sizeof(tmp); - retval = rndis_query_oid(usbdev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp, - &len); + retval = rndis_query_oid(usbdev, + RNDIS_OID_802_3_MAXIMUM_LIST_SIZE, + &tmp, &len); priv->multicast_size = le32_to_cpu(tmp); if (retval < 0 || priv->multicast_size < 0) priv->multicast_size = 0; @@ -3587,7 +3576,7 @@ /* Set current packet filter zero to block receiving data packets from device. */ filter = 0; - rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter, + rndis_set_oid(usbdev, RNDIS_OID_GEN_CURRENT_PACKET_FILTER, &filter, sizeof(filter)); return retval;
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index e54488d..f4c852c 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c
@@ -1460,7 +1460,7 @@ return; /* and only beacons from the associated BSSID, please */ - if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid)) + if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) return; if (rtl_find_221_ie(hw, data, len))
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 5b9c3b5..5ae26647 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -480,7 +480,7 @@ return; /* and only beacons from the associated BSSID, please */ - if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid)) + if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) return; rtlpriv->psc.last_beacon = jiffies;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 37b1363..3af874e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -508,14 +508,14 @@ packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && - (!compare_ether_addr(mac->bssid, - (c_fc & IEEE80211_FCTL_TODS) ? - hdr->addr1 : (c_fc & IEEE80211_FCTL_FROMDS) ? - hdr->addr2 : hdr->addr3)) && + ether_addr_equal(mac->bssid, + (c_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : + (c_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : + hdr->addr3) && (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); packet_toself = packet_matchbssid && - (!compare_ether_addr(praddr, rtlefuse->dev_addr)); + ether_addr_equal(praddr, rtlefuse->dev_addr); if (ieee80211_is_beacon(fc)) packet_beacon = true;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 025bdc2..7e91c76 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
@@ -1099,14 +1099,14 @@ praddr = hdr->addr1; packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && - (!compare_ether_addr(mac->bssid, - (cpu_fc & IEEE80211_FCTL_TODS) ? - hdr->addr1 : (cpu_fc & IEEE80211_FCTL_FROMDS) ? - hdr->addr2 : hdr->addr3)) && + ether_addr_equal(mac->bssid, + (cpu_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : + (cpu_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : + hdr->addr3) && (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); packet_toself = packet_matchbssid && - (!compare_ether_addr(praddr, rtlefuse->dev_addr)); + ether_addr_equal(praddr, rtlefuse->dev_addr); if (ieee80211_is_beacon(fc)) packet_beacon = true; _rtl92c_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index a7f6126..1666ef7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
@@ -466,12 +466,13 @@ type = WLAN_FC_GET_TYPE(fc); praddr = hdr->addr1; packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && - (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ? - hdr->addr1 : (cfc & IEEE80211_FCTL_FROMDS) ? - hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) && - (!pstats->crc) && (!pstats->icv)); + ether_addr_equal(mac->bssid, + (cfc & IEEE80211_FCTL_TODS) ? hdr->addr1 : + (cfc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : + hdr->addr3) && + (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); packet_toself = packet_matchbssid && - (!compare_ether_addr(praddr, rtlefuse->dev_addr)); + ether_addr_equal(praddr, rtlefuse->dev_addr); if (ieee80211_is_beacon(fc)) packet_beacon = true; _rtl92de_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 2fd3d13..812b585 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -492,13 +492,14 @@ praddr = hdr->addr1; packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && - (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ? - hdr->addr1 : (cfc & IEEE80211_FCTL_FROMDS) ? - hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) && - (!pstats->crc) && (!pstats->icv)); + ether_addr_equal(mac->bssid, + (cfc & IEEE80211_FCTL_TODS) ? hdr->addr1 : + (cfc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : + hdr->addr3) && + (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); packet_toself = packet_matchbssid && - (!compare_ether_addr(praddr, rtlefuse->dev_addr)); + ether_addr_equal(praddr, rtlefuse->dev_addr); if (ieee80211_is_beacon(fc)) packet_beacon = true;
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 8644d53..42cfcd9 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c
@@ -44,6 +44,7 @@ #include <asm/ropes.h> #include <asm/mckinley.h> /* for proc_mckinley_root */ #include <asm/runway.h> /* for proc_runway_root */ +#include <asm/page.h> /* for PAGE0 */ #include <asm/pdc.h> /* for PDC_MODEL_* */ #include <asm/pdcpat.h> /* for is_pdc_pat() */ #include <asm/parisc-device.h>
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 0f150f2..61e2fef 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c
@@ -200,7 +200,7 @@ return PCI_D1; case ACPI_STATE_D2: return PCI_D2; - case ACPI_STATE_D3: + case ACPI_STATE_D3_HOT: return PCI_D3hot; case ACPI_STATE_D3_COLD: return PCI_D3cold;
diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c index 0a3594c..bcbad84 100644 --- a/drivers/platform/x86/intel_mid_powerbtn.c +++ b/drivers/platform/x86/intel_mid_powerbtn.c
@@ -78,7 +78,7 @@ input_set_capability(input, EV_KEY, KEY_POWER); - error = request_threaded_irq(irq, NULL, mfld_pb_isr, 0, + error = request_threaded_irq(irq, NULL, mfld_pb_isr, IRQF_NO_SUSPEND, DRIVER_NAME, input); if (error) { dev_err(&pdev->dev, "Unable to request irq %d for mfld power"
diff --git a/drivers/ptp/ptp_pch.c b/drivers/ptp/ptp_pch.c index 08c3311..3a9c17e 100644 --- a/drivers/ptp/ptp_pch.c +++ b/drivers/ptp/ptp_pch.c
@@ -30,6 +30,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/ptp_clock_kernel.h> +#include <linux/slab.h> #define STATION_ADDR_LEN 20 #define PCI_DEVICE_ID_PCH_1588 0x8819
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e70dd38..046fb1b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c
@@ -1431,7 +1431,10 @@ rc = devres_destroy(regulator->dev, devm_regulator_release, devm_regulator_match, regulator); - WARN_ON(rc); + if (rc == 0) + regulator_put(regulator); + else + WARN_ON(rc); } EXPORT_SYMBOL_GPL(devm_regulator_put);
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 9657929..17a58c5 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c
@@ -684,7 +684,7 @@ } new_val++; - } while (desc->min + desc->step + new_val <= desc->max); + } while (desc->min + desc->step * new_val <= desc->max); new_idx = tmp_idx; new_val = tmp_val;
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index ee15c68..e756a0d 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c
@@ -354,7 +354,7 @@ { struct rproc *rproc = rvdev->rproc; - for (i--; i > 0; i--) { + for (i--; i >= 0; i--) { struct rproc_vring *rvring = &rvdev->vring[i]; int size = PAGE_ALIGN(vring_size(rvring->len, rvring->align));
diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 42f5f82..029e421 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c
@@ -360,12 +360,11 @@ &mpc5200_rtc_ops, THIS_MODULE); } - rtc->rtc->uie_unsupported = 1; - if (IS_ERR(rtc->rtc)) { err = PTR_ERR(rtc->rtc); goto out_free_irq; } + rtc->rtc->uie_unsupported = 1; return 0;
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 684ef4b..f027c063 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c
@@ -312,6 +312,7 @@ int ret; struct pl031_local *ldata; struct rtc_class_ops *ops = id->data; + unsigned long time; ret = amba_request_regions(adev, NULL); if (ret) @@ -343,6 +344,23 @@ writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN, ldata->base + RTC_CR); + /* + * On ST PL031 variants, the RTC reset value does not provide correct + * weekday for 2000-01-01. Correct the erroneous sunday to saturday. + */ + if (ldata->hw_designer == AMBA_VENDOR_ST) { + if (readl(ldata->base + RTC_YDR) == 0x2000) { + time = readl(ldata->base + RTC_DR); + if ((time & + (RTC_MON_MASK | RTC_MDAY_MASK | RTC_WDAY_MASK)) + == 0x02120000) { + time = time | (0x7 << RTC_WDAY_SHIFT); + writel(0x2000, ldata->base + RTC_YLR); + writel(time, ldata->base + RTC_LR); + } + } + } + ldata->rtc = rtc_device_register("pl031", &adev->dev, ops, THIS_MODULE); if (IS_ERR(ldata->rtc)) {
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 231a1d8..3650636 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c
@@ -352,7 +352,17 @@ static int sclp_assign_storage(u16 rn) { - return do_assign_storage(0x000d0001, rn); + unsigned long long start, address; + int rc; + + rc = do_assign_storage(0x000d0001, rn); + if (rc) + goto out; + start = address = rn2addr(rn); + for (; address < start + rzm; address += PAGE_SIZE) + page_set_storage_key(address, PAGE_DEFAULT_KEY, 0); +out: + return rc; } static int sclp_unassign_storage(u16 rn)
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index 267b54e..bc6c7cf 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h
@@ -154,12 +154,6 @@ struct tape_request *(*read_block)(struct tape_device *, size_t); struct tape_request *(*write_block)(struct tape_device *, size_t); void (*process_eov)(struct tape_device*); -#ifdef CONFIG_S390_TAPE_BLOCK - /* Block device stuff. */ - struct tape_request *(*bread)(struct tape_device *, struct request *); - void (*check_locate)(struct tape_device *, struct tape_request *); - void (*free_bread)(struct tape_request *); -#endif /* ioctl function for additional ioctls. */ int (*ioctl_fn)(struct tape_device *, unsigned int, unsigned long); /* Array of tape commands with TAPE_NR_MTOPS entries */ @@ -182,26 +176,6 @@ int block_size; /* of size block_size. */ }; -#ifdef CONFIG_S390_TAPE_BLOCK -/* Block Frontend Data */ -struct tape_blk_data -{ - struct tape_device * device; - /* Block device request queue. */ - struct request_queue * request_queue; - spinlock_t request_queue_lock; - - /* Task to move entries from block request to CCS request queue. */ - struct work_struct requeue_task; - atomic_t requeue_scheduled; - - /* Current position on the tape. */ - long block_position; - int medium_changed; - struct gendisk * disk; -}; -#endif - /* Tape Info */ struct tape_device { /* entry in tape_device_list */ @@ -248,10 +222,6 @@ /* Character device frontend data */ struct tape_char_data char_data; -#ifdef CONFIG_S390_TAPE_BLOCK - /* Block dev frontend data */ - struct tape_blk_data blk_data; -#endif /* Function to start or stop the next request later. */ struct delayed_work tape_dnr; @@ -313,19 +283,6 @@ extern int tapechar_setup_device(struct tape_device *); extern void tapechar_cleanup_device(struct tape_device *); -/* Externals from tape_block.c */ -#ifdef CONFIG_S390_TAPE_BLOCK -extern int tapeblock_init (void); -extern void tapeblock_exit(void); -extern int tapeblock_setup_device(struct tape_device *); -extern void tapeblock_cleanup_device(struct tape_device *); -#else -static inline int tapeblock_init (void) {return 0;} -static inline void tapeblock_exit (void) {;} -static inline int tapeblock_setup_device(struct tape_device *t) {return 0;} -static inline void tapeblock_cleanup_device (struct tape_device *t) {;} -#endif - /* tape initialisation functions */ #ifdef CONFIG_PROC_FS extern void tape_proc_init (void);
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 934ef33eb..b28de80 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c
@@ -323,20 +323,6 @@ inhibit_cu_recovery = (*device->modeset_byte & 0x80) ? 1 : 0; sense = irb->ecw; -#ifdef CONFIG_S390_TAPE_BLOCK - if (request->op == TO_BLOCK) { - /* - * Recovery for block device requests. Set the block_position - * to something invalid and retry. - */ - device->blk_data.block_position = -1; - if (request->retries-- <= 0) - return tape_34xx_erp_failed(request, -EIO); - else - return tape_34xx_erp_retry(request); - } -#endif - if ( sense[0] & SENSE_COMMAND_REJECT && sense[1] & SENSE_WRITE_PROTECT @@ -1129,123 +1115,6 @@ return tape_do_io_free(device, request); } -#ifdef CONFIG_S390_TAPE_BLOCK -/* - * Tape block read for 34xx. - */ -static struct tape_request * -tape_34xx_bread(struct tape_device *device, struct request *req) -{ - struct tape_request *request; - struct ccw1 *ccw; - int count = 0; - unsigned off; - char *dst; - struct bio_vec *bv; - struct req_iterator iter; - struct tape_34xx_block_id * start_block; - - DBF_EVENT(6, "xBREDid:"); - - /* Count the number of blocks for the request. */ - rq_for_each_segment(bv, req, iter) - count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9); - - /* Allocate the ccw request. */ - request = tape_alloc_request(3+count+1, 8); - if (IS_ERR(request)) - return request; - - /* Setup ccws. */ - request->op = TO_BLOCK; - start_block = (struct tape_34xx_block_id *) request->cpdata; - start_block->block = blk_rq_pos(req) >> TAPEBLOCK_HSEC_S2B; - DBF_EVENT(6, "start_block = %i\n", start_block->block); - - ccw = request->cpaddr; - ccw = tape_ccw_cc(ccw, MODE_SET_DB, 1, device->modeset_byte); - - /* - * We always setup a nop after the mode set ccw. This slot is - * used in tape_std_check_locate to insert a locate ccw if the - * current tape position doesn't match the start block to be read. - * The second nop will be filled with a read block id which is in - * turn used by tape_34xx_free_bread to populate the segment bid - * table. - */ - ccw = tape_ccw_cc(ccw, NOP, 0, NULL); - ccw = tape_ccw_cc(ccw, NOP, 0, NULL); - - rq_for_each_segment(bv, req, iter) { - dst = kmap(bv->bv_page) + bv->bv_offset; - for (off = 0; off < bv->bv_len; off += TAPEBLOCK_HSEC_SIZE) { - ccw->flags = CCW_FLAG_CC; - ccw->cmd_code = READ_FORWARD; - ccw->count = TAPEBLOCK_HSEC_SIZE; - set_normalized_cda(ccw, (void*) __pa(dst)); - ccw++; - dst += TAPEBLOCK_HSEC_SIZE; - } - } - - ccw = tape_ccw_end(ccw, NOP, 0, NULL); - DBF_EVENT(6, "xBREDccwg\n"); - return request; -} - -static void -tape_34xx_free_bread (struct tape_request *request) -{ - struct ccw1* ccw; - - ccw = request->cpaddr; - if ((ccw + 2)->cmd_code == READ_BLOCK_ID) { - struct { - struct tape_34xx_block_id cbid; - struct tape_34xx_block_id dbid; - } __attribute__ ((packed)) *rbi_data; - - rbi_data = request->cpdata; - - if (request->device) - tape_34xx_add_sbid(request->device, rbi_data->cbid); - } - - /* Last ccw is a nop and doesn't need clear_normalized_cda */ - for (; ccw->flags & CCW_FLAG_CC; ccw++) - if (ccw->cmd_code == READ_FORWARD) - clear_normalized_cda(ccw); - tape_free_request(request); -} - -/* - * check_locate is called just before the tape request is passed to - * the common io layer for execution. It has to check the current - * tape position and insert a locate ccw if it doesn't match the - * start block for the request. - */ -static void -tape_34xx_check_locate(struct tape_device *device, struct tape_request *request) -{ - struct tape_34xx_block_id * start_block; - - start_block = (struct tape_34xx_block_id *) request->cpdata; - if (start_block->block == device->blk_data.block_position) - return; - - DBF_LH(4, "Block seek(%06d+%06d)\n", start_block->block, device->bof); - start_block->wrap = 0; - start_block->segment = 1; - start_block->format = (*device->modeset_byte & 0x08) ? - TAPE34XX_FMT_3480_XF : - TAPE34XX_FMT_3480; - start_block->block = start_block->block + device->bof; - tape_34xx_merge_sbid(device, start_block); - tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata); - tape_ccw_cc(request->cpaddr + 2, READ_BLOCK_ID, 8, request->cpdata); -} -#endif - /* * List of 3480/3490 magnetic tape commands. */ @@ -1295,11 +1164,6 @@ .irq = tape_34xx_irq, .read_block = tape_std_read_block, .write_block = tape_std_write_block, -#ifdef CONFIG_S390_TAPE_BLOCK - .bread = tape_34xx_bread, - .free_bread = tape_34xx_free_bread, - .check_locate = tape_34xx_check_locate, -#endif .ioctl_fn = tape_34xx_ioctl, .mtop_array = tape_34xx_mtop };
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 49c6aab..a5c6614 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c
@@ -670,92 +670,6 @@ return 0; } -#ifdef CONFIG_S390_TAPE_BLOCK -/* - * Tape Block READ - */ -static struct tape_request * -tape_3590_bread(struct tape_device *device, struct request *req) -{ - struct tape_request *request; - struct ccw1 *ccw; - int count = 0, start_block; - unsigned off; - char *dst; - struct bio_vec *bv; - struct req_iterator iter; - - DBF_EVENT(6, "xBREDid:"); - start_block = blk_rq_pos(req) >> TAPEBLOCK_HSEC_S2B; - DBF_EVENT(6, "start_block = %i\n", start_block); - - rq_for_each_segment(bv, req, iter) - count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9); - - request = tape_alloc_request(2 + count + 1, 4); - if (IS_ERR(request)) - return request; - request->op = TO_BLOCK; - *(__u32 *) request->cpdata = start_block; - ccw = request->cpaddr; - ccw = tape_ccw_cc(ccw, MODE_SET_DB, 1, device->modeset_byte); - - /* - * We always setup a nop after the mode set ccw. This slot is - * used in tape_std_check_locate to insert a locate ccw if the - * current tape position doesn't match the start block to be read. - */ - ccw = tape_ccw_cc(ccw, NOP, 0, NULL); - - rq_for_each_segment(bv, req, iter) { - dst = page_address(bv->bv_page) + bv->bv_offset; - for (off = 0; off < bv->bv_len; off += TAPEBLOCK_HSEC_SIZE) { - ccw->flags = CCW_FLAG_CC; - ccw->cmd_code = READ_FORWARD; - ccw->count = TAPEBLOCK_HSEC_SIZE; - set_normalized_cda(ccw, (void *) __pa(dst)); - ccw++; - dst += TAPEBLOCK_HSEC_SIZE; - } - BUG_ON(off > bv->bv_len); - } - ccw = tape_ccw_end(ccw, NOP, 0, NULL); - DBF_EVENT(6, "xBREDccwg\n"); - return request; -} - -static void -tape_3590_free_bread(struct tape_request *request) -{ - struct ccw1 *ccw; - - /* Last ccw is a nop and doesn't need clear_normalized_cda */ - for (ccw = request->cpaddr; ccw->flags & CCW_FLAG_CC; ccw++) - if (ccw->cmd_code == READ_FORWARD) - clear_normalized_cda(ccw); - tape_free_request(request); -} - -/* - * check_locate is called just before the tape request is passed to - * the common io layer for execution. It has to check the current - * tape position and insert a locate ccw if it doesn't match the - * start block for the request. - */ -static void -tape_3590_check_locate(struct tape_device *device, struct tape_request *request) -{ - __u32 *start_block; - - start_block = (__u32 *) request->cpdata; - if (*start_block != device->blk_data.block_position) { - /* Add the start offset of the file to get the real block. */ - *start_block += device->bof; - tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata); - } -} -#endif - static void tape_3590_med_state_set(struct tape_device *device, struct tape_3590_med_sense *sense) { @@ -1423,20 +1337,6 @@ { struct tape_3590_sense *sense; -#ifdef CONFIG_S390_TAPE_BLOCK - if (request->op == TO_BLOCK) { - /* - * Recovery for block device requests. Set the block_position - * to something invalid and retry. - */ - device->blk_data.block_position = -1; - if (request->retries-- <= 0) - return tape_3590_erp_failed(device, request, irb, -EIO); - else - return tape_3590_erp_retry(device, request, irb); - } -#endif - sense = (struct tape_3590_sense *) irb->ecw; DBF_EVENT(6, "Unit Check: RQC = %x\n", sense->rc_rqc); @@ -1729,11 +1629,6 @@ .irq = tape_3590_irq, .read_block = tape_std_read_block, .write_block = tape_std_write_block, -#ifdef CONFIG_S390_TAPE_BLOCK - .bread = tape_3590_bread, - .free_bread = tape_3590_free_bread, - .check_locate = tape_3590_check_locate, -#endif .ioctl_fn = tape_3590_ioctl, .mtop_array = tape_3590_mtop };
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 87cd0ab..46886a7 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c
@@ -161,11 +161,6 @@ if (rc) return rc; -#ifdef CONFIG_S390_TAPE_BLOCK - /* Changes position. */ - device->blk_data.medium_changed = 1; -#endif - DBF_EVENT(6, "TCHAR:nbytes: %lx\n", block_size); /* Let the discipline build the ccw chain. */ request = device->discipline->read_block(device, block_size); @@ -218,11 +213,6 @@ if (rc) return rc; -#ifdef CONFIG_S390_TAPE_BLOCK - /* Changes position. */ - device->blk_data.medium_changed = 1; -#endif - DBF_EVENT(6,"TCHAR:nbytes: %lx\n", block_size); DBF_EVENT(6, "TCHAR:nblocks: %x\n", nblocks); /* Let the discipline build the ccw chain. */ @@ -379,9 +369,6 @@ case MTBSFM: case MTFSFM: case MTSEEK: -#ifdef CONFIG_S390_TAPE_BLOCK - device->blk_data.medium_changed = 1; -#endif if (device->required_tapemarks) tape_std_terminate_write(device); default:
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index b3a3e8e..5856186 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c
@@ -401,9 +401,6 @@ rc = tapechar_setup_device(device); if (rc) goto out_minor; - rc = tapeblock_setup_device(device); - if (rc) - goto out_char; tape_state_set(device, TS_UNUSED); @@ -411,8 +408,6 @@ return 0; -out_char: - tapechar_cleanup_device(device); out_minor: tape_remove_minor(device); out_discipline: @@ -426,7 +421,6 @@ static void tape_cleanup_device(struct tape_device *device) { - tapeblock_cleanup_device(device); tapechar_cleanup_device(device); device->discipline->cleanup_device(device); module_put(device->discipline->owner); @@ -785,10 +779,6 @@ { int rc; -#ifdef CONFIG_S390_TAPE_BLOCK - if (request->op == TO_BLOCK) - device->discipline->check_locate(device, request); -#endif rc = ccw_device_start( device->cdev, request->cpaddr, @@ -1253,7 +1243,7 @@ } /* - * Tape device open function used by tape_char & tape_block frontends. + * Tape device open function used by tape_char frontend. */ int tape_open(struct tape_device *device) @@ -1283,7 +1273,7 @@ } /* - * Tape device release function used by tape_char & tape_block frontends. + * Tape device release function used by tape_char frontend. */ int tape_release(struct tape_device *device) @@ -1344,7 +1334,6 @@ DBF_EVENT(3, "tape init\n"); tape_proc_init(); tapechar_init (); - tapeblock_init (); return 0; } @@ -1358,7 +1347,6 @@ /* Get rid of the frontends */ tapechar_exit(); - tapeblock_exit(); tape_proc_cleanup(); debug_unregister (TAPE_DBF_AREA); }
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 5f1dc6f..731470e 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c
@@ -1,7 +1,7 @@ /* * bus driver for ccwgroup * - * Copyright IBM Corp. 2002, 2009 + * Copyright IBM Corp. 2002, 2012 * * Author(s): Arnd Bergmann (arndb@de.ibm.com) * Cornelia Huck (cornelia.huck@de.ibm.com) @@ -15,10 +15,13 @@ #include <linux/ctype.h> #include <linux/dcache.h> +#include <asm/cio.h> #include <asm/ccwdev.h> #include <asm/ccwgroup.h> -#define CCW_BUS_ID_SIZE 20 +#include "device.h" + +#define CCW_BUS_ID_SIZE 10 /* In Linux 2.4, we had a channel device layer called "chandev" * that did all sorts of obscure stuff for networking devices. @@ -27,19 +30,6 @@ * to devices that use multiple subchannels. */ -/* a device matches a driver if all its slave devices match the same - * entry of the driver */ -static int ccwgroup_bus_match(struct device *dev, struct device_driver * drv) -{ - struct ccwgroup_device *gdev = to_ccwgroupdev(dev); - struct ccwgroup_driver *gdrv = to_ccwgroupdrv(drv); - - if (gdev->creator_id == gdrv->driver_id) - return 1; - - return 0; -} - static struct bus_type ccwgroup_bus_type; static void __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev) @@ -254,9 +244,10 @@ return 0; } -static int __get_next_bus_id(const char **buf, char *bus_id) +static int __get_next_id(const char **buf, struct ccw_dev_id *id) { - int rc, len; + unsigned int cssid, ssid, devno; + int ret = 0, len; char *start, *end; start = (char *)*buf; @@ -271,49 +262,40 @@ len = end - start + 1; end++; } - if (len < CCW_BUS_ID_SIZE) { - strlcpy(bus_id, start, len); - rc = 0; + if (len <= CCW_BUS_ID_SIZE) { + if (sscanf(start, "%2x.%1x.%04x", &cssid, &ssid, &devno) != 3) + ret = -EINVAL; } else - rc = -EINVAL; + ret = -EINVAL; + + if (!ret) { + id->ssid = ssid; + id->devno = devno; + } *buf = end; - return rc; -} - -static int __is_valid_bus_id(char bus_id[CCW_BUS_ID_SIZE]) -{ - int cssid, ssid, devno; - - /* Must be of form %x.%x.%04x */ - if (sscanf(bus_id, "%x.%1x.%04x", &cssid, &ssid, &devno) != 3) - return 0; - return 1; + return ret; } /** - * ccwgroup_create_from_string() - create and register a ccw group device - * @root: parent device for the new device - * @creator_id: identifier of creating driver - * @cdrv: ccw driver of slave devices + * ccwgroup_create_dev() - create and register a ccw group device + * @parent: parent device for the new device + * @gdrv: driver for the new group device * @num_devices: number of slave devices * @buf: buffer containing comma separated bus ids of slave devices * - * Create and register a new ccw group device as a child of @root. Slave - * devices are obtained from the list of bus ids given in @buf and must all - * belong to @cdrv. + * Create and register a new ccw group device as a child of @parent. Slave + * devices are obtained from the list of bus ids given in @buf. * Returns: * %0 on success and an error code on failure. * Context: * non-atomic */ -int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, - struct ccw_driver *cdrv, int num_devices, - const char *buf) +int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv, + int num_devices, const char *buf) { struct ccwgroup_device *gdev; + struct ccw_dev_id dev_id; int rc, i; - char tmp_bus_id[CCW_BUS_ID_SIZE]; - const char *curr_buf; gdev = kzalloc(sizeof(*gdev) + num_devices * sizeof(gdev->cdev[0]), GFP_KERNEL); @@ -323,29 +305,24 @@ atomic_set(&gdev->onoff, 0); mutex_init(&gdev->reg_mutex); mutex_lock(&gdev->reg_mutex); - gdev->creator_id = creator_id; gdev->count = num_devices; gdev->dev.bus = &ccwgroup_bus_type; - gdev->dev.parent = root; + gdev->dev.parent = parent; gdev->dev.release = ccwgroup_release; device_initialize(&gdev->dev); - curr_buf = buf; - for (i = 0; i < num_devices && curr_buf; i++) { - rc = __get_next_bus_id(&curr_buf, tmp_bus_id); + for (i = 0; i < num_devices && buf; i++) { + rc = __get_next_id(&buf, &dev_id); if (rc != 0) goto error; - if (!__is_valid_bus_id(tmp_bus_id)) { - rc = -EINVAL; - goto error; - } - gdev->cdev[i] = get_ccwdev_by_busid(cdrv, tmp_bus_id); + gdev->cdev[i] = get_ccwdev_by_dev_id(&dev_id); /* * All devices have to be of the same type in * order to be grouped. */ - if (!gdev->cdev[i] - || gdev->cdev[i]->id.driver_info != + if (!gdev->cdev[i] || !gdev->cdev[i]->drv || + gdev->cdev[i]->drv != gdev->cdev[0]->drv || + gdev->cdev[i]->id.driver_info != gdev->cdev[0]->id.driver_info) { rc = -EINVAL; goto error; @@ -361,18 +338,25 @@ spin_unlock_irq(gdev->cdev[i]->ccwlock); } /* Check for sufficient number of bus ids. */ - if (i < num_devices && !curr_buf) { + if (i < num_devices) { rc = -EINVAL; goto error; } /* Check for trailing stuff. */ - if (i == num_devices && strlen(curr_buf) > 0) { + if (i == num_devices && strlen(buf) > 0) { rc = -EINVAL; goto error; } dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev)); gdev->dev.groups = ccwgroup_attr_groups; + + if (gdrv) { + gdev->dev.driver = &gdrv->driver; + rc = gdrv->setup ? gdrv->setup(gdev) : 0; + if (rc) + goto error; + } rc = device_add(&gdev->dev); if (rc) goto error; @@ -397,7 +381,7 @@ put_device(&gdev->dev); return rc; } -EXPORT_SYMBOL(ccwgroup_create_from_string); +EXPORT_SYMBOL(ccwgroup_create_dev); static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action, void *data) @@ -440,14 +424,6 @@ /************************** driver stuff ******************************/ -static int ccwgroup_probe(struct device *dev) -{ - struct ccwgroup_device *gdev = to_ccwgroupdev(dev); - struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver); - - return gdrv->probe ? gdrv->probe(gdev) : -ENODEV; -} - static int ccwgroup_remove(struct device *dev) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); @@ -542,8 +518,6 @@ static struct bus_type ccwgroup_bus_type = { .name = "ccwgroup", - .match = ccwgroup_bus_match, - .probe = ccwgroup_probe, .remove = ccwgroup_remove, .shutdown = ccwgroup_shutdown, .pm = &ccwgroup_pm_ops,
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index a49c46c9..a6ddaed 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c
@@ -656,51 +656,34 @@ static int console_subchannel_in_use; /* - * Use cio_tpi to get a pending interrupt and call the interrupt handler. - * Return non-zero if an interrupt was processed, zero otherwise. + * Use cio_tsch to update the subchannel status and call the interrupt handler + * if status had been pending. Called with the console_subchannel lock. */ -static int cio_tpi(void) +static void cio_tsch(struct subchannel *sch) { - struct tpi_info *tpi_info; - struct subchannel *sch; struct irb *irb; int irq_context; - tpi_info = (struct tpi_info *)&S390_lowcore.subchannel_id; - if (tpi(NULL) != 1) - return 0; - kstat_cpu(smp_processor_id()).irqs[IO_INTERRUPT]++; - if (tpi_info->adapter_IO) { - do_adapter_IO(tpi_info->isc); - return 1; - } irb = (struct irb *)&S390_lowcore.irb; /* Store interrupt response block to lowcore. */ - if (tsch(tpi_info->schid, irb) != 0) { + if (tsch(sch->schid, irb) != 0) /* Not status pending or not operational. */ - kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; - return 1; - } - sch = (struct subchannel *)(unsigned long)tpi_info->intparm; - if (!sch) { - kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; - return 1; - } - irq_context = in_interrupt(); - if (!irq_context) - local_bh_disable(); - irq_enter(); - spin_lock(sch->lock); + return; memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw)); + /* Call interrupt handler with updated status. */ + irq_context = in_interrupt(); + if (!irq_context) { + local_bh_disable(); + irq_enter(); + } if (sch->driver && sch->driver->irq) sch->driver->irq(sch); else kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; - spin_unlock(sch->lock); - irq_exit(); - if (!irq_context) + if (!irq_context) { + irq_exit(); _local_bh_enable(); - return 1; + } } void *cio_get_console_priv(void) @@ -712,34 +695,16 @@ * busy wait for the next interrupt on the console */ void wait_cons_dev(void) - __releases(console_subchannel.lock) - __acquires(console_subchannel.lock) { - unsigned long cr6 __attribute__ ((aligned (8))); - unsigned long save_cr6 __attribute__ ((aligned (8))); - - /* - * before entering the spinlock we may already have - * processed the interrupt on a different CPU... - */ if (!console_subchannel_in_use) return; - /* disable all but the console isc */ - __ctl_store (save_cr6, 6, 6); - cr6 = 1UL << (31 - CONSOLE_ISC); - __ctl_load (cr6, 6, 6); - - do { - spin_unlock(console_subchannel.lock); - if (!cio_tpi()) - cpu_relax(); - spin_lock(console_subchannel.lock); - } while (console_subchannel.schib.scsw.cmd.actl != 0); - /* - * restore previous isc value - */ - __ctl_load (save_cr6, 6, 6); + while (1) { + cio_tsch(&console_subchannel); + if (console_subchannel.schib.scsw.cmd.actl == 0) + break; + udelay_simple(100); + } } static int
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 02d0152..f8f952d 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c
@@ -695,7 +695,17 @@ return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id); } -static struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id) +/** + * get_ccwdev_by_dev_id() - obtain device from a ccw device id + * @dev_id: id of the device to be searched + * + * This function searches all devices attached to the ccw bus for a device + * matching @dev_id. + * Returns: + * If a device is found its reference count is increased and returned; + * else %NULL is returned. + */ +struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id) { struct device *dev; @@ -703,6 +713,7 @@ return dev ? to_ccwdev(dev) : NULL; } +EXPORT_SYMBOL_GPL(get_ccwdev_by_dev_id); static void ccw_device_do_unbind_bind(struct ccw_device *cdev) {
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h index 179824b..6bace69 100644 --- a/drivers/s390/cio/device.h +++ b/drivers/s390/cio/device.h
@@ -101,6 +101,7 @@ void ccw_device_schedule_sch_unregister(struct ccw_device *); int ccw_purge_blacklisted(void); void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo); +struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id); /* Function prototypes for device status and basic sense stuff. */ void ccw_device_accumulate_irb(struct ccw_device *, struct irb *);
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 35c685c..7493efa 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c
@@ -63,7 +63,7 @@ " ipm %0\n" " srl %0,28\n" : "=d" (cc) - : "d" (__fc), "d" (__schid), "d" (__mask) : "cc", "memory"); + : "d" (__fc), "d" (__schid), "d" (__mask) : "cc"); return cc; } @@ -74,7 +74,7 @@ * @bb: busy bit indicator, set only if SIGA-w/wt could not access a buffer * @fc: function code to perform * - * Returns cc or QDIO_ERROR_SIGA_ACCESS_EXCEPTION. + * Returns condition code. * Note: For IQDC unicast queues only the highest priority queue is processed. */ static inline int do_siga_output(unsigned long schid, unsigned long mask, @@ -85,18 +85,16 @@ register unsigned long __schid asm("1") = schid; register unsigned long __mask asm("2") = mask; register unsigned long __aob asm("3") = aob; - int cc = QDIO_ERROR_SIGA_ACCESS_EXCEPTION; + int cc; asm volatile( " siga 0\n" - "0: ipm %0\n" + " ipm %0\n" " srl %0,28\n" - "1:\n" - EX_TABLE(0b, 1b) - : "+d" (cc), "+d" (__fc), "+d" (__schid), "+d" (__mask), - "+d" (__aob) - : : "cc", "memory"); - *bb = ((unsigned int) __fc) >> 31; + : "=d" (cc), "+d" (__fc), "+d" (__aob) + : "d" (__schid), "d" (__mask) + : "cc"); + *bb = __fc >> 31; return cc; } @@ -167,7 +165,7 @@ DBF_ERROR("%4x EQBS ERROR", SCH_NO(q)); DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); - q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, + q->handler(q->irq_ptr->cdev, QDIO_ERROR_GET_BUF_STATE, q->nr, q->first_to_kick, count, q->irq_ptr->int_parm); return 0; } @@ -215,7 +213,7 @@ DBF_ERROR("%4x SQBS ERROR", SCH_NO(q)); DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); - q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, + q->handler(q->irq_ptr->cdev, QDIO_ERROR_SET_BUF_STATE, q->nr, q->first_to_kick, count, q->irq_ptr->int_parm); return 0; } @@ -313,7 +311,7 @@ cc = do_siga_sync(schid, output, input, fc); if (unlikely(cc)) DBF_ERROR("%4x SIGA-S:%2d", SCH_NO(q), cc); - return cc; + return (cc) ? -EIO : 0; } static inline int qdio_siga_sync_q(struct qdio_q *q) @@ -384,7 +382,7 @@ cc = do_siga_input(schid, q->mask, fc); if (unlikely(cc)) DBF_ERROR("%4x SIGA-R:%2d", SCH_NO(q), cc); - return cc; + return (cc) ? -EIO : 0; } #define qdio_siga_sync_out(q) qdio_siga_sync(q, ~0U, 0) @@ -443,7 +441,7 @@ unsigned char state = (q->is_input_q) ? SLSB_P_INPUT_NOT_INIT : SLSB_P_OUTPUT_NOT_INIT; - q->qdio_error |= QDIO_ERROR_SLSB_STATE; + q->qdio_error = QDIO_ERROR_SLSB_STATE; /* special handling for no target buffer empty */ if ((!q->is_input_q && @@ -519,7 +517,7 @@ int count, stop; unsigned char state = 0; - q->timestamp = get_clock_fast(); + q->timestamp = get_clock(); /* * Don't check 128 buffers, as otherwise qdio_inbound_q_moved @@ -575,7 +573,7 @@ bufnr = get_inbound_buffer_frontier(q); - if ((bufnr != q->last_move) || q->qdio_error) { + if (bufnr != q->last_move) { q->last_move = bufnr; if (!is_thinint_irq(q->irq_ptr) && MACHINE_IS_LPAR) q->u.in.timestamp = get_clock(); @@ -790,7 +788,7 @@ int count, stop; unsigned char state = 0; - q->timestamp = get_clock_fast(); + q->timestamp = get_clock(); if (need_siga_sync(q)) if (((queue_type(q) != QDIO_IQDIO_QFMT) && @@ -863,7 +861,7 @@ bufnr = get_outbound_buffer_frontier(q); - if ((bufnr != q->last_move) || q->qdio_error) { + if (bufnr != q->last_move) { q->last_move = bufnr; DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr); return 1; @@ -894,13 +892,16 @@ goto retry; } DBF_ERROR("%4x cc2 BBC:%1d", SCH_NO(q), q->nr); - cc |= QDIO_ERROR_SIGA_BUSY; - } else + cc = -EBUSY; + } else { DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr); + cc = -ENOBUFS; + } break; case 1: case 3: DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc); + cc = -EIO; break; } if (retries) { @@ -1090,7 +1091,7 @@ } count = sub_buf(q->first_to_check, q->first_to_kick); - q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, + q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE, q->nr, q->first_to_kick, count, irq_ptr->int_parm); no_handler: qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); @@ -1691,7 +1692,7 @@ "do%02x b:%02x c:%02x", callflags, bufnr, count); if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE) - return -EBUSY; + return -EIO; if (!count) return 0; if (callflags & QDIO_FLAG_SYNC_INPUT)
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 7e9a72e..b987d46 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c
@@ -215,7 +215,7 @@ register struct ap_queue_status reg1_out asm ("1"); register void *reg2 asm ("2") = ind; asm volatile( - ".long 0xb2af0000" /* PQAP(RAPQ) */ + ".long 0xb2af0000" /* PQAP(AQIC) */ : "+d" (reg0), "+d" (reg1_in), "=d" (reg1_out), "+d" (reg2) : : "cc" ); @@ -232,7 +232,7 @@ register unsigned long reg2 asm ("2"); asm volatile( - ".long 0xb2af0000\n" + ".long 0xb2af0000\n" /* PQAP(TAPQ) */ "0:\n" EX_TABLE(0b, 0b) : "+d" (reg0), "+d" (reg1), "=d" (reg2) @@ -391,7 +391,7 @@ reg0 |= 0x400000UL; asm volatile ( - "0: .long 0xb2ad0042\n" /* DQAP */ + "0: .long 0xb2ad0042\n" /* NQAP */ " brc 2,0b" : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3) : "d" (reg4), "d" (reg5), "m" (*(msgblock *) msg) @@ -450,7 +450,7 @@ asm volatile( - "0: .long 0xb2ae0064\n" + "0: .long 0xb2ae0064\n" /* DQAP */ " brc 6,0b\n" : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7), @@ -836,12 +836,12 @@ list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) { list_del_init(&ap_msg->list); ap_dev->pendingq_count--; - ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); + ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); } list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) { list_del_init(&ap_msg->list); ap_dev->requestq_count--; - ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); + ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); } } @@ -1329,7 +1329,7 @@ continue; list_del_init(&ap_msg->list); ap_dev->pendingq_count--; - ap_dev->drv->receive(ap_dev, ap_msg, ap_dev->reply); + ap_msg->receive(ap_dev, ap_msg, ap_dev->reply); break; } if (ap_dev->queue_count > 0) @@ -1450,10 +1450,10 @@ return -EBUSY; case AP_RESPONSE_REQ_FAC_NOT_INST: case AP_RESPONSE_MESSAGE_TOO_BIG: - ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL)); + ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL)); return -EINVAL; default: /* Device is gone. */ - ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); + ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); return -ENODEV; } } else { @@ -1471,6 +1471,10 @@ unsigned long flags; int rc; + /* For asynchronous message handling a valid receive-callback + * is required. */ + BUG_ON(!ap_msg->receive); + spin_lock_bh(&ap_dev->lock); if (!ap_dev->unregistered) { /* Make room on the queue by polling for finished requests. */ @@ -1482,7 +1486,7 @@ if (rc == -ENODEV) ap_dev->unregistered = 1; } else { - ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); + ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); rc = -ENODEV; } spin_unlock_bh(&ap_dev->lock);
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index d960a63..726fc65 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h
@@ -136,9 +136,6 @@ int (*probe)(struct ap_device *); void (*remove)(struct ap_device *); - /* receive is called from tasklet context */ - void (*receive)(struct ap_device *, struct ap_message *, - struct ap_message *); int request_timeout; /* request timeout in jiffies */ }; @@ -183,6 +180,9 @@ void *private; /* ap driver private pointer. */ unsigned int special:1; /* Used for special commands. */ + /* receive is called from tasklet context */ + void (*receive)(struct ap_device *, struct ap_message *, + struct ap_message *); }; #define AP_DEVICE(dt) \ @@ -199,6 +199,7 @@ ap_msg->psmid = 0; ap_msg->length = 0; ap_msg->special = 0; + ap_msg->receive = NULL; } /*
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c index 0842867..4681244 100644 --- a/drivers/s390/crypto/zcrypt_cex2a.c +++ b/drivers/s390/crypto/zcrypt_cex2a.c
@@ -77,7 +77,6 @@ static struct ap_driver zcrypt_cex2a_driver = { .probe = zcrypt_cex2a_probe, .remove = zcrypt_cex2a_remove, - .receive = zcrypt_cex2a_receive, .ids = zcrypt_cex2a_ids, .request_timeout = CEX2A_CLEANUP_TIME, }; @@ -349,6 +348,7 @@ ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; + ap_msg.receive = zcrypt_cex2a_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &work; @@ -390,6 +390,7 @@ ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; + ap_msg.receive = zcrypt_cex2a_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &work;
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c index 0effca9..ad7951c 100644 --- a/drivers/s390/crypto/zcrypt_pcica.c +++ b/drivers/s390/crypto/zcrypt_pcica.c
@@ -67,7 +67,6 @@ static struct ap_driver zcrypt_pcica_driver = { .probe = zcrypt_pcica_probe, .remove = zcrypt_pcica_remove, - .receive = zcrypt_pcica_receive, .ids = zcrypt_pcica_ids, .request_timeout = PCICA_CLEANUP_TIME, }; @@ -284,6 +283,7 @@ ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; + ap_msg.receive = zcrypt_pcica_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &work; @@ -322,6 +322,7 @@ ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; + ap_msg.receive = zcrypt_pcica_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &work;
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c index f9523c0..e5dd335 100644 --- a/drivers/s390/crypto/zcrypt_pcicc.c +++ b/drivers/s390/crypto/zcrypt_pcicc.c
@@ -79,7 +79,6 @@ static struct ap_driver zcrypt_pcicc_driver = { .probe = zcrypt_pcicc_probe, .remove = zcrypt_pcicc_remove, - .receive = zcrypt_pcicc_receive, .ids = zcrypt_pcicc_ids, .request_timeout = PCICC_CLEANUP_TIME, }; @@ -488,6 +487,7 @@ ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; + ap_msg.receive = zcrypt_pcicc_receive; ap_msg.length = PAGE_SIZE; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); @@ -527,6 +527,7 @@ ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; + ap_msg.receive = zcrypt_pcicc_receive; ap_msg.length = PAGE_SIZE; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step);
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index cf1cbd4..f7cc434 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -89,7 +89,6 @@ static struct ap_driver zcrypt_pcixcc_driver = { .probe = zcrypt_pcixcc_probe, .remove = zcrypt_pcixcc_remove, - .receive = zcrypt_pcixcc_receive, .ids = zcrypt_pcixcc_ids, .request_timeout = PCIXCC_CLEANUP_TIME, }; @@ -698,6 +697,7 @@ ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; + ap_msg.receive = zcrypt_pcixcc_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &resp_type; @@ -738,6 +738,7 @@ ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; + ap_msg.receive = zcrypt_pcixcc_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &resp_type; @@ -778,6 +779,7 @@ ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; + ap_msg.receive = zcrypt_pcixcc_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &resp_type; @@ -818,6 +820,7 @@ ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; + ap_msg.receive = zcrypt_pcixcc_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &resp_type;
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig index 9b66d2d..dfda748 100644 --- a/drivers/s390/net/Kconfig +++ b/drivers/s390/net/Kconfig
@@ -4,11 +4,10 @@ config LCS def_tristate m prompt "Lan Channel Station Interface" - depends on CCW && NETDEVICES && (ETHERNET || TR || FDDI) + depends on CCW && NETDEVICES && (ETHERNET || FDDI) help Select this option if you want to use LCS networking on IBM System z. - This device driver supports Token Ring (IEEE 802.5), - FDDI (IEEE 802.7) and Ethernet. + This device driver supports FDDI (IEEE 802.7) and Ethernet. To compile as a module, choose M. The module name is lcs. If you do not know what it is, it's safe to choose Y.
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index b41fae3..6b1ff90 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c
@@ -136,7 +136,6 @@ claw_set_busy(struct net_device *dev) { ((struct claw_privbk *)dev->ml_priv)->tbusy = 1; - eieio(); } static inline void @@ -144,13 +143,11 @@ { clear_bit(0, &(((struct claw_privbk *) dev->ml_priv)->tbusy)); netif_wake_queue(dev); - eieio(); } static inline int claw_check_busy(struct net_device *dev) { - eieio(); return ((struct claw_privbk *) dev->ml_priv)->tbusy; } @@ -233,8 +230,6 @@ static ssize_t claw_rbuff_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); -static int claw_add_files(struct device *dev); -static void claw_remove_files(struct device *dev); /* Functions for System Validate */ static int claw_process_control( struct net_device *dev, struct ccwbk * p_ccw); @@ -267,12 +262,10 @@ .owner = THIS_MODULE, .name = "claw", }, - .max_slaves = 2, - .driver_id = 0xC3D3C1E6, - .probe = claw_probe, - .remove = claw_remove_device, - .set_online = claw_new_device, - .set_offline = claw_shutdown_device, + .setup = claw_probe, + .remove = claw_remove_device, + .set_online = claw_new_device, + .set_offline = claw_shutdown_device, .prepare = claw_pm_prepare, }; @@ -293,30 +286,24 @@ .int_class = IOINT_CLW, }; -static ssize_t -claw_driver_group_store(struct device_driver *ddrv, const char *buf, - size_t count) +static ssize_t claw_driver_group_store(struct device_driver *ddrv, + const char *buf, size_t count) { int err; - err = ccwgroup_create_from_string(claw_root_dev, - claw_group_driver.driver_id, - &claw_ccw_driver, 2, buf); + err = ccwgroup_create_dev(claw_root_dev, &claw_group_driver, 2, buf); return err ? err : count; } - static DRIVER_ATTR(group, 0200, NULL, claw_driver_group_store); -static struct attribute *claw_group_attrs[] = { +static struct attribute *claw_drv_attrs[] = { &driver_attr_group.attr, NULL, }; - -static struct attribute_group claw_group_attr_group = { - .attrs = claw_group_attrs, +static struct attribute_group claw_drv_attr_group = { + .attrs = claw_drv_attrs, }; - -static const struct attribute_group *claw_group_attr_groups[] = { - &claw_group_attr_group, +static const struct attribute_group *claw_drv_attr_groups[] = { + &claw_drv_attr_group, NULL, }; @@ -324,60 +311,6 @@ * Key functions */ -/*----------------------------------------------------------------* - * claw_probe * - * this function is called for each CLAW device. * - *----------------------------------------------------------------*/ -static int -claw_probe(struct ccwgroup_device *cgdev) -{ - int rc; - struct claw_privbk *privptr=NULL; - - CLAW_DBF_TEXT(2, setup, "probe"); - if (!get_device(&cgdev->dev)) - return -ENODEV; - privptr = kzalloc(sizeof(struct claw_privbk), GFP_KERNEL); - dev_set_drvdata(&cgdev->dev, privptr); - if (privptr == NULL) { - probe_error(cgdev); - put_device(&cgdev->dev); - CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM); - return -ENOMEM; - } - privptr->p_mtc_envelope= kzalloc( MAX_ENVELOPE_SIZE, GFP_KERNEL); - privptr->p_env = kzalloc(sizeof(struct claw_env), GFP_KERNEL); - if ((privptr->p_mtc_envelope==NULL) || (privptr->p_env==NULL)) { - probe_error(cgdev); - put_device(&cgdev->dev); - CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM); - return -ENOMEM; - } - memcpy(privptr->p_env->adapter_name,WS_NAME_NOT_DEF,8); - memcpy(privptr->p_env->host_name,WS_NAME_NOT_DEF,8); - memcpy(privptr->p_env->api_type,WS_NAME_NOT_DEF,8); - privptr->p_env->packing = 0; - privptr->p_env->write_buffers = 5; - privptr->p_env->read_buffers = 5; - privptr->p_env->read_size = CLAW_FRAME_SIZE; - privptr->p_env->write_size = CLAW_FRAME_SIZE; - rc = claw_add_files(&cgdev->dev); - if (rc) { - probe_error(cgdev); - put_device(&cgdev->dev); - dev_err(&cgdev->dev, "Creating the /proc files for a new" - " CLAW device failed\n"); - CLAW_DBF_TEXT_(2, setup, "probex%d", rc); - return rc; - } - privptr->p_env->p_priv = privptr; - cgdev->cdev[0]->handler = claw_irq_handler; - cgdev->cdev[1]->handler = claw_irq_handler; - CLAW_DBF_TEXT(2, setup, "prbext 0"); - - return 0; -} /* end of claw_probe */ - /*-------------------------------------------------------------------* * claw_tx * *-------------------------------------------------------------------*/ @@ -3093,7 +3026,6 @@ dev_info(&cgdev->dev, " will be removed.\n"); if (cgdev->state == CCWGROUP_ONLINE) claw_shutdown_device(cgdev); - claw_remove_files(&cgdev->dev); kfree(priv->p_mtc_envelope); priv->p_mtc_envelope=NULL; kfree(priv->p_env); @@ -3321,7 +3253,6 @@ CLAW_DBF_TEXT_(2, setup, "RB=%d", p_env->read_buffers); return count; } - static DEVICE_ATTR(read_buffer, 0644, claw_rbuff_show, claw_rbuff_write); static struct attribute *claw_attr[] = { @@ -3332,40 +3263,73 @@ &dev_attr_host_name.attr, NULL, }; - static struct attribute_group claw_attr_group = { .attrs = claw_attr, }; +static const struct attribute_group *claw_attr_groups[] = { + &claw_attr_group, + NULL, +}; +static const struct device_type claw_devtype = { + .name = "claw", + .groups = claw_attr_groups, +}; -static int -claw_add_files(struct device *dev) +/*----------------------------------------------------------------* + * claw_probe * + * this function is called for each CLAW device. * + *----------------------------------------------------------------*/ +static int claw_probe(struct ccwgroup_device *cgdev) { - CLAW_DBF_TEXT(2, setup, "add_file"); - return sysfs_create_group(&dev->kobj, &claw_attr_group); -} + struct claw_privbk *privptr = NULL; -static void -claw_remove_files(struct device *dev) -{ - CLAW_DBF_TEXT(2, setup, "rem_file"); - sysfs_remove_group(&dev->kobj, &claw_attr_group); -} + CLAW_DBF_TEXT(2, setup, "probe"); + if (!get_device(&cgdev->dev)) + return -ENODEV; + privptr = kzalloc(sizeof(struct claw_privbk), GFP_KERNEL); + dev_set_drvdata(&cgdev->dev, privptr); + if (privptr == NULL) { + probe_error(cgdev); + put_device(&cgdev->dev); + CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM); + return -ENOMEM; + } + privptr->p_mtc_envelope = kzalloc(MAX_ENVELOPE_SIZE, GFP_KERNEL); + privptr->p_env = kzalloc(sizeof(struct claw_env), GFP_KERNEL); + if ((privptr->p_mtc_envelope == NULL) || (privptr->p_env == NULL)) { + probe_error(cgdev); + put_device(&cgdev->dev); + CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM); + return -ENOMEM; + } + memcpy(privptr->p_env->adapter_name, WS_NAME_NOT_DEF, 8); + memcpy(privptr->p_env->host_name, WS_NAME_NOT_DEF, 8); + memcpy(privptr->p_env->api_type, WS_NAME_NOT_DEF, 8); + privptr->p_env->packing = 0; + privptr->p_env->write_buffers = 5; + privptr->p_env->read_buffers = 5; + privptr->p_env->read_size = CLAW_FRAME_SIZE; + privptr->p_env->write_size = CLAW_FRAME_SIZE; + privptr->p_env->p_priv = privptr; + cgdev->cdev[0]->handler = claw_irq_handler; + cgdev->cdev[1]->handler = claw_irq_handler; + cgdev->dev.type = &claw_devtype; + CLAW_DBF_TEXT(2, setup, "prbext 0"); + + return 0; +} /* end of claw_probe */ /*--------------------------------------------------------------------* * claw_init and cleanup * *---------------------------------------------------------------------*/ -static void __exit -claw_cleanup(void) +static void __exit claw_cleanup(void) { - driver_remove_file(&claw_group_driver.driver, - &driver_attr_group); ccwgroup_driver_unregister(&claw_group_driver); ccw_driver_unregister(&claw_ccw_driver); root_device_unregister(claw_root_dev); claw_unregister_debug_facility(); pr_info("Driver unloaded\n"); - } /** @@ -3374,8 +3338,7 @@ * * @return 0 on success, !0 on error. */ -static int __init -claw_init(void) +static int __init claw_init(void) { int ret = 0; @@ -3394,7 +3357,7 @@ ret = ccw_driver_register(&claw_ccw_driver); if (ret) goto ccw_err; - claw_group_driver.driver.groups = claw_group_attr_groups; + claw_group_driver.driver.groups = claw_drv_attr_groups; ret = ccwgroup_driver_register(&claw_group_driver); if (ret) goto ccwgroup_err;
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index 11f3b07..3cd2554 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c
@@ -1296,6 +1296,11 @@ } +static const struct device_type ctcm_devtype = { + .name = "ctcm", + .groups = ctcm_attr_groups, +}; + /** * Add ctcm specific attributes. * Add ctcm private data. @@ -1307,7 +1312,6 @@ static int ctcm_probe_device(struct ccwgroup_device *cgdev) { struct ctcm_priv *priv; - int rc; CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, "%s %p", @@ -1324,17 +1328,11 @@ put_device(&cgdev->dev); return -ENOMEM; } - - rc = ctcm_add_files(&cgdev->dev); - if (rc) { - kfree(priv); - put_device(&cgdev->dev); - return rc; - } priv->buffer_size = CTCM_BUFSIZE_DEFAULT; cgdev->cdev[0]->handler = ctcm_irq_handler; cgdev->cdev[1]->handler = ctcm_irq_handler; dev_set_drvdata(&cgdev->dev, priv); + cgdev->dev.type = &ctcm_devtype; return 0; } @@ -1611,11 +1609,6 @@ goto out_dev; } - if (ctcm_add_attributes(&cgdev->dev)) { - result = -ENODEV; - goto out_unregister; - } - strlcpy(priv->fsm->name, dev->name, sizeof(priv->fsm->name)); dev_info(&dev->dev, @@ -1629,8 +1622,6 @@ priv->channel[CTCM_WRITE]->id, priv->protocol); return 0; -out_unregister: - unregister_netdev(dev); out_dev: ctcm_free_netdevice(dev); out_ccw2: @@ -1669,7 +1660,6 @@ /* Close the device */ ctcm_close(dev); dev->flags &= ~IFF_RUNNING; - ctcm_remove_attributes(&cgdev->dev); channel_free(priv->channel[CTCM_READ]); } else dev = NULL; @@ -1711,7 +1701,6 @@ if (cgdev->state == CCWGROUP_ONLINE) ctcm_shutdown_device(cgdev); - ctcm_remove_files(&cgdev->dev); dev_set_drvdata(&cgdev->dev, NULL); kfree(priv); put_device(&cgdev->dev); @@ -1778,9 +1767,7 @@ .owner = THIS_MODULE, .name = CTC_DRIVER_NAME, }, - .max_slaves = 2, - .driver_id = 0xC3E3C3D4, /* CTCM */ - .probe = ctcm_probe_device, + .setup = ctcm_probe_device, .remove = ctcm_remove_device, .set_online = ctcm_new_device, .set_offline = ctcm_shutdown_device, @@ -1789,31 +1776,25 @@ .restore = ctcm_pm_resume, }; -static ssize_t -ctcm_driver_group_store(struct device_driver *ddrv, const char *buf, - size_t count) +static ssize_t ctcm_driver_group_store(struct device_driver *ddrv, + const char *buf, size_t count) { int err; - err = ccwgroup_create_from_string(ctcm_root_dev, - ctcm_group_driver.driver_id, - &ctcm_ccw_driver, 2, buf); + err = ccwgroup_create_dev(ctcm_root_dev, &ctcm_group_driver, 2, buf); return err ? err : count; } - static DRIVER_ATTR(group, 0200, NULL, ctcm_driver_group_store); -static struct attribute *ctcm_group_attrs[] = { +static struct attribute *ctcm_drv_attrs[] = { &driver_attr_group.attr, NULL, }; - -static struct attribute_group ctcm_group_attr_group = { - .attrs = ctcm_group_attrs, +static struct attribute_group ctcm_drv_attr_group = { + .attrs = ctcm_drv_attrs, }; - -static const struct attribute_group *ctcm_group_attr_groups[] = { - &ctcm_group_attr_group, +static const struct attribute_group *ctcm_drv_attr_groups[] = { + &ctcm_drv_attr_group, NULL, }; @@ -1829,7 +1810,6 @@ */ static void __exit ctcm_exit(void) { - driver_remove_file(&ctcm_group_driver.driver, &driver_attr_group); ccwgroup_driver_unregister(&ctcm_group_driver); ccw_driver_unregister(&ctcm_ccw_driver); root_device_unregister(ctcm_root_dev); @@ -1867,7 +1847,7 @@ ret = ccw_driver_register(&ctcm_ccw_driver); if (ret) goto ccw_err; - ctcm_group_driver.driver.groups = ctcm_group_attr_groups; + ctcm_group_driver.driver.groups = ctcm_drv_attr_groups; ret = ccwgroup_driver_register(&ctcm_group_driver); if (ret) goto ccwgroup_err;
diff --git a/drivers/s390/net/ctcm_main.h b/drivers/s390/net/ctcm_main.h index 24d5215..b9056a5 100644 --- a/drivers/s390/net/ctcm_main.h +++ b/drivers/s390/net/ctcm_main.h
@@ -225,13 +225,7 @@ int ctcm_open(struct net_device *dev); int ctcm_close(struct net_device *dev); -/* - * prototypes for non-static sysfs functions - */ -int ctcm_add_attributes(struct device *dev); -void ctcm_remove_attributes(struct device *dev); -int ctcm_add_files(struct device *dev); -void ctcm_remove_files(struct device *dev); +extern const struct attribute_group *ctcm_attr_groups[]; /* * Compatibility macros for busy handling
diff --git a/drivers/s390/net/ctcm_sysfs.c b/drivers/s390/net/ctcm_sysfs.c index 650aec18..0c27ae7 100644 --- a/drivers/s390/net/ctcm_sysfs.c +++ b/drivers/s390/net/ctcm_sysfs.c
@@ -13,6 +13,7 @@ #define KMSG_COMPONENT "ctcm" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#include <linux/device.h> #include <linux/sysfs.h> #include <linux/slab.h> #include "ctcm_main.h" @@ -108,10 +109,12 @@ } static ssize_t stats_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { + struct ccwgroup_device *gdev = to_ccwgroupdev(dev); struct ctcm_priv *priv = dev_get_drvdata(dev); - if (!priv) + + if (!priv || gdev->state != CCWGROUP_ONLINE) return -ENODEV; ctcm_print_statistics(priv); return sprintf(buf, "0\n"); @@ -190,34 +193,14 @@ &dev_attr_protocol.attr, &dev_attr_type.attr, &dev_attr_buffer.attr, + &dev_attr_stats.attr, NULL, }; static struct attribute_group ctcm_attr_group = { .attrs = ctcm_attr, }; - -int ctcm_add_attributes(struct device *dev) -{ - int rc; - - rc = device_create_file(dev, &dev_attr_stats); - - return rc; -} - -void ctcm_remove_attributes(struct device *dev) -{ - device_remove_file(dev, &dev_attr_stats); -} - -int ctcm_add_files(struct device *dev) -{ - return sysfs_create_group(&dev->kobj, &ctcm_attr_group); -} - -void ctcm_remove_files(struct device *dev) -{ - sysfs_remove_group(&dev->kobj, &ctcm_attr_group); -} - +const struct attribute_group *ctcm_attr_groups[] = { + &ctcm_attr_group, + NULL, +};
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 687efe4..a3adf4b 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c
@@ -30,7 +30,6 @@ #include <linux/if.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> -#include <linux/trdevice.h> #include <linux/fddidevice.h> #include <linux/inetdevice.h> #include <linux/in.h> @@ -50,8 +49,7 @@ #include "lcs.h" -#if !defined(CONFIG_ETHERNET) && \ - !defined(CONFIG_TR) && !defined(CONFIG_FDDI) +#if !defined(CONFIG_ETHERNET) && !defined(CONFIG_FDDI) #error Cannot compile lcs.c without some net devices switched on. #endif @@ -1166,10 +1164,7 @@ lcs_get_mac_for_ipm(__be32 ipm, char *mac, struct net_device *dev) { LCS_DBF_TEXT(4,trace, "getmac"); - if (dev->type == ARPHRD_IEEE802_TR) - ip_tr_mc_map(ipm, mac); - else - ip_eth_mc_map(ipm, mac); + ip_eth_mc_map(ipm, mac); } /** @@ -1641,12 +1636,6 @@ return 0; #endif -#ifdef CONFIG_TR - card->lan_type = LCS_FRAME_TYPE_TR; - rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP); - if (rc == 0) - return 0; -#endif #ifdef CONFIG_FDDI card->lan_type = LCS_FRAME_TYPE_FDDI; rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP); @@ -2051,10 +2040,17 @@ &dev_attr_recover.attr, NULL, }; - static struct attribute_group lcs_attr_group = { .attrs = lcs_attrs, }; +static const struct attribute_group *lcs_attr_groups[] = { + &lcs_attr_group, + NULL, +}; +static const struct device_type lcs_devtype = { + .name = "lcs", + .groups = lcs_attr_groups, +}; /** * lcs_probe_device is called on establishing a new ccwgroup_device. @@ -2063,7 +2059,6 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev) { struct lcs_card *card; - int ret; if (!get_device(&ccwgdev->dev)) return -ENODEV; @@ -2075,12 +2070,6 @@ put_device(&ccwgdev->dev); return -ENOMEM; } - ret = sysfs_create_group(&ccwgdev->dev.kobj, &lcs_attr_group); - if (ret) { - lcs_free_card(card); - put_device(&ccwgdev->dev); - return ret; - } dev_set_drvdata(&ccwgdev->dev, card); ccwgdev->cdev[0]->handler = lcs_irq; ccwgdev->cdev[1]->handler = lcs_irq; @@ -2089,7 +2078,9 @@ card->thread_start_mask = 0; card->thread_allowed_mask = 0; card->thread_running_mask = 0; - return 0; + ccwgdev->dev.type = &lcs_devtype; + + return 0; } static int @@ -2172,12 +2163,6 @@ dev = alloc_etherdev(0); break; #endif -#ifdef CONFIG_TR - case LCS_FRAME_TYPE_TR: - card->lan_type_trans = tr_type_trans; - dev = alloc_trdev(0); - break; -#endif #ifdef CONFIG_FDDI case LCS_FRAME_TYPE_FDDI: card->lan_type_trans = fddi_type_trans; @@ -2323,9 +2308,9 @@ } if (card->dev) unregister_netdev(card->dev); - sysfs_remove_group(&ccwgdev->dev.kobj, &lcs_attr_group); lcs_cleanup_card(card); lcs_free_card(card); + dev_set_drvdata(&ccwgdev->dev, NULL); put_device(&ccwgdev->dev); } @@ -2410,9 +2395,7 @@ .owner = THIS_MODULE, .name = "lcs", }, - .max_slaves = 2, - .driver_id = 0xD3C3E2, - .probe = lcs_probe_device, + .setup = lcs_probe_device, .remove = lcs_remove_device, .set_online = lcs_new_device, .set_offline = lcs_shutdown_device, @@ -2423,30 +2406,24 @@ .restore = lcs_restore, }; -static ssize_t -lcs_driver_group_store(struct device_driver *ddrv, const char *buf, - size_t count) +static ssize_t lcs_driver_group_store(struct device_driver *ddrv, + const char *buf, size_t count) { int err; - err = ccwgroup_create_from_string(lcs_root_dev, - lcs_group_driver.driver_id, - &lcs_ccw_driver, 2, buf); + err = ccwgroup_create_dev(lcs_root_dev, &lcs_group_driver, 2, buf); return err ? err : count; } - static DRIVER_ATTR(group, 0200, NULL, lcs_driver_group_store); -static struct attribute *lcs_group_attrs[] = { +static struct attribute *lcs_drv_attrs[] = { &driver_attr_group.attr, NULL, }; - -static struct attribute_group lcs_group_attr_group = { - .attrs = lcs_group_attrs, +static struct attribute_group lcs_drv_attr_group = { + .attrs = lcs_drv_attrs, }; - -static const struct attribute_group *lcs_group_attr_groups[] = { - &lcs_group_attr_group, +static const struct attribute_group *lcs_drv_attr_groups[] = { + &lcs_drv_attr_group, NULL, }; @@ -2470,7 +2447,7 @@ rc = ccw_driver_register(&lcs_ccw_driver); if (rc) goto ccw_err; - lcs_group_driver.driver.groups = lcs_group_attr_groups; + lcs_group_driver.driver.groups = lcs_drv_attr_groups; rc = ccwgroup_driver_register(&lcs_group_driver); if (rc) goto ccwgroup_err; @@ -2496,8 +2473,6 @@ { pr_info("Terminating lcs module.\n"); LCS_DBF_TEXT(0, trace, "cleanup"); - driver_remove_file(&lcs_group_driver.driver, - &driver_attr_group); ccwgroup_driver_unregister(&lcs_group_driver); ccw_driver_unregister(&lcs_ccw_driver); root_device_unregister(lcs_root_dev);
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index ec7921b..06e8f31 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h
@@ -13,8 +13,6 @@ #include <linux/if.h> #include <linux/if_arp.h> -#include <linux/if_tr.h> -#include <linux/trdevice.h> #include <linux/etherdevice.h> #include <linux/if_vlan.h> #include <linux/ctype.h> @@ -676,8 +674,6 @@ struct qeth_ipa_info adp; /*Adapter parameters*/ struct qeth_routing_info route6; struct qeth_ipa_info ipa6; - int broadcast_mode; - int macaddr_mode; int fake_broadcast; int add_hhlen; int layer2; @@ -711,7 +707,16 @@ qdio_handler_t *input_handler; qdio_handler_t *output_handler; int (*recover)(void *ptr); - struct ccwgroup_driver *ccwgdriver; + int (*setup) (struct ccwgroup_device *); + void (*remove) (struct ccwgroup_device *); + int (*set_online) (struct ccwgroup_device *); + int (*set_offline) (struct ccwgroup_device *); + void (*shutdown)(struct ccwgroup_device *); + int (*prepare) (struct ccwgroup_device *); + void (*complete) (struct ccwgroup_device *); + int (*freeze)(struct ccwgroup_device *); + int (*thaw) (struct ccwgroup_device *); + int (*restore)(struct ccwgroup_device *); }; struct qeth_vlan_vid { @@ -775,7 +780,7 @@ struct qeth_perf_stats perf_stats; int read_or_write_problem; struct qeth_osn_info osn_info; - struct qeth_discipline discipline; + struct qeth_discipline *discipline; atomic_t force_alloc_skb; struct service_level qeth_service_level; struct qdio_ssqd_desc ssqd; @@ -841,16 +846,15 @@ return card->info.diagass_support & (__u32)cmd; } -extern struct ccwgroup_driver qeth_l2_ccwgroup_driver; -extern struct ccwgroup_driver qeth_l3_ccwgroup_driver; +extern struct qeth_discipline qeth_l2_discipline; +extern struct qeth_discipline qeth_l3_discipline; +extern const struct attribute_group *qeth_generic_attr_groups[]; +extern const struct attribute_group *qeth_osn_attr_groups[]; + const char *qeth_get_cardname_short(struct qeth_card *); int qeth_realloc_buffer_pool(struct qeth_card *, int); int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id); void qeth_core_free_discipline(struct qeth_card *); -int qeth_core_create_device_attributes(struct device *); -void qeth_core_remove_device_attributes(struct device *); -int qeth_core_create_osn_attributes(struct device *); -void qeth_core_remove_osn_attributes(struct device *); void qeth_buffer_reclaim_work(struct work_struct *); /* exports for qeth discipline device drivers */
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 8334dad..e118e1e 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c
@@ -1329,8 +1329,6 @@ { card->options.route4.type = NO_ROUTER; card->options.route6.type = NO_ROUTER; - card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS; - card->options.macaddr_mode = QETH_TR_MACADDR_NONCANONICAL; card->options.fake_broadcast = 0; card->options.add_hhlen = DEFAULT_ADD_HHLEN; card->options.performance_stats = 0; @@ -1365,7 +1363,7 @@ card->write.state != CH_STATE_UP) return; if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) { - ts = kthread_run(card->discipline.recover, (void *)card, + ts = kthread_run(card->discipline->recover, (void *)card, "qeth_recover"); if (IS_ERR(ts)) { qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); @@ -3339,7 +3337,7 @@ if (rc) { queue->card->stats.tx_errors += count; /* ignore temporary SIGA errors without busy condition */ - if (rc == QDIO_ERROR_SIGA_TARGET) + if (rc == -ENOBUFS) return; QETH_CARD_TEXT(queue->card, 2, "flushbuf"); QETH_CARD_TEXT_(queue->card, 2, " q%d", queue->queue_no); @@ -3533,7 +3531,7 @@ int i; QETH_CARD_TEXT(card, 6, "qdouhdl"); - if (qdio_error & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) { + if (qdio_error & QDIO_ERROR_FATAL) { QETH_CARD_TEXT(card, 2, "achkcond"); netif_stop_queue(card->dev); qeth_schedule_recovery(card); @@ -4629,7 +4627,7 @@ goto out_free_in_sbals; } for (i = 0; i < card->qdio.no_in_queues; ++i) - queue_start_poll[i] = card->discipline.start_poll; + queue_start_poll[i] = card->discipline->start_poll; qeth_qdio_establish_cq(card, in_sbal_ptrs, queue_start_poll); @@ -4653,8 +4651,8 @@ init_data.qib_param_field = qib_param_field; init_data.no_input_qs = card->qdio.no_in_queues; init_data.no_output_qs = card->qdio.no_out_queues; - init_data.input_handler = card->discipline.input_handler; - init_data.output_handler = card->discipline.output_handler; + init_data.input_handler = card->discipline->input_handler; + init_data.output_handler = card->discipline->output_handler; init_data.queue_start_poll_array = queue_start_poll; init_data.int_parm = (unsigned long) card; init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; @@ -4739,13 +4737,6 @@ .remove = ccwgroup_remove_ccwdev, }; -static int qeth_core_driver_group(const char *buf, struct device *root_dev, - unsigned long driver_id) -{ - return ccwgroup_create_from_string(root_dev, driver_id, - &qeth_ccw_driver, 3, buf); -} - int qeth_core_hardsetup_card(struct qeth_card *card) { int retries = 0; @@ -4911,11 +4902,7 @@ break; case QETH_HEADER_TYPE_LAYER3: skb_len = (*hdr)->hdr.l3.length; - if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || - (card->info.link_type == QETH_LINK_TYPE_HSTR)) - headroom = TR_HLEN; - else - headroom = ETH_HLEN; + headroom = ETH_HLEN; break; case QETH_HEADER_TYPE_OSN: skb_len = (*hdr)->hdr.osn.pdu_length; @@ -5046,17 +5033,15 @@ mutex_lock(&qeth_mod_mutex); switch (discipline) { case QETH_DISCIPLINE_LAYER3: - card->discipline.ccwgdriver = try_then_request_module( - symbol_get(qeth_l3_ccwgroup_driver), - "qeth_l3"); + card->discipline = try_then_request_module( + symbol_get(qeth_l3_discipline), "qeth_l3"); break; case QETH_DISCIPLINE_LAYER2: - card->discipline.ccwgdriver = try_then_request_module( - symbol_get(qeth_l2_ccwgroup_driver), - "qeth_l2"); + card->discipline = try_then_request_module( + symbol_get(qeth_l2_discipline), "qeth_l2"); break; } - if (!card->discipline.ccwgdriver) { + if (!card->discipline) { dev_err(&card->gdev->dev, "There is no kernel module to " "support discipline %d\n", discipline); rc = -EINVAL; @@ -5068,12 +5053,21 @@ void qeth_core_free_discipline(struct qeth_card *card) { if (card->options.layer2) - symbol_put(qeth_l2_ccwgroup_driver); + symbol_put(qeth_l2_discipline); else - symbol_put(qeth_l3_ccwgroup_driver); - card->discipline.ccwgdriver = NULL; + symbol_put(qeth_l3_discipline); + card->discipline = NULL; } +static const struct device_type qeth_generic_devtype = { + .name = "qeth_generic", + .groups = qeth_generic_attr_groups, +}; +static const struct device_type qeth_osn_devtype = { + .name = "qeth_osn", + .groups = qeth_osn_attr_groups, +}; + static int qeth_core_probe_device(struct ccwgroup_device *gdev) { struct qeth_card *card; @@ -5128,18 +5122,17 @@ } if (card->info.type == QETH_CARD_TYPE_OSN) - rc = qeth_core_create_osn_attributes(dev); + gdev->dev.type = &qeth_osn_devtype; else - rc = qeth_core_create_device_attributes(dev); - if (rc) - goto err_dbf; + gdev->dev.type = &qeth_generic_devtype; + switch (card->info.type) { case QETH_CARD_TYPE_OSN: case QETH_CARD_TYPE_OSM: rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2); if (rc) - goto err_attr; - rc = card->discipline.ccwgdriver->probe(card->gdev); + goto err_dbf; + rc = card->discipline->setup(card->gdev); if (rc) goto err_disc; case QETH_CARD_TYPE_OSD: @@ -5157,11 +5150,6 @@ err_disc: qeth_core_free_discipline(card); -err_attr: - if (card->info.type == QETH_CARD_TYPE_OSN) - qeth_core_remove_osn_attributes(dev); - else - qeth_core_remove_device_attributes(dev); err_dbf: debug_unregister(card->debug); err_card: @@ -5178,14 +5166,8 @@ QETH_DBF_TEXT(SETUP, 2, "removedv"); - if (card->info.type == QETH_CARD_TYPE_OSN) { - qeth_core_remove_osn_attributes(&gdev->dev); - } else { - qeth_core_remove_device_attributes(&gdev->dev); - } - - if (card->discipline.ccwgdriver) { - card->discipline.ccwgdriver->remove(gdev); + if (card->discipline) { + card->discipline->remove(gdev); qeth_core_free_discipline(card); } @@ -5205,7 +5187,7 @@ int rc = 0; int def_discipline; - if (!card->discipline.ccwgdriver) { + if (!card->discipline) { if (card->info.type == QETH_CARD_TYPE_IQD) def_discipline = QETH_DISCIPLINE_LAYER3; else @@ -5213,11 +5195,11 @@ rc = qeth_core_load_discipline(card, def_discipline); if (rc) goto err; - rc = card->discipline.ccwgdriver->probe(card->gdev); + rc = card->discipline->setup(card->gdev); if (rc) goto err; } - rc = card->discipline.ccwgdriver->set_online(gdev); + rc = card->discipline->set_online(gdev); err: return rc; } @@ -5225,58 +5207,52 @@ static int qeth_core_set_offline(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - return card->discipline.ccwgdriver->set_offline(gdev); + return card->discipline->set_offline(gdev); } static void qeth_core_shutdown(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline.ccwgdriver && - card->discipline.ccwgdriver->shutdown) - card->discipline.ccwgdriver->shutdown(gdev); + if (card->discipline && card->discipline->shutdown) + card->discipline->shutdown(gdev); } static int qeth_core_prepare(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline.ccwgdriver && - card->discipline.ccwgdriver->prepare) - return card->discipline.ccwgdriver->prepare(gdev); + if (card->discipline && card->discipline->prepare) + return card->discipline->prepare(gdev); return 0; } static void qeth_core_complete(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline.ccwgdriver && - card->discipline.ccwgdriver->complete) - card->discipline.ccwgdriver->complete(gdev); + if (card->discipline && card->discipline->complete) + card->discipline->complete(gdev); } static int qeth_core_freeze(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline.ccwgdriver && - card->discipline.ccwgdriver->freeze) - return card->discipline.ccwgdriver->freeze(gdev); + if (card->discipline && card->discipline->freeze) + return card->discipline->freeze(gdev); return 0; } static int qeth_core_thaw(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline.ccwgdriver && - card->discipline.ccwgdriver->thaw) - return card->discipline.ccwgdriver->thaw(gdev); + if (card->discipline && card->discipline->thaw) + return card->discipline->thaw(gdev); return 0; } static int qeth_core_restore(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline.ccwgdriver && - card->discipline.ccwgdriver->restore) - return card->discipline.ccwgdriver->restore(gdev); + if (card->discipline && card->discipline->restore) + return card->discipline->restore(gdev); return 0; } @@ -5285,8 +5261,7 @@ .owner = THIS_MODULE, .name = "qeth", }, - .driver_id = 0xD8C5E3C8, - .probe = qeth_core_probe_device, + .setup = qeth_core_probe_device, .remove = qeth_core_remove_device, .set_online = qeth_core_set_online, .set_offline = qeth_core_set_offline, @@ -5298,21 +5273,30 @@ .restore = qeth_core_restore, }; -static ssize_t -qeth_core_driver_group_store(struct device_driver *ddrv, const char *buf, - size_t count) +static ssize_t qeth_core_driver_group_store(struct device_driver *ddrv, + const char *buf, size_t count) { int err; - err = qeth_core_driver_group(buf, qeth_core_root_dev, - qeth_core_ccwgroup_driver.driver_id); - if (err) - return err; - else - return count; -} + err = ccwgroup_create_dev(qeth_core_root_dev, + &qeth_core_ccwgroup_driver, 3, buf); + + return err ? err : count; +} static DRIVER_ATTR(group, 0200, NULL, qeth_core_driver_group_store); +static struct attribute *qeth_drv_attrs[] = { + &driver_attr_group.attr, + NULL, +}; +static struct attribute_group qeth_drv_attr_group = { + .attrs = qeth_drv_attrs, +}; +static const struct attribute_group *qeth_drv_attr_groups[] = { + &qeth_drv_attr_group, + NULL, +}; + static struct { const char str[ETH_GSTRING_LEN]; } qeth_ethtool_stats_keys[] = { @@ -5550,49 +5534,41 @@ rc = qeth_register_dbf_views(); if (rc) goto out_err; - rc = ccw_driver_register(&qeth_ccw_driver); - if (rc) - goto ccw_err; - rc = ccwgroup_driver_register(&qeth_core_ccwgroup_driver); - if (rc) - goto ccwgroup_err; - rc = driver_create_file(&qeth_core_ccwgroup_driver.driver, - &driver_attr_group); - if (rc) - goto driver_err; qeth_core_root_dev = root_device_register("qeth"); rc = IS_ERR(qeth_core_root_dev) ? PTR_ERR(qeth_core_root_dev) : 0; if (rc) goto register_err; - qeth_core_header_cache = kmem_cache_create("qeth_hdr", sizeof(struct qeth_hdr) + ETH_HLEN, 64, 0, NULL); if (!qeth_core_header_cache) { rc = -ENOMEM; goto slab_err; } - qeth_qdio_outbuf_cache = kmem_cache_create("qeth_buf", sizeof(struct qeth_qdio_out_buffer), 0, 0, NULL); if (!qeth_qdio_outbuf_cache) { rc = -ENOMEM; goto cqslab_err; } + rc = ccw_driver_register(&qeth_ccw_driver); + if (rc) + goto ccw_err; + qeth_core_ccwgroup_driver.driver.groups = qeth_drv_attr_groups; + rc = ccwgroup_driver_register(&qeth_core_ccwgroup_driver); + if (rc) + goto ccwgroup_err; return 0; + +ccwgroup_err: + ccw_driver_unregister(&qeth_ccw_driver); +ccw_err: + kmem_cache_destroy(qeth_qdio_outbuf_cache); cqslab_err: kmem_cache_destroy(qeth_core_header_cache); slab_err: root_device_unregister(qeth_core_root_dev); register_err: - driver_remove_file(&qeth_core_ccwgroup_driver.driver, - &driver_attr_group); -driver_err: - ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); -ccwgroup_err: - ccw_driver_unregister(&qeth_ccw_driver); -ccw_err: - QETH_DBF_MESSAGE(2, "Initialization failed with code %d\n", rc); qeth_unregister_dbf_views(); out_err: pr_err("Initializing the qeth device driver failed\n"); @@ -5601,13 +5577,11 @@ static void __exit qeth_core_exit(void) { - root_device_unregister(qeth_core_root_dev); - driver_remove_file(&qeth_core_ccwgroup_driver.driver, - &driver_attr_group); ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); ccw_driver_unregister(&qeth_ccw_driver); kmem_cache_destroy(qeth_qdio_outbuf_cache); kmem_cache_destroy(qeth_core_header_cache); + root_device_unregister(qeth_core_root_dev); qeth_unregister_dbf_views(); pr_info("core functions removed\n"); }
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index ff41e42..a11b30c 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h
@@ -70,16 +70,6 @@ QETH_LINK_TYPE_ATM_NATIVE = 0x90, }; -enum qeth_tr_macaddr_modes { - QETH_TR_MACADDR_NONCANONICAL = 0, - QETH_TR_MACADDR_CANONICAL = 1, -}; - -enum qeth_tr_broadcast_modes { - QETH_TR_BROADCAST_ALLRINGS = 0, - QETH_TR_BROADCAST_LOCAL = 1, -}; - /* * Routing stuff */
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index 0a8e86c..f163af5 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c
@@ -434,8 +434,8 @@ goto out; else { card->info.mac_bits = 0; - if (card->discipline.ccwgdriver) { - card->discipline.ccwgdriver->remove(card->gdev); + if (card->discipline) { + card->discipline->remove(card->gdev); qeth_core_free_discipline(card); } } @@ -444,7 +444,7 @@ if (rc) goto out; - rc = card->discipline.ccwgdriver->probe(card->gdev); + rc = card->discipline->setup(card->gdev); out: mutex_unlock(&card->discipline_mutex); return rc ? rc : count; @@ -693,7 +693,6 @@ &dev_attr_inter_jumbo.attr, NULL, }; - static struct attribute_group qeth_device_blkt_group = { .name = "blkt", .attrs = qeth_blkt_device_attrs, @@ -716,11 +715,16 @@ &dev_attr_hw_trap.attr, NULL, }; - static struct attribute_group qeth_device_attr_group = { .attrs = qeth_device_attrs, }; +const struct attribute_group *qeth_generic_attr_groups[] = { + &qeth_device_attr_group, + &qeth_device_blkt_group, + NULL, +}; + static struct attribute *qeth_osn_device_attrs[] = { &dev_attr_state.attr, &dev_attr_chpid.attr, @@ -730,37 +734,10 @@ &dev_attr_recover.attr, NULL, }; - static struct attribute_group qeth_osn_device_attr_group = { .attrs = qeth_osn_device_attrs, }; - -int qeth_core_create_device_attributes(struct device *dev) -{ - int ret; - ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group); - if (ret) - return ret; - ret = sysfs_create_group(&dev->kobj, &qeth_device_blkt_group); - if (ret) - sysfs_remove_group(&dev->kobj, &qeth_device_attr_group); - - return 0; -} - -void qeth_core_remove_device_attributes(struct device *dev) -{ - sysfs_remove_group(&dev->kobj, &qeth_device_attr_group); - sysfs_remove_group(&dev->kobj, &qeth_device_blkt_group); -} - -int qeth_core_create_osn_attributes(struct device *dev) -{ - return sysfs_create_group(&dev->kobj, &qeth_osn_device_attr_group); -} - -void qeth_core_remove_osn_attributes(struct device *dev) -{ - sysfs_remove_group(&dev->kobj, &qeth_osn_device_attr_group); - return; -} +const struct attribute_group *qeth_osn_attr_groups[] = { + &qeth_osn_device_attr_group, + NULL, +};
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 0e7c29d..4269865 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c
@@ -882,12 +882,6 @@ INIT_LIST_HEAD(&card->mc_list); card->options.layer2 = 1; card->info.hwtrap = 0; - card->discipline.start_poll = qeth_qdio_start_poll; - card->discipline.input_handler = (qdio_handler_t *) - qeth_qdio_input_handler; - card->discipline.output_handler = (qdio_handler_t *) - qeth_qdio_output_handler; - card->discipline.recover = qeth_l2_recover; return 0; } @@ -1227,8 +1221,12 @@ return rc; } -struct ccwgroup_driver qeth_l2_ccwgroup_driver = { - .probe = qeth_l2_probe_device, +struct qeth_discipline qeth_l2_discipline = { + .start_poll = qeth_qdio_start_poll, + .input_handler = (qdio_handler_t *) qeth_qdio_input_handler, + .output_handler = (qdio_handler_t *) qeth_qdio_output_handler, + .recover = qeth_l2_recover, + .setup = qeth_l2_probe_device, .remove = qeth_l2_remove_device, .set_online = qeth_l2_set_online, .set_offline = qeth_l2_set_offline, @@ -1237,7 +1235,7 @@ .thaw = qeth_l2_pm_resume, .restore = qeth_l2_pm_resume, }; -EXPORT_SYMBOL_GPL(qeth_l2_ccwgroup_driver); +EXPORT_SYMBOL_GPL(qeth_l2_discipline); static int qeth_osn_send_control_data(struct qeth_card *card, int len, struct qeth_cmd_buffer *iob)
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index f859216..7be5e97 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c
@@ -976,57 +976,6 @@ return ct | QETH_CAST_UNICAST; } -static int qeth_l3_send_setadp_mode(struct qeth_card *card, __u32 command, - __u32 mode) -{ - int rc; - struct qeth_cmd_buffer *iob; - struct qeth_ipa_cmd *cmd; - - QETH_CARD_TEXT(card, 4, "adpmode"); - - iob = qeth_get_adapter_cmd(card, command, - sizeof(struct qeth_ipacmd_setadpparms)); - cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); - cmd->data.setadapterparms.data.mode = mode; - rc = qeth_send_ipa_cmd(card, iob, qeth_default_setadapterparms_cb, - NULL); - return rc; -} - -static int qeth_l3_setadapter_hstr(struct qeth_card *card) -{ - int rc; - - QETH_CARD_TEXT(card, 4, "adphstr"); - - if (qeth_adp_supported(card, IPA_SETADP_SET_BROADCAST_MODE)) { - rc = qeth_l3_send_setadp_mode(card, - IPA_SETADP_SET_BROADCAST_MODE, - card->options.broadcast_mode); - if (rc) - QETH_DBF_MESSAGE(2, "couldn't set broadcast mode on " - "device %s: x%x\n", - CARD_BUS_ID(card), rc); - rc = qeth_l3_send_setadp_mode(card, - IPA_SETADP_ALTER_MAC_ADDRESS, - card->options.macaddr_mode); - if (rc) - QETH_DBF_MESSAGE(2, "couldn't set macaddr mode on " - "device %s: x%x\n", CARD_BUS_ID(card), rc); - return rc; - } - if (card->options.broadcast_mode == QETH_TR_BROADCAST_LOCAL) - QETH_DBF_MESSAGE(2, "set adapter parameters not available " - "to set broadcast mode, using ALLRINGS " - "on device %s:\n", CARD_BUS_ID(card)); - if (card->options.macaddr_mode == QETH_TR_MACADDR_CANONICAL) - QETH_DBF_MESSAGE(2, "set adapter parameters not available " - "to set macaddr mode, using NONCANONICAL " - "on device %s:\n", CARD_BUS_ID(card)); - return 0; -} - static int qeth_l3_setadapter_parms(struct qeth_card *card) { int rc; @@ -1052,10 +1001,6 @@ " address failed\n"); } - if ((card->info.link_type == QETH_LINK_TYPE_HSTR) || - (card->info.link_type == QETH_LINK_TYPE_LANE_TR)) - rc = qeth_l3_setadapter_hstr(card); - return rc; } @@ -1671,10 +1616,7 @@ static void qeth_l3_get_mac_for_ipm(__u32 ipm, char *mac, struct net_device *dev) { - if (dev->type == ARPHRD_IEEE802_TR) - ip_tr_mc_map(ipm, mac); - else - ip_eth_mc_map(ipm, mac); + ip_eth_mc_map(ipm, mac); } static void qeth_l3_add_mc(struct qeth_card *card, struct in_device *in4_dev) @@ -1922,8 +1864,6 @@ #endif case __constant_htons(ETH_P_IP): ip_hdr = (struct iphdr *)skb->data; - (card->dev->type == ARPHRD_IEEE802_TR) ? - ip_tr_mc_map(ip_hdr->daddr, tg_addr): ip_eth_mc_map(ip_hdr->daddr, tg_addr); break; default: @@ -1959,12 +1899,7 @@ tg_addr, "FAKELL", card->dev->addr_len); } -#ifdef CONFIG_TR - if (card->dev->type == ARPHRD_IEEE802_TR) - skb->protocol = tr_type_trans(skb, card->dev); - else -#endif - skb->protocol = eth_type_trans(skb, card->dev); + skb->protocol = eth_type_trans(skb, card->dev); if (hdr->hdr.l3.ext_flags & (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) { @@ -2138,7 +2073,7 @@ struct net_device *netdev; rcu_read_lock(); - netdev = __vlan_find_dev_deep(dev, vid); + netdev = __vlan_find_dev_deep(card->dev, vid); rcu_read_unlock(); if (netdev == dev) { rc = QETH_VLAN_CARD; @@ -2883,13 +2818,7 @@ hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU; memcpy(hdr->hdr.l3.dest_addr, pkey, 16); } else { - /* passthrough */ - if ((skb->dev->type == ARPHRD_IEEE802_TR) && - !memcmp(skb->data + sizeof(struct qeth_hdr) + - sizeof(__u16), skb->dev->broadcast, 6)) { - hdr->hdr.l3.flags = QETH_CAST_BROADCAST | - QETH_HDR_PASSTHRU; - } else if (!memcmp(skb->data + sizeof(struct qeth_hdr), + if (!memcmp(skb->data + sizeof(struct qeth_hdr), skb->dev->broadcast, 6)) { /* broadcast? */ hdr->hdr.l3.flags = QETH_CAST_BROADCAST | @@ -3031,10 +2960,7 @@ skb_pull(new_skb, ETH_HLEN); } else { if (ipv == 4) { - if (card->dev->type == ARPHRD_IEEE802_TR) - skb_pull(new_skb, TR_HLEN); - else - skb_pull(new_skb, ETH_HLEN); + skb_pull(new_skb, ETH_HLEN); } if (ipv != 4 && vlan_tx_tag_present(new_skb)) { @@ -3318,12 +3244,8 @@ card->info.type == QETH_CARD_TYPE_OSX) { if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || (card->info.link_type == QETH_LINK_TYPE_HSTR)) { -#ifdef CONFIG_TR - card->dev = alloc_trdev(0); -#endif - if (!card->dev) - return -ENODEV; - card->dev->netdev_ops = &qeth_l3_netdev_ops; + pr_info("qeth_l3: ignoring TR device\n"); + return -ENODEV; } else { card->dev = alloc_etherdev(0); if (!card->dev) @@ -3376,12 +3298,6 @@ qeth_l3_create_device_attributes(&gdev->dev); card->options.layer2 = 0; card->info.hwtrap = 0; - card->discipline.start_poll = qeth_qdio_start_poll; - card->discipline.input_handler = (qdio_handler_t *) - qeth_qdio_input_handler; - card->discipline.output_handler = (qdio_handler_t *) - qeth_qdio_output_handler; - card->discipline.recover = qeth_l3_recover; return 0; } @@ -3656,8 +3572,12 @@ return rc; } -struct ccwgroup_driver qeth_l3_ccwgroup_driver = { - .probe = qeth_l3_probe_device, +struct qeth_discipline qeth_l3_discipline = { + .start_poll = qeth_qdio_start_poll, + .input_handler = (qdio_handler_t *) qeth_qdio_input_handler, + .output_handler = (qdio_handler_t *) qeth_qdio_output_handler, + .recover = qeth_l3_recover, + .setup = qeth_l3_probe_device, .remove = qeth_l3_remove_device, .set_online = qeth_l3_set_online, .set_offline = qeth_l3_set_offline, @@ -3666,7 +3586,7 @@ .thaw = qeth_l3_pm_resume, .restore = qeth_l3_pm_resume, }; -EXPORT_SYMBOL_GPL(qeth_l3_ccwgroup_driver); +EXPORT_SYMBOL_GPL(qeth_l3_discipline); static int qeth_l3_ip_event(struct notifier_block *this, unsigned long event, void *ptr) @@ -3680,9 +3600,9 @@ return NOTIFY_DONE; card = qeth_l3_get_card_from_dev(dev); - QETH_CARD_TEXT(card, 3, "ipevent"); if (!card) return NOTIFY_DONE; + QETH_CARD_TEXT(card, 3, "ipevent"); addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV4); if (addr != NULL) {
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index d979bb2..4cafedf 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c
@@ -175,116 +175,6 @@ static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show, qeth_l3_dev_fake_broadcast_store); -static ssize_t qeth_l3_dev_broadcast_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct qeth_card *card = dev_get_drvdata(dev); - - if (!card) - return -EINVAL; - - if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || - (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) - return sprintf(buf, "n/a\n"); - - return sprintf(buf, "%s\n", (card->options.broadcast_mode == - QETH_TR_BROADCAST_ALLRINGS)? - "all rings":"local"); -} - -static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct qeth_card *card = dev_get_drvdata(dev); - char *tmp; - int rc = 0; - - if (!card) - return -EINVAL; - - mutex_lock(&card->conf_mutex); - if ((card->state != CARD_STATE_DOWN) && - (card->state != CARD_STATE_RECOVER)) { - rc = -EPERM; - goto out; - } - - if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || - (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { - rc = -EINVAL; - goto out; - } - - tmp = strsep((char **) &buf, "\n"); - - if (!strcmp(tmp, "local")) - card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL; - else if (!strcmp(tmp, "all_rings")) - card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS; - else - rc = -EINVAL; -out: - mutex_unlock(&card->conf_mutex); - return rc ? rc : count; -} - -static DEVICE_ATTR(broadcast_mode, 0644, qeth_l3_dev_broadcast_mode_show, - qeth_l3_dev_broadcast_mode_store); - -static ssize_t qeth_l3_dev_canonical_macaddr_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct qeth_card *card = dev_get_drvdata(dev); - - if (!card) - return -EINVAL; - - if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || - (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) - return sprintf(buf, "n/a\n"); - - return sprintf(buf, "%i\n", (card->options.macaddr_mode == - QETH_TR_MACADDR_CANONICAL)? 1:0); -} - -static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct qeth_card *card = dev_get_drvdata(dev); - char *tmp; - int i, rc = 0; - - if (!card) - return -EINVAL; - - mutex_lock(&card->conf_mutex); - if ((card->state != CARD_STATE_DOWN) && - (card->state != CARD_STATE_RECOVER)) { - rc = -EPERM; - goto out; - } - - if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || - (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { - rc = -EINVAL; - goto out; - } - - i = simple_strtoul(buf, &tmp, 16); - if ((i == 0) || (i == 1)) - card->options.macaddr_mode = i? - QETH_TR_MACADDR_CANONICAL : - QETH_TR_MACADDR_NONCANONICAL; - else - rc = -EINVAL; -out: - mutex_unlock(&card->conf_mutex); - return rc ? rc : count; -} - -static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show, - qeth_l3_dev_canonical_macaddr_store); - static ssize_t qeth_l3_dev_sniffer_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -458,8 +348,6 @@ &dev_attr_route4.attr, &dev_attr_route6.attr, &dev_attr_fake_broadcast.attr, - &dev_attr_broadcast_mode.attr, - &dev_attr_canonical_macaddr.attr, &dev_attr_sniffer.attr, &dev_attr_hsuid.attr, NULL,
diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index 04a154f..df740cb 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c
@@ -572,7 +572,7 @@ } -int __init atari_scsi_detect(struct scsi_host_template *host) +static int __init atari_scsi_detect(struct scsi_host_template *host) { static int called = 0; struct Scsi_Host *instance; @@ -724,7 +724,7 @@ return 1; } -int atari_scsi_release(struct Scsi_Host *sh) +static int atari_scsi_release(struct Scsi_Host *sh) { if (IS_A_TT()) free_irq(IRQ_TT_MFP_SCSI, sh); @@ -734,17 +734,21 @@ return 1; } -void __init atari_scsi_setup(char *str, int *ints) +#ifndef MODULE +static int __init atari_scsi_setup(char *str) { /* Format of atascsi parameter is: * atascsi=<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags> * Defaults depend on TT or Falcon, hostid determined at run time. * Negative values mean don't change. */ + int ints[6]; + + get_options(str, ARRAY_SIZE(ints), ints); if (ints[0] < 1) { printk("atari_scsi_setup: no arguments!\n"); - return; + return 0; } if (ints[0] >= 1) { @@ -777,9 +781,14 @@ setup_use_tagged_queuing = !!ints[5]; } #endif + + return 1; } -int atari_scsi_bus_reset(Scsi_Cmnd *cmd) +__setup("atascsi=", atari_scsi_setup); +#endif /* !MODULE */ + +static int atari_scsi_bus_reset(Scsi_Cmnd *cmd) { int rv; struct NCR5380_hostdata *hostdata = @@ -852,7 +861,7 @@ #endif -const char *atari_scsi_info(struct Scsi_Host *host) +static const char *atari_scsi_info(struct Scsi_Host *host) { /* atari_scsi_detect() is verbose enough... */ static const char string[] = "Atari native SCSI"; @@ -862,8 +871,9 @@ #if defined(REAL_DMA) -unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance, void *data, - unsigned long count, int dir) +static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance, + void *data, unsigned long count, + int dir) { unsigned long addr = virt_to_phys(data);
diff --git a/drivers/scsi/atari_scsi.h b/drivers/scsi/atari_scsi.h index efadb8d5..bd52df7 100644 --- a/drivers/scsi/atari_scsi.h +++ b/drivers/scsi/atari_scsi.h
@@ -18,11 +18,6 @@ /* (I_HAVE_OVERRUNS stuff removed) */ #ifndef ASM -int atari_scsi_detect (struct scsi_host_template *); -const char *atari_scsi_info (struct Scsi_Host *); -int atari_scsi_reset (Scsi_Cmnd *, unsigned int); -int atari_scsi_release (struct Scsi_Host *); - /* The values for CMD_PER_LUN and CAN_QUEUE are somehow arbitrary. Higher * values should work, too; try it! (but cmd_per_lun costs memory!) */
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 351dc0b..a3a056a9 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c
@@ -218,6 +218,9 @@ if (!shost->shost_gendev.parent) shost->shost_gendev.parent = dev ? dev : &platform_bus; + if (!dma_dev) + dma_dev = shost->shost_gendev.parent; + shost->dma_dev = dma_dev; error = device_add(&shost->shost_gendev);
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index f74cc06..bc3cc6d 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -1367,6 +1367,9 @@ struct qla_hw_data *ha = vha->hw; int rval = 0; + if (ha->flags.isp82xx_reset_hdlr_active) + return -EBUSY; + rval = qla2x00_optrom_setup(bsg_job, vha, 0); if (rval) return rval;
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 897731b..62324a1 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -15,7 +15,7 @@ * | Mailbox commands | 0x113e | 0x112c-0x112e | * | | | 0x113a | * | Device Discovery | 0x2086 | 0x2020-0x2022 | - * | Queue Command and IO tracing | 0x302f | 0x3006,0x3008 | + * | Queue Command and IO tracing | 0x3030 | 0x3006,0x3008 | * | | | 0x302d-0x302e | * | DPC Thread | 0x401c | | * | Async Events | 0x505d | 0x502b-0x502f |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index f79844c..ce422880 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1715,13 +1715,24 @@ res = DID_ERROR << 16; break; } - } else { + } else if (lscsi_status != SAM_STAT_TASK_SET_FULL && + lscsi_status != SAM_STAT_BUSY) { + /* + * scsi status of task set and busy are considered to be + * task not completed. + */ + ql_dbg(ql_dbg_io, fcport->vha, 0x301f, "Dropped frame(s) detected (0x%x " - "of 0x%x bytes).\n", resid, scsi_bufflen(cp)); + "of 0x%x bytes).\n", resid, + scsi_bufflen(cp)); res = DID_ERROR << 16 | lscsi_status; goto check_scsi_status; + } else { + ql_dbg(ql_dbg_io, fcport->vha, 0x3030, + "scsi_status: 0x%x, lscsi_status: 0x%x\n", + scsi_status, lscsi_status); } res = DID_OK << 16 | lscsi_status;
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index f0528539..de722a9 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -3125,6 +3125,7 @@ ql_log(ql_log_info, vha, 0x00b7, "HW State: COLD/RE-INIT.\n"); qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_COLD); + qla82xx_set_rst_ready(ha); if (ql2xmdenable) { if (qla82xx_md_collect(vha)) ql_log(ql_log_warn, vha, 0xb02c,
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index a2f9992..7db8033 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -3577,9 +3577,25 @@ continue; /* Attempt a retry. */ status = 1; - } else + } else { status = qla2x00_fabric_login(vha, fcport, &next_loopid); + if (status == QLA_SUCCESS) { + int status2; + uint8_t opts; + + opts = 0; + if (fcport->flags & + FCF_FCP2_DEVICE) + opts |= BIT_1; + status2 = + qla2x00_get_port_database( + vha, fcport, + opts); + if (status2 != QLA_SUCCESS) + status = 1; + } + } } else status = qla2x00_local_device_login(vha, fcport);
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 3c13c0a..a683e76 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -1017,6 +1017,9 @@ !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha)) return; + if (ha->flags.isp82xx_reset_hdlr_active) + return; + ha->isp_ops->read_optrom(vha, (uint8_t *)&hdr, ha->flt_region_npiv_conf << 2, sizeof(struct qla_npiv_header)); if (hdr.version == __constant_cpu_to_le16(0xffff))
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 29d780c..f5fdb16 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,9 +7,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.03.07.13-k" +#define QLA2XXX_VERSION "8.04.00.03-k" #define QLA_DRIVER_MAJOR_VER 8 -#define QLA_DRIVER_MINOR_VER 3 -#define QLA_DRIVER_PATCH_VER 7 +#define QLA_DRIVER_MINOR_VER 4 +#define QLA_DRIVER_PATCH_VER 0 #define QLA_DRIVER_BETA_VER 3
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index efccd72c..1b38431 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c
@@ -175,7 +175,8 @@ if (cmd->comp) complete_all(cmd->comp); - mempool_free(cmd, virtscsi_cmd_pool); + else + mempool_free(cmd, virtscsi_cmd_pool); } static void virtscsi_ctrl_done(struct virtqueue *vq) @@ -311,21 +312,22 @@ static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) { DECLARE_COMPLETION_ONSTACK(comp); - int ret; + int ret = FAILED; cmd->comp = ∁ - ret = virtscsi_kick_cmd(vscsi, vscsi->ctrl_vq, cmd, - sizeof cmd->req.tmf, sizeof cmd->resp.tmf, - GFP_NOIO); - if (ret < 0) - return FAILED; + if (virtscsi_kick_cmd(vscsi, vscsi->ctrl_vq, cmd, + sizeof cmd->req.tmf, sizeof cmd->resp.tmf, + GFP_NOIO) < 0) + goto out; wait_for_completion(&comp); - if (cmd->resp.tmf.response != VIRTIO_SCSI_S_OK && - cmd->resp.tmf.response != VIRTIO_SCSI_S_FUNCTION_SUCCEEDED) - return FAILED; + if (cmd->resp.tmf.response == VIRTIO_SCSI_S_OK || + cmd->resp.tmf.response == VIRTIO_SCSI_S_FUNCTION_SUCCEEDED) + ret = SUCCESS; - return SUCCESS; +out: + mempool_free(cmd, virtscsi_cmd_pool); + return ret; } static int virtscsi_device_reset(struct scsi_cmnd *sc)
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 7ed58e2..f286955 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c
@@ -169,6 +169,7 @@ inode = file->f_mapping->host; if (S_ISBLK(inode->i_mode)) { struct request_queue *q; + unsigned long long dev_size; /* * Setup the local scope queue_limits from struct request_queue->limits * to pass into transport_add_device_to_core_hba() as struct se_dev_limits. @@ -183,13 +184,12 @@ * one (1) logical sector from underlying struct block_device */ fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev); - fd_dev->fd_dev_size = (i_size_read(file->f_mapping->host) - + dev_size = (i_size_read(file->f_mapping->host) - fd_dev->fd_block_size); pr_debug("FILEIO: Using size: %llu bytes from struct" " block_device blocks: %llu logical_block_size: %d\n", - fd_dev->fd_dev_size, - div_u64(fd_dev->fd_dev_size, fd_dev->fd_block_size), + dev_size, div_u64(dev_size, fd_dev->fd_block_size), fd_dev->fd_block_size); } else { if (!(fd_dev->fbd_flags & FBDF_HAS_SIZE)) { @@ -605,10 +605,20 @@ static sector_t fd_get_blocks(struct se_device *dev) { struct fd_dev *fd_dev = dev->dev_ptr; - unsigned long long blocks_long = div_u64(fd_dev->fd_dev_size, - dev->se_sub_dev->se_dev_attrib.block_size); + struct file *f = fd_dev->fd_file; + struct inode *i = f->f_mapping->host; + unsigned long long dev_size; + /* + * When using a file that references an underlying struct block_device, + * ensure dev_size is always based on the current inode size in order + * to handle underlying block_device resize operations. + */ + if (S_ISBLK(i->i_mode)) + dev_size = (i_size_read(i) - fd_dev->fd_block_size); + else + dev_size = fd_dev->fd_dev_size; - return blocks_long; + return div_u64(dev_size, dev->se_sub_dev->se_dev_attrib.block_size); } static struct se_subsystem_api fileio_template = {
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 86f0c3b..c3148b1 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c
@@ -220,6 +220,9 @@ if (dev->dev_reserved_node_acl != sess->se_node_acl) goto out_unlock; + if (dev->dev_res_bin_isid != sess->sess_bin_isid) + goto out_unlock; + dev->dev_reserved_node_acl = NULL; dev->dev_flags &= ~DF_SPC2_RESERVATIONS; if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) {
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 70c3ffb..e320ec2 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c
@@ -60,7 +60,6 @@ int i; struct se_dev_entry *deve; struct se_lun *lun; - struct se_lun_acl *acl, *acl_tmp; spin_lock_irq(&nacl->device_list_lock); for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { @@ -81,28 +80,7 @@ core_update_device_list_for_node(lun, NULL, deve->mapped_lun, TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg, 0); - spin_lock(&lun->lun_acl_lock); - list_for_each_entry_safe(acl, acl_tmp, - &lun->lun_acl_list, lacl_list) { - if (!strcmp(acl->initiatorname, nacl->initiatorname) && - (acl->mapped_lun == deve->mapped_lun)) - break; - } - - if (!acl) { - pr_err("Unable to locate struct se_lun_acl for %s," - " mapped_lun: %u\n", nacl->initiatorname, - deve->mapped_lun); - spin_unlock(&lun->lun_acl_lock); - spin_lock_irq(&nacl->device_list_lock); - continue; - } - - list_del(&acl->lacl_list); - spin_unlock(&lun->lun_acl_lock); - spin_lock_irq(&nacl->device_list_lock); - kfree(acl); } spin_unlock_irq(&nacl->device_list_lock); }
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 29ca20d..3b0c4e3 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c
@@ -2044,7 +2044,7 @@ kbd->default_ledflagstate = ((arg >> 4) & 7); set_leds(); spin_unlock_irqrestore(&kbd_event_lock, flags); - break; + return 0; /* the ioctls below only set the lights, not the functions */ /* for those, see KDGKBLED and KDSKBLED above */
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 5234365..d4f823f 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c
@@ -637,7 +637,7 @@ DBG(cdev, "%s\n", __func__); - rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3, + rndis_set_param_medium(rndis->config, RNDIS_MEDIUM_802_3, bitrate(cdev->gadget) / 100); rndis_signal_connect(rndis->config); } @@ -648,7 +648,7 @@ DBG(geth->func.config->cdev, "%s\n", __func__); - rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3, 0); + rndis_set_param_medium(rndis->config, RNDIS_MEDIUM_802_3, 0); rndis_signal_disconnect(rndis->config); } @@ -765,7 +765,7 @@ goto fail; rndis->config = status; - rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3, 0); + rndis_set_param_medium(rndis->config, RNDIS_MEDIUM_802_3, 0); rndis_set_host_mac(rndis->config, rndis->ethaddr); #if 0
diff --git a/drivers/usb/gadget/ndis.h b/drivers/usb/gadget/ndis.h index b0e52fc..a19f72d 100644 --- a/drivers/usb/gadget/ndis.h +++ b/drivers/usb/gadget/ndis.h
@@ -15,11 +15,6 @@ #ifndef _LINUX_NDIS_H #define _LINUX_NDIS_H - -#define NDIS_STATUS_MULTICAST_FULL 0xC0010009 -#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A -#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B - enum NDIS_DEVICE_POWER_STATE { NdisDeviceStateUnspecified = 0, NdisDeviceStateD0, @@ -35,11 +30,6 @@ enum NDIS_DEVICE_POWER_STATE MinLinkChangeWakeUp; }; -/* NDIS_PNP_CAPABILITIES.Flags constants */ -#define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001 -#define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 -#define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 - struct NDIS_PNP_CAPABILITIES { __le32 Flags; struct NDIS_PM_WAKE_UP_CAPABILITIES WakeUpCapabilities; @@ -54,158 +44,4 @@ __le32 PatternFlags; }; - -/* Required Object IDs (OIDs) */ -#define OID_GEN_SUPPORTED_LIST 0x00010101 -#define OID_GEN_HARDWARE_STATUS 0x00010102 -#define OID_GEN_MEDIA_SUPPORTED 0x00010103 -#define OID_GEN_MEDIA_IN_USE 0x00010104 -#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 -#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 -#define OID_GEN_LINK_SPEED 0x00010107 -#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 -#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 -#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A -#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B -#define OID_GEN_VENDOR_ID 0x0001010C -#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D -#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E -#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F -#define OID_GEN_DRIVER_VERSION 0x00010110 -#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 -#define OID_GEN_PROTOCOL_OPTIONS 0x00010112 -#define OID_GEN_MAC_OPTIONS 0x00010113 -#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 -#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 -#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 -#define OID_GEN_SUPPORTED_GUIDS 0x00010117 -#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 -#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 -#define OID_GEN_MACHINE_NAME 0x0001021A -#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B -#define OID_GEN_VLAN_ID 0x0001021C - -/* Optional OIDs */ -#define OID_GEN_MEDIA_CAPABILITIES 0x00010201 -#define OID_GEN_PHYSICAL_MEDIUM 0x00010202 - -/* Required statistics OIDs */ -#define OID_GEN_XMIT_OK 0x00020101 -#define OID_GEN_RCV_OK 0x00020102 -#define OID_GEN_XMIT_ERROR 0x00020103 -#define OID_GEN_RCV_ERROR 0x00020104 -#define OID_GEN_RCV_NO_BUFFER 0x00020105 - -/* Optional statistics OIDs */ -#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 -#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 -#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 -#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 -#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 -#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 -#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 -#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 -#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 -#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A -#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B -#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C -#define OID_GEN_RCV_CRC_ERROR 0x0002020D -#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E -#define OID_GEN_GET_TIME_CAPS 0x0002020F -#define OID_GEN_GET_NETCARD_TIME 0x00020210 -#define OID_GEN_NETCARD_LOAD 0x00020211 -#define OID_GEN_DEVICE_PROFILE 0x00020212 -#define OID_GEN_INIT_TIME_MS 0x00020213 -#define OID_GEN_RESET_COUNTS 0x00020214 -#define OID_GEN_MEDIA_SENSE_COUNTS 0x00020215 -#define OID_GEN_FRIENDLY_NAME 0x00020216 -#define OID_GEN_MINIPORT_INFO 0x00020217 -#define OID_GEN_RESET_VERIFY_PARAMETERS 0x00020218 - -/* IEEE 802.3 (Ethernet) OIDs */ -#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 - -#define OID_802_3_PERMANENT_ADDRESS 0x01010101 -#define OID_802_3_CURRENT_ADDRESS 0x01010102 -#define OID_802_3_MULTICAST_LIST 0x01010103 -#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 -#define OID_802_3_MAC_OPTIONS 0x01010105 -#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 -#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 -#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 -#define OID_802_3_XMIT_DEFERRED 0x01020201 -#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 -#define OID_802_3_RCV_OVERRUN 0x01020203 -#define OID_802_3_XMIT_UNDERRUN 0x01020204 -#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 -#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 -#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 - -/* OID_GEN_MINIPORT_INFO constants */ -#define NDIS_MINIPORT_BUS_MASTER 0x00000001 -#define NDIS_MINIPORT_WDM_DRIVER 0x00000002 -#define NDIS_MINIPORT_SG_LIST 0x00000004 -#define NDIS_MINIPORT_SUPPORTS_MEDIA_QUERY 0x00000008 -#define NDIS_MINIPORT_INDICATES_PACKETS 0x00000010 -#define NDIS_MINIPORT_IGNORE_PACKET_QUEUE 0x00000020 -#define NDIS_MINIPORT_IGNORE_REQUEST_QUEUE 0x00000040 -#define NDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00000080 -#define NDIS_MINIPORT_INTERMEDIATE_DRIVER 0x00000100 -#define NDIS_MINIPORT_IS_NDIS_5 0x00000200 -#define NDIS_MINIPORT_IS_CO 0x00000400 -#define NDIS_MINIPORT_DESERIALIZE 0x00000800 -#define NDIS_MINIPORT_REQUIRES_MEDIA_POLLING 0x00001000 -#define NDIS_MINIPORT_SUPPORTS_MEDIA_SENSE 0x00002000 -#define NDIS_MINIPORT_NETBOOT_CARD 0x00004000 -#define NDIS_MINIPORT_PM_SUPPORTED 0x00008000 -#define NDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00010000 -#define NDIS_MINIPORT_USES_SAFE_BUFFER_APIS 0x00020000 -#define NDIS_MINIPORT_HIDDEN 0x00040000 -#define NDIS_MINIPORT_SWENUM 0x00080000 -#define NDIS_MINIPORT_SURPRISE_REMOVE_OK 0x00100000 -#define NDIS_MINIPORT_NO_HALT_ON_SUSPEND 0x00200000 -#define NDIS_MINIPORT_HARDWARE_DEVICE 0x00400000 -#define NDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS 0x00800000 -#define NDIS_MINIPORT_64BITS_DMA 0x01000000 - -#define NDIS_MEDIUM_802_3 0x00000000 -#define NDIS_MEDIUM_802_5 0x00000001 -#define NDIS_MEDIUM_FDDI 0x00000002 -#define NDIS_MEDIUM_WAN 0x00000003 -#define NDIS_MEDIUM_LOCAL_TALK 0x00000004 -#define NDIS_MEDIUM_DIX 0x00000005 -#define NDIS_MEDIUM_ARCENT_RAW 0x00000006 -#define NDIS_MEDIUM_ARCENT_878_2 0x00000007 -#define NDIS_MEDIUM_ATM 0x00000008 -#define NDIS_MEDIUM_WIRELESS_LAN 0x00000009 -#define NDIS_MEDIUM_IRDA 0x0000000A -#define NDIS_MEDIUM_BPC 0x0000000B -#define NDIS_MEDIUM_CO_WAN 0x0000000C -#define NDIS_MEDIUM_1394 0x0000000D - -#define NDIS_PACKET_TYPE_DIRECTED 0x00000001 -#define NDIS_PACKET_TYPE_MULTICAST 0x00000002 -#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 -#define NDIS_PACKET_TYPE_BROADCAST 0x00000008 -#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 -#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 -#define NDIS_PACKET_TYPE_SMT 0x00000040 -#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 -#define NDIS_PACKET_TYPE_GROUP 0x00000100 -#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200 -#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400 -#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800 - -#define NDIS_MEDIA_STATE_CONNECTED 0x00000000 -#define NDIS_MEDIA_STATE_DISCONNECTED 0x00000001 - -#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 -#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 -#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 -#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 -#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 -#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 -#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040 -#define NDIS_MAC_OPTION_RESERVED 0x80000000 - #endif /* _LINUX_NDIS_H */
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 73a934a..b35babe 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c
@@ -73,65 +73,65 @@ static const u32 oid_supported_list[] = { /* the general stuff */ - OID_GEN_SUPPORTED_LIST, - OID_GEN_HARDWARE_STATUS, - OID_GEN_MEDIA_SUPPORTED, - OID_GEN_MEDIA_IN_USE, - OID_GEN_MAXIMUM_FRAME_SIZE, - OID_GEN_LINK_SPEED, - OID_GEN_TRANSMIT_BLOCK_SIZE, - OID_GEN_RECEIVE_BLOCK_SIZE, - OID_GEN_VENDOR_ID, - OID_GEN_VENDOR_DESCRIPTION, - OID_GEN_VENDOR_DRIVER_VERSION, - OID_GEN_CURRENT_PACKET_FILTER, - OID_GEN_MAXIMUM_TOTAL_SIZE, - OID_GEN_MEDIA_CONNECT_STATUS, - OID_GEN_PHYSICAL_MEDIUM, + RNDIS_OID_GEN_SUPPORTED_LIST, + RNDIS_OID_GEN_HARDWARE_STATUS, + RNDIS_OID_GEN_MEDIA_SUPPORTED, + RNDIS_OID_GEN_MEDIA_IN_USE, + RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE, + RNDIS_OID_GEN_LINK_SPEED, + RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE, + RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE, + RNDIS_OID_GEN_VENDOR_ID, + RNDIS_OID_GEN_VENDOR_DESCRIPTION, + RNDIS_OID_GEN_VENDOR_DRIVER_VERSION, + RNDIS_OID_GEN_CURRENT_PACKET_FILTER, + RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE, + RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, + RNDIS_OID_GEN_PHYSICAL_MEDIUM, /* the statistical stuff */ - OID_GEN_XMIT_OK, - OID_GEN_RCV_OK, - OID_GEN_XMIT_ERROR, - OID_GEN_RCV_ERROR, - OID_GEN_RCV_NO_BUFFER, + RNDIS_OID_GEN_XMIT_OK, + RNDIS_OID_GEN_RCV_OK, + RNDIS_OID_GEN_XMIT_ERROR, + RNDIS_OID_GEN_RCV_ERROR, + RNDIS_OID_GEN_RCV_NO_BUFFER, #ifdef RNDIS_OPTIONAL_STATS - OID_GEN_DIRECTED_BYTES_XMIT, - OID_GEN_DIRECTED_FRAMES_XMIT, - OID_GEN_MULTICAST_BYTES_XMIT, - OID_GEN_MULTICAST_FRAMES_XMIT, - OID_GEN_BROADCAST_BYTES_XMIT, - OID_GEN_BROADCAST_FRAMES_XMIT, - OID_GEN_DIRECTED_BYTES_RCV, - OID_GEN_DIRECTED_FRAMES_RCV, - OID_GEN_MULTICAST_BYTES_RCV, - OID_GEN_MULTICAST_FRAMES_RCV, - OID_GEN_BROADCAST_BYTES_RCV, - OID_GEN_BROADCAST_FRAMES_RCV, - OID_GEN_RCV_CRC_ERROR, - OID_GEN_TRANSMIT_QUEUE_LENGTH, + RNDIS_OID_GEN_DIRECTED_BYTES_XMIT, + RNDIS_OID_GEN_DIRECTED_FRAMES_XMIT, + RNDIS_OID_GEN_MULTICAST_BYTES_XMIT, + RNDIS_OID_GEN_MULTICAST_FRAMES_XMIT, + RNDIS_OID_GEN_BROADCAST_BYTES_XMIT, + RNDIS_OID_GEN_BROADCAST_FRAMES_XMIT, + RNDIS_OID_GEN_DIRECTED_BYTES_RCV, + RNDIS_OID_GEN_DIRECTED_FRAMES_RCV, + RNDIS_OID_GEN_MULTICAST_BYTES_RCV, + RNDIS_OID_GEN_MULTICAST_FRAMES_RCV, + RNDIS_OID_GEN_BROADCAST_BYTES_RCV, + RNDIS_OID_GEN_BROADCAST_FRAMES_RCV, + RNDIS_OID_GEN_RCV_CRC_ERROR, + RNDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH, #endif /* RNDIS_OPTIONAL_STATS */ /* mandatory 802.3 */ /* the general stuff */ - OID_802_3_PERMANENT_ADDRESS, - OID_802_3_CURRENT_ADDRESS, - OID_802_3_MULTICAST_LIST, - OID_802_3_MAC_OPTIONS, - OID_802_3_MAXIMUM_LIST_SIZE, + RNDIS_OID_802_3_PERMANENT_ADDRESS, + RNDIS_OID_802_3_CURRENT_ADDRESS, + RNDIS_OID_802_3_MULTICAST_LIST, + RNDIS_OID_802_3_MAC_OPTIONS, + RNDIS_OID_802_3_MAXIMUM_LIST_SIZE, /* the statistical stuff */ - OID_802_3_RCV_ERROR_ALIGNMENT, - OID_802_3_XMIT_ONE_COLLISION, - OID_802_3_XMIT_MORE_COLLISIONS, + RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT, + RNDIS_OID_802_3_XMIT_ONE_COLLISION, + RNDIS_OID_802_3_XMIT_MORE_COLLISIONS, #ifdef RNDIS_OPTIONAL_STATS - OID_802_3_XMIT_DEFERRED, - OID_802_3_XMIT_MAX_COLLISIONS, - OID_802_3_RCV_OVERRUN, - OID_802_3_XMIT_UNDERRUN, - OID_802_3_XMIT_HEARTBEAT_FAILURE, - OID_802_3_XMIT_TIMES_CRS_LOST, - OID_802_3_XMIT_LATE_COLLISIONS, + RNDIS_OID_802_3_XMIT_DEFERRED, + RNDIS_OID_802_3_XMIT_MAX_COLLISIONS, + RNDIS_OID_802_3_RCV_OVERRUN, + RNDIS_OID_802_3_XMIT_UNDERRUN, + RNDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE, + RNDIS_OID_802_3_XMIT_TIMES_CRS_LOST, + RNDIS_OID_802_3_XMIT_LATE_COLLISIONS, #endif /* RNDIS_OPTIONAL_STATS */ #ifdef RNDIS_PM @@ -200,8 +200,8 @@ /* general oids (table 4-1) */ /* mandatory */ - case OID_GEN_SUPPORTED_LIST: - pr_debug("%s: OID_GEN_SUPPORTED_LIST\n", __func__); + case RNDIS_OID_GEN_SUPPORTED_LIST: + pr_debug("%s: RNDIS_OID_GEN_SUPPORTED_LIST\n", __func__); length = sizeof(oid_supported_list); count = length / sizeof(u32); for (i = 0; i < count; i++) @@ -210,8 +210,8 @@ break; /* mandatory */ - case OID_GEN_HARDWARE_STATUS: - pr_debug("%s: OID_GEN_HARDWARE_STATUS\n", __func__); + case RNDIS_OID_GEN_HARDWARE_STATUS: + pr_debug("%s: RNDIS_OID_GEN_HARDWARE_STATUS\n", __func__); /* Bogus question! * Hardware must be ready to receive high level protocols. * BTW: @@ -223,23 +223,23 @@ break; /* mandatory */ - case OID_GEN_MEDIA_SUPPORTED: - pr_debug("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__); + case RNDIS_OID_GEN_MEDIA_SUPPORTED: + pr_debug("%s: RNDIS_OID_GEN_MEDIA_SUPPORTED\n", __func__); *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium); retval = 0; break; /* mandatory */ - case OID_GEN_MEDIA_IN_USE: - pr_debug("%s: OID_GEN_MEDIA_IN_USE\n", __func__); + case RNDIS_OID_GEN_MEDIA_IN_USE: + pr_debug("%s: RNDIS_OID_GEN_MEDIA_IN_USE\n", __func__); /* one medium, one transport... (maybe you do it better) */ *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium); retval = 0; break; /* mandatory */ - case OID_GEN_MAXIMUM_FRAME_SIZE: - pr_debug("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__); + case RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE: + pr_debug("%s: RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__); if (rndis_per_dev_params[configNr].dev) { *outbuf = cpu_to_le32( rndis_per_dev_params[configNr].dev->mtu); @@ -248,11 +248,11 @@ break; /* mandatory */ - case OID_GEN_LINK_SPEED: + case RNDIS_OID_GEN_LINK_SPEED: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__); + pr_debug("%s: RNDIS_OID_GEN_LINK_SPEED\n", __func__); if (rndis_per_dev_params[configNr].media_state - == NDIS_MEDIA_STATE_DISCONNECTED) + == RNDIS_MEDIA_STATE_DISCONNECTED) *outbuf = cpu_to_le32(0); else *outbuf = cpu_to_le32( @@ -261,8 +261,8 @@ break; /* mandatory */ - case OID_GEN_TRANSMIT_BLOCK_SIZE: - pr_debug("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__); + case RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE: + pr_debug("%s: RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__); if (rndis_per_dev_params[configNr].dev) { *outbuf = cpu_to_le32( rndis_per_dev_params[configNr].dev->mtu); @@ -271,8 +271,8 @@ break; /* mandatory */ - case OID_GEN_RECEIVE_BLOCK_SIZE: - pr_debug("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__); + case RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE: + pr_debug("%s: RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__); if (rndis_per_dev_params[configNr].dev) { *outbuf = cpu_to_le32( rndis_per_dev_params[configNr].dev->mtu); @@ -281,16 +281,16 @@ break; /* mandatory */ - case OID_GEN_VENDOR_ID: - pr_debug("%s: OID_GEN_VENDOR_ID\n", __func__); + case RNDIS_OID_GEN_VENDOR_ID: + pr_debug("%s: RNDIS_OID_GEN_VENDOR_ID\n", __func__); *outbuf = cpu_to_le32( rndis_per_dev_params[configNr].vendorID); retval = 0; break; /* mandatory */ - case OID_GEN_VENDOR_DESCRIPTION: - pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__); + case RNDIS_OID_GEN_VENDOR_DESCRIPTION: + pr_debug("%s: RNDIS_OID_GEN_VENDOR_DESCRIPTION\n", __func__); if (rndis_per_dev_params[configNr].vendorDescr) { length = strlen(rndis_per_dev_params[configNr]. vendorDescr); @@ -303,38 +303,38 @@ retval = 0; break; - case OID_GEN_VENDOR_DRIVER_VERSION: - pr_debug("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__); + case RNDIS_OID_GEN_VENDOR_DRIVER_VERSION: + pr_debug("%s: RNDIS_OID_GEN_VENDOR_DRIVER_VERSION\n", __func__); /* Created as LE */ *outbuf = rndis_driver_version; retval = 0; break; /* mandatory */ - case OID_GEN_CURRENT_PACKET_FILTER: - pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__); + case RNDIS_OID_GEN_CURRENT_PACKET_FILTER: + pr_debug("%s: RNDIS_OID_GEN_CURRENT_PACKET_FILTER\n", __func__); *outbuf = cpu_to_le32(*rndis_per_dev_params[configNr].filter); retval = 0; break; /* mandatory */ - case OID_GEN_MAXIMUM_TOTAL_SIZE: - pr_debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__); + case RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE: + pr_debug("%s: RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__); *outbuf = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); retval = 0; break; /* mandatory */ - case OID_GEN_MEDIA_CONNECT_STATUS: + case RNDIS_OID_GEN_MEDIA_CONNECT_STATUS: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__); + pr_debug("%s: RNDIS_OID_GEN_MEDIA_CONNECT_STATUS\n", __func__); *outbuf = cpu_to_le32(rndis_per_dev_params[configNr] .media_state); retval = 0; break; - case OID_GEN_PHYSICAL_MEDIUM: - pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__); + case RNDIS_OID_GEN_PHYSICAL_MEDIUM: + pr_debug("%s: RNDIS_OID_GEN_PHYSICAL_MEDIUM\n", __func__); *outbuf = cpu_to_le32(0); retval = 0; break; @@ -343,20 +343,20 @@ * of MS-Windows expect OIDs that aren't specified there. Other * versions emit undefined RNDIS messages. DOCUMENT ALL THESE! */ - case OID_GEN_MAC_OPTIONS: /* from WinME */ - pr_debug("%s: OID_GEN_MAC_OPTIONS\n", __func__); + case RNDIS_OID_GEN_MAC_OPTIONS: /* from WinME */ + pr_debug("%s: RNDIS_OID_GEN_MAC_OPTIONS\n", __func__); *outbuf = cpu_to_le32( - NDIS_MAC_OPTION_RECEIVE_SERIALIZED - | NDIS_MAC_OPTION_FULL_DUPLEX); + RNDIS_MAC_OPTION_RECEIVE_SERIALIZED + | RNDIS_MAC_OPTION_FULL_DUPLEX); retval = 0; break; /* statistics OIDs (table 4-2) */ /* mandatory */ - case OID_GEN_XMIT_OK: + case RNDIS_OID_GEN_XMIT_OK: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_XMIT_OK\n", __func__); + pr_debug("%s: RNDIS_OID_GEN_XMIT_OK\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->tx_packets - stats->tx_errors - stats->tx_dropped); @@ -365,9 +365,9 @@ break; /* mandatory */ - case OID_GEN_RCV_OK: + case RNDIS_OID_GEN_RCV_OK: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_RCV_OK\n", __func__); + pr_debug("%s: RNDIS_OID_GEN_RCV_OK\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->rx_packets - stats->rx_errors - stats->rx_dropped); @@ -376,9 +376,9 @@ break; /* mandatory */ - case OID_GEN_XMIT_ERROR: + case RNDIS_OID_GEN_XMIT_ERROR: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_XMIT_ERROR\n", __func__); + pr_debug("%s: RNDIS_OID_GEN_XMIT_ERROR\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->tx_errors); retval = 0; @@ -386,9 +386,9 @@ break; /* mandatory */ - case OID_GEN_RCV_ERROR: + case RNDIS_OID_GEN_RCV_ERROR: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_RCV_ERROR\n", __func__); + pr_debug("%s: RNDIS_OID_GEN_RCV_ERROR\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->rx_errors); retval = 0; @@ -396,8 +396,8 @@ break; /* mandatory */ - case OID_GEN_RCV_NO_BUFFER: - pr_debug("%s: OID_GEN_RCV_NO_BUFFER\n", __func__); + case RNDIS_OID_GEN_RCV_NO_BUFFER: + pr_debug("%s: RNDIS_OID_GEN_RCV_NO_BUFFER\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->rx_dropped); retval = 0; @@ -407,8 +407,8 @@ /* ieee802.3 OIDs (table 4-3) */ /* mandatory */ - case OID_802_3_PERMANENT_ADDRESS: - pr_debug("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__); + case RNDIS_OID_802_3_PERMANENT_ADDRESS: + pr_debug("%s: RNDIS_OID_802_3_PERMANENT_ADDRESS\n", __func__); if (rndis_per_dev_params[configNr].dev) { length = ETH_ALEN; memcpy(outbuf, @@ -419,8 +419,8 @@ break; /* mandatory */ - case OID_802_3_CURRENT_ADDRESS: - pr_debug("%s: OID_802_3_CURRENT_ADDRESS\n", __func__); + case RNDIS_OID_802_3_CURRENT_ADDRESS: + pr_debug("%s: RNDIS_OID_802_3_CURRENT_ADDRESS\n", __func__); if (rndis_per_dev_params[configNr].dev) { length = ETH_ALEN; memcpy(outbuf, @@ -431,23 +431,23 @@ break; /* mandatory */ - case OID_802_3_MULTICAST_LIST: - pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__); + case RNDIS_OID_802_3_MULTICAST_LIST: + pr_debug("%s: RNDIS_OID_802_3_MULTICAST_LIST\n", __func__); /* Multicast base address only */ *outbuf = cpu_to_le32(0xE0000000); retval = 0; break; /* mandatory */ - case OID_802_3_MAXIMUM_LIST_SIZE: - pr_debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__); + case RNDIS_OID_802_3_MAXIMUM_LIST_SIZE: + pr_debug("%s: RNDIS_OID_802_3_MAXIMUM_LIST_SIZE\n", __func__); /* Multicast base address only */ *outbuf = cpu_to_le32(1); retval = 0; break; - case OID_802_3_MAC_OPTIONS: - pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__); + case RNDIS_OID_802_3_MAC_OPTIONS: + pr_debug("%s: RNDIS_OID_802_3_MAC_OPTIONS\n", __func__); *outbuf = cpu_to_le32(0); retval = 0; break; @@ -455,8 +455,8 @@ /* ieee802.3 statistics OIDs (table 4-4) */ /* mandatory */ - case OID_802_3_RCV_ERROR_ALIGNMENT: - pr_debug("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__); + case RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT: + pr_debug("%s: RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->rx_frame_errors); retval = 0; @@ -464,15 +464,15 @@ break; /* mandatory */ - case OID_802_3_XMIT_ONE_COLLISION: - pr_debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__); + case RNDIS_OID_802_3_XMIT_ONE_COLLISION: + pr_debug("%s: RNDIS_OID_802_3_XMIT_ONE_COLLISION\n", __func__); *outbuf = cpu_to_le32(0); retval = 0; break; /* mandatory */ - case OID_802_3_XMIT_MORE_COLLISIONS: - pr_debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__); + case RNDIS_OID_802_3_XMIT_MORE_COLLISIONS: + pr_debug("%s: RNDIS_OID_802_3_XMIT_MORE_COLLISIONS\n", __func__); *outbuf = cpu_to_le32(0); retval = 0; break; @@ -516,7 +516,7 @@ params = &rndis_per_dev_params[configNr]; switch (OID) { - case OID_GEN_CURRENT_PACKET_FILTER: + case RNDIS_OID_GEN_CURRENT_PACKET_FILTER: /* these NDIS_PACKET_TYPE_* bitflags are shared with * cdc_filter; it's not RNDIS-specific @@ -525,7 +525,7 @@ * MULTICAST, ALL_MULTICAST, BROADCAST */ *params->filter = (u16)get_unaligned_le32(buf); - pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n", + pr_debug("%s: RNDIS_OID_GEN_CURRENT_PACKET_FILTER %08x\n", __func__, *params->filter); /* this call has a significant side effect: it's @@ -545,9 +545,9 @@ } break; - case OID_802_3_MULTICAST_LIST: + case RNDIS_OID_802_3_MULTICAST_LIST: /* I think we can ignore this */ - pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__); + pr_debug("%s: RNDIS_OID_802_3_MULTICAST_LIST\n", __func__); retval = 0; break; @@ -577,7 +577,7 @@ return -ENOMEM; resp = (rndis_init_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32(REMOTE_NDIS_INITIALIZE_CMPLT); + resp->MessageType = cpu_to_le32(RNDIS_MSG_INIT_C); resp->MessageLength = cpu_to_le32(52); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); @@ -621,7 +621,7 @@ return -ENOMEM; resp = (rndis_query_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32(REMOTE_NDIS_QUERY_CMPLT); + resp->MessageType = cpu_to_le32(RNDIS_MSG_QUERY_C); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ if (gen_ndis_query_resp(configNr, le32_to_cpu(buf->OID), @@ -668,7 +668,7 @@ pr_debug("\n"); #endif - resp->MessageType = cpu_to_le32(REMOTE_NDIS_SET_CMPLT); + resp->MessageType = cpu_to_le32(RNDIS_MSG_SET_C); resp->MessageLength = cpu_to_le32(16); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ if (gen_ndis_set_resp(configNr, le32_to_cpu(buf->OID), @@ -692,7 +692,7 @@ return -ENOMEM; resp = (rndis_reset_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32(REMOTE_NDIS_RESET_CMPLT); + resp->MessageType = cpu_to_le32(RNDIS_MSG_RESET_C); resp->MessageLength = cpu_to_le32(16); resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); /* resent information */ @@ -716,8 +716,7 @@ return -ENOMEM; resp = (rndis_keepalive_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32( - REMOTE_NDIS_KEEPALIVE_CMPLT); + resp->MessageType = cpu_to_le32(RNDIS_MSG_KEEPALIVE_C); resp->MessageLength = cpu_to_le32(16); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); @@ -745,7 +744,7 @@ return -ENOMEM; resp = (rndis_indicate_status_msg_type *)r->buf; - resp->MessageType = cpu_to_le32(REMOTE_NDIS_INDICATE_STATUS_MSG); + resp->MessageType = cpu_to_le32(RNDIS_MSG_INDICATE); resp->MessageLength = cpu_to_le32(20); resp->Status = cpu_to_le32(status); resp->StatusBufferLength = cpu_to_le32(0); @@ -758,7 +757,7 @@ int rndis_signal_connect(int configNr) { rndis_per_dev_params[configNr].media_state - = NDIS_MEDIA_STATE_CONNECTED; + = RNDIS_MEDIA_STATE_CONNECTED; return rndis_indicate_status_msg(configNr, RNDIS_STATUS_MEDIA_CONNECT); } @@ -766,7 +765,7 @@ int rndis_signal_disconnect(int configNr) { rndis_per_dev_params[configNr].media_state - = NDIS_MEDIA_STATE_DISCONNECTED; + = RNDIS_MEDIA_STATE_DISCONNECTED; return rndis_indicate_status_msg(configNr, RNDIS_STATUS_MEDIA_DISCONNECT); } @@ -817,15 +816,15 @@ /* For USB: responses may take up to 10 seconds */ switch (MsgType) { - case REMOTE_NDIS_INITIALIZE_MSG: - pr_debug("%s: REMOTE_NDIS_INITIALIZE_MSG\n", + case RNDIS_MSG_INIT: + pr_debug("%s: RNDIS_MSG_INIT\n", __func__); params->state = RNDIS_INITIALIZED; return rndis_init_response(configNr, (rndis_init_msg_type *)buf); - case REMOTE_NDIS_HALT_MSG: - pr_debug("%s: REMOTE_NDIS_HALT_MSG\n", + case RNDIS_MSG_HALT: + pr_debug("%s: RNDIS_MSG_HALT\n", __func__); params->state = RNDIS_UNINITIALIZED; if (params->dev) { @@ -834,24 +833,24 @@ } return 0; - case REMOTE_NDIS_QUERY_MSG: + case RNDIS_MSG_QUERY: return rndis_query_response(configNr, (rndis_query_msg_type *)buf); - case REMOTE_NDIS_SET_MSG: + case RNDIS_MSG_SET: return rndis_set_response(configNr, (rndis_set_msg_type *)buf); - case REMOTE_NDIS_RESET_MSG: - pr_debug("%s: REMOTE_NDIS_RESET_MSG\n", + case RNDIS_MSG_RESET: + pr_debug("%s: RNDIS_MSG_RESET\n", __func__); return rndis_reset_response(configNr, (rndis_reset_msg_type *)buf); - case REMOTE_NDIS_KEEPALIVE_MSG: + case RNDIS_MSG_KEEPALIVE: /* For USB: host does this every 5 seconds */ if (rndis_debug > 1) - pr_debug("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", + pr_debug("%s: RNDIS_MSG_KEEPALIVE\n", __func__); return rndis_keepalive_response(configNr, (rndis_keepalive_msg_type *) @@ -963,7 +962,7 @@ return; header = (void *)skb_push(skb, sizeof(*header)); memset(header, 0, sizeof *header); - header->MessageType = cpu_to_le32(REMOTE_NDIS_PACKET_MSG); + header->MessageType = cpu_to_le32(RNDIS_MSG_PACKET); header->MessageLength = cpu_to_le32(skb->len); header->DataOffset = cpu_to_le32(36); header->DataLength = cpu_to_le32(skb->len - sizeof(*header)); @@ -1031,7 +1030,7 @@ __le32 *tmp = (void *)skb->data; /* MessageType, MessageLength */ - if (cpu_to_le32(REMOTE_NDIS_PACKET_MSG) + if (cpu_to_le32(RNDIS_MSG_PACKET) != get_unaligned(tmp++)) { dev_kfree_skb_any(skb); return -EINVAL; @@ -1173,7 +1172,7 @@ rndis_per_dev_params[i].used = 0; rndis_per_dev_params[i].state = RNDIS_UNINITIALIZED; rndis_per_dev_params[i].media_state - = NDIS_MEDIA_STATE_DISCONNECTED; + = RNDIS_MEDIA_STATE_DISCONNECTED; INIT_LIST_HEAD(&(rndis_per_dev_params[i].resp_queue)); }
diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h index 907c330..0647f2f 100644 --- a/drivers/usb/gadget/rndis.h +++ b/drivers/usb/gadget/rndis.h
@@ -15,58 +15,12 @@ #ifndef _LINUX_RNDIS_H #define _LINUX_RNDIS_H +#include <linux/rndis.h> #include "ndis.h" #define RNDIS_MAXIMUM_FRAME_SIZE 1518 #define RNDIS_MAX_TOTAL_SIZE 1558 -/* Remote NDIS Versions */ -#define RNDIS_MAJOR_VERSION 1 -#define RNDIS_MINOR_VERSION 0 - -/* Status Values */ -#define RNDIS_STATUS_SUCCESS 0x00000000U /* Success */ -#define RNDIS_STATUS_FAILURE 0xC0000001U /* Unspecified error */ -#define RNDIS_STATUS_INVALID_DATA 0xC0010015U /* Invalid data */ -#define RNDIS_STATUS_NOT_SUPPORTED 0xC00000BBU /* Unsupported request */ -#define RNDIS_STATUS_MEDIA_CONNECT 0x4001000BU /* Device connected */ -#define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CU /* Device disconnected */ -/* For all not specified status messages: - * RNDIS_STATUS_Xxx -> NDIS_STATUS_Xxx - */ - -/* Message Set for Connectionless (802.3) Devices */ -#define REMOTE_NDIS_PACKET_MSG 0x00000001U -#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002U /* Initialize device */ -#define REMOTE_NDIS_HALT_MSG 0x00000003U -#define REMOTE_NDIS_QUERY_MSG 0x00000004U -#define REMOTE_NDIS_SET_MSG 0x00000005U -#define REMOTE_NDIS_RESET_MSG 0x00000006U -#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007U -#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008U - -/* Message completion */ -#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002U -#define REMOTE_NDIS_QUERY_CMPLT 0x80000004U -#define REMOTE_NDIS_SET_CMPLT 0x80000005U -#define REMOTE_NDIS_RESET_CMPLT 0x80000006U -#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008U - -/* Device Flags */ -#define RNDIS_DF_CONNECTIONLESS 0x00000001U -#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002U - -#define RNDIS_MEDIUM_802_3 0x00000000U - -/* from drivers/net/sk98lin/h/skgepnmi.h */ -#define OID_PNP_CAPABILITIES 0xFD010100 -#define OID_PNP_SET_POWER 0xFD010101 -#define OID_PNP_QUERY_POWER 0xFD010102 -#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 -#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 -#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 - - typedef struct rndis_init_msg_type { __le32 MessageType;
diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h index 1d5eda2..f7c1c8e2 100644 --- a/drivers/usb/musb/musb_io.h +++ b/drivers/usb/musb/musb_io.h
@@ -40,7 +40,7 @@ #if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \ && !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \ && !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN) \ - && !defined(CONFIG_MIPS) + && !defined(CONFIG_MIPS) && !defined(CONFIG_M68K) static inline void readsl(const void __iomem *addr, void *buf, int len) { insl((unsigned long)addr, buf, len); } static inline void readsw(const void __iomem *addr, void *buf, int len)
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 853db7a..f82a739 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c
@@ -24,6 +24,7 @@ #include <linux/if_arp.h> #include <linux/if_tun.h> #include <linux/if_macvlan.h> +#include <linux/if_vlan.h> #include <net/sock.h> @@ -286,8 +287,12 @@ spin_lock_irqsave(&sk->sk_receive_queue.lock, flags); head = skb_peek(&sk->sk_receive_queue); - if (likely(head)) + if (likely(head)) { len = head->len; + if (vlan_tx_tag_present(head)) + len += VLAN_HLEN; + } + spin_unlock_irqrestore(&sk->sk_receive_queue.lock, flags); return len; }
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 6468a29..39571f9 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c
@@ -22,7 +22,9 @@ #include <linux/font.h> #include <asm/hardware.h> +#include <asm/page.h> #include <asm/parisc-device.h> +#include <asm/pdc.h> #include <asm/cacheflush.h> #include <asm/grfioctl.h>
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c index 26e83d7..b0e2a42 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/uvesafb.c
@@ -73,7 +73,7 @@ struct uvesafb_task *utask; struct uvesafb_ktask *task; - if (!cap_raised(current_cap(), CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN)) return; if (msg->seq >= UVESAFB_TASKS_MAX)
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c index cb4529c..b7f5173 100644 --- a/drivers/video/xen-fbfront.c +++ b/drivers/video/xen-fbfront.c
@@ -365,7 +365,7 @@ struct fb_info *fb_info; int fb_size; int val; - int ret; + int ret = 0; info = kzalloc(sizeof(*info), GFP_KERNEL); if (info == NULL) { @@ -458,26 +458,31 @@ xenfb_init_shared_page(info, fb_info); ret = xenfb_connect_backend(dev, info); - if (ret < 0) - goto error; + if (ret < 0) { + xenbus_dev_fatal(dev, ret, "xenfb_connect_backend"); + goto error_fb; + } ret = register_framebuffer(fb_info); if (ret) { - fb_deferred_io_cleanup(fb_info); - fb_dealloc_cmap(&fb_info->cmap); - framebuffer_release(fb_info); xenbus_dev_fatal(dev, ret, "register_framebuffer"); - goto error; + goto error_fb; } info->fb_info = fb_info; xenfb_make_preferred_console(); return 0; - error_nomem: - ret = -ENOMEM; - xenbus_dev_fatal(dev, ret, "allocating device memory"); - error: +error_fb: + fb_deferred_io_cleanup(fb_info); + fb_dealloc_cmap(&fb_info->cmap); + framebuffer_release(fb_info); +error_nomem: + if (!ret) { + ret = -ENOMEM; + xenbus_dev_fatal(dev, ret, "allocating device memory"); + } +error: xenfb_remove(dev); return ret; }
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index c2d05a8..8807fe5 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c
@@ -390,6 +390,7 @@ /* There might be pages left in the balloon: free them. */ while (vb->num_pages) leak_balloon(vb, vb->num_pages); + update_balloon_size(vb); /* Now we reset the device so we can clean up the queues. */ vdev->config->reset(vdev);
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 9424313..ea20c51 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig
@@ -183,15 +183,17 @@ depends on XEN && X86 && ACPI_PROCESSOR && CPU_FREQ default m help - This ACPI processor uploads Power Management information to the Xen hypervisor. + This ACPI processor uploads Power Management information to the Xen + hypervisor. - To do that the driver parses the Power Management data and uploads said - information to the Xen hypervisor. Then the Xen hypervisor can select the - proper Cx and Pxx states. It also registers itslef as the SMM so that - other drivers (such as ACPI cpufreq scaling driver) will not load. + To do that the driver parses the Power Management data and uploads + said information to the Xen hypervisor. Then the Xen hypervisor can + select the proper Cx and Pxx states. It also registers itslef as the + SMM so that other drivers (such as ACPI cpufreq scaling driver) will + not load. - To compile this driver as a module, choose M here: the - module will be called xen_acpi_processor If you do not know what to choose, - select M here. If the CPUFREQ drivers are built in, select Y here. + To compile this driver as a module, choose M here: the module will be + called xen_acpi_processor If you do not know what to choose, select + M here. If the CPUFREQ drivers are built in, select Y here. endmenu
diff --git a/firmware/3com/3C359.bin.ihex b/firmware/3com/3C359.bin.ihex deleted file mode 100644 index 781bac3..0000000 --- a/firmware/3com/3C359.bin.ihex +++ /dev/null
@@ -1,1573 +0,0 @@ -:10000000FE3A0000000000000000000000000000B8 -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000000000000000000000000000000C0 -:1000400000000000000030332F30322F39392031CA -:10005000373A3133000000000000000000000000CB -:1000600030313233343536373839414243444546EE -:10007000000007FF0200FE9F0600007C48000070A1 -:100080008200FFFF8600FFFF8800FFFF9A00FFFF4E -:10009000FFFF1100C000FFFFFFFF11223344556630 -:1000A00033434F4D20424142451140C000FFFFFF06 -:1000B000FF1122334455665374617274206F6620B9 -:1000C0004C4C43206672616D652E2020546F746124 -:1000D0006C20646174612073697A6520697320788B -:1000E000787820202042414245E8D201833EF7340F -:1000F000007521E84100833EF734007517E882005F -:10010000833EF73400750DE8BF00833EF734007579 -:1001100003E84102C31EB800F08ED833F6B9008060 -:1001200033DBAD03D8E2FB1FB8000083FB00740390 -:10013000B82200A3F734C3FABA5600B0FFEE33C0BA -:100140008EC033F6B9FF7F833EFF340074088D3EC6 -:100150003061D1EF2BCF268B1C26C704FFFF2683EF -:100160003CFF751726C704000026833C00750C264B -:10017000891C4646E2E0B80000EB03B82400A3F770 -:1001800034C3FAB4D79E733A753879367B349FB14D -:1001900005D2EC732DB040D0E071277925D0E07303 -:1001A000217B1F32C0751B32E49E721674147812C4 -:1001B0007A109FD2EC720BD0E470077505B800007E -:1001C000EB03B82600A3F734C3FABA5A0033C0EFE2 -:1001D000EFEFEFB000E656B000E654BA5200B801B7 -:1001E00001EFE8CA003C01757FE88300BA5200B80D -:1001F0000202EFE8B9003C02756EE87A00BA5200DC -:10020000B80404EFE8A8003C04755DE87100BA5238 -:1002100000B80808EFE897003C08754CE86800BA99 -:100220005200B81010EFE886003C10753BE85F0004 -:10023000BA5200B82020EFE875003C20752AE85635 -:1002400000BA5200B84040EFE864003C407519E83D -:100250004D00BA5200B88080EFE853003C8075082A -:10026000E84400B80000EB03B82800A3F734C3BA91 -:100270005A00B80080EFC3BA5A00B80180EFC3BA81 -:100280005A00B80280EFC3BA5A00B80380EFC3BA6D -:100290005A00B80480EFC3BA5A00B80580EFC3BA59 -:1002A0005A00B80680EFC3BA5A00B80780EFC3B946 -:1002B000FFFFE458E4543C0075034975F7C3FA3274 -:1002C000C0E656E4563C007403E98200B0FFE656EF -:1002D000E4563CFF7578BA5200B8FFFFEFED3CFFE3 -:1002E000756CB800FFEFED3C007563B0FFE654E4B9 -:1002F000543CFF755932C0E654E4543C00754FB08D -:100300000FE650E450240F3C0F7543B000E650E474 -:1003100050240F3C0075378CC88EC0BE7000268BF1 -:1003200014268B5C02B80000EFED23C33D0000757E -:100330001DB8FFFF23C3EF8BC8ED23C33BC1750E70 -:1003400083C60426833CFF75D5B80000EB03B82AAA -:1003500000A3F734C3FA33C0BF0020B91700F3ABD2 -:10036000BF0030B91700F3ABBF0022B94000F3ABB8 -:10037000BF0032B94000F3ABFC1E8CC88ED833C02E -:100380008EC0BE9200BF0020B91700F3A4BEA90022 -:10039000BF0022B94000F3A41FC706FB346400BAB3 -:1003A0000800B80F00EFE88201E89B01720DC70654 -:1003B000F7342C00C706F9340400C3BA0A0033C06E -:1003C000EFE89801E8B501B81700BA9C00EFB80053 -:1003D00010BA9A00EFB81700A90100740140BA8C56 -:1003E00000EFB80018BA8600EFB80C00BA8200EF30 -:1003F000BA0200ED25F9FF0D0200EFBA060033C086 -:10040000EFBA0400B86000EFBA0000B81800EFBA05 -:100410008000B9FFFFEDA901007504E2F8EB3EBAD8 -:100420000A00EDA900407435A90020743033C0EFF4 -:1004300051B9C800E2FE591E061F268B0E023083FA -:10044000F91775184949BE0220BF0630F3A61F23CD -:10045000C9750AFF0EFB347412E94DFF1FB82C005A -:10046000BB0000A3F734891EF934C3C706FB34640C -:1004700000E8D300720DC706F7342C00C706F93424 -:100480000400C3E8D600E8F300B80300BA8200EF26 -:10049000B84080BA9800EFB80011BA9600EFB840A3 -:1004A00000A90100740140BA9200EFB80019BA8E99 -:1004B00000EFBA0200ED25F9FF0D0600EFBA0600C5 -:1004C00033C0EFBA0000B81800EFBA8000B9FFFFE0 -:1004D000EDA920007504E2F8EB43BA0A00EDA9008B -:1004E00040743AA90020743533C0EF51B9C800E216 -:1004F000FE591E061F268B0E023283F940751D49D8 -:1005000049BE0222BF0632F3A61F23C9750FFF0E94 -:10051000FB347403E95AFFB80000EB0B1FB82C0042 -:10052000BB0200891EF934A3F734C3BA0200B80035 -:100530009CEFBA0000B80084EF33C0EFBA0A00EFB6 -:10054000BA0E0033C0EFC3BA0A00B9FFFFED2500B1 -:10055000603D00607404E2F5F8C3F9C3B000E656EC -:10056000B800FFBA5200EFB9FFFFBA5800ED25EF0F -:10057000007408BA5A0033C0EFE2EFC3BA8000ED4E -:10058000BA8400EFBA8000EDC30000000000000054 -:10059000C606EC341533C08ED88EC01E8CC8BE4043 -:1005A00054BF60FE8ED8B91000F3A41FC706803672 -:1005B0001035C7068C3630358D063835A33035A357 -:1005C0003235053301A33435C70636355001C70629 -:1005D000843680FEC7068836C0FEC606C2FEFFC649 -:1005E00006933680C606923600C60680FE80C70691 -:1005F00082FE5450C70684FE2B4DE5CEA90200753D -:1006000008C60681FE23E90500C60681FE22A1F781 -:1006100034A386FEB8483486E0A388FE8D064E34A7 -:1006200086E0A38AFEB8583486E0A38CFEB89C34DA -:1006300086E0A38EFE8D06200386E0A390FE33C0E5 -:10064000BA7200EF33C0BA7400EFBA7600EFB88028 -:10065000FE86E0BA7200EFE8BF07BA0C01B840406E -:10066000EFEDBA6A00B80300C1E0080D0300EFB96E -:100670000A00E89400BA6A00B80300C1E008EFA1DC -:100680003234A3A233C706A63304008D06A033C1BB -:10069000E804CD39C7069036FFFFE9E300630D6635 -:1006A0000D660D8A0DE60E75122E0F030F500F60AA -:1006B0000D600D600DED0FE912600D600D600D60B5 -:1006C0000D600D2210600D600D600D600DFE10605C -:1006D0000D600D600D600D600D600DAF0F321037B5 -:1006E0000D600D600D600D600D600D600D600D60A2 -:1006F0000D600D600D600D600D600D600D600D6092 -:100700000D640E000F9509600A49BBFFFFBA6A002D -:10071000EDA900207438803E80FE127531E84A0051 -:10072000A13234A3A233C706A63304008D06A0333A -:10073000C1E804CD39E82200C706F3344600C706F5 -:10074000F534FFFFC7069036FFFF58E932004B83B0 -:10075000FB0075B983F90075B0C352BA6A00B803DB -:1007600000C1E0080D0300EF5AC352BA6A00B80393 -:1007700000C1E008EF5AC3000000000000000000C4 -:10078000688007A19036CD358B3624022EFFA43524 -:100790000AFA8A2694368826E834C606943600FB80 -:1007A00022E47501C3F6C420747DF6C40874058084 -:1007B0000E9236048026E834D7C41E8436268B3742 -:1007C00081E6FF0083FE207605B001E9280053068C -:1007D000D1E62EFF949D06075B268847023CFF74F6 -:1007E000073CFE7511E93B00F6069236087534F6B3 -:1007F00006923604742D80269236F3803E9536009C -:10080000752126803F057513C60695360026807F24 -:1008100006007407268B4704A29536BA0C01B8402F -:1008200040EFED8A26E834F6C4107503E95B00F664 -:10083000C4047405800E9236018026E834EBC43E71 -:100840008836268B3583E67F83FE12720826C645DE -:100850000201E9240083C620D1E62EFF949D06C440 -:100860003E8836268845023CFF750EF60692360114 -:100870007414F606923602750D80269236FCBA0C78 -:1008800001B82020EFED8A26E834F6C408742280EF -:1008900026E834F7800E923604F606923608741174 -:1008A00080269236F3BA0C01B84040EFED8A26E874 -:1008B00034F6C40474228026E834FB800E9236019C -:1008C000F606923602751180269236FEBA0C01B8F1 -:1008D0002020EFED8A26E834F6C40174678026E80C -:1008E00034FE803EE8FF007439803EE8FF04743235 -:1008F000803EE8FF017521E580A90007740ABA9ED1 -:1009000000B80002EFE9EFFFC606E8FF03BA0C01EA -:10091000B80808EFEDE92800803EE8FF037406E917 -:100920001E00E90000BA1001B80202EFEDE5000D6B -:100930001800E700E5820D0200E782C606E8FF0422 -:100940008A26E834F6C402740D8026E834FD802639 -:100950009236BFE84F0BFAA0E83408069436C60674 -:10096000E83400FBC3E8E70FC41E84362EFF1601EF -:100970000726884702E97EFEE82D10C41E84362E25 -:10098000FF16030726884702E96BFE8E0626022E15 -:10099000FF160707C3C3833EF53400740FFF0EF341 -:1009A000347509E8C4FDC706F5340000F606933631 -:1009B000207430A1C2343B06E934A3E934742480A6 -:1009C0003E953600751DF706E63420007412A92006 -:1009D00000740D8326C234DF8326E934DFE9030087 -:1009E000E8DD09BA0601ED8BD081E200C0C1EA0E54 -:1009F00003167434C1E002110672347304FF0674E6 -:100A000034BA0201ED8BD081E200C0C1EA0E0316B8 -:100A10007034C1E00211066E347304FF067034C7EF -:100A200006A6330400C706AA3300008D06A033C112 -:100A3000E804CD39C39509950965097809950995A3 -:100A4000099107950996098B0995099509950995C5 -:100A500009950995098BC08BC08BC08BC08BC0904A -:100A6000F6069336207503E9CC008CC0408EC02674 -:100A70008B0E060086E926890E06008CC2C1E204B0 -:100A8000BE0E0026A10400D0E024C08AE0C0EC0421 -:100A90000AC426A2050026A10800A900C07403E923 -:100AA0009E0026F6061000807503E90A0026A016AF -:100AB00000241F32E403F0803EEC3406725C803E7A -:100AC00095360075668BFA33DB8EC326891D268822 -:100AD0005D045150C41E8C36B90F0033C0E82109A3 -:100AE00058590BDB7434FE0EE63A26C6078126C63B -:100AF00047010026C64702FF26C747040000268993 -:100B00004F0A86F2268957062689770826C647099E -:100B10000026C6470C02E88C09C3FF06EC338CC0E4 -:100B2000488EC0FAE89710FBE9EBFF8CC0488EC0F6 -:100B3000FAE88A10FBC38CC08EC0FAE88010FBC3B1 -:100B4000803E9536007503E9C200BF080026F60610 -:100B5000100080750503FEE90C0026A01600241F76 -:100B600032E403F003FEA095363C007503E99C00D7 -:100B70003C01740B3C0274143C03741DE98D00C6E7 -:100B800006963601E83C017227E98000C6069636D3 -:100B900002E88300721AE97300C606963601E8225D -:100BA00001720DC606963602E86C007203E95C001D -:100BB000530650C41E8C36B90B0033C0E8420858A7 -:100BC00026C6078226C64702FF8D06E0FE86C4269B -:100BD000894706A0963626884708E8C808075B8339 -:100BE00026AD36FEA1AD36E704BA1001B88080EF1D -:100BF000EDBA1001B80202EFED52BAE000B84110B0 -:100C0000EF5AB89C03CD39C6069536008CC0488E85 -:100C1000C0FAE8A90FFBC31E061F0633C08EC08BA7 -:100C2000F08D3E20F351B10A26837D0C01752A57C1 -:100C300026837D0E007406E82F00E90300E86607AE -:100C40005F731633C08ED8268B4D128D75208D3E66 -:100C5000E0FEF3A459071FF9C3FEC9740781C7203A -:100C600001E9C4FF59071FF8C35150535652573377 -:100C7000DB268A5D0E268B4D128D7D205A87D72666 -:100C80008A451487D74232FF80FF087508FECB22C1 -:100C9000DB75EA33DB23DB7406FEC7D0C8730C5068 -:100CA000268A053804587403E90A0049464723C9CF -:100CB000740AE9D3FF5A5E5B5859F8C35A5E5B5811 -:100CC00059F9C31E061F0633C08EC086CD2BCE8BAE -:100CD000F78BC133C9803CFF741680F90673093263 -:100CE000C94648742EE9EDFF3D6000730CE923000E -:100CF000FEC14648741DE9DCFFB810008D3E183473 -:100D000032EDB106F3A67403E908004823C0740766 -:100D1000E9E9FF071FF8C38D36183433C08ED88D2C -:100D20003EE0FEB81000B9060056F3A45E483D0050 -:100D30000075F3071FF9C3FF06E433C606EB340062 -:100D4000268B450686E0C1E80448068EC0FE06E60E -:100D50003AFAE8690EFB07B0FFC30000000000008C -:100D6000B001C3B000C3F6069336207503B004C3C8 -:100D70008B0E973681E18030268B4704257FCF0B81 -:100D8000C1A39736A3E634B000C3F60693362074A9 -:100D900003B003C3268B4708A39736A3E634268AFD -:100DA0004720A2FD343C017506C706A13600002687 -:100DB0008A4721A2FE34268B470AA31834A358344D -:100DC000268B470CA31A34A35A34268B470EA31C38 -:100DD00034A35C34C6062A34C0268B4714257FFF13 -:100DE00009062C34268B471625FFFE25FFFC090635 -:100DF0002E34C6060034C0268B4710A30234268B3F -:100E00004712A304340653E8840A5B073D000075CB -:100E100007800E923608B0FEC3B90001A1AC33338F -:100E2000D2F7F9A3AE33914933D2F7E905003BA3DA -:100E30004634BF003B893E4434BA6800B8E0E0EF76 -:100E4000A1AE33E762A1AE33BA0801EFA14434E7A3 -:100E500064A14434BA0A01EFB800012D04000D006A -:100E600010E792C33D0000740A26894707E8833AD9 -:100E7000B007C3A1AE332689472BA1443426894746 -:100E80002DA146342689472F800E933620A188361F -:100E900086E026894708A1843686E02689470AA18C -:100EA000803686E02689470CB860FE86E0268947B2 -:100EB0000EA0A136268847108B36883626C64402F7 -:100EC000FFE59EA90008740CBA8400ED0D0800EF40 -:100ED000BA8E00EFE50225F9FFE702BA1001B80269 -:100EE00002EFEDB000C3F6069336207503B001C3E0 -:100EF000802693369FE88D0A800E923608B0FEC396 -:100F0000B000C3F6069336207503B004C3C6062AA4 -:100F100034C0268B4706257FFFA32C34268B470839 -:100F200025FFFE25FFFCA32E34CD52B000C3F606EC -:100F30009336207503B004C3C6060034C0268B4721 -:100F400006A30234268B4708A30434CD52B000C355 -:100F5000F6069336207503B004C3578D7F0651B94A -:100F6000070033C0F3AB598D7F06A17A34030639ED -:100F700037268805A1953726884502A180340306C7 -:100F8000763426884507A1C63426884509A1D8337A -:100F90002688450A33C0A37A34A33937A39537A3EB -:100FA0008034A37634A3C634A3D8335FB000C3F62D -:100FB000069336207503B004C3268B4F0483F906CD -:100FC000741283F904740D83F900740883F90274B0 -:100FD00003B001C3890EE83A8326AB36F9090EAB9C -:100FE00036E50225F9FF0BC1E702B000C3F6069310 -:100FF00036207503B004C3268B4F0480F9FF7408B4 -:1010000080F9007410B001C3830EAD3602A1AD3675 -:10101000E704E90A008326AD36FDA1AD36E704B04A -:1010200000C3F6069336207503B004C3E8D504B0B8 -:1010300000C3F6069336807503B001C326837F068E -:10104000057503E99D00268B5704268B47082681EA -:101050007F0600807508ED2689470AE99D002683F2 -:101060007F06017504EFE9920026817F06018075F5 -:1010700009EFED2689470AE9810026837F0602757C -:101080000726214704E9730026817F060280750C3C -:1010900026214704ED2689470AE95F0026837F065B -:1010A00003750726094704E9510026817F0603805E -:1010B000750C26094704ED2689470AE93D00268379 -:1010C0007F0604750726314704E92F0026817F0635 -:1010D0000480750C26314704ED2689470AE91B0078 -:1010E000B001C3FA53268B4F080BC9740C8D1EE058 -:1010F000FEE852FF83C308E2F85BFBB000C3F606CC -:10110000933680750AF6069336207503B001C38DB9 -:101110003EE0FEE500268905E50226894502A1ADEF -:101120003626894504E50626894506E508268945CB -:1011300008E50A2689450AE50E2689450CE5482674 -:1011400089450EE54A26894510E54C26894512A1B8 -:10115000B73626894514E55026894516E552268975 -:101160004518E5542689451AE5562689451CE55853 -:101170002689451EE56226894520E56426894522A3 -:10118000E56626894524E56826894526E56A268997 -:101190004528E56C2689452AE5702689452CE572A7 -:1011A0002689452EE57426894530E576268945321F -:1011B000E57C26894534E57E26894536E580268905 -:1011C0004538E5822689453AE5862689453CE58805 -:1011D0002689453EE59A26894540E59E2689454271 -:1011E000E5CC26894544E5CE26894546E5D02689C5 -:1011F0004548E5D22689454ABA0001ED1106663414 -:101200007304FF0668342689454CBA0201EDC1E03B -:101210000211066E347304FF0670342689454EBAF7 -:101220000401ED11066A347304FF066C3426894507 -:1012300050BA0601EDC1E002110672347304FF06D4 -:10124000743426894552BA0801ED26894554BA0AF4 -:1012500001ED26894556BA0C01ED26894558BA0E8E -:1012600001ED01067A342689455EBA1001ED268922 -:10127000455CB000C3F6069336807407F6069336D5 -:10128000207503B001C326807F06007530803E952F -:1012900036007452C6069536008326AD36FEA1ADE3 -:1012A00036E704BA1001B88080EFEDBA1001B80239 -:1012B00002EFEDBAE000B80010EFB000C3268B4794 -:1012C000043D000074203D0300771BBA1001B802F2 -:1012D00000EFBAE000B80110EF830EAD3601A1AD0A -:1012E00036E704B000C3B006C3F606933680750334 -:1012F000B001C326837F0401740A26837F0402742D -:1013000019B006C326837F060C77F626837F0A6012 -:1013100077EFE81000720BB046C3E84E007203B0DE -:1013200046C3B000C351B10A8B3E20F326837D0C27 -:10133000027503E90E00FEC9740781C72001E9EBBD -:10134000FF59F8C3578D7D0E8D7706B91200F3A4AF -:101350008D7D208D36E0FE268B4D12F3A4FF060115 -:10136000355F26C7450C010059F9C351B10A8D3EBE -:1013700020F38D36E0FE26837D0C01751B57E82592 -:10138000005F731433C0B92001F3AA26C7450C02CD -:1013900000FF0E013559F9C3FEC9740781C720014A -:1013A000E9D3FF59F8C351268B4D128D7D20F3A64A -:1013B000740359F8C359F9C300000000000000008D -:1013C000803EEC34067233FF06F03350C41E8C3678 -:1013D000B90F0033C0E82900588126C234DF7F816D -:1013E00026E934DF7F0BDB741126C6078426C64747 -:1013F00002FF26894706E8AC00C3FF06EA33E9F599 -:10140000FF57268B3F03F9263B7F027416263B7F4E -:10141000047C2A3D000075138D7F0803F9263B7F6D -:10142000027C14FF06DE3333DB5FC3268B7F02268C -:10143000893F03F9E9060026893F26290F26C705BB -:10144000FFFF26873F26890D8D5D02508BFB83E9C8 -:101450000233C0F3AA58FE0EEC345FC38B7C023B10 -:101460003C742F833DFF750B8D7C08897C02833D86 -:10147000FF741E8A45023C81750C803EEB3400747B -:101480000533C0E90B008B0D014C028D750283E919 -:1014900002C3803EEC3406720533C0E9F3FFFF0659 -:1014A000EE33E9BEFFF6069236407401C35756513B -:1014B000528B368C36E8A4FF7503E91A00E91C004C -:1014C000FE06EC34C43E8036F3A4800E923640BA59 -:1014D0000C01B88080EFED5A595E5FC3FF06E03320 -:1014E000803C81750CFF06E233C606EB3401E9CF80 -:1014F000FF803C847507FF06E633E9C3FFFF06E87B -:1015000033E9BCFF8D3EE0FEA17234C706723400A1 -:10151000008905A17434C70674340000894502BAF5 -:101520000401ED894504C745060000A16E34C706D5 -:101530006E340000894508A17034C706703400007D -:1015400089450ABA0001ED89450CC7450E000032F5 -:10155000E4BA0E01EC894510A17E34C7067E340042 -:1015600000894512A18C34C7068C340000894514CB -:10157000A18A34C7068A340000894516A17C34C785 -:10158000067C340000894518A18834C706883400D9 -:101590000089451AA1CA33C706CA33000089451C11 -:1015A000A17834C7067834000089451EA1C634C727 -:1015B00006C6340000894520C3000000000000007A -:1015C000FA33C08ED88EC0B8A001C1E8048ED08D89 -:1015D000268000E80001E810EB8B1EF7348B16F92B -:1015E000348B36FF3433C0B9EFFF8D3E14002BCF60 -:1015F0002BCED1E9F3AB891EF7348916F93483FE7B -:1016000000740CB9EFFFBF80FE2BCFD1E9F3ABB96B -:10161000FFFF81E9003B83FE007403E91B00511EBC -:10162000B800E08ED833F68D3E00D8B9000CF3A593 -:101630001F59BEFFFF81EE00D82BCE81E100FF894C -:101640000EAC338D062002C1E804A332348ED036AE -:10165000C7061E00801836C7062200FF7F36C70661 -:101660000A00FFFF36C7061C0080008D06A002C1DD -:10167000E804A330348ED036C7061E00502836C783 -:10168000060A00FFFF36C7061C008000B8A001C193 -:10169000E804A33434A3F2338ED08D268000B80042 -:1016A00090E7028D3E70018BC7C1E804B903008941 -:1016B000450E894502C705FFFF83C710050100E2FB -:1016C000EEE85B01E5CEA3B536E82100E84501A1CF -:1016D00032348CCBCD370E58A900F0740733F6891D -:1016E00036FF34C38D3630618936FF34C333C08B47 -:1016F000D08BF2B968002E80BCAC17807501EF83E7 -:10170000C20246E2F1B80200E750B95A0033FFC7FF -:101710000565188C4D0283C704E2F433C08EC08C7B -:10172000C88ED88D3E80008D369C17B90800E837EA -:10173000008D3620218D3EC000B90D00E829008DB6 -:101740003E4001B90A00E81F00E84B0E33C08ED8B6 -:10175000C7064E376F17E748E74CB8409CE74AE5A5 -:101760004890B80070E748C3A583C702E2FAC3E512 -:101770004CC35051565752061E33C08ED8E558D12F -:10178000E073118BF0D1E633C08ED88BB480008328 -:10179000C60BFFE61F075A5F5E5958CF581CE41C62 -:1017A0006C1C8E1AC01F401A441C6518808080FF74 -:1017B00080030280FFFFFFFFFFFFFFFFFFFFFFFF30 -:1017C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 -:1017D0008003034380800280420302FF0301030170 -:1017E00001030203FFFFFFFFFFFFFFFF02030103EF -:1017F00003FF0101FF01FF0101030303FFFFFFFFDF -:10180000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 -:10181000FFFFFF02B80F00E784B80FF8E782C3B9F3 -:101820000800890EE63A8D0620038BD0C1E804A398 -:1018300090018BC28BD8C1E8048EC005610026A33D -:101840000000A1303426A3020083C314D1EB268903 -:101850001E080081C21006E2D926C7060000FFFF5D -:101860008C069201C35051565752061E33C08ED873 -:10187000E75AFF06BE33BAD200EDCF0000000000E9 -:101880008CCBA13034CD37E906EDB83200C3E88CFB -:1018900001FE06E234E8210175F0E8530E810EAF37 -:1018A0003600C0C706AD366000F706E63480007526 -:1018B0001AF706E63400087409C706AB360B00E9D0 -:1018C0000F00C706AB360300E90600C706AB3611AA -:1018D0009CC706A9361800F706E6348000750DF798 -:1018E00006B53602007405830EA93620A1A936E795 -:1018F00000A1AB36E702F706E6348000742EE8F26A -:101900002F33C00D4100E756A1B1360D0010E70896 -:10191000A1B336E70AA1AF36E706B84000E74E3379 -:10192000C0E70EC70626020000E92300C7064E37AF -:101930003F208E06303426F7060A00008074072602 -:10194000810E08000080C606E03401B80000C3FE26 -:1019500006E134C606E03400A126020BC07401C3C0 -:10196000E80400B80000C3A1A936E7008B1EAB361F -:1019700083E306E50225F9FF0BC30D1000E702A182 -:10198000AD36E704C3B80A00E784FE06E534C606B0 -:10199000E334018E06303426F7060A00004074074F -:1019A00026810E08000040C3C7064E376F17FE069B -:1019B000E434C606E33400C3C3F606183480750D5C -:1019C000A118340B061A340B061C347501C3A12E62 -:1019D0003425FFFE8B16E73681E200010BC2A32EF1 -:1019E000348D161000BF0000B908008B850034EF5D -:1019F00083C2108B850234EF83C2108B850434EFD1 -:101A000083C2E283C7064975E2B800008EC0BE00FB -:101A100034BFB936B91800F3A5B80000C333C08E7F -:101A2000C08D3EB033B90800F3AB8D3E3E34B903F0 -:101A300000F3ABC300000000000000000000000045 -:101A40005051565752061E33C08ED8E75AFF06BA79 -:101A500033E5560D2000E756BA7A00ED0826943695 -:101A600033C0B10832ED068EC08D3EE0FFF3AA8E82 -:101A700006323426810E0800000207E55625DFFFF6 -:101A8000E756E9F8FC00BD1B101BD91AF31A505198 -:101A9000565752061E33C08ED8E75AFF06B6335348 -:101AA0000651E580A3B4338BD88BC8251000A3ED75 -:101AB000340BC07414FF068034803EFE340074037F -:101AC000E90600B88000E89D0483E303D1E32EFF1C -:101AD00097861A59075BE9A4FCBA20008E063C34AD -:101AE000833E3C34007503E9F000C7063C34000037 -:101AF000E92A00BA10008E063A34833E3A34007563 -:101B000003E9D5FFC7063A340000E81000E9C9FF31 -:101B1000BA10008E063A34C7063A34000026A114E3 -:101B20000026A30C0026A1160026A30E0026C6063A -:101B30000A0000C1EA0223D1741CBA200026C7069D -:101B40000E00EA05260B160C002689160C00FF066F -:101B50008634FF06DC3326A10C00A9003774162654 -:101B6000C6060A0002A900307404FF067A34FF0694 -:101B7000DA33E94900C0EC0783168A340024073CB5 -:101B8000077504FF068C34FF067E34A130348CC305 -:101B90008EC08EDB26830E0800408CD82687061662 -:101BA0000026833E1400FF740A8EC0268C1E00009F -:101BB000E90500268C1E140033C08ED8C3C38CC028 -:101BC000870692013DFFFF740D8ED88C060000330E -:101BD000C08ED8E904008C069001E80100C306839A -:101BE0003E9001FF7429833E3A34007511BA860095 -:101BF000E81E008C063A34833E9001FF7411833E48 -:101C00003C3400750ABA8800E806008C063C3407AC -:101C1000C3A190018EC026A10800EF26A1000026D6 -:101C2000C7060000FFFFA390013DFFFF7503A392CD -:101C300001833EED3400740BB81000E784C706ED55 -:101C4000340000C35051565752061E33C08ED8E799 -:101C50005AFF06BC33E925FB5051565752061E3336 -:101C6000C08ED8E75AFF06B033E911FB50515657E2 -:101C700052061E33C08ED8E75AFF06B43306FF065D -:101C80007634803EFE3400740407E9F0FAB8800030 -:101C9000E8D30207E9E6FA000000000000000000B7 -:101CA000C61D081D911E5D1E731E891E911EA81D56 -:101CB000911E911EAF1EAF1E151D151D911E991F61 -:101CC000000000000000000000040000000200000E -:101CD00000010010000100400000000000010000B1 -:101CE00007E999FA5051565752061E33C08ED8E76D -:101CF0005AFF06B2330668F61CE506A3B2338BF032 -:101D000083E61E2EFFA4A01CE50CA980007406E843 -:101D1000A401E506C353E50C8BD8A9010074148314 -:101D20003EE03A00740D8E063834E8BF06C706E080 -:101D30003A0000E5000D1800E700E5020D1100E78C -:101D4000028BC35BA901007401C38BD0B80008E704 -:101D5000848BC28E06383426A30C008BD0C1E003DE -:101D60008316883400FF067C3426833E06000A75FD -:101D7000218BC22540183D4000740C3D00107512A7 -:101D800026FE0E0A00740BF706EF3420007503E9F7 -:101D90005A068CC0268E06020026830E08002026D6 -:101DA000A3120026A31000C3FF06C433E50CA9014B -:101DB000007501C3A9F0077401C3FF06D433E50021 -:101DC0000D1800E700C3FF06CA33803EA036087531 -:101DD000148E06303426F7060A00000874072681A0 -:101DE0000E08000008E58225FDFFE782E50C50E5BE -:101DF00080250007A3E43AE58C250080A3E23A5849 -:101E0000A902007525833EE23A00751E833EE43A3E -:101E1000007517E5080D000425FF04E708E86A01CE -:101E2000E5820D0200E782E92100E81A06803EE81B -:101E3000FF00740A803EE8FF047403E90D00C60643 -:101E4000E8FF01BA0C01B80808EFED803E9F3606A6 -:101E50007505830E993640B80001E90901FF06CCEB -:101E6000338126AF36FFF7A1AF36E706FF06C6344B -:101E7000E91E00FF06CE33FF0695378126AF36FFF9 -:101E8000EFA1AF36E706E90800FF06D033FF067A78 -:101E900034FF06D233D1E68E0630342E8B84C01C3C -:101EA00026090608002E8B84C21C09066637C3E586 -:101EB0000CA98000745650E8F00058A9000175077D -:101EC000FF06C633E90800FF067834FF06C833E58D -:101ED0008225FDFFE782E86E05BA1001ED803EE83D -:101EE000FF00740A803EE8FF047403E91D00C60683 -:101EF000E8FF01BA0C01B80808EFEDE90D00C606CD -:101F0000E8FF03BA0C01B80808EFEDC3A90100749B -:101F10001CE82C00833EE03A00740F068E0638342D -:101F2000E8C904C706E03A000007E95D008BD08EDF -:101F300006383426A30C00E8060068691DE94A004B -:101F4000A90004740AB80004FF06D833E91700A9F1 -:101F50000001740AFF063937B80001E90800A9102A -:101F600000B81000741D090666378CC08E06303428 -:101F700026F7060A000001740726810E08000001FA -:101F80008EC0C3FF06C233E9F8FFE5000D1800E775 -:101F900000E5020D1100E702C358E943FDE5080D15 -:101FA000000425FF04E708E9E0FFE50EA900087535 -:101FB00001C3E9F5FF000000000000000000000080 -:101FC0005051565752061E33C08ED8E75AFF06B8F6 -:101FD00033E548065357FF164E375F5B833E80015B -:101FE000FF74588E06800126FF0E0800754D26A14D -:101FF0000000A3800126C7060000FFFF8CC0268ECC -:1020000006020026810E080080008BD02687061A63 -:102010000026833E1800FF740A8EC0268916000031 -:10202000E905002689161800833E8001FF740C8E96 -:1020300006800126833E08000074B307E93EF7E5F9 -:102040004C90E502A90020740D25FFDF0D0100E78B -:10205000020D0020E702E50A8BD8A3F43325C3570D -:102060000D0010E70AF7069B3600807437F7C300AF -:10207000807406F7C30008745D8126C2347FFFC7F1 -:102080000635370500B88003CD3981269B36FF7FA2 -:10209000C7060F370400F7069B3640007506C706D3 -:1020A0000F370300F7069B360020742AF7C3000899 -:1020B0007424803E9D36067C1DFF069434830E6694 -:1020C00037208E06303426F7060A000001740726F2 -:1020D000810E08000001F7C30020753BF7069A3710 -:1020E0008000740BFF06893733C0E70EE90400FF58 -:1020F000063B37F7069B360020741C80269E36FF71 -:1021000075158E06303426F7060A00000874072677 -:10211000810E08000008C3C300000000000000009A -:1021200002230223022302230323DD220223FD21B3 -:102130000223A424F32402238D227A23022397244A -:102140001B247524022302238E25FB8E067E01FBB1 -:1021500026833E0000FF74F2268E060000FA268BCE -:102160001E080026231E0A0074E58CC08ED0268B24 -:102170002602008C16F23322FF756A26A11C008A03 -:10218000E38ADC22D8750DD0E824F80AC075F2B0D5 -:1021900080E9EDFFD0E824F80AC07502B08032E48F -:1021A00026A31C00F7C3080075472E8A9FC5252E5D -:1021B0008BBFC52680C310268E1D268C1E06008B65 -:1021C000160000C7060000FFFF26891583FAFF7579 -:1021D0000A2E8B97CD26262116080033C08ED826CE -:1021E000891E0400C38ADFB7002E8A9FC525E9E057 -:1021F000FF2683260800F783C310E9DEFF60061E72 -:102200006887256A001F8E06F2338B0E3434390E30 -:10221000F233740E26810E0A00000226810E080099 -:1022200000022689260200A3F2338ED08D2680007C -:10223000368926020036891E200036C706080000AF -:1022400000B90400BE00002E8BBCC52636C705FFB2 -:10225000FF36C74502FFFF83C602E2EB8E067E0112 -:10226000368B0E22008CC026833E0000FF268E0691 -:1022700000007407263B0E22007DEA368C06000023 -:102280008EC0268C160000FB36FF2E1E00061E6830 -:102290008B256A001F2609360800F7C600FF740167 -:1022A000C356522E8BB4C52581E6FF002E8BB4C5D4 -:1022B000268CC28EC026C7060000FFFF8EC2268372 -:1022C0003CFF740F8BD0268754028EC226A30000D9 -:1022D000E90700268944022689045A5EC3061E685F -:1022E0008B256A001F8E06F23326A30A0026892654 -:1022F0000200A134348ED08D2680008C16F233E992 -:102300004DFECF501E525333C08ED826833E04005C -:10231000FF26C706040000007403E91A00833EE6A6 -:102320003A027613FF06D6338CC08E063234BE4096 -:1023300000683A23E95EFFE884F85B5A1F58CFE84B -:10234000E10026C606180010268A1E2900881E1BDA -:102350003726C7060C00FF7F26A10E00E79C26A1AA -:102360000800E79AE50080FB0874090D18ACE70047 -:10237000071F58CF0D1800E9F4FF501E0633C08E1A -:10238000D8833EA1360075B7268B3606002EFF9403 -:10239000DC23071F58CFE88A00E5000D1800E7008E -:1023A000E84900C353F706EF342000752DE58C256E -:1023B00000708BD8E58C2500703BC374058BD8E981 -:1023C000F2FF3D00307510E50225EFFFE702C7067A -:1023D000E03AFFFFE90300E812005BC3A323962362 -:1023E000A423A4239623A4239623962326A029007E -:1023F000A21B3726C7060C00FF7F26A10E00E79C14 -:1024000026A10800E79AE50025FF53268B36060033 -:1024100083E60E2E0B84AD25E700C3061E688B25D0 -:102420006A001F830EEF3420830E9B3608E50025DB -:10243000EFFF0D0800E700E500A910007501C3E5F6 -:1024400000A9100075F9C350535156061E33C08EB3 -:10245000D8B80500E784E5080D000425FF04E70867 -:10246000E5000D1800E700E5020D1100E7021F0767 -:102470005E595B58C3501E33C08ED8C706EF340078 -:102480000083269B36F7E5000D1800E700E5020DF6 -:102490001100E7021F58CF60061E6887256A001FDB -:1024A000E816F5C3061E688B256A001F8EC02683BA -:1024B0003E0A00007403E8430026C7060A00FFFF37 -:1024C000268B1606008E1E8E018CD88BCA833E008A -:1024D00000FF8E1E0000740A2B16080073EB290EF5 -:1024E000080026890E0800268C1E00008ED88C0657 -:1024F0000000C360061E6887256A001F8EC08BC857 -:102500008E1E8E0126C7060A0000008CD8833E006E -:1025100000FF74253B0E00008E1E000075ED8ED866 -:1025200026A10000A300003DFFFF74568ED826A10F -:10253000080001060800E94900268E1E0200BE18A8 -:1025400000833CFF743C390C74198E1CBE00008360 -:102550003E0000FF742C390E000074078E1E000030 -:10256000E9ECFF26A10000890433C98ED93DFFFFA5 -:10257000751083FE18750B268E1E0200812608003A -:102580007FFF33C08ED8C31F0761CF1F07CF600600 -:102590001E6887256A001FE506251E003D1E007582 -:1025A000F6B90800E558E75A23C0E0F8C300000078 -:1025B000000000000000AC000000A8008C02040035 -:1025C0000008102000FF0E0C0C0A0A0A0A0808086E -:1025D0000808080808060606060606060606060691 -:1025E00006060606060404040404040404040404A1 -:1025F000040404040404040404040404040404049B -:1026000004040404040202020202020202020202A0 -:10261000020202020202020202020202020202029A -:10262000020202020202020202020202020202028A -:10263000020202020202020202020202020202027A -:102640000202020202000000000000000000000080 -:10265000000000000000000000000000000000007A -:10266000000000000000000000000000000000006A -:10267000000000000000000000000000000000005A -:10268000000000000000000000000000000000004A -:10269000000000000000000000000000000000003A -:1026A000000000000000000000000000000000002A -:1026B000000000000000000000000000000000001A -:1026C00000000000001800140010000C00FF7FFF45 -:1026D000BFFFDFFFEFFFF7FFFBFFFDFFFE7FFFBF49 -:1026E000FFDFFFEFFFF7FFFBFFFDFFFEFF00000036 -:1026F000803EE234017603E9A500B80000E74EB958 -:102700002800E2FEC606453702BF3F282E8B45084B -:10271000E74EB92800E2FE2E8B1DC706B3364011E6 -:10272000C706B1362700C70646370200C706483736 -:102730006400F706B5360200751C2E0B5D0281267B -:10274000B336FFFEC706B1369C00C7064637080001 -:10275000C70648379001891EB736891EFE33BE2052 -:10276000008BC3E74EB92800E2FE2E8B4504E74EEE -:10277000B92800E2FEE54E8BCB2E2345062E234DD5 -:10278000063AC174364E75D9803E453700740BC683 -:1027900006453700BF2F28E972FFC606453701F707 -:1027A00006B53602007414E5CE25FDFFE7CEE843FA -:1027B00000E5CE0D0200E7CEE83900803EE23401AC -:1027C0007601C3B8EA05E78CFAE812F4FB8D06D06F -:1027D000398BD8C1E804A338348EC0A1303426A385 -:1027E000020026C7060000FFFF83C318D1EB26892D -:1027F0001E0800C3E5020D0040E702E5000D0400DD -:10280000E700B80000E70AE50AA900807514E508AA -:102810000D0010E708E50A0D0008B90500E70AE217 -:10282000FCC3E5080D0010B90500E708E2FCC3048D -:102830000C2000010C7EFF000C0200100040000C78 -:10284000C6010000C0F7FF00C002001000400000F9 -:1028500033C08ED88D3E72498D36B037B914008B97 -:102860001E3034895C022E8B45028944062E8B056E -:1028700089440483C70483C610E2E8C6069E360E68 -:10288000E8FD26688328A1AA02CD35833EA1360043 -:102890007403E93B2733FF8E06A6028B36A4022E73 -:1028A000FFA42E30830E993604C70637370100C6C1 -:1028B00006CA3401E97D19803EA0360874E68026F8 -:1028C0009E36FF751AF7069B3600207412F7069B9A -:1028D000360300750A830E663710C606A03608E96F -:1028E000FB01803E9E360275CEC606A03606E9EC98 -:1028F00001C3E9E80126C7060A00000026FF2604F6 -:1029000000A1D1362639061A007522A1D336263900 -:10291000061C007518A1D5362639061E00750E2630 -:10292000F7060C0040007405830E663740810EAF39 -:10293000360010A1AF36E706803E9D36027506CD03 -:1029400034E9A21AC3F7069B361000755426F60622 -:102950000A00FF754C26A0190024C03C4075118068 -:102960003E953600743B26C7060400FFFFE93100A0 -:10297000E8F104F7069B360300742F8BD8B87D036B -:10298000CD3A8BC3C606A03606F7069B3602007505 -:1029900005C606A03604810E9B36800083269B3632 -:1029A000FCE92301E8871DE933015026A10C00252D -:1029B00007003D07007503E984003D05007503E944 -:1029C0007C00833EE83A047475833EE83A02746EF4 -:1029D000F706E63418807503E96A00F706E6340066 -:1029E00080743526803E290002752D5156578D364C -:1029F0003E348D3E2000B90600F3A65F5E59744553 -:102A000026A12000A33E3426A12200A3403426A103 -:102A10002400A34234E92600F706E6340800740BCC -:102A200026803E1900007403E91300F706E634100F -:102A300000741226A02800C0E80422C0740726C72C -:102A4000060400FFFF5823C07403E957FF81269B4B -:102A500036FFFE83FE067F2426A120003B06D136EA -:102A6000751A26A122003B06D336751026A1240034 -:102A70003B06D5367506810E9B36000126A1200047 -:102A8000257FFFA3B83426A12200A3BA3426A124AF -:102A900000A3BC348BC686C4A3C034D1E680FC0935 -:102AA0007403E8AA1C8BC62EFFA4304926A10C0093 -:102AB0003DFF7F740F26FF2604008E063834E8366B -:102AC00006CD50C3E91600CD34E91100CD34893666 -:102AD0003D37A19D36A33F37C606A0360CE88E00D1 -:102AE000A19F3622E47532F7064C370100752AF6AD -:102AF000069D3680740788269E36E931003A069D89 -:102B000036A39D3674288BF02EFFA40D2B4429EE9E -:102B1000421944CD442F455A453A269E367501C385 -:102B200032C086C48BF0A29E362EFFA420498B2E85 -:102B3000993623ED7501C3BF0100BE000085FD7508 -:102B40001A46D1E7E9F6FF2A0029002800270025C8 -:102B50000005000700260006002000F7D7213E9957 -:102B600036D1E62E8BB4472BE94FFFE956FF80267E -:102B70009E36FF7517F7064C370100750FF6069D58 -:102B800036807408F7066637FFFF7507C706663795 -:102B90000000C3F70641370100750BB87F03CD393C -:102BA000C7064137010033F6B80040850666377422 -:102BB0002180BC5437FF7404FE84543780BC9634A3 -:102BC000FF7404FE84963431066637833E66370010 -:102BD000740546D1E873D4C3A1F433A90088740BFB -:102BE000A9001075098B1E4337FFE3E9D700C7061C -:102BF00035370500C70643371E2CF706F4330008A7 -:102C00007406C7064337102CB88003CD39E9CDFED2 -:102C1000A9000874D9FF0E353775EDE96600A900E3 -:102C20000875CBFF0E353775DF810EC234C000F654 -:102C3000069D36807448810E9B360080F7069B36D1 -:102C40000100741EB87D03CD3A810E9B368000834F -:102C5000269B36FEC7060F370200C606A03604E9DB -:102C60007BFE803EA036047507833E0F3701750555 -:102C7000C606A03606C7060F370200E95FFEBE0291 -:102C800000E94AFE80269E36FF753AF6069D36809C -:102C9000742DF7069B360020752BC606A03606FF5E -:102CA000069434830E6637208E06303426F7060AE3 -:102CB000000001740726810E08000001E90600BE2D -:102CC0000400E909FE810EAF360008A1AF36E70621 -:102CD000E50AA90080740E8126AF36FFF7A1AF3652 -:102CE000E706E909FFE9F5FDC70641370000830E55 -:102CF000993602E9E7FD80269E36FF751DF7069B93 -:102D00003600407505830E993608830E993620816A -:102D1000269B36FFBFB88503CD39E9C0FD803E9EB6 -:102D200036067407803E9E360A7534F6069D368058 -:102D30007506BE0700E996FDC606A03604833E0F61 -:102D40003702741BC7060F370400803E9E36067597 -:102D50000EF7069B3640007506C7060F370300E9DD -:102D60007BFD803E9D36047512810EC2340040FF0B -:102D7000069234C606A03606E962FDBE0500E94D9E -:102D8000FDF6069D36807519830EC23404BE06001A -:102D9000E93BFD80269E36FF75C5FF063137E90009 -:102DA000008326C234BFC606A03606E92FFDE50A19 -:102DB0005025C3BFE70A5880269E36FF750DA9002F -:102DC000407508C606A03606E912FDB88303CD3962 -:102DD000C3B87C03CD39F706F43300107509C70674 -:102DE00033370200E9F6FCFF0E33377403E9EDFCDC -:102DF000FF068E34E8F719830EC23408BE0300E9DB -:102E0000CCFC0000000000000000000400040405E9 -:102E1000040404000300030300000000000000009D -:102E20000004000808050808080003000303000068 -:102E3000020404040400000800000A1400001A0040 -:102E40001C001E2000000441060B08C2FFE704031B -:102E500006040405040604870403060404854EA240 -:102E600004CF04CDC706A2370000C706A63700006E -:102E700026A12000257FFFA3F53626A12200A3F777 -:102E80003626A12400A3F936E83B198BF0268B0ED9 -:102E90000E002BC883E90EB8018083F9047C51260B -:102EA0008A542888161C3740268B6C2686CD3BCD4D -:102EB00086CD890EA43775384032FF268A5C29807A -:102EC000FB15772580FB0A742080FB01741BB80476 -:102ED000802E3A97022E74072E3A97182E751133CA -:102EE000C080FB09754F8BF3C326C7060400FFFFA4 -:102EF0005052A1A43786C4263B0626007C32268188 -:102F00003E260000047E298D742A268B1422D2745A -:102F10001F80E6BF80FE097517C706A23701008033 -:102F2000FA04750C268B4402A3033786C4A3D0345D -:102F30005A58E9B1FFBD72372E8A872E2E22C074EF -:102F40001605442E8BF82E8B053E89460083C5025C -:102F500083C70222E47DEF8D742A83E9047503E9B7 -:102F6000A100268B1422D27503E97C00C706A63780 -:102F70000100BF72378B0583C70280E6BF80E43F44 -:102F800080FE09752280FA04755EC706A23701002B -:102F9000268B4402A3033786C4A3D03486C4C70655 -:102FA000A6370000E947003BFD7E15268B04A840AC -:102FB0007406B80780E938FF32C0268B04E92E007A -:102FC0003AF475B1C745FE000080FE22750D3AD077 -:102FD0007716C706A6370000E913003AD07509C76F -:102FE00006A6370000E90600B80580E902FF32F6C0 -:102FF00003F22BCAB8058023C97603E964FF740382 -:10300000E9EDFE33C0BF72378B1547473BFD7F1B91 -:10301000F6C6807416F706A63701007406B8088055 -:10302000E9C3FEF6C64074E0B80780E9B8FE7D4209 -:10303000A34544294429B728E228EE2BF228F52895 -:103040000129AC2A4429442944294429442900005F -:10305000733600000336C535833545350735D23420 -:1030600045340000000000000000000000000000E7 -:103070000000A6380000E03800000000000000005A -:103080000000000000000000000000000000000040 -:10309000F2330000A6336033FD32BC3277323C326B -:1030A000FB316A310A31E0E0101010E0E0E0E000AE -:1030B0000000000000000000000000000000000010 -:1030C000000000000000E000E0E0E0E0E0E0E0E020 -:1030D000E033FF26F6061A0080741B2680261A00AD -:1030E0007F268B3E260083E71F740B26800E200070 -:1030F0008026013E0E00C3602E8B84A63026A318C6 -:1031000000D1E62EFF94503061C326C7060400C4E8 -:103110002A26C7060E00160026C706060006002649 -:10312000C606190000E8BF05E8980526C706260070 -:10313000000826C60628004026C60629002ABF2AFF -:103140000026C6050426C645012AA1933733DBA90C -:1031500040007502B301A900107402B788A90008E5 -:10316000740380CF4426895D02C3830EC2342026B7 -:10317000C70604006B2B26C7060E00300026C706C4 -:1031800006000A0026C7060A00040026C606190023 -:1031900000E86905E82C0526C7062600002226C699 -:1031A0000628006026C606290029BF2A0026C60573 -:1031B0000826C645012D8D7D02BE5437B90300F3A4 -:1031C000A526C6050826C645012E8D7D02BE5A37A6 -:1031D000B90300F3A5E8D405E86405B90600BE54B8 -:1031E000378D2E2C00268B4600290483C60283C50A -:1031F0000283F90475024545E2EBC326C7060400C5 -:10320000C42A26C7060E00240026C70606000600AC -:1032100026C606190000E8E404E8A70426C7062627 -:1032200000001626C60628006026C606290028BF0C -:103230002A00E85B06E87405E80405C326C706040F -:1032400000C42A26C7060E001A0026C70606000676 -:103250000026C606190000E8A304E8660426C7068F -:103260002600000C26C60628006026C60629002770 -:10327000BF2A00E82105C326C7060400C42A26C7C2 -:10328000060E00200026C70606000A0026C7060A0A -:1032900000040026C606190000E84B04E8240426B2 -:1032A000C7062600001226C60628004026C60629A4 -:1032B0000026BF2A00E8F404E88404C326C70604F5 -:1032C00000C42A26C7060E00340026C706060006DC -:1032D0000026C606190000E80D04E8E60326C70626 -:1032E0002600002626C60628004026C606290025F8 -:1032F000BF2A00E8B604E84604E8FA04C326C70675 -:103300000400C42A26C7060E003800A1A237500BBD -:10331000C0750726C7060E00340026C7060600063D -:103320000026C606190000E89903E8A4FD26C74553 -:1033300026002A580BC0750626C745260026A11C64 -:1033400037C1E0042688452826C645292483C72A94 -:10335000E82904E8A004E82205E8F803E80904C322 -:1033600026C7060400C42A26C7060E00320026C758 -:10337000060600060026C606190000E84503E850C8 -:10338000FD26C745260024A11C37C1E00426884538 -:103390002826C645292383C72AE8E003E86C04E809 -:1033A0008A04E89C04C326C7060400C42A26C7066C -:1033B0000E00340026C7060600060026C6061900C1 -:1033C00000E8FF02E80AFD26C745260026A11C37B3 -:1033D000C1E0042688452826C645292283C72AE855 -:1033E0009A03E8C703E85703E8F803E87804E88A93 -:1033F00004C326C7060400744526C7060E003E0017 -:1034000026C7060600060026C7060A00040026C6D0 -:1034100006190000E8FC02E8A902833E8D37037517 -:10342000019026C7062600003026C6062800502632 -:10343000C606290020BF2A00E8D003E80103E8B54A -:1034400003E89F03C326C70604006143B9F0008365 -:10345000E90226890E0E0026C7060600020026C6CF -:103460000619000026C7061A00000026C7061C0021 -:10347000000026C7061E000000E8470283E90E860A -:10348000CD26890E260086CD26C60628000026C633 -:1034900006290008BF2A0083E90426890D26C645AF -:1034A00001268D7D0283E902BB0100B830304B75E7 -:1034B00017BB0A008AC4268805B03180C40180FC8D -:1034C0003A750AB461E90500268805040147497583 -:1034D000DDC326C7060400044526C7060E001200F9 -:1034E00026C7060600060026C606190001E8E50103 -:1034F000E8D00126C7062600000426C606280000DC -:1035000026C606290007C326C7060400C42A26C704 -:10351000060E00200026C7060600060026C606196D -:103520000006E80402E89B0126C7062600001226D2 -:10353000C60628000026C606290006BF2A00E86B3A -:1035400002E8FB01C326C7060400C42A26C7060EEC -:1035500000200026C7060600060026C6061900053C -:10356000E8C601E85D0126C7062600001226C60649 -:1035700028000026C606290005BF2A00E82D02E81B -:10358000BD01C3FF06823426C70604003D4126C79D -:10359000060E00200026C70606000E0026C60619E5 -:1035A0000004E88401E81B0126C706260000122655 -:1035B000C60628000026C606290004BF2A00E8EB3C -:1035C00001E87B01C326C7060400674226C7060E32 -:1035D00000200026C7060600080026C606190003BC -:1035E000E84601E8DD0026C7062600001226C606CA -:1035F00028000026C606290003BF2A00E8AD01E81E -:103600003D01C3FF06843426C7060400674226C76F -:10361000060E00240026C7060600080026C6061966 -:103620000002E80401E89B0026C7062600001626D3 -:10363000C60628000026C606290002BF2A0026C6A4 -:10364000050426C6450101A10F3786E0F6066F374F -:1036500001750F3906CC3474098BD8B88903CD397C -:103660008BC3A3CC34268945028D7D04E83D01E857 -:10367000CD00C326C7060400C42A26C7060E001CB8 -:1036800000A1A237500BC0750726C7060E00180010 -:1036900026C7060600060026C606190000E8230015 -:1036A000E82EFA26C74526000E580BC0750626C719 -:1036B0004526000A26C645290083C72AE8BD00E83A -:1036C000FF00C3565751B90300BED136BF2000F3E7 -:1036D000A5595F5EC3565751B90300BED136BF1A14 -:1036E00000F3A5595F5EC326C7061A00C00026C7AF -:1036F000061C00000026C7061E000010C326C706D1 -:103700001A00C00026C7061C00000026C7061E00BF -:103710000008C326C7061A00C00026C7061C000002 -:103720000026C7061E000002C326C7061A00C000F6 -:1037300026C7061C00FFFF26C7061E00FFFFC32684 -:10374000C6050826C64501028D7D02BE0537B903B0 -:1037500000F3A5C326C6050426C6450106A10D37FC -:10376000268945028D7D04C326C6050426C645016B -:1037700007A10B372689450283C704C3A1A2370BD3 -:10378000C0741326C6050426C6450109A1033726C1 -:1037900089450283C704C326C6050826C64501021B -:1037A0008D7D02BE0537B90300F3A5C326C6050605 -:1037B00026C645010B8D7D02BEEF36B90200F3A58A -:1037C000C326C6050626C6450120A16837268945B9 -:1037D00002A16A3726886505C1E00426884504836E -:1037E000C706C326C6050426C645012126C74502CD -:1037F000000083C704C326C6051426C64501228DD2 -:103800007D02BE1F37B90900F3A5C326C6050C26E5 -:10381000C64501238D7D021E0E1F8D364054B9030F -:1038200000F3A533C0B90200F3AB1FC326C60508D9 -:1038300026C64501288D7D02BED136B90300F3A509 -:10384000C326C6050826C6450129A1C23486E0263E -:10385000894502A19B362689450426884506268887 -:1038600045078D7D08C326C6050626C645012B8D56 -:103870007D02BEBB36B90200F3A5C326C6050626E7 -:10388000C645012C8D7D02BEE536B90200F3A5C305 -:1038900026C6050426C6450130A1373786E02689AD -:1038A00045028D7D04C326C7060E001E0026C706EE -:1038B0000600020026C606190000E86CFEE803FEBA -:1038C00026C7062600001026C60628003026C60693 -:1038D000290011BF2A00E83500E84500E85500C37B -:1038E00026C7060E00120026C7060600020026C6DE -:1038F00006190000E832FEE8C9FD26C706260000CA -:103900000426C60628003026C606290013C326C68C -:10391000050426C645010C26C74502000183C704DD -:10392000C326C6050426C645010E26C74502000269 -:1039300083C704C326C6050426C645012126C745FC -:1039400002000083C704C300000000000000000064 -:10395000B339C939833AB339B339B3391C3A1C3A4C -:10396000A3B634A1E936A31137A3D234A1EB36A311 -:103970001337A3D434A1ED36A31537A3D634A10150 -:1039800037A3CE34A1F736A31737A3DC34A1F93619 -:10399000A31937A3DE34F7069B360200750C33C03B -:1039A000A09E368BF02EFFA45039E90F01BE070010 -:1039B000E919F1F6069D368074F3C606A03602C6F4 -:1039C000066E3708C606703702B88803CD39F6068A -:1039D0006F3701754AA1D1363A06E93675413A2664 -:1039E000EA36753BA1D3363A06EB3675323A26EC09 -:1039F00036752CA1D5363A06ED3675233A26EE36C5 -:103A0000751DC606703702FE0E6E37750FB8880337 -:103A1000CD3A830E9B3612C606A0360CE9A8F0A15B -:103A20000537263B0620007540A10737263B0622B6 -:103A3000007536A10937263B062400752CA09E365A -:103A40003C02750826F6061800087547C6066E374C -:103A500008FE0E7037751CC606703702E5020D01B0 -:103A60000425EFFFE702E95EF0C606703702C606DE -:103A70006E3708E50225FFFB0D010025EFFFE70289 -:103A8000E944F0F7069B360001742526F606180077 -:103A90000875ED81269B367FFFB88903CD3AB8843F -:103AA00003CD3AC606A036068326C234AFE917F026 -:103AB000A101373A260F377FC7E9F7FE83269B36E9 -:103AC000ECE82A0D810E9B368000BBFF7FCD53C6EC -:103AD00006A03602E9F0EF830E9B3611C606A0362B -:103AE0000CE9F9EF443B2C3BC72A6B3B443BC72A0C -:103AF000C72AC72AA3B634810EC2340020F7064174 -:103B0000370100741B8CC3C70641370000B87F0320 -:103B1000CD3A33C08EC0BF5437B90600F3AB8EC365 -:103B200033C0A09E368BF02EFFA4E43AF7069B36F6 -:103B3000000175218326C234BFA1A936E700A19BED -:103B400036E90900A19B3681269B36FFDFA90020BC -:103B50007506E96E00E96FEF830E993604C70637E4 -:103B6000370100C606CA3401E95800830E9B36406F -:103B7000E85800A105373B06E9367537A107373B02 -:103B800006EB36752EA109373B06ED367525FE0E80 -:103B90007137751CB88703CD3A830E993610A15042 -:103BA00037C7065037000009069936C606A0360802 -:103BB000E914EF830E993604C70637370300C606AB -:103BC000CA3403C606A0360AE9FCEEA1D136263B6C -:103BD0000620007515A1D336263B0622007512A1DA -:103BE000D536263B062400750FC38D362000E90B21 -:103BF000008D362200E904008D36240083C402F7CC -:103C000006E63401007415263A047708720E263A47 -:103C100064017208C606A03606E9ABEEE87C0A8CA1 -:103C2000C03DFFFF741B26C60618001026C70604F9 -:103C300000493C26C70606000C00CD50B94E00E2F4 -:103C4000FEC606A0360AE994EEE97BEE8F3C063DFF -:103C5000063D063DD23CEA3C063D063DA3B6348116 -:103C600026C234AFDFC7064C370000B88A03CD3A0E -:103C7000803E9D3604750C803E9E36067405C60651 -:103C80009F360633C0A09E368BF02EFFA44C3CF727 -:103C9000069B360020750E81269B36FFBFB88B032E -:103CA000CD3AE95400F7069B3600017403E917EE9C -:103CB000C70637370200C606CA3402830E99360497 -:103CC000830E503704F6069D3680752AE81F0BE9EF -:103CD0002700F7069B36000175D3C7063737020069 -:103CE000C606CA3402830E993604C606A03600F60C -:103CF000069D36807403E8DE0A81269B367CFFBB76 -:103D0000FFFFCD53CD54E9BEEDA3B634E8AD01B805 -:103D10008603CD39C7064C3700008126C234AFDF99 -:103D2000F6069D36807434F7069B3600207456F7ED -:103D3000069B3600017427E83501721CBE004085E1 -:103D400036C23475080936C234FF069234E88B0156 -:103D50007306810E99368000E96CEDE9B500C7065F -:103D600037370200C606CA3402830E993604830E22 -:103D7000503704803E9E36087403E85A0AE8EF0084 -:103D800072D6E9C8FF803E9E360A7512C606A03676 -:103D900000F7069B3608007402CD54E8390A8126E4 -:103DA0009B36FFBFE8C80072AFB88B03CD39E99CE2 -:103DB000FFF6069E36FF7558A3B634E8FE0081264E -:103DC000C234FFBFF6069D36807448F7069B360066 -:103DD000207422F7069B3600407508E89100723087 -:103DE000E9220026A10C00A960007524810E663727 -:103DF0000008E9D2ECC7064C370000E871007210E9 -:103E0000B88B03CD39E8D3007306810E9936800054 -:103E1000E9B4EC803E9D3604750C803E9E360674F7 -:103E200046C6069F3606F7069B360001740C803E98 -:103E30009D36087505C6069F360AE8320072D1E83D -:103E40009900803E9D36087513810E99368000F7E3 -:103E5000069B3600207508B88B03CD39E968ECC69F -:103E6000069F360AE960ECB88603CD3AE958EC269D -:103E7000A10C00A9600074088126C234FFBFF9C3F9 -:103E8000F7069B3600407413810E66370008E84A37 -:103E9000007306810E99368000F9C3810E9B3600AF -:103EA0004080266F37FE81269B367FFFC606A036F0 -:103EB00000F8C3810E99360001E921EC26A120000B -:103EC000A3FB36A3AA3426A12200A3FD36A3AC345B -:103ED00026A12400A3FF36A3AE34C3A10537263B99 -:103EE0000620007519A10737263B062200750FA191 -:103EF0000937263B0624007505E80200F8C3511E69 -:103F0000068BC78D362000BF0537B903001E061F7C -:103F100007F3A58BF88D362000BFA034B90300F35A -:103F2000A5071F598BF8A10737A3A634A10937A30A -:103F3000A834F9C3C606B63401E98BEBE887088BD1 -:103F4000F00512002629060E00268B442A263A0682 -:103F50000E00755B26832E0E000280FC277550260E -:103F60008B442CA9FFFF75478BFE33C026F6453CDA -:103F7000807406268A453A241F03F826807D450969 -:103F8000752D8CC28E0638348EDA8B0E0E00268983 -:103F90000E0E008D742CBF1800F3A433C08ED826EB -:103FA000C7060400B53F26C70606000600CD50B878 -:103FB0000680E9EFE926A10C00A39337830E99361A -:103FC00001E900EB26803E1C00FF752F26803E1E77 -:103FD00000FF752726F7060C004000751BA1D1369F -:103FE00026A31A00A1D33626A31C00A1D53626A3EA -:103FF0001E00B80A80E83607E9E2EAFF069034BE00 -:104000000A00C606B63401F6069D36807505830E95 -:10401000C23401E9B6EA803E9D360A750F26A10C2E -:10402000002507003D04007503E87900A1F33686FA -:10403000E0E71EA3E33681260B37000381260D3708 -:104040007B7F830E0D3748E81E0026A10C00250754 -:10405000003D0400740926F7060C0020007506B820 -:104060000100E93FE9E95FEAC70641370000B87F90 -:1040700003CD3AA11D37A3C43486E0687F031FA394 -:10408000060033C08ED8A10B37A3B234A10D37A3DD -:10409000B434A1F336A3C834A1EF36A39C34A1F104 -:1040A00036A39E34C3800E9D3680BE0000E8B40760 -:1040B000B87B03CD3AB87C03CD39C706333702004D -:1040C000A1E536E72EA1E736E73EB88203CD3AF701 -:1040D000069B3600207503E8FD06A1D336A3EF3614 -:1040E000A39C34A1D536A3F136A39E34C3F6069D16 -:1040F00036807431BE2200E91700F6069D368074C2 -:1041000024BE2300E90A00F6069D36807417BE24FB -:104110000056E8A8058CC03DFFFF5E7405E8D7EFA8 -:10412000CD50E91FE8E99FE9000000000000000011 -:10413000B88403CD3AB88A03CD39E9F700803EA0B0 -:104140003608752EA9D007752CA1B1360D0004E7ED -:1041500008E50025FF73E700B88A03CD3AE8C306F7 -:1041600033C0E70EE50A25C317E70ACD54C606A0FB -:104170003600E968E9BE0400E93FE983269B36BFC3 -:10418000C606713703B88603CD3AB88803CD3AB86E -:104190008303CD3AB88703CD39810EC2340020E9BC -:1041A0009200E84906B88703CD39BBFF7FCD53B8ED -:1041B0008403CD3AB88803CD3AB88B03CD3AB8839F -:1041C00003CD3AB88603CD3AB88503CD3AC3E500AE -:1041D00025FF53E700830EC234408326C234EFE844 -:1041E0000C06BBFF7FCD53B88A03CD3AB88503CD0B -:1041F0003AB88603CD3AB88303CD3AB88703CD3AAF -:10420000B88B03CD3AB88403CD3AB88903CD3AC30D -:10421000830EC23450E81804E8D305F6066F370160 -:104220007512B88903CD39833E0F37007506C7066E -:104230000F370400A19D3680FC087405B88403CDB7 -:1042400039E5020D010825EFFFE702A19D3686E062 -:1042500032E48BF0D1EE33C00D20000906AD36A15B -:10426000AD36E704E953E8E95AE833C0A01B37D17B -:10427000E03A06A0367503E9BAFFE960E8C70641EF -:10428000370000E8C1E1E86A0633C00D4100E75697 -:10429000A1B1360D0010E708E50225F9FF0D030076 -:1042A000E702A1B336E70AA1AF36E706A1AD36E7CC -:1042B00004E87C03E89F03C7061D3700C8C7060B48 -:1042C000370003C7060D377B7F33C0A39936A39B06 -:1042D00036A39D36A39F36A34C37A3F336A3EF3600 -:1042E000A3F136E882FDC6069F3602E9EFE7E50254 -:1042F0000D018825EFFF0D00400D0004E702E8F2F4 -:1043000005E50A0D4000E70A33C0A38137A38537CE -:10431000A38337A38737A38937E5000D0084E7001F -:10432000B88C03CD39B88000CD35C706AA02FFFF8F -:10433000E50025FF7BE700810E9A378000B87E03F9 -:10434000CD3933C0E70EBE08008E063834E8A7ED3D -:104350008326EF34DFFF068137CD50830EEF342004 -:10436000C3F7069A378000743DA9D0077410A900DE -:1043700004741233C0E70EFF068737E9D2FFFF0649 -:104380008537E9CBFFFF068337E9C4FF83269A37D9 -:104390007FA18937030687373D05007F01C3BBFF37 -:1043A0007FCD53E90000E50225FFFB25EFFF0D015E -:1043B00000E702A183373B0646377F2AA185373BBA -:1043C0000648377C21A18937030687373D05007FE2 -:1043D00015C6069F3604E50225FFF70D010025EFFF -:1043E000FFE702E9F7E6BE0100F7069B360300741B -:1043F0000A83269B36FC830EC23404E9D0E6B87BE0 -:1044000003CD39E5020D016025EFFFE702C706F194 -:10441000342003B88E03CD39C38126C2347FFF8098 -:104420000E6F3701F7069B36030074D2B87B03CDBD -:104430003AB87D03CD3983269B36EF33C0B08AA2CC -:104440009F36A29D36C7064C370100C7060F3704BA -:1044500000F7069B3640007506C7060F370300B805 -:104460008D03CD39E800D5E5020D014025EFFF8B26 -:10447000D8B87C03CD39C706333702008BC30D0093 -:104480002025F9FF0B06E83AE702C3FF0EF1347569 -:1044900001C3E54EA901007512E500A900047505E8 -:1044A0000D0004E700B88E03CD39C3E500A9000470 -:1044B00074F325FFFBE700E9EBFFC606A036048393 -:1044C000269B36FC810E9B368000E910E6B88E03F1 -:1044D000CD3ACD54810EAF360018A1AF36E706B8FD -:1044E0007B03CD39A1D336A38F37A1D536A391371E -:1044F000C7068B370200C7068D370200830E993638 -:1045000040E9D9E5803E9F36067515A9D00775ECC0 -:10451000250018750EFF0E8B3775E1C6069F36080D -:10452000E9BAE5FF0E8D3775D3BE0800E99FE5B8FF -:104530007B03CD39F7069B3600207408C6069F36EC -:104540000AE90D00F7069B360040740BB88B03CDCB -:1045500039810E99368000E983E5B87B03CD39C7F0 -:10456000068B370400C7068D370400810E9936008C -:1045700002E969E5F6069D3680751BA9D00775EB43 -:10458000A90018750CFF0E8D3775E0E817FBE94C94 -:10459000E5B88203CD39C3FF0E8B3775CEBE090057 -:1045A000E92BE5C7063D370000C7069B360000E84B -:1045B0003C028126AF36FFE7A1AF36E70681269B96 -:1045C00036FF7FE5020D010025EFFF25FFDFE70243 -:1045D000BBFF7FCD5333C0A39D36A39F36E8500069 -:1045E000E87300B88103CD39C3F7069B3603007426 -:1045F0000DC6069F3602C606A03600E9DFE4830E2C -:104600009B3610C70699360000E8E702E5560D0212 -:1046100000E756C706A80200008B363D37E8440283 -:10462000C606A0360EE9B5E4000000000000000058 -:1046300006B88A03CD3AB88503CD3AB88603CD3A99 -:10464000B88303CD3AB88703CD3AB88B03CD3AB8D7 -:104650008803CD3A07C306B88803CD3AB87B03CDAB -:104660003AB88203CD3AB87F03CD3AB87C03CD3A4D -:10467000B87E03CD3AB88003CD3AB88103CD3AB8BD -:104680008403CD3AB88903CD3AB87D03CD3AB88DCD -:1046900003CD3AC7064137000007C3068E063834FB -:1046A0001F8B0E0E0026890E0E00BE1800BF1800CC -:1046B000F3A4061E07CD340733C08ED8C326F606F2 -:1046C000200080744433C026A02600241F8BF026CF -:1046D0008B5C28891E6A37068E0638341FC0E304B7 -:1046E00026885C288BC6B90600BE2000BF1A00F3DE -:1046F000A48BC883C706F3A426812626001F802624 -:10470000813626000080E9A9FF268B1E2800891E1D -:104710006A37068E0638341FC0E30426881E280038 -:10472000B90600BE2000BF1A00F3A4E984FF86C4C6 -:10473000A36837E887FFF7066A370F007410803EDA -:104740009E36007509BE0000E8ACE9CD50C3C350E9 -:10475000560633C026F606200080740626A02600E2 -:10476000241F8BF0268B5C2686FB83EB04744F831F -:10477000C62A8CC08ED8B9070033C08EC0BF72372E -:10478000F3AB33C98A0C80F9007503E930003BD9DB -:104790007303E929002BD98A4401253F0074193D90 -:1047A0000B007D14D1E08BF82E8BBD5C498D74021B -:1047B00083E902F3A4E9020003F123DB75C433C0EB -:1047C0008ED8075E58C333C026F6062000807406D4 -:1047D00026A02600241FC3E50A25C3BFE70AB88622 -:1047E00003CD39B88303CD3981269B367CDFB8856C -:1047F00003CD3AE50225FFF30D010025EFFFE702A7 -:10480000E50025FF53E700A1E73625FFFEA3E736C5 -:10481000E73E83269936CF810EAF360010A1AF3622 -:10482000E706C3E5020D010C25EFFFE702A1E7361D -:104830000D0001E73EA3E736810E9B360020830E74 -:1048400099362081269B367CBF810EAF360010A1A1 -:10485000AF36E706B88603CD39B88503CD39B883BE -:1048600003CD3AC30BF67549068E063234803EE01E -:104870003401751B26893606008E06323426F7066B -:104880000A000020740726810E0800002007C3805C -:104890003EE33401751926893606008E0632342629 -:1048A000F7060A000010740726810E0800001007A2 -:1048B000C3E9B4FF50515733C0B906008EC0BFD111 -:1048C00036F3AE5F740C26F6060000C07504F85986 -:1048D00058C3F9E9F9FF8B050B45020B4504C35298 -:1048E00050E506251E003D1E0075F6B80180E75A0A -:1048F000585AC3E8E9FF50E50225FF7F0D01002566 -:10490000EFFFE7020D0080E702A1AD36E704A1AF9B -:1049100036E70658C3000000000000000000000059 -:104920002E2BCE4110427B413041A241AF4544295C -:10493000C72AC72A6039F43A5C3C093DB13D343F8F -:10494000C72A3C3FC72AC43F16401640ED40FA40F4 -:104950000741C72AC72AC72AC72AD65200000137EB -:10496000E936F336EF361D370D370B379C370337F3 -:10497000FB36622D4006D12DF401BA4440068C432B -:104980006400E82CC800D82B0500E9455000974585 -:10499000FA00AE2D04016A420200F62CBC02932DEF -:1049A000DC051D2D6400A12D1400D73A0807812DC8 -:1049B0006400B33E020030436400C52CF4018B4414 -:1049C00002000000000000000000000000000000E5 -:1049D000803EFD3402740CE82005C706A1360000B5 -:1049E000E99AF8FF06C033E810058B363D37E873C7 -:1049F000FEC3CD34E9E805C706A3360000C706416B -:104A0000370000E8EDFE33C00D4100E756A1B13696 -:104A10000D0010E708A1B336E70AA1AF36E706A1FB -:104A2000AD36E704E82B09C7061D3700C8C7060BDB -:104A3000370003C7060D377B7F33C0A39B36A39D8A -:104A400036C7064C370100C6069E36FFC706053737 -:104A50000000C70607370000C70609370000A3F3A8 -:104A600036A3EF36A3F136E8FEF5E50225F9FF0D92 -:104A700003000D008825EFFF0D00400D0004E70244 -:104A8000B88F03CD39B88000CD35C706AA02FFFF25 -:104A9000A1A936A3A7360D00A40D0008E700A3A91D -:104AA00036C706A3360100C706A5360C00833EA50F -:104AB00036007509C7063D370500E913FFFF0EA54F -:104AC00036BE1100E82205B89003CD39C3833EA35A -:104AD000360174D9C3B89003CD3A26A02B00268B9B -:104AE0001E2C00CD34833EA336017403E9F0043C50 -:104AF0000F751E81FB0002751826A12000A3053743 -:104B000026A12200A3073726A12400A30937E9091B -:104B100000C7063D370100E9B6FEC706A33602000E -:104B2000C6069E36FFE8CBFDE81CD933C0A3853707 -:104B3000A38337A38737A38937B89103CD39B880CA -:104B400000CD35C706AA02FFFFE50025FF53E700A9 -:104B5000810E9A378000B89203CD3933C0E70EBE7C -:104B600008008E063834E88EE526C70604007D4B23 -:104B70008326EF34DFCD50830EEF3420C3F7069A3F -:104B80003780007432A9D007740CA90004740E3366 -:104B9000C0E70EE9DAFFFF068537E9D3FFFF06839A -:104BA00037E9CCFFC7063D370100E936FE83269A78 -:104BB000377FBBFF7FCD53E5000D00ACE700E5027A -:104BC00025FFFB25EFFF25FFF70D0100E702A1837D -:104BD000373B0646377FCDA185373B0648377CC437 -:104BE000C706A3360300BE1300E8FD03B89303CD48 -:104BF00039B89403CD39B89603CD39B89503CD397A -:104C0000BE0600E8E303E9D603833EA3360374013E -:104C1000C3BE1300E8D203B89403CD39C3B89403DC -:104C2000CD3A26A02B00268B1E2C00CD34833EA32C -:104C300036037403E9A8033C0D753E83FB00753908 -:104C4000E5020D0020E702B89303CD3AC706A3366C -:104C50000400BE0000E80CFCC6069D3680C6069E19 -:104C60003600C70633370200B89A03CD39E8FC0096 -:104C7000C7064C370000E96603C7063D370800E960 -:104C800061FD833EA336037509C7063D370500E97C -:104C900051FDE94A03833EA336047412833EA336D2 -:104CA00005740BCD34C7063D370700E935FDC7064F -:104CB000A3360600C6069E36FFB89A03CD3AB899C9 -:104CC00003CD3AB89603CD3AB89703CD39B89803D7 -:104CD000CD39B89B03CD39E918FDCD34833EA336D9 -:104CE000047718833EA336037508F7069B36000148 -:104CF0007509C7063D370100E9E8FCE9E102CD345A -:104D0000833EA336027709C7063D370100E9D3FC8D -:104D1000833EA336047705B89603CD39E9C00283F4 -:104D20003EA33603751026A10C00250700503D0454 -:104D3000007503E83600A1F33686E0E71EA3E336EC -:104D400081260B37000381260D377B7F830E0D37BD -:104D500048E814F3583D0400740926F7060C0020B7 -:104D6000007506B80100E97A02E986FCA1E536E79C -:104D70002EA1E736E73EA1D336A39C34A1D536A3B6 -:104D80009E34C326803E1C00FF752F26803E1E00E9 -:104D9000FF752726F7060C004000751BA1D13626AB -:104DA000A31A00A1D33626A31C00A1D53626A31E24 -:104DB00000B80A80E92C02E938FCFF069034BE0AEC -:104DC00000C606B63401F6069D36807505830EC210 -:104DD0003401CD34E90CFC833EA336037509C706C4 -:104DE0003D370500E9FCFBE5020D03000D00880DD1 -:104DF00000400D0004E702C706A3360500C6069E64 -:104E000036FFBE0200E8E101B88903CD3AB89A0343 -:104E1000CD3AB89903CD39B89703CD39B89803CDB9 -:104E200039E9BB01833EA33603740A833EA33604EB -:104E30007403E9AA01BE0600E8AE01B89503CD39B6 -:104E4000E99C01833EA336057403E99201BE02008A -:104E5000E89601B89903CD39E98401C7060F3705F3 -:104E600000E97B01E50225FFDFE702C706A336075D -:104E700000C7060F370500E96501E8D504C6069DA1 -:104E80003600C7069B360000C7060F370500C70669 -:104E9000A8020000C7064C370100E50225F9FF0D06 -:104EA00003000D008825EFFF0D00400D0004E70210 -:104EB000E967FCB89A03CD39F706F4330010750999 -:104EC000C70633370200E91601FF0E33377403E9D2 -:104ED0000D01FF068E34830EC23408C7063D37032A -:104EE00000E9FFFAC35250BAE000B80010EF585A78 -:104EF000C3C7063D370000E9E9FAFAE85404B88070 -:104F0000038EC026C7060400D82BB87F038EC026A8 -:104F1000C7060400E82C33C08EC0A1A736A3A9366B -:104F2000A1A936E700A1AB36E702C70605370000A6 -:104F3000C70607370000C70609370000C6069D36BA -:104F400000C6069E36FFC7069B360000C706A3367E -:104F50000000C7060F370000C706A8020000C706FA -:104F60004C3701008126AF36FFE7A1AF36E706BB1D -:104F7000FF7FCD53E87CF9E5560D0200E756FBC3F1 -:104F80008D3EC0538D36F038B90E008B1E303489FB -:104F90005C022E8B45028944062E8B0589440483CE -:104FA000C70483C610E2E8B880038EC026C7060493 -:104FB00000E251B87F038EC026C7060400B2523308 -:104FC000C08EC0C706A1360100C7060F370500C353 -:104FD00033FF8E06A6028B36A4022EFFA4A053E850 -:104FE0008CDBC3E848F7E9F6FF8E063834E807E1C2 -:104FF00026C7060400DF4FCD50C326C7060A0000AF -:105000000026FF260400CD34E9D4FFA1D13626398D -:10501000061A007522A1D3362639061C007518A180 -:10502000D5362639061E00750E26F7060C00400000 -:105030007405830E663740810EAF360010A1AF367F -:10504000E706833EA336027505CD34E956FB833E61 -:10505000A3360074B1833EA3360577AA26F6060A66 -:1050600000FF75A2E8FDDD50F6069336207503E9D2 -:105070008C0026A10C002507003D07007503E9768A -:10508000003D05007503E96E00F706E634188075EB -:1050900003E96A00F706E6340080743526803E296D -:1050A0000002752D5156578D363E348D3E2000B985 -:1050B0000600F3A65F5E59754526A12000A33E3485 -:1050C00026A12200A3403426A12400A34234E926CD -:1050D00000F706E6340800740B26803E19000074C1 -:1050E00003E91300F706E6341000741226A0280026 -:1050F000C0E80422C0740726C7060400FFFF582337 -:10510000C07403E9DDFE81269B36FFFE26A1200048 -:105110003B06D136751A26A122003B06D336751000 -:1051200026A124003B06D5367506810E9B3600016C -:1051300026A12000257FFFA3B83426A12200A3BA10 -:105140003426A12400A3BC348BC686C4A3C034D1AA -:10515000E680FC097403E8F6F5A105370B0607376E -:105160000B060937743E26A120003B06053775174C -:1051700026A122003B060737750D26A124003B0619 -:1051800009377503E91D0026A02800240F3C03748D -:105190001B3C00750F833EA336047410F7069B3644 -:1051A000000174082EFF94F853E933FECD34C7068E -:1051B0003D370100E92CF8833EA336057410833E89 -:1051C000A336017E0983EE162EFF942454C3CD34FA -:1051D000C326A10C003DFF7F740526FF260400E9CD -:1051E000FDFDA1F433A90088740BA9001075098B8B -:1051F0001E4337FFE3E99700C70635370500C706AA -:1052000043372852F706F43300087406C7064337BD -:105210001A52B88003CD39E9C5FDA9000874D9FF39 -:105220000E353775EDE93000A9000875CBFF0E3556 -:105230003775DF810EC234C000F6069D3680740FCC -:10524000810E9B360080C7060F370200E990FDC72C -:10525000063D370200E98BF780269E36FF7530F653 -:10526000069D36807420FF069434830E6637208EA8 -:1052700006303426F7060A000001740726810E085E -:10528000000001E90900C7063D370400E954F78131 -:105290000EAF360008A1AF36E706E50AA900807414 -:1052A0000E8126AF36FFF7A1AF36E706E949FFE9E1 -:1052B0002DFDC70641370000BE2900E82BFDE91E81 -:1052C000FDCD34833EA336047709C7063D37010080 -:1052D000E910F7E909FDCD34C3C7069B360000E8A5 -:1052E0000CF58126AF36FFE7A1AF36E70681269B96 -:1052F00036FF7FE5020D010025EFFF25FFDFE70206 -:10530000BBFF7FCD5333C0A39D36A39F36E820F368 -:10531000E843F3830E9B3610C70699360000E8D2A7 -:10532000F5E5560D0200E756C706A8020000BE00CC -:1053300000E830F5C606A0360EB89C03CD39B8801B -:1053400000CD35C706AA02FFFFC706A1360100E956 -:10535000A5F606B88F03CD3AB89003CD3AB89103BD -:10536000CD3AB89203CD3AB89303CD3AB89403CD71 -:105370003AB89503CD3AB89603CD3AB89703CD3AEB -:10538000B89803CD3AB89903CD3AB89A03CD3AB854 -:105390009B03CD3AB87F03CD3AB88003CD3A07C31B -:1053A000F749F14EDF4FDF4FDF4FDF4FF851DF4F4F -:1053B000FA4F0B50D151DF4FDF4FDF4FDF4FDF4F41 -:1053C000E44E0600CD4A0400E44E1900AD4BFA004D -:1053D000824C0807094C1400244E6400D74DF40198 -:1053E000644EBC027A4EE803434E0200B34EF40111 -:1053F0005B4EF401E54E140006500650954CC15228 -:10540000C152FE4CDA4C0650065006500650B751B9 -:10541000B751B751B751B751B7510650D54A065099 -:105420001D4C0650834D1F4D1F4DED40FA40074166 -:1054300037372E3737202079792F79792F797920CE -:1054400030312E3930202030322F31372F3939206A -:10545000000000000000000000000000000000004C -:10546000000000000000000000000000000000003C -:10547000000000000000000000000000000000002C -:10548000000000000000000000000000000000001C -:10549000000000000000000000000000000000000C -:1054A00000000000000000000000000000000000FC -:1054B00000000000000000000000000000000000EC -:1054C00000000000000000000000000000000000DC -:1054D00000000000000000000000000000000000CC -:1054E00000000000000000000000000000000000BC -:1054F00000000000000000000000000000000000AC -:10550000000000000000000000000000000000009B -:10551000000000000000000000000000000000008B -:10552000000000000000000000000000000000007B -:10553000000000000000000000000000000000006B -:10554000000000000000000000000000000000005B -:10555000000000000000000000000000000000004B -:10556000000000000000000000000000000000003B -:10557000000000000000000000000000000000002B -:10558000000000000000000000000000000000001B -:10559000000000000000000000000000000000000B -:1055A00000000000000000000000000000000000FB -:1055B00000000000000000000000000000000000EB -:1055C00000000000000000000000000000000000DB -:1055D00000000000000000000000000000000000CB -:1055E00000000000000000000000000000000000BB -:1055F00000000000000000000000000000000000AB -:10560000000000000000000000000000000000009A -:10561000000000000000000000000000000000008A -:10562000000000000000000000000000000000007A -:10563000000000000000000000000000000000006A -:10564000000000000000000000000000000000005A -:10565000000000000000000000000000000000004A -:10566000000000000000000000000000000000003A -:10567000000000000000000000000000000000002A -:10568000000000000000000000000000000000001A -:10569000000000000000000000000000000000000A -:1056A00000000000000000000000000000000000FA -:1056B00000000000000000000000000000000000EA -:1056C00000000000000000000000000000000000DA -:1056D00000000000000000000000000000000000CA -:1056E00000000000000000000000000000000000BA -:1056F00000000000000000000000000000000000AA -:105700000000000000000000000000000000000099 -:105710000000000000000000000000000000000089 -:105720000000000000000000000000000000000079 -:105730000000000000000000000000000000000069 -:105740000000000000000000000000000000000059 -:105750000000000000000000000000000000000049 -:105760000000000000000000000000000000000039 -:105770000000000000000000000000000000000029 -:105780000000000000000000000000000000000019 -:105790000000000000000000000000000000000009 -:1057A00000000000000000000000000000000000F9 -:1057B00000000000000000000000000000000000E9 -:1057C00000000000000000000000000000000000D9 -:1057D00000000000000000000000000000000000C9 -:1057E00000000000000000000000000000000000B9 -:1057F00000000000000000000000000000000000A9 -:105800000000000000000000000000000000000098 -:105810000000000000000000000000000000000088 -:105820000000000000000000000000000000000078 -:105830000000000000000000000000000000000068 -:105840000000000000000000000000000000000058 -:105850000000000000000000000000000000000048 -:105860000000000000000000000000000000000038 -:105870000000000000000000000000000000000028 -:105880000000000000000000000000000000000018 -:105890000000000000000000000000000000000008 -:1058A00000000000000000000000000000000000F8 -:1058B00000000000000000000000000000000000E8 -:1058C00000000000000000000000000000000000D8 -:1058D00000000000000000000000000000000000C8 -:1058E00000000000000000000000000000000000B8 -:1058F00000000000000000000000000000000000A8 -:105900000000000000000000000000000000000097 -:105910000000000000000000000000000000000087 -:105920000000000000000000000000000000000077 -:105930000000000000000000000000000000000067 -:105940000000000000000000000000000000000057 -:105950000000000000000000000000000000000047 -:105960000000000000000000000000000000000037 -:105970000000000000000000000000000000000027 -:105980000000000000000000000000000000000017 -:105990000000000000000000000000000000000007 -:1059A00000000000000000000000000000000000F7 -:1059B00000000000000000000000000000000000E7 -:1059C00000000000000000000000000000000000D7 -:1059D00000000000000000000000000000000000C7 -:1059E00000000000000000000000000000000000B7 -:1059F00000000000000000000000000000000000A7 -:105A00000000000000000000000000000000000096 -:105A10000000000000000000000000000000000086 -:105A20000000000000000000000000000000000076 -:105A30000000000000000000000000000000000066 -:105A40000000000000000000000000000000000056 -:105A50000000000000000000000000000000000046 -:105A60000000000000000000000000000000000036 -:105A70000000000000000000000000000000000026 -:105A80000000000000000000000000000000000016 -:105A90000000000000000000000000000000000006 -:105AA00000000000000000000000000000000000F6 -:105AB00000000000000000000000000000000000E6 -:105AC00000000000000000000000000000000000D6 -:105AD00000000000000000000000000000000000C6 -:105AE00000000000000000000000000000000000B6 -:105AF00000000000000000000000000000000000A6 -:105B00000000000000000000000000000000000095 -:105B10000000000000000000000000000000000085 -:105B20000000000000000000000000000000000075 -:105B30000000000000000000000000000000000065 -:105B40000000000000000000000000000000000055 -:105B50000000000000000000000000000000000045 -:105B60000000000000000000000000000000000035 -:105B70000000000000000000000000000000000025 -:105B80000000000000000000000000000000000015 -:105B90000000000000000000000000000000000005 -:105BA00000000000000000000000000000000000F5 -:105BB00000000000000000000000000000000000E5 -:105BC00000000000000000000000000000000000D5 -:105BD00000000000000000000000000000000000C5 -:105BE00000000000000000000000000000000000B5 -:105BF00000000000000000000000000000000000A5 -:105C00000000000000000000000000000000000094 -:105C10000000000000000000000000000000000084 -:105C20000000000000000000000000000000000074 -:105C30000000000000000000000000000000000064 -:105C40000000000000000000000000000000000054 -:105C50000000000000000000000000000000000044 -:105C60000000000000000000000000000000000034 -:105C70000000000000000000000000000000000024 -:105C80000000000000000000000000000000000014 -:105C90000000000000000000000000000000000004 -:105CA00000000000000000000000000000000000F4 -:105CB00000000000000000000000000000000000E4 -:105CC00000000000000000000000000000000000D4 -:105CD00000000000000000000000000000000000C4 -:105CE00000000000000000000000000000000000B4 -:105CF00000000000000000000000000000000000A4 -:105D00000000000000000000000000000000000093 -:105D10000000000000000000000000000000000083 -:105D20000000000000000000000000000000000073 -:105D30000000000000000000000000000000000063 -:105D40000000000000000000000000000000000053 -:105D50000000000000000000000000000000000043 -:105D60000000000000000000000000000000000033 -:105D70000000000000000000000000000000000023 -:105D80000000000000000000000000000000000013 -:105D90000000000000000000000000000000000003 -:105DA00000000000000000000000000000000000F3 -:105DB00000000000000000000000000000000000E3 -:105DC00000000000000000000000000000000000D3 -:105DD00000000000000000000000000000000000C3 -:105DE00000000000000000000000000000000000B3 -:105DF00000000000000000000000000000000000A3 -:105E00000000000000000000000000000000000092 -:105E10000000000000000000000000000000000082 -:105E20000000000000000000000000000000000072 -:105E30000000000000000000000000000000000062 -:105E40000000000000000000000000000000000052 -:105E50000000000000000000000000000000000042 -:105E60000000000000000000000000000000000032 -:105E70000000000000000000000000000000000022 -:105E80000000000000000000000000000000000012 -:105E90000000000000000000000000000000000002 -:105EA00000000000000000000000000000000000F2 -:105EB00000000000000000000000000000000000E2 -:105EC00000000000000000000000000000000000D2 -:105ED00000000000000000000000000000000000C2 -:105EE00000000000000000000000000000000000B2 -:105EF00000000000000000000000000000000000A2 -:105F00000000000000000000000000000000000091 -:105F10000000000000000000000000000000000081 -:105F20000000000000000000000000000000000071 -:105F30000000000000000000000000000000000061 -:105F40000000000000000000000000000000000051 -:105F50000000000000000000000000000000000041 -:105F60000000000000000000000000000000000031 -:105F70000000000000000000000000000000000021 -:105F80000000000000000000000000000000000011 -:105F90000000000000000000000000000000000001 -:105FA00000000000000000000000000000000000F1 -:105FB00000000000000000000000000000000000E1 -:105FC00000000000000000000000000000000000D1 -:105FD00000000000000000000000000000000000C1 -:105FE00000000000000000000000000000000000B1 -:105FF00000000000000000000000000000000000A1 -:106000000000000000000000000000000000000090 -:106010000000000000000000000000000000000080 -:106020000000000000000000000000000000000070 -:106030000000000000000000000000000000000060 -:106040000000000000000000000000000000000050 -:106050000000000000000000000000000000000040 -:106060000000000000000000000000000000000030 -:106070000000000000000000000000000000000020 -:106080000000000000000000000000000000000010 -:106090000000000000000000000000000000000000 -:1060A00000000000000000000000000000000000F0 -:1060B00000000000000000000000000000000000E0 -:1060C00000000000000000000000000000000000D0 -:1060D00000000000000000000000000000000000C0 -:1060E00000000000000000000000000000000000B0 -:1060F00000000000000000000000000000000000A0 -:10610000000000000000000000000000000000008F -:10611000000000000000000000000000000000007F -:1061200090EAC01500000000000000000000130607 -:00000001FF -/* - * The firmware this driver downloads into the tokenring card is a - * separate program and is not GPL'd source code, even though the Linux - * side driver and the routine that loads this data into the card are. - * - * This firmware is licensed to you strictly for use in conjunction - * with the use of 3Com 3C359 TokenRing adapters. There is no - * waranty expressed or implied about its fitness for any purpose. - */ - -/* 3c359_microcode.mac: 3Com 3C359 Tokenring microcode. - * - * Notes: - * - Loaded from xl_init upon adapter initialization. - * - * Available from 3Com as part of their standard 3C359 driver. - */
diff --git a/firmware/Makefile b/firmware/Makefile index 0d15a3d..344713b 100644 --- a/firmware/Makefile +++ b/firmware/Makefile
@@ -26,7 +26,6 @@ else acenic-objs := acenic/tg1.bin acenic/tg2.bin endif -fw-shipped-$(CONFIG_3C359) += 3com/3C359.bin fw-shipped-$(CONFIG_ACENIC) += $(acenic-objs) fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \ adaptec/starfire_tx.bin @@ -86,7 +85,6 @@ qlogic/12160.bin fw-shipped-$(CONFIG_SCSI_QLOGICPTI) += qlogic/isp1000.bin fw-shipped-$(CONFIG_INFINIBAND_QIB) += qlogic/sd7220.fw -fw-shipped-$(CONFIG_SMCTR) += tr_smctr.bin fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ ess/maestro3_assp_minisrc.fw
diff --git a/firmware/WHENCE b/firmware/WHENCE index 182ecb6..8388f02 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE
@@ -89,18 +89,6 @@ Copyright (C) 2001 Qlogic Corporation (www.qlogic.com) -------------------------------------------------------------------------- -Driver: smctr -- SMC ISA/MCA Token Ring adapter - -File: tr_smctr.bin -Info: MCT.BIN v6.3C1 03/01/95 - -Original licence info: - - * This firmware is licensed to you strictly for use in conjunction - * with the use of SMC TokenRing adapters. There is no waranty - * expressed or implied about its fitness for any purpose. - --------------------------------------------------------------------------- Driver: kaweth -- USB KLSI KL5USB101-based Ethernet device @@ -567,32 +555,6 @@ -------------------------------------------------------------------------- -Driver: 3C359 - 3Com 3C359 Token Link Velocity XL adapter - -File: 3com/3C359.bin - -Licence: -/* - * The firmware this driver downloads into the tokenring card is a - * separate program and is not GPL'd source code, even though the Linux - * side driver and the routine that loads this data into the card are. - * - * This firmware is licensed to you strictly for use in conjunction - * with the use of 3Com 3C359 TokenRing adapters. There is no - * waranty expressed or implied about its fitness for any purpose. - */ -/* 3c359_microcode.mac: 3Com 3C359 Tokenring microcode. - * - * Notes: - * - Loaded from xl_init upon adapter initialization. - * - * Available from 3Com as part of their standard 3C359 driver. - */ - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - Driver: PCMCIA_PCNET - NE2000 compatible PCMCIA adapter File: cis/LA-PCM.cis
diff --git a/firmware/tr_smctr.bin.ihex b/firmware/tr_smctr.bin.ihex deleted file mode 100644 index 6797451..0000000 --- a/firmware/tr_smctr.bin.ihex +++ /dev/null
@@ -1,477 +0,0 @@ -:10000000BC1D123B63B4E900001F000101000205A2 -:10001000010006030100040901000A070100080BA2 -:1000200001000C000000000F0100100D01000E1374 -:10003000010014110100120000050015010016193D -:1000400001001A1701001800000E00000001000056 -:100050000004001B01001C0000070000000F00004E -:10006000000B001D01001E0000080000000200003F -:10007000000C000000060000000D0000000300005E -:10008000000A00000009000478C6BC0194049380B3 -:10009000C84062E9DA1C2C1555555555555555582B -:1000A0000BE9E5D595C19D77CEBBA06E1C05F67713 -:1000B000C602FA9670E81DC0170E02FA587DC05F9E -:1000C00072CEECA4C384907A30CD8D7919E76C247C -:1000D000279C08390738A84A4CEA4D989B244CC005 -:1000E00026D3E7545A4DF24C0C13234990326EA498 -:1000F000DF9371137726E126F8260C4C12260809A7 -:10010000828260A9307936B0B2A8A772648F9B331F -:1001100033F9B839D51173AA75265D2651932A494A -:1001200094C99589BC4DC89B809BA099064C862696 -:10013000589BA49B9937626C679B3330BF366661CE -:10014000BF36ECC5BD66825A5031D59D9818293C02 -:1001500098864C17263E2CB8693B492EB408431AA2 -:10016000A4F9B351F110F343CD086F6379B3330EA3 -:100170001398499804DA7CE05279310C982E4DACF2 -:100180002C8414EE4CFE675EE49A7529D7A9353AA3 -:10019000945BD59B58B4AF7566AF14A9EF40952515 -:1001A00008B9AD42FCD8D98C330E1398661E45AC05 -:1001B000B00C42D3CCA61262DEB4B180497DA2DE7F -:1001C000B418C02484E654F5834601681A630CC64B -:1001D0001264FA4C351C2C0EAAAAAAAAAAAAAAAA88 -:1001E000AAAAAAAAAAADD70270E04CF3A1C1D5C0B1 -:1001F0003CB96939604E58770267933C99E4CF382F -:100200001C972E401B903146A35E0E88346A35E061 -:10021000E8AA351AA9F51546A3EA7D4AA351AA9F73 -:100220007054A6572EB4CDC8A30CC1DAC6E1CB7A60 -:10023000D41C68FFCF55A8C02D851117442A300B58 -:100240004A88C24DB520D5260169516952195260BC -:100250001695168296549805A545F3DD6AF9281877 -:10026000EF003030514E445D12D143E6126F9EBA1A -:10027000CCDF25031DE006060A30CCA9EB2D008655 -:10028000A612654F56D665495F3DE837C940C77825 -:100290000181828C33184980AE40C518059C6D18C9 -:1002A000660EF3A0C61262DEF504B4AC6BC61991FB -:1002B0007305482E72948073A1C8473666642F3642 -:1002C0006664079902918E72D10F9D063173A0C3A7 -:1002D000516A1A20BF3A0C2C7387435E600223FCDC -:1002E000E0D635EF9EF5EF92818EF0030305186698 -:1002F00045CC0B482E700A4039D0E4239B3332178B -:100300009B333203CC8548C73814A5CE297ED280D2 -:10031000A1A8B448882FCE830B1CE1D0D7980488BD -:1003200087CE963173A58FF38358D7BE7B82AF9269 -:10033000818EF0030305186645CC1520B9C8290045 -:10034000E743908E6CCCC85E6CCCC80F3205231C82 -:10035000E450D45A17882FCE8310F9D023173A04CB -:1003600035E600221639C3A3FCE0D635E0BFF41809 -:10037000F22D4D43516E5A221F30D417E74191732D -:1003800005482E776900E743908E6CCCC85E6CCC34 -:10039000C80F3205231CEF4C4E0604C99E0BFF41CB -:1003A0008F22D4D43516E5A221F35A82FCE8322EEE -:1003B00060A905CE1348073A1C8473666642F3664B -:1003C000664079902918E70A989C0A9EB5125C7CD1 -:1003D000C3318B982A7CD3ED38E9D34E74ED499E16 -:1003E0000BFF418F22D4D43516E5A22DEB45338F78 -:1003F000FCF7A05F25031DE40E060A30CC0CF3EBDE -:1004000040DE61A870920A00E1241E00E1241E0073 -:10041000E1241E00E1241E00E1241E010F982A0B96 -:10042000F3A0C8B9A2A4173A6900E743908E7548B3 -:100430005E706901E6005231CC1814A5CC09829493 -:10044000730CA091F525CC070684849F30A2A47D6F -:100450005075A665014A8EB4CCC435547566A49710 -:100460007A895053138019E3495C6DCEA940350653 -:1004700078D25706F1B32A8D972362925D69991C51 -:100480006A36E6CD46126F9EE1ABE4A30CC0DEAC4B -:10049000D40D281BD012A500F84BAD332806A0DEE2 -:1004A00014973A895DC00DE30690925D699866B92C -:1004B0001995E4A8CF9D331849BE7B86AF928C3343 -:1004C00024140CF4832421C270BFF418F22D4D4380 -:1004D000516E5A221F32A82FCE8322E605A4173A66 -:1004E0006900E743908E75485E706901E642A46337 -:1004F0009802294B9A2978E9405313818132678207 -:10050000FFD063C8B5350D45AE50087CE0D05F9D87 -:100510000645CC01A4173A6900E743908E75485E02 -:10052000706901E659A463981C52973B30528E7D46 -:100530002A091F51EBA4A40AB99487AEC531380229 -:10054000FFD063C8B5350D45AE50087CEA20BF3AF0 -:100550000C8B9A16905CE9A4039D0E4239D5217943 -:1005600095480F300A918E60EB297300095404CA34 -:1005700082655265E4CA226572650932E099724C5F -:10058000C4E00BFF418F22D4D43516B94021F38A41 -:1005900082FCE8322E60A905CE9A4039D0E4239D32 -:1005A00052179954619901E640A4639804B1849864 -:1005B00018EF2D0305313802FFD063C8B5350D455E -:1005C000B968887CE0505F9D0645CC81482E713427 -:1005D0008F48014815210521E90A5203CE5A4639B0 -:1005E000CF478E60AB1AF35343EB3524B81B30076B -:1005F000098A742F7E41741E1D0D874649D595D1F9 -:10060000D5D5BBA94E829D053A0A7414E829D0427B -:10061000745BCE50C40745BCE20C40745BCE8304CF -:10062000F9954D13635E6F313BA08BA2C5398D7870 -:100630003A22A0006BC1D1546016D991A2E7438C35 -:1006400024DC1CE05117396B3BCC4B422E6B50BF66 -:100650003636654F7A185525789823E7503EF38152 -:100660004C026D3E7153AF78A9D4A629B1BCD9997B -:10067000B28E628F222E7516B0B2AB23281654525A -:1006800031BCD999B28E6619022E7516502CA9C8A4 -:10069000C6F520D3E47F4F9C0AD6167F90EE4CEB34 -:1006A000CFE288BA2F4286AEBDE5A7529F93637909 -:1006B000EB3308F9945247CD99256F3A0C13E65560 -:1006C000344C5A4DB52395A548115A0A4395AC2C84 -:1006D000BA240549B1BCCAA7726C6BC5BDE83169C3 -:1006E000525D0612653EB1504C7D4FAC0A300B3660 -:1006F0006411738A838E75129F7BD29958EE822E75 -:1007000077A0E39D5D4FBC2A532953DE9324BAB3EF -:1007100036AA4AC679D4B9DE625A11735050BF372F -:10072000366F1323BA0C24CEBDE2A752B28E6B6093 -:10073000622E751330ACA059CA646379B333651C5B -:10074000CC32045CEA2CA059DF231BD4835247DD52 -:100750007996D49EB3524BA25A1A8D5D7B82A752D2 -:10076000B28E6619022E7516502C8C321D7B8EA708 -:1007700052B1BCD9999804DA7CE2ACFE6619022E1B -:100780006550BF336664FE7418864C1726D6165221 -:100790003918DE7ACCC23E651491F36649086E833F -:1007A0000933AF31ED0D9D0612622A318D6DE7419F -:1007B000827CCAA68987092E29B1AF1039D66497E1 -:1007C000301D42759344028C24D27AB350F68905C9 -:1007D000435E6198C02C92253C8B2489490549E7EA -:1007E0000CB98498B7AD3344AE5A5186609F38A98E -:1007F000A26C6BC48EF45E49461262DEB4CD215CFD -:10080000B4A30CC13E7229A26C6BC6126247F0E819 -:10081000C33204354092A4828810927CCBD42FA49A -:1008200002118498B7AD3344AE5A5186609F38A9FF -:10083000A26C6BC48EF45E494408493E65EA17D247 -:100840000108C24C5BD699A42B9694619827CE459B -:10085000344D8D78810927CCBD12286C58AFB6F382 -:10086000A0C13E655344D8D7928E7D4BC2FA612613 -:10087000063AB36B030549E70CB96F5A66955CB449 -:10088000A30CC13E7029A26EA4DF9371137726E1F9 -:1008900026F826C6BC9473F92F0BE9849818EACC85 -:1008A000EC0C15279C32FF3D56AF928B7AD335D591 -:1008B000CB4A30CC13E7029A26C6BC947341979179 -:1008C000F483CE0420628B0516498C24C0C7569051 -:1008D000C0C15279C32E5BD5A672D294FAAD58C866 -:1008E000FA9F54B3324BB954A651866B79D0609FAE -:1008F0003205344D8D7A4D1E7AB35100A93D59A869 -:100900007B4482A1AF4A8D52A95241494F3A2E40B1 -:10091000A49950BE90085279C32E61262DEB4CD07D -:1009200015CB4A30CC13E7029A26C6BC48FE1D25DB -:1009300046A954A920A4A79D1720524CA85F48049B -:100940002309316F5A6680AE5A5186609F3814D1A0 -:100950003635E4A79D1720524CA2450D8B15F49116 -:10096000DE8BC928C24C5BD699A95CB4A30CD6F324 -:10097000A0C13E640A689B1AF16D4CAA92E03694BD -:10098000709B297813AEB3AA85D44375093AC9EB95 -:100990003524B81B328E13487E4EFD40FD40FD408D -:1009A000FD40FD40FC13F421F917458A300B335FFD -:1009B00083A22A300B335F83A2A8C02DB32070928C -:1009C000139ADE741827CCAA689B1AF70745518042 -:1009D0005B66470738A823E751113FE0E8854601E9 -:1009E0006D990612654F7A2024BAB33215257BAD76 -:1009F0003378AE0E73D047CEA730CC44FF83A2A885 -:100A0000C02CD991C1D11518059B3208BA2C518040 -:100A100059B3207092E29889FDBCEE1890FC8BA22D -:100A2000C52B0D783A22A561AF074551805B66441E -:100A30009EB3524B83ADC709BE1F9F74655D0A17F5 -:100A40007CABA0C24C3849122E384907A30CC13EDA -:100A5000655344D8D7ADE700324B9B33344A03008B -:100A60009D25CE8324B819998C02124BA199D8C028 -:100A7000274973CFF93CF47CE79804E92E7F39E3EA -:100A80004F4653C06013A4B9E53C03DE8F9CF300CE -:100A90009C6FCF3E85F9A336021E6038923E631AE2 -:100AA000109FCF181092BCD0A40CDCC00F9C9734C0 -:100AB00062B6E7F3F3A5CF1842341CC2CAFA8E68B7 -:100AC0005206AF3CA30DBF9E50E1D173CAE03AFC81 -:100AD000C1091A1E6A5C5B8E634E7773CC6167DD59 -:100AE000E66C48D1F31B24695108D4421BF467D14A -:100AF000804E2FD08CD83009C21E801C46013A4748 -:100B0000D031A106013A7F4630211804E95E8429DC -:100B100000C027CDD0007C9804F92E84628C027D21 -:100B2000BA3E7E4C027D2E8C61083009F41D0165B1 -:100B300073009F51D085201804FABD194618C027AC -:100B4000DFD194384C027D174657013009F5FA0180 -:100B50000906013E87A14B88C027DC740D39D300FC -:100B60009F73D030B39804FBBD06C483009F47D069 -:100B70003648CC0271BF3F9A17E63F0821E692A49F -:100B80008F9A1031A7F310B184AF3AACDCF773F24F -:100B90005CC62ADB9E7E7E97310863D0737B43A8B8 -:100BA000E63D34EAF3E315BF9F185F45CFE89F5F4A -:100BB0009A5B03D0F3D3CE371CD00FBB9E68783B33 -:100BC000BCCA31E8F9A20212A27351086FD1F346F0 -:100BD0000138BF40FC23009C21E84951804E91F42C -:100BE000210319804E9FD0216306013A568C02746E -:100BF000FE75495E63D34A54423513A7D1804E95A2 -:100C0000E81E9A4C027CDD1BB9E6013E4BA062A3B4 -:100C1000009F6E8CFCF3009F4BA04218CC027D0716 -:100C200043DA13009F51D03D349804FABD1C628C06 -:100C3000027DFD1C6173009F45D1F44E6013EBF4FF -:100C400025B033009F43D1A79C1804FB8E8403E991 -:100C5000804FB9E843C13009F77A0A319804FA3E67 -:100C6000844041804E82E7418709230423009D058B -:100C7000CE961C248C108C0274173A043849182123 -:100C80001804E82E7450E12460846013A0B9D411D4 -:100C9000C248C108C0274173A82384918211804EA5 -:100CA00082E7528E12460846013A0B9D401C248C66 -:100CB000108C0274173A090E12460846013A0B9836 -:100CC0006A1C24B0E11804E82E6B50E1258708C0A7 -:100CD000274173054384961C23009D05CCAA1C2440 -:100CE000B0E11804E82E70687092C3846013E54484 -:100CF000F9409D05CE5A1C24B0E11804F9D13E708C -:100D000027CF13E5442CA042CB89F2213A0B9C0A51 -:100D10001C24B0E11804F9D10B3810B3C4213936C2 -:100D20005C42C8842B79D061C2741524BAD331E5F2 -:100D300059082908E066634295128100290BC151C8 -:100D400024B81999902290B418A0914101414141D1 -:100D50005283CA4028682908BA16109C990B5694E9 -:100D600090521574C0271A2AD29025D3009D28AB23 -:100D70004A42174C0270D4842E9804E12A42174C40 -:100D8000027082904BA60138514842E9804E15A46A -:100D90002174C0270FA412E9804E82AC80ACA0ACB5 -:100DA000A959E5644565CAC84ACE0ACE4ACE95918E -:100DB000959495932925C0CCCC88A4975636647217 -:100DC00090548A9C4508B9B766129309C9B2748ECB -:100DD000BA6013E5348EBA6013E4748EBA6013E51A -:100DE000691D74C027CA291D74C027CED225D3001F -:100DF0009F38A44BA6013E5E912E9804F915225D02 -:100E00003009F3E912E9804F905225D3009DC5487F -:100E100025D3009C45CECD09C9B21A44BA6013E768 -:100E2000348974C0271C27B79C80C2D776599B93FE -:100E30000C64C31D1BF4454BC7C63A37E8814BC74A -:100E4000C63A37E8914BC7C632618EB3BCC34A225B -:100E5000E6B5249771C987B431AE73A2CF39D25D9C -:100E6000044442C0D6DE710616BBDBCE830C64C3DD -:100E70001D311304F9954D133293635E6614CC292A -:100E80002A5330A6614CC299853A72CCC299850624 -:100E90001BB30A661414249985330A08B186614C81 -:100EA000C2842168733B30A661414EA5985330AC93 -:100EB0005976614CC2B08DD6614CC2B02CF6614CF3 -:100EC000C2B18CA5985330AC0F24CC2998560F286A -:100ED0006615921A1985330ACA850CC2998565C3AD -:100EE000D985330ACE7086614CC2B397710C993B99 -:100EF000CC83580BEA779D064ABE047460E0D14E5D -:100F0000384C3EEE3EEE3EEE3EEE30BBCAE11F7781 -:100F10001F771F771F7727708FBB800E11F771F730 -:100F20007C6F3CB33602FB8DE655707F2D246955EE -:100F30004F58A9231F54F78A95252B750CCCAC5616 -:100F400051CC51E445CEA21239C0A0AF566A497FB8 -:100F5000028C09F80BEBAF56766752B28E69A71177 -:100F600073A8B1BCCAA0A936502C98E70AF566A4AC -:100F700097E25A3027BAF7834EA5330A66158DE6F5 -:100F80005539D2A7AC546016701B728E628F222E18 -:100F9000751602FB8DE60A953D62A300B701B553B5 -:100FA000DE2A5494ADD43332B15947314791173AC0 -:100FB0008848E702B017DC679D4B8DE752AA7BD4C7 -:100FC000AA92BDD699BC5602FB8CF36666C6F36640 -:100FD0006662992AF8186870B08A0D5555555552B1 -:100FE00032E1405C380BEA9B87017DC05F7017DC03 -:100FF00005F5DC9B017D614D80BEA77982A21F5063 -:10100000152A8F8B1CE5A5138458E702915405021D -:101010004BBD221A947F9C1AC05F421A21D180597D -:10102000C06D1C2C0A83555555555555555555556C -:1010300055541CB85C6E179C2F385E70E7B85E7014 -:10104000BCE179C2F385E70BCE179C299C299C292A -:101050009C230F5814EE357726219305C9B017D27B -:101060001D188A219305C9B017D187AC0A740FAE39 -:10107000F55A82A3E43A3114BBD7599974A21930B6 -:101080005C9B017D187AC0A740F843D4638925D0C2 -:1010900010D61C6A10F5558925D151661F51F5915E -:1010A000492E8915986AA3E08A9465640E1317384F -:1010B000A8864C1726C05F461EB028631F087A8C8E -:1010C0007124BA021AD00D421EAAB124BA2A2D31B7 -:1010D000F51F587492E8875A6352DEF451694A3E0C -:1010E00009694650F0E131730545BD598D8B4A7C45 -:1010F000D3ED38E9D34E74ED443260B93602FA5B71 -:10110000DE8A2D29D0E121F5A39221F219305C9BD2 -:10111000017D21F5A0C6016701B445CEA51239D4E1 -:101120001C05F440A1C2C3506AAAAAAAAAAAAAAAE4 -:10113000AAAAAAAAAAAA81AF869F191BE781F3656A -:10114000F280BE7017DFDF380BEB0DC380BEA70F38 -:10115000954F5A94C02CD8B1A7CE5A1173A83AC251 -:10116000CCB63017DC6F35A9804DA7CE2A1879C5CB -:1011700049DE61A822E75033F9986408B99542FC2A -:10118000CCD9953D62A248D448E70288B9C1A0E312 -:101190009D4E62E6CCC66BCE8310C982E4DAC2C82B -:1011A0001EC3B93602FAA9EB4E3030FA0DF0A9EBA6 -:1011B00040B90FAA7AD2C2C8FAA7AD410A47D53DB5 -:1011C00068ACF1F54F5A97547D4FA8AA551F11737B -:1011D0005AB017DE5D59A925D0552A46BCB822AEB3 -:1011E00045293E14FAE19994CA4ABE3DD699925DCA -:1011F0001517C8D7DC15178A401F0A9EACC9654968 -:101200005C1D10684A3E5BDE83169580BE91745863 -:10121000A4007C38E7563017DF75A6649745209DFB -:10122000035F70545E291DF0A9EACC865495C1D1A4 -:1012300006830FAA7BD0654945BDE962D291DF04E0 -:101240005D16291C7D4FAC1A471AA9F5676653280D -:10125000B7BD2C5A523BE3DD59A925D1A8AC086B88 -:10126000EE08ABC5202F854F566675495C1C181DCE -:1012700081C26405F080BE355CD017C255F0957C04 -:10128000255F080BE1017C7BAB3524BA1055931A1E -:10129000FB822AF148D7C2A7AB31B2A4AC639D4A06 -:1012A0008D7C7BAB3524BA1054308D7DC11578AC64 -:1012B0006F5A94601AE379D4AA4F854F5666D54980 -:1012C00058C73A9549F045D1629486BC1D13D29017 -:1012D000FFCF7A83F25031DE006060A11735A85F3E -:1012E0009B1B3707441A300B380DBC1CE0D047CE8F -:1012F000A0AA7AA1986A92953D6831805B80DAA9AC -:10130000EF41952516F7A58B4AC679B333602FAA0E -:101310009EB15180599ECAA7AC0A300B67B2ADD5B9 -:10132000DA925D17A300B32D956E08A958A1173A5C -:101330008B017D54F78E9525081CE05602FBC1D128 -:10134000151805926B3C1D1228C02CA56C11701746 -:10135000B2384D80BEE02FB4EC4AEDB39E02FB8064 -:10136000BEE02FB139933E6DE710609F32A9A26CA9 -:1013700005F440E60A953D6A2300B380DAA7D62A31 -:10138000030D7017D22E76294FBC54A6516F7A5890 -:10139000B4AC05F48BA2F40E350D492EB4CC18A5CF -:1013A000C8F84A9723E1052E47C28A5C8F85697287 -:1013B0003E1F4AC3551F5643328CA35E60A845CEDC -:1013C0000D602FA3849DD8F017D22E0E1B2384D836 -:1013D0000BEB89F380BEE02FBB3985DF2203E701E9 -:1013E0007DC05F7017D11738145BD6A2740D4B7A8D -:1013F000B33196946BCC3523D749481573290F5DCB -:101400008AC05F4D79843580BE881CC3529F59685D -:10141000C02CE036AA7BCD4A92BEF3814A7D5B594F -:1014200094CA1C24EEC780BE881CC3529F5968C052 -:101430002CE036AA7BCD4A92BEF38143849C7B3854 -:101440000BEBAF70D4EA53009B4F9C5430F38A945B -:10145000FAB6B3299422E61A85F9B05993F9D2C4A1 -:101460003260B936B0B390D977261C2722E896B4FB -:1014700023EA9EB511805965862073968D79AD5803 -:101480000BE917448A4A07D77A82A190FAEF0154F0 -:10149000BA50D4591E2CE9F38A99856B0B23159702 -:1014A00072611730D42C738748AA028125DE910D12 -:1014B0004AC05F7ED280A53EB2D0C86B80BE881C79 -:1014C000EA0917441A371A917458A371AF074454A4 -:1014D0006E35E0E8AA640F90FAD06300B380DA2C8E -:1014E000738748AA028125DE910D4AC05F48BA275A -:1014F000A300B701B74F9CB46BCC3516F566632DCE -:10150000291EBA4A40AB99487AEC508B9C0822FCC1 -:10151000F9B2553D62A92351239C0A3C730D445CEA -:10152000E15071CEA11FE7156B0B25ED0B93602FDA -:10153000AA9EAC3665495F7A2050087FEF3914497E -:10154000011181046040CC59C0AD23EB41B081F260 -:101550003A41AA5043E4D48654A087C152CA9301A9 -:1015600032549D2402000052AF1646A7916708B47A -:101570000451F16519B46E2DC0AD490092571B742A -:10158000455F2351B7440A1006A36E8B6B081F19E1 -:10159000D1E680828054042A4591A9E459C22D01E4 -:1015A000140450D3FC558461D980512FE21F465F4B -:1015B00040E020154ABC591A9E459C22D01148CBC8 -:1015C000E81408015415E2C8D4F22CE116808A46CA -:1015D0005F527CD9A8F888D05A3CD25C5B80DAA7ED -:1015E000D65A0886A45D17A0C3522E88A8221F537E -:1015F000EADACCA650E127763C05F54FAB6B329981 -:1016000043849C7B380BE927ACD492E00EDA384D4A -:1016100080BEE67D50BA51AE66EFBCDC7B871E0211 -:10162000FA93E6CD47C443CD0F349DA300B05501D6 -:10163000AE038404CE01D0E17002800E89E9221F3E -:10164000E0E896B011F4C2CE036A442DC06D48059F -:10165000B80DA300B776D5DEB150DC7D77BC54BAA7 -:10166000527F5814340F9AF381580BEAEF581460E4 -:1016700016A56C2EF7814BA56F7D5DEEB52E95807E -:10168000BEF073BD047CEAFEEB4CDE2953DD6A54E8 -:1016900094A9EA0A8C02D64C3C05F400EACD56AF78 -:1016A000C047D29C8D29CAE02FAEBD75999D4AF9DD -:1016B000EF517C940C77801818292AF8E0E8AA30BA -:1016C0000B2A987C1D1151805954C351F51B3324AA -:1016D000BB82A5195C1D1028C02C9AC7C1D1228CD1 -:1016E00002C994645C0CD68E13602FB80BEA30E309 -:1016F000C05F48DC780BE800E3C05F6C38D52E355E -:101700004F5A8A61AA9F561B32994642C8010C451E -:10171000CEA517E6C6CEA9EB151646A24738144348 -:101720002622E73D602FAA9EB512E07F017DE3E708 -:101730000293F995445CE5A0E39D4A7F9C54A9EB94 -:10174000510546B9FCC01B222E64542FCD46CCA7B0 -:10175000D586CCA65055C645CE5A0E39D4A7F9C564 -:101760004A9EB5118059C06DCFE600D9117322A1F0 -:101770007E6A36653EAC366532B017DD3E72D27990 -:10178000310C982E4C20732A8FF38AADE741827C6E -:10179000CAA689B5859FB0F017D51F5454251AA83D -:1017A000FF2A946511D74944D5CCA055D8AE0E88F0 -:1017B0001460164D6322E07286384D80BEE02FB86B -:1017C0000BEE02FB8138F017D7D71E02FAFAE3C0FE -:1017D0005F4C85900218C85B80DA300B701B4C227E -:1017E000D34C33038C2E4C4326D0F56366D095A79B -:1017F000CE45330AD61642386EE4CEBD592CD2AB54 -:10180000BA949DE61AB017D54F5A8B091A88B9C5F4 -:10181000424730D43216728865BD599925A5602F8C -:10182000B860F308B74A1A8FAB0D994651AF38A884 -:101830008E9065135218A054B1422E61A848E72D2E -:1018400016F7A805A5602FA475D251357328157613 -:101850002B83A20518059358C8B806286384D80BB3 -:10186000EE02FB80BEE02FA043A7017D4CE3C05FEA -:101870007017DC05F4642DC06D1805B80DA5BD6AA0 -:101880002386AA9EB511A46AA3EA8A8D23E117389C -:101890003469719845A6986A3EAC36651946BCE233 -:1018A000A23A41944D48628152C516F7A88B4A541A -:1018B000F5A88C02DC06D1039CB4A9EE0A95252A72 -:1018C0007AAD46016701B5D7AC0A300B6C4935E6F5 -:1018D000B567F3006C88B99150BF311B32A7B86867 -:1018E00095257BAD3378A7CD3ED38E9D34E74ED47E -:1018F00022E706848E60A8FF38AB839C2A08F9D4BF -:101900002063BC1A060AC05F4642DC06D1805B80B9 -:10191000DA22E61A848E72D16F5A80871AAA7AD494 -:1019200048C8D547D5152323E11738348CBA4B7BEB -:10193000D402D28C22DC06D51F561B328CA35E71DA -:10194000511D20CA26A43140A962B017DF9EF4B70A -:10195000C940C778018182B83839491C26C05F70F8 -:1019600017D4ABE12AF84ABE12AF8F974FCBA7012D -:101970007DDA80AA91647F4A81D522C8FE828025C3 -:1019800048B23EBBDC352E9407E88A9C03E24BA5A7 -:1019900077ABB332E94BBD598684977A04BA53E1E9 -:1019A00032EF50D4E63553EB029CC7D77AB330D22E -:1019B0005DEA02E9445D1628C02CE0369174455971 -:1019C00018D54FAC0AC435308B38692BBD5998698E -:1019D0002EF512E958674AEF50D58E3E1CA4B0CEC2 -:1019E00093216E1A481FA22AC30D577AB30D092EF0 -:1019F000F4435D288B832092384D80BEE02FAC17D6 -:101A000049B3A582E93EE93674E02FA6CE9C05F4E1 -:101A1000C22C8C52577AD48D48FAEF50D5AE35533C -:101A2000EB028621AAEF56661A4BBD44BA50C4E9B0 -:101A300053EB028681F5DEA1A8621F5DFEA25D293F -:101A400077A86A618D40FD11530C6AA7D60530C78F -:101A5000D77FA9574A5DEB481B0C7C8B9D8A53EFBF -:101A60006694CA54F5A0C6016E036A9F5676653225 -:101A70008B7BD2C5A5602FAA7D65A300B701B4C832 -:101A80005A078FED01D527916701B48B9C541C73C5 -:101A9000A8845CC150BF365660AB8C8B9C541C73C1 -:101AA000A8845CC150BF36566C05F553D6A2300BE6 -:101AB000295B19FCF69445CF150BF33CB32A7AC584 -:101AC0004601648A31239C0A5DEA34332E95C7CEE1 -:101AD0002A4FE65020B9310C9BEF391445CE45070B -:101AE0001CEA4687AB1B3684A75EAC966752B017DC -:101AF000DCFE7B4A22E78A85F99E59977A8D0CCBCA -:101B0000A527F3A0443260B937DE72288B9C8A0E79 -:101B100039D48C05F7E7B82AF92818EF0030305788 -:101B200007440A508FF07391411F3A9045C0BB188B -:101B3000E13602FBFB9E02FAEEE7F5CF017D105C79 -:101B4000F017D105CF017D53EB2D1805B80DA64236 -:101B5000DC06D31735A88B9C0A0E39D40CFE7B4AC1 -:101B600022E6550BF331B3602FBC7CE2A4FE655135 -:101B70001738141C73A819FCF69445CCAA17E66311 -:101B8000660AB8CC85A158F6A23548487F4A89959F -:101B90002121FD0502549E45910E3C05F507405557 -:101BA00048523E86A07548523EB5004A9C006BC71D -:101BB000CE4527F32A843735DEA0AB231AAEF58352 -:101BC0005918D743DE2AD094EBDE053A959FCCC353 -:101BD0002045CCAA17E666CC43264FE741222E705B -:101BE0006838E753E02FABBC12D2E9580BEAA7AD37 -:101BF00045A11FC05F7839C8A08F9D481C24EEC73F -:101C000080BEBAF56D6649770D4EA53009B4F9C5A9 -:101C1000430F38A93F9D02FBCE4511739141C73A4E -:101C2000919FCF69445CF150BF33CB32A7AC549045 -:101C30008D448E702977A8D0CCBA56B0B29D8C86D0 -:101C40004C172677261C271C249E2361BE8E124F1C -:101C500011871CEA5C05F5D7B86A752977AB0D9931 -:101C600074A54F72A0AA4AC6F36666C63982AF75DC -:101C7000A66F146BCE05707396823E7528E13AA765 -:101C8000AD44601652B61D7AB6B324BB86A75298EF -:101C900004DA7CE2A1879C55F79CB5AC2C9533B94E -:101CA0003105D953D6A2300B295B022E615A17E6B3 -:101CB0009CB32A7AC54021A891CE0527F3A5886454 -:101CC000C172654F58140C8D7EF381445CEF41C79F -:101CD0003ABE02FAA9EACECCA92953D6A24647DDDC -:101CE0007AC0A30086E29B29788B810998709B2992 -:101CF000795DD972ED94BCB976133B2A5DB29795A4 -:101D00002ED94BCA7D5B5994CA1C24EEC794BCC023 -:101D100026D3E7150C3CE2ACFE7B4A22E78A85F924 -:101D20009E59977A8D0CCBA527F3A0417262193783 -:101D3000DE70288B9C8A0E39D48D0F56366D094E75 -:101D4000BD592CCEA56B0B22D99DC9B297BEF3818C -:101D50004A7D65A300938F672978C24DC1D1068261 -:101D600031AF07383411F3A82A9EA8661AA4A54FEC -:101D70005A0C118FAA7BD0654945BDE962D2B19E4C -:101D80006CCCC6198709C38E75411F3AA513D5556A -:101D900055555555555555555555555555555555F3 -:101DA00055555555555555555555555555555555E3 -:0E1DB00055555555555555555555555ACC90C8 -:00000001FF
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index e95d1b64..0225742 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt
@@ -33,7 +33,7 @@ config BINFMT_ELF_FDPIC bool "Kernel support for FDPIC ELF binaries" default y - depends on (FRV || BLACKFIN || (SUPERH32 && !MMU)) + depends on (FRV || BLACKFIN || (SUPERH32 && !MMU) || C6X) help ELF FDPIC binaries are based on ELF, but allow the individual load segments of a binary to be located in memory independently of each
diff --git a/fs/bio.c b/fs/bio.c index e453924..84da885 100644 --- a/fs/bio.c +++ b/fs/bio.c
@@ -505,9 +505,14 @@ int bio_get_nr_vecs(struct block_device *bdev) { struct request_queue *q = bdev_get_queue(bdev); - return min_t(unsigned, + int nr_pages; + + nr_pages = min_t(unsigned, queue_max_segments(q), queue_max_sectors(q) / (PAGE_SIZE >> 9) + 1); + + return min_t(unsigned, nr_pages, BIO_MAX_PAGES); + } EXPORT_SYMBOL(bio_get_nr_vecs);
diff --git a/fs/block_dev.c b/fs/block_dev.c index e08f6a20..ba11c30 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c
@@ -70,7 +70,7 @@ spin_unlock(&dst->wb.list_lock); } -static sector_t max_block(struct block_device *bdev) +sector_t blkdev_max_block(struct block_device *bdev) { sector_t retval = ~((sector_t)0); loff_t sz = i_size_read(bdev->bd_inode); @@ -163,7 +163,7 @@ blkdev_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh, int create) { - if (iblock >= max_block(I_BDEV(inode))) { + if (iblock >= blkdev_max_block(I_BDEV(inode))) { if (create) return -EIO; @@ -185,7 +185,7 @@ blkdev_get_blocks(struct inode *inode, sector_t iblock, struct buffer_head *bh, int create) { - sector_t end_block = max_block(I_BDEV(inode)); + sector_t end_block = blkdev_max_block(I_BDEV(inode)); unsigned long max_blocks = bh->b_size >> inode->i_blkbits; if ((iblock + max_blocks) > end_block) {
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index e801f22..4106264 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c
@@ -220,10 +220,12 @@ */ static void add_root_to_dirty_list(struct btrfs_root *root) { + spin_lock(&root->fs_info->trans_lock); if (root->track_dirty && list_empty(&root->dirty_list)) { list_add(&root->dirty_list, &root->fs_info->dirty_cowonly_roots); } + spin_unlock(&root->fs_info->trans_lock); } /* @@ -723,7 +725,7 @@ cur = btrfs_find_tree_block(root, blocknr, blocksize); if (cur) - uptodate = btrfs_buffer_uptodate(cur, gen); + uptodate = btrfs_buffer_uptodate(cur, gen, 0); else uptodate = 0; if (!cur || !uptodate) { @@ -1358,7 +1360,12 @@ block1 = btrfs_node_blockptr(parent, slot - 1); gen = btrfs_node_ptr_generation(parent, slot - 1); eb = btrfs_find_tree_block(root, block1, blocksize); - if (eb && btrfs_buffer_uptodate(eb, gen)) + /* + * if we get -eagain from btrfs_buffer_uptodate, we + * don't want to return eagain here. That will loop + * forever + */ + if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0) block1 = 0; free_extent_buffer(eb); } @@ -1366,7 +1373,7 @@ block2 = btrfs_node_blockptr(parent, slot + 1); gen = btrfs_node_ptr_generation(parent, slot + 1); eb = btrfs_find_tree_block(root, block2, blocksize); - if (eb && btrfs_buffer_uptodate(eb, gen)) + if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0) block2 = 0; free_extent_buffer(eb); } @@ -1504,8 +1511,9 @@ tmp = btrfs_find_tree_block(root, blocknr, blocksize); if (tmp) { - if (btrfs_buffer_uptodate(tmp, 0)) { - if (btrfs_buffer_uptodate(tmp, gen)) { + /* first we do an atomic uptodate check */ + if (btrfs_buffer_uptodate(tmp, 0, 1) > 0) { + if (btrfs_buffer_uptodate(tmp, gen, 1) > 0) { /* * we found an up to date block without * sleeping, return @@ -1523,8 +1531,9 @@ free_extent_buffer(tmp); btrfs_set_path_blocking(p); + /* now we're allowed to do a blocking uptodate check */ tmp = read_tree_block(root, blocknr, blocksize, gen); - if (tmp && btrfs_buffer_uptodate(tmp, gen)) { + if (tmp && btrfs_buffer_uptodate(tmp, gen, 0) > 0) { *eb_ret = tmp; return 0; } @@ -1559,7 +1568,7 @@ * and give up so that our caller doesn't loop forever * on our EAGAINs. */ - if (!btrfs_buffer_uptodate(tmp, 0)) + if (!btrfs_buffer_uptodate(tmp, 0, 0)) ret = -EIO; free_extent_buffer(tmp); } @@ -4043,7 +4052,7 @@ tmp = btrfs_find_tree_block(root, blockptr, btrfs_level_size(root, level - 1)); - if (tmp && btrfs_buffer_uptodate(tmp, gen)) { + if (tmp && btrfs_buffer_uptodate(tmp, gen, 1) > 0) { free_extent_buffer(tmp); break; } @@ -4166,7 +4175,8 @@ struct extent_buffer *cur; cur = btrfs_find_tree_block(root, blockptr, btrfs_level_size(root, level - 1)); - if (!cur || !btrfs_buffer_uptodate(cur, gen)) { + if (!cur || + btrfs_buffer_uptodate(cur, gen, 1) <= 0) { slot++; if (cur) free_extent_buffer(cur);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index d0c969b..a7ffc88 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c
@@ -323,7 +323,8 @@ * in the wrong place. */ static int verify_parent_transid(struct extent_io_tree *io_tree, - struct extent_buffer *eb, u64 parent_transid) + struct extent_buffer *eb, u64 parent_transid, + int atomic) { struct extent_state *cached_state = NULL; int ret; @@ -331,6 +332,9 @@ if (!parent_transid || btrfs_header_generation(eb) == parent_transid) return 0; + if (atomic) + return -EAGAIN; + lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1, 0, &cached_state); if (extent_buffer_uptodate(eb) && @@ -372,7 +376,8 @@ ret = read_extent_buffer_pages(io_tree, eb, start, WAIT_COMPLETE, btree_get_extent, mirror_num); - if (!ret && !verify_parent_transid(io_tree, eb, parent_transid)) + if (!ret && !verify_parent_transid(io_tree, eb, + parent_transid, 0)) break; /* @@ -1202,7 +1207,7 @@ root->commit_root = NULL; root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), blocksize, generation); - if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) { + if (!root->node || !btrfs_buffer_uptodate(root->node, generation, 0)) { free_extent_buffer(root->node); root->node = NULL; return -EIO; @@ -3143,7 +3148,8 @@ return 0; } -int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid) +int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, + int atomic) { int ret; struct inode *btree_inode = buf->pages[0]->mapping->host; @@ -3153,7 +3159,9 @@ return ret; ret = verify_parent_transid(&BTRFS_I(btree_inode)->io_tree, buf, - parent_transid); + parent_transid, atomic); + if (ret == -EAGAIN) + return ret; return !ret; }
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index a7ace1a..ab1830a 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h
@@ -66,7 +66,8 @@ void __btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr); void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root); void btrfs_mark_buffer_dirty(struct extent_buffer *buf); -int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid); +int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, + int atomic); int btrfs_set_buffer_uptodate(struct extent_buffer *buf); int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid); u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 6fc2e6f..49fd7b6 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c
@@ -6568,7 +6568,7 @@ goto skip; } - if (!btrfs_buffer_uptodate(next, generation)) { + if (!btrfs_buffer_uptodate(next, generation, 0)) { btrfs_tree_unlock(next); free_extent_buffer(next); next = NULL;
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 198c2ba..c9018a0 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c
@@ -4120,6 +4120,7 @@ if (atomic_inc_not_zero(&exists->refs)) { spin_unlock(&mapping->private_lock); unlock_page(p); + page_cache_release(p); mark_extent_buffer_accessed(exists); goto free_eb; } @@ -4199,8 +4200,7 @@ unlock_page(eb->pages[i]); } - if (!atomic_dec_and_test(&eb->refs)) - return exists; + WARN_ON(!atomic_dec_and_test(&eb->refs)); btrfs_release_extent_buffer(eb); return exists; }
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 4f69028a..086e6bd 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h
@@ -252,7 +252,7 @@ struct btrfs_ioctl_ino_path_args { __u64 inum; /* in */ - __u32 size; /* in */ + __u64 size; /* in */ __u64 reserved[4]; /* struct btrfs_data_container *fspath; out */ __u64 fspath; /* out */ @@ -260,7 +260,7 @@ struct btrfs_ioctl_logical_ino_args { __u64 logical; /* in */ - __u32 size; /* in */ + __u64 size; /* in */ __u64 reserved[4]; /* struct btrfs_data_container *inodes; out */ __u64 inodes;
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 4f76fc3..2f3d6f9 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c
@@ -998,6 +998,7 @@ page = sblock->pagev + page_index; page->logical = logical; page->physical = bbio->stripes[mirror_index].physical; + /* for missing devices, bdev is NULL */ page->bdev = bbio->stripes[mirror_index].dev->bdev; page->mirror_num = mirror_index + 1; page->page = alloc_page(GFP_NOFS); @@ -1042,6 +1043,12 @@ struct scrub_page *page = sblock->pagev + page_num; DECLARE_COMPLETION_ONSTACK(complete); + if (page->bdev == NULL) { + page->io_error = 1; + sblock->no_io_error_seen = 0; + continue; + } + BUG_ON(!page->page); bio = bio_alloc(GFP_NOFS, 1); if (!bio)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index d017283..eb1ae90 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c
@@ -279,7 +279,7 @@ log->fs_info->extent_root, eb->start, eb->len); - if (btrfs_buffer_uptodate(eb, gen)) { + if (btrfs_buffer_uptodate(eb, gen, 0)) { if (wc->write) btrfs_write_tree_block(eb); if (wc->wait)
diff --git a/fs/buffer.c b/fs/buffer.c index 351e18e..ad5938c 100644 --- a/fs/buffer.c +++ b/fs/buffer.c
@@ -921,6 +921,7 @@ struct buffer_head *head = page_buffers(page); struct buffer_head *bh = head; int uptodate = PageUptodate(page); + sector_t end_block = blkdev_max_block(I_BDEV(bdev->bd_inode)); do { if (!buffer_mapped(bh)) { @@ -929,7 +930,8 @@ bh->b_blocknr = block; if (uptodate) set_buffer_uptodate(bh); - set_buffer_mapped(bh); + if (block < end_block) + set_buffer_mapped(bh); } block++; bh = bh->b_this_page;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 811245b..541ef81 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c
@@ -442,7 +442,7 @@ seq_printf(s, ",rsize=%u", cifs_sb->rsize); seq_printf(s, ",wsize=%u", cifs_sb->wsize); /* convert actimeo and display it in seconds */ - seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); + seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); return 0; } @@ -699,7 +699,7 @@ * origin == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate * the cached file length */ - if (origin != SEEK_SET || origin != SEEK_CUR) { + if (origin != SEEK_SET && origin != SEEK_CUR) { int rc; struct inode *inode = file->f_path.dentry->d_inode;
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index d1389bb..6536535 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h
@@ -125,5 +125,5 @@ extern const struct export_operations cifs_export_ops; #endif /* CONFIG_CIFS_NFSD_EXPORT */ -#define CIFS_VERSION "1.77" +#define CIFS_VERSION "1.78" #endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index f52c5ab..da2f544 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c
@@ -4844,8 +4844,12 @@ max_len = data_end - temp; node->node_name = cifs_strndup_from_utf16(temp, max_len, is_unicode, nls_codepage); - if (!node->node_name) + if (!node->node_name) { rc = -ENOMEM; + goto parse_DFS_referrals_exit; + } + + ref++; } parse_DFS_referrals_exit:
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index f4d381e..e0b56d7 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c
@@ -164,7 +164,8 @@ { Opt_sign, "sign" }, { Opt_seal, "seal" }, { Opt_direct, "direct" }, - { Opt_direct, "forceddirectio" }, + { Opt_direct, "directio" }, + { Opt_direct, "forcedirectio" }, { Opt_strictcache, "strictcache" }, { Opt_noac, "noac" }, { Opt_fsc, "fsc" }, @@ -215,6 +216,8 @@ { Opt_ignore, "cred" }, { Opt_ignore, "credentials" }, + { Opt_ignore, "cred=%s" }, + { Opt_ignore, "credentials=%s" }, { Opt_ignore, "guest" }, { Opt_ignore, "rw" }, { Opt_ignore, "ro" }, @@ -2183,6 +2186,7 @@ tcp_ses->session_estab = false; tcp_ses->sequence_number = 0; tcp_ses->lstrp = jiffies; + spin_lock_init(&tcp_ses->req_lock); INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); INIT_LIST_HEAD(&tcp_ses->smb_ses_list); INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); @@ -3614,22 +3618,6 @@ return volume_info; } -/* make sure ra_pages is a multiple of rsize */ -static inline unsigned int -cifs_ra_pages(struct cifs_sb_info *cifs_sb) -{ - unsigned int reads; - unsigned int rsize_pages = cifs_sb->rsize / PAGE_CACHE_SIZE; - - if (rsize_pages >= default_backing_dev_info.ra_pages) - return default_backing_dev_info.ra_pages; - else if (rsize_pages == 0) - return rsize_pages; - - reads = default_backing_dev_info.ra_pages / rsize_pages; - return reads * rsize_pages; -} - int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) { @@ -3717,7 +3705,7 @@ cifs_sb->rsize = cifs_negotiate_rsize(tcon, volume_info); /* tune readahead according to rsize */ - cifs_sb->bdi.ra_pages = cifs_ra_pages(cifs_sb); + cifs_sb->bdi.ra_pages = cifs_sb->rsize / PAGE_CACHE_SIZE; remote_path_check: #ifdef CONFIG_CIFS_DFS_UPCALL
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index d172c8e..ec4e9a2 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c
@@ -668,12 +668,19 @@ return 0; else { /* - * Forcibly invalidate automounting directory inodes - * (remote DFS directories) so to have them - * instantiated again for automount + * If the inode wasn't known to be a dfs entry when + * the dentry was instantiated, such as when created + * via ->readdir(), it needs to be set now since the + * attributes will have been updated by + * cifs_revalidate_dentry(). */ - if (IS_AUTOMOUNT(direntry->d_inode)) - return 0; + if (IS_AUTOMOUNT(direntry->d_inode) && + !(direntry->d_flags & DCACHE_NEED_AUTOMOUNT)) { + spin_lock(&direntry->d_lock); + direntry->d_flags |= DCACHE_NEED_AUTOMOUNT; + spin_unlock(&direntry->d_lock); + } + return 1; } }
diff --git a/fs/dcache.c b/fs/dcache.c index b60ddc4..92099f6 100644 --- a/fs/dcache.c +++ b/fs/dcache.c
@@ -141,18 +141,25 @@ * Compare 2 name strings, return 0 if they match, otherwise non-zero. * The strings are both count bytes long, and count is non-zero. */ -static inline int dentry_cmp(const unsigned char *cs, size_t scount, - const unsigned char *ct, size_t tcount) -{ #ifdef CONFIG_DCACHE_WORD_ACCESS - unsigned long a,b,mask; - if (unlikely(scount != tcount)) - return 1; +#include <asm/word-at-a-time.h> +/* + * NOTE! 'cs' and 'scount' come from a dentry, so it has a + * aligned allocation for this particular component. We don't + * strictly need the load_unaligned_zeropad() safety, but it + * doesn't hurt either. + * + * In contrast, 'ct' and 'tcount' can be from a pathname, and do + * need the careful unaligned handling. + */ +static inline int dentry_string_cmp(const unsigned char *cs, const unsigned char *ct, unsigned tcount) +{ + unsigned long a,b,mask; for (;;) { a = *(unsigned long *)cs; - b = *(unsigned long *)ct; + b = load_unaligned_zeropad(ct); if (tcount < sizeof(unsigned long)) break; if (unlikely(a != b)) @@ -165,10 +172,12 @@ } mask = ~(~0ul << tcount*8); return unlikely(!!((a ^ b) & mask)); -#else - if (scount != tcount) - return 1; +} +#else + +static inline int dentry_string_cmp(const unsigned char *cs, const unsigned char *ct, unsigned tcount) +{ do { if (*cs != *ct) return 1; @@ -177,7 +186,29 @@ tcount--; } while (tcount); return 0; +} + #endif + +static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *ct, unsigned tcount) +{ + /* + * Be careful about RCU walk racing with rename: + * use ACCESS_ONCE to fetch the name pointer. + * + * NOTE! Even if a rename will mean that the length + * was not loaded atomically, we don't care. The + * RCU walk will check the sequence count eventually, + * and catch it. And we won't overrun the buffer, + * because we're reading the name pointer atomically, + * and a dentry name is guaranteed to be properly + * terminated with a NUL byte. + * + * End result: even if 'len' is wrong, we'll exit + * early because the data cannot match (there can + * be no NUL in the ct/tcount data) + */ + return dentry_string_cmp(ACCESS_ONCE(dentry->d_name.name), ct, tcount); } static void __d_free(struct rcu_head *head) @@ -1421,18 +1452,18 @@ } list_for_each_entry(alias, &inode->i_dentry, d_alias) { - struct qstr *qstr = &alias->d_name; - /* * Don't need alias->d_lock here, because aliases with * d_parent == entry->d_parent are not subject to name or * parent changes, because the parent inode i_mutex is held. */ - if (qstr->hash != hash) + if (alias->d_name.hash != hash) continue; if (alias->d_parent != entry->d_parent) continue; - if (dentry_cmp(qstr->name, qstr->len, name, len)) + if (alias->d_name.len != len) + continue; + if (dentry_cmp(alias, name, len)) continue; __dget(alias); return alias; @@ -1471,7 +1502,7 @@ struct dentry *res = NULL; if (root_inode) { - static const struct qstr name = { .name = "/", .len = 1 }; + static const struct qstr name = QSTR_INIT("/", 1); res = __d_alloc(root_inode->i_sb, &name); if (res) @@ -1709,6 +1740,48 @@ } EXPORT_SYMBOL(d_add_ci); +/* + * Do the slow-case of the dentry name compare. + * + * Unlike the dentry_cmp() function, we need to atomically + * load the name, length and inode information, so that the + * filesystem can rely on them, and can use the 'name' and + * 'len' information without worrying about walking off the + * end of memory etc. + * + * Thus the read_seqcount_retry() and the "duplicate" info + * in arguments (the low-level filesystem should not look + * at the dentry inode or name contents directly, since + * rename can change them while we're in RCU mode). + */ +enum slow_d_compare { + D_COMP_OK, + D_COMP_NOMATCH, + D_COMP_SEQRETRY, +}; + +static noinline enum slow_d_compare slow_dentry_cmp( + const struct dentry *parent, + struct inode *inode, + struct dentry *dentry, + unsigned int seq, + const struct qstr *name) +{ + int tlen = dentry->d_name.len; + const char *tname = dentry->d_name.name; + struct inode *i = dentry->d_inode; + + if (read_seqcount_retry(&dentry->d_seq, seq)) { + cpu_relax(); + return D_COMP_SEQRETRY; + } + if (parent->d_op->d_compare(parent, inode, + dentry, i, + tlen, tname, name)) + return D_COMP_NOMATCH; + return D_COMP_OK; +} + /** * __d_lookup_rcu - search for a dentry (racy, store-free) * @parent: parent dentry @@ -1735,15 +1808,17 @@ * the returned dentry, so long as its parent's seqlock is checked after the * child is looked up. Thus, an interlocking stepping of sequence lock checks * is formed, giving integrity down the path walk. + * + * NOTE! The caller *has* to check the resulting dentry against the sequence + * number we've returned before using any of the resulting dentry state! */ struct dentry *__d_lookup_rcu(const struct dentry *parent, const struct qstr *name, - unsigned *seqp, struct inode **inode) + unsigned *seqp, struct inode *inode) { - unsigned int len = name->len; - unsigned int hash = name->hash; + u64 hashlen = name->hash_len; const unsigned char *str = name->name; - struct hlist_bl_head *b = d_hash(parent, hash); + struct hlist_bl_head *b = d_hash(parent, hashlen_hash(hashlen)); struct hlist_bl_node *node; struct dentry *dentry; @@ -1769,49 +1844,45 @@ */ hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) { unsigned seq; - struct inode *i; - const char *tname; - int tlen; - - if (dentry->d_name.hash != hash) - continue; seqretry: - seq = read_seqcount_begin(&dentry->d_seq); + /* + * The dentry sequence count protects us from concurrent + * renames, and thus protects inode, parent and name fields. + * + * The caller must perform a seqcount check in order + * to do anything useful with the returned dentry, + * including using the 'd_inode' pointer. + * + * NOTE! We do a "raw" seqcount_begin here. That means that + * we don't wait for the sequence count to stabilize if it + * is in the middle of a sequence change. If we do the slow + * dentry compare, we will do seqretries until it is stable, + * and if we end up with a successful lookup, we actually + * want to exit RCU lookup anyway. + */ + seq = raw_seqcount_begin(&dentry->d_seq); if (dentry->d_parent != parent) continue; - if (d_unhashed(dentry)) - continue; - tlen = dentry->d_name.len; - tname = dentry->d_name.name; - i = dentry->d_inode; - prefetch(tname); - /* - * This seqcount check is required to ensure name and - * len are loaded atomically, so as not to walk off the - * edge of memory when walking. If we could load this - * atomically some other way, we could drop this check. - */ - if (read_seqcount_retry(&dentry->d_seq, seq)) - goto seqretry; - if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) { - if (parent->d_op->d_compare(parent, *inode, - dentry, i, - tlen, tname, name)) - continue; - } else { - if (dentry_cmp(tname, tlen, str, len)) - continue; - } - /* - * No extra seqcount check is required after the name - * compare. The caller must perform a seqcount check in - * order to do anything useful with the returned dentry - * anyway. - */ *seqp = seq; - *inode = i; - return dentry; + + if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) { + if (dentry->d_name.hash != hashlen_hash(hashlen)) + continue; + switch (slow_dentry_cmp(parent, inode, dentry, seq, name)) { + case D_COMP_OK: + return dentry; + case D_COMP_NOMATCH: + continue; + default: + goto seqretry; + } + } + + if (dentry->d_name.hash_len != hashlen) + continue; + if (!dentry_cmp(dentry, str, hashlen_len(hashlen))) + return dentry; } return NULL; } @@ -1890,8 +1961,6 @@ rcu_read_lock(); hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) { - const char *tname; - int tlen; if (dentry->d_name.hash != hash) continue; @@ -1906,15 +1975,17 @@ * It is safe to compare names since d_move() cannot * change the qstr (protected by d_lock). */ - tlen = dentry->d_name.len; - tname = dentry->d_name.name; if (parent->d_flags & DCACHE_OP_COMPARE) { + int tlen = dentry->d_name.len; + const char *tname = dentry->d_name.name; if (parent->d_op->d_compare(parent, parent->d_inode, dentry, dentry->d_inode, tlen, tname, name)) goto next; } else { - if (dentry_cmp(tname, tlen, str, len)) + if (dentry->d_name.len != len) + goto next; + if (dentry_cmp(dentry, str, len)) goto next; }
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index dffb865..f663a67 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c
@@ -79,7 +79,7 @@ struct dentry *ext2_get_parent(struct dentry *child) { - struct qstr dotdot = {.name = "..", .len = 2}; + struct qstr dotdot = QSTR_INIT("..", 2); unsigned long ino = ext2_inode_by_name(child->d_inode, &dotdot); if (!ino) return ERR_PTR(-ENOENT);
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index d7940b2..eeb63df 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c
@@ -1045,7 +1045,7 @@ struct dentry *ext3_get_parent(struct dentry *child) { unsigned long ino; - struct qstr dotdot = {.name = "..", .len = 2}; + struct qstr dotdot = QSTR_INIT("..", 2); struct ext3_dir_entry_2 * de; struct buffer_head *bh;
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 349d7b3..e2a3f4b 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c
@@ -1052,10 +1052,7 @@ struct dentry *ext4_get_parent(struct dentry *child) { __u32 ino; - static const struct qstr dotdot = { - .name = "..", - .len = 2, - }; + static const struct qstr dotdot = QSTR_INIT("..", 2); struct ext4_dir_entry_2 * de; struct buffer_head *bh;
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index a836056..8aaeb07 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c
@@ -821,7 +821,7 @@ struct buffer_head *bh; struct gfs2_leaf *leaf; struct gfs2_dirent *dent; - struct qstr name = { .name = "", .len = 0, .hash = 0 }; + struct qstr name = { .name = "" }; error = gfs2_alloc_blocks(ip, &bn, &n, 0, NULL); if (error)
diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c index 4dfbfec3..ec2a9c2 100644 --- a/fs/hfsplus/catalog.c +++ b/fs/hfsplus/catalog.c
@@ -366,6 +366,10 @@ err = hfs_brec_find(&src_fd); if (err) goto out; + if (src_fd.entrylength > sizeof(entry) || src_fd.entrylength < 0) { + err = -EIO; + goto out; + } hfs_bnode_read(src_fd.bnode, &entry, src_fd.entryoffset, src_fd.entrylength);
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 88e155f..26b53fb 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c
@@ -150,6 +150,11 @@ filp->f_pos++; /* fall through */ case 1: + if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { + err = -EIO; + goto out; + } + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); if (be16_to_cpu(entry.type) != HFSPLUS_FOLDER_THREAD) { @@ -181,6 +186,12 @@ err = -EIO; goto out; } + + if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { + err = -EIO; + goto out; + } + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); type = be16_to_cpu(entry.type);
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c index ad271c7..5a2dec2 100644 --- a/fs/jffs2/gc.c +++ b/fs/jffs2/gc.c
@@ -234,8 +234,8 @@ return 0; jffs2_dbg(1, "No progress from erasing block; doing GC anyway\n"); - spin_lock(&c->erase_completion_lock); mutex_lock(&c->alloc_sem); + spin_lock(&c->erase_completion_lock); } /* First, work out which block we're garbage-collecting */
diff --git a/fs/libfs.c b/fs/libfs.c index 18d08f5..f86ec27 100644 --- a/fs/libfs.c +++ b/fs/libfs.c
@@ -68,7 +68,7 @@ int dcache_dir_open(struct inode *inode, struct file *file) { - static struct qstr cursor_name = {.len = 1, .name = "."}; + static struct qstr cursor_name = QSTR_INIT(".", 1); file->private_data = d_alloc(file->f_path.dentry, &cursor_name); @@ -225,7 +225,7 @@ struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); struct dentry *dentry; struct inode *root; - struct qstr d_name = {.name = name, .len = strlen(name)}; + struct qstr d_name = QSTR_INIT(name, strlen(name)); if (IS_ERR(s)) return ERR_CAST(s);
diff --git a/fs/namei.c b/fs/namei.c index 0062dd1..f9e883c 100644 --- a/fs/namei.c +++ b/fs/namei.c
@@ -116,47 +116,37 @@ * POSIX.1 2.4: an empty pathname is invalid (ENOENT). * PATH_MAX includes the nul terminator --RR. */ -static int do_getname(const char __user *filename, char *page) -{ - int retval; - unsigned long len = PATH_MAX; - - if (!segment_eq(get_fs(), KERNEL_DS)) { - if ((unsigned long) filename >= TASK_SIZE) - return -EFAULT; - if (TASK_SIZE - (unsigned long) filename < PATH_MAX) - len = TASK_SIZE - (unsigned long) filename; - } - - retval = strncpy_from_user(page, filename, len); - if (retval > 0) { - if (retval < len) - return 0; - return -ENAMETOOLONG; - } else if (!retval) - retval = -ENOENT; - return retval; -} - static char *getname_flags(const char __user *filename, int flags, int *empty) { - char *result = __getname(); - int retval; + char *result = __getname(), *err; + int len; - if (!result) + if (unlikely(!result)) return ERR_PTR(-ENOMEM); - retval = do_getname(filename, result); - if (retval < 0) { - if (retval == -ENOENT && empty) + len = strncpy_from_user(result, filename, PATH_MAX); + err = ERR_PTR(len); + if (unlikely(len < 0)) + goto error; + + /* The empty path is special. */ + if (unlikely(!len)) { + if (empty) *empty = 1; - if (retval != -ENOENT || !(flags & LOOKUP_EMPTY)) { - __putname(result); - return ERR_PTR(retval); - } + err = ERR_PTR(-ENOENT); + if (!(flags & LOOKUP_EMPTY)) + goto error; } - audit_getname(result); - return result; + + err = ERR_PTR(-ENAMETOOLONG); + if (likely(len < PATH_MAX)) { + audit_getname(result); + return result; + } + +error: + __putname(result); + return err; } char *getname(const char __user * filename) @@ -1154,12 +1144,25 @@ */ if (nd->flags & LOOKUP_RCU) { unsigned seq; - *inode = nd->inode; - dentry = __d_lookup_rcu(parent, name, &seq, inode); + dentry = __d_lookup_rcu(parent, name, &seq, nd->inode); if (!dentry) goto unlazy; - /* Memory barrier in read_seqcount_begin of child is enough */ + /* + * This sequence count validates that the inode matches + * the dentry name information from lookup. + */ + *inode = dentry->d_inode; + if (read_seqcount_retry(&dentry->d_seq, seq)) + return -ECHILD; + + /* + * This sequence count validates that the parent had no + * changes while we did the lookup of the dentry above. + * + * The memory barrier in read_seqcount_begin of child is + * enough, we can use __read_seqcount_retry here. + */ if (__read_seqcount_retry(&parent->d_seq, nd->seq)) return -ECHILD; nd->seq = seq; @@ -1429,7 +1432,7 @@ unsigned long hash = 0; for (;;) { - a = *(unsigned long *)name; + a = load_unaligned_zeropad(name); if (len < sizeof(unsigned long)) break; hash += a; @@ -1459,7 +1462,7 @@ do { hash = (hash + a) * 9; len += sizeof(unsigned long); - a = *(unsigned long *)(name+len); + a = load_unaligned_zeropad(name+len); /* Do we have any NUL or '/' bytes in this word? */ mask = has_zero(a) | has_zero(a ^ REPEAT_BYTE('/')); } while (!mask);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 8789210..eedd24d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c
@@ -477,10 +477,7 @@ static void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) { - struct qstr filename = { - .len = entry->len, - .name = entry->name, - }; + struct qstr filename = QSTR_INIT(entry->name, entry->len); struct dentry *dentry; struct dentry *alias; struct inode *dir = parent->d_inode;
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 5242eae..75c6829 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c
@@ -398,8 +398,7 @@ { struct nfs_removeargs arg = { .fh = NFS_FH(dir), - .name.len = name->len, - .name.name = name->name, + .name = *name, }; struct nfs_removeres res; struct rpc_message msg = {
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 99650aa..ab985f6 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c
@@ -2782,8 +2782,7 @@ struct nfs_server *server = NFS_SERVER(dir); struct nfs_removeargs args = { .fh = NFS_FH(dir), - .name.len = name->len, - .name.name = name->name, + .name = *name, .bitmask = server->attr_bitmask, }; struct nfs_removeres res = {
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index b63b6f4..d6408b6 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c
@@ -335,8 +335,7 @@ { struct nfs_removeargs arg = { .fh = NFS_FH(dir), - .name.len = name->len, - .name.name = name->name, + .name = *name, }; struct rpc_message msg = { .rpc_proc = &nfs_procedures[NFSPROC_REMOVE],
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index fce2bbe..0bb2c20 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c
@@ -441,7 +441,7 @@ { unsigned long ino; struct inode *inode; - struct qstr dotdot = {.name = "..", .len = 2}; + struct qstr dotdot = QSTR_INIT("..", 2); struct nilfs_root *root; ino = nilfs_inode_by_name(child->d_inode, &dotdot);
diff --git a/fs/proc/base.c b/fs/proc/base.c index 1c8b280..57b8159 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c
@@ -1799,10 +1799,15 @@ if (task) { files = get_files_struct(task); if (files) { + struct file *file; rcu_read_lock(); - if (fcheck_files(files, fd)) { + file = fcheck_files(files, fd); + if (file) { + unsigned i_mode, f_mode = file->f_mode; + rcu_read_unlock(); put_files_struct(files); + if (task_dumpable(task)) { rcu_read_lock(); cred = __task_cred(task); @@ -1813,7 +1818,14 @@ inode->i_uid = 0; inode->i_gid = 0; } - inode->i_mode &= ~(S_ISUID | S_ISGID); + + i_mode = S_IFLNK; + if (f_mode & FMODE_READ) + i_mode |= S_IRUSR | S_IXUSR; + if (f_mode & FMODE_WRITE) + i_mode |= S_IWUSR | S_IXUSR; + inode->i_mode = i_mode; + security_task_to_inode(task, inode); put_task_struct(task); return 1; @@ -1837,8 +1849,6 @@ struct dentry *dentry, struct task_struct *task, const void *ptr) { unsigned fd = *(const unsigned *)ptr; - struct file *file; - struct files_struct *files; struct inode *inode; struct proc_inode *ei; struct dentry *error = ERR_PTR(-ENOENT); @@ -1848,25 +1858,6 @@ goto out; ei = PROC_I(inode); ei->fd = fd; - files = get_files_struct(task); - if (!files) - goto out_iput; - inode->i_mode = S_IFLNK; - - /* - * We are not taking a ref to the file structure, so we must - * hold ->file_lock. - */ - spin_lock(&files->file_lock); - file = fcheck_files(files, fd); - if (!file) - goto out_unlock; - if (file->f_mode & FMODE_READ) - inode->i_mode |= S_IRUSR | S_IXUSR; - if (file->f_mode & FMODE_WRITE) - inode->i_mode |= S_IWUSR | S_IXUSR; - spin_unlock(&files->file_lock); - put_files_struct(files); inode->i_op = &proc_pid_link_inode_operations; inode->i_size = 64; @@ -1879,12 +1870,6 @@ out: return error; -out_unlock: - spin_unlock(&files->file_lock); - put_files_struct(files); -out_iput: - iput(inode); - goto out; } static struct dentry *proc_lookupfd_common(struct inode *dir, @@ -2177,16 +2162,16 @@ goto out; result = ERR_PTR(-EACCES); - if (lock_trace(task)) + if (!ptrace_may_access(task, PTRACE_MODE_READ)) goto out_put_task; result = ERR_PTR(-ENOENT); if (dname_to_vma_addr(dentry, &vm_start, &vm_end)) - goto out_unlock; + goto out_put_task; mm = get_task_mm(task); if (!mm) - goto out_unlock; + goto out_put_task; down_read(&mm->mmap_sem); vma = find_exact_vma(mm, vm_start, vm_end); @@ -2198,8 +2183,6 @@ out_no_vma: up_read(&mm->mmap_sem); mmput(mm); -out_unlock: - unlock_trace(task); out_put_task: put_task_struct(task); out: @@ -2233,7 +2216,7 @@ goto out; ret = -EACCES; - if (lock_trace(task)) + if (!ptrace_may_access(task, PTRACE_MODE_READ)) goto out_put_task; ret = 0; @@ -2241,12 +2224,12 @@ case 0: ino = inode->i_ino; if (filldir(dirent, ".", 1, 0, ino, DT_DIR) < 0) - goto out_unlock; + goto out_put_task; filp->f_pos++; case 1: ino = parent_ino(dentry); if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0) - goto out_unlock; + goto out_put_task; filp->f_pos++; default: { @@ -2257,7 +2240,7 @@ mm = get_task_mm(task); if (!mm) - goto out_unlock; + goto out_put_task; down_read(&mm->mmap_sem); nr_files = 0; @@ -2287,7 +2270,7 @@ flex_array_free(fa); up_read(&mm->mmap_sem); mmput(mm); - goto out_unlock; + goto out_put_task; } for (i = 0, vma = mm->mmap, pos = 2; vma; vma = vma->vm_next) { @@ -2332,8 +2315,6 @@ } } -out_unlock: - unlock_trace(task); out_put_task: put_task_struct(task); out:
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 2d60492..1030a71 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c
@@ -747,6 +747,8 @@ else if (pte_present(pte)) *pme = make_pme(PM_PFRAME(pte_pfn(pte)) | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT); + else + *pme = make_pme(PM_NOT_PRESENT); } #ifdef CONFIG_TRANSPARENT_HUGEPAGE @@ -761,6 +763,8 @@ if (pmd_present(pmd)) *pme = make_pme(PM_PFRAME(pmd_pfn(pmd) + offset) | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT); + else + *pme = make_pme(PM_NOT_PRESENT); } #else static inline void thp_pmd_to_pagemap_entry(pagemap_entry_t *pme, @@ -801,8 +805,10 @@ /* check to see if we've left 'vma' behind * and need a new, higher one */ - if (vma && (addr >= vma->vm_end)) + if (vma && (addr >= vma->vm_end)) { vma = find_vma(walk->mm, addr); + pme = make_pme(PM_NOT_PRESENT); + } /* check that 'vma' actually covers this address, * and that it isn't a huge page vma */ @@ -830,6 +836,8 @@ if (pte_present(pte)) *pme = make_pme(PM_PFRAME(pte_pfn(pte) + offset) | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT); + else + *pme = make_pme(PM_NOT_PRESENT); } /* This function walks within one hugetlb entry in the single call */ @@ -839,7 +847,7 @@ { struct pagemapread *pm = walk->private; int err = 0; - pagemap_entry_t pme = make_pme(PM_NOT_PRESENT); + pagemap_entry_t pme; for (; addr != end; addr += PAGE_SIZE) { int offset = (addr & ~hmask) >> PAGE_SHIFT;
diff --git a/fs/stat.c b/fs/stat.c index c733dc5..0cef336 100644 --- a/fs/stat.c +++ b/fs/stat.c
@@ -57,12 +57,13 @@ int vfs_fstat(unsigned int fd, struct kstat *stat) { - struct file *f = fget(fd); + int fput_needed; + struct file *f = fget_light(fd, &fput_needed); int error = -EBADF; if (f) { error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat); - fput(f); + fput_light(f, fput_needed); } return error; } @@ -190,24 +191,32 @@ #endif /* __ARCH_WANT_OLD_STAT */ +#if BITS_PER_LONG == 32 +# define choose_32_64(a,b) a +#else +# define choose_32_64(a,b) b +#endif + +#define valid_dev(x) choose_32_64(old_valid_dev,new_valid_dev)(x) +#define encode_dev(x) choose_32_64(old_encode_dev,new_encode_dev)(x) + +#ifndef INIT_STRUCT_STAT_PADDING +# define INIT_STRUCT_STAT_PADDING(st) memset(&st, 0, sizeof(st)) +#endif + static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf) { struct stat tmp; -#if BITS_PER_LONG == 32 - if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev)) + if (!valid_dev(stat->dev) || !valid_dev(stat->rdev)) return -EOVERFLOW; -#else - if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev)) +#if BITS_PER_LONG == 32 + if (stat->size > MAX_NON_LFS) return -EOVERFLOW; #endif - memset(&tmp, 0, sizeof(tmp)); -#if BITS_PER_LONG == 32 - tmp.st_dev = old_encode_dev(stat->dev); -#else - tmp.st_dev = new_encode_dev(stat->dev); -#endif + INIT_STRUCT_STAT_PADDING(tmp); + tmp.st_dev = encode_dev(stat->dev); tmp.st_ino = stat->ino; if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) return -EOVERFLOW; @@ -217,15 +226,7 @@ return -EOVERFLOW; SET_UID(tmp.st_uid, stat->uid); SET_GID(tmp.st_gid, stat->gid); -#if BITS_PER_LONG == 32 - tmp.st_rdev = old_encode_dev(stat->rdev); -#else - tmp.st_rdev = new_encode_dev(stat->rdev); -#endif -#if BITS_PER_LONG == 32 - if (stat->size > MAX_NON_LFS) - return -EOVERFLOW; -#endif + tmp.st_rdev = encode_dev(stat->rdev); tmp.st_size = stat->size; tmp.st_atime = stat->atime.tv_sec; tmp.st_mtime = stat->mtime.tv_sec; @@ -327,11 +328,15 @@ /* ---------- LFS-64 ----------- */ #ifdef __ARCH_WANT_STAT64 +#ifndef INIT_STRUCT_STAT64_PADDING +# define INIT_STRUCT_STAT64_PADDING(st) memset(&st, 0, sizeof(st)) +#endif + static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf) { struct stat64 tmp; - memset(&tmp, 0, sizeof(struct stat64)); + INIT_STRUCT_STAT64_PADDING(tmp); #ifdef CONFIG_MIPS /* mips has weird padding, so we don't get 64 bits there */ if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 16ad84d..abd5133 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c
@@ -2361,7 +2361,7 @@ * by passing 'ubifs_tnc_remove_nm()' the same key but * an unmatchable name. */ - struct qstr noname = { .len = 0, .name = "" }; + struct qstr noname = { .name = "" }; err = dbg_check_tnc(c, 0); mutex_unlock(&c->tnc_mutex);
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index 85b2722..7a8bafa 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c
@@ -298,7 +298,7 @@ { struct inode *inode, *host = dentry->d_inode; struct ubifs_info *c = host->i_sb->s_fs_info; - struct qstr nm = { .name = name, .len = strlen(name) }; + struct qstr nm = QSTR_INIT(name, strlen(name)); struct ubifs_dent_node *xent; union ubifs_key key; int err, type; @@ -361,7 +361,7 @@ { struct inode *inode, *host = dentry->d_inode; struct ubifs_info *c = host->i_sb->s_fs_info; - struct qstr nm = { .name = name, .len = strlen(name) }; + struct qstr nm = QSTR_INIT(name, strlen(name)); struct ubifs_inode *ui; struct ubifs_dent_node *xent; union ubifs_key key; @@ -524,7 +524,7 @@ { struct inode *inode, *host = dentry->d_inode; struct ubifs_info *c = host->i_sb->s_fs_info; - struct qstr nm = { .name = name, .len = strlen(name) }; + struct qstr nm = QSTR_INIT(name, strlen(name)); struct ubifs_dent_node *xent; union ubifs_key key; int err;
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 38de8f2..a165c66 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c
@@ -1193,7 +1193,7 @@ { struct kernel_lb_addr tloc; struct inode *inode = NULL; - struct qstr dotdot = {.name = "..", .len = 2}; + struct qstr dotdot = QSTR_INIT("..", 2); struct fileIdentDesc cfi; struct udf_fileident_bh fibh;
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index ac8e279..302f340 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c
@@ -146,10 +146,7 @@ static struct dentry *ufs_get_parent(struct dentry *child) { - struct qstr dot_dot = { - .name = "..", - .len = 2, - }; + struct qstr dot_dot = QSTR_INIT("..", 2); ino_t ino; ino = ufs_inode_by_name(child->d_inode, &dot_dot);
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index eba6604..e8bcc47 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h
@@ -499,9 +499,10 @@ #define ACPI_STATE_D0 (u8) 0 #define ACPI_STATE_D1 (u8) 1 #define ACPI_STATE_D2 (u8) 2 -#define ACPI_STATE_D3 (u8) 3 -#define ACPI_STATE_D3_COLD (u8) 4 -#define ACPI_D_STATES_MAX ACPI_STATE_D3_COLD +#define ACPI_STATE_D3_HOT (u8) 3 +#define ACPI_STATE_D3 (u8) 4 +#define ACPI_STATE_D3_COLD ACPI_STATE_D3 +#define ACPI_D_STATES_MAX ACPI_STATE_D3 #define ACPI_D_STATE_COUNT 5 #define ACPI_STATE_C0 (u8) 0
diff --git a/include/asm-generic/statfs.h b/include/asm-generic/statfs.h index 0fd28e0..c749af9 100644 --- a/include/asm-generic/statfs.h +++ b/include/asm-generic/statfs.h
@@ -15,7 +15,7 @@ * with a 10' pole. */ #ifndef __statfs_word -#if BITS_PER_LONG == 64 +#if __BITS_PER_LONG == 64 #define __statfs_word long #else #define __statfs_word __u32
diff --git a/include/linux/Kbuild b/include/linux/Kbuild index f08e3ae..02f691c 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild
@@ -167,7 +167,6 @@ header-y += if_bonding.h header-y += if_bridge.h header-y += if_cablemodem.h -header-y += if_ec.h header-y += if_eql.h header-y += if_ether.h header-y += if_fc.h @@ -186,7 +185,6 @@ header-y += if_slip.h header-y += if_strip.h header-y += if_team.h -header-y += if_tr.h header-y += if_tun.h header-y += if_tunnel.h header-y += if_vlan.h
diff --git a/include/linux/atmlec.h b/include/linux/atmlec.h index 39c917f..302791e 100644 --- a/include/linux/atmlec.h +++ b/include/linux/atmlec.h
@@ -21,13 +21,6 @@ /* Maximum number of LEC interfaces (tweakable) */ #define MAX_LEC_ITF 48 -/* - * From the total of MAX_LEC_ITF, last NUM_TR_DEVS are reserved for Token Ring. - * E.g. if MAX_LEC_ITF = 48 and NUM_TR_DEVS = 8, then lec0-lec39 are for - * Ethernet ELANs and lec40-lec47 are for Token Ring ELANS. - */ -#define NUM_TR_DEVS 8 - typedef enum { l_set_mac_addr, l_del_mac_addr,
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 2aa2466..4d4ac24 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h
@@ -1,9 +1,10 @@ #ifndef _LINUX_BLKDEV_H #define _LINUX_BLKDEV_H +#include <linux/sched.h> + #ifdef CONFIG_BLOCK -#include <linux/sched.h> #include <linux/major.h> #include <linux/genhd.h> #include <linux/list.h>
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 7e11f14..094789f 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h
@@ -25,6 +25,13 @@ #define IS_ROOT(x) ((x) == (x)->d_parent) +/* The hash is always the low bits of hash_len */ +#ifdef __LITTLE_ENDIAN + #define HASH_LEN_DECLARE u32 hash; u32 len; +#else + #define HASH_LEN_DECLARE u32 len; u32 hash; +#endif + /* * "quick string" -- eases parameter passing, but more importantly * saves "metadata" about the string (ie length and the hash). @@ -33,11 +40,19 @@ * dentry. */ struct qstr { - unsigned int hash; - unsigned int len; + union { + struct { + HASH_LEN_DECLARE; + }; + u64 hash_len; + }; const unsigned char *name; }; +#define QSTR_INIT(n,l) { { { .len = l } }, .name = n } +#define hashlen_hash(hashlen) ((u32) (hashlen)) +#define hashlen_len(hashlen) ((u32)((hashlen) >> 32)) + struct dentry_stat_t { int nr_dentry; int nr_unused; @@ -282,7 +297,7 @@ extern struct dentry *__d_lookup(struct dentry *, struct qstr *); extern struct dentry *__d_lookup_rcu(const struct dentry *parent, const struct qstr *name, - unsigned *seq, struct inode **inode); + unsigned *seq, struct inode *inode); /** * __d_rcu_to_refcount - take a refcount on dentry if sequence check is ok
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index c47631f..3d406e0 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h
@@ -18,8 +18,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * WARNING: This move may well be temporary. This file will get merged with others RSN. - * */ #ifndef _LINUX_ETHERDEVICE_H #define _LINUX_ETHERDEVICE_H @@ -159,7 +157,7 @@ * @addr1: Pointer to a six-byte array containing the Ethernet address * @addr2: Pointer other six-byte array containing the Ethernet address * - * Compare two ethernet addresses, returns 0 if equal, non-zero otherwise. + * Compare two Ethernet addresses, returns 0 if equal, non-zero otherwise. * Unlike memcmp(), it doesn't return a value suitable for sorting. */ static inline unsigned compare_ether_addr(const u8 *addr1, const u8 *addr2) @@ -171,6 +169,18 @@ return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0; } +/** + * ether_addr_equal - Compare two Ethernet addresses + * @addr1: Pointer to a six-byte array containing the Ethernet address + * @addr2: Pointer other six-byte array containing the Ethernet address + * + * Compare two Ethernet addresses, returns true if equal + */ +static inline bool ether_addr_equal(const u8 *addr1, const u8 *addr2) +{ + return !compare_ether_addr(addr1, addr2); +} + static inline unsigned long zap_last_2bytes(unsigned long value) { #ifdef __BIG_ENDIAN @@ -181,34 +191,34 @@ } /** - * compare_ether_addr_64bits - Compare two Ethernet addresses + * ether_addr_equal_64bits - Compare two Ethernet addresses * @addr1: Pointer to an array of 8 bytes * @addr2: Pointer to an other array of 8 bytes * - * Compare two ethernet addresses, returns 0 if equal, non-zero otherwise. - * Unlike memcmp(), it doesn't return a value suitable for sorting. + * Compare two Ethernet addresses, returns true if equal, false otherwise. + * * The function doesn't need any conditional branches and possibly uses * word memory accesses on CPU allowing cheap unaligned memory reads. - * arrays = { byte1, byte2, byte3, byte4, byte6, byte7, pad1, pad2} + * arrays = { byte1, byte2, byte3, byte4, byte5, byte6, pad1, pad2 } * - * Please note that alignment of addr1 & addr2 is only guaranted to be 16 bits. + * Please note that alignment of addr1 & addr2 are only guaranteed to be 16 bits. */ -static inline unsigned compare_ether_addr_64bits(const u8 addr1[6+2], - const u8 addr2[6+2]) +static inline bool ether_addr_equal_64bits(const u8 addr1[6+2], + const u8 addr2[6+2]) { #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS unsigned long fold = ((*(unsigned long *)addr1) ^ (*(unsigned long *)addr2)); if (sizeof(fold) == 8) - return zap_last_2bytes(fold) != 0; + return zap_last_2bytes(fold) == 0; fold |= zap_last_2bytes((*(unsigned long *)(addr1 + 4)) ^ (*(unsigned long *)(addr2 + 4))); - return fold != 0; + return fold == 0; #else - return compare_ether_addr(addr1, addr2); + return ether_addr_equal(addr1, addr2); #endif } @@ -220,23 +230,23 @@ * Compare passed address with all addresses of the device. Return true if the * address if one of the device addresses. * - * Note that this function calls compare_ether_addr_64bits() so take care of + * Note that this function calls ether_addr_equal_64bits() so take care of * the right padding. */ static inline bool is_etherdev_addr(const struct net_device *dev, const u8 addr[6 + 2]) { struct netdev_hw_addr *ha; - int res = 1; + bool res = false; rcu_read_lock(); for_each_dev_addr(dev, ha) { - res = compare_ether_addr_64bits(addr, ha->addr); - if (!res) + res = ether_addr_equal_64bits(addr, ha->addr); + if (res) break; } rcu_read_unlock(); - return !res; + return res; } #endif /* __KERNEL__ */ @@ -245,7 +255,7 @@ * @a: Pointer to Ethernet header * @b: Pointer to Ethernet header * - * Compare two ethernet headers, returns 0 if equal. + * Compare two Ethernet headers, returns 0 if equal. * This assumes that the network header (i.e., IP header) is 4-byte * aligned OR the platform can handle unaligned access. This is the * case for all packets coming into netif_receive_skb or similar
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 89d68d8..e17fa71 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h
@@ -137,6 +137,23 @@ }; /** + * struct ethtool_modinfo - plugin module eeprom information + * @cmd: %ETHTOOL_GMODULEINFO + * @type: Standard the module information conforms to %ETH_MODULE_SFF_xxxx + * @eeprom_len: Length of the eeprom + * + * This structure is used to return the information to + * properly size memory for a subsequent call to %ETHTOOL_GMODULEEEPROM. + * The type code indicates the eeprom data format + */ +struct ethtool_modinfo { + __u32 cmd; + __u32 type; + __u32 eeprom_len; + __u32 reserved[8]; +}; + +/** * struct ethtool_coalesce - coalescing parameters for IRQs and stats updates * @cmd: ETHTOOL_{G,S}COALESCE * @rx_coalesce_usecs: How many usecs to delay an RX interrupt after @@ -661,12 +678,17 @@ * %ETHTOOL_SET_DUMP * @version: FW version of the dump, filled in by driver * @flag: driver dependent flag for dump setting, filled in by driver during - * get and filled in by ethtool for set operation + * get and filled in by ethtool for set operation. + * flag must be initialized by macro ETH_FW_DUMP_DISABLE value when + * firmware dump is disabled. * @len: length of dump data, used as the length of the user buffer on entry to * %ETHTOOL_GET_DUMP_DATA and this is returned as dump length by driver * for %ETHTOOL_GET_DUMP_FLAG command * @data: data collected for get dump data operation */ + +#define ETH_FW_DUMP_DISABLE 0 + struct ethtool_dump { __u32 cmd; __u32 version; @@ -920,6 +942,9 @@ * @get_ts_info: Get the time stamping and PTP hardware clock capabilities. * Drivers supporting transmit time stamps in software should set this to * ethtool_op_get_ts_info(). + * @get_module_info: Get the size and type of the eeprom contained within + * a plug-in module. + * @get_module_eeprom: Get the eeprom information from the plug-in module * * All operations are optional (i.e. the function pointer may be set * to %NULL) and callers must take this into account. Callers must @@ -982,6 +1007,11 @@ struct ethtool_dump *, void *); int (*set_dump)(struct net_device *, struct ethtool_dump *); int (*get_ts_info)(struct net_device *, struct ethtool_ts_info *); + int (*get_module_info)(struct net_device *, + struct ethtool_modinfo *); + int (*get_module_eeprom)(struct net_device *, + struct ethtool_eeprom *, u8 *); + }; #endif /* __KERNEL__ */ @@ -1057,6 +1087,8 @@ #define ETHTOOL_GET_DUMP_FLAG 0x0000003f /* Get dump settings */ #define ETHTOOL_GET_DUMP_DATA 0x00000040 /* Get dump data */ #define ETHTOOL_GET_TS_INFO 0x00000041 /* Get time stamping and PHC info */ +#define ETHTOOL_GMODULEINFO 0x00000042 /* Get plug-in module information */ +#define ETHTOOL_GMODULEEEPROM 0x00000043 /* Get plug-in module eeprom */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET @@ -1206,6 +1238,12 @@ #define RX_CLS_LOC_FIRST 0xfffffffe #define RX_CLS_LOC_LAST 0xfffffffd +/* EEPROM Standards for plug in modules */ +#define ETH_MODULE_SFF_8079 0x1 +#define ETH_MODULE_SFF_8079_LEN 256 +#define ETH_MODULE_SFF_8472 0x2 +#define ETH_MODULE_SFF_8472_LEN 512 + /* Reset flags */ /* The reset() operation must clear the flags for the components which * were actually reset. On successful return, the flags indicate the
diff --git a/include/linux/fs.h b/include/linux/fs.h index 8de6755..25c40b9 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h
@@ -2051,6 +2051,7 @@ extern struct block_device *bdget(dev_t); extern struct block_device *bdgrab(struct block_device *bdev); extern void bd_set_size(struct block_device *, loff_t size); +extern sector_t blkdev_max_block(struct block_device *bdev); extern void bd_forget(struct inode *inode); extern void bdput(struct block_device *); extern void invalidate_bdev(struct block_device *);
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 5f3f3be..176a939 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h
@@ -179,6 +179,7 @@ TRACE_EVENT_FL_RECORDED_CMD_BIT, TRACE_EVENT_FL_CAP_ANY_BIT, TRACE_EVENT_FL_NO_SET_FILTER_BIT, + TRACE_EVENT_FL_IGNORE_ENABLE_BIT, }; enum { @@ -187,6 +188,7 @@ TRACE_EVENT_FL_RECORDED_CMD = (1 << TRACE_EVENT_FL_RECORDED_CMD_BIT), TRACE_EVENT_FL_CAP_ANY = (1 << TRACE_EVENT_FL_CAP_ANY_BIT), TRACE_EVENT_FL_NO_SET_FILTER = (1 << TRACE_EVENT_FL_NO_SET_FILTER_BIT), + TRACE_EVENT_FL_IGNORE_ENABLE = (1 << TRACE_EVENT_FL_IGNORE_ENABLE_BIT), }; struct ftrace_event_call {
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index e61d319..017a7fb 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h
@@ -222,12 +222,6 @@ } } -static inline char *part_unpack_uuid(const u8 *uuid, char *out) -{ - sprintf(out, "%pU", uuid); - return out; -} - static inline int disk_max_parts(struct gendisk *disk) { if (disk->flags & GENHD_FL_EXT_DEVT)
diff --git a/include/linux/ibmtr.h b/include/linux/ibmtr.h deleted file mode 100644 index 06695b7..0000000 --- a/include/linux/ibmtr.h +++ /dev/null
@@ -1,373 +0,0 @@ -#ifndef __LINUX_IBMTR_H__ -#define __LINUX_IBMTR_H__ - -/* Definitions for an IBM Token Ring card. */ -/* This file is distributed under the GNU GPL */ - -/* ported to the Alpha architecture 02/20/96 (just used the HZ macro) */ - -#define TR_RETRY_INTERVAL (30*HZ) /* 500 on PC = 5 s */ -#define TR_RST_TIME (msecs_to_jiffies(50)) /* 5 on PC = 50 ms */ -#define TR_BUSY_INTERVAL (msecs_to_jiffies(200)) /* 5 on PC = 200 ms */ -#define TR_SPIN_INTERVAL (3*HZ) /* 3 seconds before init timeout */ - -#define TR_ISA 1 -#define TR_MCA 2 -#define TR_ISAPNP 3 -#define NOTOK 0 - -#define IBMTR_SHARED_RAM_SIZE 0x10000 -#define IBMTR_IO_EXTENT 4 -#define IBMTR_MAX_ADAPTERS 4 - -#define CHANNEL_ID 0X1F30 -#define AIP 0X1F00 -#define AIPADAPTYPE 0X1FA0 -#define AIPDATARATE 0X1FA2 -#define AIPEARLYTOKEN 0X1FA4 -#define AIPAVAILSHRAM 0X1FA6 -#define AIPSHRAMPAGE 0X1FA8 -#define AIP4MBDHB 0X1FAA -#define AIP16MBDHB 0X1FAC -#define AIPFID 0X1FBA - -#define ADAPTRESET 0x1 /* Control Adapter reset (add to base) */ -#define ADAPTRESETREL 0x2 /* Release Adapter from reset ( """) */ -#define ADAPTINTREL 0x3 /* Adapter interrupt release */ - -#define GLOBAL_INT_ENABLE 0x02f0 - -/* MMIO bits 0-4 select register */ -#define RRR_EVEN 0x00 /* Shared RAM relocation registers - even and odd */ -/* Used to set the starting address of shared RAM */ -/* Bits 1 through 7 of this register map to bits 13 through 19 of the shared - RAM address.*/ -/* ie: 0x02 sets RAM address to ...ato! issy su wazzoo !! GODZILLA!!! */ -#define RRR_ODD 0x01 -/* Bits 2 and 3 of this register can be read to determine shared RAM size */ -/* 00 for 8k, 01 for 16k, 10 for 32k, 11 for 64k */ -#define WRBR_EVEN 0x02 /* Write region base registers - even and odd */ -#define WRBR_ODD 0x03 -#define WWOR_EVEN 0x04 /* Write window open registers - even and odd */ -#define WWOR_ODD 0x05 -#define WWCR_EVEN 0x06 /* Write window close registers - even and odd */ -#define WWCR_ODD 0x07 - -/* Interrupt status registers - PC system - even and odd */ -#define ISRP_EVEN 0x08 - -#define TCR_INT 0x10 /* Bit 4 - Timer interrupt. The TVR_EVEN timer has - expired. */ -#define ERR_INT 0x08 /* Bit 3 - Error interrupt. The adapter has had an - internal error. */ -#define ACCESS_INT 0x04 /* Bit 2 - Access interrupt. You have attempted to - write to an invalid area of shared RAM - or an invalid register within the MMIO. */ -/* In addition, the following bits within ISRP_EVEN can be turned on or off */ -/* by you to control the interrupt processing: */ -#define INT_ENABLE 0x40 /* Bit 6 - Interrupt enable. If 0, no interrupts will - occur. If 1, interrupts will occur normally. - Normally set to 1. */ -/* Bit 0 - Primary or alternate adapter. Set to zero if this adapter is the - primary adapter, 1 if this adapter is the alternate adapter. */ - - -#define ISRP_ODD 0x09 - -#define ADAP_CHK_INT 0x40 /* Bit 6 - Adapter check. the adapter has - encountered a serious problem and has closed - itself. Whoa. */ -#define SRB_RESP_INT 0x20 /* Bit 5 - SRB response. The adapter has accepted - an SRB request and set the return code within - the SRB. */ -#define ASB_FREE_INT 0x10 /* Bit 4 - ASB free. The adapter has read the ASB - and this area can be safely reused. This interrupt - is only used if your application has set the ASB - free request bit in ISRA_ODD or if an error was - detected in your response. */ -#define ARB_CMD_INT 0x08 /* Bit 3 - ARB command. The adapter has given you a - command for action. The command is located in the - ARB area of shared memory. */ -#define SSB_RESP_INT 0x04 /* Bit 2 - SSB response. The adapter has posted a - response to your SRB (the response is located in - the SSB area of shared memory). */ -/* Bit 1 - Bridge frame forward complete. */ - - - -#define ISRA_EVEN 0x0A /*Interrupt status registers - adapter - even and odd */ -/* Bit 7 - Internal parity error (on adapter's internal bus) */ -/* Bit 6 - Timer interrupt pending */ -/* Bit 5 - Access interrupt (attempt by adapter to access illegal address) */ -/* Bit 4 - Adapter microcode problem (microcode dead-man timer expired) */ -/* Bit 3 - Adapter processor check status */ -/* Bit 2 - Reserved */ -/* Bit 1 - Adapter hardware interrupt mask (prevents internal interrupts) */ -/* Bit 0 - Adapter software interrupt mask (prevents internal software ints) */ - -#define ISRA_ODD 0x0B -#define CMD_IN_SRB 0x20 /* Bit 5 - Indicates that you have placed a new - command in the SRB and are ready for the adapter to - process the command. */ -#define RESP_IN_ASB 0x10 /* Bit 4 - Indicates that you have placed a response - (an ASB) in the shared RAM which is available for - the adapter's use. */ -/* Bit 3 - Indicates that you are ready to put an SRB in the shared RAM, but - that a previous command is still pending. The adapter will then - interrupt you when the previous command is completed */ -/* Bit 2 - Indicates that you are ready to put an ASB in the shared RAM, but - that a previous ASB is still pending. The adapter will then interrupt - you when the previous ASB is copied. */ -#define ARB_FREE 0x2 -#define SSB_FREE 0x1 - -#define TCR_EVEN 0x0C /* Timer control registers - even and odd */ -#define TCR_ODD 0x0D -#define TVR_EVEN 0x0E /* Timer value registers - even and odd */ -#define TVR_ODD 0x0F -#define SRPR_EVEN 0x18 /* Shared RAM paging registers - even and odd */ -#define SRPR_ENABLE_PAGING 0xc0 -#define SRPR_ODD 0x19 /* Not used. */ -#define TOKREAD 0x60 -#define TOKOR 0x40 -#define TOKAND 0x20 -#define TOKWRITE 0x00 - -/* MMIO bits 5-6 select operation */ -/* 00 is used to write to a register */ -/* 01 is used to bitwise AND a byte with a register */ -/* 10 is used to bitwise OR a byte with a register */ -/* 11 is used to read from a register */ - -/* MMIO bits 7-8 select area of interest.. see below */ -/* 00 selects attachment control area. */ -/* 01 is reserved. */ -/* 10 selects adapter identification area A containing the adapter encoded - address. */ -/* 11 selects the adapter identification area B containing test patterns. */ - -#define PCCHANNELID 5049434F3631313039393020 -#define MCCHANNELID 4D4152533633583435313820 - -#define ACA_OFFSET 0x1e00 -#define ACA_SET 0x40 -#define ACA_RESET 0x20 -#define ACA_RW 0x00 - -#ifdef ENABLE_PAGING -#define SET_PAGE(x) (writeb((x), ti->mmio + ACA_OFFSET+ ACA_RW + SRPR_EVEN)) -#else -#define SET_PAGE(x) -#endif - -/* do_tok_int possible values */ -#define FIRST_INT 1 -#define NOT_FIRST 2 - -typedef enum { CLOSED, OPEN } open_state; -//staic const char *printstate[] = { "CLOSED","OPEN"}; - -struct tok_info { - unsigned char irq; - void __iomem *mmio; - unsigned char hw_address[32]; - unsigned char adapter_type; - unsigned char data_rate; - unsigned char token_release; - unsigned char avail_shared_ram; - unsigned char shared_ram_paging; - unsigned char turbo; - unsigned short dhb_size4mb; - unsigned short rbuf_len4; - unsigned short rbuf_cnt4; - unsigned short maxmtu4; - unsigned short dhb_size16mb; - unsigned short rbuf_len16; - unsigned short rbuf_cnt16; - unsigned short maxmtu16; - /* Additions by David Morris */ - unsigned char do_tok_int; - wait_queue_head_t wait_for_reset; - unsigned char sram_base; - /* Additions by Peter De Schrijver */ - unsigned char page_mask; /* mask to select RAM page to Map*/ - unsigned char mapped_ram_size; /* size of RAM page */ - __u32 sram_phys; /* Shared memory base address */ - void __iomem *sram_virt; /* Shared memory base address */ - void __iomem *init_srb; /* Initial System Request Block address */ - void __iomem *srb; /* System Request Block address */ - void __iomem *ssb; /* System Status Block address */ - void __iomem *arb; /* Adapter Request Block address */ - void __iomem *asb; /* Adapter Status Block address */ - __u8 init_srb_page; - __u8 srb_page; - __u8 ssb_page; - __u8 arb_page; - __u8 asb_page; - unsigned short exsap_station_id; - unsigned short global_int_enable; - struct sk_buff *current_skb; - - unsigned char auto_speedsave; - open_state open_status, sap_status; - enum {MANUAL, AUTOMATIC} open_mode; - enum {FAIL, RESTART, REOPEN} open_action; - enum {NO, YES} open_failure; - unsigned char readlog_pending; - unsigned short adapter_int_enable; /* Adapter-specific int enable */ - struct timer_list tr_timer; - unsigned char ring_speed; - spinlock_t lock; /* SMP protection */ -}; - -/* token ring adapter commands */ -#define DIR_INTERRUPT 0x00 /* struct srb_interrupt */ -#define DIR_MOD_OPEN_PARAMS 0x01 -#define DIR_OPEN_ADAPTER 0x03 /* struct dir_open_adapter */ -#define DIR_CLOSE_ADAPTER 0x04 -#define DIR_SET_GRP_ADDR 0x06 -#define DIR_SET_FUNC_ADDR 0x07 /* struct srb_set_funct_addr */ -#define DIR_READ_LOG 0x08 /* struct srb_read_log */ -#define DLC_OPEN_SAP 0x15 /* struct dlc_open_sap */ -#define DLC_CLOSE_SAP 0x16 -#define DATA_LOST 0x20 /* struct asb_rec */ -#define REC_DATA 0x81 /* struct arb_rec_req */ -#define XMIT_DATA_REQ 0x82 /* struct arb_xmit_req */ -#define DLC_STATUS 0x83 /* struct arb_dlc_status */ -#define RING_STAT_CHANGE 0x84 /* struct dlc_open_sap ??? */ - -/* DIR_OPEN_ADAPTER options */ -#define OPEN_PASS_BCON_MAC 0x0100 -#define NUM_RCV_BUF 2 -#define RCV_BUF_LEN 1024 -#define DHB_LENGTH 2048 -#define NUM_DHB 2 -#define DLC_MAX_SAP 2 -#define DLC_MAX_STA 1 - -/* DLC_OPEN_SAP options */ -#define MAX_I_FIELD 0x0088 -#define SAP_OPEN_IND_SAP 0x04 -#define SAP_OPEN_PRIORITY 0x20 -#define SAP_OPEN_STATION_CNT 0x1 -#define XMIT_DIR_FRAME 0x0A -#define XMIT_UI_FRAME 0x0d -#define XMIT_XID_CMD 0x0e -#define XMIT_TEST_CMD 0x11 - -/* srb close return code */ -#define SIGNAL_LOSS 0x8000 -#define HARD_ERROR 0x4000 -#define XMIT_BEACON 0x1000 -#define LOBE_FAULT 0x0800 -#define AUTO_REMOVAL 0x0400 -#define REMOVE_RECV 0x0100 -#define LOG_OVERFLOW 0x0080 -#define RING_RECOVER 0x0020 - -struct srb_init_response { - unsigned char command; - unsigned char init_status; - unsigned char init_status_2; - unsigned char reserved[3]; - __u16 bring_up_code; - __u16 encoded_address; - __u16 level_address; - __u16 adapter_address; - __u16 parms_address; - __u16 mac_address; -}; - -struct dir_open_adapter { - unsigned char command; - char reserved[7]; - __u16 open_options; - unsigned char node_address[6]; - unsigned char group_address[4]; - unsigned char funct_address[4]; - __u16 num_rcv_buf; - __u16 rcv_buf_len; - __u16 dhb_length; - unsigned char num_dhb; - char reserved2; - unsigned char dlc_max_sap; - unsigned char dlc_max_sta; - unsigned char dlc_max_gsap; - unsigned char dlc_max_gmem; - unsigned char dlc_t1_tick_1; - unsigned char dlc_t2_tick_1; - unsigned char dlc_ti_tick_1; - unsigned char dlc_t1_tick_2; - unsigned char dlc_t2_tick_2; - unsigned char dlc_ti_tick_2; - unsigned char product_id[18]; -}; - -struct dlc_open_sap { - unsigned char command; - unsigned char reserved1; - unsigned char ret_code; - unsigned char reserved2; - __u16 station_id; - unsigned char timer_t1; - unsigned char timer_t2; - unsigned char timer_ti; - unsigned char maxout; - unsigned char maxin; - unsigned char maxout_incr; - unsigned char max_retry_count; - unsigned char gsap_max_mem; - __u16 max_i_field; - unsigned char sap_value; - unsigned char sap_options; - unsigned char station_count; - unsigned char sap_gsap_mem; - unsigned char gsap[0]; -}; - -struct srb_xmit { - unsigned char command; - unsigned char cmd_corr; - unsigned char ret_code; - unsigned char reserved1; - __u16 station_id; -}; - -struct arb_rec_req { - unsigned char command; - unsigned char reserved1[3]; - __u16 station_id; - __u16 rec_buf_addr; - unsigned char lan_hdr_len; - unsigned char dlc_hdr_len; - __u16 frame_len; - unsigned char msg_type; -}; - -struct asb_rec { - unsigned char command; - unsigned char reserved1; - unsigned char ret_code; - unsigned char reserved2; - __u16 station_id; - __u16 rec_buf_addr; -}; - -struct rec_buf { - unsigned char reserved1[2]; - __u16 buf_ptr; - unsigned char reserved2; - unsigned char receive_fs; - __u16 buf_len; - unsigned char data[0]; -}; - -struct srb_set_funct_addr { - unsigned char command; - unsigned char reserved1; - unsigned char ret_code; - unsigned char reserved2[3]; - unsigned char funct_address[4]; -}; - -#endif
diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h index 6d722f4..26cb3c2 100644 --- a/include/linux/if_arp.h +++ b/include/linux/if_arp.h
@@ -82,11 +82,12 @@ #define ARPHRD_FCPL 786 /* Fibrechannel public loop */ #define ARPHRD_FCFABRIC 787 /* Fibrechannel fabric */ /* 787->799 reserved for fibrechannel media types */ -#define ARPHRD_IEEE802_TR 800 /* Magic type ident for TR */ +/* 800 used to be used for token ring */ #define ARPHRD_IEEE80211 801 /* IEEE 802.11 */ #define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */ #define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */ #define ARPHRD_IEEE802154 804 +#define ARPHRD_IEEE802154_MONITOR 805 /* IEEE 802.15.4 network monitor */ #define ARPHRD_PHONET 820 /* PhoNet media type */ #define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */
diff --git a/include/linux/if_ec.h b/include/linux/if_ec.h deleted file mode 100644 index d85f9f4..0000000 --- a/include/linux/if_ec.h +++ /dev/null
@@ -1,68 +0,0 @@ -/* Definitions for Econet sockets. */ - -#ifndef __LINUX_IF_EC -#define __LINUX_IF_EC - -/* User visible stuff. Glibc provides its own but libc5 folk will use these */ - -struct ec_addr { - unsigned char station; /* Station number. */ - unsigned char net; /* Network number. */ -}; - -struct sockaddr_ec { - unsigned short sec_family; - unsigned char port; /* Port number. */ - unsigned char cb; /* Control/flag byte. */ - unsigned char type; /* Type of message. */ - struct ec_addr addr; - unsigned long cookie; -}; - -#define ECTYPE_PACKET_RECEIVED 0 /* Packet received */ -#define ECTYPE_TRANSMIT_STATUS 0x10 /* Transmit completed, - low nibble holds status */ - -#define ECTYPE_TRANSMIT_OK 1 -#define ECTYPE_TRANSMIT_NOT_LISTENING 2 -#define ECTYPE_TRANSMIT_NET_ERROR 3 -#define ECTYPE_TRANSMIT_NO_CLOCK 4 -#define ECTYPE_TRANSMIT_LINE_JAMMED 5 -#define ECTYPE_TRANSMIT_NOT_PRESENT 6 - -#ifdef __KERNEL__ - -#define EC_HLEN 6 - -/* This is what an Econet frame looks like on the wire. */ -struct ec_framehdr { - unsigned char dst_stn; - unsigned char dst_net; - unsigned char src_stn; - unsigned char src_net; - unsigned char cb; - unsigned char port; -}; - -struct econet_sock { - /* struct sock has to be the first member of econet_sock */ - struct sock sk; - unsigned char cb; - unsigned char port; - unsigned char station; - unsigned char net; - unsigned short num; -}; - -static inline struct econet_sock *ec_sk(const struct sock *sk) -{ - return (struct econet_sock *)sk; -} - -struct ec_device { - unsigned char station, net; /* Econet protocol address */ -}; - -#endif - -#endif
diff --git a/include/linux/if_tr.h b/include/linux/if_tr.h deleted file mode 100644 index fc23aeb..0000000 --- a/include/linux/if_tr.h +++ /dev/null
@@ -1,103 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * Global definitions for the Token-Ring IEEE 802.5 interface. - * - * Version: @(#)if_tr.h 0.0 07/11/94 - * - * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> - * Donald Becker, <becker@super.org> - * Peter De Schrijver, <stud11@cc4.kuleuven.ac.be> - * - * 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 _LINUX_IF_TR_H -#define _LINUX_IF_TR_H - -#include <linux/types.h> -#include <asm/byteorder.h> /* For __be16 */ - -/* IEEE 802.5 Token-Ring magic constants. The frame sizes omit the preamble - and FCS/CRC (frame check sequence). */ -#define TR_ALEN 6 /* Octets in one token-ring addr */ -#define TR_HLEN (sizeof(struct trh_hdr)+sizeof(struct trllc)) -#define AC 0x10 -#define LLC_FRAME 0x40 - -/* LLC and SNAP constants */ -#define EXTENDED_SAP 0xAA -#define UI_CMD 0x03 - -/* This is an Token-Ring frame header. */ -struct trh_hdr { - __u8 ac; /* access control field */ - __u8 fc; /* frame control field */ - __u8 daddr[TR_ALEN]; /* destination address */ - __u8 saddr[TR_ALEN]; /* source address */ - __be16 rcf; /* route control field */ - __be16 rseg[8]; /* routing registers */ -}; - -#ifdef __KERNEL__ -#include <linux/skbuff.h> - -static inline struct trh_hdr *tr_hdr(const struct sk_buff *skb) -{ - return (struct trh_hdr *)skb_mac_header(skb); -} -#endif - -/* This is an Token-Ring LLC structure */ -struct trllc { - __u8 dsap; /* destination SAP */ - __u8 ssap; /* source SAP */ - __u8 llc; /* LLC control field */ - __u8 protid[3]; /* protocol id */ - __be16 ethertype; /* ether type field */ -}; - -/* Token-Ring statistics collection data. */ -struct tr_statistics { - unsigned long rx_packets; /* total packets received */ - unsigned long tx_packets; /* total packets transmitted */ - unsigned long rx_bytes; /* total bytes received */ - unsigned long tx_bytes; /* total bytes transmitted */ - unsigned long rx_errors; /* bad packets received */ - unsigned long tx_errors; /* packet transmit problems */ - unsigned long rx_dropped; /* no space in linux buffers */ - unsigned long tx_dropped; /* no space available in linux */ - unsigned long multicast; /* multicast packets received */ - unsigned long transmit_collision; - - /* detailed Token-Ring errors. See IBM Token-Ring Network - Architecture for more info */ - - unsigned long line_errors; - unsigned long internal_errors; - unsigned long burst_errors; - unsigned long A_C_errors; - unsigned long abort_delimiters; - unsigned long lost_frames; - unsigned long recv_congest_count; - unsigned long frame_copied_errors; - unsigned long frequency_errors; - unsigned long token_errors; - unsigned long dummy1; -}; - -/* source routing stuff */ -#define TR_RII 0x80 -#define TR_RCF_DIR_BIT 0x80 -#define TR_RCF_LEN_MASK 0x1f00 -#define TR_RCF_BROADCAST 0x8000 /* all-routes broadcast */ -#define TR_RCF_LIMITED_BROADCAST 0xC000 /* single-route broadcast */ -#define TR_RCF_FRAME2K 0x20 -#define TR_RCF_BROADCAST_MASK 0xC000 -#define TR_MAXRIFLEN 18 - -#endif /* _LINUX_IF_TR_H */
diff --git a/include/linux/in6.h b/include/linux/in6.h index 5c83d9e..cba469b 100644 --- a/include/linux/in6.h +++ b/include/linux/in6.h
@@ -142,7 +142,7 @@ /* * IPv6 TLV options. */ -#define IPV6_TLV_PAD0 0 +#define IPV6_TLV_PAD1 0 #define IPV6_TLV_PADN 1 #define IPV6_TLV_ROUTERALERT 5 #define IPV6_TLV_JUMBO 194
diff --git a/include/linux/ipx.h b/include/linux/ipx.h index 3d48014..8f02439 100644 --- a/include/linux/ipx.h +++ b/include/linux/ipx.h
@@ -38,7 +38,7 @@ #define IPX_FRAME_8022 2 #define IPX_FRAME_ETHERII 3 #define IPX_FRAME_8023 4 -#define IPX_FRAME_TR_8022 5 /* obsolete */ +/* obsolete token ring was 5 */ unsigned char ipx_special; #define IPX_SPECIAL_NONE 0 #define IPX_PRIMARY 1
diff --git a/include/linux/mISDNhw.h b/include/linux/mISDNhw.h index de165b5..d0752ec 100644 --- a/include/linux/mISDNhw.h +++ b/include/linux/mISDNhw.h
@@ -72,7 +72,9 @@ #define FLG_LL_OK 24 #define FLG_LL_CONN 25 #define FLG_DTMFSEND 26 - +#define FLG_TX_EMPTY 27 +/* stop sending received data upstream */ +#define FLG_RX_OFF 28 /* workq events */ #define FLG_RECVQUEUE 30 #define FLG_PHCHANGE 31 @@ -142,6 +144,7 @@ struct layer1; extern int l1_event(struct layer1 *, u_int); +#define MISDN_BCH_FILL_SIZE 4 struct bchannel { struct mISDNchannel ch; @@ -153,8 +156,14 @@ int slot; /* multiport card channel slot */ struct timer_list timer; /* receive data */ + u8 fill[MISDN_BCH_FILL_SIZE]; struct sk_buff *rx_skb; - int maxlen; + unsigned short maxlen; + unsigned short init_maxlen; /* initial value */ + unsigned short next_maxlen; /* pending value */ + unsigned short minlen; /* for transparent data */ + unsigned short init_minlen; /* initial value */ + unsigned short next_minlen; /* pending value */ /* send data */ struct sk_buff *next_skb; struct sk_buff *tx_skb; @@ -166,23 +175,26 @@ int err_crc; int err_tx; int err_rx; + int dropcnt; }; extern int mISDN_initdchannel(struct dchannel *, int, void *); -extern int mISDN_initbchannel(struct bchannel *, int); +extern int mISDN_initbchannel(struct bchannel *, unsigned short, + unsigned short); extern int mISDN_freedchannel(struct dchannel *); extern void mISDN_clear_bchannel(struct bchannel *); extern int mISDN_freebchannel(struct bchannel *); +extern int mISDN_ctrl_bchannel(struct bchannel *, struct mISDN_ctrl_req *); extern void queue_ch_frame(struct mISDNchannel *, u_int, int, struct sk_buff *); extern int dchannel_senddata(struct dchannel *, struct sk_buff *); extern int bchannel_senddata(struct bchannel *, struct sk_buff *); +extern int bchannel_get_rxbuf(struct bchannel *, int); extern void recv_Dchannel(struct dchannel *); extern void recv_Echannel(struct dchannel *, struct dchannel *); -extern void recv_Bchannel(struct bchannel *, unsigned int id); +extern void recv_Bchannel(struct bchannel *, unsigned int, bool); extern void recv_Dchannel_skb(struct dchannel *, struct sk_buff *); extern void recv_Bchannel_skb(struct bchannel *, struct sk_buff *); -extern void confirm_Bsend(struct bchannel *bch); extern int get_next_bframe(struct bchannel *); extern int get_next_dframe(struct dchannel *);
diff --git a/include/linux/mISDNif.h b/include/linux/mISDNif.h index ce6e613..246a352 100644 --- a/include/linux/mISDNif.h +++ b/include/linux/mISDNif.h
@@ -37,7 +37,7 @@ */ #define MISDN_MAJOR_VERSION 1 #define MISDN_MINOR_VERSION 1 -#define MISDN_RELEASE 28 +#define MISDN_RELEASE 29 /* primitives for information exchange * generell format @@ -365,6 +365,7 @@ #define MISDN_CTRL_LOOP 0x0001 #define MISDN_CTRL_CONNECT 0x0002 #define MISDN_CTRL_DISCONNECT 0x0004 +#define MISDN_CTRL_RX_BUFFER 0x0008 #define MISDN_CTRL_PCMCONNECT 0x0010 #define MISDN_CTRL_PCMDISCONNECT 0x0020 #define MISDN_CTRL_SETPEER 0x0040 @@ -387,6 +388,12 @@ #define MISDN_CTRL_HFC_WD_INIT 0x4009 #define MISDN_CTRL_HFC_WD_RESET 0x400A +/* special RX buffer value for MISDN_CTRL_RX_BUFFER request.p1 is the minimum + * buffer size request.p2 the maximum. Using MISDN_CTRL_RX_SIZE_IGNORE will + * not change the value, but still read back the actual stetting. + */ +#define MISDN_CTRL_RX_SIZE_IGNORE -1 + /* socket options */ #define MISDN_TIME_STAMP 0x0001
diff --git a/include/linux/mm.h b/include/linux/mm.h index 74aa71b..7d5c37f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h
@@ -896,10 +896,8 @@ unsigned long size); void zap_page_range(struct vm_area_struct *vma, unsigned long address, unsigned long size, struct zap_details *); -void unmap_vmas(struct mmu_gather *tlb, - struct vm_area_struct *start_vma, unsigned long start_addr, - unsigned long end_addr, unsigned long *nr_accounted, - struct zap_details *); +void unmap_vmas(struct mmu_gather *tlb, struct vm_area_struct *start_vma, + unsigned long start, unsigned long end); /** * mm_walk - callbacks for walk_page_range
diff --git a/include/linux/net.h b/include/linux/net.h index be60c7f..2d7510f 100644 --- a/include/linux/net.h +++ b/include/linux/net.h
@@ -250,6 +250,29 @@ #define sockfd_put(sock) fput(sock->file) extern int net_ratelimit(void); +#define net_ratelimited_function(function, ...) \ +do { \ + if (net_ratelimit()) \ + function(__VA_ARGS__); \ +} while (0) + +#define net_emerg_ratelimited(fmt, ...) \ + net_ratelimited_function(pr_emerg, fmt, ##__VA_ARGS__) +#define net_alert_ratelimited(fmt, ...) \ + net_ratelimited_function(pr_alert, fmt, ##__VA_ARGS__) +#define net_crit_ratelimited(fmt, ...) \ + net_ratelimited_function(pr_crit, fmt, ##__VA_ARGS__) +#define net_err_ratelimited(fmt, ...) \ + net_ratelimited_function(pr_err, fmt, ##__VA_ARGS__) +#define net_notice_ratelimited(fmt, ...) \ + net_ratelimited_function(pr_notice, fmt, ##__VA_ARGS__) +#define net_warn_ratelimited(fmt, ...) \ + net_ratelimited_function(pr_warn, fmt, ##__VA_ARGS__) +#define net_info_ratelimited(fmt, ...) \ + net_ratelimited_function(pr_info, fmt, ##__VA_ARGS__) +#define net_dbg_ratelimited(fmt, ...) \ + net_ratelimited_function(pr_debug, fmt, ##__VA_ARGS__) + #define net_random() random32() #define net_srandom(seed) srandom32((__force u32)seed)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 7f377fb..e7fd468 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h
@@ -1155,7 +1155,6 @@ struct in_device __rcu *ip_ptr; /* IPv4 specific data */ struct dn_dev __rcu *dn_ptr; /* DECnet specific data */ struct inet6_dev __rcu *ip6_ptr; /* IPv6 specific data */ - void *ec_ptr; /* Econet specific data */ void *ax25_ptr; /* AX.25 specific data */ struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data, assign before registering */ @@ -1426,15 +1425,6 @@ return 0; } -#ifndef CONFIG_NET_NS -static inline void skb_set_dev(struct sk_buff *skb, struct net_device *dev) -{ - skb->dev = dev; -} -#else /* CONFIG_NET_NS */ -void skb_set_dev(struct sk_buff *skb, struct net_device *dev); -#endif - static inline bool netdev_uses_trailer_tags(struct net_device *dev) { #ifdef CONFIG_NET_DSA_TAG_TRAILER @@ -2152,7 +2142,6 @@ extern gro_result_t napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, gro_result_t ret); -extern struct sk_buff * napi_frags_skb(struct napi_struct *napi); extern gro_result_t napi_gro_frags(struct napi_struct *napi); static inline void napi_free_frags(struct napi_struct *napi)
diff --git a/include/linux/netfilter/ipset/ip_set_ahash.h b/include/linux/netfilter/ipset/ip_set_ahash.h index 289b62d..b114d35 100644 --- a/include/linux/netfilter/ipset/ip_set_ahash.h +++ b/include/linux/netfilter/ipset/ip_set_ahash.h
@@ -99,6 +99,22 @@ #endif }; +static size_t +htable_size(u8 hbits) +{ + size_t hsize; + + /* We must fit both into u32 in jhash and size_t */ + if (hbits > 31) + return 0; + hsize = jhash_size(hbits); + if ((((size_t)-1) - sizeof(struct htable))/sizeof(struct hbucket) + < hsize) + return 0; + + return hsize * sizeof(struct hbucket) + sizeof(struct htable); +} + /* Compute htable_bits from the user input parameter hashsize */ static u8 htable_bits(u32 hashsize)
diff --git a/include/linux/netfilter/ipset/ip_set_timeout.h b/include/linux/netfilter/ipset/ip_set_timeout.h index 4792320..41d9cfa 100644 --- a/include/linux/netfilter/ipset/ip_set_timeout.h +++ b/include/linux/netfilter/ipset/ip_set_timeout.h
@@ -30,6 +30,10 @@ { unsigned int timeout = ip_set_get_h32(tb); + /* Normalize to fit into jiffies */ + if (timeout > UINT_MAX/MSEC_PER_SEC) + timeout = UINT_MAX/MSEC_PER_SEC; + /* Userspace supplied TIMEOUT parameter: adjust crazy size */ return timeout == IPSET_NO_TIMEOUT ? IPSET_NO_TIMEOUT - 1 : timeout; }
diff --git a/include/linux/netfilter/xt_HMARK.h b/include/linux/netfilter/xt_HMARK.h new file mode 100644 index 0000000..abb1650 --- /dev/null +++ b/include/linux/netfilter/xt_HMARK.h
@@ -0,0 +1,45 @@ +#ifndef XT_HMARK_H_ +#define XT_HMARK_H_ + +#include <linux/types.h> + +enum { + XT_HMARK_SADDR_MASK, + XT_HMARK_DADDR_MASK, + XT_HMARK_SPI, + XT_HMARK_SPI_MASK, + XT_HMARK_SPORT, + XT_HMARK_DPORT, + XT_HMARK_SPORT_MASK, + XT_HMARK_DPORT_MASK, + XT_HMARK_PROTO_MASK, + XT_HMARK_RND, + XT_HMARK_MODULUS, + XT_HMARK_OFFSET, + XT_HMARK_CT, + XT_HMARK_METHOD_L3, + XT_HMARK_METHOD_L3_4, +}; +#define XT_HMARK_FLAG(flag) (1 << flag) + +union hmark_ports { + struct { + __u16 src; + __u16 dst; + } p16; + __u32 v32; +}; + +struct xt_hmark_info { + union nf_inet_addr src_mask; + union nf_inet_addr dst_mask; + union hmark_ports port_mask; + union hmark_ports port_set; + __u32 flags; + __u16 proto_mask; + __u32 hashrnd; + __u32 hmodulus; + __u32 hoffset; /* Mark offset to start from */ +}; + +#endif /* XT_HMARK_H_ */
diff --git a/include/linux/netfilter/xt_hashlimit.h b/include/linux/netfilter/xt_hashlimit.h index b1925b5..c42e52f 100644 --- a/include/linux/netfilter/xt_hashlimit.h +++ b/include/linux/netfilter/xt_hashlimit.h
@@ -6,7 +6,11 @@ /* timings are in milliseconds. */ #define XT_HASHLIMIT_SCALE 10000 /* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490 - seconds, or one every 59 hours. */ + * seconds, or one packet every 59 hours. + */ + +/* packet length accounting is done in 16-byte steps */ +#define XT_HASHLIMIT_BYTE_SHIFT 4 /* details of this structure hidden by the implementation */ struct xt_hashlimit_htable; @@ -17,7 +21,13 @@ XT_HASHLIMIT_HASH_SIP = 1 << 2, XT_HASHLIMIT_HASH_SPT = 1 << 3, XT_HASHLIMIT_INVERT = 1 << 4, + XT_HASHLIMIT_BYTES = 1 << 5, }; +#ifdef __KERNEL__ +#define XT_HASHLIMIT_ALL (XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT | \ + XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT | \ + XT_HASHLIMIT_INVERT | XT_HASHLIMIT_BYTES) +#endif struct hashlimit_cfg { __u32 mode; /* bitmask of XT_HASHLIMIT_HASH_* */
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h index 1bc898b..08c2cbb 100644 --- a/include/linux/netfilter_ipv6/ip6_tables.h +++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -298,9 +298,14 @@ (nexthdr == IPPROTO_DSTOPTS); } +enum { + IP6T_FH_F_FRAG = (1 << 0), + IP6T_FH_F_AUTH = (1 << 1), +}; + /* find specified header and get offset to it */ extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, - int target, unsigned short *fragoff); + int target, unsigned short *fragoff, int *fragflg); #ifdef CONFIG_COMPAT #include <net/compat.h>
diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h index 33d9f51..5a3db3a 100644 --- a/include/linux/nl802154.h +++ b/include/linux/nl802154.h
@@ -68,6 +68,7 @@ IEEE802154_ATTR_CHANNEL_PAGE_LIST, IEEE802154_ATTR_PHY_NAME, + IEEE802154_ATTR_DEV_TYPE, __IEEE802154_ATTR_MAX, }; @@ -126,4 +127,23 @@ #define IEEE802154_CMD_MAX (__IEEE802154_CMD_MAX - 1) +enum { + __IEEE802154_DEV_INVALID = -1, + + /* TODO: + * Nowadays three device types supported by this stack at linux-zigbee + * project: WPAN = 0, MONITOR = 1 and SMAC = 2. + * + * Since this stack implementation exists many years, it's definitely + * bad idea to change the assigned values due to they are already used + * by third-party userspace software like: iz-tools, wireshark... + * + * Currently only monitor device is added and initialized by '1' for + * compatibility. + */ + IEEE802154_DEV_MONITOR = 1, + + __IEEE802154_DEV_MAX, +}; + #endif
diff --git a/include/linux/phy.h b/include/linux/phy.h index f092032..c291cae 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h
@@ -480,7 +480,6 @@ return mdiobus_write(phydev->bus, phydev->addr, regnum, val); } -int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id); struct phy_device* get_phy_device(struct mii_bus *bus, int addr); int phy_device_register(struct phy_device *phy); int phy_init_hw(struct phy_device *phydev);
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index ffe975c..32aef0a 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h
@@ -655,4 +655,84 @@ __u32 lmax; }; +/* CODEL */ + +enum { + TCA_CODEL_UNSPEC, + TCA_CODEL_TARGET, + TCA_CODEL_LIMIT, + TCA_CODEL_INTERVAL, + TCA_CODEL_ECN, + __TCA_CODEL_MAX +}; + +#define TCA_CODEL_MAX (__TCA_CODEL_MAX - 1) + +struct tc_codel_xstats { + __u32 maxpacket; /* largest packet we've seen so far */ + __u32 count; /* how many drops we've done since the last time we + * entered dropping state + */ + __u32 lastcount; /* count at entry to dropping state */ + __u32 ldelay; /* in-queue delay seen by most recently dequeued packet */ + __s32 drop_next; /* time to drop next packet */ + __u32 drop_overlimit; /* number of time max qdisc packet limit was hit */ + __u32 ecn_mark; /* number of packets we ECN marked instead of dropped */ + __u32 dropping; /* are we in dropping state ? */ +}; + +/* FQ_CODEL */ + +enum { + TCA_FQ_CODEL_UNSPEC, + TCA_FQ_CODEL_TARGET, + TCA_FQ_CODEL_LIMIT, + TCA_FQ_CODEL_INTERVAL, + TCA_FQ_CODEL_ECN, + TCA_FQ_CODEL_FLOWS, + TCA_FQ_CODEL_QUANTUM, + __TCA_FQ_CODEL_MAX +}; + +#define TCA_FQ_CODEL_MAX (__TCA_FQ_CODEL_MAX - 1) + +enum { + TCA_FQ_CODEL_XSTATS_QDISC, + TCA_FQ_CODEL_XSTATS_CLASS, +}; + +struct tc_fq_codel_qd_stats { + __u32 maxpacket; /* largest packet we've seen so far */ + __u32 drop_overlimit; /* number of time max qdisc + * packet limit was hit + */ + __u32 ecn_mark; /* number of packets we ECN marked + * instead of being dropped + */ + __u32 new_flow_count; /* number of time packets + * created a 'new flow' + */ + __u32 new_flows_len; /* count of flows in new list */ + __u32 old_flows_len; /* count of flows in old list */ +}; + +struct tc_fq_codel_cl_stats { + __s32 deficit; + __u32 ldelay; /* in-queue delay seen by most recently + * dequeued packet + */ + __u32 count; + __u32 lastcount; + __u32 dropping; + __s32 drop_next; +}; + +struct tc_fq_codel_xstats { + __u32 type; + union { + struct tc_fq_codel_qd_stats qdisc_stats; + struct tc_fq_codel_cl_stats class_stats; + }; +}; + #endif
diff --git a/include/linux/rndis.h b/include/linux/rndis.h new file mode 100644 index 0000000..0c8dc71 --- /dev/null +++ b/include/linux/rndis.h
@@ -0,0 +1,390 @@ +/* + * Remote Network Driver Interface Specification (RNDIS) + * definitions of the magic numbers used by this protocol + */ + +/* Remote NDIS Versions */ +#define RNDIS_MAJOR_VERSION 0x00000001 +#define RNDIS_MINOR_VERSION 0x00000000 + +/* Device Flags */ +#define RNDIS_DF_CONNECTIONLESS 0x00000001U +#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002U +#define RNDIS_DF_RAW_DATA 0x00000004U + +/* + * Codes for "msg_type" field of rndis messages; + * only the data channel uses packet messages (maybe batched); + * everything else goes on the control channel. + */ +#define RNDIS_MSG_COMPLETION 0x80000000 +#define RNDIS_MSG_PACKET 0x00000001 /* 1-N packets */ +#define RNDIS_MSG_INIT 0x00000002 +#define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_HALT 0x00000003 +#define RNDIS_MSG_QUERY 0x00000004 +#define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_SET 0x00000005 +#define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_RESET 0x00000006 +#define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_INDICATE 0x00000007 +#define RNDIS_MSG_KEEPALIVE 0x00000008 +#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION) +/* + * Reserved message type for private communication between lower-layer host + * driver and remote device, if necessary. + */ +#define RNDIS_MSG_BUS 0xff000001 + +/* codes for "status" field of completion messages */ +#define RNDIS_STATUS_SUCCESS 0x00000000 +#define RNDIS_STATUS_PENDING 0x00000103 + +/* Status codes */ +#define RNDIS_STATUS_NOT_RECOGNIZED 0x00010001 +#define RNDIS_STATUS_NOT_COPIED 0x00010002 +#define RNDIS_STATUS_NOT_ACCEPTED 0x00010003 +#define RNDIS_STATUS_CALL_ACTIVE 0x00010007 + +#define RNDIS_STATUS_ONLINE 0x40010003 +#define RNDIS_STATUS_RESET_START 0x40010004 +#define RNDIS_STATUS_RESET_END 0x40010005 +#define RNDIS_STATUS_RING_STATUS 0x40010006 +#define RNDIS_STATUS_CLOSED 0x40010007 +#define RNDIS_STATUS_WAN_LINE_UP 0x40010008 +#define RNDIS_STATUS_WAN_LINE_DOWN 0x40010009 +#define RNDIS_STATUS_WAN_FRAGMENT 0x4001000A +#define RNDIS_STATUS_MEDIA_CONNECT 0x4001000B +#define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000C +#define RNDIS_STATUS_HARDWARE_LINE_UP 0x4001000D +#define RNDIS_STATUS_HARDWARE_LINE_DOWN 0x4001000E +#define RNDIS_STATUS_INTERFACE_UP 0x4001000F +#define RNDIS_STATUS_INTERFACE_DOWN 0x40010010 +#define RNDIS_STATUS_MEDIA_BUSY 0x40010011 +#define RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION 0x40010012 +#define RNDIS_STATUS_WW_INDICATION RDIA_SPECIFIC_INDICATION +#define RNDIS_STATUS_LINK_SPEED_CHANGE 0x40010013L + +#define RNDIS_STATUS_NOT_RESETTABLE 0x80010001 +#define RNDIS_STATUS_SOFT_ERRORS 0x80010003 +#define RNDIS_STATUS_HARD_ERRORS 0x80010004 +#define RNDIS_STATUS_BUFFER_OVERFLOW 0x80000005 + +#define RNDIS_STATUS_FAILURE 0xC0000001 +#define RNDIS_STATUS_RESOURCES 0xC000009A +#define RNDIS_STATUS_NOT_SUPPORTED 0xc00000BB +#define RNDIS_STATUS_CLOSING 0xC0010002 +#define RNDIS_STATUS_BAD_VERSION 0xC0010004 +#define RNDIS_STATUS_BAD_CHARACTERISTICS 0xC0010005 +#define RNDIS_STATUS_ADAPTER_NOT_FOUND 0xC0010006 +#define RNDIS_STATUS_OPEN_FAILED 0xC0010007 +#define RNDIS_STATUS_DEVICE_FAILED 0xC0010008 +#define RNDIS_STATUS_MULTICAST_FULL 0xC0010009 +#define RNDIS_STATUS_MULTICAST_EXISTS 0xC001000A +#define RNDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B +#define RNDIS_STATUS_REQUEST_ABORTED 0xC001000C +#define RNDIS_STATUS_RESET_IN_PROGRESS 0xC001000D +#define RNDIS_STATUS_CLOSING_INDICATING 0xC001000E +#define RNDIS_STATUS_INVALID_PACKET 0xC001000F +#define RNDIS_STATUS_OPEN_LIST_FULL 0xC0010010 +#define RNDIS_STATUS_ADAPTER_NOT_READY 0xC0010011 +#define RNDIS_STATUS_ADAPTER_NOT_OPEN 0xC0010012 +#define RNDIS_STATUS_NOT_INDICATING 0xC0010013 +#define RNDIS_STATUS_INVALID_LENGTH 0xC0010014 +#define RNDIS_STATUS_INVALID_DATA 0xC0010015 +#define RNDIS_STATUS_BUFFER_TOO_SHORT 0xC0010016 +#define RNDIS_STATUS_INVALID_OID 0xC0010017 +#define RNDIS_STATUS_ADAPTER_REMOVED 0xC0010018 +#define RNDIS_STATUS_UNSUPPORTED_MEDIA 0xC0010019 +#define RNDIS_STATUS_GROUP_ADDRESS_IN_USE 0xC001001A +#define RNDIS_STATUS_FILE_NOT_FOUND 0xC001001B +#define RNDIS_STATUS_ERROR_READING_FILE 0xC001001C +#define RNDIS_STATUS_ALREADY_MAPPED 0xC001001D +#define RNDIS_STATUS_RESOURCE_CONFLICT 0xC001001E +#define RNDIS_STATUS_NO_CABLE 0xC001001F + +#define RNDIS_STATUS_INVALID_SAP 0xC0010020 +#define RNDIS_STATUS_SAP_IN_USE 0xC0010021 +#define RNDIS_STATUS_INVALID_ADDRESS 0xC0010022 +#define RNDIS_STATUS_VC_NOT_ACTIVATED 0xC0010023 +#define RNDIS_STATUS_DEST_OUT_OF_ORDER 0xC0010024 +#define RNDIS_STATUS_VC_NOT_AVAILABLE 0xC0010025 +#define RNDIS_STATUS_CELLRATE_NOT_AVAILABLE 0xC0010026 +#define RNDIS_STATUS_INCOMPATABLE_QOS 0xC0010027 +#define RNDIS_STATUS_AAL_PARAMS_UNSUPPORTED 0xC0010028 +#define RNDIS_STATUS_NO_ROUTE_TO_DESTINATION 0xC0010029 + +#define RNDIS_STATUS_TOKEN_RING_OPEN_ERROR 0xC0011000 + +/* codes for RNDIS_OID_GEN_PHYSICAL_MEDIUM */ +#define RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED 0x00000000 +#define RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN 0x00000001 +#define RNDIS_PHYSICAL_MEDIUM_CABLE_MODEM 0x00000002 +#define RNDIS_PHYSICAL_MEDIUM_PHONE_LINE 0x00000003 +#define RNDIS_PHYSICAL_MEDIUM_POWER_LINE 0x00000004 +#define RNDIS_PHYSICAL_MEDIUM_DSL 0x00000005 +#define RNDIS_PHYSICAL_MEDIUM_FIBRE_CHANNEL 0x00000006 +#define RNDIS_PHYSICAL_MEDIUM_1394 0x00000007 +#define RNDIS_PHYSICAL_MEDIUM_WIRELESS_WAN 0x00000008 +#define RNDIS_PHYSICAL_MEDIUM_MAX 0x00000009 + +/* Remote NDIS medium types. */ +#define RNDIS_MEDIUM_UNSPECIFIED 0x00000000 +#define RNDIS_MEDIUM_802_3 0x00000000 +#define RNDIS_MEDIUM_802_5 0x00000001 +#define RNDIS_MEDIUM_FDDI 0x00000002 +#define RNDIS_MEDIUM_WAN 0x00000003 +#define RNDIS_MEDIUM_LOCAL_TALK 0x00000004 +#define RNDIS_MEDIUM_ARCNET_RAW 0x00000006 +#define RNDIS_MEDIUM_ARCNET_878_2 0x00000007 +#define RNDIS_MEDIUM_ATM 0x00000008 +#define RNDIS_MEDIUM_WIRELESS_LAN 0x00000009 +#define RNDIS_MEDIUM_IRDA 0x0000000A +#define RNDIS_MEDIUM_BPC 0x0000000B +#define RNDIS_MEDIUM_CO_WAN 0x0000000C +#define RNDIS_MEDIUM_1394 0x0000000D +/* Not a real medium, defined as an upper-bound */ +#define RNDIS_MEDIUM_MAX 0x0000000E + +/* Remote NDIS medium connection states. */ +#define RNDIS_MEDIA_STATE_CONNECTED 0x00000000 +#define RNDIS_MEDIA_STATE_DISCONNECTED 0x00000001 + +/* packet filter bits used by RNDIS_OID_GEN_CURRENT_PACKET_FILTER */ +#define RNDIS_PACKET_TYPE_DIRECTED 0x00000001 +#define RNDIS_PACKET_TYPE_MULTICAST 0x00000002 +#define RNDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 +#define RNDIS_PACKET_TYPE_BROADCAST 0x00000008 +#define RNDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 +#define RNDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 +#define RNDIS_PACKET_TYPE_SMT 0x00000040 +#define RNDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 +#define RNDIS_PACKET_TYPE_GROUP 0x00001000 +#define RNDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00002000 +#define RNDIS_PACKET_TYPE_FUNCTIONAL 0x00004000 +#define RNDIS_PACKET_TYPE_MAC_FRAME 0x00008000 + +/* RNDIS_OID_GEN_MINIPORT_INFO constants */ +#define RNDIS_MINIPORT_BUS_MASTER 0x00000001 +#define RNDIS_MINIPORT_WDM_DRIVER 0x00000002 +#define RNDIS_MINIPORT_SG_LIST 0x00000004 +#define RNDIS_MINIPORT_SUPPORTS_MEDIA_QUERY 0x00000008 +#define RNDIS_MINIPORT_INDICATES_PACKETS 0x00000010 +#define RNDIS_MINIPORT_IGNORE_PACKET_QUEUE 0x00000020 +#define RNDIS_MINIPORT_IGNORE_REQUEST_QUEUE 0x00000040 +#define RNDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00000080 +#define RNDIS_MINIPORT_INTERMEDIATE_DRIVER 0x00000100 +#define RNDIS_MINIPORT_IS_NDIS_5 0x00000200 +#define RNDIS_MINIPORT_IS_CO 0x00000400 +#define RNDIS_MINIPORT_DESERIALIZE 0x00000800 +#define RNDIS_MINIPORT_REQUIRES_MEDIA_POLLING 0x00001000 +#define RNDIS_MINIPORT_SUPPORTS_MEDIA_SENSE 0x00002000 +#define RNDIS_MINIPORT_NETBOOT_CARD 0x00004000 +#define RNDIS_MINIPORT_PM_SUPPORTED 0x00008000 +#define RNDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00010000 +#define RNDIS_MINIPORT_USES_SAFE_BUFFER_APIS 0x00020000 +#define RNDIS_MINIPORT_HIDDEN 0x00040000 +#define RNDIS_MINIPORT_SWENUM 0x00080000 +#define RNDIS_MINIPORT_SURPRISE_REMOVE_OK 0x00100000 +#define RNDIS_MINIPORT_NO_HALT_ON_SUSPEND 0x00200000 +#define RNDIS_MINIPORT_HARDWARE_DEVICE 0x00400000 +#define RNDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS 0x00800000 +#define RNDIS_MINIPORT_64BITS_DMA 0x01000000 + +#define RNDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 +#define RNDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 +#define RNDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 +#define RNDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 +#define RNDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 +#define RNDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 +#define RNDIS_MAC_OPTION_8021P_PRIORITY 0x00000040 +#define RNDIS_MAC_OPTION_RESERVED 0x80000000 + +/* Object Identifiers used by NdisRequest Query/Set Information */ +/* General (Required) Objects */ +#define RNDIS_OID_GEN_SUPPORTED_LIST 0x00010101 +#define RNDIS_OID_GEN_HARDWARE_STATUS 0x00010102 +#define RNDIS_OID_GEN_MEDIA_SUPPORTED 0x00010103 +#define RNDIS_OID_GEN_MEDIA_IN_USE 0x00010104 +#define RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 +#define RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 +#define RNDIS_OID_GEN_LINK_SPEED 0x00010107 +#define RNDIS_OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 +#define RNDIS_OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 +#define RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A +#define RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B +#define RNDIS_OID_GEN_VENDOR_ID 0x0001010C +#define RNDIS_OID_GEN_VENDOR_DESCRIPTION 0x0001010D +#define RNDIS_OID_GEN_CURRENT_PACKET_FILTER 0x0001010E +#define RNDIS_OID_GEN_CURRENT_LOOKAHEAD 0x0001010F +#define RNDIS_OID_GEN_DRIVER_VERSION 0x00010110 +#define RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 +#define RNDIS_OID_GEN_PROTOCOL_OPTIONS 0x00010112 +#define RNDIS_OID_GEN_MAC_OPTIONS 0x00010113 +#define RNDIS_OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 +#define RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 +#define RNDIS_OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 +#define RNDIS_OID_GEN_SUPPORTED_GUIDS 0x00010117 +#define RNDIS_OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 +#define RNDIS_OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 +#define RNDIS_OID_GEN_PHYSICAL_MEDIUM 0x00010202 +#define RNDIS_OID_GEN_MACHINE_NAME 0x0001021A +#define RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B +#define RNDIS_OID_GEN_VLAN_ID 0x0001021C + +/* Optional OIDs */ +#define RNDIS_OID_GEN_MEDIA_CAPABILITIES 0x00010201 + +/* Required statistics OIDs */ +#define RNDIS_OID_GEN_XMIT_OK 0x00020101 +#define RNDIS_OID_GEN_RCV_OK 0x00020102 +#define RNDIS_OID_GEN_XMIT_ERROR 0x00020103 +#define RNDIS_OID_GEN_RCV_ERROR 0x00020104 +#define RNDIS_OID_GEN_RCV_NO_BUFFER 0x00020105 + +/* Optional statistics OIDs */ +#define RNDIS_OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 +#define RNDIS_OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 +#define RNDIS_OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 +#define RNDIS_OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 +#define RNDIS_OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 +#define RNDIS_OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 +#define RNDIS_OID_GEN_DIRECTED_BYTES_RCV 0x00020207 +#define RNDIS_OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 +#define RNDIS_OID_GEN_MULTICAST_BYTES_RCV 0x00020209 +#define RNDIS_OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A +#define RNDIS_OID_GEN_BROADCAST_BYTES_RCV 0x0002020B +#define RNDIS_OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C + +#define RNDIS_OID_GEN_RCV_CRC_ERROR 0x0002020D +#define RNDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E + +#define RNDIS_OID_GEN_GET_TIME_CAPS 0x0002020F +#define RNDIS_OID_GEN_GET_NETCARD_TIME 0x00020210 + +#define RNDIS_OID_GEN_NETCARD_LOAD 0x00020211 +#define RNDIS_OID_GEN_DEVICE_PROFILE 0x00020212 +#define RNDIS_OID_GEN_INIT_TIME_MS 0x00020213 +#define RNDIS_OID_GEN_RESET_COUNTS 0x00020214 +#define RNDIS_OID_GEN_MEDIA_SENSE_COUNTS 0x00020215 +#define RNDIS_OID_GEN_FRIENDLY_NAME 0x00020216 +#define RNDIS_OID_GEN_MINIPORT_INFO 0x00020217 +#define RNDIS_OID_GEN_RESET_VERIFY_PARAMETERS 0x00020218 + +/* These are connection-oriented general OIDs. */ +/* These replace the above OIDs for connection-oriented media. */ +#define RNDIS_OID_GEN_CO_SUPPORTED_LIST 0x00010101 +#define RNDIS_OID_GEN_CO_HARDWARE_STATUS 0x00010102 +#define RNDIS_OID_GEN_CO_MEDIA_SUPPORTED 0x00010103 +#define RNDIS_OID_GEN_CO_MEDIA_IN_USE 0x00010104 +#define RNDIS_OID_GEN_CO_LINK_SPEED 0x00010105 +#define RNDIS_OID_GEN_CO_VENDOR_ID 0x00010106 +#define RNDIS_OID_GEN_CO_VENDOR_DESCRIPTION 0x00010107 +#define RNDIS_OID_GEN_CO_DRIVER_VERSION 0x00010108 +#define RNDIS_OID_GEN_CO_PROTOCOL_OPTIONS 0x00010109 +#define RNDIS_OID_GEN_CO_MAC_OPTIONS 0x0001010A +#define RNDIS_OID_GEN_CO_MEDIA_CONNECT_STATUS 0x0001010B +#define RNDIS_OID_GEN_CO_VENDOR_DRIVER_VERSION 0x0001010C +#define RNDIS_OID_GEN_CO_MINIMUM_LINK_SPEED 0x0001010D + +#define RNDIS_OID_GEN_CO_GET_TIME_CAPS 0x00010201 +#define RNDIS_OID_GEN_CO_GET_NETCARD_TIME 0x00010202 + +/* These are connection-oriented statistics OIDs. */ +#define RNDIS_OID_GEN_CO_XMIT_PDUS_OK 0x00020101 +#define RNDIS_OID_GEN_CO_RCV_PDUS_OK 0x00020102 +#define RNDIS_OID_GEN_CO_XMIT_PDUS_ERROR 0x00020103 +#define RNDIS_OID_GEN_CO_RCV_PDUS_ERROR 0x00020104 +#define RNDIS_OID_GEN_CO_RCV_PDUS_NO_BUFFER 0x00020105 + + +#define RNDIS_OID_GEN_CO_RCV_CRC_ERROR 0x00020201 +#define RNDIS_OID_GEN_CO_TRANSMIT_QUEUE_LENGTH 0x00020202 +#define RNDIS_OID_GEN_CO_BYTES_XMIT 0x00020203 +#define RNDIS_OID_GEN_CO_BYTES_RCV 0x00020204 +#define RNDIS_OID_GEN_CO_BYTES_XMIT_OUTSTANDING 0x00020205 +#define RNDIS_OID_GEN_CO_NETCARD_LOAD 0x00020206 + +/* These are objects for Connection-oriented media call-managers. */ +#define RNDIS_OID_CO_ADD_PVC 0xFF000001 +#define RNDIS_OID_CO_DELETE_PVC 0xFF000002 +#define RNDIS_OID_CO_GET_CALL_INFORMATION 0xFF000003 +#define RNDIS_OID_CO_ADD_ADDRESS 0xFF000004 +#define RNDIS_OID_CO_DELETE_ADDRESS 0xFF000005 +#define RNDIS_OID_CO_GET_ADDRESSES 0xFF000006 +#define RNDIS_OID_CO_ADDRESS_CHANGE 0xFF000007 +#define RNDIS_OID_CO_SIGNALING_ENABLED 0xFF000008 +#define RNDIS_OID_CO_SIGNALING_DISABLED 0xFF000009 + +/* 802.3 Objects (Ethernet) */ +#define RNDIS_OID_802_3_PERMANENT_ADDRESS 0x01010101 +#define RNDIS_OID_802_3_CURRENT_ADDRESS 0x01010102 +#define RNDIS_OID_802_3_MULTICAST_LIST 0x01010103 +#define RNDIS_OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 +#define RNDIS_OID_802_3_MAC_OPTIONS 0x01010105 + +#define RNDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 + +#define RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 +#define RNDIS_OID_802_3_XMIT_ONE_COLLISION 0x01020102 +#define RNDIS_OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 + +#define RNDIS_OID_802_3_XMIT_DEFERRED 0x01020201 +#define RNDIS_OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 +#define RNDIS_OID_802_3_RCV_OVERRUN 0x01020203 +#define RNDIS_OID_802_3_XMIT_UNDERRUN 0x01020204 +#define RNDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 +#define RNDIS_OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 +#define RNDIS_OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 + +#define RNDIS_OID_802_11_BSSID 0x0d010101 +#define RNDIS_OID_802_11_SSID 0x0d010102 +#define RNDIS_OID_802_11_INFRASTRUCTURE_MODE 0x0d010108 +#define RNDIS_OID_802_11_ADD_WEP 0x0d010113 +#define RNDIS_OID_802_11_REMOVE_WEP 0x0d010114 +#define RNDIS_OID_802_11_DISASSOCIATE 0x0d010115 +#define RNDIS_OID_802_11_AUTHENTICATION_MODE 0x0d010118 +#define RNDIS_OID_802_11_PRIVACY_FILTER 0x0d010119 +#define RNDIS_OID_802_11_BSSID_LIST_SCAN 0x0d01011a +#define RNDIS_OID_802_11_ENCRYPTION_STATUS 0x0d01011b +#define RNDIS_OID_802_11_ADD_KEY 0x0d01011d +#define RNDIS_OID_802_11_REMOVE_KEY 0x0d01011e +#define RNDIS_OID_802_11_ASSOCIATION_INFORMATION 0x0d01011f +#define RNDIS_OID_802_11_CAPABILITY 0x0d010122 +#define RNDIS_OID_802_11_PMKID 0x0d010123 +#define RNDIS_OID_802_11_NETWORK_TYPES_SUPPORTED 0x0d010203 +#define RNDIS_OID_802_11_NETWORK_TYPE_IN_USE 0x0d010204 +#define RNDIS_OID_802_11_TX_POWER_LEVEL 0x0d010205 +#define RNDIS_OID_802_11_RSSI 0x0d010206 +#define RNDIS_OID_802_11_RSSI_TRIGGER 0x0d010207 +#define RNDIS_OID_802_11_FRAGMENTATION_THRESHOLD 0x0d010209 +#define RNDIS_OID_802_11_RTS_THRESHOLD 0x0d01020a +#define RNDIS_OID_802_11_SUPPORTED_RATES 0x0d01020e +#define RNDIS_OID_802_11_CONFIGURATION 0x0d010211 +#define RNDIS_OID_802_11_POWER_MODE 0x0d010216 +#define RNDIS_OID_802_11_BSSID_LIST 0x0d010217 + +/* Plug and Play capabilities */ +#define RNDIS_OID_PNP_CAPABILITIES 0xFD010100 +#define RNDIS_OID_PNP_SET_POWER 0xFD010101 +#define RNDIS_OID_PNP_QUERY_POWER 0xFD010102 +#define RNDIS_OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 +#define RNDIS_OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 +#define RNDIS_OID_PNP_ENABLE_WAKE_UP 0xFD010106 + +/* RNDIS_PNP_CAPABILITIES.Flags constants */ +#define RNDIS_DEVICE_WAKE_UP_ENABLE 0x00000001 +#define RNDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 +#define RNDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 + +#define REMOTE_CONDIS_MP_CREATE_VC_MSG 0x00008001 +#define REMOTE_CONDIS_MP_DELETE_VC_MSG 0x00008002 +#define REMOTE_CONDIS_MP_ACTIVATE_VC_MSG 0x00008005 +#define REMOTE_CONDIS_MP_DEACTIVATE_VC_MSG 0x00008006 +#define REMOTE_CONDIS_INDICATE_STATUS_MSG 0x00008007 + +#define REMOTE_CONDIS_MP_CREATE_VC_CMPLT 0x80008001 +#define REMOTE_CONDIS_MP_DELETE_VC_CMPLT 0x80008002 +#define REMOTE_CONDIS_MP_ACTIVATE_VC_CMPLT 0x80008005 +#define REMOTE_CONDIS_MP_DEACTIVATE_VC_CMPLT 0x80008006
diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h index c6db9fb..600060e2 100644 --- a/include/linux/seqlock.h +++ b/include/linux/seqlock.h
@@ -141,7 +141,7 @@ unsigned ret; repeat: - ret = s->sequence; + ret = ACCESS_ONCE(s->sequence); if (unlikely(ret & 1)) { cpu_relax(); goto repeat; @@ -166,6 +166,27 @@ } /** + * raw_seqcount_begin - begin a seq-read critical section + * @s: pointer to seqcount_t + * Returns: count to be passed to read_seqcount_retry + * + * raw_seqcount_begin opens a read critical section of the given seqcount. + * Validity of the critical section is tested by checking read_seqcount_retry + * function. + * + * Unlike read_seqcount_begin(), this function will not wait for the count + * to stabilize. If a writer is active when we begin, we will fail the + * read_seqcount_retry() instead of stabilizing at the beginning of the + * critical section. + */ +static inline unsigned raw_seqcount_begin(const seqcount_t *s) +{ + unsigned ret = ACCESS_ONCE(s->sequence); + smp_rmb(); + return ret & ~1; +} + +/** * __read_seqcount_retry - end a seq-read critical section (without barrier) * @s: pointer to seqcount_t * @start: count, from read_seqcount_begin
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index bb47314..0e50171 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h
@@ -562,6 +562,11 @@ extern void consume_skb(struct sk_buff *skb); extern void __kfree_skb(struct sk_buff *skb); extern struct kmem_cache *skbuff_head_cache; + +extern void kfree_skb_partial(struct sk_buff *skb, bool head_stolen); +extern bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, + bool *fragstolen, int *delta_truesize); + extern struct sk_buff *__alloc_skb(unsigned int size, gfp_t priority, int fclone, int node); extern struct sk_buff *build_skb(void *data, unsigned int frag_size); @@ -1680,31 +1685,11 @@ kfree_skb(skb); } -/** - * __dev_alloc_skb - allocate an skbuff for receiving - * @length: length to allocate - * @gfp_mask: get_free_pages mask, passed to alloc_skb - * - * Allocate a new &sk_buff and assign it a usage count of one. The - * buffer has unspecified headroom built in. Users should allocate - * the headroom they think they need without accounting for the - * built in space. The built in space is used for optimisations. - * - * %NULL is returned if there is no free memory. - */ -static inline struct sk_buff *__dev_alloc_skb(unsigned int length, - gfp_t gfp_mask) -{ - struct sk_buff *skb = alloc_skb(length + NET_SKB_PAD, gfp_mask); - if (likely(skb)) - skb_reserve(skb, NET_SKB_PAD); - return skb; -} - -extern struct sk_buff *dev_alloc_skb(unsigned int length); +extern void *netdev_alloc_frag(unsigned int fragsz); extern struct sk_buff *__netdev_alloc_skb(struct net_device *dev, - unsigned int length, gfp_t gfp_mask); + unsigned int length, + gfp_t gfp_mask); /** * netdev_alloc_skb - allocate an skbuff for rx on a specific device @@ -1720,11 +1705,25 @@ * allocates memory it can be called from an interrupt. */ static inline struct sk_buff *netdev_alloc_skb(struct net_device *dev, - unsigned int length) + unsigned int length) { return __netdev_alloc_skb(dev, length, GFP_ATOMIC); } +/* legacy helper around __netdev_alloc_skb() */ +static inline struct sk_buff *__dev_alloc_skb(unsigned int length, + gfp_t gfp_mask) +{ + return __netdev_alloc_skb(NULL, length, gfp_mask); +} + +/* legacy helper around netdev_alloc_skb() */ +static inline struct sk_buff *dev_alloc_skb(unsigned int length) +{ + return netdev_alloc_skb(NULL, length); +} + + static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, unsigned int length, gfp_t gfp) {
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index f85c93d..b69bdb1 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h
@@ -86,6 +86,7 @@ struct stmmac_dma_cfg { int pbl; int fixed_burst; + int mixed_burst; int burst_len; };
diff --git a/include/linux/trdevice.h b/include/linux/trdevice.h deleted file mode 100644 index bfc84a7..0000000 --- a/include/linux/trdevice.h +++ /dev/null
@@ -1,37 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. NET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * Definitions for the Token-ring handlers. - * - * Version: @(#)eth.h 1.0.4 05/13/93 - * - * Authors: Ross Biro - * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> - * - * Relocated to include/linux where it belongs by Alan Cox - * <gw4pts@gw4pts.ampr.org> - * - * 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. - * - * WARNING: This move may well be temporary. This file will get merged with others RSN. - * - */ -#ifndef _LINUX_TRDEVICE_H -#define _LINUX_TRDEVICE_H - - -#include <linux/if_tr.h> - -#ifdef __KERNEL__ -extern __be16 tr_type_trans(struct sk_buff *skb, struct net_device *dev); -extern void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh, struct net_device *dev); -extern struct net_device *alloc_trdev(int sizeof_priv); - -#endif - -#endif /* _LINUX_TRDEVICE_H */
diff --git a/include/linux/usb/rndis_host.h b/include/linux/usb/rndis_host.h index 88fceb7..d44ef85 100644 --- a/include/linux/usb/rndis_host.h +++ b/include/linux/usb/rndis_host.h
@@ -20,6 +20,8 @@ #ifndef __LINUX_USB_RNDIS_HOST_H #define __LINUX_USB_RNDIS_HOST_H +#include <linux/rndis.h> + /* * CONTROL uses CDC "encapsulated commands" with funky notifications. * - control-out: SEND_ENCAPSULATED @@ -49,47 +51,6 @@ */ #define RNDIS_CONTROL_TIMEOUT_MS (5 * 1000) -#define RNDIS_MSG_COMPLETION cpu_to_le32(0x80000000) - -/* codes for "msg_type" field of rndis messages; - * only the data channel uses packet messages (maybe batched); - * everything else goes on the control channel. - */ -#define RNDIS_MSG_PACKET cpu_to_le32(0x00000001) /* 1-N packets */ -#define RNDIS_MSG_INIT cpu_to_le32(0x00000002) -#define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION) -#define RNDIS_MSG_HALT cpu_to_le32(0x00000003) -#define RNDIS_MSG_QUERY cpu_to_le32(0x00000004) -#define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION) -#define RNDIS_MSG_SET cpu_to_le32(0x00000005) -#define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION) -#define RNDIS_MSG_RESET cpu_to_le32(0x00000006) -#define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION) -#define RNDIS_MSG_INDICATE cpu_to_le32(0x00000007) -#define RNDIS_MSG_KEEPALIVE cpu_to_le32(0x00000008) -#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION) - -/* codes for "status" field of completion messages */ -#define RNDIS_STATUS_SUCCESS cpu_to_le32(0x00000000) -#define RNDIS_STATUS_FAILURE cpu_to_le32(0xc0000001) -#define RNDIS_STATUS_INVALID_DATA cpu_to_le32(0xc0010015) -#define RNDIS_STATUS_NOT_SUPPORTED cpu_to_le32(0xc00000bb) -#define RNDIS_STATUS_MEDIA_CONNECT cpu_to_le32(0x4001000b) -#define RNDIS_STATUS_MEDIA_DISCONNECT cpu_to_le32(0x4001000c) -#define RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION cpu_to_le32(0x40010012) - -/* codes for OID_GEN_PHYSICAL_MEDIUM */ -#define RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED cpu_to_le32(0x00000000) -#define RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN cpu_to_le32(0x00000001) -#define RNDIS_PHYSICAL_MEDIUM_CABLE_MODEM cpu_to_le32(0x00000002) -#define RNDIS_PHYSICAL_MEDIUM_PHONE_LINE cpu_to_le32(0x00000003) -#define RNDIS_PHYSICAL_MEDIUM_POWER_LINE cpu_to_le32(0x00000004) -#define RNDIS_PHYSICAL_MEDIUM_DSL cpu_to_le32(0x00000005) -#define RNDIS_PHYSICAL_MEDIUM_FIBRE_CHANNEL cpu_to_le32(0x00000006) -#define RNDIS_PHYSICAL_MEDIUM_1394 cpu_to_le32(0x00000007) -#define RNDIS_PHYSICAL_MEDIUM_WIRELESS_WAN cpu_to_le32(0x00000008) -#define RNDIS_PHYSICAL_MEDIUM_MAX cpu_to_le32(0x00000009) - struct rndis_data_hdr { __le32 msg_type; /* RNDIS_MSG_PACKET */ __le32 msg_len; /* rndis_data_hdr + data_len + pad */ @@ -222,29 +183,6 @@ __le32 status; } __attribute__ ((packed)); -/* NOTE: about 30 OIDs are "mandatory" for peripherals to support ... and - * there are gobs more that may optionally be supported. We'll avoid as much - * of that mess as possible. - */ -#define OID_802_3_PERMANENT_ADDRESS cpu_to_le32(0x01010101) -#define OID_GEN_MAXIMUM_FRAME_SIZE cpu_to_le32(0x00010106) -#define OID_GEN_CURRENT_PACKET_FILTER cpu_to_le32(0x0001010e) -#define OID_GEN_PHYSICAL_MEDIUM cpu_to_le32(0x00010202) - -/* packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */ -#define RNDIS_PACKET_TYPE_DIRECTED cpu_to_le32(0x00000001) -#define RNDIS_PACKET_TYPE_MULTICAST cpu_to_le32(0x00000002) -#define RNDIS_PACKET_TYPE_ALL_MULTICAST cpu_to_le32(0x00000004) -#define RNDIS_PACKET_TYPE_BROADCAST cpu_to_le32(0x00000008) -#define RNDIS_PACKET_TYPE_SOURCE_ROUTING cpu_to_le32(0x00000010) -#define RNDIS_PACKET_TYPE_PROMISCUOUS cpu_to_le32(0x00000020) -#define RNDIS_PACKET_TYPE_SMT cpu_to_le32(0x00000040) -#define RNDIS_PACKET_TYPE_ALL_LOCAL cpu_to_le32(0x00000080) -#define RNDIS_PACKET_TYPE_GROUP cpu_to_le32(0x00001000) -#define RNDIS_PACKET_TYPE_ALL_FUNCTIONAL cpu_to_le32(0x00002000) -#define RNDIS_PACKET_TYPE_FUNCTIONAL cpu_to_le32(0x00004000) -#define RNDIS_PACKET_TYPE_MAC_FRAME cpu_to_le32(0x00008000) - /* default filter used with RNDIS devices */ #define RNDIS_DEFAULT_FILTER ( \ RNDIS_PACKET_TYPE_DIRECTED | \
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 605b0aa..76f4396 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h
@@ -191,7 +191,8 @@ enum skb_state { illegal = 0, tx_start, tx_done, - rx_start, rx_done, rx_cleanup + rx_start, rx_done, rx_cleanup, + unlink_start }; struct skb_data { /* skb->cb is one of these */
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index b5c2b6c..cad374b 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h
@@ -59,7 +59,8 @@ struct soc_camera_host { struct v4l2_device v4l2_dev; struct list_head list; - unsigned char nr; /* Host number */ + struct mutex host_lock; /* Protect during probing */ + unsigned char nr; /* Host number */ void *priv; const char *drv_name; struct soc_camera_host_ops *ops;
diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 27f450b..f2b801c 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h
@@ -131,9 +131,9 @@ extern int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr); extern void ipv6_sock_mc_close(struct sock *sk); -extern int inet6_mc_check(struct sock *sk, - const struct in6_addr *mc_addr, - const struct in6_addr *src_addr); +extern bool inet6_mc_check(struct sock *sk, + const struct in6_addr *mc_addr, + const struct in6_addr *src_addr); extern int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr); extern int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr); @@ -146,10 +146,10 @@ extern void ipv6_mc_destroy_dev(struct inet6_dev *idev); extern void addrconf_dad_failure(struct inet6_ifaddr *ifp); -extern int ipv6_chk_mcast_addr(struct net_device *dev, - const struct in6_addr *group, - const struct in6_addr *src_addr); -extern int ipv6_is_mld(struct sk_buff *skb, int nexthdr); +extern bool ipv6_chk_mcast_addr(struct net_device *dev, + const struct in6_addr *group, + const struct in6_addr *src_addr); +extern bool ipv6_is_mld(struct sk_buff *skb, int nexthdr); extern void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao); @@ -163,8 +163,8 @@ extern int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr); extern int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr); -extern int ipv6_chk_acast_addr(struct net *net, struct net_device *dev, - const struct in6_addr *addr); +extern bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev, + const struct in6_addr *addr); /* Device notifier */
diff --git a/include/net/codel.h b/include/net/codel.h new file mode 100644 index 0000000..550debf --- /dev/null +++ b/include/net/codel.h
@@ -0,0 +1,342 @@ +#ifndef __NET_SCHED_CODEL_H +#define __NET_SCHED_CODEL_H + +/* + * Codel - The Controlled-Delay Active Queue Management algorithm + * + * Copyright (C) 2011-2012 Kathleen Nichols <nichols@pollere.com> + * Copyright (C) 2011-2012 Van Jacobson <van@pollere.net> + * Copyright (C) 2012 Michael D. Taht <dave.taht@bufferbloat.net> + * Copyright (C) 2012 Eric Dumazet <edumazet@google.com> + * + * 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, + * without modification. + * 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. The names of the authors may not 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. + * + * 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/types.h> +#include <linux/ktime.h> +#include <linux/skbuff.h> +#include <net/pkt_sched.h> +#include <net/inet_ecn.h> +#include <linux/reciprocal_div.h> + +/* Controlling Queue Delay (CoDel) algorithm + * ========================================= + * Source : Kathleen Nichols and Van Jacobson + * http://queue.acm.org/detail.cfm?id=2209336 + * + * Implemented on linux by Dave Taht and Eric Dumazet + */ + + +/* CoDel uses a 1024 nsec clock, encoded in u32 + * This gives a range of 2199 seconds, because of signed compares + */ +typedef u32 codel_time_t; +typedef s32 codel_tdiff_t; +#define CODEL_SHIFT 10 +#define MS2TIME(a) ((a * NSEC_PER_MSEC) >> CODEL_SHIFT) + +static inline codel_time_t codel_get_time(void) +{ + u64 ns = ktime_to_ns(ktime_get()); + + return ns >> CODEL_SHIFT; +} + +#define codel_time_after(a, b) ((s32)(a) - (s32)(b) > 0) +#define codel_time_after_eq(a, b) ((s32)(a) - (s32)(b) >= 0) +#define codel_time_before(a, b) ((s32)(a) - (s32)(b) < 0) +#define codel_time_before_eq(a, b) ((s32)(a) - (s32)(b) <= 0) + +/* Qdiscs using codel plugin must use codel_skb_cb in their own cb[] */ +struct codel_skb_cb { + codel_time_t enqueue_time; +}; + +static struct codel_skb_cb *get_codel_cb(const struct sk_buff *skb) +{ + qdisc_cb_private_validate(skb, sizeof(struct codel_skb_cb)); + return (struct codel_skb_cb *)qdisc_skb_cb(skb)->data; +} + +static codel_time_t codel_get_enqueue_time(const struct sk_buff *skb) +{ + return get_codel_cb(skb)->enqueue_time; +} + +static void codel_set_enqueue_time(struct sk_buff *skb) +{ + get_codel_cb(skb)->enqueue_time = codel_get_time(); +} + +static inline u32 codel_time_to_us(codel_time_t val) +{ + u64 valns = ((u64)val << CODEL_SHIFT); + + do_div(valns, NSEC_PER_USEC); + return (u32)valns; +} + +/** + * struct codel_params - contains codel parameters + * @target: target queue size (in time units) + * @interval: width of moving time window + * @ecn: is Explicit Congestion Notification enabled + */ +struct codel_params { + codel_time_t target; + codel_time_t interval; + bool ecn; +}; + +/** + * struct codel_vars - contains codel variables + * @count: how many drops we've done since the last time we + * entered dropping state + * @lastcount: count at entry to dropping state + * @dropping: set to true if in dropping state + * @rec_inv_sqrt: reciprocal value of sqrt(count) >> 1 + * @first_above_time: when we went (or will go) continuously above target + * for interval + * @drop_next: time to drop next packet, or when we dropped last + * @ldelay: sojourn time of last dequeued packet + */ +struct codel_vars { + u32 count; + u32 lastcount; + bool dropping; + u16 rec_inv_sqrt; + codel_time_t first_above_time; + codel_time_t drop_next; + codel_time_t ldelay; +}; + +#define REC_INV_SQRT_BITS (8 * sizeof(u16)) /* or sizeof_in_bits(rec_inv_sqrt) */ +/* needed shift to get a Q0.32 number from rec_inv_sqrt */ +#define REC_INV_SQRT_SHIFT (32 - REC_INV_SQRT_BITS) + +/** + * struct codel_stats - contains codel shared variables and stats + * @maxpacket: largest packet we've seen so far + * @drop_count: temp count of dropped packets in dequeue() + * ecn_mark: number of packets we ECN marked instead of dropping + */ +struct codel_stats { + u32 maxpacket; + u32 drop_count; + u32 ecn_mark; +}; + +static void codel_params_init(struct codel_params *params) +{ + params->interval = MS2TIME(100); + params->target = MS2TIME(5); + params->ecn = false; +} + +static void codel_vars_init(struct codel_vars *vars) +{ + memset(vars, 0, sizeof(*vars)); +} + +static void codel_stats_init(struct codel_stats *stats) +{ + stats->maxpacket = 256; +} + +/* + * http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Iterative_methods_for_reciprocal_square_roots + * new_invsqrt = (invsqrt / 2) * (3 - count * invsqrt^2) + * + * Here, invsqrt is a fixed point number (< 1.0), 32bit mantissa, aka Q0.32 + */ +static void codel_Newton_step(struct codel_vars *vars) +{ + u32 invsqrt = ((u32)vars->rec_inv_sqrt) << REC_INV_SQRT_SHIFT; + u32 invsqrt2 = ((u64)invsqrt * invsqrt) >> 32; + u64 val = (3LL << 32) - ((u64)vars->count * invsqrt2); + + val >>= 2; /* avoid overflow in following multiply */ + val = (val * invsqrt) >> (32 - 2 + 1); + + vars->rec_inv_sqrt = val >> REC_INV_SQRT_SHIFT; +} + +/* + * CoDel control_law is t + interval/sqrt(count) + * We maintain in rec_inv_sqrt the reciprocal value of sqrt(count) to avoid + * both sqrt() and divide operation. + */ +static codel_time_t codel_control_law(codel_time_t t, + codel_time_t interval, + u32 rec_inv_sqrt) +{ + return t + reciprocal_divide(interval, rec_inv_sqrt << REC_INV_SQRT_SHIFT); +} + + +static bool codel_should_drop(const struct sk_buff *skb, + struct Qdisc *sch, + struct codel_vars *vars, + struct codel_params *params, + struct codel_stats *stats, + codel_time_t now) +{ + bool ok_to_drop; + + if (!skb) { + vars->first_above_time = 0; + return false; + } + + vars->ldelay = now - codel_get_enqueue_time(skb); + sch->qstats.backlog -= qdisc_pkt_len(skb); + + if (unlikely(qdisc_pkt_len(skb) > stats->maxpacket)) + stats->maxpacket = qdisc_pkt_len(skb); + + if (codel_time_before(vars->ldelay, params->target) || + sch->qstats.backlog <= stats->maxpacket) { + /* went below - stay below for at least interval */ + vars->first_above_time = 0; + return false; + } + ok_to_drop = false; + if (vars->first_above_time == 0) { + /* just went above from below. If we stay above + * for at least interval we'll say it's ok to drop + */ + vars->first_above_time = now + params->interval; + } else if (codel_time_after(now, vars->first_above_time)) { + ok_to_drop = true; + } + return ok_to_drop; +} + +typedef struct sk_buff * (*codel_skb_dequeue_t)(struct codel_vars *vars, + struct Qdisc *sch); + +static struct sk_buff *codel_dequeue(struct Qdisc *sch, + struct codel_params *params, + struct codel_vars *vars, + struct codel_stats *stats, + codel_skb_dequeue_t dequeue_func) +{ + struct sk_buff *skb = dequeue_func(vars, sch); + codel_time_t now; + bool drop; + + if (!skb) { + vars->dropping = false; + return skb; + } + now = codel_get_time(); + drop = codel_should_drop(skb, sch, vars, params, stats, now); + if (vars->dropping) { + if (!drop) { + /* sojourn time below target - leave dropping state */ + vars->dropping = false; + } else if (codel_time_after_eq(now, vars->drop_next)) { + /* It's time for the next drop. Drop the current + * packet and dequeue the next. The dequeue might + * take us out of dropping state. + * If not, schedule the next drop. + * A large backlog might result in drop rates so high + * that the next drop should happen now, + * hence the while loop. + */ + while (vars->dropping && + codel_time_after_eq(now, vars->drop_next)) { + vars->count++; /* dont care of possible wrap + * since there is no more divide + */ + codel_Newton_step(vars); + if (params->ecn && INET_ECN_set_ce(skb)) { + stats->ecn_mark++; + vars->drop_next = + codel_control_law(vars->drop_next, + params->interval, + vars->rec_inv_sqrt); + goto end; + } + qdisc_drop(skb, sch); + stats->drop_count++; + skb = dequeue_func(vars, sch); + if (!codel_should_drop(skb, sch, + vars, params, stats, now)) { + /* leave dropping state */ + vars->dropping = false; + } else { + /* and schedule the next drop */ + vars->drop_next = + codel_control_law(vars->drop_next, + params->interval, + vars->rec_inv_sqrt); + } + } + } + } else if (drop) { + if (params->ecn && INET_ECN_set_ce(skb)) { + stats->ecn_mark++; + } else { + qdisc_drop(skb, sch); + stats->drop_count++; + + skb = dequeue_func(vars, sch); + drop = codel_should_drop(skb, sch, vars, params, + stats, now); + } + vars->dropping = true; + /* if min went above target close to when we last went below it + * assume that the drop rate that controlled the queue on the + * last cycle is a good starting point to control it now. + */ + if (codel_time_before(now - vars->drop_next, + 16 * params->interval)) { + vars->count = (vars->count - vars->lastcount) | 1; + /* we dont care if rec_inv_sqrt approximation + * is not very precise : + * Next Newton steps will correct it quadratically. + */ + codel_Newton_step(vars); + } else { + vars->count = 1; + vars->rec_inv_sqrt = ~0U >> REC_INV_SQRT_SHIFT; + } + vars->lastcount = vars->count; + vars->drop_next = codel_control_law(now, params->interval, + vars->rec_inv_sqrt); + } +end: + return skb; +} +#endif
diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index 5743055..d104c88 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h
@@ -1,7 +1,7 @@ /* * An interface between IEEE802.15.4 device and rest of the kernel. * - * Copyright (C) 2007, 2008, 2009 Siemens AG + * Copyright (C) 2007-2012 Siemens AG * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -21,11 +21,14 @@ * Maxim Gorbachyov <maxim.gorbachev@siemens.com> * Maxim Osipov <maxim.osipov@siemens.com> * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> + * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> */ #ifndef IEEE802154_NETDEVICE_H #define IEEE802154_NETDEVICE_H +#include <net/af_ieee802154.h> + /* * A control block of skb passed between the ARPHRD_IEEE802154 device * and other stack parts. @@ -110,12 +113,26 @@ u8 (*get_bsn)(const struct net_device *dev); }; -static inline struct ieee802154_mlme_ops *ieee802154_mlme_ops( - const struct net_device *dev) +/* The IEEE 802.15.4 standard defines 2 type of the devices: + * - FFD - full functionality device + * - RFD - reduce functionality device + * + * So 2 sets of mlme operations are needed + */ +struct ieee802154_reduced_mlme_ops { + struct wpan_phy *(*get_phy)(const struct net_device *dev); +}; + +static inline struct ieee802154_mlme_ops * +ieee802154_mlme_ops(const struct net_device *dev) +{ + return dev->ml_priv; +} + +static inline struct ieee802154_reduced_mlme_ops * +ieee802154_reduced_mlme_ops(const struct net_device *dev) { return dev->ml_priv; } #endif - -
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index 50f325f..9356322 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h
@@ -209,60 +209,6 @@ memcpy(buf + 2, &addr->s6_addr32[3], sizeof(__u32)); } -static inline void ipv6_tr_mc_map(const struct in6_addr *addr, char *buf) -{ - /* All nodes FF01::1, FF02::1, FF02::1:FFxx:xxxx */ - - if (((addr->s6_addr[0] == 0xFF) && - ((addr->s6_addr[1] == 0x01) || (addr->s6_addr[1] == 0x02)) && - (addr->s6_addr16[1] == 0) && - (addr->s6_addr32[1] == 0) && - (addr->s6_addr32[2] == 0) && - (addr->s6_addr16[6] == 0) && - (addr->s6_addr[15] == 1)) || - ((addr->s6_addr[0] == 0xFF) && - (addr->s6_addr[1] == 0x02) && - (addr->s6_addr16[1] == 0) && - (addr->s6_addr32[1] == 0) && - (addr->s6_addr16[4] == 0) && - (addr->s6_addr[10] == 0) && - (addr->s6_addr[11] == 1) && - (addr->s6_addr[12] == 0xff))) - { - buf[0]=0xC0; - buf[1]=0x00; - buf[2]=0x01; - buf[3]=0x00; - buf[4]=0x00; - buf[5]=0x00; - /* All routers FF0x::2 */ - } else if ((addr->s6_addr[0] ==0xff) && - ((addr->s6_addr[1] & 0xF0) == 0) && - (addr->s6_addr16[1] == 0) && - (addr->s6_addr32[1] == 0) && - (addr->s6_addr32[2] == 0) && - (addr->s6_addr16[6] == 0) && - (addr->s6_addr[15] == 2)) - { - buf[0]=0xC0; - buf[1]=0x00; - buf[2]=0x02; - buf[3]=0x00; - buf[4]=0x00; - buf[5]=0x00; - } else { - unsigned char i ; - - i = addr->s6_addr[15] & 7 ; - buf[0]=0xC0; - buf[1]=0x00; - buf[2]=0x00; - buf[3]=0x01 << i ; - buf[4]=0x00; - buf[5]=0x00; - } -} - static inline void ipv6_arcnet_mc_map(const struct in6_addr *addr, char *buf) { buf[0] = 0x00;
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h index 16ff29a..2431cf8 100644 --- a/include/net/inet_frag.h +++ b/include/net/inet_frag.h
@@ -46,8 +46,7 @@ void *arg); void (*destructor)(struct inet_frag_queue *); void (*skb_free)(struct sk_buff *); - int (*match)(struct inet_frag_queue *q, - void *arg); + bool (*match)(struct inet_frag_queue *q, void *arg); void (*frag_expire)(unsigned long data); };
diff --git a/include/net/ip.h b/include/net/ip.h index 94ddb69c..83e0619 100644 --- a/include/net/ip.h +++ b/include/net/ip.h
@@ -141,23 +141,6 @@ extern int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); -/* - * Map a multicast IP onto multicast MAC for type Token Ring. - * This conforms to RFC1469 Option 2 Multicasting i.e. - * using a functional address to transmit / receive - * multicast packets. - */ - -static inline void ip_tr_mc_map(__be32 addr, char *buf) -{ - buf[0]=0xC0; - buf[1]=0x00; - buf[2]=0x00; - buf[3]=0x04; - buf[4]=0x00; - buf[5]=0x00; -} - struct ip_reply_arg { struct kvec iov[1]; int flags;
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index c062b67..37c1a1e 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h
@@ -175,7 +175,7 @@ spin_unlock(&sk->sk_dst_lock); } -static inline int ipv6_unicast_destination(struct sk_buff *skb) +static inline bool ipv6_unicast_destination(const struct sk_buff *skb) { struct rt6_info *rt = (struct rt6_info *) skb_dst(skb);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 4332e9a..aecf884 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h
@@ -263,7 +263,7 @@ struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space, struct ipv6_txoptions *opt); -extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb); +extern bool ipv6_opt_accepted(const struct sock *sk, const struct sk_buff *skb); int ip6_frag_nqueues(struct net *net); int ip6_frag_mem(struct net *net); @@ -332,8 +332,8 @@ addr->s6_addr32[3] = w4; } -static inline int ipv6_addr_equal(const struct in6_addr *a1, - const struct in6_addr *a2) +static inline bool ipv6_addr_equal(const struct in6_addr *a1, + const struct in6_addr *a2) { return ((a1->s6_addr32[0] ^ a2->s6_addr32[0]) | (a1->s6_addr32[1] ^ a2->s6_addr32[1]) | @@ -341,27 +341,27 @@ (a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0; } -static inline int __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2, - unsigned int prefixlen) +static inline bool __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2, + unsigned int prefixlen) { unsigned int pdw, pbi; /* check complete u32 in prefix */ pdw = prefixlen >> 5; if (pdw && memcmp(a1, a2, pdw << 2)) - return 0; + return false; /* check incomplete u32 in prefix */ pbi = prefixlen & 0x1f; if (pbi && ((a1[pdw] ^ a2[pdw]) & htonl((0xffffffff) << (32 - pbi)))) - return 0; + return false; - return 1; + return true; } -static inline int ipv6_prefix_equal(const struct in6_addr *a1, - const struct in6_addr *a2, - unsigned int prefixlen) +static inline bool ipv6_prefix_equal(const struct in6_addr *a1, + const struct in6_addr *a2, + unsigned int prefixlen) { return __ipv6_prefix_equal(a1->s6_addr32, a2->s6_addr32, prefixlen); @@ -387,21 +387,21 @@ }; void ip6_frag_init(struct inet_frag_queue *q, void *a); -int ip6_frag_match(struct inet_frag_queue *q, void *a); +bool ip6_frag_match(struct inet_frag_queue *q, void *a); -static inline int ipv6_addr_any(const struct in6_addr *a) +static inline bool ipv6_addr_any(const struct in6_addr *a) { return (a->s6_addr32[0] | a->s6_addr32[1] | a->s6_addr32[2] | a->s6_addr32[3]) == 0; } -static inline int ipv6_addr_loopback(const struct in6_addr *a) +static inline bool ipv6_addr_loopback(const struct in6_addr *a) { return (a->s6_addr32[0] | a->s6_addr32[1] | a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0; } -static inline int ipv6_addr_v4mapped(const struct in6_addr *a) +static inline bool ipv6_addr_v4mapped(const struct in6_addr *a) { return (a->s6_addr32[0] | a->s6_addr32[1] | (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0; @@ -411,7 +411,7 @@ * Check for a RFC 4843 ORCHID address * (Overlay Routable Cryptographic Hash Identifiers) */ -static inline int ipv6_addr_orchid(const struct in6_addr *a) +static inline bool ipv6_addr_orchid(const struct in6_addr *a) { return (a->s6_addr32[0] & htonl(0xfffffff0)) == htonl(0x20010010); } @@ -559,7 +559,7 @@ extern int ipv6_skip_exthdr(const struct sk_buff *, int start, u8 *nexthdrp, __be16 *frag_offp); -extern int ipv6_ext_hdr(u8 nexthdr); +extern bool ipv6_ext_hdr(u8 nexthdr); extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type);
diff --git a/include/net/lapb.h b/include/net/lapb.h index fd2bf57..df892a9 100644 --- a/include/net/lapb.h +++ b/include/net/lapb.h
@@ -149,4 +149,10 @@ */ #define LAPB_DEBUG 0 +#define lapb_dbg(level, fmt, ...) \ +do { \ + if (level < LAPB_DEBUG) \ + pr_debug(fmt, ##__VA_ARGS__); \ +} while (0) + #endif
diff --git a/include/net/llc_pdu.h b/include/net/llc_pdu.h index f57e7d4..5a93d13 100644 --- a/include/net/llc_pdu.h +++ b/include/net/llc_pdu.h
@@ -13,7 +13,6 @@ */ #include <linux/if_ether.h> -#include <linux/if_tr.h> /* Lengths of frame formats */ #define LLC_PDU_LEN_I 4 /* header and 2 control bytes */ @@ -253,10 +252,6 @@ { if (skb->protocol == htons(ETH_P_802_2)) memcpy(sa, eth_hdr(skb)->h_source, ETH_ALEN); - else if (skb->protocol == htons(ETH_P_TR_802_2)) { - memcpy(sa, tr_hdr(skb)->saddr, ETH_ALEN); - *sa &= 0x7F; - } } /** @@ -270,8 +265,6 @@ { if (skb->protocol == htons(ETH_P_802_2)) memcpy(da, eth_hdr(skb)->h_dest, ETH_ALEN); - else if (skb->protocol == htons(ETH_P_TR_802_2)) - memcpy(da, tr_hdr(skb)->daddr, ETH_ALEN); } /**
diff --git a/include/net/mac802154.h b/include/net/mac802154.h new file mode 100644 index 0000000..c9f8ab5 --- /dev/null +++ b/include/net/mac802154.h
@@ -0,0 +1,136 @@ +/* + * IEEE802.15.4-2003 specification + * + * Copyright (C) 2007-2012 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef NET_MAC802154_H +#define NET_MAC802154_H + +#include <net/af_ieee802154.h> + +/* The following flags are used to indicate changed address settings from + * the stack to the hardware. + */ + +/* indicates that the Short Address changed */ +#define IEEE802515_AFILT_SADDR_CHANGED 0x00000001 +/* indicates that the IEEE Address changed */ +#define IEEE802515_AFILT_IEEEADDR_CHANGED 0x00000002 +/* indicates that the PAN ID changed */ +#define IEEE802515_AFILT_PANID_CHANGED 0x00000004 +/* indicates that PAN Coordinator status changed */ +#define IEEE802515_AFILT_PANC_CHANGED 0x00000008 + +struct ieee802154_hw_addr_filt { + __le16 pan_id; /* Each independent PAN selects a unique + * identifier. This PAN id allows communication + * between devices within a network using short + * addresses and enables transmissions between + * devices across independent networks. + */ + __le16 short_addr; + u8 ieee_addr[IEEE802154_ADDR_LEN]; + u8 pan_coord; +}; + +struct ieee802154_dev { + /* filled by the driver */ + int extra_tx_headroom; + u32 flags; + struct device *parent; + + /* filled by mac802154 core */ + struct ieee802154_hw_addr_filt hw_filt; + void *priv; + struct wpan_phy *phy; +}; + +/* Checksum is in hardware and is omitted from a packet + * + * These following flags are used to indicate hardware capabilities to + * the stack. Generally, flags here should have their meaning + * done in a way that the simplest hardware doesn't need setting + * any particular flags. There are some exceptions to this rule, + * however, so you are advised to review these flags carefully. + */ + +/* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */ +#define IEEE802154_HW_OMIT_CKSUM 0x00000001 +/* Indicates that receiver will autorespond with ACK frames. */ +#define IEEE802154_HW_AACK 0x00000002 + +/* struct ieee802154_ops - callbacks from mac802154 to the driver + * + * This structure contains various callbacks that the driver may + * handle or, in some cases, must handle, for example to transmit + * a frame. + * + * start: Handler that 802.15.4 module calls for device initialization. + * This function is called before the first interface is attached. + * + * stop: Handler that 802.15.4 module calls for device cleanup. + * This function is called after the last interface is removed. + * + * xmit: Handler that 802.15.4 module calls for each transmitted frame. + * skb cntains the buffer starting from the IEEE 802.15.4 header. + * The low-level driver should send the frame based on available + * configuration. + * This function should return zero or negative errno. Called with + * pib_lock held. + * + * ed: Handler that 802.15.4 module calls for Energy Detection. + * This function should place the value for detected energy + * (usually device-dependant) in the level pointer and return + * either zero or negative errno. Called with pib_lock held. + * + * set_channel: + * Set radio for listening on specific channel. + * Set the device for listening on specified channel. + * Returns either zero, or negative errno. Called with pib_lock held. + * + * set_hw_addr_filt: + * Set radio for listening on specific address. + * Set the device for listening on specified address. + * Returns either zero, or negative errno. + */ +struct ieee802154_ops { + struct module *owner; + int (*start)(struct ieee802154_dev *dev); + void (*stop)(struct ieee802154_dev *dev); + int (*xmit)(struct ieee802154_dev *dev, + struct sk_buff *skb); + int (*ed)(struct ieee802154_dev *dev, u8 *level); + int (*set_channel)(struct ieee802154_dev *dev, + int page, + int channel); + int (*set_hw_addr_filt)(struct ieee802154_dev *dev, + struct ieee802154_hw_addr_filt *filt, + unsigned long changed); + int (*ieee_addr)(struct ieee802154_dev *dev, + u8 addr[IEEE802154_ADDR_LEN]); +}; + +/* Basic interface to register ieee802154 device */ +struct ieee802154_dev * +ieee802154_alloc_device(size_t priv_data_lex, struct ieee802154_ops *ops); +void ieee802154_free_device(struct ieee802154_dev *dev); +int ieee802154_register_device(struct ieee802154_dev *dev); +void ieee802154_unregister_device(struct ieee802154_dev *dev); + +void ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, + u8 lqi); + +#endif /* NET_MAC802154_H */
diff --git a/include/net/rawv6.h b/include/net/rawv6.h index cf75772..e7ea660 100644 --- a/include/net/rawv6.h +++ b/include/net/rawv6.h
@@ -5,7 +5,7 @@ void raw6_icmp_error(struct sk_buff *, int nexthdr, u8 type, u8 code, int inner_offset, __be32); -int raw6_local_deliver(struct sk_buff *, int); +bool raw6_local_deliver(struct sk_buff *, int); extern int rawv6_rcv(struct sock *sk, struct sk_buff *skb);
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 6ee44b2..a2ef814 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h
@@ -704,4 +704,17 @@ addr->v6.sin6_addr.s6_addr32[2] = htonl(0x0000ffff); } +/* The cookie is always 0 since this is how it's used in the + * pmtu code. + */ +static inline struct dst_entry *sctp_transport_dst_check(struct sctp_transport *t) +{ + if (t->dst && !dst_check(t->dst, 0)) { + dst_release(t->dst); + t->dst = NULL; + } + + return t->dst; +} + #endif /* __net_sctp_h__ */
diff --git a/include/net/sock.h b/include/net/sock.h index e613704..da93155 100644 --- a/include/net/sock.h +++ b/include/net/sock.h
@@ -97,7 +97,7 @@ #else /* Validate arguments and do nothing */ static inline __printf(2, 3) -void SOCK_DEBUG(struct sock *sk, const char *msg, ...) +void SOCK_DEBUG(const struct sock *sk, const char *msg, ...) { } #endif @@ -372,8 +372,8 @@ void (*sk_data_ready)(struct sock *sk, int bytes); void (*sk_write_space)(struct sock *sk); void (*sk_error_report)(struct sock *sk); - int (*sk_backlog_rcv)(struct sock *sk, - struct sk_buff *skb); + int (*sk_backlog_rcv)(struct sock *sk, + struct sk_buff *skb); void (*sk_destruct)(struct sock *sk); }; @@ -454,40 +454,40 @@ NULL; } -static inline int sk_unhashed(const struct sock *sk) +static inline bool sk_unhashed(const struct sock *sk) { return hlist_unhashed(&sk->sk_node); } -static inline int sk_hashed(const struct sock *sk) +static inline bool sk_hashed(const struct sock *sk) { return !sk_unhashed(sk); } -static __inline__ void sk_node_init(struct hlist_node *node) +static inline void sk_node_init(struct hlist_node *node) { node->pprev = NULL; } -static __inline__ void sk_nulls_node_init(struct hlist_nulls_node *node) +static inline void sk_nulls_node_init(struct hlist_nulls_node *node) { node->pprev = NULL; } -static __inline__ void __sk_del_node(struct sock *sk) +static inline void __sk_del_node(struct sock *sk) { __hlist_del(&sk->sk_node); } /* NB: equivalent to hlist_del_init_rcu */ -static __inline__ int __sk_del_node_init(struct sock *sk) +static inline bool __sk_del_node_init(struct sock *sk) { if (sk_hashed(sk)) { __sk_del_node(sk); sk_node_init(&sk->sk_node); - return 1; + return true; } - return 0; + return false; } /* Grab socket reference count. This operation is valid only @@ -509,9 +509,9 @@ atomic_dec(&sk->sk_refcnt); } -static __inline__ int sk_del_node_init(struct sock *sk) +static inline bool sk_del_node_init(struct sock *sk) { - int rc = __sk_del_node_init(sk); + bool rc = __sk_del_node_init(sk); if (rc) { /* paranoid for a while -acme */ @@ -522,18 +522,18 @@ } #define sk_del_node_init_rcu(sk) sk_del_node_init(sk) -static __inline__ int __sk_nulls_del_node_init_rcu(struct sock *sk) +static inline bool __sk_nulls_del_node_init_rcu(struct sock *sk) { if (sk_hashed(sk)) { hlist_nulls_del_init_rcu(&sk->sk_nulls_node); - return 1; + return true; } - return 0; + return false; } -static __inline__ int sk_nulls_del_node_init_rcu(struct sock *sk) +static inline bool sk_nulls_del_node_init_rcu(struct sock *sk) { - int rc = __sk_nulls_del_node_init_rcu(sk); + bool rc = __sk_nulls_del_node_init_rcu(sk); if (rc) { /* paranoid for a while -acme */ @@ -543,40 +543,40 @@ return rc; } -static __inline__ void __sk_add_node(struct sock *sk, struct hlist_head *list) +static inline void __sk_add_node(struct sock *sk, struct hlist_head *list) { hlist_add_head(&sk->sk_node, list); } -static __inline__ void sk_add_node(struct sock *sk, struct hlist_head *list) +static inline void sk_add_node(struct sock *sk, struct hlist_head *list) { sock_hold(sk); __sk_add_node(sk, list); } -static __inline__ void sk_add_node_rcu(struct sock *sk, struct hlist_head *list) +static inline void sk_add_node_rcu(struct sock *sk, struct hlist_head *list) { sock_hold(sk); hlist_add_head_rcu(&sk->sk_node, list); } -static __inline__ void __sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list) +static inline void __sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list) { hlist_nulls_add_head_rcu(&sk->sk_nulls_node, list); } -static __inline__ void sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list) +static inline void sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list) { sock_hold(sk); __sk_nulls_add_node_rcu(sk, list); } -static __inline__ void __sk_del_bind_node(struct sock *sk) +static inline void __sk_del_bind_node(struct sock *sk) { __hlist_del(&sk->sk_bind_node); } -static __inline__ void sk_add_bind_node(struct sock *sk, +static inline void sk_add_bind_node(struct sock *sk, struct hlist_head *list) { hlist_add_head(&sk->sk_bind_node, list); @@ -650,7 +650,7 @@ __clear_bit(flag, &sk->sk_flags); } -static inline int sock_flag(struct sock *sk, enum sock_flags flag) +static inline bool sock_flag(const struct sock *sk, enum sock_flags flag) { return test_bit(flag, &sk->sk_flags); } @@ -665,7 +665,7 @@ sk->sk_ack_backlog++; } -static inline int sk_acceptq_is_full(struct sock *sk) +static inline bool sk_acceptq_is_full(const struct sock *sk) { return sk->sk_ack_backlog > sk->sk_max_ack_backlog; } @@ -673,19 +673,19 @@ /* * Compute minimal free write space needed to queue new packets. */ -static inline int sk_stream_min_wspace(struct sock *sk) +static inline int sk_stream_min_wspace(const struct sock *sk) { return sk->sk_wmem_queued >> 1; } -static inline int sk_stream_wspace(struct sock *sk) +static inline int sk_stream_wspace(const struct sock *sk) { return sk->sk_sndbuf - sk->sk_wmem_queued; } extern void sk_stream_write_space(struct sock *sk); -static inline int sk_stream_memory_free(struct sock *sk) +static inline bool sk_stream_memory_free(const struct sock *sk) { return sk->sk_wmem_queued < sk->sk_sndbuf; } @@ -809,26 +809,26 @@ * transport -> network interface is defined by struct inet_proto */ struct proto { - void (*close)(struct sock *sk, + void (*close)(struct sock *sk, long timeout); int (*connect)(struct sock *sk, - struct sockaddr *uaddr, + struct sockaddr *uaddr, int addr_len); int (*disconnect)(struct sock *sk, int flags); - struct sock * (*accept) (struct sock *sk, int flags, int *err); + struct sock * (*accept)(struct sock *sk, int flags, int *err); int (*ioctl)(struct sock *sk, int cmd, unsigned long arg); int (*init)(struct sock *sk); void (*destroy)(struct sock *sk); void (*shutdown)(struct sock *sk, int how); - int (*setsockopt)(struct sock *sk, int level, + int (*setsockopt)(struct sock *sk, int level, int optname, char __user *optval, unsigned int optlen); - int (*getsockopt)(struct sock *sk, int level, - int optname, char __user *optval, - int __user *option); + int (*getsockopt)(struct sock *sk, int level, + int optname, char __user *optval, + int __user *option); #ifdef CONFIG_COMPAT int (*compat_setsockopt)(struct sock *sk, int level, @@ -845,14 +845,14 @@ struct msghdr *msg, size_t len); int (*recvmsg)(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, - size_t len, int noblock, int flags, - int *addr_len); + size_t len, int noblock, int flags, + int *addr_len); int (*sendpage)(struct sock *sk, struct page *page, int offset, size_t size, int flags); - int (*bind)(struct sock *sk, + int (*bind)(struct sock *sk, struct sockaddr *uaddr, int addr_len); - int (*backlog_rcv) (struct sock *sk, + int (*backlog_rcv) (struct sock *sk, struct sk_buff *skb); /* Keeping track of sk's, looking them up, and port selection methods. */ @@ -1173,7 +1173,7 @@ extern void sock_prot_inuse_add(struct net *net, struct proto *prot, int inc); extern int sock_prot_inuse_get(struct net *net, struct proto *proto); #else -static void inline sock_prot_inuse_add(struct net *net, struct proto *prot, +static inline void sock_prot_inuse_add(struct net *net, struct proto *prot, int inc) { } @@ -1260,24 +1260,24 @@ return (amt + SK_MEM_QUANTUM - 1) >> SK_MEM_QUANTUM_SHIFT; } -static inline int sk_has_account(struct sock *sk) +static inline bool sk_has_account(struct sock *sk) { /* return true if protocol supports memory accounting */ return !!sk->sk_prot->memory_allocated; } -static inline int sk_wmem_schedule(struct sock *sk, int size) +static inline bool sk_wmem_schedule(struct sock *sk, int size) { if (!sk_has_account(sk)) - return 1; + return true; return size <= sk->sk_forward_alloc || __sk_mem_schedule(sk, size, SK_MEM_SEND); } -static inline int sk_rmem_schedule(struct sock *sk, int size) +static inline bool sk_rmem_schedule(struct sock *sk, int size) { if (!sk_has_account(sk)) - return 1; + return true; return size <= sk->sk_forward_alloc || __sk_mem_schedule(sk, size, SK_MEM_RECV); } @@ -1342,7 +1342,7 @@ * Mark both the sk_lock and the sk_lock.slock as a * per-address-family lock class. */ -#define sock_lock_init_class_and_name(sk, sname, skey, name, key) \ +#define sock_lock_init_class_and_name(sk, sname, skey, name, key) \ do { \ sk->sk_lock.owned = 0; \ init_waitqueue_head(&sk->sk_lock.wq); \ @@ -1350,7 +1350,7 @@ debug_check_no_locks_freed((void *)&(sk)->sk_lock, \ sizeof((sk)->sk_lock)); \ lockdep_set_class_and_name(&(sk)->sk_lock.slock, \ - (skey), (sname)); \ + (skey), (sname)); \ lockdep_init_map(&(sk)->sk_lock.dep_map, (name), (key), 0); \ } while (0) @@ -1410,13 +1410,13 @@ unsigned int optlen); extern int sock_getsockopt(struct socket *sock, int level, - int op, char __user *optval, + int op, char __user *optval, int __user *optlen); -extern struct sk_buff *sock_alloc_send_skb(struct sock *sk, +extern struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, int noblock, int *errcode); -extern struct sk_buff *sock_alloc_send_pskb(struct sock *sk, +extern struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, unsigned long data_len, int noblock, @@ -1438,7 +1438,7 @@ * Functions to fill in entries in struct proto_ops when a protocol * does not implement a particular function. */ -extern int sock_no_bind(struct socket *, +extern int sock_no_bind(struct socket *, struct sockaddr *, int); extern int sock_no_connect(struct socket *, struct sockaddr *, int, int); @@ -1467,7 +1467,7 @@ struct vm_area_struct *vma); extern ssize_t sock_no_sendpage(struct socket *sock, struct page *page, - int offset, size_t size, + int offset, size_t size, int flags); /* @@ -1490,7 +1490,7 @@ /* * Default socket callbacks and setup code */ - + /* Initialise core socket variables */ extern void sock_init_data(struct socket *sock, struct sock *sk); @@ -1690,7 +1690,7 @@ extern struct dst_entry *sk_dst_check(struct sock *sk, u32 cookie); -static inline int sk_can_gso(const struct sock *sk) +static inline bool sk_can_gso(const struct sock *sk) { return net_gso_ok(sk->sk_route_caps, sk->sk_gso_type); } @@ -1807,7 +1807,7 @@ * * Returns true if socket has write or read allocations */ -static inline int sk_has_allocations(const struct sock *sk) +static inline bool sk_has_allocations(const struct sock *sk) { return sk_wmem_alloc_get(sk) || sk_rmem_alloc_get(sk); } @@ -1846,9 +1846,7 @@ */ static inline bool wq_has_sleeper(struct socket_wq *wq) { - - /* - * We need to be sure we are in sync with the + /* We need to be sure we are in sync with the * add_wait_queue modifications to the wait queue. * * This memory barrier is paired in the sock_poll_wait. @@ -1870,22 +1868,21 @@ { if (!poll_does_not_wait(p) && wait_address) { poll_wait(filp, wait_address, p); - /* - * We need to be sure we are in sync with the + /* We need to be sure we are in sync with the * socket flags modification. * * This memory barrier is paired in the wq_has_sleeper. - */ + */ smp_mb(); } } /* - * Queue a received datagram if it will fit. Stream and sequenced + * Queue a received datagram if it will fit. Stream and sequenced * protocols can't normally use this as they need to fit buffers in * and play with them. * - * Inlined as it's very short and called for pretty much every + * Inlined as it's very short and called for pretty much every * packet ever received. */ @@ -1911,10 +1908,10 @@ sk_mem_charge(sk, skb->truesize); } -extern void sk_reset_timer(struct sock *sk, struct timer_list* timer, +extern void sk_reset_timer(struct sock *sk, struct timer_list *timer, unsigned long expires); -extern void sk_stop_timer(struct sock *sk, struct timer_list* timer); +extern void sk_stop_timer(struct sock *sk, struct timer_list *timer); extern int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); @@ -1923,7 +1920,7 @@ /* * Recover an error report and clear atomically */ - + static inline int sock_error(struct sock *sk) { int err; @@ -1939,7 +1936,7 @@ if (!(sk->sk_shutdown & SEND_SHUTDOWN)) { amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); - if (amt < 0) + if (amt < 0) amt = 0; } return amt; @@ -1983,7 +1980,7 @@ /* * Default write policy as shown to user space via poll/select/SIGIO */ -static inline int sock_writeable(const struct sock *sk) +static inline bool sock_writeable(const struct sock *sk) { return atomic_read(&sk->sk_wmem_alloc) < (sk->sk_sndbuf >> 1); } @@ -1993,12 +1990,12 @@ return in_softirq() ? GFP_ATOMIC : GFP_KERNEL; } -static inline long sock_rcvtimeo(const struct sock *sk, int noblock) +static inline long sock_rcvtimeo(const struct sock *sk, bool noblock) { return noblock ? 0 : sk->sk_rcvtimeo; } -static inline long sock_sndtimeo(const struct sock *sk, int noblock) +static inline long sock_sndtimeo(const struct sock *sk, bool noblock) { return noblock ? 0 : sk->sk_sndtimeo; } @@ -2021,7 +2018,7 @@ extern void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk, struct sk_buff *skb); -static __inline__ void +static inline void sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) { ktime_t kt = skb->tstamp; @@ -2062,7 +2059,7 @@ (1UL << SOCK_RCVTSTAMP) | \ (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE) | \ (1UL << SOCK_TIMESTAMPING_SOFTWARE) | \ - (1UL << SOCK_TIMESTAMPING_RAW_HARDWARE) | \ + (1UL << SOCK_TIMESTAMPING_RAW_HARDWARE) | \ (1UL << SOCK_TIMESTAMPING_SYS_HARDWARE)) if (sk->sk_flags & FLAGS_TS_OR_DROPS) @@ -2091,7 +2088,7 @@ * locked so that the sk_buff queue operation is ok. */ #ifdef CONFIG_NET_DMA -static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb, int copied_early) +static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb, bool copied_early) { __skb_unlink(skb, &sk->sk_receive_queue); if (!copied_early) @@ -2100,7 +2097,7 @@ __skb_queue_tail(&sk->sk_async_wait_queue, skb); } #else -static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb, int copied_early) +static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb, bool copied_early) { __skb_unlink(skb, &sk->sk_receive_queue); __kfree_skb(skb); @@ -2147,8 +2144,8 @@ extern int sock_get_timestamp(struct sock *, struct timeval __user *); extern int sock_get_timestampns(struct sock *, struct timespec __user *); -/* - * Enable debug/info messages +/* + * Enable debug/info messages */ extern int net_msg_warn; #define NETDEBUG(fmt, args...) \
diff --git a/include/net/tcp.h b/include/net/tcp.h index 92faa6a..e79aa48 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h
@@ -263,14 +263,14 @@ * and worry about wraparound (automatic with unsigned arithmetic). */ -static inline int before(__u32 seq1, __u32 seq2) +static inline bool before(__u32 seq1, __u32 seq2) { return (__s32)(seq1-seq2) < 0; } #define after(seq2, seq1) before(seq1, seq2) /* is s2<=s1<=s3 ? */ -static inline int between(__u32 seq1, __u32 seq2, __u32 seq3) +static inline bool between(__u32 seq1, __u32 seq2, __u32 seq3) { return seq3 - seq2 >= seq1 - seq2; } @@ -305,7 +305,7 @@ } /* syncookies: no recent synqueue overflow on this listening socket? */ -static inline int tcp_synq_no_recent_overflow(const struct sock *sk) +static inline bool tcp_synq_no_recent_overflow(const struct sock *sk) { unsigned long last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp; return time_after(jiffies, last_overflow + TCP_TIMEOUT_FALLBACK); @@ -383,7 +383,7 @@ struct request_sock **prev); extern int tcp_child_process(struct sock *parent, struct sock *child, struct sk_buff *skb); -extern int tcp_use_frto(struct sock *sk); +extern bool tcp_use_frto(struct sock *sk); extern void tcp_enter_frto(struct sock *sk); extern void tcp_enter_loss(struct sock *sk, int how); extern void tcp_clear_retrans(struct tcp_sock *tp); @@ -432,8 +432,7 @@ void tcp_connect_init(struct sock *sk); void tcp_finish_connect(struct sock *sk, struct sk_buff *skb); -int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, - int hdrlen, bool *fragstolen); +int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size); /* From syncookies.c */ extern __u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS]; @@ -471,7 +470,7 @@ extern void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss, int nonagle); -extern int tcp_may_send_now(struct sock *sk); +extern bool tcp_may_send_now(struct sock *sk); extern int tcp_retransmit_skb(struct sock *, struct sk_buff *); extern void tcp_retransmit_timer(struct sock *sk); extern void tcp_xmit_retransmit_queue(struct sock *); @@ -485,9 +484,9 @@ extern void tcp_send_fin(struct sock *sk); extern void tcp_send_active_reset(struct sock *sk, gfp_t priority); extern int tcp_send_synack(struct sock *); -extern int tcp_syn_flood_action(struct sock *sk, - const struct sk_buff *skb, - const char *proto); +extern bool tcp_syn_flood_action(struct sock *sk, + const struct sk_buff *skb, + const char *proto); extern void tcp_push_one(struct sock *, unsigned int mss_now); extern void tcp_send_ack(struct sock *sk); extern void tcp_send_delayed_ack(struct sock *sk); @@ -795,12 +794,12 @@ return tp->rx_opt.sack_ok; } -static inline int tcp_is_reno(const struct tcp_sock *tp) +static inline bool tcp_is_reno(const struct tcp_sock *tp) { return !tcp_is_sack(tp); } -static inline int tcp_is_fack(const struct tcp_sock *tp) +static inline bool tcp_is_fack(const struct tcp_sock *tp) { return tp->rx_opt.sack_ok & TCP_FACK_ENABLED; } @@ -902,7 +901,7 @@ { return tp->snd_una + tp->snd_wnd; } -extern int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight); +extern bool tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight); static inline void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss, const struct sk_buff *skb) @@ -945,7 +944,7 @@ return __skb_checksum_complete(skb); } -static inline int tcp_checksum_complete(struct sk_buff *skb) +static inline bool tcp_checksum_complete(struct sk_buff *skb) { return !skb_csum_unnecessary(skb) && __tcp_checksum_complete(skb); @@ -975,12 +974,12 @@ * * NOTE: is this not too big to inline? */ -static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb) +static inline bool tcp_prequeue(struct sock *sk, struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); if (sysctl_tcp_low_latency || !tp->ucopy.task) - return 0; + return false; __skb_queue_tail(&tp->ucopy.prequeue, skb); tp->ucopy.memory += skb->truesize; @@ -1004,7 +1003,7 @@ (3 * tcp_rto_min(sk)) / 4, TCP_RTO_MAX); } - return 1; + return true; } @@ -1109,28 +1108,28 @@ return fin_timeout; } -static inline int tcp_paws_check(const struct tcp_options_received *rx_opt, - int paws_win) +static inline bool tcp_paws_check(const struct tcp_options_received *rx_opt, + int paws_win) { if ((s32)(rx_opt->ts_recent - rx_opt->rcv_tsval) <= paws_win) - return 1; + return true; if (unlikely(get_seconds() >= rx_opt->ts_recent_stamp + TCP_PAWS_24DAYS)) - return 1; + return true; /* * Some OSes send SYN and SYNACK messages with tsval=0 tsecr=0, * then following tcp messages have valid values. Ignore 0 value, * or else 'negative' tsval might forbid us to accept their packets. */ if (!rx_opt->ts_recent) - return 1; - return 0; + return true; + return false; } -static inline int tcp_paws_reject(const struct tcp_options_received *rx_opt, - int rst) +static inline bool tcp_paws_reject(const struct tcp_options_received *rx_opt, + int rst) { if (tcp_paws_check(rx_opt, 0)) - return 0; + return false; /* RST segments are not recommended to carry timestamp, and, if they do, it is recommended to ignore PAWS because @@ -1145,8 +1144,8 @@ However, we can relax time bounds for RST segments to MSL. */ if (rst && get_seconds() >= rx_opt->ts_recent_stamp + TCP_PAWS_MSL) - return 0; - return 1; + return false; + return true; } static inline void tcp_mib_init(struct net *net) @@ -1384,7 +1383,7 @@ __skb_unlink(skb, &sk->sk_write_queue); } -static inline int tcp_write_queue_empty(struct sock *sk) +static inline bool tcp_write_queue_empty(struct sock *sk) { return skb_queue_empty(&sk->sk_write_queue); } @@ -1441,7 +1440,7 @@ /* Determines whether this is a thin stream (which may suffer from * increased latency). Used to trigger latency-reducing mechanisms. */ -static inline unsigned int tcp_stream_is_thin(struct tcp_sock *tp) +static inline bool tcp_stream_is_thin(struct tcp_sock *tp) { return tp->packets_out < 4 && !tcp_in_initial_slowstart(tp); }
diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h index ff27f1b..b52bda8 100644 --- a/include/net/wpan-phy.h +++ b/include/net/wpan-phy.h
@@ -25,6 +25,14 @@ #include <linux/mutex.h> #include <linux/bug.h> +/* According to the IEEE 802.15.4 stadard the upper most significant bits of + * the 32-bit channel bitmaps shall be used as an integer value to specify 32 + * possible channel pages. The lower 27 bits of the channel bit map shall be + * used as a bit mask to specify channel numbers within a channel page. + */ +#define WPAN_NUM_CHANNELS 27 +#define WPAN_NUM_PAGES 32 + struct wpan_phy { struct mutex pib_lock; @@ -43,7 +51,7 @@ int idx; struct net_device *(*add_iface)(struct wpan_phy *phy, - const char *name); + const char *name, int type); void (*del_iface)(struct wpan_phy *phy, struct net_device *dev); char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 1cb32bf..e0a55df 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h
@@ -886,15 +886,15 @@ return port; } -extern int xfrm_selector_match(const struct xfrm_selector *sel, - const struct flowi *fl, - unsigned short family); +extern bool xfrm_selector_match(const struct xfrm_selector *sel, + const struct flowi *fl, + unsigned short family); #ifdef CONFIG_SECURITY_NETWORK_XFRM /* If neither has a context --> match * Otherwise, both must have a context and the sids, doi, alg must match */ -static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2) +static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2) { return ((!s1 && !s2) || (s1 && s2 && @@ -903,9 +903,9 @@ (s1->ctx_alg == s2->ctx_alg))); } #else -static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2) +static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2) { - return 1; + return true; } #endif
diff --git a/include/video/vga.h b/include/video/vga.h index 2b8691f..cac567f 100644 --- a/include/video/vga.h +++ b/include/video/vga.h
@@ -19,29 +19,7 @@ #include <linux/types.h> #include <asm/io.h> -#ifndef CONFIG_AMIGA #include <asm/vga.h> -#else -/* - * FIXME - * Ugh, we don't have PCI space, so map readb() and friends to use Zorro space - * for MMIO accesses. This should make cirrusfb work again on Amiga - */ -#undef inb_p -#undef inw_p -#undef outb_p -#undef outw -#undef readb -#undef writeb -#undef writew -#define inb_p(port) 0 -#define inw_p(port) 0 -#define outb_p(port, val) do { } while (0) -#define outw(port, val) do { } while (0) -#define readb z_readb -#define writeb z_writeb -#define writew z_writew -#endif #include <asm/byteorder.h>
diff --git a/init/do_mounts.c b/init/do_mounts.c index 0e93f92..42b0707 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c
@@ -472,7 +472,7 @@ void __init mount_root(void) { #ifdef CONFIG_ROOT_NFS - if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { + if (ROOT_DEV == Root_NFS) { if (mount_nfs_root()) return;
diff --git a/init/main.c b/init/main.c index 44b2433..cb54cd3 100644 --- a/init/main.c +++ b/init/main.c
@@ -560,9 +560,6 @@ early_boot_irqs_disabled = false; local_irq_enable(); - /* Interrupts are enabled now so all GFP allocations are safe. */ - gfp_allowed_mask = __GFP_BITS_MASK; - kmem_cache_init_late(); /* @@ -842,6 +839,10 @@ * Wait until kthreadd is all set-up. */ wait_for_completion(&kthreadd_done); + + /* Now the scheduler is fully set up and can do blocking allocations */ + gfp_allowed_mask = __GFP_BITS_MASK; + /* * init can allocate pages on any node */
diff --git a/kernel/compat.c b/kernel/compat.c index 74ff849..d2c67aa 100644 --- a/kernel/compat.c +++ b/kernel/compat.c
@@ -372,25 +372,54 @@ #ifdef __ARCH_WANT_SYS_SIGPROCMASK -asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set, - compat_old_sigset_t __user *oset) +/* + * sys_sigprocmask SIG_SETMASK sets the first (compat) word of the + * blocked set of signals to the supplied signal set + */ +static inline void compat_sig_setmask(sigset_t *blocked, compat_sigset_word set) { - old_sigset_t s; - long ret; - mm_segment_t old_fs; + memcpy(blocked->sig, &set, sizeof(set)); +} - if (set && get_user(s, set)) - return -EFAULT; - old_fs = get_fs(); - set_fs(KERNEL_DS); - ret = sys_sigprocmask(how, - set ? (old_sigset_t __user *) &s : NULL, - oset ? (old_sigset_t __user *) &s : NULL); - set_fs(old_fs); - if (ret == 0) - if (oset) - ret = put_user(s, oset); - return ret; +asmlinkage long compat_sys_sigprocmask(int how, + compat_old_sigset_t __user *nset, + compat_old_sigset_t __user *oset) +{ + old_sigset_t old_set, new_set; + sigset_t new_blocked; + + old_set = current->blocked.sig[0]; + + if (nset) { + if (get_user(new_set, nset)) + return -EFAULT; + new_set &= ~(sigmask(SIGKILL) | sigmask(SIGSTOP)); + + new_blocked = current->blocked; + + switch (how) { + case SIG_BLOCK: + sigaddsetmask(&new_blocked, new_set); + break; + case SIG_UNBLOCK: + sigdelsetmask(&new_blocked, new_set); + break; + case SIG_SETMASK: + compat_sig_setmask(&new_blocked, new_set); + break; + default: + return -EINVAL; + } + + set_current_blocked(&new_blocked); + } + + if (oset) { + if (put_user(old_set, oset)) + return -EFAULT; + } + + return 0; } #endif
diff --git a/kernel/fork.c b/kernel/fork.c index b9372a0..687a15d5 100644 --- a/kernel/fork.c +++ b/kernel/fork.c
@@ -47,6 +47,7 @@ #include <linux/audit.h> #include <linux/memcontrol.h> #include <linux/ftrace.h> +#include <linux/proc_fs.h> #include <linux/profile.h> #include <linux/rmap.h> #include <linux/ksm.h> @@ -1464,6 +1465,8 @@ if (p->io_context) exit_io_context(p); bad_fork_cleanup_namespaces: + if (unlikely(clone_flags & CLONE_NEWPID)) + pid_ns_release_proc(p->nsproxy->pid_ns); exit_task_namespaces(p); bad_fork_cleanup_mm: if (p->mm)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 6080f6b..3914c1e 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c
@@ -518,6 +518,7 @@ out_unlock: raw_spin_unlock(&desc->lock); } +EXPORT_SYMBOL(handle_edge_irq); #ifdef CONFIG_IRQ_EDGE_EOI_HANDLER /**
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index d86e254..192a302 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c
@@ -112,6 +112,7 @@ { return radix_tree_lookup(&irq_desc_tree, irq); } +EXPORT_SYMBOL(irq_to_desc); static void delete_irq_desc(unsigned int irq) {
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 0533a68..e5212ae 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c
@@ -6382,6 +6382,8 @@ if (!sg) return -ENOMEM; + sg->next = sg; + *per_cpu_ptr(sdd->sg, j) = sg; sgp = kzalloc_node(sizeof(struct sched_group_power),
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 079a93a..29111da 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c
@@ -294,6 +294,9 @@ if (!call->name || !call->class || !call->class->reg) continue; + if (call->flags & TRACE_EVENT_FL_IGNORE_ENABLE) + continue; + if (match && strcmp(match, call->name) != 0 && strcmp(match, call->class->system) != 0) @@ -1164,7 +1167,7 @@ return -1; } - if (call->class->reg) + if (call->class->reg && !(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE)) trace_create_file("enable", 0644, call->dir, call, enable);
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index 3dd15e8..e039906 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c
@@ -180,6 +180,7 @@ .event.type = etype, \ .class = &event_class_ftrace_##call, \ .print_fmt = print, \ + .flags = TRACE_EVENT_FL_IGNORE_ENABLE, \ }; \ struct ftrace_event_call __used \ __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call;
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 5a16423..ae8f708 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c
@@ -2498,7 +2498,6 @@ if (outside_reserve) { BUG_ON(huge_pte_none(pte)); if (unmap_ref_private(mm, vma, old_page, address)) { - BUG_ON(page_count(old_page) != 1); BUG_ON(huge_pte_none(pte)); spin_lock(&mm->page_table_lock); ptep = huge_pte_offset(mm, address & huge_page_mask(h));
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 31ab9c3..7685d4a 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c
@@ -4507,6 +4507,12 @@ swap_buffers: /* Swap primary and spare array */ thresholds->spare = thresholds->primary; + /* If all events are unregistered, free the spare array */ + if (!new) { + kfree(thresholds->spare); + thresholds->spare = NULL; + } + rcu_assign_pointer(thresholds->primary, new); /* To be sure that nobody uses thresholds */ @@ -5475,7 +5481,7 @@ * part of thp split is not executed yet. */ if (pmd_trans_huge_lock(pmd, vma) == 1) { - if (!mc.precharge) { + if (mc.precharge < HPAGE_PMD_NR) { spin_unlock(&vma->vm_mm->page_table_lock); return 0; }
diff --git a/mm/memory.c b/mm/memory.c index 6105f47..1e77da6 100644 --- a/mm/memory.c +++ b/mm/memory.c
@@ -1295,7 +1295,7 @@ static void unmap_single_vma(struct mmu_gather *tlb, struct vm_area_struct *vma, unsigned long start_addr, - unsigned long end_addr, unsigned long *nr_accounted, + unsigned long end_addr, struct zap_details *details) { unsigned long start = max(vma->vm_start, start_addr); @@ -1307,9 +1307,6 @@ if (end <= vma->vm_start) return; - if (vma->vm_flags & VM_ACCOUNT) - *nr_accounted += (end - start) >> PAGE_SHIFT; - if (unlikely(is_pfn_mapping(vma))) untrack_pfn_vma(vma, 0, 0); @@ -1339,8 +1336,6 @@ * @vma: the starting vma * @start_addr: virtual address at which to start unmapping * @end_addr: virtual address at which to end unmapping - * @nr_accounted: Place number of unmapped pages in vm-accountable vma's here - * @details: details of nonlinear truncation or shared cache invalidation * * Unmap all pages in the vma list. * @@ -1355,15 +1350,13 @@ */ void unmap_vmas(struct mmu_gather *tlb, struct vm_area_struct *vma, unsigned long start_addr, - unsigned long end_addr, unsigned long *nr_accounted, - struct zap_details *details) + unsigned long end_addr) { struct mm_struct *mm = vma->vm_mm; mmu_notifier_invalidate_range_start(mm, start_addr, end_addr); for ( ; vma && vma->vm_start < end_addr; vma = vma->vm_next) - unmap_single_vma(tlb, vma, start_addr, end_addr, nr_accounted, - details); + unmap_single_vma(tlb, vma, start_addr, end_addr, NULL); mmu_notifier_invalidate_range_end(mm, start_addr, end_addr); } @@ -1376,19 +1369,21 @@ * * Caller must protect the VMA list */ -void zap_page_range(struct vm_area_struct *vma, unsigned long address, +void zap_page_range(struct vm_area_struct *vma, unsigned long start, unsigned long size, struct zap_details *details) { struct mm_struct *mm = vma->vm_mm; struct mmu_gather tlb; - unsigned long end = address + size; - unsigned long nr_accounted = 0; + unsigned long end = start + size; lru_add_drain(); tlb_gather_mmu(&tlb, mm, 0); update_hiwater_rss(mm); - unmap_vmas(&tlb, vma, address, end, &nr_accounted, details); - tlb_finish_mmu(&tlb, address, end); + mmu_notifier_invalidate_range_start(mm, start, end); + for ( ; vma && vma->vm_start < end; vma = vma->vm_next) + unmap_single_vma(&tlb, vma, start, end, details); + mmu_notifier_invalidate_range_end(mm, start, end); + tlb_finish_mmu(&tlb, start, end); } /** @@ -1406,13 +1401,12 @@ struct mm_struct *mm = vma->vm_mm; struct mmu_gather tlb; unsigned long end = address + size; - unsigned long nr_accounted = 0; lru_add_drain(); tlb_gather_mmu(&tlb, mm, 0); update_hiwater_rss(mm); mmu_notifier_invalidate_range_start(mm, address, end); - unmap_single_vma(&tlb, vma, address, end, &nr_accounted, details); + unmap_single_vma(&tlb, vma, address, end, details); mmu_notifier_invalidate_range_end(mm, address, end); tlb_finish_mmu(&tlb, address, end); }
diff --git a/mm/mmap.c b/mm/mmap.c index 848ef52..69a1889 100644 --- a/mm/mmap.c +++ b/mm/mmap.c
@@ -1889,15 +1889,20 @@ */ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma) { + unsigned long nr_accounted = 0; + /* Update high watermark before we lower total_vm */ update_hiwater_vm(mm); do { long nrpages = vma_pages(vma); + if (vma->vm_flags & VM_ACCOUNT) + nr_accounted += nrpages; mm->total_vm -= nrpages; vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages); vma = remove_vma(vma); } while (vma); + vm_unacct_memory(nr_accounted); validate_mm(mm); } @@ -1912,13 +1917,11 @@ { struct vm_area_struct *next = prev? prev->vm_next: mm->mmap; struct mmu_gather tlb; - unsigned long nr_accounted = 0; lru_add_drain(); tlb_gather_mmu(&tlb, mm, 0); update_hiwater_rss(mm); - unmap_vmas(&tlb, vma, start, end, &nr_accounted, NULL); - vm_unacct_memory(nr_accounted); + unmap_vmas(&tlb, vma, start, end); free_pgtables(&tlb, vma, prev ? prev->vm_end : FIRST_USER_ADDRESS, next ? next->vm_start : 0); tlb_finish_mmu(&tlb, start, end); @@ -2305,8 +2308,7 @@ tlb_gather_mmu(&tlb, mm, 1); /* update_hiwater_rss(mm) here? but nobody should be looking */ /* Use -1 here to ensure all VMAs in the mm are unmapped */ - unmap_vmas(&tlb, vma, 0, -1, &nr_accounted, NULL); - vm_unacct_memory(nr_accounted); + unmap_vmas(&tlb, vma, 0, -1); free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0); tlb_finish_mmu(&tlb, 0, -1); @@ -2315,8 +2317,12 @@ * Walk the list again, actually closing and freeing it, * with preemption enabled, without holding any MM locks. */ - while (vma) + while (vma) { + if (vma->vm_flags & VM_ACCOUNT) + nr_accounted += vma_pages(vma); vma = remove_vma(vma); + } + vm_unacct_memory(nr_accounted); BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT); }
diff --git a/mm/nobootmem.c b/mm/nobootmem.c index e53bb8a..1983fb1 100644 --- a/mm/nobootmem.c +++ b/mm/nobootmem.c
@@ -82,8 +82,7 @@ static void __init __free_pages_memory(unsigned long start, unsigned long end) { - int i; - unsigned long start_aligned, end_aligned; + unsigned long i, start_aligned, end_aligned; int order = ilog2(BITS_PER_LONG); start_aligned = (start + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a712fb9..918330f 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c
@@ -5203,7 +5203,7 @@ int ret; ret = proc_dointvec_minmax(table, write, buffer, length, ppos); - if (!write || (ret == -EINVAL)) + if (!write || (ret < 0)) return ret; for_each_populated_zone(zone) { for_each_possible_cpu(cpu) {
diff --git a/mm/percpu.c b/mm/percpu.c index f47af91..bb4be74 100644 --- a/mm/percpu.c +++ b/mm/percpu.c
@@ -1132,20 +1132,20 @@ for (alloc_end += gi->nr_units / upa; alloc < alloc_end; alloc++) { if (!(alloc % apl)) { - printk("\n"); + printk(KERN_CONT "\n"); printk("%spcpu-alloc: ", lvl); } - printk("[%0*d] ", group_width, group); + printk(KERN_CONT "[%0*d] ", group_width, group); for (unit_end += upa; unit < unit_end; unit++) if (gi->cpu_map[unit] != NR_CPUS) - printk("%0*d ", cpu_width, + printk(KERN_CONT "%0*d ", cpu_width, gi->cpu_map[unit]); else - printk("%s ", empty_str); + printk(KERN_CONT "%s ", empty_str); } } - printk("\n"); + printk(KERN_CONT "\n"); } /** @@ -1650,6 +1650,16 @@ areas[group] = ptr; base = min(ptr, base); + } + + /* + * Copy data and free unused parts. This should happen after all + * allocations are complete; otherwise, we may end up with + * overlapping groups. + */ + for (group = 0; group < ai->nr_groups; group++) { + struct pcpu_group_info *gi = &ai->groups[group]; + void *ptr = areas[group]; for (i = 0; i < gi->nr_units; i++, ptr += ai->unit_size) { if (gi->cpu_map[i] == NR_CPUS) { @@ -1885,6 +1895,8 @@ fc = __alloc_bootmem(unit_size, PAGE_SIZE, __pa(MAX_DMA_ADDRESS)); if (!ai || !fc) panic("Failed to allocate memory for percpu areas."); + /* kmemleak tracks the percpu allocations separately */ + kmemleak_free(fc); ai->dyn_size = unit_size; ai->unit_size = unit_size;
diff --git a/mm/slub.c b/mm/slub.c index ffe13fd..80848cd 100644 --- a/mm/slub.c +++ b/mm/slub.c
@@ -2040,7 +2040,7 @@ struct kmem_cache *s = info; struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu); - return !!(c->page); + return c->page || c->partial; } static void flush_all(struct kmem_cache *s)
diff --git a/net/802/Makefile b/net/802/Makefile index 7893d67..a30d6e3 100644 --- a/net/802/Makefile +++ b/net/802/Makefile
@@ -4,7 +4,6 @@ # Check the p8022 selections against net/core/Makefile. obj-$(CONFIG_LLC) += p8022.o psnap.o -obj-$(CONFIG_TR) += p8022.o psnap.o tr.o obj-$(CONFIG_NET_FC) += fc.o obj-$(CONFIG_FDDI) += fddi.o obj-$(CONFIG_HIPPI) += hippi.o
diff --git a/net/802/p8022.c b/net/802/p8022.c index 7f353c4..0bda8de 100644 --- a/net/802/p8022.c +++ b/net/802/p8022.c
@@ -1,6 +1,5 @@ /* - * NET3: Support for 802.2 demultiplexing off Ethernet (Token ring - * is kept separate see p8022tr.c) + * NET3: Support for 802.2 demultiplexing off Ethernet * 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
diff --git a/net/802/stp.c b/net/802/stp.c index 15540b7..2c40ba0 100644 --- a/net/802/stp.c +++ b/net/802/stp.c
@@ -46,7 +46,7 @@ proto = rcu_dereference(garp_protos[eh->h_dest[5] - GARP_ADDR_MIN]); if (proto && - compare_ether_addr(eh->h_dest, proto->group_address)) + !ether_addr_equal(eh->h_dest, proto->group_address)) goto err; } else proto = rcu_dereference(stp_proto);
diff --git a/net/802/tr.c b/net/802/tr.c deleted file mode 100644 index 30a352e..0000000 --- a/net/802/tr.c +++ /dev/null
@@ -1,670 +0,0 @@ -/* - * NET3: Token ring device handling subroutines - * - * 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. - * - * Fixes: 3 Feb 97 Paul Norton <pnorton@cts.com> Minor routing fixes. - * Added rif table to /proc/net/tr_rif and rif timeout to - * /proc/sys/net/token-ring/rif_timeout. - * 22 Jun 98 Paul Norton <p.norton@computer.org> Rearranged - * tr_header and tr_type_trans to handle passing IPX SNAP and - * 802.2 through the correct layers. Eliminated tr_reformat. - * - */ - -#include <asm/uaccess.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/jiffies.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/socket.h> -#include <linux/in.h> -#include <linux/inet.h> -#include <linux/netdevice.h> -#include <linux/trdevice.h> -#include <linux/skbuff.h> -#include <linux/errno.h> -#include <linux/timer.h> -#include <linux/net.h> -#include <linux/proc_fs.h> -#include <linux/seq_file.h> -#include <linux/init.h> -#include <linux/sysctl.h> -#include <linux/slab.h> -#include <net/arp.h> -#include <net/net_namespace.h> - -static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev); -static void rif_check_expire(unsigned long dummy); - -#define TR_SR_DEBUG 0 - -/* - * Each RIF entry we learn is kept this way - */ - -struct rif_cache { - unsigned char addr[TR_ALEN]; - int iface; - __be16 rcf; - __be16 rseg[8]; - struct rif_cache *next; - unsigned long last_used; - unsigned char local_ring; -}; - -#define RIF_TABLE_SIZE 32 - -/* - * We hash the RIF cache 32 ways. We do after all have to look it - * up a lot. - */ - -static struct rif_cache *rif_table[RIF_TABLE_SIZE]; - -static DEFINE_SPINLOCK(rif_lock); - - -/* - * Garbage disposal timer. - */ - -static struct timer_list rif_timer; - -static int sysctl_tr_rif_timeout = 60*10*HZ; - -static inline unsigned long rif_hash(const unsigned char *addr) -{ - unsigned long x; - - x = addr[0]; - x = (x << 2) ^ addr[1]; - x = (x << 2) ^ addr[2]; - x = (x << 2) ^ addr[3]; - x = (x << 2) ^ addr[4]; - x = (x << 2) ^ addr[5]; - - x ^= x >> 8; - - return x & (RIF_TABLE_SIZE - 1); -} - -/* - * Put the headers on a token ring packet. Token ring source routing - * makes this a little more exciting than on ethernet. - */ - -static int tr_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, - const void *daddr, const void *saddr, unsigned int len) -{ - struct trh_hdr *trh; - int hdr_len; - - /* - * Add the 802.2 SNAP header if IP as the IPv4/IPv6 code calls - * dev->hard_header directly. - */ - if (type == ETH_P_IP || type == ETH_P_IPV6 || type == ETH_P_ARP) - { - struct trllc *trllc; - - hdr_len = sizeof(struct trh_hdr) + sizeof(struct trllc); - trh = (struct trh_hdr *)skb_push(skb, hdr_len); - trllc = (struct trllc *)(trh+1); - trllc->dsap = trllc->ssap = EXTENDED_SAP; - trllc->llc = UI_CMD; - trllc->protid[0] = trllc->protid[1] = trllc->protid[2] = 0x00; - trllc->ethertype = htons(type); - } - else - { - hdr_len = sizeof(struct trh_hdr); - trh = (struct trh_hdr *)skb_push(skb, hdr_len); - } - - trh->ac=AC; - trh->fc=LLC_FRAME; - - if(saddr) - memcpy(trh->saddr,saddr,dev->addr_len); - else - memcpy(trh->saddr,dev->dev_addr,dev->addr_len); - - /* - * Build the destination and then source route the frame - */ - - if(daddr) - { - memcpy(trh->daddr,daddr,dev->addr_len); - tr_source_route(skb, trh, dev); - return hdr_len; - } - - return -hdr_len; -} - -/* - * A neighbour discovery of some species (eg arp) has completed. We - * can now send the packet. - */ - -static int tr_rebuild_header(struct sk_buff *skb) -{ - struct trh_hdr *trh=(struct trh_hdr *)skb->data; - struct trllc *trllc=(struct trllc *)(skb->data+sizeof(struct trh_hdr)); - struct net_device *dev = skb->dev; - - /* - * FIXME: We don't yet support IPv6 over token rings - */ - - if(trllc->ethertype != htons(ETH_P_IP)) { - printk("tr_rebuild_header: Don't know how to resolve type %04X addresses ?\n", ntohs(trllc->ethertype)); - return 0; - } - -#ifdef CONFIG_INET - if(arp_find(trh->daddr, skb)) { - return 1; - } - else -#endif - { - tr_source_route(skb,trh,dev); - return 0; - } -} - -/* - * Some of this is a bit hackish. We intercept RIF information - * used for source routing. We also grab IP directly and don't feed - * it via SNAP. - */ - -__be16 tr_type_trans(struct sk_buff *skb, struct net_device *dev) -{ - - struct trh_hdr *trh; - struct trllc *trllc; - unsigned int riflen=0; - - skb->dev = dev; - skb_reset_mac_header(skb); - trh = tr_hdr(skb); - - if(trh->saddr[0] & TR_RII) - riflen = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8; - - trllc = (struct trllc *)(skb->data+sizeof(struct trh_hdr)-TR_MAXRIFLEN+riflen); - - skb_pull(skb,sizeof(struct trh_hdr)-TR_MAXRIFLEN+riflen); - - if(*trh->daddr & 0x80) - { - if(!memcmp(trh->daddr,dev->broadcast,TR_ALEN)) - skb->pkt_type=PACKET_BROADCAST; - else - skb->pkt_type=PACKET_MULTICAST; - } - else if ( (trh->daddr[0] & 0x01) && (trh->daddr[1] & 0x00) && (trh->daddr[2] & 0x5E)) - { - skb->pkt_type=PACKET_MULTICAST; - } - else if(dev->flags & IFF_PROMISC) - { - if(memcmp(trh->daddr, dev->dev_addr, TR_ALEN)) - skb->pkt_type=PACKET_OTHERHOST; - } - - if ((skb->pkt_type != PACKET_BROADCAST) && - (skb->pkt_type != PACKET_MULTICAST)) - tr_add_rif_info(trh,dev) ; - - /* - * Strip the SNAP header from ARP packets since we don't - * pass them through to the 802.2/SNAP layers. - */ - - if (trllc->dsap == EXTENDED_SAP && - (trllc->ethertype == htons(ETH_P_IP) || - trllc->ethertype == htons(ETH_P_IPV6) || - trllc->ethertype == htons(ETH_P_ARP))) - { - skb_pull(skb, sizeof(struct trllc)); - return trllc->ethertype; - } - - return htons(ETH_P_TR_802_2); -} - -/* - * We try to do source routing... - */ - -void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh, - struct net_device *dev) -{ - int slack; - unsigned int hash; - struct rif_cache *entry; - unsigned char *olddata; - unsigned long flags; - static const unsigned char mcast_func_addr[] - = {0xC0,0x00,0x00,0x04,0x00,0x00}; - - spin_lock_irqsave(&rif_lock, flags); - - /* - * Broadcasts are single route as stated in RFC 1042 - */ - if( (!memcmp(&(trh->daddr[0]),&(dev->broadcast[0]),TR_ALEN)) || - (!memcmp(&(trh->daddr[0]),&(mcast_func_addr[0]), TR_ALEN)) ) - { - trh->rcf=htons((((sizeof(trh->rcf)) << 8) & TR_RCF_LEN_MASK) - | TR_RCF_FRAME2K | TR_RCF_LIMITED_BROADCAST); - trh->saddr[0]|=TR_RII; - } - else - { - hash = rif_hash(trh->daddr); - /* - * Walk the hash table and look for an entry - */ - for(entry=rif_table[hash];entry && memcmp(&(entry->addr[0]),&(trh->daddr[0]),TR_ALEN);entry=entry->next); - - /* - * If we found an entry we can route the frame. - */ - if(entry) - { -#if TR_SR_DEBUG -printk("source routing for %pM\n", trh->daddr); -#endif - if(!entry->local_ring && (ntohs(entry->rcf) & TR_RCF_LEN_MASK) >> 8) - { - trh->rcf=entry->rcf; - memcpy(&trh->rseg[0],&entry->rseg[0],8*sizeof(unsigned short)); - trh->rcf^=htons(TR_RCF_DIR_BIT); - trh->rcf&=htons(0x1fff); /* Issam Chehab <ichehab@madge1.demon.co.uk> */ - - trh->saddr[0]|=TR_RII; -#if TR_SR_DEBUG - printk("entry found with rcf %04x\n", entry->rcf); - } - else - { - printk("entry found but without rcf length, local=%02x\n", entry->local_ring); -#endif - } - entry->last_used=jiffies; - } - else - { - /* - * Without the information we simply have to shout - * on the wire. The replies should rapidly clean this - * situation up. - */ - trh->rcf=htons((((sizeof(trh->rcf)) << 8) & TR_RCF_LEN_MASK) - | TR_RCF_FRAME2K | TR_RCF_LIMITED_BROADCAST); - trh->saddr[0]|=TR_RII; -#if TR_SR_DEBUG - printk("no entry in rif table found - broadcasting frame\n"); -#endif - } - } - - /* Compress the RIF here so we don't have to do it in the driver(s) */ - if (!(trh->saddr[0] & 0x80)) - slack = 18; - else - slack = 18 - ((ntohs(trh->rcf) & TR_RCF_LEN_MASK)>>8); - olddata = skb->data; - spin_unlock_irqrestore(&rif_lock, flags); - - skb_pull(skb, slack); - memmove(skb->data, olddata, sizeof(struct trh_hdr) - slack); -} - -/* - * We have learned some new RIF information for our source - * routing. - */ - -static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev) -{ - unsigned int hash, rii_p = 0; - unsigned long flags; - struct rif_cache *entry; - unsigned char saddr0; - - spin_lock_irqsave(&rif_lock, flags); - saddr0 = trh->saddr[0]; - - /* - * Firstly see if the entry exists - */ - - if(trh->saddr[0] & TR_RII) - { - trh->saddr[0]&=0x7f; - if (((ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8) > 2) - { - rii_p = 1; - } - } - - hash = rif_hash(trh->saddr); - for(entry=rif_table[hash];entry && memcmp(&(entry->addr[0]),&(trh->saddr[0]),TR_ALEN);entry=entry->next); - - if(entry==NULL) - { -#if TR_SR_DEBUG - printk("adding rif_entry: addr:%pM rcf:%04X\n", - trh->saddr, ntohs(trh->rcf)); -#endif - /* - * Allocate our new entry. A failure to allocate loses - * use the information. This is harmless. - * - * FIXME: We ought to keep some kind of cache size - * limiting and adjust the timers to suit. - */ - entry=kmalloc(sizeof(struct rif_cache),GFP_ATOMIC); - - if(!entry) - { - printk(KERN_DEBUG "tr.c: Couldn't malloc rif cache entry !\n"); - spin_unlock_irqrestore(&rif_lock, flags); - return; - } - - memcpy(&(entry->addr[0]),&(trh->saddr[0]),TR_ALEN); - entry->iface = dev->ifindex; - entry->next=rif_table[hash]; - entry->last_used=jiffies; - rif_table[hash]=entry; - - if (rii_p) - { - entry->rcf = trh->rcf & htons((unsigned short)~TR_RCF_BROADCAST_MASK); - memcpy(&(entry->rseg[0]),&(trh->rseg[0]),8*sizeof(unsigned short)); - entry->local_ring = 0; - } - else - { - entry->local_ring = 1; - } - } - else /* Y. Tahara added */ - { - /* - * Update existing entries - */ - if (!entry->local_ring) - if (entry->rcf != (trh->rcf & htons((unsigned short)~TR_RCF_BROADCAST_MASK)) && - !(trh->rcf & htons(TR_RCF_BROADCAST_MASK))) - { -#if TR_SR_DEBUG -printk("updating rif_entry: addr:%pM rcf:%04X\n", - trh->saddr, ntohs(trh->rcf)); -#endif - entry->rcf = trh->rcf & htons((unsigned short)~TR_RCF_BROADCAST_MASK); - memcpy(&(entry->rseg[0]),&(trh->rseg[0]),8*sizeof(unsigned short)); - } - entry->last_used=jiffies; - } - trh->saddr[0]=saddr0; /* put the routing indicator back for tcpdump */ - spin_unlock_irqrestore(&rif_lock, flags); -} - -/* - * Scan the cache with a timer and see what we need to throw out. - */ - -static void rif_check_expire(unsigned long dummy) -{ - int i; - unsigned long flags, next_interval = jiffies + sysctl_tr_rif_timeout/2; - - spin_lock_irqsave(&rif_lock, flags); - - for(i =0; i < RIF_TABLE_SIZE; i++) { - struct rif_cache *entry, **pentry; - - pentry = rif_table+i; - while((entry=*pentry) != NULL) { - unsigned long expires - = entry->last_used + sysctl_tr_rif_timeout; - - if (time_before_eq(expires, jiffies)) { - *pentry = entry->next; - kfree(entry); - } else { - pentry = &entry->next; - - if (time_before(expires, next_interval)) - next_interval = expires; - } - } - } - - spin_unlock_irqrestore(&rif_lock, flags); - - mod_timer(&rif_timer, next_interval); - -} - -/* - * Generate the /proc/net information for the token ring RIF - * routing. - */ - -#ifdef CONFIG_PROC_FS - -static struct rif_cache *rif_get_idx(loff_t pos) -{ - int i; - struct rif_cache *entry; - loff_t off = 0; - - for(i = 0; i < RIF_TABLE_SIZE; i++) - for(entry = rif_table[i]; entry; entry = entry->next) { - if (off == pos) - return entry; - ++off; - } - - return NULL; -} - -static void *rif_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(&rif_lock) -{ - spin_lock_irq(&rif_lock); - - return *pos ? rif_get_idx(*pos - 1) : SEQ_START_TOKEN; -} - -static void *rif_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - int i; - struct rif_cache *ent = v; - - ++*pos; - - if (v == SEQ_START_TOKEN) { - i = -1; - goto scan; - } - - if (ent->next) - return ent->next; - - i = rif_hash(ent->addr); - scan: - while (++i < RIF_TABLE_SIZE) { - if ((ent = rif_table[i]) != NULL) - return ent; - } - return NULL; -} - -static void rif_seq_stop(struct seq_file *seq, void *v) - __releases(&rif_lock) -{ - spin_unlock_irq(&rif_lock); -} - -static int rif_seq_show(struct seq_file *seq, void *v) -{ - int j, rcf_len, segment, brdgnmb; - struct rif_cache *entry = v; - - if (v == SEQ_START_TOKEN) - seq_puts(seq, - "if TR address TTL rcf routing segments\n"); - else { - struct net_device *dev = dev_get_by_index(&init_net, entry->iface); - long ttl = (long) (entry->last_used + sysctl_tr_rif_timeout) - - (long) jiffies; - - seq_printf(seq, "%s %pM %7li ", - dev?dev->name:"?", - entry->addr, - ttl/HZ); - - if (entry->local_ring) - seq_puts(seq, "local\n"); - else { - - seq_printf(seq, "%04X", ntohs(entry->rcf)); - rcf_len = ((ntohs(entry->rcf) & TR_RCF_LEN_MASK)>>8)-2; - if (rcf_len) - rcf_len >>= 1; - for(j = 1; j < rcf_len; j++) { - if(j==1) { - segment=ntohs(entry->rseg[j-1])>>4; - seq_printf(seq," %03X",segment); - } - - segment=ntohs(entry->rseg[j])>>4; - brdgnmb=ntohs(entry->rseg[j-1])&0x00f; - seq_printf(seq,"-%01X-%03X",brdgnmb,segment); - } - seq_putc(seq, '\n'); - } - - if (dev) - dev_put(dev); - } - return 0; -} - - -static const struct seq_operations rif_seq_ops = { - .start = rif_seq_start, - .next = rif_seq_next, - .stop = rif_seq_stop, - .show = rif_seq_show, -}; - -static int rif_seq_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &rif_seq_ops); -} - -static const struct file_operations rif_seq_fops = { - .owner = THIS_MODULE, - .open = rif_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -#endif - -static const struct header_ops tr_header_ops = { - .create = tr_header, - .rebuild= tr_rebuild_header, -}; - -static void tr_setup(struct net_device *dev) -{ - /* - * Configure and register - */ - - dev->header_ops = &tr_header_ops; - - dev->type = ARPHRD_IEEE802_TR; - dev->hard_header_len = TR_HLEN; - dev->mtu = 2000; - dev->addr_len = TR_ALEN; - dev->tx_queue_len = 100; /* Long queues on tr */ - - memset(dev->broadcast,0xFF, TR_ALEN); - - /* New-style flags. */ - dev->flags = IFF_BROADCAST | IFF_MULTICAST ; -} - -/** - * alloc_trdev - Register token ring device - * @sizeof_priv: Size of additional driver-private structure to be allocated - * for this token ring device - * - * Fill in the fields of the device structure with token ring-generic values. - * - * Constructs a new net device, complete with a private data area of - * size @sizeof_priv. A 32-byte (not bit) alignment is enforced for - * this private data area. - */ -struct net_device *alloc_trdev(int sizeof_priv) -{ - return alloc_netdev(sizeof_priv, "tr%d", tr_setup); -} - -#ifdef CONFIG_SYSCTL -static struct ctl_table tr_table[] = { - { - .procname = "rif_timeout", - .data = &sysctl_tr_rif_timeout, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec - }, - { }, -}; -#endif - -/* - * Called during bootup. We don't actually have to initialise - * too much for this. - */ - -static int __init rif_init(void) -{ - rif_timer.expires = jiffies + sysctl_tr_rif_timeout; - setup_timer(&rif_timer, rif_check_expire, 0); - add_timer(&rif_timer); -#ifdef CONFIG_SYSCTL - register_net_sysctl(&init_net, "net/token-ring", tr_table); -#endif - proc_net_fops_create(&init_net, "tr_rif", S_IRUGO, &rif_seq_fops); - return 0; -} - -module_init(rif_init); - -EXPORT_SYMBOL(tr_type_trans); -EXPORT_SYMBOL(alloc_trdev); - -MODULE_LICENSE("GPL");
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index efea35b..6089f0c 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c
@@ -266,19 +266,19 @@ struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev); /* May be called without an actual change */ - if (!compare_ether_addr(vlan->real_dev_addr, dev->dev_addr)) + if (ether_addr_equal(vlan->real_dev_addr, dev->dev_addr)) return; /* vlan address was different from the old address and is equal to * the new address */ - if (compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && - !compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) + if (!ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) && + ether_addr_equal(vlandev->dev_addr, dev->dev_addr)) dev_uc_del(dev, vlandev->dev_addr); /* vlan address was equal to the old address and is different from * the new address */ - if (!compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && - compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) + if (ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) && + !ether_addr_equal(vlandev->dev_addr, dev->dev_addr)) dev_uc_add(dev, vlandev->dev_addr); memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN);
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 4d39d80..8ca533c 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c
@@ -31,8 +31,7 @@ /* Our lower layer thinks this is not local, let's make sure. * This allows the VLAN to have a different MAC than the * underlying device, and still route correctly. */ - if (!compare_ether_addr(eth_hdr(skb)->h_dest, - vlan_dev->dev_addr)) + if (ether_addr_equal(eth_hdr(skb)->h_dest, vlan_dev->dev_addr)) skb->pkt_type = PACKET_HOST; }
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 9988d4a..da1bc9c 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c
@@ -157,7 +157,7 @@ skb = __vlan_hwaccel_put_tag(skb, vlan_tci); } - skb_set_dev(skb, vlan_dev_priv(dev)->real_dev); + skb->dev = vlan_dev_priv(dev)->real_dev; len = skb->len; if (netpoll_tx_running(dev)) return skb->dev->netdev_ops->ndo_start_xmit(skb, skb->dev); @@ -277,7 +277,7 @@ !(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) return -ENETDOWN; - if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { + if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) { err = dev_uc_add(real_dev, dev->dev_addr); if (err < 0) goto out; @@ -307,7 +307,7 @@ if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(real_dev, -1); del_unicast: - if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) + if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) dev_uc_del(real_dev, dev->dev_addr); out: netif_carrier_off(dev); @@ -326,7 +326,7 @@ if (dev->flags & IFF_PROMISC) dev_set_promiscuity(real_dev, -1); - if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) + if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) dev_uc_del(real_dev, dev->dev_addr); netif_carrier_off(dev); @@ -345,13 +345,13 @@ if (!(dev->flags & IFF_UP)) goto out; - if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) { + if (!ether_addr_equal(addr->sa_data, real_dev->dev_addr)) { err = dev_uc_add(real_dev, addr->sa_data); if (err < 0) return err; } - if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) + if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) dev_uc_del(real_dev, dev->dev_addr); out:
diff --git a/net/Kconfig b/net/Kconfig index e07272d..245831b 100644 --- a/net/Kconfig +++ b/net/Kconfig
@@ -207,10 +207,10 @@ source "drivers/net/appletalk/Kconfig" source "net/x25/Kconfig" source "net/lapb/Kconfig" -source "net/econet/Kconfig" source "net/wanrouter/Kconfig" source "net/phonet/Kconfig" source "net/ieee802154/Kconfig" +source "net/mac802154/Kconfig" source "net/sched/Kconfig" source "net/dcb/Kconfig" source "net/dns_resolver/Kconfig" @@ -246,9 +246,6 @@ select DQL default y -config HAVE_BPF_JIT - bool - config BPF_JIT bool "enable BPF Just In Time compiler" depends on HAVE_BPF_JIT @@ -295,7 +292,7 @@ module will be called tcp_probe. config NET_DROP_MONITOR - boolean "Network packet drop alerting service" + tristate "Network packet drop alerting service" depends on INET && EXPERIMENTAL && TRACEPOINTS ---help--- This feature provides an alerting service to userspace in the @@ -340,3 +337,7 @@ endif # if NET + +# Used by archs to tell that they support BPF_JIT +config HAVE_BPF_JIT + bool
diff --git a/net/Makefile b/net/Makefile index ad432fa..4f4ee08 100644 --- a/net/Makefile +++ b/net/Makefile
@@ -40,7 +40,6 @@ obj-$(CONFIG_ATM) += atm/ obj-$(CONFIG_L2TP) += l2tp/ obj-$(CONFIG_DECNET) += decnet/ -obj-$(CONFIG_ECONET) += econet/ obj-$(CONFIG_PHONET) += phonet/ ifneq ($(CONFIG_VLAN_8021Q),) obj-y += 8021q/ @@ -60,6 +59,7 @@ obj-y += dcb/ endif obj-$(CONFIG_IEEE802154) += ieee802154/ +obj-$(CONFIG_MAC802154) += mac802154/ ifeq ($(CONFIG_NET),y) obj-$(CONFIG_SYSCTL) += sysctl_net.o
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c index 62dc8bf..bbd3b63 100644 --- a/net/atm/ioctl.c +++ b/net/atm/ioctl.c
@@ -97,9 +97,8 @@ error = sock_get_timestampns(sk, argp); goto done; case ATM_SETSC: - if (net_ratelimit()) - pr_warning("ATM_SETSC is obsolete; used by %s:%d\n", - current->comm, task_pid_nr(current)); + net_warn_ratelimited("ATM_SETSC is obsolete; used by %s:%d\n", + current->comm, task_pid_nr(current)); error = 0; goto done; case ATMSIGD_CTRL: @@ -123,8 +122,7 @@ work for 32-bit userspace. TBH I don't really want to think about it at all. dwmw2. */ if (compat) { - if (net_ratelimit()) - pr_warning("32-bit task cannot be atmsigd\n"); + net_warn_ratelimited("32-bit task cannot be atmsigd\n"); error = -EINVAL; goto done; }
diff --git a/net/atm/lec.c b/net/atm/lec.c index f1964ca..a7d1721 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c
@@ -26,11 +26,6 @@ #include <linux/spinlock.h> #include <linux/seq_file.h> -/* TokenRing if needed */ -#ifdef CONFIG_TR -#include <linux/trdevice.h> -#endif - /* And atm device */ #include <linux/atmdev.h> #include <linux/atmlec.h> @@ -163,50 +158,6 @@ #endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */ /* - * Modelled after tr_type_trans - * All multicast and ARE or STE frames go to BUS. - * Non source routed frames go by destination address. - * Last hop source routed frames go by destination address. - * Not last hop source routed frames go by _next_ route descriptor. - * Returns pointer to destination MAC address or fills in rdesc - * and returns NULL. - */ -#ifdef CONFIG_TR -static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc) -{ - struct trh_hdr *trh; - unsigned int riflen, num_rdsc; - - trh = (struct trh_hdr *)packet; - if (trh->daddr[0] & (uint8_t) 0x80) - return bus_mac; /* multicast */ - - if (trh->saddr[0] & TR_RII) { - riflen = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8; - if ((ntohs(trh->rcf) >> 13) != 0) - return bus_mac; /* ARE or STE */ - } else - return trh->daddr; /* not source routed */ - - if (riflen < 6) - return trh->daddr; /* last hop, source routed */ - - /* riflen is 6 or more, packet has more than one route descriptor */ - num_rdsc = (riflen / 2) - 1; - memset(rdesc, 0, ETH_ALEN); - /* offset 4 comes from LAN destination field in LE control frames */ - if (trh->rcf & htons((uint16_t) TR_RCF_DIR_BIT)) - memcpy(&rdesc[4], &trh->rseg[num_rdsc - 2], sizeof(__be16)); - else { - memcpy(&rdesc[4], &trh->rseg[1], sizeof(__be16)); - rdesc[5] = ((ntohs(trh->rseg[0]) & 0x000f) | (rdesc[5] & 0xf0)); - } - - return NULL; -} -#endif /* CONFIG_TR */ - -/* * Open/initialize the netdevice. This is called (in the current kernel) * sometime after booting when the 'ifconfig' program is run. * @@ -257,9 +208,6 @@ struct lec_arp_table *entry; unsigned char *dst; int min_frame_size; -#ifdef CONFIG_TR - unsigned char rdesc[ETH_ALEN]; /* Token Ring route descriptor */ -#endif int is_rdesc; pr_debug("called\n"); @@ -290,24 +238,10 @@ } skb_push(skb, 2); - /* Put le header to place, works for TokenRing too */ + /* Put le header to place */ lec_h = (struct lecdatahdr_8023 *)skb->data; lec_h->le_header = htons(priv->lecid); -#ifdef CONFIG_TR - /* - * Ugly. Use this to realign Token Ring packets for - * e.g. PCA-200E driver. - */ - if (priv->is_trdev) { - skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN); - kfree_skb(skb); - if (skb2 == NULL) - return NETDEV_TX_OK; - skb = skb2; - } -#endif - #if DUMP_PACKETS >= 2 #define MAX_DUMP_SKB 99 #elif DUMP_PACKETS >= 1 @@ -321,12 +255,7 @@ #endif /* DUMP_PACKETS >= 1 */ /* Minimum ethernet-frame size */ -#ifdef CONFIG_TR - if (priv->is_trdev) - min_frame_size = LEC_MINIMUM_8025_SIZE; - else -#endif - min_frame_size = LEC_MINIMUM_8023_SIZE; + min_frame_size = LEC_MINIMUM_8023_SIZE; if (skb->len < min_frame_size) { if ((skb->len + skb_tailroom(skb)) < min_frame_size) { skb2 = skb_copy_expand(skb, 0, @@ -345,15 +274,6 @@ /* Send to right vcc */ is_rdesc = 0; dst = lec_h->h_dest; -#ifdef CONFIG_TR - if (priv->is_trdev) { - dst = get_tr_dst(skb->data + 2, rdesc); - if (dst == NULL) { - dst = rdesc; - is_rdesc = 1; - } - } -#endif entry = NULL; vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry); pr_debug("%s:vcc:%p vcc_flags:%lx, entry:%p\n", @@ -710,12 +630,7 @@ dev_kfree_skb(skb); return; } -#ifdef CONFIG_TR - if (priv->is_trdev) - dst = ((struct lecdatahdr_8025 *)skb->data)->h_dest; - else -#endif - dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest; + dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest; /* * If this is a Data Direct VCC, and the VCC does not match @@ -723,16 +638,7 @@ */ spin_lock_irqsave(&priv->lec_arp_lock, flags); if (lec_is_data_direct(vcc)) { -#ifdef CONFIG_TR - if (priv->is_trdev) - src = - ((struct lecdatahdr_8025 *)skb->data)-> - h_source; - else -#endif - src = - ((struct lecdatahdr_8023 *)skb->data)-> - h_source; + src = ((struct lecdatahdr_8023 *)skb->data)->h_source; entry = lec_arp_find(priv, src); if (entry && entry->vcc != vcc) { lec_arp_remove(priv, entry); @@ -750,12 +656,7 @@ if (!hlist_empty(&priv->lec_arp_empty_ones)) lec_arp_check_empties(priv, vcc, skb); skb_pull(skb, 2); /* skip lec_id */ -#ifdef CONFIG_TR - if (priv->is_trdev) - skb->protocol = tr_type_trans(skb, dev); - else -#endif - skb->protocol = eth_type_trans(skb, dev); + skb->protocol = eth_type_trans(skb, dev); dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len; memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data)); @@ -827,27 +728,13 @@ i = 0; else i = arg; -#ifdef CONFIG_TR if (arg >= MAX_LEC_ITF) return -EINVAL; -#else /* Reserve the top NUM_TR_DEVS for TR */ - if (arg >= (MAX_LEC_ITF - NUM_TR_DEVS)) - return -EINVAL; -#endif if (!dev_lec[i]) { - int is_trdev, size; - - is_trdev = 0; - if (i >= (MAX_LEC_ITF - NUM_TR_DEVS)) - is_trdev = 1; + int size; size = sizeof(struct lec_priv); -#ifdef CONFIG_TR - if (is_trdev) - dev_lec[i] = alloc_trdev(size); - else -#endif - dev_lec[i] = alloc_etherdev(size); + dev_lec[i] = alloc_etherdev(size); if (!dev_lec[i]) return -ENOMEM; dev_lec[i]->netdev_ops = &lec_netdev_ops; @@ -858,7 +745,6 @@ } priv = netdev_priv(dev_lec[i]); - priv->is_trdev = is_trdev; } else { priv = netdev_priv(dev_lec[i]); if (priv->lecd) @@ -1255,7 +1141,7 @@ struct sk_buff *skb; struct lec_priv *priv = netdev_priv(dev); - if (compare_ether_addr(lan_dst, dev->dev_addr)) + if (!ether_addr_equal(lan_dst, dev->dev_addr)) return 0; /* not our mac address */ kfree(priv->tlvs); /* NULL if there was no previous association */ @@ -1662,7 +1548,7 @@ head = &priv->lec_arp_tables[HASH(mac_addr[ETH_ALEN - 1])]; hlist_for_each_entry(entry, node, head, next) { - if (!compare_ether_addr(mac_addr, entry->mac_addr)) + if (ether_addr_equal(mac_addr, entry->mac_addr)) return entry; } return NULL; @@ -1849,7 +1735,7 @@ case 1: return priv->mcast_vcc; case 2: /* LANE2 wants arp for multicast addresses */ - if (!compare_ether_addr(mac_to_find, bus_mac)) + if (ether_addr_equal(mac_to_find, bus_mac)) return priv->mcast_vcc; break; default: @@ -2372,15 +2258,7 @@ struct hlist_node *node, *next; struct lec_arp_table *entry, *tmp; struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data; - unsigned char *src; -#ifdef CONFIG_TR - struct lecdatahdr_8025 *tr_hdr = (struct lecdatahdr_8025 *)skb->data; - - if (priv->is_trdev) - src = tr_hdr->h_source; - else -#endif - src = hdr->h_source; + unsigned char *src = hdr->h_source; spin_lock_irqsave(&priv->lec_arp_lock, flags); hlist_for_each_entry_safe(entry, node, next,
diff --git a/net/atm/lec.h b/net/atm/lec.h index dfc0719..c730e57 100644 --- a/net/atm/lec.h +++ b/net/atm/lec.h
@@ -142,7 +142,6 @@ int itfnum; /* e.g. 2 for lec2, 5 for lec5 */ struct lane2_ops *lane2_ops; /* can be NULL for LANE v1 */ int is_proxy; /* bridge between ATM and Ethernet */ - int is_trdev; /* Device type, 0 = Ethernet, 1 = TokenRing */ }; struct lec_vcc_priv {
diff --git a/net/atm/mpc.c b/net/atm/mpc.c index aa972409f..d4cc1be 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c
@@ -592,8 +592,7 @@ goto non_ip; while (i < mpc->number_of_mps_macs) { - if (!compare_ether_addr(eth->h_dest, - (mpc->mps_macs + i*ETH_ALEN))) + if (ether_addr_equal(eth->h_dest, mpc->mps_macs + i * ETH_ALEN)) if (send_via_shortcut(skb, mpc) == 0) /* try shortcut */ return NETDEV_TX_OK; i++;
diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index 916380c..3b588f8 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c
@@ -83,8 +83,8 @@ va_start(args, fmt); vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args); - fdebug_log(bat_priv->debug_log, "[%10lu] %s", - (jiffies / HZ), tmp_log_buf); + fdebug_log(bat_priv->debug_log, "[%10u] %s", + jiffies_to_msecs(jiffies), tmp_log_buf); va_end(args); return 0;
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 8b2db2e..dc53798 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c
@@ -30,6 +30,31 @@ #include "send.h" #include "bat_algo.h" +static struct neigh_node *bat_iv_ogm_neigh_new(struct hard_iface *hard_iface, + const uint8_t *neigh_addr, + struct orig_node *orig_node, + struct orig_node *orig_neigh, + uint32_t seqno) +{ + struct neigh_node *neigh_node; + + neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, seqno); + if (!neigh_node) + goto out; + + INIT_LIST_HEAD(&neigh_node->bonding_list); + + neigh_node->orig_node = orig_neigh; + neigh_node->if_incoming = hard_iface; + + spin_lock_bh(&orig_node->neigh_list_lock); + hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); + spin_unlock_bh(&orig_node->neigh_list_lock); + +out: + return neigh_node; +} + static int bat_iv_ogm_iface_enable(struct hard_iface *hard_iface) { struct batman_ogm_packet *batman_ogm_packet; @@ -67,16 +92,7 @@ hard_iface->packet_buff = NULL; } -static void bat_iv_ogm_primary_iface_set(struct hard_iface *hard_iface) -{ - struct batman_ogm_packet *batman_ogm_packet; - - batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; - batman_ogm_packet->flags = PRIMARIES_FIRST_HOP; - batman_ogm_packet->header.ttl = TTL; -} - -static void bat_iv_ogm_update_mac(struct hard_iface *hard_iface) +static void bat_iv_ogm_iface_update_mac(struct hard_iface *hard_iface) { struct batman_ogm_packet *batman_ogm_packet; @@ -87,6 +103,15 @@ hard_iface->net_dev->dev_addr, ETH_ALEN); } +static void bat_iv_ogm_primary_iface_set(struct hard_iface *hard_iface) +{ + struct batman_ogm_packet *batman_ogm_packet; + + batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; + batman_ogm_packet->flags = PRIMARIES_FIRST_HOP; + batman_ogm_packet->header.ttl = TTL; +} + /* when do we schedule our own ogm to be sent */ static unsigned long bat_iv_ogm_emit_send_time(const struct bat_priv *bat_priv) { @@ -480,11 +505,11 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node, const struct ethhdr *ethhdr, struct batman_ogm_packet *batman_ogm_packet, - int directlink, struct hard_iface *if_incoming) + bool is_single_hop_neigh, + bool is_from_best_next_hop, + struct hard_iface *if_incoming) { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); - struct neigh_node *router; - uint8_t in_tq, in_ttl, tq_avg = 0; uint8_t tt_num_changes; if (batman_ogm_packet->header.ttl <= 1) { @@ -492,48 +517,37 @@ return; } - router = orig_node_get_router(orig_node); + if (!is_from_best_next_hop) { + /* Mark the forwarded packet when it is not coming from our + * best next hop. We still need to forward the packet for our + * neighbor link quality detection to work in case the packet + * originated from a single hop neighbor. Otherwise we can + * simply drop the ogm. + */ + if (is_single_hop_neigh) + batman_ogm_packet->flags |= NOT_BEST_NEXT_HOP; + else + return; + } - in_tq = batman_ogm_packet->tq; - in_ttl = batman_ogm_packet->header.ttl; tt_num_changes = batman_ogm_packet->tt_num_changes; batman_ogm_packet->header.ttl--; memcpy(batman_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN); - /* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast - * of our best tq value */ - if (router && router->tq_avg != 0) { - - /* rebroadcast ogm of best ranking neighbor as is */ - if (!compare_eth(router->addr, ethhdr->h_source)) { - batman_ogm_packet->tq = router->tq_avg; - - if (router->last_ttl) - batman_ogm_packet->header.ttl = - router->last_ttl - 1; - } - - tq_avg = router->tq_avg; - } - - if (router) - neigh_node_free_ref(router); - /* apply hop penalty */ batman_ogm_packet->tq = hop_penalty(batman_ogm_packet->tq, bat_priv); bat_dbg(DBG_BATMAN, bat_priv, - "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", - in_tq, tq_avg, batman_ogm_packet->tq, in_ttl - 1, - batman_ogm_packet->header.ttl); + "Forwarding packet: tq: %i, ttl: %i\n", + batman_ogm_packet->tq, batman_ogm_packet->header.ttl); batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno); batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc); /* switch of primaries first hop flag when forwarding */ batman_ogm_packet->flags &= ~PRIMARIES_FIRST_HOP; - if (directlink) + if (is_single_hop_neigh) batman_ogm_packet->flags |= DIRECTLINK; else batman_ogm_packet->flags &= ~DIRECTLINK; @@ -622,12 +636,12 @@ if (is_duplicate) continue; - spin_lock_bh(&tmp_neigh_node->tq_lock); + spin_lock_bh(&tmp_neigh_node->lq_update_lock); ring_buffer_set(tmp_neigh_node->tq_recv, &tmp_neigh_node->tq_index, 0); tmp_neigh_node->tq_avg = ring_buffer_avg(tmp_neigh_node->tq_recv); - spin_unlock_bh(&tmp_neigh_node->tq_lock); + spin_unlock_bh(&tmp_neigh_node->lq_update_lock); } if (!neigh_node) { @@ -637,8 +651,9 @@ if (!orig_tmp) goto unlock; - neigh_node = create_neighbor(orig_node, orig_tmp, - ethhdr->h_source, if_incoming); + neigh_node = bat_iv_ogm_neigh_new(if_incoming, ethhdr->h_source, + orig_node, orig_tmp, + batman_ogm_packet->seqno); orig_node_free_ref(orig_tmp); if (!neigh_node) @@ -650,14 +665,14 @@ rcu_read_unlock(); orig_node->flags = batman_ogm_packet->flags; - neigh_node->last_valid = jiffies; + neigh_node->last_seen = jiffies; - spin_lock_bh(&neigh_node->tq_lock); + spin_lock_bh(&neigh_node->lq_update_lock); ring_buffer_set(neigh_node->tq_recv, &neigh_node->tq_index, batman_ogm_packet->tq); neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv); - spin_unlock_bh(&neigh_node->tq_lock); + spin_unlock_bh(&neigh_node->lq_update_lock); if (!is_duplicate) { orig_node->last_ttl = batman_ogm_packet->header.ttl; @@ -763,19 +778,20 @@ rcu_read_unlock(); if (!neigh_node) - neigh_node = create_neighbor(orig_neigh_node, - orig_neigh_node, - orig_neigh_node->orig, - if_incoming); + neigh_node = bat_iv_ogm_neigh_new(if_incoming, + orig_neigh_node->orig, + orig_neigh_node, + orig_neigh_node, + batman_ogm_packet->seqno); if (!neigh_node) goto out; - /* if orig_node is direct neighbor update neigh_node last_valid */ + /* if orig_node is direct neighbor update neigh_node last_seen */ if (orig_node == orig_neigh_node) - neigh_node->last_valid = jiffies; + neigh_node->last_seen = jiffies; - orig_node->last_valid = jiffies; + orig_node->last_seen = jiffies; /* find packet count of corresponding one hop neighbor */ spin_lock_bh(&orig_node->ogm_cnt_lock); @@ -918,7 +934,9 @@ struct neigh_node *orig_neigh_router = NULL; int has_directlink_flag; int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; - int is_broadcast = 0, is_bidirectional, is_single_hop_neigh; + int is_broadcast = 0, is_bidirectional; + bool is_single_hop_neigh = false; + bool is_from_best_next_hop = false; int is_duplicate; uint32_t if_incoming_seqno; @@ -942,8 +960,8 @@ has_directlink_flag = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0); - is_single_hop_neigh = (compare_eth(ethhdr->h_source, - batman_ogm_packet->orig) ? 1 : 0); + if (compare_eth(ethhdr->h_source, batman_ogm_packet->orig)) + is_single_hop_neigh = true; bat_dbg(DBG_BATMAN, bat_priv, "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, ttvn %u, crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n", @@ -1040,6 +1058,13 @@ return; } + if (batman_ogm_packet->flags & NOT_BEST_NEXT_HOP) { + bat_dbg(DBG_BATMAN, bat_priv, + "Drop packet: ignoring all packets not forwarded from the best next hop (sender: %pM)\n", + ethhdr->h_source); + return; + } + orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig); if (!orig_node) return; @@ -1064,6 +1089,10 @@ if (router) router_router = orig_node_get_router(router->orig_node); + if ((router && router->tq_avg != 0) && + (compare_eth(router->addr, ethhdr->h_source))) + is_from_best_next_hop = true; + /* avoid temporary routing loops */ if (router && router_router && (compare_eth(router->addr, batman_ogm_packet->prev_sender)) && @@ -1114,7 +1143,8 @@ /* mark direct link on incoming interface */ bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, - 1, if_incoming); + is_single_hop_neigh, is_from_best_next_hop, + if_incoming); bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: rebroadcast neighbor packet with direct link flag\n"); @@ -1137,7 +1167,8 @@ bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: rebroadcast originator packet\n"); bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, - 0, if_incoming); + is_single_hop_neigh, is_from_best_next_hop, + if_incoming); out_neigh: if ((orig_neigh_node) && (!is_single_hop_neigh)) @@ -1153,13 +1184,25 @@ orig_node_free_ref(orig_node); } -static void bat_iv_ogm_receive(struct hard_iface *if_incoming, - struct sk_buff *skb) +static int bat_iv_ogm_receive(struct sk_buff *skb, + struct hard_iface *if_incoming) { + struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct batman_ogm_packet *batman_ogm_packet; struct ethhdr *ethhdr; int buff_pos = 0, packet_len; unsigned char *tt_buff, *packet_buff; + bool ret; + + ret = check_management_packet(skb, if_incoming, BATMAN_OGM_HLEN); + if (!ret) + return NET_RX_DROP; + + /* did we receive a B.A.T.M.A.N. IV OGM packet on an interface + * that does not have B.A.T.M.A.N. IV enabled ? + */ + if (bat_priv->bat_algo_ops->bat_ogm_emit != bat_iv_ogm_emit) + return NET_RX_DROP; packet_len = skb_headlen(skb); ethhdr = (struct ethhdr *)skb_mac_header(skb); @@ -1185,20 +1228,38 @@ (packet_buff + buff_pos); } while (bat_iv_ogm_aggr_packet(buff_pos, packet_len, batman_ogm_packet->tt_num_changes)); + + kfree_skb(skb); + return NET_RX_SUCCESS; } static struct bat_algo_ops batman_iv __read_mostly = { .name = "BATMAN IV", .bat_iface_enable = bat_iv_ogm_iface_enable, .bat_iface_disable = bat_iv_ogm_iface_disable, + .bat_iface_update_mac = bat_iv_ogm_iface_update_mac, .bat_primary_iface_set = bat_iv_ogm_primary_iface_set, - .bat_ogm_update_mac = bat_iv_ogm_update_mac, .bat_ogm_schedule = bat_iv_ogm_schedule, .bat_ogm_emit = bat_iv_ogm_emit, - .bat_ogm_receive = bat_iv_ogm_receive, }; int __init bat_iv_init(void) { - return bat_algo_register(&batman_iv); + int ret; + + /* batman originator packet */ + ret = recv_handler_register(BAT_IV_OGM, bat_iv_ogm_receive); + if (ret < 0) + goto out; + + ret = bat_algo_register(&batman_iv); + if (ret < 0) + goto handler_unregister; + + goto out; + +handler_unregister: + recv_handler_unregister(BAT_IV_OGM); +out: + return ret; }
diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index 2c81688..5bc7b66d 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c
@@ -63,7 +63,7 @@ .store = _store, \ }; -#define BAT_ATTR_STORE_BOOL(_name, _post_func) \ +#define BAT_ATTR_SIF_STORE_BOOL(_name, _post_func) \ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ char *buff, size_t count) \ { \ @@ -73,9 +73,9 @@ &bat_priv->_name, net_dev); \ } -#define BAT_ATTR_SHOW_BOOL(_name) \ -ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ - char *buff) \ +#define BAT_ATTR_SIF_SHOW_BOOL(_name) \ +ssize_t show_##_name(struct kobject *kobj, \ + struct attribute *attr, char *buff) \ { \ struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ return sprintf(buff, "%s\n", \ @@ -83,16 +83,17 @@ "disabled" : "enabled"); \ } \ -/* Use this, if you are going to turn a [name] in bat_priv on or off */ -#define BAT_ATTR_BOOL(_name, _mode, _post_func) \ - static BAT_ATTR_STORE_BOOL(_name, _post_func) \ - static BAT_ATTR_SHOW_BOOL(_name) \ +/* Use this, if you are going to turn a [name] in the soft-interface + * (bat_priv) on or off */ +#define BAT_ATTR_SIF_BOOL(_name, _mode, _post_func) \ + static BAT_ATTR_SIF_STORE_BOOL(_name, _post_func) \ + static BAT_ATTR_SIF_SHOW_BOOL(_name) \ static BAT_ATTR(_name, _mode, show_##_name, store_##_name) -#define BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \ +#define BAT_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ - char *buff, size_t count) \ + char *buff, size_t count) \ { \ struct net_device *net_dev = kobj_to_netdev(kobj); \ struct bat_priv *bat_priv = netdev_priv(net_dev); \ @@ -100,19 +101,62 @@ attr, &bat_priv->_name, net_dev); \ } -#define BAT_ATTR_SHOW_UINT(_name) \ -ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ - char *buff) \ +#define BAT_ATTR_SIF_SHOW_UINT(_name) \ +ssize_t show_##_name(struct kobject *kobj, \ + struct attribute *attr, char *buff) \ { \ struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ return sprintf(buff, "%i\n", atomic_read(&bat_priv->_name)); \ } \ -/* Use this, if you are going to set [name] in bat_priv to unsigned integer - * values only */ -#define BAT_ATTR_UINT(_name, _mode, _min, _max, _post_func) \ - static BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \ - static BAT_ATTR_SHOW_UINT(_name) \ +/* Use this, if you are going to set [name] in the soft-interface + * (bat_priv) to an unsigned integer value */ +#define BAT_ATTR_SIF_UINT(_name, _mode, _min, _max, _post_func) \ + static BAT_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \ + static BAT_ATTR_SIF_SHOW_UINT(_name) \ + static BAT_ATTR(_name, _mode, show_##_name, store_##_name) + + +#define BAT_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \ +ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ + char *buff, size_t count) \ +{ \ + struct net_device *net_dev = kobj_to_netdev(kobj); \ + struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); \ + ssize_t length; \ + \ + if (!hard_iface) \ + return 0; \ + \ + length = __store_uint_attr(buff, count, _min, _max, _post_func, \ + attr, &hard_iface->_name, net_dev); \ + \ + hardif_free_ref(hard_iface); \ + return length; \ +} + +#define BAT_ATTR_HIF_SHOW_UINT(_name) \ +ssize_t show_##_name(struct kobject *kobj, \ + struct attribute *attr, char *buff) \ +{ \ + struct net_device *net_dev = kobj_to_netdev(kobj); \ + struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); \ + ssize_t length; \ + \ + if (!hard_iface) \ + return 0; \ + \ + length = sprintf(buff, "%i\n", atomic_read(&hard_iface->_name));\ + \ + hardif_free_ref(hard_iface); \ + return length; \ +} + +/* Use this, if you are going to set [name] in hard_iface to an + * unsigned integer value*/ +#define BAT_ATTR_HIF_UINT(_name, _mode, _min, _max, _post_func) \ + static BAT_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \ + static BAT_ATTR_HIF_SHOW_UINT(_name) \ static BAT_ATTR(_name, _mode, show_##_name, store_##_name) @@ -384,24 +428,24 @@ return gw_bandwidth_set(net_dev, buff, count); } -BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); -BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); +BAT_ATTR_SIF_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); +BAT_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); #ifdef CONFIG_BATMAN_ADV_BLA -BAT_ATTR_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL); +BAT_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL); #endif -BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); -BAT_ATTR_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); +BAT_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); +BAT_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); static BAT_ATTR(routing_algo, S_IRUGO, show_bat_algo, NULL); static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode); -BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); -BAT_ATTR_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); -BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, - post_gw_deselect); +BAT_ATTR_SIF_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); +BAT_ATTR_SIF_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); +BAT_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, + post_gw_deselect); static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth, store_gw_bwidth); #ifdef CONFIG_BATMAN_ADV_DEBUG -BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 15, NULL); +BAT_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, 15, NULL); #endif static struct bat_attribute *mesh_attrs[] = {
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index ad394c6..8bf9751 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 B.A.T.M.A.N. contributors: + * Copyright (C) 2011-2012 B.A.T.M.A.N. contributors: * * Simon Wunderlich *
diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h index 4a8e4fc..e39f93a 100644 --- a/net/batman-adv/bridge_loop_avoidance.h +++ b/net/batman-adv/bridge_loop_avoidance.h
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 B.A.T.M.A.N. contributors: + * Copyright (C) 2011-2012 B.A.T.M.A.N. contributors: * * Simon Wunderlich *
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 6f9b9b7..47f7186 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c
@@ -558,10 +558,10 @@ p++; /* ...and then we jump over the data */ - if (pkt_len < *p) + if (pkt_len < 1 + (*p)) goto out; - pkt_len -= *p; - p += (*p); + pkt_len -= 1 + (*p); + p += 1 + (*p); } } out:
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 47c79d7..dc334fa 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c
@@ -32,12 +32,6 @@ #include <linux/if_arp.h> - -static int batman_skb_recv(struct sk_buff *skb, - struct net_device *dev, - struct packet_type *ptype, - struct net_device *orig_dev); - void hardif_free_rcu(struct rcu_head *rcu) { struct hard_iface *hard_iface; @@ -179,9 +173,9 @@ net_dev->dev_addr)) continue; - pr_warning("The newly added mac address (%pM) already exists on: %s\n", - net_dev->dev_addr, hard_iface->net_dev->name); - pr_warning("It is strongly recommended to keep mac addresses unique to avoid problems!\n"); + pr_warn("The newly added mac address (%pM) already exists on: %s\n", + net_dev->dev_addr, hard_iface->net_dev->name); + pr_warn("It is strongly recommended to keep mac addresses unique to avoid problems!\n"); } rcu_read_unlock(); } @@ -234,7 +228,7 @@ bat_priv = netdev_priv(hard_iface->soft_iface); - bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface); + bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface); hard_iface->if_status = IF_TO_BE_ACTIVATED; /** @@ -530,7 +524,7 @@ check_known_mac_addr(hard_iface->net_dev); bat_priv = netdev_priv(hard_iface->soft_iface); - bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface); + bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface); primary_if = primary_if_get_selected(bat_priv); if (!primary_if) @@ -551,113 +545,6 @@ return NOTIFY_DONE; } -/* incoming packets with the batman ethertype received on any active hard - * interface */ -static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *ptype, - struct net_device *orig_dev) -{ - struct bat_priv *bat_priv; - struct batman_ogm_packet *batman_ogm_packet; - struct hard_iface *hard_iface; - int ret; - - hard_iface = container_of(ptype, struct hard_iface, batman_adv_ptype); - skb = skb_share_check(skb, GFP_ATOMIC); - - /* skb was released by skb_share_check() */ - if (!skb) - goto err_out; - - /* packet should hold at least type and version */ - if (unlikely(!pskb_may_pull(skb, 2))) - goto err_free; - - /* expect a valid ethernet header here. */ - if (unlikely(skb->mac_len != ETH_HLEN || !skb_mac_header(skb))) - goto err_free; - - if (!hard_iface->soft_iface) - goto err_free; - - bat_priv = netdev_priv(hard_iface->soft_iface); - - if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) - goto err_free; - - /* discard frames on not active interfaces */ - if (hard_iface->if_status != IF_ACTIVE) - goto err_free; - - batman_ogm_packet = (struct batman_ogm_packet *)skb->data; - - if (batman_ogm_packet->header.version != COMPAT_VERSION) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: incompatible batman version (%i)\n", - batman_ogm_packet->header.version); - goto err_free; - } - - /* all receive handlers return whether they received or reused - * the supplied skb. if not, we have to free the skb. */ - - switch (batman_ogm_packet->header.packet_type) { - /* batman originator packet */ - case BAT_IV_OGM: - ret = recv_bat_ogm_packet(skb, hard_iface); - break; - - /* batman icmp packet */ - case BAT_ICMP: - ret = recv_icmp_packet(skb, hard_iface); - break; - - /* unicast packet */ - case BAT_UNICAST: - ret = recv_unicast_packet(skb, hard_iface); - break; - - /* fragmented unicast packet */ - case BAT_UNICAST_FRAG: - ret = recv_ucast_frag_packet(skb, hard_iface); - break; - - /* broadcast packet */ - case BAT_BCAST: - ret = recv_bcast_packet(skb, hard_iface); - break; - - /* vis packet */ - case BAT_VIS: - ret = recv_vis_packet(skb, hard_iface); - break; - /* Translation table query (request or response) */ - case BAT_TT_QUERY: - ret = recv_tt_query(skb, hard_iface); - break; - /* Roaming advertisement */ - case BAT_ROAM_ADV: - ret = recv_roam_adv(skb, hard_iface); - break; - default: - ret = NET_RX_DROP; - } - - if (ret == NET_RX_DROP) - kfree_skb(skb); - - /* return NET_RX_SUCCESS in any case as we - * most probably dropped the packet for - * routing-logical reasons. */ - - return NET_RX_SUCCESS; - -err_free: - kfree_skb(skb); -err_out: - return NET_RX_DROP; -} - /* This function returns true if the interface represented by ifindex is a * 802.11 wireless device */ bool is_wifi_iface(int ifindex)
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 7913272..083a299 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c
@@ -39,6 +39,7 @@ /* List manipulations on hardif_list have to be rtnl_lock()'ed, * list traversals just rcu-locked */ struct list_head hardif_list; +static int (*recv_packet_handler[256])(struct sk_buff *, struct hard_iface *); char bat_routing_algo[20] = "BATMAN IV"; static struct hlist_head bat_algo_list; @@ -46,11 +47,15 @@ struct workqueue_struct *bat_event_workqueue; +static void recv_handler_init(void); + static int __init batman_init(void) { INIT_LIST_HEAD(&hardif_list); INIT_HLIST_HEAD(&bat_algo_list); + recv_handler_init(); + bat_iv_init(); /* the name should not be longer than 10 chars - see @@ -179,6 +184,120 @@ return 0; } +static int recv_unhandled_packet(struct sk_buff *skb, + struct hard_iface *recv_if) +{ + return NET_RX_DROP; +} + +/* incoming packets with the batman ethertype received on any active hard + * interface + */ +int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *ptype, struct net_device *orig_dev) +{ + struct bat_priv *bat_priv; + struct batman_ogm_packet *batman_ogm_packet; + struct hard_iface *hard_iface; + uint8_t idx; + int ret; + + hard_iface = container_of(ptype, struct hard_iface, batman_adv_ptype); + skb = skb_share_check(skb, GFP_ATOMIC); + + /* skb was released by skb_share_check() */ + if (!skb) + goto err_out; + + /* packet should hold at least type and version */ + if (unlikely(!pskb_may_pull(skb, 2))) + goto err_free; + + /* expect a valid ethernet header here. */ + if (unlikely(skb->mac_len != ETH_HLEN || !skb_mac_header(skb))) + goto err_free; + + if (!hard_iface->soft_iface) + goto err_free; + + bat_priv = netdev_priv(hard_iface->soft_iface); + + if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) + goto err_free; + + /* discard frames on not active interfaces */ + if (hard_iface->if_status != IF_ACTIVE) + goto err_free; + + batman_ogm_packet = (struct batman_ogm_packet *)skb->data; + + if (batman_ogm_packet->header.version != COMPAT_VERSION) { + bat_dbg(DBG_BATMAN, bat_priv, + "Drop packet: incompatible batman version (%i)\n", + batman_ogm_packet->header.version); + goto err_free; + } + + /* all receive handlers return whether they received or reused + * the supplied skb. if not, we have to free the skb. + */ + idx = batman_ogm_packet->header.packet_type; + ret = (*recv_packet_handler[idx])(skb, hard_iface); + + if (ret == NET_RX_DROP) + kfree_skb(skb); + + /* return NET_RX_SUCCESS in any case as we + * most probably dropped the packet for + * routing-logical reasons. + */ + return NET_RX_SUCCESS; + +err_free: + kfree_skb(skb); +err_out: + return NET_RX_DROP; +} + +static void recv_handler_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(recv_packet_handler); i++) + recv_packet_handler[i] = recv_unhandled_packet; + + /* batman icmp packet */ + recv_packet_handler[BAT_ICMP] = recv_icmp_packet; + /* unicast packet */ + recv_packet_handler[BAT_UNICAST] = recv_unicast_packet; + /* fragmented unicast packet */ + recv_packet_handler[BAT_UNICAST_FRAG] = recv_ucast_frag_packet; + /* broadcast packet */ + recv_packet_handler[BAT_BCAST] = recv_bcast_packet; + /* vis packet */ + recv_packet_handler[BAT_VIS] = recv_vis_packet; + /* Translation table query (request or response) */ + recv_packet_handler[BAT_TT_QUERY] = recv_tt_query; + /* Roaming advertisement */ + recv_packet_handler[BAT_ROAM_ADV] = recv_roam_adv; +} + +int recv_handler_register(uint8_t packet_type, + int (*recv_handler)(struct sk_buff *, + struct hard_iface *)) +{ + if (recv_packet_handler[packet_type] != &recv_unhandled_packet) + return -EBUSY; + + recv_packet_handler[packet_type] = recv_handler; + return 0; +} + +void recv_handler_unregister(uint8_t packet_type) +{ + recv_packet_handler[packet_type] = recv_unhandled_packet; +} + static struct bat_algo_ops *bat_algo_get(char *name) { struct bat_algo_ops *bat_algo_ops = NULL, *bat_algo_ops_tmp; @@ -210,11 +329,10 @@ /* all algorithms must implement all ops (for now) */ if (!bat_algo_ops->bat_iface_enable || !bat_algo_ops->bat_iface_disable || + !bat_algo_ops->bat_iface_update_mac || !bat_algo_ops->bat_primary_iface_set || - !bat_algo_ops->bat_ogm_update_mac || !bat_algo_ops->bat_ogm_schedule || - !bat_algo_ops->bat_ogm_emit || - !bat_algo_ops->bat_ogm_receive) { + !bat_algo_ops->bat_ogm_emit) { pr_info("Routing algo '%s' does not implement required ops\n", bat_algo_ops->name); goto out;
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index d9832ac..f4a3ec0 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h
@@ -28,7 +28,7 @@ #define DRIVER_DEVICE "batman-adv" #ifndef SOURCE_VERSION -#define SOURCE_VERSION "2012.1.0" +#define SOURCE_VERSION "2012.2.0" #endif /* B.A.T.M.A.N. parameters */ @@ -155,6 +155,12 @@ void inc_module_count(void); void dec_module_count(void); int is_my_mac(const uint8_t *addr); +int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *ptype, struct net_device *orig_dev); +int recv_handler_register(uint8_t packet_type, + int (*recv_handler)(struct sk_buff *, + struct hard_iface *)); +void recv_handler_unregister(uint8_t packet_type); int bat_algo_register(struct bat_algo_ops *bat_algo_ops); int bat_algo_select(struct bat_priv *bat_priv, char *name); int bat_algo_seq_print_text(struct seq_file *seq, void *offset);
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index ce49698..41147942 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c
@@ -35,7 +35,8 @@ static void start_purge_timer(struct bat_priv *bat_priv) { INIT_DELAYED_WORK(&bat_priv->orig_work, purge_orig); - queue_delayed_work(bat_event_workqueue, &bat_priv->orig_work, 1 * HZ); + queue_delayed_work(bat_event_workqueue, + &bat_priv->orig_work, msecs_to_jiffies(1000)); } /* returns 1 if they are the same originator */ @@ -84,35 +85,30 @@ return router; } -struct neigh_node *create_neighbor(struct orig_node *orig_node, - struct orig_node *orig_neigh_node, - const uint8_t *neigh, - struct hard_iface *if_incoming) +struct neigh_node *batadv_neigh_node_new(struct hard_iface *hard_iface, + const uint8_t *neigh_addr, + uint32_t seqno) { - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); + struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct neigh_node *neigh_node; - bat_dbg(DBG_BATMAN, bat_priv, - "Creating new last-hop neighbor of originator\n"); - neigh_node = kzalloc(sizeof(*neigh_node), GFP_ATOMIC); if (!neigh_node) - return NULL; + goto out; INIT_HLIST_NODE(&neigh_node->list); - INIT_LIST_HEAD(&neigh_node->bonding_list); - spin_lock_init(&neigh_node->tq_lock); - memcpy(neigh_node->addr, neigh, ETH_ALEN); - neigh_node->orig_node = orig_neigh_node; - neigh_node->if_incoming = if_incoming; + memcpy(neigh_node->addr, neigh_addr, ETH_ALEN); + spin_lock_init(&neigh_node->lq_update_lock); /* extra reference for return */ atomic_set(&neigh_node->refcount, 2); - spin_lock_bh(&orig_node->neigh_list_lock); - hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); - spin_unlock_bh(&orig_node->neigh_list_lock); + bat_dbg(DBG_BATMAN, bat_priv, + "Creating new neighbor %pM, initial seqno %d\n", + neigh_addr, seqno); + +out: return neigh_node; } @@ -274,6 +270,7 @@ struct hlist_node *node, *node_tmp; struct neigh_node *neigh_node; bool neigh_purged = false; + unsigned long last_seen; *best_neigh_node = NULL; @@ -283,11 +280,13 @@ hlist_for_each_entry_safe(neigh_node, node, node_tmp, &orig_node->neigh_list, list) { - if ((has_timed_out(neigh_node->last_valid, PURGE_TIMEOUT)) || + if ((has_timed_out(neigh_node->last_seen, PURGE_TIMEOUT)) || (neigh_node->if_incoming->if_status == IF_INACTIVE) || (neigh_node->if_incoming->if_status == IF_NOT_IN_USE) || (neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED)) { + last_seen = neigh_node->last_seen; + if ((neigh_node->if_incoming->if_status == IF_INACTIVE) || (neigh_node->if_incoming->if_status == @@ -300,9 +299,9 @@ neigh_node->if_incoming->net_dev->name); else bat_dbg(DBG_BATMAN, bat_priv, - "neighbor timeout: originator %pM, neighbor: %pM, last_valid: %lu\n", + "neighbor timeout: originator %pM, neighbor: %pM, last_seen: %u\n", orig_node->orig, neigh_node->addr, - (neigh_node->last_valid / HZ)); + jiffies_to_msecs(last_seen)); neigh_purged = true; @@ -325,10 +324,11 @@ { struct neigh_node *best_neigh_node; - if (has_timed_out(orig_node->last_valid, 2 * PURGE_TIMEOUT)) { + if (has_timed_out(orig_node->last_seen, 2 * PURGE_TIMEOUT)) { bat_dbg(DBG_BATMAN, bat_priv, - "Originator timeout: originator %pM, last_valid %lu\n", - orig_node->orig, (orig_node->last_valid / HZ)); + "Originator timeout: originator %pM, last_seen %u\n", + orig_node->orig, + jiffies_to_msecs(orig_node->last_seen)); return true; } else { if (purge_orig_neighbors(bat_priv, orig_node, @@ -446,9 +446,9 @@ goto next; last_seen_secs = jiffies_to_msecs(jiffies - - orig_node->last_valid) / 1000; + orig_node->last_seen) / 1000; last_seen_msecs = jiffies_to_msecs(jiffies - - orig_node->last_valid) % 1000; + orig_node->last_seen) % 1000; seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:", orig_node->orig, last_seen_secs,
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h index 3fe2eda..f74d0d6 100644 --- a/net/batman-adv/originator.h +++ b/net/batman-adv/originator.h
@@ -29,10 +29,9 @@ void purge_orig_ref(struct bat_priv *bat_priv); void orig_node_free_ref(struct orig_node *orig_node); struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr); -struct neigh_node *create_neighbor(struct orig_node *orig_node, - struct orig_node *orig_neigh_node, - const uint8_t *neigh, - struct hard_iface *if_incoming); +struct neigh_node *batadv_neigh_node_new(struct hard_iface *hard_iface, + const uint8_t *neigh_addr, + uint32_t seqno); void neigh_node_free_ref(struct neigh_node *neigh_node); struct neigh_node *orig_node_get_router(struct orig_node *orig_node); int orig_seq_print_text(struct seq_file *seq, void *offset);
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index f54969c..0ee1af7 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h
@@ -39,6 +39,7 @@ #define COMPAT_VERSION 14 enum batman_iv_flags { + NOT_BEST_NEXT_HOP = 1 << 3, PRIMARIES_FIRST_HOP = 1 << 4, VIS_SERVER = 1 << 5, DIRECTLINK = 1 << 6
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index ff56086..840e2c6 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c
@@ -234,51 +234,46 @@ { if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { - if (has_timed_out(*last_reset, RESET_PROTECTION_MS)) { - - *last_reset = jiffies; - bat_dbg(DBG_BATMAN, bat_priv, - "old packet received, start protection\n"); - - return 0; - } else { + if (!has_timed_out(*last_reset, RESET_PROTECTION_MS)) return 1; - } + + *last_reset = jiffies; + bat_dbg(DBG_BATMAN, bat_priv, + "old packet received, start protection\n"); } + return 0; } -int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *hard_iface) +bool check_management_packet(struct sk_buff *skb, + struct hard_iface *hard_iface, + int header_len) { - struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct ethhdr *ethhdr; /* drop packet if it has not necessary minimum size */ - if (unlikely(!pskb_may_pull(skb, BATMAN_OGM_HLEN))) - return NET_RX_DROP; + if (unlikely(!pskb_may_pull(skb, header_len))) + return false; ethhdr = (struct ethhdr *)skb_mac_header(skb); /* packet with broadcast indication but unicast recipient */ if (!is_broadcast_ether_addr(ethhdr->h_dest)) - return NET_RX_DROP; + return false; /* packet with broadcast sender address */ if (is_broadcast_ether_addr(ethhdr->h_source)) - return NET_RX_DROP; + return false; /* create a copy of the skb, if needed, to modify it. */ if (skb_cow(skb, 0) < 0) - return NET_RX_DROP; + return false; /* keep skb linear */ if (skb_linearize(skb) < 0) - return NET_RX_DROP; + return false; - bat_priv->bat_algo_ops->bat_ogm_receive(hard_iface, skb); - - kfree_skb(skb); - return NET_RX_SUCCESS; + return true; } static int recv_my_icmp_packet(struct bat_priv *bat_priv, @@ -918,12 +913,20 @@ /* Check whether I have to reroute the packet */ if (seq_before(unicast_packet->ttvn, curr_ttvn) || tt_poss_change) { - /* Linearize the skb before accessing it */ - if (skb_linearize(skb) < 0) + /* check if there is enough data before accessing it */ + if (pskb_may_pull(skb, sizeof(struct unicast_packet) + + ETH_HLEN) < 0) return 0; ethhdr = (struct ethhdr *)(skb->data + sizeof(struct unicast_packet)); + + /* we don't have an updated route for this client, so we should + * not try to reroute the packet!! + */ + if (tt_global_client_is_roaming(bat_priv, ethhdr->h_dest)) + return 1; + orig_node = transtable_search(bat_priv, NULL, ethhdr->h_dest); if (!orig_node) {
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h index 3d729cb..d6bbbeb 100644 --- a/net/batman-adv/routing.h +++ b/net/batman-adv/routing.h
@@ -23,6 +23,9 @@ #define _NET_BATMAN_ADV_ROUTING_H_ void slide_own_bcast_window(struct hard_iface *hard_iface); +bool check_management_packet(struct sk_buff *skb, + struct hard_iface *hard_iface, + int header_len); void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, struct neigh_node *neigh_node); int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if); @@ -30,7 +33,6 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if); int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if); int recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if); -int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *recv_if); int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if); int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if); struct neigh_node *find_router(struct bat_priv *bat_priv,
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 7c66b61..f47299f 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c
@@ -45,8 +45,8 @@ goto send_skb_err; if (!(hard_iface->net_dev->flags & IFF_UP)) { - pr_warning("Interface %s is not up - can't send packet via that interface!\n", - hard_iface->net_dev->name); + pr_warn("Interface %s is not up - can't send packet via that interface!\n", + hard_iface->net_dev->name); goto send_skb_err; } @@ -292,7 +292,7 @@ /* if we still have some more bcasts to send */ if (forw_packet->num_packets < 3) { _add_bcast_packet_to_list(bat_priv, forw_packet, - ((5 * HZ) / 1000)); + msecs_to_jiffies(5)); return; }
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index a38d315..a66c2dc 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c
@@ -1,7 +1,7 @@ /* * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * - * Marek Lindner, Simon Wunderlich + * Marek Lindner, Simon Wunderlich, Antonio Quartulli * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -206,6 +206,8 @@ if (tt_local_entry) { tt_local_entry->last_seen = jiffies; + /* possibly unset the TT_CLIENT_PENDING flag */ + tt_local_entry->common.flags &= ~TT_CLIENT_PENDING; goto out; } @@ -2117,3 +2119,22 @@ } } } + +/* returns true whether we know that the client has moved from its old + * originator to another one. This entry is kept is still kept for consistency + * purposes + */ +bool tt_global_client_is_roaming(struct bat_priv *bat_priv, uint8_t *addr) +{ + struct tt_global_entry *tt_global_entry; + bool ret = false; + + tt_global_entry = tt_global_hash_find(bat_priv, addr); + if (!tt_global_entry) + goto out; + + ret = tt_global_entry->common.flags & TT_CLIENT_ROAM; + tt_global_entry_free_ref(tt_global_entry); +out: + return ret; +}
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h index bfebe26..c43374d 100644 --- a/net/batman-adv/translation-table.h +++ b/net/batman-adv/translation-table.h
@@ -1,7 +1,7 @@ /* * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * - * Marek Lindner, Simon Wunderlich + * Marek Lindner, Simon Wunderlich, Antonio Quartulli * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -53,5 +53,7 @@ void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, const unsigned char *tt_buff, uint8_t tt_num_changes, uint8_t ttvn, uint16_t tt_crc); +bool tt_global_client_is_roaming(struct bat_priv *bat_priv, uint8_t *addr); + #endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 2f4848b..61308e8 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h
@@ -52,7 +52,7 @@ /** * orig_node - structure for orig_list maintaining nodes of mesh * @primary_addr: hosts primary interface address - * @last_valid: when last packet from this node was received + * @last_seen: when last packet from this node was received * @bcast_seqno_reset: time when the broadcast seqno window was reset * @batman_seqno_reset: time when the batman seqno window was reset * @gw_flags: flags related to gateway class @@ -70,7 +70,7 @@ struct neigh_node __rcu *router; /* rcu protected pointer */ unsigned long *bcast_own; uint8_t *bcast_own_sum; - unsigned long last_valid; + unsigned long last_seen; unsigned long bcast_seqno_reset; unsigned long batman_seqno_reset; uint8_t gw_flags; @@ -120,7 +120,7 @@ /** * neigh_node - * @last_valid: when last packet via this neighbor was received + * @last_seen: when last packet via this neighbor was received */ struct neigh_node { struct hlist_node list; @@ -131,13 +131,13 @@ uint8_t tq_avg; uint8_t last_ttl; struct list_head bonding_list; - unsigned long last_valid; + unsigned long last_seen; DECLARE_BITMAP(real_bits, TQ_LOCAL_WINDOW_SIZE); atomic_t refcount; struct rcu_head rcu; struct orig_node *orig_node; struct hard_iface *if_incoming; - spinlock_t tq_lock; /* protects: tq_recv, tq_index */ + spinlock_t lq_update_lock; /* protects: tq_recv, tq_index */ }; #ifdef CONFIG_BATMAN_ADV_BLA @@ -381,18 +381,17 @@ int (*bat_iface_enable)(struct hard_iface *hard_iface); /* de-init routing info when hard-interface is disabled */ void (*bat_iface_disable)(struct hard_iface *hard_iface); + /* (re-)init mac addresses of the protocol information + * belonging to this hard-interface + */ + void (*bat_iface_update_mac)(struct hard_iface *hard_iface); /* called when primary interface is selected / changed */ void (*bat_primary_iface_set)(struct hard_iface *hard_iface); - /* init mac addresses of the OGM belonging to this hard-interface */ - void (*bat_ogm_update_mac)(struct hard_iface *hard_iface); /* prepare a new outgoing OGM for the send queue */ void (*bat_ogm_schedule)(struct hard_iface *hard_iface, int tt_num_changes); /* send scheduled OGM */ void (*bat_ogm_emit)(struct forw_packet *forw_packet); - /* receive incoming OGM */ - void (*bat_ogm_receive)(struct hard_iface *if_incoming, - struct sk_buff *skb); }; #endif /* _NET_BATMAN_ADV_TYPES_H_ */
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index 676f6a6..74175c2 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c
@@ -331,6 +331,14 @@ unicast_packet->ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); + /* inform the destination node that we are still missing a correct route + * for this client. The destination will receive this packet and will + * try to reroute it because the ttvn contained in the header is less + * than the current one + */ + if (tt_global_client_is_roaming(bat_priv, ethhdr->h_dest)) + unicast_packet->ttvn = unicast_packet->ttvn - 1; + if (atomic_read(&bat_priv->fragmentation) && data_len + sizeof(*unicast_packet) > neigh_node->if_incoming->net_dev->mtu) {
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 4fab436..031d7d6 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c
@@ -69,7 +69,7 @@ BT_DBG(""); list_for_each_entry(s, &bnep_session_list, list) - if (!compare_ether_addr(dst, s->eh.h_source)) + if (ether_addr_equal(dst, s->eh.h_source)) return s; return NULL; @@ -422,10 +422,10 @@ iv[il++] = (struct kvec) { &type, 1 }; len++; - if (compress_src && !compare_ether_addr(eh->h_dest, s->eh.h_source)) + if (compress_src && ether_addr_equal(eh->h_dest, s->eh.h_source)) type |= 0x01; - if (compress_dst && !compare_ether_addr(eh->h_source, s->eh.h_dest)) + if (compress_dst && ether_addr_equal(eh->h_source, s->eh.h_dest)) type |= 0x02; if (type)
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index d6e5929..929e48aed 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c
@@ -170,7 +170,7 @@ return -EADDRNOTAVAIL; spin_lock_bh(&br->lock); - if (compare_ether_addr(dev->dev_addr, addr->sa_data)) { + if (!ether_addr_equal(dev->dev_addr, addr->sa_data)) { dev->addr_assign_type &= ~NET_ADDR_RANDOM; memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); br_fdb_change_mac_address(br, addr->sa_data);
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 5945c54..d21f323 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c
@@ -107,8 +107,8 @@ struct net_bridge_port *op; list_for_each_entry(op, &br->port_list, list) { if (op != p && - !compare_ether_addr(op->dev->dev_addr, - f->addr.addr)) { + ether_addr_equal(op->dev->dev_addr, + f->addr.addr)) { f->dst = op; goto insert; } @@ -214,8 +214,8 @@ struct net_bridge_port *op; list_for_each_entry(op, &br->port_list, list) { if (op != p && - !compare_ether_addr(op->dev->dev_addr, - f->addr.addr)) { + ether_addr_equal(op->dev->dev_addr, + f->addr.addr)) { f->dst = op; goto skip_delete; } @@ -237,7 +237,7 @@ struct net_bridge_fdb_entry *fdb; hlist_for_each_entry_rcu(fdb, h, &br->hash[br_mac_hash(addr)], hlist) { - if (!compare_ether_addr(fdb->addr.addr, addr)) { + if (ether_addr_equal(fdb->addr.addr, addr)) { if (unlikely(has_expired(br, fdb))) break; return fdb; @@ -331,7 +331,7 @@ struct net_bridge_fdb_entry *fdb; hlist_for_each_entry(fdb, h, head, hlist) { - if (!compare_ether_addr(fdb->addr.addr, addr)) + if (ether_addr_equal(fdb->addr.addr, addr)) return fdb; } return NULL; @@ -344,7 +344,7 @@ struct net_bridge_fdb_entry *fdb; hlist_for_each_entry_rcu(fdb, h, head, hlist) { - if (!compare_ether_addr(fdb->addr.addr, addr)) + if (ether_addr_equal(fdb->addr.addr, addr)) return fdb; } return NULL;
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 5a31731..76f15fd 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c
@@ -216,7 +216,7 @@ } /* fall through */ case BR_STATE_LEARNING: - if (!compare_ether_addr(p->br->dev->dev_addr, dest)) + if (ether_addr_equal(p->br->dev->dev_addr, dest)) skb->pkt_type = PACKET_HOST; NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 5ca4c50..b665812 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c
@@ -460,8 +460,8 @@ hopopt[3] = 2; /* Length of RA Option */ hopopt[4] = 0; /* Type = 0x0000 (MLD) */ hopopt[5] = 0; - hopopt[6] = IPV6_TLV_PAD0; /* Pad0 */ - hopopt[7] = IPV6_TLV_PAD0; /* Pad0 */ + hopopt[6] = IPV6_TLV_PAD1; /* Pad1 */ + hopopt[7] = IPV6_TLV_PAD1; /* Pad1 */ skb_put(skb, sizeof(*ip6h) + 8);
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index dce55d4..e41456bd 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c
@@ -558,7 +558,7 @@ int optlen = nh[off + 1] + 2; switch (nh[off]) { - case IPV6_TLV_PAD0: + case IPV6_TLV_PAD1: optlen = 1; break;
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index e16aade..fd30a60 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c
@@ -167,7 +167,7 @@ if (p->state == BR_STATE_DISABLED) goto out; - if (compare_ether_addr(dest, br->group_addr) != 0) + if (!ether_addr_equal(dest, br->group_addr)) goto out; buf = skb_pull(skb, 3);
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index f494496..9d5a414 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c
@@ -178,7 +178,7 @@ /* called under bridge lock */ void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr) { - /* should be aligned on 2 bytes for compare_ether_addr() */ + /* should be aligned on 2 bytes for ether_addr_equal() */ unsigned short oldaddr_aligned[ETH_ALEN >> 1]; unsigned char *oldaddr = (unsigned char *)oldaddr_aligned; struct net_bridge_port *p; @@ -191,12 +191,11 @@ memcpy(br->dev->dev_addr, addr, ETH_ALEN); list_for_each_entry(p, &br->port_list, list) { - if (!compare_ether_addr(p->designated_bridge.addr, oldaddr)) + if (ether_addr_equal(p->designated_bridge.addr, oldaddr)) memcpy(p->designated_bridge.addr, addr, ETH_ALEN); - if (!compare_ether_addr(p->designated_root.addr, oldaddr)) + if (ether_addr_equal(p->designated_root.addr, oldaddr)) memcpy(p->designated_root.addr, addr, ETH_ALEN); - } br_configuration_update(br); @@ -205,7 +204,7 @@ br_become_root_bridge(br); } -/* should be aligned on 2 bytes for compare_ether_addr() */ +/* should be aligned on 2 bytes for ether_addr_equal() */ static const unsigned short br_mac_zero_aligned[ETH_ALEN >> 1]; /* called under bridge lock */ @@ -227,7 +226,7 @@ } - if (compare_ether_addr(br->bridge_id.addr, addr) == 0) + if (ether_addr_equal(br->bridge_id.addr, addr)) return false; /* no change */ br_stp_change_bridge_id(br, addr);
diff --git a/net/bridge/netfilter/ebt_stp.c b/net/bridge/netfilter/ebt_stp.c index 5b33a2e..071d872 100644 --- a/net/bridge/netfilter/ebt_stp.c +++ b/net/bridge/netfilter/ebt_stp.c
@@ -164,8 +164,8 @@ !(info->bitmask & EBT_STP_MASK)) return -EINVAL; /* Make sure the match only receives stp frames */ - if (compare_ether_addr(e->destmac, bridge_ula) || - compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC)) + if (!ether_addr_equal(e->destmac, bridge_ula) || + !ether_addr_equal(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC)) return -EINVAL; return 0;
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 0dccdb3..fb89443 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c
@@ -131,10 +131,9 @@ if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= (unsigned int)sk->sk_rcvbuf && rx_flow_is_on(cf_sk)) { - if (net_ratelimit()) - pr_debug("sending flow OFF (queue len = %d %d)\n", - atomic_read(&cf_sk->sk.sk_rmem_alloc), - sk_rcvbuf_lowwater(cf_sk)); + net_dbg_ratelimited("sending flow OFF (queue len = %d %d)\n", + atomic_read(&cf_sk->sk.sk_rmem_alloc), + sk_rcvbuf_lowwater(cf_sk)); set_rx_flow_off(cf_sk); caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ); } @@ -144,8 +143,7 @@ return err; if (!sk_rmem_schedule(sk, skb->truesize) && rx_flow_is_on(cf_sk)) { set_rx_flow_off(cf_sk); - if (net_ratelimit()) - pr_debug("sending flow OFF due to rmem_schedule\n"); + net_dbg_ratelimited("sending flow OFF due to rmem_schedule\n"); caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ); } skb->dev = NULL;
diff --git a/net/core/dev.c b/net/core/dev.c index a2be59f..cd09819 100644 --- a/net/core/dev.c +++ b/net/core/dev.c
@@ -300,10 +300,9 @@ ARPHRD_BIF, ARPHRD_SIT, ARPHRD_IPDDP, ARPHRD_IPGRE, ARPHRD_PIMREG, ARPHRD_HIPPI, ARPHRD_ASH, ARPHRD_ECONET, ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL, - ARPHRD_FCFABRIC, ARPHRD_IEEE802_TR, ARPHRD_IEEE80211, - ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, - ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154, - ARPHRD_VOID, ARPHRD_NONE}; + ARPHRD_FCFABRIC, ARPHRD_IEEE80211, ARPHRD_IEEE80211_PRISM, + ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, ARPHRD_PHONET_PIPE, + ARPHRD_IEEE802154, ARPHRD_VOID, ARPHRD_NONE}; static const char *const netdev_lock_name[] = {"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25", @@ -318,10 +317,9 @@ "_xmit_BIF", "_xmit_SIT", "_xmit_IPDDP", "_xmit_IPGRE", "_xmit_PIMREG", "_xmit_HIPPI", "_xmit_ASH", "_xmit_ECONET", "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL", - "_xmit_FCFABRIC", "_xmit_IEEE802_TR", "_xmit_IEEE80211", - "_xmit_IEEE80211_PRISM", "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", - "_xmit_PHONET_PIPE", "_xmit_IEEE802154", - "_xmit_VOID", "_xmit_NONE"}; + "_xmit_FCFABRIC", "_xmit_IEEE80211", "_xmit_IEEE80211_PRISM", + "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", "_xmit_PHONET_PIPE", + "_xmit_IEEE802154", "_xmit_VOID", "_xmit_NONE"}; static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)]; static struct lock_class_key netdev_addr_lock_key[ARRAY_SIZE(netdev_lock_type)]; @@ -1618,10 +1616,14 @@ return NET_RX_DROP; } skb->skb_iif = 0; - skb_set_dev(skb, dev); + skb->dev = dev; + skb_dst_drop(skb); skb->tstamp.tv64 = 0; skb->pkt_type = PACKET_HOST; skb->protocol = eth_type_trans(skb, dev); + skb->mark = 0; + secpath_reset(skb); + nf_reset(skb); return netif_rx(skb); } EXPORT_SYMBOL_GPL(dev_forward_skb); @@ -1673,10 +1675,9 @@ if (skb_network_header(skb2) < skb2->data || skb2->network_header > skb2->tail) { - if (net_ratelimit()) - pr_crit("protocol %04x is buggy, dev %s\n", - ntohs(skb2->protocol), - dev->name); + net_crit_ratelimited("protocol %04x is buggy, dev %s\n", + ntohs(skb2->protocol), + dev->name); skb_reset_network_header(skb2); } @@ -1870,36 +1871,6 @@ } EXPORT_SYMBOL(netif_device_attach); -/** - * skb_dev_set -- assign a new device to a buffer - * @skb: buffer for the new device - * @dev: network device - * - * If an skb is owned by a device already, we have to reset - * all data private to the namespace a device belongs to - * before assigning it a new device. - */ -#ifdef CONFIG_NET_NS -void skb_set_dev(struct sk_buff *skb, struct net_device *dev) -{ - skb_dst_drop(skb); - if (skb->dev && !net_eq(dev_net(skb->dev), dev_net(dev))) { - secpath_reset(skb); - nf_reset(skb); - skb_init_secmark(skb); - skb->mark = 0; - skb->priority = 0; - skb->nf_trace = 0; - skb->ipvs_property = 0; -#ifdef CONFIG_NET_SCHED - skb->tc_index = 0; -#endif - } - skb->dev = dev; -} -EXPORT_SYMBOL(skb_set_dev); -#endif /* CONFIG_NET_NS */ - static void skb_warn_bad_offload(const struct sk_buff *skb) { static const netdev_features_t null_features = 0; @@ -2343,11 +2314,9 @@ static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index) { if (unlikely(queue_index >= dev->real_num_tx_queues)) { - if (net_ratelimit()) { - pr_warn("%s selects TX queue %d, but real number of TX queues is %d\n", - dev->name, queue_index, - dev->real_num_tx_queues); - } + net_warn_ratelimited("%s selects TX queue %d, but real number of TX queues is %d\n", + dev->name, queue_index, + dev->real_num_tx_queues); return 0; } return queue_index; @@ -2589,17 +2558,15 @@ } } HARD_TX_UNLOCK(dev, txq); - if (net_ratelimit()) - pr_crit("Virtual device %s asks to queue packet!\n", - dev->name); + net_crit_ratelimited("Virtual device %s asks to queue packet!\n", + dev->name); } else { /* Recursion is detected! It is possible, * unfortunately */ recursion_alert: - if (net_ratelimit()) - pr_crit("Dead loop on virtual device %s, fix it urgently!\n", - dev->name); + net_crit_ratelimited("Dead loop on virtual device %s, fix it urgently!\n", + dev->name); } } @@ -3080,9 +3047,8 @@ struct Qdisc *q; if (unlikely(MAX_RED_LOOP < ttl++)) { - if (net_ratelimit()) - pr_warn("Redir loop detected Dropping packet (%d->%d)\n", - skb->skb_iif, dev->ifindex); + net_warn_ratelimited("Redir loop detected Dropping packet (%d->%d)\n", + skb->skb_iif, dev->ifindex); return TC_ACT_SHOT; } @@ -3636,7 +3602,7 @@ } EXPORT_SYMBOL(napi_frags_finish); -struct sk_buff *napi_frags_skb(struct napi_struct *napi) +static struct sk_buff *napi_frags_skb(struct napi_struct *napi) { struct sk_buff *skb = napi->skb; struct ethhdr *eth; @@ -3671,7 +3637,6 @@ out: return skb; } -EXPORT_SYMBOL(napi_frags_skb); gro_result_t napi_gro_frags(struct napi_struct *napi) {
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index a7cad74..3252e7e 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c
@@ -4,6 +4,8 @@ * Copyright (C) 2009 Neil Horman <nhorman@tuxdriver.com> */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/string.h> @@ -22,6 +24,7 @@ #include <linux/timer.h> #include <linux/bitops.h> #include <linux/slab.h> +#include <linux/module.h> #include <net/genetlink.h> #include <net/netevent.h> @@ -261,9 +264,15 @@ switch (state) { case TRACE_ON: + if (!try_module_get(THIS_MODULE)) { + rc = -ENODEV; + break; + } + rc |= register_trace_kfree_skb(trace_kfree_skb_hit, NULL); rc |= register_trace_napi_poll(trace_napi_poll_hit, NULL); break; + case TRACE_OFF: rc |= unregister_trace_kfree_skb(trace_kfree_skb_hit, NULL); rc |= unregister_trace_napi_poll(trace_napi_poll_hit, NULL); @@ -279,6 +288,9 @@ kfree_rcu(new_stat, rcu); } } + + module_put(THIS_MODULE); + break; default: rc = 1; @@ -381,10 +393,10 @@ struct per_cpu_dm_data *data; int cpu, rc; - printk(KERN_INFO "Initializing network drop monitor service\n"); + pr_info("Initializing network drop monitor service\n"); if (sizeof(void *) > 8) { - printk(KERN_ERR "Unable to store program counters on this arch, Drop monitor failed\n"); + pr_err("Unable to store program counters on this arch, Drop monitor failed\n"); return -ENOSPC; } @@ -392,19 +404,19 @@ dropmon_ops, ARRAY_SIZE(dropmon_ops)); if (rc) { - printk(KERN_ERR "Could not create drop monitor netlink family\n"); + pr_err("Could not create drop monitor netlink family\n"); return rc; } rc = register_netdevice_notifier(&dropmon_net_notifier); if (rc < 0) { - printk(KERN_CRIT "Failed to register netdevice notifier\n"); + pr_crit("Failed to register netdevice notifier\n"); goto out_unreg; } rc = 0; - for_each_present_cpu(cpu) { + for_each_possible_cpu(cpu) { data = &per_cpu(dm_cpu_data, cpu); data->cpu = cpu; INIT_WORK(&data->dm_alert_work, send_dm_alert); @@ -423,4 +435,36 @@ return rc; } -late_initcall(init_net_drop_monitor); +static void exit_net_drop_monitor(void) +{ + struct per_cpu_dm_data *data; + int cpu; + + BUG_ON(unregister_netdevice_notifier(&dropmon_net_notifier)); + + /* + * Because of the module_get/put we do in the trace state change path + * we are guarnateed not to have any current users when we get here + * all we need to do is make sure that we don't have any running timers + * or pending schedule calls + */ + + for_each_possible_cpu(cpu) { + data = &per_cpu(dm_cpu_data, cpu); + del_timer_sync(&data->send_timer); + cancel_work_sync(&data->dm_alert_work); + /* + * At this point, we should have exclusive access + * to this struct and can free the skb inside it + */ + kfree_skb(data->skb); + } + + BUG_ON(genl_unregister_family(&net_drop_monitor_family)); +} + +module_init(init_net_drop_monitor); +module_exit(exit_net_drop_monitor); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Neil Horman <nhorman@tuxdriver.com>");
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index beacdd9..9c2afb4 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c
@@ -751,18 +751,17 @@ return 0; } -static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) +static int ethtool_get_any_eeprom(struct net_device *dev, void __user *useraddr, + int (*getter)(struct net_device *, + struct ethtool_eeprom *, u8 *), + u32 total_len) { struct ethtool_eeprom eeprom; - const struct ethtool_ops *ops = dev->ethtool_ops; void __user *userbuf = useraddr + sizeof(eeprom); u32 bytes_remaining; u8 *data; int ret = 0; - if (!ops->get_eeprom || !ops->get_eeprom_len) - return -EOPNOTSUPP; - if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) return -EFAULT; @@ -771,7 +770,7 @@ return -EINVAL; /* Check for exceeding total eeprom len */ - if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev)) + if (eeprom.offset + eeprom.len > total_len) return -EINVAL; data = kmalloc(PAGE_SIZE, GFP_USER); @@ -782,7 +781,7 @@ while (bytes_remaining > 0) { eeprom.len = min(bytes_remaining, (u32)PAGE_SIZE); - ret = ops->get_eeprom(dev, &eeprom, data); + ret = getter(dev, &eeprom, data); if (ret) break; if (copy_to_user(userbuf, data, eeprom.len)) { @@ -803,6 +802,17 @@ return ret; } +static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) +{ + const struct ethtool_ops *ops = dev->ethtool_ops; + + if (!ops->get_eeprom || !ops->get_eeprom_len) + return -EOPNOTSUPP; + + return ethtool_get_any_eeprom(dev, useraddr, ops->get_eeprom, + ops->get_eeprom_len(dev)); +} + static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr) { struct ethtool_eeprom eeprom; @@ -1325,6 +1335,47 @@ return err; } +static int ethtool_get_module_info(struct net_device *dev, + void __user *useraddr) +{ + int ret; + struct ethtool_modinfo modinfo; + const struct ethtool_ops *ops = dev->ethtool_ops; + + if (!ops->get_module_info) + return -EOPNOTSUPP; + + if (copy_from_user(&modinfo, useraddr, sizeof(modinfo))) + return -EFAULT; + + ret = ops->get_module_info(dev, &modinfo); + if (ret) + return ret; + + if (copy_to_user(useraddr, &modinfo, sizeof(modinfo))) + return -EFAULT; + + return 0; +} + +static int ethtool_get_module_eeprom(struct net_device *dev, + void __user *useraddr) +{ + int ret; + struct ethtool_modinfo modinfo; + const struct ethtool_ops *ops = dev->ethtool_ops; + + if (!ops->get_module_info || !ops->get_module_eeprom) + return -EOPNOTSUPP; + + ret = ops->get_module_info(dev, &modinfo); + if (ret) + return ret; + + return ethtool_get_any_eeprom(dev, useraddr, ops->get_module_eeprom, + modinfo.eeprom_len); +} + /* The main entry point in this file. Called from net/core/dev.c */ int dev_ethtool(struct net *net, struct ifreq *ifr) @@ -1549,6 +1600,12 @@ case ETHTOOL_GET_TS_INFO: rc = ethtool_get_ts_info(dev, useraddr); break; + case ETHTOOL_GMODULEINFO: + rc = ethtool_get_module_info(dev, useraddr); + break; + case ETHTOOL_GMODULEEEPROM: + rc = ethtool_get_module_eeprom(dev, useraddr); + break; default: rc = -EOPNOTSUPP; }
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index fadaa81..eb09f8b 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c
@@ -15,6 +15,8 @@ * Harald Welte Add neighbour cache statistics like rtstat */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/slab.h> #include <linux/types.h> #include <linux/kernel.h> @@ -712,14 +714,13 @@ NEIGH_CACHE_STAT_INC(neigh->tbl, destroys); if (!neigh->dead) { - printk(KERN_WARNING - "Destroying alive neighbour %p\n", neigh); + pr_warn("Destroying alive neighbour %p\n", neigh); dump_stack(); return; } if (neigh_del_timer(neigh)) - printk(KERN_WARNING "Impossible event.\n"); + pr_warn("Impossible event\n"); skb_queue_purge(&neigh->arp_queue); neigh->arp_queue_len_bytes = 0; @@ -1554,8 +1555,8 @@ write_unlock(&neigh_tbl_lock); if (unlikely(tmp)) { - printk(KERN_ERR "NEIGH: Registering multiple tables for " - "family %d\n", tbl->family); + pr_err("Registering multiple tables for family %d\n", + tbl->family); dump_stack(); } } @@ -1571,7 +1572,7 @@ pneigh_queue_purge(&tbl->proxy_queue); neigh_ifdown(tbl, NULL); if (atomic_read(&tbl->entries)) - printk(KERN_CRIT "neighbour leakage\n"); + pr_crit("neighbour leakage\n"); write_lock(&neigh_tbl_lock); for (tp = &neigh_tables; *tp; tp = &(*tp)->next) { if (*tp == tbl) {
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 31a5ae5..dddbacb 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c
@@ -1,3 +1,5 @@ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/workqueue.h> #include <linux/rtnetlink.h> #include <linux/cache.h> @@ -212,8 +214,8 @@ { #ifdef NETNS_REFCNT_DEBUG if (unlikely(atomic_read(&net->use_count) != 0)) { - printk(KERN_EMERG "network namespace not free! Usage: %d\n", - atomic_read(&net->use_count)); + pr_emerg("network namespace not free! Usage: %d\n", + atomic_read(&net->use_count)); return; } #endif
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c index ba6900f..09eda68 100644 --- a/net/core/netprio_cgroup.c +++ b/net/core/netprio_cgroup.c
@@ -9,6 +9,8 @@ * Authors: Neil Horman <nhorman@tuxdriver.com> */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/slab.h> #include <linux/types.h> @@ -88,7 +90,7 @@ old_priomap = rtnl_dereference(dev->priomap); if (!new_priomap) { - printk(KERN_WARNING "Unable to alloc new priomap!\n"); + pr_warn("Unable to alloc new priomap!\n"); return; } @@ -136,7 +138,7 @@ ret = get_prioidx(&cs->prioidx); if (ret != 0) { - printk(KERN_WARNING "No space in priority index array\n"); + pr_warn("No space in priority index array\n"); kfree(cs); return ERR_PTR(ret); }
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index ffb5d38..cce9e53 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c
@@ -891,8 +891,8 @@ if (copy_from_user(tb, user_buffer, copy)) return -EFAULT; tb[copy] = 0; - printk(KERN_DEBUG "pktgen: %s,%lu buffer -:%s:-\n", name, - (unsigned long)count, tb); + pr_debug("%s,%lu buffer -:%s:-\n", + name, (unsigned long)count, tb); } if (!strcmp(name, "min_pkt_size")) { @@ -1261,8 +1261,7 @@ pkt_dev->cur_daddr = pkt_dev->daddr_min; } if (debug) - printk(KERN_DEBUG "pktgen: dst_min set to: %s\n", - pkt_dev->dst_min); + pr_debug("dst_min set to: %s\n", pkt_dev->dst_min); i += len; sprintf(pg_result, "OK: dst_min=%s", pkt_dev->dst_min); return count; @@ -1284,8 +1283,7 @@ pkt_dev->cur_daddr = pkt_dev->daddr_max; } if (debug) - printk(KERN_DEBUG "pktgen: dst_max set to: %s\n", - pkt_dev->dst_max); + pr_debug("dst_max set to: %s\n", pkt_dev->dst_max); i += len; sprintf(pg_result, "OK: dst_max=%s", pkt_dev->dst_max); return count; @@ -1307,7 +1305,7 @@ pkt_dev->cur_in6_daddr = pkt_dev->in6_daddr; if (debug) - printk(KERN_DEBUG "pktgen: dst6 set to: %s\n", buf); + pr_debug("dst6 set to: %s\n", buf); i += len; sprintf(pg_result, "OK: dst6=%s", buf); @@ -1329,7 +1327,7 @@ pkt_dev->cur_in6_daddr = pkt_dev->min_in6_daddr; if (debug) - printk(KERN_DEBUG "pktgen: dst6_min set to: %s\n", buf); + pr_debug("dst6_min set to: %s\n", buf); i += len; sprintf(pg_result, "OK: dst6_min=%s", buf); @@ -1350,7 +1348,7 @@ snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->max_in6_daddr); if (debug) - printk(KERN_DEBUG "pktgen: dst6_max set to: %s\n", buf); + pr_debug("dst6_max set to: %s\n", buf); i += len; sprintf(pg_result, "OK: dst6_max=%s", buf); @@ -1373,7 +1371,7 @@ pkt_dev->cur_in6_saddr = pkt_dev->in6_saddr; if (debug) - printk(KERN_DEBUG "pktgen: src6 set to: %s\n", buf); + pr_debug("src6 set to: %s\n", buf); i += len; sprintf(pg_result, "OK: src6=%s", buf); @@ -1394,8 +1392,7 @@ pkt_dev->cur_saddr = pkt_dev->saddr_min; } if (debug) - printk(KERN_DEBUG "pktgen: src_min set to: %s\n", - pkt_dev->src_min); + pr_debug("src_min set to: %s\n", pkt_dev->src_min); i += len; sprintf(pg_result, "OK: src_min=%s", pkt_dev->src_min); return count; @@ -1415,8 +1412,7 @@ pkt_dev->cur_saddr = pkt_dev->saddr_max; } if (debug) - printk(KERN_DEBUG "pktgen: src_max set to: %s\n", - pkt_dev->src_max); + pr_debug("src_max set to: %s\n", pkt_dev->src_max); i += len; sprintf(pg_result, "OK: src_max=%s", pkt_dev->src_max); return count; @@ -1527,7 +1523,7 @@ pkt_dev->svlan_id = 0xffff; if (debug) - printk(KERN_DEBUG "pktgen: VLAN/SVLAN auto turned off\n"); + pr_debug("VLAN/SVLAN auto turned off\n"); } return count; } @@ -1542,10 +1538,10 @@ pkt_dev->vlan_id = value; /* turn on VLAN */ if (debug) - printk(KERN_DEBUG "pktgen: VLAN turned on\n"); + pr_debug("VLAN turned on\n"); if (debug && pkt_dev->nr_labels) - printk(KERN_DEBUG "pktgen: MPLS auto turned off\n"); + pr_debug("MPLS auto turned off\n"); pkt_dev->nr_labels = 0; /* turn off MPLS */ sprintf(pg_result, "OK: vlan_id=%u", pkt_dev->vlan_id); @@ -1554,7 +1550,7 @@ pkt_dev->svlan_id = 0xffff; if (debug) - printk(KERN_DEBUG "pktgen: VLAN/SVLAN turned off\n"); + pr_debug("VLAN/SVLAN turned off\n"); } return count; } @@ -1599,10 +1595,10 @@ pkt_dev->svlan_id = value; /* turn on SVLAN */ if (debug) - printk(KERN_DEBUG "pktgen: SVLAN turned on\n"); + pr_debug("SVLAN turned on\n"); if (debug && pkt_dev->nr_labels) - printk(KERN_DEBUG "pktgen: MPLS auto turned off\n"); + pr_debug("MPLS auto turned off\n"); pkt_dev->nr_labels = 0; /* turn off MPLS */ sprintf(pg_result, "OK: svlan_id=%u", pkt_dev->svlan_id); @@ -1611,7 +1607,7 @@ pkt_dev->svlan_id = 0xffff; if (debug) - printk(KERN_DEBUG "pktgen: VLAN/SVLAN turned off\n"); + pr_debug("VLAN/SVLAN turned off\n"); } return count; } @@ -1779,8 +1775,7 @@ i += len; if (debug) - printk(KERN_DEBUG "pktgen: t=%s, count=%lu\n", - name, (unsigned long)count); + pr_debug("t=%s, count=%lu\n", name, (unsigned long)count); if (!t) { pr_err("ERROR: No thread\n"); @@ -1931,7 +1926,7 @@ { struct net_device *dev = ptr; - if (!net_eq(dev_net(dev), &init_net)) + if (!net_eq(dev_net(dev), &init_net) || pktgen_exiting) return NOTIFY_DONE; /* It is OK that we do not hold the group lock right now, @@ -2934,8 +2929,7 @@ if (datalen < sizeof(struct pktgen_hdr)) { datalen = sizeof(struct pktgen_hdr); - if (net_ratelimit()) - pr_info("increased datalen to %d\n", datalen); + net_info_ratelimited("increased datalen to %d\n", datalen); } udph->source = htons(pkt_dev->cur_udp_src); @@ -3365,8 +3359,8 @@ pkt_dev->errors++; break; default: /* Drivers are not supposed to return other values! */ - if (net_ratelimit()) - pr_info("%s xmit error: %d\n", pkt_dev->odevname, ret); + net_info_ratelimited("%s xmit error: %d\n", + pkt_dev->odevname, ret); pkt_dev->errors++; /* fallthru */ case NETDEV_TX_LOCKED: @@ -3755,12 +3749,18 @@ { struct pktgen_thread *t; struct list_head *q, *n; + LIST_HEAD(list); /* Stop all interfaces & threads */ pktgen_exiting = true; - list_for_each_safe(q, n, &pktgen_threads) { + mutex_lock(&pktgen_thread_lock); + list_splice_init(&pktgen_threads, &list); + mutex_unlock(&pktgen_thread_lock); + + list_for_each_safe(q, n, &list) { t = list_entry(q, struct pktgen_thread, th_list); + list_del(&t->th_list); kthread_stop(t->tsk); kfree(t); }
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index b442d35..21318d1 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c
@@ -1524,11 +1524,9 @@ err = 0; errout: - if (err < 0 && modified && net_ratelimit()) - printk(KERN_WARNING "A link change request failed with " - "some changes committed already. Interface %s may " - "have been left with an inconsistent configuration, " - "please check.\n", dev->name); + if (err < 0 && modified) + net_warn_ratelimited("A link change request failed with some changes committed already. Interface %s may have been left with an inconsistent configuration, please check.\n", + dev->name); if (send_addr_notify) call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 2c35da81..016694d 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c
@@ -36,6 +36,8 @@ * The functions in this file will not compile correctly with gcc 2.4.x */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> @@ -118,11 +120,10 @@ */ static void skb_over_panic(struct sk_buff *skb, int sz, void *here) { - printk(KERN_EMERG "skb_over_panic: text:%p len:%d put:%d head:%p " - "data:%p tail:%#lx end:%#lx dev:%s\n", - here, skb->len, sz, skb->head, skb->data, - (unsigned long)skb->tail, (unsigned long)skb->end, - skb->dev ? skb->dev->name : "<NULL>"); + pr_emerg("%s: text:%p len:%d put:%d head:%p data:%p tail:%#lx end:%#lx dev:%s\n", + __func__, here, skb->len, sz, skb->head, skb->data, + (unsigned long)skb->tail, (unsigned long)skb->end, + skb->dev ? skb->dev->name : "<NULL>"); BUG(); } @@ -137,11 +138,10 @@ static void skb_under_panic(struct sk_buff *skb, int sz, void *here) { - printk(KERN_EMERG "skb_under_panic: text:%p len:%d put:%d head:%p " - "data:%p tail:%#lx end:%#lx dev:%s\n", - here, skb->len, sz, skb->head, skb->data, - (unsigned long)skb->tail, (unsigned long)skb->end, - skb->dev ? skb->dev->name : "<NULL>"); + pr_emerg("%s: text:%p len:%d put:%d head:%p data:%p tail:%#lx end:%#lx dev:%s\n", + __func__, here, skb->len, sz, skb->head, skb->data, + (unsigned long)skb->tail, (unsigned long)skb->end, + skb->dev ? skb->dev->name : "<NULL>"); BUG(); } @@ -293,6 +293,46 @@ } EXPORT_SYMBOL(build_skb); +struct netdev_alloc_cache { + struct page *page; + unsigned int offset; +}; +static DEFINE_PER_CPU(struct netdev_alloc_cache, netdev_alloc_cache); + +/** + * netdev_alloc_frag - allocate a page fragment + * @fragsz: fragment size + * + * Allocates a frag from a page for receive buffer. + * Uses GFP_ATOMIC allocations. + */ +void *netdev_alloc_frag(unsigned int fragsz) +{ + struct netdev_alloc_cache *nc; + void *data = NULL; + unsigned long flags; + + local_irq_save(flags); + nc = &__get_cpu_var(netdev_alloc_cache); + if (unlikely(!nc->page)) { +refill: + nc->page = alloc_page(GFP_ATOMIC | __GFP_COLD); + nc->offset = 0; + } + if (likely(nc->page)) { + if (nc->offset + fragsz > PAGE_SIZE) { + put_page(nc->page); + goto refill; + } + data = page_address(nc->page) + nc->offset; + nc->offset += fragsz; + get_page(nc->page); + } + local_irq_restore(flags); + return data; +} +EXPORT_SYMBOL(netdev_alloc_frag); + /** * __netdev_alloc_skb - allocate an skbuff for rx on a specific device * @dev: network device to receive on @@ -307,11 +347,23 @@ * %NULL is returned if there is no free memory. */ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, - unsigned int length, gfp_t gfp_mask) + unsigned int length, gfp_t gfp_mask) { - struct sk_buff *skb; + struct sk_buff *skb = NULL; + unsigned int fragsz = SKB_DATA_ALIGN(length + NET_SKB_PAD) + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, NUMA_NO_NODE); + if (fragsz <= PAGE_SIZE && !(gfp_mask & __GFP_WAIT)) { + void *data = netdev_alloc_frag(fragsz); + + if (likely(data)) { + skb = build_skb(data, fragsz); + if (unlikely(!skb)) + put_page(virt_to_head_page(data)); + } + } else { + skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, NUMA_NO_NODE); + } if (likely(skb)) { skb_reserve(skb, NET_SKB_PAD); skb->dev = dev; @@ -330,28 +382,6 @@ } EXPORT_SYMBOL(skb_add_rx_frag); -/** - * dev_alloc_skb - allocate an skbuff for receiving - * @length: length to allocate - * - * Allocate a new &sk_buff and assign it a usage count of one. The - * buffer has unspecified headroom built in. Users should allocate - * the headroom they think they need without accounting for the - * built in space. The built in space is used for optimisations. - * - * %NULL is returned if there is no free memory. Although this function - * allocates memory it can be called from an interrupt. - */ -struct sk_buff *dev_alloc_skb(unsigned int length) -{ - /* - * There is more code here than it seems: - * __dev_alloc_skb is an inline - */ - return __dev_alloc_skb(length, GFP_ATOMIC); -} -EXPORT_SYMBOL(dev_alloc_skb); - static void skb_drop_list(struct sk_buff **listp) { struct sk_buff *list = *listp; @@ -3299,10 +3329,8 @@ { if (unlikely(start > skb_headlen(skb)) || unlikely((int)start + off > skb_headlen(skb) - 2)) { - if (net_ratelimit()) - printk(KERN_WARNING - "bad partial csum: csum=%u/%u len=%u\n", - start, off, skb_headlen(skb)); + net_warn_ratelimited("bad partial csum: csum=%u/%u len=%u\n", + start, off, skb_headlen(skb)); return false; } skb->ip_summed = CHECKSUM_PARTIAL; @@ -3314,8 +3342,93 @@ void __skb_warn_lro_forwarding(const struct sk_buff *skb) { - if (net_ratelimit()) - pr_warning("%s: received packets cannot be forwarded" - " while LRO is enabled\n", skb->dev->name); + net_warn_ratelimited("%s: received packets cannot be forwarded while LRO is enabled\n", + skb->dev->name); } EXPORT_SYMBOL(__skb_warn_lro_forwarding); + +void kfree_skb_partial(struct sk_buff *skb, bool head_stolen) +{ + if (head_stolen) + kmem_cache_free(skbuff_head_cache, skb); + else + __kfree_skb(skb); +} +EXPORT_SYMBOL(kfree_skb_partial); + +/** + * skb_try_coalesce - try to merge skb to prior one + * @to: prior buffer + * @from: buffer to add + * @fragstolen: pointer to boolean + * + */ +bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, + bool *fragstolen, int *delta_truesize) +{ + int i, delta, len = from->len; + + *fragstolen = false; + + if (skb_cloned(to)) + return false; + + if (len <= skb_tailroom(to)) { + BUG_ON(skb_copy_bits(from, 0, skb_put(to, len), len)); + *delta_truesize = 0; + return true; + } + + if (skb_has_frag_list(to) || skb_has_frag_list(from)) + return false; + + if (skb_headlen(from) != 0) { + struct page *page; + unsigned int offset; + + if (skb_shinfo(to)->nr_frags + + skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS) + return false; + + if (skb_head_is_locked(from)) + return false; + + delta = from->truesize - SKB_DATA_ALIGN(sizeof(struct sk_buff)); + + page = virt_to_head_page(from->head); + offset = from->data - (unsigned char *)page_address(page); + + skb_fill_page_desc(to, skb_shinfo(to)->nr_frags, + page, offset, skb_headlen(from)); + *fragstolen = true; + } else { + if (skb_shinfo(to)->nr_frags + + skb_shinfo(from)->nr_frags > MAX_SKB_FRAGS) + return false; + + delta = from->truesize - + SKB_TRUESIZE(skb_end_pointer(from) - from->head); + } + + WARN_ON_ONCE(delta < len); + + memcpy(skb_shinfo(to)->frags + skb_shinfo(to)->nr_frags, + skb_shinfo(from)->frags, + skb_shinfo(from)->nr_frags * sizeof(skb_frag_t)); + skb_shinfo(to)->nr_frags += skb_shinfo(from)->nr_frags; + + if (!skb_cloned(from)) + skb_shinfo(from)->nr_frags = 0; + + /* if the skb is cloned this does nothing since we set nr_frags to 0 */ + for (i = 0; i < skb_shinfo(from)->nr_frags; i++) + skb_frag_ref(from, i); + + to->truesize += delta; + to->len += len; + to->data_len += len; + + *delta_truesize = delta; + return true; +} +EXPORT_SYMBOL(skb_try_coalesce);
diff --git a/net/core/sock.c b/net/core/sock.c index 26ed27f..5efcd63 100644 --- a/net/core/sock.c +++ b/net/core/sock.c
@@ -89,6 +89,8 @@ * 2 of the License, or (at your option) any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/capability.h> #include <linux/errno.h> #include <linux/types.h> @@ -297,9 +299,8 @@ *timeo_p = 0; if (warned < 10 && net_ratelimit()) { warned++; - printk(KERN_INFO "sock_set_timeout: `%s' (pid %d) " - "tries to set negative timeout\n", - current->comm, task_pid_nr(current)); + pr_info("%s: `%s' (pid %d) tries to set negative timeout\n", + __func__, current->comm, task_pid_nr(current)); } return 0; } @@ -317,8 +318,8 @@ static char warncomm[TASK_COMM_LEN]; if (strcmp(warncomm, current->comm) && warned < 5) { strcpy(warncomm, current->comm); - printk(KERN_WARNING "process `%s' is using obsolete " - "%s SO_BSDCOMPAT\n", warncomm, name); + pr_warn("process `%s' is using obsolete %s SO_BSDCOMPAT\n", + warncomm, name); warned++; } } @@ -849,7 +850,7 @@ break; case SO_BROADCAST: - v.val = !!sock_flag(sk, SOCK_BROADCAST); + v.val = sock_flag(sk, SOCK_BROADCAST); break; case SO_SNDBUF: @@ -865,7 +866,7 @@ break; case SO_KEEPALIVE: - v.val = !!sock_flag(sk, SOCK_KEEPOPEN); + v.val = sock_flag(sk, SOCK_KEEPOPEN); break; case SO_TYPE: @@ -887,7 +888,7 @@ break; case SO_OOBINLINE: - v.val = !!sock_flag(sk, SOCK_URGINLINE); + v.val = sock_flag(sk, SOCK_URGINLINE); break; case SO_NO_CHECK: @@ -900,7 +901,7 @@ case SO_LINGER: lv = sizeof(v.ling); - v.ling.l_onoff = !!sock_flag(sk, SOCK_LINGER); + v.ling.l_onoff = sock_flag(sk, SOCK_LINGER); v.ling.l_linger = sk->sk_lingertime / HZ; break; @@ -1012,11 +1013,11 @@ break; case SO_RXQ_OVFL: - v.val = !!sock_flag(sk, SOCK_RXQ_OVFL); + v.val = sock_flag(sk, SOCK_RXQ_OVFL); break; case SO_WIFI_STATUS: - v.val = !!sock_flag(sk, SOCK_WIFI_STATUS); + v.val = sock_flag(sk, SOCK_WIFI_STATUS); break; case SO_PEEK_OFF: @@ -1026,7 +1027,7 @@ v.val = sk->sk_peek_off; break; case SO_NOFCS: - v.val = !!sock_flag(sk, SOCK_NOFCS); + v.val = sock_flag(sk, SOCK_NOFCS); break; default: return -ENOPROTOOPT; @@ -1238,8 +1239,8 @@ sock_disable_timestamp(sk, SK_FLAGS_TIMESTAMP); if (atomic_read(&sk->sk_omem_alloc)) - printk(KERN_DEBUG "%s: optmem leakage (%d bytes) detected.\n", - __func__, atomic_read(&sk->sk_omem_alloc)); + pr_debug("%s: optmem leakage (%d bytes) detected\n", + __func__, atomic_read(&sk->sk_omem_alloc)); if (sk->sk_peer_cred) put_cred(sk->sk_peer_cred); @@ -2424,7 +2425,7 @@ prot->inuse_idx = find_first_zero_bit(proto_inuse_idx, PROTO_INUSE_NR); if (unlikely(prot->inuse_idx == PROTO_INUSE_NR - 1)) { - printk(KERN_ERR "PROTO_INUSE_NR exhausted\n"); + pr_err("PROTO_INUSE_NR exhausted\n"); return; } @@ -2454,8 +2455,8 @@ NULL); if (prot->slab == NULL) { - printk(KERN_CRIT "%s: Can't create sock SLAB cache!\n", - prot->name); + pr_crit("%s: Can't create sock SLAB cache!\n", + prot->name); goto out; } @@ -2469,8 +2470,8 @@ SLAB_HWCACHE_ALIGN, NULL); if (prot->rsk_prot->slab == NULL) { - printk(KERN_CRIT "%s: Can't create request sock SLAB cache!\n", - prot->name); + pr_crit("%s: Can't create request sock SLAB cache!\n", + prot->name); goto out_free_request_sock_slab_name; } }
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 7065c0a..6c7c78b8 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c
@@ -848,7 +848,7 @@ default: dccp_pr_debug("packet_type=%s\n", dccp_packet_name(dh->dccph_type)); - sk_eat_skb(sk, skb, 0); + sk_eat_skb(sk, skb, false); } verify_sock_status: if (sock_flag(sk, SOCK_DONE)) { @@ -905,7 +905,7 @@ len = skb->len; found_fin_ok: if (!(flags & MSG_PEEK)) - sk_eat_skb(sk, skb, 0); + sk_eat_skb(sk, skb, false); break; } while (1); out:
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 65a8cd7..7eaf987 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c
@@ -438,9 +438,8 @@ res->fi = NULL; return 1; default: - if (net_ratelimit()) - printk("DECnet: impossible routing event : dn_fib_semantic_match type=%d\n", - type); + net_err_ratelimited("DECnet: impossible routing event : dn_fib_semantic_match type=%d\n", + type); res->fi = NULL; return -EINVAL; }
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index ee7013f..ac90f658 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c
@@ -162,8 +162,8 @@ else if ((dev->type == ARPHRD_ETHER) || (dev->type == ARPHRD_LOOPBACK)) dn_dn2eth(neigh->ha, dn->addr); else { - if (net_ratelimit()) - printk(KERN_DEBUG "Trying to create neigh for hw %d\n", dev->type); + net_dbg_ratelimited("Trying to create neigh for hw %d\n", + dev->type); return -EINVAL; } @@ -236,15 +236,13 @@ if (skb_headroom(skb) < headroom) { struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom); if (skb2 == NULL) { - if (net_ratelimit()) - printk(KERN_CRIT "dn_long_output: no memory\n"); + net_crit_ratelimited("dn_long_output: no memory\n"); kfree_skb(skb); return -ENOBUFS; } kfree_skb(skb); skb = skb2; - if (net_ratelimit()) - printk(KERN_INFO "dn_long_output: Increasing headroom\n"); + net_info_ratelimited("dn_long_output: Increasing headroom\n"); } data = skb_push(skb, sizeof(struct dn_long_packet) + 3); @@ -281,15 +279,13 @@ if (skb_headroom(skb) < headroom) { struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom); if (skb2 == NULL) { - if (net_ratelimit()) - printk(KERN_CRIT "dn_short_output: no memory\n"); + net_crit_ratelimited("dn_short_output: no memory\n"); kfree_skb(skb); return -ENOBUFS; } kfree_skb(skb); skb = skb2; - if (net_ratelimit()) - printk(KERN_INFO "dn_short_output: Increasing headroom\n"); + net_info_ratelimited("dn_short_output: Increasing headroom\n"); } data = skb_push(skb, sizeof(struct dn_short_packet) + 2); @@ -322,15 +318,13 @@ if (skb_headroom(skb) < headroom) { struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom); if (skb2 == NULL) { - if (net_ratelimit()) - printk(KERN_CRIT "dn_phase3_output: no memory\n"); + net_crit_ratelimited("dn_phase3_output: no memory\n"); kfree_skb(skb); return -ENOBUFS; } kfree_skb(skb); skb = skb2; - if (net_ratelimit()) - printk(KERN_INFO "dn_phase3_output: Increasing headroom\n"); + net_info_ratelimited("dn_phase3_output: Increasing headroom\n"); } data = skb_push(skb, sizeof(struct dn_short_packet) + 2);
diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c index 58084f3..c344163 100644 --- a/net/decnet/dn_nsp_in.c +++ b/net/decnet/dn_nsp_in.c
@@ -80,12 +80,15 @@ static void dn_log_martian(struct sk_buff *skb, const char *msg) { - if (decnet_log_martians && net_ratelimit()) { + if (decnet_log_martians) { char *devname = skb->dev ? skb->dev->name : "???"; struct dn_skb_cb *cb = DN_SKB_CB(skb); - printk(KERN_INFO "DECnet: Martian packet (%s) dev=%s src=0x%04hx dst=0x%04hx srcport=0x%04hx dstport=0x%04hx\n", - msg, devname, le16_to_cpu(cb->src), le16_to_cpu(cb->dst), - le16_to_cpu(cb->src_port), le16_to_cpu(cb->dst_port)); + net_info_ratelimited("DECnet: Martian packet (%s) dev=%s src=0x%04hx dst=0x%04hx srcport=0x%04hx dstport=0x%04hx\n", + msg, devname, + le16_to_cpu(cb->src), + le16_to_cpu(cb->dst), + le16_to_cpu(cb->src_port), + le16_to_cpu(cb->dst_port)); } }
diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c index b952f88..564a6ad 100644 --- a/net/decnet/dn_nsp_out.c +++ b/net/decnet/dn_nsp_out.c
@@ -1,4 +1,3 @@ - /* * DECnet An implementation of the DECnet protocol suite for the LINUX * operating system. DECnet is implemented using the BSD Socket @@ -554,8 +553,8 @@ unsigned char *msg; if ((dst == NULL) || (rem == 0)) { - if (net_ratelimit()) - printk(KERN_DEBUG "DECnet: dn_nsp_do_disc: BUG! Please report this to SteveW@ACM.org rem=%u dst=%p\n", le16_to_cpu(rem), dst); + net_dbg_ratelimited("DECnet: dn_nsp_do_disc: BUG! Please report this to SteveW@ACM.org rem=%u dst=%p\n", + le16_to_cpu(rem), dst); return; }
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 7e1f878..586302e 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c
@@ -748,8 +748,7 @@ dn_to_neigh_output); error: - if (net_ratelimit()) - printk(KERN_DEBUG "dn_output: This should not happen\n"); + net_dbg_ratelimited("dn_output: This should not happen\n"); kfree_skb(skb); @@ -807,12 +806,10 @@ */ static int dn_rt_bug(struct sk_buff *skb) { - if (net_ratelimit()) { - struct dn_skb_cb *cb = DN_SKB_CB(skb); + struct dn_skb_cb *cb = DN_SKB_CB(skb); - printk(KERN_DEBUG "dn_rt_bug: skb from:%04x to:%04x\n", - le16_to_cpu(cb->src), le16_to_cpu(cb->dst)); - } + net_dbg_ratelimited("dn_rt_bug: skb from:%04x to:%04x\n", + le16_to_cpu(cb->src), le16_to_cpu(cb->dst)); kfree_skb(skb); @@ -1327,9 +1324,7 @@ out_dev = DN_FIB_RES_DEV(res); if (out_dev == NULL) { - if (net_ratelimit()) - printk(KERN_CRIT "Bug in dn_route_input_slow() " - "No output device\n"); + net_crit_ratelimited("Bug in dn_route_input_slow() No output device\n"); goto e_inval; } dev_hold(out_dev);
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index a9a62f2..650f338 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c
@@ -836,8 +836,8 @@ if (!create) return NULL; - if (in_interrupt() && net_ratelimit()) { - printk(KERN_DEBUG "DECnet: BUG! Attempt to create routing table from interrupt\n"); + if (in_interrupt()) { + net_dbg_ratelimited("DECnet: BUG! Attempt to create routing table from interrupt\n"); return NULL; }
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c index 1531135..44b8909 100644 --- a/net/decnet/netfilter/dn_rtmsg.c +++ b/net/decnet/netfilter/dn_rtmsg.c
@@ -57,8 +57,7 @@ if (skb) kfree_skb(skb); *errp = -ENOMEM; - if (net_ratelimit()) - printk(KERN_ERR "dn_rtmsg: error creating netlink message\n"); + net_err_ratelimited("dn_rtmsg: error creating netlink message\n"); return NULL; }
diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 56cf9b8..e32083d 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c
@@ -66,7 +66,7 @@ if (!(master->flags & IFF_UP)) return -ENETDOWN; - if (compare_ether_addr(dev->dev_addr, master->dev_addr)) { + if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) { err = dev_uc_add(master, dev->dev_addr); if (err < 0) goto out; @@ -89,7 +89,7 @@ if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(master, -1); del_unicast: - if (compare_ether_addr(dev->dev_addr, master->dev_addr)) + if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) dev_uc_del(master, dev->dev_addr); out: return err; @@ -107,7 +107,7 @@ if (dev->flags & IFF_PROMISC) dev_set_promiscuity(master, -1); - if (compare_ether_addr(dev->dev_addr, master->dev_addr)) + if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) dev_uc_del(master, dev->dev_addr); return 0; @@ -146,13 +146,13 @@ if (!(dev->flags & IFF_UP)) goto out; - if (compare_ether_addr(addr->sa_data, master->dev_addr)) { + if (!ether_addr_equal(addr->sa_data, master->dev_addr)) { err = dev_uc_add(master, addr->sa_data); if (err < 0) return err; } - if (compare_ether_addr(dev->dev_addr, master->dev_addr)) + if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) dev_uc_del(master, dev->dev_addr); out:
diff --git a/net/econet/Kconfig b/net/econet/Kconfig deleted file mode 100644 index 39a2d29..0000000 --- a/net/econet/Kconfig +++ /dev/null
@@ -1,36 +0,0 @@ -# -# Acorn Econet/AUN protocols -# - -config ECONET - tristate "Acorn Econet/AUN protocols (EXPERIMENTAL)" - depends on EXPERIMENTAL && INET - ---help--- - Econet is a fairly old and slow networking protocol mainly used by - Acorn computers to access file and print servers. It uses native - Econet network cards. AUN is an implementation of the higher level - parts of Econet that runs over ordinary Ethernet connections, on - top of the UDP packet protocol, which in turn runs on top of the - Internet protocol IP. - - If you say Y here, you can choose with the next two options whether - to send Econet/AUN traffic over a UDP Ethernet connection or over - a native Econet network card. - - To compile this driver as a module, choose M here: the module - will be called econet. - -config ECONET_AUNUDP - bool "AUN over UDP" - depends on ECONET - help - Say Y here if you want to send Econet/AUN traffic over a UDP - connection (UDP is a packet based protocol that runs on top of the - Internet protocol IP) using an ordinary Ethernet network card. - -config ECONET_NATIVE - bool "Native Econet" - depends on ECONET - help - Say Y here if you have a native Econet network card installed in - your computer.
diff --git a/net/econet/Makefile b/net/econet/Makefile deleted file mode 100644 index 05fae8b..0000000 --- a/net/econet/Makefile +++ /dev/null
@@ -1,7 +0,0 @@ -# -# Makefile for Econet support code. -# - -obj-$(CONFIG_ECONET) += econet.o - -econet-y := af_econet.o
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c deleted file mode 100644 index fa14ca7..0000000 --- a/net/econet/af_econet.c +++ /dev/null
@@ -1,1172 +0,0 @@ -/* - * An implementation of the Acorn Econet and AUN protocols. - * Philip Blundell <philb@gnu.org> - * - * 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) fmt - -#include <linux/module.h> - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/socket.h> -#include <linux/sockios.h> -#include <linux/in.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/if_ether.h> -#include <linux/netdevice.h> -#include <linux/inetdevice.h> -#include <linux/route.h> -#include <linux/inet.h> -#include <linux/etherdevice.h> -#include <linux/if_arp.h> -#include <linux/wireless.h> -#include <linux/skbuff.h> -#include <linux/udp.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <net/sock.h> -#include <net/inet_common.h> -#include <linux/stat.h> -#include <linux/init.h> -#include <linux/if_ec.h> -#include <net/udp.h> -#include <net/ip.h> -#include <linux/spinlock.h> -#include <linux/rcupdate.h> -#include <linux/bitops.h> -#include <linux/mutex.h> - -#include <linux/uaccess.h> - -static const struct proto_ops econet_ops; -static struct hlist_head econet_sklist; -static DEFINE_SPINLOCK(econet_lock); -static DEFINE_MUTEX(econet_mutex); - -/* Since there are only 256 possible network numbers (or fewer, depends - how you count) it makes sense to use a simple lookup table. */ -static struct net_device *net2dev_map[256]; - -#define EC_PORT_IP 0xd2 - -#ifdef CONFIG_ECONET_AUNUDP -static DEFINE_SPINLOCK(aun_queue_lock); -static struct socket *udpsock; -#define AUN_PORT 0x8000 - -struct aunhdr { - unsigned char code; /* AUN magic protocol byte */ - unsigned char port; - unsigned char cb; - unsigned char pad; - unsigned long handle; -}; - -static unsigned long aun_seq; - -/* Queue of packets waiting to be transmitted. */ -static struct sk_buff_head aun_queue; -static struct timer_list ab_cleanup_timer; - -#endif /* CONFIG_ECONET_AUNUDP */ - -/* Per-packet information */ -struct ec_cb { - struct sockaddr_ec sec; - unsigned long cookie; /* Supplied by user. */ -#ifdef CONFIG_ECONET_AUNUDP - int done; - unsigned long seq; /* Sequencing */ - unsigned long timeout; /* Timeout */ - unsigned long start; /* jiffies */ -#endif -#ifdef CONFIG_ECONET_NATIVE - void (*sent)(struct sk_buff *, int result); -#endif -}; - -static void econet_remove_socket(struct hlist_head *list, struct sock *sk) -{ - spin_lock_bh(&econet_lock); - sk_del_node_init(sk); - spin_unlock_bh(&econet_lock); -} - -static void econet_insert_socket(struct hlist_head *list, struct sock *sk) -{ - spin_lock_bh(&econet_lock); - sk_add_node(sk, list); - spin_unlock_bh(&econet_lock); -} - -/* - * Pull a packet from our receive queue and hand it to the user. - * If necessary we block. - */ - -static int econet_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len, int flags) -{ - struct sock *sk = sock->sk; - struct sk_buff *skb; - size_t copied; - int err; - - msg->msg_namelen = sizeof(struct sockaddr_ec); - - mutex_lock(&econet_mutex); - - /* - * Call the generic datagram receiver. This handles all sorts - * of horrible races and re-entrancy so we can forget about it - * in the protocol layers. - * - * Now it will return ENETDOWN, if device have just gone down, - * but then it will block. - */ - - skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err); - - /* - * An error occurred so return it. Because skb_recv_datagram() - * handles the blocking we don't see and worry about blocking - * retries. - */ - - if (skb == NULL) - goto out; - - /* - * You lose any data beyond the buffer you gave. If it worries a - * user program they can ask the device for its MTU anyway. - */ - - copied = skb->len; - if (copied > len) { - copied = len; - msg->msg_flags |= MSG_TRUNC; - } - - /* We can't use skb_copy_datagram here */ - err = memcpy_toiovec(msg->msg_iov, skb->data, copied); - if (err) - goto out_free; - sk->sk_stamp = skb->tstamp; - - if (msg->msg_name) - memcpy(msg->msg_name, skb->cb, msg->msg_namelen); - - /* - * Free or return the buffer as appropriate. Again this - * hides all the races and re-entrancy issues from us. - */ - err = copied; - -out_free: - skb_free_datagram(sk, skb); -out: - mutex_unlock(&econet_mutex); - return err; -} - -/* - * Bind an Econet socket. - */ - -static int econet_bind(struct socket *sock, struct sockaddr *uaddr, - int addr_len) -{ - struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr; - struct sock *sk; - struct econet_sock *eo; - - /* - * Check legality - */ - - if (addr_len < sizeof(struct sockaddr_ec) || - sec->sec_family != AF_ECONET) - return -EINVAL; - - mutex_lock(&econet_mutex); - - sk = sock->sk; - eo = ec_sk(sk); - - eo->cb = sec->cb; - eo->port = sec->port; - eo->station = sec->addr.station; - eo->net = sec->addr.net; - - mutex_unlock(&econet_mutex); - - return 0; -} - -#if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE) -/* - * Queue a transmit result for the user to be told about. - */ - -static void tx_result(struct sock *sk, unsigned long cookie, int result) -{ - struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); - struct ec_cb *eb; - struct sockaddr_ec *sec; - - if (skb == NULL) { - pr_debug("econet: memory squeeze, transmit result dropped\n"); - return; - } - - eb = (struct ec_cb *)&skb->cb; - sec = (struct sockaddr_ec *)&eb->sec; - memset(sec, 0, sizeof(struct sockaddr_ec)); - sec->cookie = cookie; - sec->type = ECTYPE_TRANSMIT_STATUS | result; - sec->sec_family = AF_ECONET; - - if (sock_queue_rcv_skb(sk, skb) < 0) - kfree_skb(skb); -} -#endif - -#ifdef CONFIG_ECONET_NATIVE -/* - * Called by the Econet hardware driver when a packet transmit - * has completed. Tell the user. - */ - -static void ec_tx_done(struct sk_buff *skb, int result) -{ - struct ec_cb *eb = (struct ec_cb *)&skb->cb; - tx_result(skb->sk, eb->cookie, result); -} -#endif - -/* - * Send a packet. We have to work out which device it's going out on - * and hence whether to use real Econet or the UDP emulation. - */ - -static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len) -{ - struct sockaddr_ec *saddr = (struct sockaddr_ec *)msg->msg_name; - struct net_device *dev; - struct ec_addr addr; - int err; - unsigned char port, cb; -#if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE) - struct sock *sk = sock->sk; - struct sk_buff *skb; - struct ec_cb *eb; -#endif -#ifdef CONFIG_ECONET_AUNUDP - struct msghdr udpmsg; - struct iovec iov[2]; - struct aunhdr ah; - struct sockaddr_in udpdest; - __kernel_size_t size; - mm_segment_t oldfs; - char *userbuf; -#endif - - /* - * Check the flags. - */ - - if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) - return -EINVAL; - - /* - * Get and verify the address. - */ - - mutex_lock(&econet_mutex); - - if (saddr == NULL || msg->msg_namelen < sizeof(struct sockaddr_ec)) { - mutex_unlock(&econet_mutex); - return -EINVAL; - } - addr.station = saddr->addr.station; - addr.net = saddr->addr.net; - port = saddr->port; - cb = saddr->cb; - - /* Look for a device with the right network number. */ - dev = net2dev_map[addr.net]; - - /* If not directly reachable, use some default */ - if (dev == NULL) { - dev = net2dev_map[0]; - /* No interfaces at all? */ - if (dev == NULL) { - mutex_unlock(&econet_mutex); - return -ENETDOWN; - } - } - - if (dev->type == ARPHRD_ECONET) { - /* Real hardware Econet. We're not worthy etc. */ -#ifdef CONFIG_ECONET_NATIVE - unsigned short proto = 0; - int hlen, tlen; - int res; - - if (len + 15 > dev->mtu) { - mutex_unlock(&econet_mutex); - return -EMSGSIZE; - } - - dev_hold(dev); - - hlen = LL_RESERVED_SPACE(dev); - tlen = dev->needed_tailroom; - skb = sock_alloc_send_skb(sk, len + hlen + tlen, - msg->msg_flags & MSG_DONTWAIT, &err); - if (skb == NULL) - goto out_unlock; - - skb_reserve(skb, hlen); - skb_reset_network_header(skb); - - eb = (struct ec_cb *)&skb->cb; - - eb->cookie = saddr->cookie; - eb->sec = *saddr; - eb->sent = ec_tx_done; - - err = -EINVAL; - res = dev_hard_header(skb, dev, ntohs(proto), &addr, NULL, len); - if (res < 0) - goto out_free; - if (res > 0) { - struct ec_framehdr *fh; - /* Poke in our control byte and - port number. Hack, hack. */ - fh = (struct ec_framehdr *)skb->data; - fh->cb = cb; - fh->port = port; - if (sock->type != SOCK_DGRAM) { - skb_reset_tail_pointer(skb); - skb->len = 0; - } - } - - /* Copy the data. Returns -EFAULT on error */ - err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); - skb->protocol = proto; - skb->dev = dev; - skb->priority = sk->sk_priority; - if (err) - goto out_free; - - err = -ENETDOWN; - if (!(dev->flags & IFF_UP)) - goto out_free; - - /* - * Now send it - */ - - dev_queue_xmit(skb); - dev_put(dev); - mutex_unlock(&econet_mutex); - return len; - -out_free: - kfree_skb(skb); -out_unlock: - if (dev) - dev_put(dev); -#else - err = -EPROTOTYPE; -#endif - mutex_unlock(&econet_mutex); - - return err; - } - -#ifdef CONFIG_ECONET_AUNUDP - /* AUN virtual Econet. */ - - if (udpsock == NULL) { - mutex_unlock(&econet_mutex); - return -ENETDOWN; /* No socket - can't send */ - } - - if (len > 32768) { - err = -E2BIG; - goto error; - } - - /* Make up a UDP datagram and hand it off to some higher intellect. */ - - memset(&udpdest, 0, sizeof(udpdest)); - udpdest.sin_family = AF_INET; - udpdest.sin_port = htons(AUN_PORT); - - /* At the moment we use the stupid Acorn scheme of Econet address - y.x maps to IP a.b.c.x. This should be replaced with something - more flexible and more aware of subnet masks. */ - { - struct in_device *idev; - unsigned long network = 0; - - rcu_read_lock(); - idev = __in_dev_get_rcu(dev); - if (idev) { - if (idev->ifa_list) - network = ntohl(idev->ifa_list->ifa_address) & - 0xffffff00; /* !!! */ - } - rcu_read_unlock(); - udpdest.sin_addr.s_addr = htonl(network | addr.station); - } - - memset(&ah, 0, sizeof(ah)); - ah.port = port; - ah.cb = cb & 0x7f; - ah.code = 2; /* magic */ - - /* tack our header on the front of the iovec */ - size = sizeof(struct aunhdr); - iov[0].iov_base = (void *)&ah; - iov[0].iov_len = size; - - userbuf = vmalloc(len); - if (userbuf == NULL) { - err = -ENOMEM; - goto error; - } - - iov[1].iov_base = userbuf; - iov[1].iov_len = len; - err = memcpy_fromiovec(userbuf, msg->msg_iov, len); - if (err) - goto error_free_buf; - - /* Get a skbuff (no data, just holds our cb information) */ - skb = sock_alloc_send_skb(sk, 0, msg->msg_flags & MSG_DONTWAIT, &err); - if (skb == NULL) - goto error_free_buf; - - eb = (struct ec_cb *)&skb->cb; - - eb->cookie = saddr->cookie; - eb->timeout = 5 * HZ; - eb->start = jiffies; - ah.handle = aun_seq; - eb->seq = (aun_seq++); - eb->sec = *saddr; - - skb_queue_tail(&aun_queue, skb); - - udpmsg.msg_name = (void *)&udpdest; - udpmsg.msg_namelen = sizeof(udpdest); - udpmsg.msg_iov = &iov[0]; - udpmsg.msg_iovlen = 2; - udpmsg.msg_control = NULL; - udpmsg.msg_controllen = 0; - udpmsg.msg_flags = 0; - - oldfs = get_fs(); - set_fs(KERNEL_DS); /* More privs :-) */ - err = sock_sendmsg(udpsock, &udpmsg, size); - set_fs(oldfs); - -error_free_buf: - vfree(userbuf); -error: -#else - err = -EPROTOTYPE; -#endif - mutex_unlock(&econet_mutex); - - return err; -} - -/* - * Look up the address of a socket. - */ - -static int econet_getname(struct socket *sock, struct sockaddr *uaddr, - int *uaddr_len, int peer) -{ - struct sock *sk; - struct econet_sock *eo; - struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr; - - if (peer) - return -EOPNOTSUPP; - - memset(sec, 0, sizeof(*sec)); - mutex_lock(&econet_mutex); - - sk = sock->sk; - eo = ec_sk(sk); - - sec->sec_family = AF_ECONET; - sec->port = eo->port; - sec->addr.station = eo->station; - sec->addr.net = eo->net; - - mutex_unlock(&econet_mutex); - - *uaddr_len = sizeof(*sec); - return 0; -} - -static void econet_destroy_timer(unsigned long data) -{ - struct sock *sk = (struct sock *)data; - - if (!sk_has_allocations(sk)) { - sk_free(sk); - return; - } - - sk->sk_timer.expires = jiffies + 10 * HZ; - add_timer(&sk->sk_timer); - pr_debug("econet: socket destroy delayed\n"); -} - -/* - * Close an econet socket. - */ - -static int econet_release(struct socket *sock) -{ - struct sock *sk; - - mutex_lock(&econet_mutex); - - sk = sock->sk; - if (!sk) - goto out_unlock; - - econet_remove_socket(&econet_sklist, sk); - - /* - * Now the socket is dead. No more input will appear. - */ - - sk->sk_state_change(sk); /* It is useless. Just for sanity. */ - - sock_orphan(sk); - - /* Purge queues */ - - skb_queue_purge(&sk->sk_receive_queue); - - if (sk_has_allocations(sk)) { - sk->sk_timer.data = (unsigned long)sk; - sk->sk_timer.expires = jiffies + HZ; - sk->sk_timer.function = econet_destroy_timer; - add_timer(&sk->sk_timer); - - goto out_unlock; - } - - sk_free(sk); - -out_unlock: - mutex_unlock(&econet_mutex); - return 0; -} - -static struct proto econet_proto = { - .name = "ECONET", - .owner = THIS_MODULE, - .obj_size = sizeof(struct econet_sock), -}; - -/* - * Create an Econet socket - */ - -static int econet_create(struct net *net, struct socket *sock, int protocol, - int kern) -{ - struct sock *sk; - struct econet_sock *eo; - int err; - - if (!net_eq(net, &init_net)) - return -EAFNOSUPPORT; - - /* Econet only provides datagram services. */ - if (sock->type != SOCK_DGRAM) - return -ESOCKTNOSUPPORT; - - sock->state = SS_UNCONNECTED; - - err = -ENOBUFS; - sk = sk_alloc(net, PF_ECONET, GFP_KERNEL, &econet_proto); - if (sk == NULL) - goto out; - - sk->sk_reuse = SK_CAN_REUSE; - sock->ops = &econet_ops; - sock_init_data(sock, sk); - - eo = ec_sk(sk); - sock_reset_flag(sk, SOCK_ZAPPED); - sk->sk_family = PF_ECONET; - eo->num = protocol; - - econet_insert_socket(&econet_sklist, sk); - return 0; -out: - return err; -} - -/* - * Handle Econet specific ioctls - */ - -static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg) -{ - struct ifreq ifr; - struct ec_device *edev; - struct net_device *dev; - struct sockaddr_ec *sec; - int err; - - /* - * Fetch the caller's info block into kernel space - */ - - if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) - return -EFAULT; - - dev = dev_get_by_name(&init_net, ifr.ifr_name); - if (dev == NULL) - return -ENODEV; - - sec = (struct sockaddr_ec *)&ifr.ifr_addr; - - mutex_lock(&econet_mutex); - - err = 0; - switch (cmd) { - case SIOCSIFADDR: - if (!capable(CAP_NET_ADMIN)) { - err = -EPERM; - break; - } - - edev = dev->ec_ptr; - if (edev == NULL) { - /* Magic up a new one. */ - edev = kzalloc(sizeof(struct ec_device), GFP_KERNEL); - if (edev == NULL) { - err = -ENOMEM; - break; - } - dev->ec_ptr = edev; - } else - net2dev_map[edev->net] = NULL; - edev->station = sec->addr.station; - edev->net = sec->addr.net; - net2dev_map[sec->addr.net] = dev; - if (!net2dev_map[0]) - net2dev_map[0] = dev; - break; - - case SIOCGIFADDR: - edev = dev->ec_ptr; - if (edev == NULL) { - err = -ENODEV; - break; - } - memset(sec, 0, sizeof(struct sockaddr_ec)); - sec->addr.station = edev->station; - sec->addr.net = edev->net; - sec->sec_family = AF_ECONET; - dev_put(dev); - if (copy_to_user(arg, &ifr, sizeof(struct ifreq))) - err = -EFAULT; - break; - - default: - err = -EINVAL; - break; - } - - mutex_unlock(&econet_mutex); - - dev_put(dev); - - return err; -} - -/* - * Handle generic ioctls - */ - -static int econet_ioctl(struct socket *sock, unsigned int cmd, - unsigned long arg) -{ - struct sock *sk = sock->sk; - void __user *argp = (void __user *)arg; - - switch (cmd) { - case SIOCGSTAMP: - return sock_get_timestamp(sk, argp); - - case SIOCGSTAMPNS: - return sock_get_timestampns(sk, argp); - - case SIOCSIFADDR: - case SIOCGIFADDR: - return ec_dev_ioctl(sock, cmd, argp); - - } - - return -ENOIOCTLCMD; -} - -static const struct net_proto_family econet_family_ops = { - .family = PF_ECONET, - .create = econet_create, - .owner = THIS_MODULE, -}; - -static const struct proto_ops econet_ops = { - .family = PF_ECONET, - .owner = THIS_MODULE, - .release = econet_release, - .bind = econet_bind, - .connect = sock_no_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .getname = econet_getname, - .poll = datagram_poll, - .ioctl = econet_ioctl, - .listen = sock_no_listen, - .shutdown = sock_no_shutdown, - .setsockopt = sock_no_setsockopt, - .getsockopt = sock_no_getsockopt, - .sendmsg = econet_sendmsg, - .recvmsg = econet_recvmsg, - .mmap = sock_no_mmap, - .sendpage = sock_no_sendpage, -}; - -#if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE) -/* - * Find the listening socket, if any, for the given data. - */ - -static struct sock *ec_listening_socket(unsigned char port, unsigned char - station, unsigned char net) -{ - struct sock *sk; - struct hlist_node *node; - - spin_lock(&econet_lock); - sk_for_each(sk, node, &econet_sklist) { - struct econet_sock *opt = ec_sk(sk); - if ((opt->port == port || opt->port == 0) && - (opt->station == station || opt->station == 0) && - (opt->net == net || opt->net == 0)) { - sock_hold(sk); - goto found; - } - } - sk = NULL; -found: - spin_unlock(&econet_lock); - return sk; -} - -/* - * Queue a received packet for a socket. - */ - -static int ec_queue_packet(struct sock *sk, struct sk_buff *skb, - unsigned char stn, unsigned char net, - unsigned char cb, unsigned char port) -{ - struct ec_cb *eb = (struct ec_cb *)&skb->cb; - struct sockaddr_ec *sec = (struct sockaddr_ec *)&eb->sec; - - memset(sec, 0, sizeof(struct sockaddr_ec)); - sec->sec_family = AF_ECONET; - sec->type = ECTYPE_PACKET_RECEIVED; - sec->port = port; - sec->cb = cb; - sec->addr.net = net; - sec->addr.station = stn; - - return sock_queue_rcv_skb(sk, skb); -} -#endif - -#ifdef CONFIG_ECONET_AUNUDP -/* - * Send an AUN protocol response. - */ - -static void aun_send_response(__u32 addr, unsigned long seq, int code, int cb) -{ - struct sockaddr_in sin = { - .sin_family = AF_INET, - .sin_port = htons(AUN_PORT), - .sin_addr = {.s_addr = addr} - }; - struct aunhdr ah = {.code = code, .cb = cb, .handle = seq}; - struct kvec iov = {.iov_base = (void *)&ah, .iov_len = sizeof(ah)}; - struct msghdr udpmsg; - - udpmsg.msg_name = (void *)&sin; - udpmsg.msg_namelen = sizeof(sin); - udpmsg.msg_control = NULL; - udpmsg.msg_controllen = 0; - udpmsg.msg_flags = 0; - - kernel_sendmsg(udpsock, &udpmsg, &iov, 1, sizeof(ah)); -} - - -/* - * Handle incoming AUN packets. Work out if anybody wants them, - * and send positive or negative acknowledgements as appropriate. - */ - -static void aun_incoming(struct sk_buff *skb, struct aunhdr *ah, size_t len) -{ - struct iphdr *ip = ip_hdr(skb); - unsigned char stn = ntohl(ip->saddr) & 0xff; - struct dst_entry *dst = skb_dst(skb); - struct ec_device *edev = NULL; - struct sock *sk = NULL; - struct sk_buff *newskb; - - if (dst) - edev = dst->dev->ec_ptr; - - if (!edev) - goto bad; - - sk = ec_listening_socket(ah->port, stn, edev->net); - if (sk == NULL) - goto bad; /* Nobody wants it */ - - newskb = alloc_skb((len - sizeof(struct aunhdr) + 15) & ~15, - GFP_ATOMIC); - if (newskb == NULL) { - pr_debug("AUN: memory squeeze, dropping packet\n"); - /* Send nack and hope sender tries again */ - goto bad; - } - - memcpy(skb_put(newskb, len - sizeof(struct aunhdr)), (void *)(ah + 1), - len - sizeof(struct aunhdr)); - - if (ec_queue_packet(sk, newskb, stn, edev->net, ah->cb, ah->port)) { - /* Socket is bankrupt. */ - kfree_skb(newskb); - goto bad; - } - - aun_send_response(ip->saddr, ah->handle, 3, 0); - sock_put(sk); - return; - -bad: - aun_send_response(ip->saddr, ah->handle, 4, 0); - if (sk) - sock_put(sk); -} - -/* - * Handle incoming AUN transmit acknowledgements. If the sequence - * number matches something in our backlog then kill it and tell - * the user. If the remote took too long to reply then we may have - * dropped the packet already. - */ - -static void aun_tx_ack(unsigned long seq, int result) -{ - struct sk_buff *skb; - unsigned long flags; - struct ec_cb *eb; - - spin_lock_irqsave(&aun_queue_lock, flags); - skb_queue_walk(&aun_queue, skb) { - eb = (struct ec_cb *)&skb->cb; - if (eb->seq == seq) - goto foundit; - } - spin_unlock_irqrestore(&aun_queue_lock, flags); - pr_debug("AUN: unknown sequence %ld\n", seq); - return; - -foundit: - tx_result(skb->sk, eb->cookie, result); - skb_unlink(skb, &aun_queue); - spin_unlock_irqrestore(&aun_queue_lock, flags); - kfree_skb(skb); -} - -/* - * Deal with received AUN frames - sort out what type of thing it is - * and hand it to the right function. - */ - -static void aun_data_available(struct sock *sk, int slen) -{ - int err; - struct sk_buff *skb; - unsigned char *data; - struct aunhdr *ah; - size_t len; - - while ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL) { - if (err == -EAGAIN) { - pr_err("AUN: no data available?!\n"); - return; - } - pr_debug("AUN: recvfrom() error %d\n", -err); - } - - data = skb_transport_header(skb) + sizeof(struct udphdr); - ah = (struct aunhdr *)data; - len = skb->len - sizeof(struct udphdr); - - switch (ah->code) { - case 2: - aun_incoming(skb, ah, len); - break; - case 3: - aun_tx_ack(ah->handle, ECTYPE_TRANSMIT_OK); - break; - case 4: - aun_tx_ack(ah->handle, ECTYPE_TRANSMIT_NOT_LISTENING); - break; - default: - pr_debug("AUN: unknown packet type: %d\n", data[0]); - } - - skb_free_datagram(sk, skb); -} - -/* - * Called by the timer to manage the AUN transmit queue. If a packet - * was sent to a dead or nonexistent host then we will never get an - * acknowledgement back. After a few seconds we need to spot this and - * drop the packet. - */ - -static void ab_cleanup(unsigned long h) -{ - struct sk_buff *skb, *n; - unsigned long flags; - - spin_lock_irqsave(&aun_queue_lock, flags); - skb_queue_walk_safe(&aun_queue, skb, n) { - struct ec_cb *eb = (struct ec_cb *)&skb->cb; - if ((jiffies - eb->start) > eb->timeout) { - tx_result(skb->sk, eb->cookie, - ECTYPE_TRANSMIT_NOT_PRESENT); - skb_unlink(skb, &aun_queue); - kfree_skb(skb); - } - } - spin_unlock_irqrestore(&aun_queue_lock, flags); - - mod_timer(&ab_cleanup_timer, jiffies + (HZ * 2)); -} - -static int __init aun_udp_initialise(void) -{ - int error; - struct sockaddr_in sin; - - skb_queue_head_init(&aun_queue); - setup_timer(&ab_cleanup_timer, ab_cleanup, 0); - ab_cleanup_timer.expires = jiffies + (HZ * 2); - add_timer(&ab_cleanup_timer); - - memset(&sin, 0, sizeof(sin)); - sin.sin_port = htons(AUN_PORT); - - /* We can count ourselves lucky Acorn machines are too dim to - speak IPv6. :-) */ - error = sock_create_kern(PF_INET, SOCK_DGRAM, 0, &udpsock); - if (error < 0) { - pr_err("AUN: socket error %d\n", -error); - return error; - } - - udpsock->sk->sk_reuse = SK_CAN_REUSE; - udpsock->sk->sk_allocation = GFP_ATOMIC; /* we're going to call it - from interrupts */ - - error = udpsock->ops->bind(udpsock, (struct sockaddr *)&sin, - sizeof(sin)); - if (error < 0) { - pr_err("AUN: bind error %d\n", -error); - goto release; - } - - udpsock->sk->sk_data_ready = aun_data_available; - - return 0; - -release: - sock_release(udpsock); - udpsock = NULL; - return error; -} -#endif - -#ifdef CONFIG_ECONET_NATIVE - -/* - * Receive an Econet frame from a device. - */ - -static int econet_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) -{ - struct ec_framehdr *hdr; - struct sock *sk = NULL; - struct ec_device *edev = dev->ec_ptr; - - if (!net_eq(dev_net(dev), &init_net)) - goto drop; - - if (skb->pkt_type == PACKET_OTHERHOST) - goto drop; - - if (!edev) - goto drop; - - skb = skb_share_check(skb, GFP_ATOMIC); - if (skb == NULL) - return NET_RX_DROP; - - if (!pskb_may_pull(skb, sizeof(struct ec_framehdr))) - goto drop; - - hdr = (struct ec_framehdr *)skb->data; - - /* First check for encapsulated IP */ - if (hdr->port == EC_PORT_IP) { - skb->protocol = htons(ETH_P_IP); - skb_pull(skb, sizeof(struct ec_framehdr)); - netif_rx(skb); - return NET_RX_SUCCESS; - } - - sk = ec_listening_socket(hdr->port, hdr->src_stn, hdr->src_net); - if (!sk) - goto drop; - - if (ec_queue_packet(sk, skb, edev->net, hdr->src_stn, hdr->cb, - hdr->port)) - goto drop; - sock_put(sk); - return NET_RX_SUCCESS; - -drop: - if (sk) - sock_put(sk); - kfree_skb(skb); - return NET_RX_DROP; -} - -static struct packet_type econet_packet_type __read_mostly = { - .type = cpu_to_be16(ETH_P_ECONET), - .func = econet_rcv, -}; - -static void econet_hw_initialise(void) -{ - dev_add_pack(&econet_packet_type); -} - -#endif - -static int econet_notifier(struct notifier_block *this, unsigned long msg, - void *data) -{ - struct net_device *dev = data; - struct ec_device *edev; - - if (!net_eq(dev_net(dev), &init_net)) - return NOTIFY_DONE; - - switch (msg) { - case NETDEV_UNREGISTER: - /* A device has gone down - kill any data we hold for it. */ - edev = dev->ec_ptr; - if (edev) { - if (net2dev_map[0] == dev) - net2dev_map[0] = NULL; - net2dev_map[edev->net] = NULL; - kfree(edev); - dev->ec_ptr = NULL; - } - break; - } - - return NOTIFY_DONE; -} - -static struct notifier_block econet_netdev_notifier = { - .notifier_call = econet_notifier, -}; - -static void __exit econet_proto_exit(void) -{ -#ifdef CONFIG_ECONET_AUNUDP - del_timer(&ab_cleanup_timer); - if (udpsock) - sock_release(udpsock); -#endif - unregister_netdevice_notifier(&econet_netdev_notifier); -#ifdef CONFIG_ECONET_NATIVE - dev_remove_pack(&econet_packet_type); -#endif - sock_unregister(econet_family_ops.family); - proto_unregister(&econet_proto); -} - -static int __init econet_proto_init(void) -{ - int err = proto_register(&econet_proto, 0); - - if (err != 0) - goto out; - sock_register(&econet_family_ops); -#ifdef CONFIG_ECONET_AUNUDP - aun_udp_initialise(); -#endif -#ifdef CONFIG_ECONET_NATIVE - econet_hw_initialise(); -#endif - register_netdevice_notifier(&econet_netdev_notifier); -out: - return err; -} - -module_init(econet_proto_init); -module_exit(econet_proto_exit); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_NETPROTO(PF_ECONET);
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 5889a6c..36e5880 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c
@@ -164,7 +164,7 @@ eth = eth_hdr(skb); if (unlikely(is_multicast_ether_addr(eth->h_dest))) { - if (!compare_ether_addr_64bits(eth->h_dest, dev->broadcast)) + if (ether_addr_equal_64bits(eth->h_dest, dev->broadcast)) skb->pkt_type = PACKET_BROADCAST; else skb->pkt_type = PACKET_MULTICAST; @@ -179,7 +179,8 @@ */ else if (1 /*dev->flags&IFF_PROMISC */ ) { - if (unlikely(compare_ether_addr_64bits(eth->h_dest, dev->dev_addr))) + if (unlikely(!ether_addr_equal_64bits(eth->h_dest, + dev->dev_addr))) skb->pkt_type = PACKET_OTHERHOST; }
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index 3bdc430..eed2916 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c
@@ -179,6 +179,7 @@ const char *devname; int rc = -ENOBUFS; struct net_device *dev; + int type = __IEEE802154_DEV_INVALID; pr_debug("%s\n", __func__); @@ -221,7 +222,13 @@ goto nla_put_failure; } - dev = phy->add_iface(phy, devname); + if (info->attrs[IEEE802154_ATTR_DEV_TYPE]) { + type = nla_get_u8(info->attrs[IEEE802154_ATTR_DEV_TYPE]); + if (type >= __IEEE802154_DEV_MAX) + return -EINVAL; + } + + dev = phy->add_iface(phy, devname, type); if (IS_ERR(dev)) { rc = PTR_ERR(dev); goto nla_put_failure;
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index d183262..20f1cb5 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig
@@ -262,8 +262,8 @@ bool "IP: ARP daemon support" ---help--- The kernel maintains an internal cache which maps IP addresses to - hardware addresses on the local network, so that Ethernet/Token Ring/ - etc. frames are sent to the proper address on the physical networking + hardware addresses on the local network, so that Ethernet + frames are sent to the proper address on the physical networking layer. Normally, kernel uses the ARP protocol to resolve these mappings. @@ -312,7 +312,7 @@ config INET_AH tristate "IP: AH transformation" - select XFRM + select XFRM_ALGO select CRYPTO select CRYPTO_HMAC select CRYPTO_MD5 @@ -324,7 +324,7 @@ config INET_ESP tristate "IP: ESP transformation" - select XFRM + select XFRM_ALGO select CRYPTO select CRYPTO_AUTHENC select CRYPTO_HMAC
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index 3a28075..e8f2617 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c
@@ -406,8 +406,8 @@ ah->spi, IPPROTO_AH, AF_INET); if (!x) return; - printk(KERN_DEBUG "pmtu discovery on SA AH/%08x/%08x\n", - ntohl(ah->spi), ntohl(iph->daddr)); + pr_debug("pmtu discovery on SA AH/%08x/%08x\n", + ntohl(ah->spi), ntohl(iph->daddr)); xfrm_state_put(x); }
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 373b56b..cda37be 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c
@@ -73,6 +73,8 @@ * Jesper D. Brouer: Proxy ARP PVLAN RFC 3069 support. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/types.h> #include <linux/string.h> @@ -89,7 +91,6 @@ #include <linux/etherdevice.h> #include <linux/fddidevice.h> #include <linux/if_arp.h> -#include <linux/trdevice.h> #include <linux/skbuff.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> @@ -193,9 +194,6 @@ case ARPHRD_IEEE802: ip_eth_mc_map(addr, haddr); return 0; - case ARPHRD_IEEE802_TR: - ip_tr_mc_map(addr, haddr); - return 0; case ARPHRD_INFINIBAND: ip_ib_mc_map(addr, dev->broadcast, haddr); return 0; @@ -364,8 +362,7 @@ probes -= neigh->parms->ucast_probes; if (probes < 0) { if (!(neigh->nud_state & NUD_VALID)) - printk(KERN_DEBUG - "trying to ucast probe in NUD_INVALID\n"); + pr_debug("trying to ucast probe in NUD_INVALID\n"); dst_ha = neigh->ha; read_lock_bh(&neigh->lock); } else { @@ -452,7 +449,7 @@ { switch (addr_hint) { case RTN_LOCAL: - printk(KERN_DEBUG "ARP: arp called for own IP address\n"); + pr_debug("arp called for own IP address\n"); memcpy(haddr, dev->dev_addr, dev->addr_len); return 1; case RTN_MULTICAST: @@ -473,7 +470,7 @@ struct neighbour *n; if (!skb_dst(skb)) { - printk(KERN_DEBUG "arp_find is called with dst==NULL\n"); + pr_debug("arp_find is called with dst==NULL\n"); kfree_skb(skb); return 1; } @@ -648,12 +645,6 @@ arp->ar_pro = htons(ETH_P_IP); break; #endif -#if IS_ENABLED(CONFIG_TR) - case ARPHRD_IEEE802_TR: - arp->ar_hrd = htons(ARPHRD_IEEE802); - arp->ar_pro = htons(ETH_P_IP); - break; -#endif } arp->ar_hln = dev->addr_len; @@ -751,11 +742,10 @@ goto out; break; case ARPHRD_ETHER: - case ARPHRD_IEEE802_TR: case ARPHRD_FDDI: case ARPHRD_IEEE802: /* - * ETHERNET, Token Ring and Fibre Channel (which are IEEE 802 + * ETHERNET, and Fibre Channel (which are IEEE 802 * devices, according to RFC 2625) devices will accept ARP * hardware types of either 1 (Ethernet) or 6 (IEEE 802.2). * This is the case also of FDDI, where the RFC 1390 says that
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 88c9e3f..10e15a1 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c
@@ -217,8 +217,7 @@ WARN_ON(idev->ifa_list); WARN_ON(idev->mc_list); #ifdef NET_REFCNT_DEBUG - printk(KERN_DEBUG "in_dev_finish_destroy: %p=%s\n", - idev, dev ? dev->name : "NIL"); + pr_debug("%s: %p=%s\n", __func__, idev, dev ? dev->name : "NIL"); #endif dev_put(dev); if (!idev->dead) @@ -1174,7 +1173,7 @@ switch (event) { case NETDEV_REGISTER: - printk(KERN_DEBUG "inetdev_event: bug\n"); + pr_debug("%s: bug\n", __func__); RCU_INIT_POINTER(dev->ip_ptr, NULL); break; case NETDEV_UP:
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index bce36f1..30b88d7 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c
@@ -1370,6 +1370,8 @@ if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos) continue; + if (fi->fib_dead) + continue; if (fa->fa_info->fib_scope < flp->flowi4_scope) continue; fib_alias_accessed(fa);
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 2cb2bf8..c75efbd 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c
@@ -713,11 +713,10 @@ if (!net->ipv4.sysctl_icmp_ignore_bogus_error_responses && inet_addr_type(net, iph->daddr) == RTN_BROADCAST) { - if (net_ratelimit()) - pr_warn("%pI4 sent an invalid ICMP type %u, code %u error to a broadcast: %pI4 on %s\n", - &ip_hdr(skb)->saddr, - icmph->type, icmph->code, - &iph->daddr, skb->dev->name); + net_warn_ratelimited("%pI4 sent an invalid ICMP type %u, code %u error to a broadcast: %pI4 on %s\n", + &ip_hdr(skb)->saddr, + icmph->type, icmph->code, + &iph->daddr, skb->dev->name); goto out; } @@ -906,8 +905,7 @@ static void icmp_address(struct sk_buff *skb) { #if 0 - if (net_ratelimit()) - printk(KERN_DEBUG "a guy asks for address mask. Who is it?\n"); + net_dbg_ratelimited("a guy asks for address mask. Who is it?\n"); #endif } @@ -943,10 +941,10 @@ inet_ifa_match(ip_hdr(skb)->saddr, ifa)) break; } - if (!ifa && net_ratelimit()) { - pr_info("Wrong address mask %pI4 from %s/%pI4\n", - mp, dev->name, &ip_hdr(skb)->saddr); - } + if (!ifa) + net_info_ratelimited("Wrong address mask %pI4 from %s/%pI4\n", + mp, + dev->name, &ip_hdr(skb)->saddr); } }
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index 543ef62..2784db3 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c
@@ -89,8 +89,8 @@ #ifdef SOCK_REFCNT_DEBUG if (atomic_read(&tw->tw_refcnt) != 1) { - printk(KERN_DEBUG "%s timewait_sock %p refcnt=%d\n", - tw->tw_prot->name, tw, atomic_read(&tw->tw_refcnt)); + pr_debug("%s timewait_sock %p refcnt=%d\n", + tw->tw_prot->name, tw, atomic_read(&tw->tw_refcnt)); } #endif while (refcnt) {
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 71e5c32..9dbd3dd 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c
@@ -148,17 +148,17 @@ return ipqhashfn(ipq->id, ipq->saddr, ipq->daddr, ipq->protocol); } -static int ip4_frag_match(struct inet_frag_queue *q, void *a) +static bool ip4_frag_match(struct inet_frag_queue *q, void *a) { struct ipq *qp; struct ip4_create_arg *arg = a; qp = container_of(q, struct ipq, q); return qp->id == arg->iph->id && - qp->saddr == arg->iph->saddr && - qp->daddr == arg->iph->daddr && - qp->protocol == arg->iph->protocol && - qp->user == arg->user; + qp->saddr == arg->iph->saddr && + qp->daddr == arg->iph->daddr && + qp->protocol == arg->iph->protocol && + qp->user == arg->user; } /* Memory Tracking Functions. */ @@ -545,6 +545,7 @@ int len; int ihlen; int err; + int sum_truesize; u8 ecn; ipq_kill(qp); @@ -611,19 +612,32 @@ atomic_add(clone->truesize, &qp->q.net->mem); } - skb_shinfo(head)->frag_list = head->next; skb_push(head, head->data - skb_network_header(head)); - for (fp=head->next; fp; fp = fp->next) { - head->data_len += fp->len; - head->len += fp->len; + sum_truesize = head->truesize; + for (fp = head->next; fp;) { + bool headstolen; + int delta; + struct sk_buff *next = fp->next; + + sum_truesize += fp->truesize; if (head->ip_summed != fp->ip_summed) head->ip_summed = CHECKSUM_NONE; else if (head->ip_summed == CHECKSUM_COMPLETE) head->csum = csum_add(head->csum, fp->csum); - head->truesize += fp->truesize; + + if (skb_try_coalesce(head, fp, &headstolen, &delta)) { + kfree_skb_partial(fp, headstolen); + } else { + if (!skb_shinfo(head)->frag_list) + skb_shinfo(head)->frag_list = fp; + head->data_len += fp->len; + head->len += fp->len; + head->truesize += fp->truesize; + } + fp = next; } - atomic_sub(head->truesize, &qp->q.net->mem); + atomic_sub(sum_truesize, &qp->q.net->mem); head->next = NULL; head->dev = dev; @@ -644,8 +658,7 @@ err = -ENOMEM; goto out_fail; out_oversize: - if (net_ratelimit()) - pr_info("Oversized IP packet from %pI4\n", &qp->saddr); + net_info_ratelimited("Oversized IP packet from %pI4\n", &qp->saddr); out_fail: IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS); return err;
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 26eccc5..8590144 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c
@@ -210,9 +210,8 @@ int ret; if (!net_eq(net, &init_net) && !ipprot->netns_ok) { - if (net_ratelimit()) - printk("%s: proto %d isn't netns-ready\n", - __func__, protocol); + net_info_ratelimited("%s: proto %d isn't netns-ready\n", + __func__, protocol); kfree_skb(skb); goto out; } @@ -298,10 +297,10 @@ if (in_dev) { if (!IN_DEV_SOURCE_ROUTE(in_dev)) { - if (IN_DEV_LOG_MARTIANS(in_dev) && - net_ratelimit()) - pr_info("source route option %pI4 -> %pI4\n", - &iph->saddr, &iph->daddr); + if (IN_DEV_LOG_MARTIANS(in_dev)) + net_info_ratelimited("source route option %pI4 -> %pI4\n", + &iph->saddr, + &iph->daddr); goto drop; } }
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 95722ed..708b994 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c
@@ -578,8 +578,10 @@ ip_hdr(skb)->daddr = opt->nexthop; ip_rt_get_source(&optptr[srrptr-1], skb, rt); optptr[2] = srrptr+4; - } else if (net_ratelimit()) - pr_crit("%s(): Argh! Destination lost!\n", __func__); + } else { + net_crit_ratelimited("%s(): Argh! Destination lost!\n", + __func__); + } if (opt->ts_needaddr) { optptr = raw + opt->ts; ip_rt_get_source(&optptr[optptr[2]-9], skb, rt);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 4910176..451f97c 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c
@@ -214,8 +214,8 @@ } rcu_read_unlock(); - if (net_ratelimit()) - printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n"); + net_dbg_ratelimited("%s: No header cache and no neighbour!\n", + __func__); kfree_skb(skb); return -EINVAL; }
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index f267280..67e8a6b 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c
@@ -808,8 +808,6 @@ b->op = BOOTP_REQUEST; if (dev->type < 256) /* check for false types */ b->htype = dev->type; - else if (dev->type == ARPHRD_IEEE802_TR) /* fix for token ring */ - b->htype = ARPHRD_IEEE802; else if (dev->type == ARPHRD_FDDI) b->htype = ARPHRD_ETHER; else { @@ -955,8 +953,7 @@ /* Fragments are not supported */ if (ip_is_fragment(h)) { - if (net_ratelimit()) - pr_err("DHCP/BOOTP: Ignoring fragmented reply\n"); + net_err_ratelimited("DHCP/BOOTP: Ignoring fragmented reply\n"); goto drop; } @@ -1004,16 +1001,14 @@ /* Is it a reply to our BOOTP request? */ if (b->op != BOOTP_REPLY || b->xid != d->xid) { - if (net_ratelimit()) - pr_err("DHCP/BOOTP: Reply not for us, op[%x] xid[%x]\n", - b->op, b->xid); + net_err_ratelimited("DHCP/BOOTP: Reply not for us, op[%x] xid[%x]\n", + b->op, b->xid); goto drop_unlock; } /* Is it a reply for the device we are configuring? */ if (b->xid != ic_dev_xid) { - if (net_ratelimit()) - pr_err("DHCP/BOOTP: Ignoring delayed packet\n"); + net_err_ratelimited("DHCP/BOOTP: Ignoring delayed packet\n"); goto drop_unlock; } @@ -1626,11 +1621,13 @@ return 1; } +__setup("ip=", ip_auto_config_setup); static int __init nfsaddrs_config_setup(char *addrs) { return ip_auto_config_setup(addrs); } +__setup("nfsaddrs=", nfsaddrs_config_setup); static int __init vendor_class_identifier_setup(char *addrs) { @@ -1641,7 +1638,4 @@ vendor_class_identifier); return 1; } - -__setup("ip=", ip_auto_config_setup); -__setup("nfsaddrs=", nfsaddrs_config_setup); __setup("dhcpclass=", vendor_class_identifier_setup);
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 5bef604..a9e519a 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c
@@ -949,8 +949,7 @@ ret = sock_queue_rcv_skb(mroute_sk, skb); rcu_read_unlock(); if (ret < 0) { - if (net_ratelimit()) - pr_warn("mroute: pending queue full, dropping entries\n"); + net_warn_ratelimited("mroute: pending queue full, dropping entries\n"); kfree_skb(skb); }
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index a393527..97e61ea 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c
@@ -221,9 +221,8 @@ static unsigned int arpt_error(struct sk_buff *skb, const struct xt_action_param *par) { - if (net_ratelimit()) - pr_err("arp_tables: error: '%s'\n", - (const char *)par->targinfo); + net_err_ratelimited("arp_tables: error: '%s'\n", + (const char *)par->targinfo); return NF_DROP; }
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 585b80f..170b1fd 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c
@@ -153,8 +153,7 @@ static unsigned int ipt_error(struct sk_buff *skb, const struct xt_action_param *par) { - if (net_ratelimit()) - pr_info("error: `%s'\n", (const char *)par->targinfo); + net_info_ratelimited("error: `%s'\n", (const char *)par->targinfo); return NF_DROP; }
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index a639967..fe5daea 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -246,8 +246,7 @@ dport = ports[1]; } } else { - if (net_ratelimit()) - pr_info("unknown protocol %u\n", iph->protocol); + net_info_ratelimited("unknown protocol %u\n", iph->protocol); } switch (config->hash_mode) {
diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index 8253670..cad29c1 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c
@@ -42,9 +42,7 @@ if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, addroff, sizeof(buf), (char *) &buf, sizeof(buf))) { - if (net_ratelimit()) - pr_notice("nf_nat_h323: nf_nat_mangle_tcp_packet" - " error\n"); + net_notice_ratelimited("nf_nat_h323: nf_nat_mangle_tcp_packet error\n"); return -1; } @@ -58,9 +56,7 @@ if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo, addroff, sizeof(buf), (char *) &buf, sizeof(buf))) { - if (net_ratelimit()) - pr_notice("nf_nat_h323: nf_nat_mangle_udp_packet" - " error\n"); + net_notice_ratelimited("nf_nat_h323: nf_nat_mangle_udp_packet error\n"); return -1; } /* nf_nat_mangle_udp_packet uses skb_make_writable() to copy @@ -214,8 +210,7 @@ /* Run out of expectations */ if (i >= H323_RTP_CHANNEL_MAX) { - if (net_ratelimit()) - pr_notice("nf_nat_h323: out of expectations\n"); + net_notice_ratelimited("nf_nat_h323: out of expectations\n"); return 0; } @@ -244,8 +239,7 @@ } if (nated_port == 0) { /* No port available */ - if (net_ratelimit()) - pr_notice("nf_nat_h323: out of RTP ports\n"); + net_notice_ratelimited("nf_nat_h323: out of RTP ports\n"); return 0; } @@ -308,8 +302,7 @@ } if (nated_port == 0) { /* No port available */ - if (net_ratelimit()) - pr_notice("nf_nat_h323: out of TCP ports\n"); + net_notice_ratelimited("nf_nat_h323: out of TCP ports\n"); return 0; } @@ -365,8 +358,7 @@ } if (nated_port == 0) { /* No port available */ - if (net_ratelimit()) - pr_notice("nf_nat_q931: out of TCP ports\n"); + net_notice_ratelimited("nf_nat_q931: out of TCP ports\n"); return 0; } @@ -456,8 +448,7 @@ } if (nated_port == 0) { /* No port available */ - if (net_ratelimit()) - pr_notice("nf_nat_ras: out of TCP ports\n"); + net_notice_ratelimited("nf_nat_ras: out of TCP ports\n"); return 0; } @@ -545,8 +536,7 @@ } if (nated_port == 0) { /* No port available */ - if (net_ratelimit()) - pr_notice("nf_nat_q931: out of TCP ports\n"); + net_notice_ratelimited("nf_nat_q931: out of TCP ports\n"); return 0; }
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index 2133c30..746edec 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -1206,8 +1206,7 @@ if (!snmp_parse_mangle((unsigned char *)udph + sizeof(struct udphdr), paylen, &map, &udph->check)) { - if (net_ratelimit()) - printk(KERN_WARNING "bsalg: parser failed\n"); + net_warn_ratelimited("bsalg: parser failed\n"); return NF_DROP; } return NF_ACCEPT; @@ -1241,9 +1240,8 @@ * can mess around with the payload. */ if (ntohs(udph->len) != skb->len - (iph->ihl << 2)) { - if (net_ratelimit()) - printk(KERN_WARNING "SNMP: dropping malformed packet src=%pI4 dst=%pI4\n", - &iph->saddr, &iph->daddr); + net_warn_ratelimited("SNMP: dropping malformed packet src=%pI4 dst=%pI4\n", + &iph->saddr, &iph->daddr); return NF_DROP; }
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 5773f5d..ffcb3b0 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c
@@ -960,8 +960,7 @@ static void rt_emergency_hash_rebuild(struct net *net) { - if (net_ratelimit()) - pr_warn("Route hash chain too long!\n"); + net_warn_ratelimited("Route hash chain too long!\n"); rt_cache_invalidate(net); } @@ -1084,8 +1083,7 @@ goto out; if (dst_entries_get_slow(&ipv4_dst_ops) < ip_rt_max_size) goto out; - if (net_ratelimit()) - pr_warn("dst cache overflow\n"); + net_warn_ratelimited("dst cache overflow\n"); RT_CACHE_STAT_INC(gc_dst_overflow); return 1; @@ -1182,8 +1180,7 @@ if (rt->rt_type == RTN_UNICAST || rt_is_output_route(rt)) { int err = rt_bind_neighbour(rt); if (err) { - if (net_ratelimit()) - pr_warn("Neighbour table failure & not caching routes\n"); + net_warn_ratelimited("Neighbour table failure & not caching routes\n"); ip_rt_put(rt); return ERR_PTR(err); } @@ -1299,8 +1296,7 @@ goto restart; } - if (net_ratelimit()) - pr_warn("Neighbour table overflow\n"); + net_warn_ratelimited("Neighbour table overflow\n"); rt_drop(rt); return ERR_PTR(-ENOBUFS); } @@ -1378,8 +1374,7 @@ return; } } else if (!rt) - printk(KERN_DEBUG "rt_bind_peer(0) @%p\n", - __builtin_return_address(0)); + pr_debug("rt_bind_peer(0) @%p\n", __builtin_return_address(0)); ip_select_fb_ident(iph); } @@ -1503,11 +1498,11 @@ reject_redirect: #ifdef CONFIG_IP_ROUTE_VERBOSE - if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) - pr_info("Redirect from %pI4 on %s about %pI4 ignored\n" - " Advised path = %pI4 -> %pI4\n", - &old_gw, dev->name, &new_gw, - &saddr, &daddr); + if (IN_DEV_LOG_MARTIANS(in_dev)) + net_info_ratelimited("Redirect from %pI4 on %s about %pI4 ignored\n" + " Advised path = %pI4 -> %pI4\n", + &old_gw, dev->name, &new_gw, + &saddr, &daddr); #endif ; } @@ -1617,11 +1612,10 @@ ++peer->rate_tokens; #ifdef CONFIG_IP_ROUTE_VERBOSE if (log_martians && - peer->rate_tokens == ip_rt_redirect_number && - net_ratelimit()) - pr_warn("host %pI4/if%d ignores redirects for %pI4 to %pI4\n", - &ip_hdr(skb)->saddr, rt->rt_iif, - &rt->rt_dst, &rt->rt_gateway); + peer->rate_tokens == ip_rt_redirect_number) + net_warn_ratelimited("host %pI4/if%d ignores redirects for %pI4 to %pI4\n", + &ip_hdr(skb)->saddr, rt->rt_iif, + &rt->rt_dst, &rt->rt_gateway); #endif } } @@ -1844,9 +1838,9 @@ static int ip_rt_bug(struct sk_buff *skb) { - printk(KERN_DEBUG "ip_rt_bug: %pI4 -> %pI4, %s\n", - &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, - skb->dev ? skb->dev->name : "?"); + pr_debug("%s: %pI4 -> %pI4, %s\n", + __func__, &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, + skb->dev ? skb->dev->name : "?"); kfree_skb(skb); WARN_ON(1); return 0; @@ -2135,8 +2129,7 @@ /* get a working reference to the output device */ out_dev = __in_dev_get_rcu(FIB_RES_DEV(*res)); if (out_dev == NULL) { - if (net_ratelimit()) - pr_crit("Bug in ip_route_input_slow(). Please report.\n"); + net_crit_ratelimited("Bug in ip_route_input_slow(). Please report.\n"); return -EINVAL; } @@ -2407,9 +2400,9 @@ martian_destination: RT_CACHE_STAT_INC(in_martian_dst); #ifdef CONFIG_IP_ROUTE_VERBOSE - if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) - pr_warn("martian destination %pI4 from %pI4, dev %s\n", - &daddr, &saddr, dev->name); + if (IN_DEV_LOG_MARTIANS(in_dev)) + net_warn_ratelimited("martian destination %pI4 from %pI4, dev %s\n", + &daddr, &saddr, dev->name); #endif e_hostunreach: @@ -3415,9 +3408,15 @@ static __initdata unsigned long rhash_entries; static int __init set_rhash_entries(char *str) { + ssize_t ret; + if (!str) return 0; - rhash_entries = simple_strtoul(str, &str, 0); + + ret = kstrtoul(str, 0, &rhash_entries); + if (ret) + return 0; + return 1; } __setup("rhash_entries=", set_rhash_entries);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 5654062..bb485fc 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c
@@ -593,7 +593,7 @@ tp->pushed_seq = tp->write_seq; } -static inline int forced_push(const struct tcp_sock *tp) +static inline bool forced_push(const struct tcp_sock *tp) { return after(tp->write_seq, tp->pushed_seq + (tp->max_window >> 1)); } @@ -917,8 +917,7 @@ wait_for_sndbuf: set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); wait_for_memory: - if (copied) - tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); + tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) goto do_error; @@ -978,39 +977,6 @@ return tmp; } -static int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) -{ - struct sk_buff *skb; - struct tcphdr *th; - bool fragstolen; - - skb = alloc_skb(size + sizeof(*th), sk->sk_allocation); - if (!skb) - goto err; - - th = (struct tcphdr *)skb_put(skb, sizeof(*th)); - skb_reset_transport_header(skb); - memset(th, 0, sizeof(*th)); - - if (memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size)) - goto err_free; - - TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt; - TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + size; - TCP_SKB_CB(skb)->ack_seq = tcp_sk(sk)->snd_una - 1; - - if (tcp_queue_rcv(sk, skb, sizeof(*th), &fragstolen)) { - WARN_ON_ONCE(fragstolen); /* should not happen */ - __kfree_skb(skb); - } - return size; - -err_free: - kfree_skb(skb); -err: - return -ENOMEM; -} - int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t size) { @@ -1115,7 +1081,7 @@ if (err) goto do_fault; } else { - int merge = 0; + bool merge = false; int i = skb_shinfo(skb)->nr_frags; struct page *page = sk->sk_sndmsg_page; int off; @@ -1129,7 +1095,7 @@ off != PAGE_SIZE) { /* We can extend the last page * fragment. */ - merge = 1; + merge = true; } else if (i == MAX_SKB_FRAGS || !sg) { /* Need to add new fragment and cannot * do this because interface is non-SG, @@ -1326,7 +1292,7 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied) { struct tcp_sock *tp = tcp_sk(sk); - int time_to_ack = 0; + bool time_to_ack = false; struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); @@ -1352,7 +1318,7 @@ ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED) && !icsk->icsk_ack.pingpong)) && !atomic_read(&sk->sk_rmem_alloc))) - time_to_ack = 1; + time_to_ack = true; } /* We send an ACK if we can now advertise a non-zero window @@ -1374,7 +1340,7 @@ * "Lots" means "at least twice" here. */ if (new_window && new_window >= 2 * rcv_window_now) - time_to_ack = 1; + time_to_ack = true; } } if (time_to_ack) @@ -1506,11 +1472,11 @@ break; } if (tcp_hdr(skb)->fin) { - sk_eat_skb(sk, skb, 0); + sk_eat_skb(sk, skb, false); ++seq; break; } - sk_eat_skb(sk, skb, 0); + sk_eat_skb(sk, skb, false); if (!desc->count) break; tp->copied_seq = seq; @@ -1546,7 +1512,7 @@ int target; /* Read at least this many bytes */ long timeo; struct task_struct *user_recv = NULL; - int copied_early = 0; + bool copied_early = false; struct sk_buff *skb; u32 urg_hole = 0; @@ -1778,9 +1744,9 @@ } if ((flags & MSG_PEEK) && (peek_seq - copied - urg_hole != tp->copied_seq)) { - if (net_ratelimit()) - printk(KERN_DEBUG "TCP(%s:%d): Application bug, race in MSG_PEEK.\n", - current->comm, task_pid_nr(current)); + net_dbg_ratelimited("TCP(%s:%d): Application bug, race in MSG_PEEK\n", + current->comm, + task_pid_nr(current)); peek_seq = tp->copied_seq; } continue; @@ -1834,7 +1800,7 @@ dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); if ((offset + used) == skb->len) - copied_early = 1; + copied_early = true; } else #endif @@ -1868,7 +1834,7 @@ goto found_fin_ok; if (!(flags & MSG_PEEK)) { sk_eat_skb(sk, skb, copied_early); - copied_early = 0; + copied_early = false; } continue; @@ -1877,7 +1843,7 @@ ++*seq; if (!(flags & MSG_PEEK)) { sk_eat_skb(sk, skb, copied_early); - copied_early = 0; + copied_early = false; } break; } while (len > 0); @@ -2035,10 +2001,10 @@ too_many_orphans = tcp_too_many_orphans(sk, shift); out_of_socket_memory = tcp_out_of_memory(sk); - if (too_many_orphans && net_ratelimit()) - pr_info("too many orphaned sockets\n"); - if (out_of_socket_memory && net_ratelimit()) - pr_info("out of memory -- consider tuning tcp_mem\n"); + if (too_many_orphans) + net_info_ratelimited("too many orphaned sockets\n"); + if (out_of_socket_memory) + net_info_ratelimited("out of memory -- consider tuning tcp_mem\n"); return too_many_orphans || out_of_socket_memory; } @@ -2204,7 +2170,7 @@ /* These states need RST on ABORT according to RFC793 */ -static inline int tcp_need_reset(int state) +static inline bool tcp_need_reset(int state) { return (1 << state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_FIN_WAIT1 | @@ -2278,7 +2244,7 @@ } EXPORT_SYMBOL(tcp_disconnect); -static inline int tcp_can_repair_sock(struct sock *sk) +static inline bool tcp_can_repair_sock(const struct sock *sk) { return capable(CAP_NET_ADMIN) && ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_ESTABLISHED)); @@ -3205,13 +3171,13 @@ struct tcp_md5sig_pool __percpu *tcp_alloc_md5sig_pool(struct sock *sk) { struct tcp_md5sig_pool __percpu *pool; - int alloc = 0; + bool alloc = false; retry: spin_lock_bh(&tcp_md5sig_pool_lock); pool = tcp_md5sig_pool; if (tcp_md5sig_users++ == 0) { - alloc = 1; + alloc = true; spin_unlock_bh(&tcp_md5sig_pool_lock); } else if (!pool) { tcp_md5sig_users--; @@ -3495,9 +3461,15 @@ static __initdata unsigned long thash_entries; static int __init set_thash_entries(char *str) { + ssize_t ret; + if (!str) return 0; - thash_entries = simple_strtoul(str, &str, 0); + + ret = kstrtoul(str, 0, &thash_entries); + if (ret) + return 0; + return 1; } __setup("thash_entries=", set_thash_entries);
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 272a845..04dbd7a 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c
@@ -280,19 +280,19 @@ /* RFC2861 Check whether we are limited by application or congestion window * This is the inverse of cwnd check in tcp_tso_should_defer */ -int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight) +bool tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight) { const struct tcp_sock *tp = tcp_sk(sk); u32 left; if (in_flight >= tp->snd_cwnd) - return 1; + return true; left = tp->snd_cwnd - in_flight; if (sk_can_gso(sk) && left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd && left * tp->mss_cache < sk->sk_gso_max_size) - return 1; + return true; return left <= tcp_max_tso_deferred_mss(tp); } EXPORT_SYMBOL_GPL(tcp_is_cwnd_limited);
diff --git a/net/ipv4/tcp_hybla.c b/net/ipv4/tcp_hybla.c index fe3ecf4..57bdd17 100644 --- a/net/ipv4/tcp_hybla.c +++ b/net/ipv4/tcp_hybla.c
@@ -15,7 +15,7 @@ /* Tcp Hybla structure. */ struct hybla { - u8 hybla_en; + bool hybla_en; u32 snd_cwnd_cents; /* Keeps increment values when it is <1, <<7 */ u32 rho; /* Rho parameter, integer part */ u32 rho2; /* Rho * Rho, integer part */ @@ -24,8 +24,7 @@ u32 minrtt; /* Minimum smoothed round trip time value seen */ }; -/* Hybla reference round trip time (default= 1/40 sec = 25 ms), - expressed in jiffies */ +/* Hybla reference round trip time (default= 1/40 sec = 25 ms), in ms */ static int rtt0 = 25; module_param(rtt0, int, 0644); MODULE_PARM_DESC(rtt0, "reference rout trip time (ms)"); @@ -39,7 +38,7 @@ ca->rho_3ls = max_t(u32, tcp_sk(sk)->srtt / msecs_to_jiffies(rtt0), 8); ca->rho = ca->rho_3ls >> 3; ca->rho2_7ls = (ca->rho_3ls * ca->rho_3ls) << 1; - ca->rho2 = ca->rho2_7ls >>7; + ca->rho2 = ca->rho2_7ls >> 7; } static void hybla_init(struct sock *sk) @@ -52,7 +51,7 @@ ca->rho_3ls = 0; ca->rho2_7ls = 0; ca->snd_cwnd_cents = 0; - ca->hybla_en = 1; + ca->hybla_en = true; tp->snd_cwnd = 2; tp->snd_cwnd_clamp = 65535; @@ -67,6 +66,7 @@ static void hybla_state(struct sock *sk, u8 ca_state) { struct hybla *ca = inet_csk_ca(sk); + ca->hybla_en = (ca_state == TCP_CA_Open); }
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index eb58b94..cfa2aa1 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c
@@ -196,9 +196,10 @@ * and the session is not interactive. */ -static inline int tcp_in_quickack_mode(const struct sock *sk) +static inline bool tcp_in_quickack_mode(const struct sock *sk) { const struct inet_connection_sock *icsk = inet_csk(sk); + return icsk->icsk_ack.quick && !icsk->icsk_ack.pingpong; } @@ -253,11 +254,11 @@ tp->ecn_flags &= ~TCP_ECN_OK; } -static inline int TCP_ECN_rcv_ecn_echo(const struct tcp_sock *tp, const struct tcphdr *th) +static bool TCP_ECN_rcv_ecn_echo(const struct tcp_sock *tp, const struct tcphdr *th) { if (th->ece && !th->syn && (tp->ecn_flags & TCP_ECN_OK)) - return 1; - return 0; + return true; + return false; } /* Buffer size and advertised window tuning. @@ -981,12 +982,12 @@ NET_INC_STATS_BH(sock_net(sk), mib_idx); #if FASTRETRANS_DEBUG > 1 - printk(KERN_DEBUG "Disorder%d %d %u f%u s%u rr%d\n", - tp->rx_opt.sack_ok, inet_csk(sk)->icsk_ca_state, - tp->reordering, - tp->fackets_out, - tp->sacked_out, - tp->undo_marker ? tp->undo_retrans : 0); + pr_debug("Disorder%d %d %u f%u s%u rr%d\n", + tp->rx_opt.sack_ok, inet_csk(sk)->icsk_ca_state, + tp->reordering, + tp->fackets_out, + tp->sacked_out, + tp->undo_marker ? tp->undo_retrans : 0); #endif tcp_disable_fack(tp); } @@ -1123,36 +1124,36 @@ * the exact amount is rather hard to quantify. However, tp->max_window can * be used as an exaggerated estimate. */ -static int tcp_is_sackblock_valid(struct tcp_sock *tp, int is_dsack, - u32 start_seq, u32 end_seq) +static bool tcp_is_sackblock_valid(struct tcp_sock *tp, bool is_dsack, + u32 start_seq, u32 end_seq) { /* Too far in future, or reversed (interpretation is ambiguous) */ if (after(end_seq, tp->snd_nxt) || !before(start_seq, end_seq)) - return 0; + return false; /* Nasty start_seq wrap-around check (see comments above) */ if (!before(start_seq, tp->snd_nxt)) - return 0; + return false; /* In outstanding window? ...This is valid exit for D-SACKs too. * start_seq == snd_una is non-sensical (see comments above) */ if (after(start_seq, tp->snd_una)) - return 1; + return true; if (!is_dsack || !tp->undo_marker) - return 0; + return false; /* ...Then it's D-SACK, and must reside below snd_una completely */ if (after(end_seq, tp->snd_una)) - return 0; + return false; if (!before(start_seq, tp->undo_marker)) - return 1; + return true; /* Too old */ if (!after(end_seq, tp->undo_marker)) - return 0; + return false; /* Undo_marker boundary crossing (overestimates a lot). Known already: * start_seq < undo_marker and end_seq >= undo_marker. @@ -1224,17 +1225,17 @@ tp->lost_retrans_low = new_low_seq; } -static int tcp_check_dsack(struct sock *sk, const struct sk_buff *ack_skb, - struct tcp_sack_block_wire *sp, int num_sacks, - u32 prior_snd_una) +static bool tcp_check_dsack(struct sock *sk, const struct sk_buff *ack_skb, + struct tcp_sack_block_wire *sp, int num_sacks, + u32 prior_snd_una) { struct tcp_sock *tp = tcp_sk(sk); u32 start_seq_0 = get_unaligned_be32(&sp[0].start_seq); u32 end_seq_0 = get_unaligned_be32(&sp[0].end_seq); - int dup_sack = 0; + bool dup_sack = false; if (before(start_seq_0, TCP_SKB_CB(ack_skb)->ack_seq)) { - dup_sack = 1; + dup_sack = true; tcp_dsack_seen(tp); NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPDSACKRECV); } else if (num_sacks > 1) { @@ -1243,7 +1244,7 @@ if (!after(end_seq_0, end_seq_1) && !before(start_seq_0, start_seq_1)) { - dup_sack = 1; + dup_sack = true; tcp_dsack_seen(tp); NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPDSACKOFORECV); @@ -1274,9 +1275,10 @@ * FIXME: this could be merged to shift decision code */ static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb, - u32 start_seq, u32 end_seq) + u32 start_seq, u32 end_seq) { - int in_sack, err; + int err; + bool in_sack; unsigned int pkt_len; unsigned int mss; @@ -1322,7 +1324,7 @@ static u8 tcp_sacktag_one(struct sock *sk, struct tcp_sacktag_state *state, u8 sacked, u32 start_seq, u32 end_seq, - int dup_sack, int pcount) + bool dup_sack, int pcount) { struct tcp_sock *tp = tcp_sk(sk); int fack_count = state->fack_count; @@ -1402,10 +1404,10 @@ /* Shift newly-SACKed bytes from this skb to the immediately previous * already-SACKed sk_buff. Mark the newly-SACKed bytes as such. */ -static int tcp_shifted_skb(struct sock *sk, struct sk_buff *skb, - struct tcp_sacktag_state *state, - unsigned int pcount, int shifted, int mss, - int dup_sack) +static bool tcp_shifted_skb(struct sock *sk, struct sk_buff *skb, + struct tcp_sacktag_state *state, + unsigned int pcount, int shifted, int mss, + bool dup_sack) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *prev = tcp_write_queue_prev(sk, skb); @@ -1455,7 +1457,7 @@ if (skb->len > 0) { BUG_ON(!tcp_skb_pcount(skb)); NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SACKSHIFTED); - return 0; + return false; } /* Whole SKB was eaten :-) */ @@ -1478,7 +1480,7 @@ NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SACKMERGED); - return 1; + return true; } /* I wish gso_size would have a bit more sane initialization than @@ -1501,7 +1503,7 @@ static struct sk_buff *tcp_shift_skb_data(struct sock *sk, struct sk_buff *skb, struct tcp_sacktag_state *state, u32 start_seq, u32 end_seq, - int dup_sack) + bool dup_sack) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *prev; @@ -1640,14 +1642,14 @@ struct tcp_sack_block *next_dup, struct tcp_sacktag_state *state, u32 start_seq, u32 end_seq, - int dup_sack_in) + bool dup_sack_in) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *tmp; tcp_for_write_queue_from(skb, sk) { int in_sack = 0; - int dup_sack = dup_sack_in; + bool dup_sack = dup_sack_in; if (skb == tcp_send_head(sk)) break; @@ -1662,7 +1664,7 @@ next_dup->start_seq, next_dup->end_seq); if (in_sack > 0) - dup_sack = 1; + dup_sack = true; } /* skb reference here is a bit tricky to get right, since @@ -1767,7 +1769,7 @@ struct sk_buff *skb; int num_sacks = min(TCP_NUM_SACKS, (ptr[1] - TCPOLEN_SACK_BASE) >> 3); int used_sacks; - int found_dup_sack = 0; + bool found_dup_sack = false; int i, j; int first_sack_index; @@ -1798,7 +1800,7 @@ used_sacks = 0; first_sack_index = 0; for (i = 0; i < num_sacks; i++) { - int dup_sack = !i && found_dup_sack; + bool dup_sack = !i && found_dup_sack; sp[used_sacks].start_seq = get_unaligned_be32(&sp_wire[i].start_seq); sp[used_sacks].end_seq = get_unaligned_be32(&sp_wire[i].end_seq); @@ -1865,7 +1867,7 @@ while (i < used_sacks) { u32 start_seq = sp[i].start_seq; u32 end_seq = sp[i].end_seq; - int dup_sack = (found_dup_sack && (i == first_sack_index)); + bool dup_sack = (found_dup_sack && (i == first_sack_index)); struct tcp_sack_block *next_dup = NULL; if (found_dup_sack && ((i + 1) == first_sack_index)) @@ -1967,9 +1969,9 @@ } /* Limits sacked_out so that sum with lost_out isn't ever larger than - * packets_out. Returns zero if sacked_out adjustement wasn't necessary. + * packets_out. Returns false if sacked_out adjustement wasn't necessary. */ -static int tcp_limit_reno_sacked(struct tcp_sock *tp) +static bool tcp_limit_reno_sacked(struct tcp_sock *tp) { u32 holes; @@ -1978,9 +1980,9 @@ if ((tp->sacked_out + holes) > tp->packets_out) { tp->sacked_out = tp->packets_out - holes; - return 1; + return true; } - return 0; + return false; } /* If we receive more dupacks than we expected counting segments @@ -2034,40 +2036,40 @@ /* F-RTO can only be used if TCP has never retransmitted anything other than * head (SACK enhanced variant from Appendix B of RFC4138 is more robust here) */ -int tcp_use_frto(struct sock *sk) +bool tcp_use_frto(struct sock *sk) { const struct tcp_sock *tp = tcp_sk(sk); const struct inet_connection_sock *icsk = inet_csk(sk); struct sk_buff *skb; if (!sysctl_tcp_frto) - return 0; + return false; /* MTU probe and F-RTO won't really play nicely along currently */ if (icsk->icsk_mtup.probe_size) - return 0; + return false; if (tcp_is_sackfrto(tp)) - return 1; + return true; /* Avoid expensive walking of rexmit queue if possible */ if (tp->retrans_out > 1) - return 0; + return false; skb = tcp_write_queue_head(sk); if (tcp_skb_is_last(sk, skb)) - return 1; + return true; skb = tcp_write_queue_next(sk, skb); /* Skips head */ tcp_for_write_queue_from(skb, sk) { if (skb == tcp_send_head(sk)) break; if (TCP_SKB_CB(skb)->sacked & TCPCB_RETRANS) - return 0; + return false; /* Short-circuit when first non-SACKed skb has been checked */ if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) break; } - return 1; + return true; } /* RTO occurred, but do not yet enter Loss state. Instead, defer RTO @@ -2303,7 +2305,7 @@ * * Do processing similar to RTO timeout. */ -static int tcp_check_sack_reneging(struct sock *sk, int flag) +static bool tcp_check_sack_reneging(struct sock *sk, int flag) { if (flag & FLAG_SACK_RENEGING) { struct inet_connection_sock *icsk = inet_csk(sk); @@ -2314,9 +2316,9 @@ tcp_retransmit_skb(sk, tcp_write_queue_head(sk)); inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); - return 1; + return true; } - return 0; + return false; } static inline int tcp_fackets_out(const struct tcp_sock *tp) @@ -2472,28 +2474,28 @@ * Main question: may we further continue forward transmission * with the same cwnd? */ -static int tcp_time_to_recover(struct sock *sk, int flag) +static bool tcp_time_to_recover(struct sock *sk, int flag) { struct tcp_sock *tp = tcp_sk(sk); __u32 packets_out; /* Do not perform any recovery during F-RTO algorithm */ if (tp->frto_counter) - return 0; + return false; /* Trick#1: The loss is proven. */ if (tp->lost_out) - return 1; + return true; /* Not-A-Trick#2 : Classic rule... */ if (tcp_dupack_heuristics(tp) > tp->reordering) - return 1; + return true; /* Trick#3 : when we use RFC2988 timer restart, fast * retransmit can be triggered by timeout of queue head. */ if (tcp_is_fack(tp) && tcp_head_timedout(sk)) - return 1; + return true; /* Trick#4: It is still not OK... But will it be useful to delay * recovery more? @@ -2505,7 +2507,7 @@ /* We have nothing to send. This connection is limited * either by receiver window or by application. */ - return 1; + return true; } /* If a thin stream is detected, retransmit after first @@ -2516,7 +2518,7 @@ if ((tp->thin_dupack || sysctl_tcp_thin_dupack) && tcp_stream_is_thin(tp) && tcp_dupack_heuristics(tp) > 1 && tcp_is_sack(tp) && !tcp_send_head(sk)) - return 1; + return true; /* Trick#6: TCP early retransmit, per RFC5827. To avoid spurious * retransmissions due to small network reorderings, we implement @@ -2528,7 +2530,7 @@ !tcp_may_send_now(sk)) return !tcp_pause_early_retransmit(sk, flag); - return 0; + return false; } /* New heuristics: it is possible only after we switched to restart timer @@ -2716,22 +2718,22 @@ struct inet_sock *inet = inet_sk(sk); if (sk->sk_family == AF_INET) { - printk(KERN_DEBUG "Undo %s %pI4/%u c%u l%u ss%u/%u p%u\n", - msg, - &inet->inet_daddr, ntohs(inet->inet_dport), - tp->snd_cwnd, tcp_left_out(tp), - tp->snd_ssthresh, tp->prior_ssthresh, - tp->packets_out); + pr_debug("Undo %s %pI4/%u c%u l%u ss%u/%u p%u\n", + msg, + &inet->inet_daddr, ntohs(inet->inet_dport), + tp->snd_cwnd, tcp_left_out(tp), + tp->snd_ssthresh, tp->prior_ssthresh, + tp->packets_out); } #if IS_ENABLED(CONFIG_IPV6) else if (sk->sk_family == AF_INET6) { struct ipv6_pinfo *np = inet6_sk(sk); - printk(KERN_DEBUG "Undo %s %pI6/%u c%u l%u ss%u/%u p%u\n", - msg, - &np->daddr, ntohs(inet->inet_dport), - tp->snd_cwnd, tcp_left_out(tp), - tp->snd_ssthresh, tp->prior_ssthresh, - tp->packets_out); + pr_debug("Undo %s %pI6/%u c%u l%u ss%u/%u p%u\n", + msg, + &np->daddr, ntohs(inet->inet_dport), + tp->snd_cwnd, tcp_left_out(tp), + tp->snd_ssthresh, tp->prior_ssthresh, + tp->packets_out); } #endif } @@ -2767,7 +2769,7 @@ } /* People celebrate: "We love our President!" */ -static int tcp_try_undo_recovery(struct sock *sk) +static bool tcp_try_undo_recovery(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); @@ -2792,10 +2794,10 @@ * is ACKed. For Reno it is MUST to prevent false * fast retransmits (RFC2582). SACK TCP is safe. */ tcp_moderate_cwnd(tp); - return 1; + return true; } tcp_set_ca_state(sk, TCP_CA_Open); - return 0; + return false; } /* Try to undo cwnd reduction, because D-SACKs acked all retransmitted data */ @@ -2825,19 +2827,19 @@ * that successive retransmissions of a segment must not advance * retrans_stamp under any conditions. */ -static int tcp_any_retrans_done(const struct sock *sk) +static bool tcp_any_retrans_done(const struct sock *sk) { const struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; if (tp->retrans_out) - return 1; + return true; skb = tcp_write_queue_head(sk); if (unlikely(skb && TCP_SKB_CB(skb)->sacked & TCPCB_EVER_RETRANS)) - return 1; + return true; - return 0; + return false; } /* Undo during fast recovery after partial ACK. */ @@ -2871,7 +2873,7 @@ } /* Undo during loss recovery after partial ACK. */ -static int tcp_try_undo_loss(struct sock *sk) +static bool tcp_try_undo_loss(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); @@ -2893,9 +2895,9 @@ tp->undo_marker = 0; if (tcp_is_sack(tp)) tcp_set_ca_state(sk, TCP_CA_Open); - return 1; + return true; } - return 0; + return false; } static inline void tcp_complete_cwr(struct sock *sk) @@ -3370,7 +3372,7 @@ const struct inet_connection_sock *icsk = inet_csk(sk); struct sk_buff *skb; u32 now = tcp_time_stamp; - int fully_acked = 1; + int fully_acked = true; int flag = 0; u32 pkts_acked = 0; u32 reord = tp->packets_out; @@ -3394,7 +3396,7 @@ if (!acked_pcount) break; - fully_acked = 0; + fully_acked = false; } else { acked_pcount = tcp_skb_pcount(skb); } @@ -3511,18 +3513,18 @@ if (!tp->packets_out && tcp_is_sack(tp)) { icsk = inet_csk(sk); if (tp->lost_out) { - printk(KERN_DEBUG "Leak l=%u %d\n", - tp->lost_out, icsk->icsk_ca_state); + pr_debug("Leak l=%u %d\n", + tp->lost_out, icsk->icsk_ca_state); tp->lost_out = 0; } if (tp->sacked_out) { - printk(KERN_DEBUG "Leak s=%u %d\n", - tp->sacked_out, icsk->icsk_ca_state); + pr_debug("Leak s=%u %d\n", + tp->sacked_out, icsk->icsk_ca_state); tp->sacked_out = 0; } if (tp->retrans_out) { - printk(KERN_DEBUG "Leak r=%u %d\n", - tp->retrans_out, icsk->icsk_ca_state); + pr_debug("Leak r=%u %d\n", + tp->retrans_out, icsk->icsk_ca_state); tp->retrans_out = 0; } } @@ -3673,7 +3675,7 @@ * to prove that the RTO is indeed spurious. It transfers the control * from F-RTO to the conventional RTO recovery */ -static int tcp_process_frto(struct sock *sk, int flag) +static bool tcp_process_frto(struct sock *sk, int flag) { struct tcp_sock *tp = tcp_sk(sk); @@ -3689,7 +3691,7 @@ if (!before(tp->snd_una, tp->frto_highmark)) { tcp_enter_frto_loss(sk, (tp->frto_counter == 1 ? 2 : 3), flag); - return 1; + return true; } if (!tcp_is_sackfrto(tp)) { @@ -3698,19 +3700,19 @@ * data, winupdate */ if (!(flag & FLAG_ANY_PROGRESS) && (flag & FLAG_NOT_DUP)) - return 1; + return true; if (!(flag & FLAG_DATA_ACKED)) { tcp_enter_frto_loss(sk, (tp->frto_counter == 1 ? 0 : 3), flag); - return 1; + return true; } } else { if (!(flag & FLAG_DATA_ACKED) && (tp->frto_counter == 1)) { /* Prevent sending of new data. */ tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)); - return 1; + return true; } if ((tp->frto_counter >= 2) && @@ -3720,10 +3722,10 @@ /* RFC4138 shortcoming (see comment above) */ if (!(flag & FLAG_FORWARD_PROGRESS) && (flag & FLAG_NOT_DUP)) - return 1; + return true; tcp_enter_frto_loss(sk, 3, flag); - return 1; + return true; } } @@ -3735,7 +3737,7 @@ if (!tcp_may_send_now(sk)) tcp_enter_frto_loss(sk, 2, flag); - return 1; + return true; } else { switch (sysctl_tcp_frto_response) { case 2: @@ -3752,7 +3754,7 @@ tp->undo_marker = 0; NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSPURIOUSRTOS); } - return 0; + return false; } /* This routine deals with incoming acks, but not outgoing ones. */ @@ -3770,7 +3772,7 @@ int prior_sacked = tp->sacked_out; int pkts_acked = 0; int newly_acked_sacked = 0; - int frto_cwnd = 0; + bool frto_cwnd = false; /* If the ack is older than previous acks * then we can probably ignore it. @@ -3952,10 +3954,9 @@ __u8 snd_wscale = *(__u8 *)ptr; opt_rx->wscale_ok = 1; if (snd_wscale > 14) { - if (net_ratelimit()) - pr_info("%s: Illegal window scaling value %d >14 received\n", - __func__, - snd_wscale); + net_info_ratelimited("%s: Illegal window scaling value %d >14 received\n", + __func__, + snd_wscale); snd_wscale = 14; } opt_rx->snd_wscale = snd_wscale; @@ -4026,7 +4027,7 @@ } EXPORT_SYMBOL(tcp_parse_options); -static int tcp_parse_aligned_timestamp(struct tcp_sock *tp, const struct tcphdr *th) +static bool tcp_parse_aligned_timestamp(struct tcp_sock *tp, const struct tcphdr *th) { const __be32 *ptr = (const __be32 *)(th + 1); @@ -4037,31 +4038,31 @@ tp->rx_opt.rcv_tsval = ntohl(*ptr); ++ptr; tp->rx_opt.rcv_tsecr = ntohl(*ptr); - return 1; + return true; } - return 0; + return false; } /* Fast parse options. This hopes to only see timestamps. * If it is wrong it falls back on tcp_parse_options(). */ -static int tcp_fast_parse_options(const struct sk_buff *skb, - const struct tcphdr *th, - struct tcp_sock *tp, const u8 **hvpp) +static bool tcp_fast_parse_options(const struct sk_buff *skb, + const struct tcphdr *th, + struct tcp_sock *tp, const u8 **hvpp) { /* In the spirit of fast parsing, compare doff directly to constant * values. Because equality is used, short doff can be ignored here. */ if (th->doff == (sizeof(*th) / 4)) { tp->rx_opt.saw_tstamp = 0; - return 0; + return false; } else if (tp->rx_opt.tstamp_ok && th->doff == ((sizeof(*th) + TCPOLEN_TSTAMP_ALIGNED) / 4)) { if (tcp_parse_aligned_timestamp(tp, th)) - return 1; + return true; } tcp_parse_options(skb, &tp->rx_opt, hvpp, 1); - return 1; + return true; } #ifdef CONFIG_TCP_MD5SIG @@ -4302,7 +4303,7 @@ } } -static inline int tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, +static inline bool tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, u32 end_seq) { if (!after(seq, sp->end_seq) && !after(sp->start_seq, end_seq)) { @@ -4310,9 +4311,9 @@ sp->start_seq = seq; if (after(end_seq, sp->end_seq)) sp->end_seq = end_seq; - return 1; + return true; } - return 0; + return false; } static void tcp_dsack_set(struct sock *sk, u32 seq, u32 end_seq) @@ -4508,10 +4509,10 @@ } } -static int tcp_prune_ofo_queue(struct sock *sk); +static bool tcp_prune_ofo_queue(struct sock *sk); static int tcp_prune_queue(struct sock *sk); -static inline int tcp_try_rmem_schedule(struct sock *sk, unsigned int size) +static int tcp_try_rmem_schedule(struct sock *sk, unsigned int size) { if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || !sk_rmem_schedule(sk, size)) { @@ -4548,84 +4549,23 @@ struct sk_buff *from, bool *fragstolen) { - int i, delta, len = from->len; + int delta; *fragstolen = false; - if (tcp_hdr(from)->fin || skb_cloned(to)) + if (tcp_hdr(from)->fin) + return false; + if (!skb_try_coalesce(to, from, fragstolen, &delta)) return false; - if (len <= skb_tailroom(to)) { - BUG_ON(skb_copy_bits(from, 0, skb_put(to, len), len)); - goto merge; - } - - if (skb_has_frag_list(to) || skb_has_frag_list(from)) - return false; - - if (skb_headlen(from) != 0) { - struct page *page; - unsigned int offset; - - if (skb_shinfo(to)->nr_frags + - skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS) - return false; - - if (skb_head_is_locked(from)) - return false; - - delta = from->truesize - SKB_DATA_ALIGN(sizeof(struct sk_buff)); - - page = virt_to_head_page(from->head); - offset = from->data - (unsigned char *)page_address(page); - - skb_fill_page_desc(to, skb_shinfo(to)->nr_frags, - page, offset, skb_headlen(from)); - *fragstolen = true; - } else { - if (skb_shinfo(to)->nr_frags + - skb_shinfo(from)->nr_frags > MAX_SKB_FRAGS) - return false; - - delta = from->truesize - - SKB_TRUESIZE(skb_end_pointer(from) - from->head); - } - - WARN_ON_ONCE(delta < len); - - memcpy(skb_shinfo(to)->frags + skb_shinfo(to)->nr_frags, - skb_shinfo(from)->frags, - skb_shinfo(from)->nr_frags * sizeof(skb_frag_t)); - skb_shinfo(to)->nr_frags += skb_shinfo(from)->nr_frags; - - if (!skb_cloned(from)) - skb_shinfo(from)->nr_frags = 0; - - /* if the skb is cloned this does nothing since we set nr_frags to 0 */ - for (i = 0; i < skb_shinfo(from)->nr_frags; i++) - skb_frag_ref(from, i); - - to->truesize += delta; atomic_add(delta, &sk->sk_rmem_alloc); sk_mem_charge(sk, delta); - to->len += len; - to->data_len += len; - -merge: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRCVCOALESCE); TCP_SKB_CB(to)->end_seq = TCP_SKB_CB(from)->end_seq; TCP_SKB_CB(to)->ack_seq = TCP_SKB_CB(from)->ack_seq; return true; } -static void kfree_skb_partial(struct sk_buff *skb, bool head_stolen) -{ - if (head_stolen) - kmem_cache_free(skbuff_head_cache, skb); - else - __kfree_skb(skb); -} - static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); @@ -4746,7 +4686,7 @@ skb_set_owner_r(skb, sk); } -int tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen, +static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen, bool *fragstolen) { int eaten; @@ -4763,6 +4703,42 @@ return eaten; } +int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) +{ + struct sk_buff *skb; + struct tcphdr *th; + bool fragstolen; + + if (tcp_try_rmem_schedule(sk, size + sizeof(*th))) + goto err; + + skb = alloc_skb(size + sizeof(*th), sk->sk_allocation); + if (!skb) + goto err; + + th = (struct tcphdr *)skb_put(skb, sizeof(*th)); + skb_reset_transport_header(skb); + memset(th, 0, sizeof(*th)); + + if (memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size)) + goto err_free; + + TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt; + TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + size; + TCP_SKB_CB(skb)->ack_seq = tcp_sk(sk)->snd_una - 1; + + if (tcp_queue_rcv(sk, skb, sizeof(*th), &fragstolen)) { + WARN_ON_ONCE(fragstolen); /* should not happen */ + __kfree_skb(skb); + } + return size; + +err_free: + kfree_skb(skb); +err: + return -ENOMEM; +} + static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) { const struct tcphdr *th = tcp_hdr(skb); @@ -5057,10 +5033,10 @@ * Purge the out-of-order queue. * Return true if queue was pruned. */ -static int tcp_prune_ofo_queue(struct sock *sk) +static bool tcp_prune_ofo_queue(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); - int res = 0; + bool res = false; if (!skb_queue_empty(&tp->out_of_order_queue)) { NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_OFOPRUNED); @@ -5074,7 +5050,7 @@ if (tp->rx_opt.sack_ok) tcp_sack_reset(&tp->rx_opt); sk_mem_reclaim(sk); - res = 1; + res = true; } return res; } @@ -5151,7 +5127,7 @@ tp->snd_cwnd_stamp = tcp_time_stamp; } -static int tcp_should_expand_sndbuf(const struct sock *sk) +static bool tcp_should_expand_sndbuf(const struct sock *sk) { const struct tcp_sock *tp = tcp_sk(sk); @@ -5159,21 +5135,21 @@ * not modify it. */ if (sk->sk_userlocks & SOCK_SNDBUF_LOCK) - return 0; + return false; /* If we are under global TCP memory pressure, do not expand. */ if (sk_under_memory_pressure(sk)) - return 0; + return false; /* If we are under soft global TCP memory pressure, do not expand. */ if (sk_memory_allocated(sk) >= sk_prot_mem_limits(sk, 0)) - return 0; + return false; /* If we filled the congestion window, do not expand. */ if (tp->packets_out >= tp->snd_cwnd) - return 0; + return false; - return 1; + return true; } /* When incoming ACK allowed to free some skb from write_queue, @@ -5399,16 +5375,16 @@ } #ifdef CONFIG_NET_DMA -static int tcp_dma_try_early_copy(struct sock *sk, struct sk_buff *skb, +static bool tcp_dma_try_early_copy(struct sock *sk, struct sk_buff *skb, int hlen) { struct tcp_sock *tp = tcp_sk(sk); int chunk = skb->len - hlen; int dma_cookie; - int copied_early = 0; + bool copied_early = false; if (tp->ucopy.wakeup) - return 0; + return false; if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list) tp->ucopy.dma_chan = net_dma_find_channel(); @@ -5424,7 +5400,7 @@ goto out; tp->ucopy.dma_cookie = dma_cookie; - copied_early = 1; + copied_early = true; tp->ucopy.len -= chunk; tp->copied_seq += chunk;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 4ff5e1f..a43b87d 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c
@@ -866,14 +866,14 @@ } /* - * Return 1 if a syncookie should be sent + * Return true if a syncookie should be sent */ -int tcp_syn_flood_action(struct sock *sk, +bool tcp_syn_flood_action(struct sock *sk, const struct sk_buff *skb, const char *proto) { const char *msg = "Dropping request"; - int want_cookie = 0; + bool want_cookie = false; struct listen_sock *lopt; @@ -881,7 +881,7 @@ #ifdef CONFIG_SYN_COOKIES if (sysctl_tcp_syncookies) { msg = "Sending cookies"; - want_cookie = 1; + want_cookie = true; NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPREQQFULLDOCOOKIES); } else #endif @@ -1196,7 +1196,7 @@ } EXPORT_SYMBOL(tcp_v4_md5_hash_skb); -static int tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) +static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) { /* * This gets called for each TCP segment that arrives @@ -1219,16 +1219,16 @@ /* We've parsed the options - do we have a hash? */ if (!hash_expected && !hash_location) - return 0; + return false; if (hash_expected && !hash_location) { NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND); - return 1; + return true; } if (!hash_expected && hash_location) { NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED); - return 1; + return true; } /* Okay, so this is hash_expected and hash_location - @@ -1239,15 +1239,14 @@ NULL, NULL, skb); if (genhash || memcmp(hash_location, newhash, 16) != 0) { - if (net_ratelimit()) { - pr_info("MD5 Hash failed for (%pI4, %d)->(%pI4, %d)%s\n", - &iph->saddr, ntohs(th->source), - &iph->daddr, ntohs(th->dest), - genhash ? " tcp_v4_calc_md5_hash failed" : ""); - } - return 1; + net_info_ratelimited("MD5 Hash failed for (%pI4, %d)->(%pI4, %d)%s\n", + &iph->saddr, ntohs(th->source), + &iph->daddr, ntohs(th->dest), + genhash ? " tcp_v4_calc_md5_hash failed" + : ""); + return true; } - return 0; + return false; } #endif @@ -1281,7 +1280,7 @@ __be32 saddr = ip_hdr(skb)->saddr; __be32 daddr = ip_hdr(skb)->daddr; __u32 isn = TCP_SKB_CB(skb)->when; - int want_cookie = 0; + bool want_cookie = false; /* Never answer to SYNs send to broadcast or multicast */ if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) @@ -1340,7 +1339,7 @@ while (l-- > 0) *c++ ^= *hash_location++; - want_cookie = 0; /* not our kind of cookie */ + want_cookie = false; /* not our kind of cookie */ tmp_ext.cookie_out_never = 0; /* false */ tmp_ext.cookie_plus = tmp_opt.cookie_plus; } else if (!tp->rx_opt.cookie_in_always) { @@ -2074,7 +2073,7 @@ return rc; } -static inline int empty_bucket(struct tcp_iter_state *st) +static inline bool empty_bucket(struct tcp_iter_state *st) { return hlist_nulls_empty(&tcp_hashinfo.ehash[st->bucket].chain) && hlist_nulls_empty(&tcp_hashinfo.ehash[st->bucket].twchain);
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 6f6a918..b85d9fe 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c
@@ -55,7 +55,7 @@ * state. */ -static int tcp_remember_stamp(struct sock *sk) +static bool tcp_remember_stamp(struct sock *sk) { const struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); @@ -72,13 +72,13 @@ } if (release_it) inet_putpeer(peer); - return 1; + return true; } - return 0; + return false; } -static int tcp_tw_remember_stamp(struct inet_timewait_sock *tw) +static bool tcp_tw_remember_stamp(struct inet_timewait_sock *tw) { struct sock *sk = (struct sock *) tw; struct inet_peer *peer; @@ -94,17 +94,17 @@ peer->tcp_ts = tcptw->tw_ts_recent; } inet_putpeer(peer); - return 1; + return true; } - return 0; + return false; } -static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win) +static bool tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win) { if (seq == s_win) - return 1; + return true; if (after(end_seq, s_win) && before(seq, e_win)) - return 1; + return true; return seq == e_win && seq == end_seq; } @@ -143,7 +143,7 @@ struct tcp_options_received tmp_opt; const u8 *hash_location; struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); - int paws_reject = 0; + bool paws_reject = false; tmp_opt.saw_tstamp = 0; if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) { @@ -316,7 +316,7 @@ struct inet_timewait_sock *tw = NULL; const struct inet_connection_sock *icsk = inet_csk(sk); const struct tcp_sock *tp = tcp_sk(sk); - int recycle_ok = 0; + bool recycle_ok = false; if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp) recycle_ok = tcp_remember_stamp(sk); @@ -575,7 +575,7 @@ struct sock *child; const struct tcphdr *th = tcp_hdr(skb); __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); - int paws_reject = 0; + bool paws_reject = false; tmp_opt.saw_tstamp = 0; if (th->doff > (sizeof(struct tcphdr)>>2)) {
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index d947330..803cbfe 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c
@@ -34,6 +34,8 @@ * */ +#define pr_fmt(fmt) "TCP: " fmt + #include <net/tcp.h> #include <linux/compiler.h> @@ -368,7 +370,7 @@ TCP_SKB_CB(skb)->end_seq = seq; } -static inline int tcp_urg_mode(const struct tcp_sock *tp) +static inline bool tcp_urg_mode(const struct tcp_sock *tp) { return tp->snd_una != tp->snd_up; } @@ -1389,20 +1391,20 @@ } /* Minshall's variant of the Nagle send check. */ -static inline int tcp_minshall_check(const struct tcp_sock *tp) +static inline bool tcp_minshall_check(const struct tcp_sock *tp) { return after(tp->snd_sml, tp->snd_una) && !after(tp->snd_sml, tp->snd_nxt); } -/* Return 0, if packet can be sent now without violation Nagle's rules: +/* Return false, if packet can be sent now without violation Nagle's rules: * 1. It is full sized. * 2. Or it contains FIN. (already checked by caller) * 3. Or TCP_CORK is not set, and TCP_NODELAY is set. * 4. Or TCP_CORK is not set, and all sent packets are ACKed. * With Minshall's modification: all sent small packets are ACKed. */ -static inline int tcp_nagle_check(const struct tcp_sock *tp, +static inline bool tcp_nagle_check(const struct tcp_sock *tp, const struct sk_buff *skb, unsigned int mss_now, int nonagle) { @@ -1411,11 +1413,11 @@ (!nonagle && tp->packets_out && tcp_minshall_check(tp))); } -/* Return non-zero if the Nagle test allows this packet to be +/* Return true if the Nagle test allows this packet to be * sent now. */ -static inline int tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, - unsigned int cur_mss, int nonagle) +static inline bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, + unsigned int cur_mss, int nonagle) { /* Nagle rule does not apply to frames, which sit in the middle of the * write_queue (they have no chances to get new data). @@ -1424,24 +1426,25 @@ * argument based upon the location of SKB in the send queue. */ if (nonagle & TCP_NAGLE_PUSH) - return 1; + return true; /* Don't use the nagle rule for urgent data (or for the final FIN). * Nagle can be ignored during F-RTO too (see RFC4138). */ if (tcp_urg_mode(tp) || (tp->frto_counter == 2) || (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)) - return 1; + return true; if (!tcp_nagle_check(tp, skb, cur_mss, nonagle)) - return 1; + return true; - return 0; + return false; } /* Does at least the first segment of SKB fit into the send window? */ -static inline int tcp_snd_wnd_test(const struct tcp_sock *tp, const struct sk_buff *skb, - unsigned int cur_mss) +static bool tcp_snd_wnd_test(const struct tcp_sock *tp, + const struct sk_buff *skb, + unsigned int cur_mss) { u32 end_seq = TCP_SKB_CB(skb)->end_seq; @@ -1474,7 +1477,7 @@ } /* Test if sending is allowed right now. */ -int tcp_may_send_now(struct sock *sk) +bool tcp_may_send_now(struct sock *sk) { const struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb = tcp_send_head(sk); @@ -1544,7 +1547,7 @@ * * This algorithm is from John Heffner. */ -static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) +static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); const struct inet_connection_sock *icsk = inet_csk(sk); @@ -1604,11 +1607,11 @@ /* Ok, it looks like it is advisable to defer. */ tp->tso_deferred = 1 | (jiffies << 1); - return 1; + return true; send_now: tp->tso_deferred = 0; - return 0; + return false; } /* Create a new MTU probe if we are ready. @@ -1750,11 +1753,11 @@ * snd_up-64k-mss .. snd_up cannot be large. However, taking into * account rare use of URG, this is not a big flaw. * - * Returns 1, if no segments are in flight and we have queued segments, but - * cannot send anything now because of SWS or another problem. + * Returns true, if no segments are in flight and we have queued segments, + * but cannot send anything now because of SWS or another problem. */ -static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, - int push_one, gfp_t gfp) +static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, + int push_one, gfp_t gfp) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; @@ -1768,7 +1771,7 @@ /* Do MTU probing. */ result = tcp_mtu_probe(sk); if (!result) { - return 0; + return false; } else if (result > 0) { sent_pkts = 1; } @@ -1827,7 +1830,7 @@ if (likely(sent_pkts)) { tcp_cwnd_validate(sk); - return 0; + return false; } return !tp->packets_out && tcp_send_head(sk); } @@ -2026,22 +2029,22 @@ } /* Check if coalescing SKBs is legal. */ -static int tcp_can_collapse(const struct sock *sk, const struct sk_buff *skb) +static bool tcp_can_collapse(const struct sock *sk, const struct sk_buff *skb) { if (tcp_skb_pcount(skb) > 1) - return 0; + return false; /* TODO: SACK collapsing could be used to remove this condition */ if (skb_shinfo(skb)->nr_frags != 0) - return 0; + return false; if (skb_cloned(skb)) - return 0; + return false; if (skb == tcp_send_head(sk)) - return 0; + return false; /* Some heurestics for collapsing over SACK'd could be invented */ if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) - return 0; + return false; - return 1; + return true; } /* Collapse packets in the retransmit queue to make to create @@ -2052,7 +2055,7 @@ { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb = to, *tmp; - int first = 1; + bool first = true; if (!sysctl_tcp_retrans_collapse) return; @@ -2066,7 +2069,7 @@ space -= skb->len; if (first) { - first = 0; + first = false; continue; } @@ -2181,8 +2184,7 @@ #if FASTRETRANS_DEBUG > 0 if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) { - if (net_ratelimit()) - printk(KERN_DEBUG "retrans_out leaked.\n"); + net_dbg_ratelimited("retrans_out leaked\n"); } #endif if (!tp->retrans_out) @@ -2207,18 +2209,18 @@ /* Check if we forward retransmits are possible in the current * window/congestion state. */ -static int tcp_can_forward_retransmit(struct sock *sk) +static bool tcp_can_forward_retransmit(struct sock *sk) { const struct inet_connection_sock *icsk = inet_csk(sk); const struct tcp_sock *tp = tcp_sk(sk); /* Forward retransmissions are possible only during Recovery. */ if (icsk->icsk_ca_state != TCP_CA_Recovery) - return 0; + return false; /* No forward retransmissions in Reno are possible. */ if (tcp_is_reno(tp)) - return 0; + return false; /* Yeah, we have to make difficult choice between forward transmission * and retransmission... Both ways have their merits... @@ -2229,9 +2231,9 @@ */ if (tcp_may_send_now(sk)) - return 0; + return false; - return 1; + return true; } /* This gets called after a retransmit timeout, and the initially @@ -2416,7 +2418,7 @@ skb = tcp_write_queue_head(sk); if (skb == NULL || !(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN)) { - printk(KERN_DEBUG "tcp_send_synack: wrong queue state\n"); + pr_debug("%s: wrong queue state\n", __func__); return -EFAULT; } if (!(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_ACK)) {
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 279fd08..609397e 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c
@@ -2173,9 +2173,15 @@ static __initdata unsigned long uhash_entries; static int __init set_uhash_entries(char *str) { + ssize_t ret; + if (!str) return 0; - uhash_entries = simple_strtoul(str, &str, 0); + + ret = kstrtoul(str, 0, &uhash_entries); + if (ret) + return 0; + if (uhash_entries && uhash_entries < UDP_HTABLE_SIZE_MIN) uhash_entries = UDP_HTABLE_SIZE_MIN; return 1;
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index 36d7437..5728695 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig
@@ -69,7 +69,7 @@ config INET6_AH tristate "IPv6: AH transformation" - select XFRM + select XFRM_ALGO select CRYPTO select CRYPTO_HMAC select CRYPTO_MD5 @@ -81,7 +81,7 @@ config INET6_ESP tristate "IPv6: ESP transformation" - select XFRM + select XFRM_ALGO select CRYPTO select CRYPTO_AUTHENC select CRYPTO_HMAC
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e3b3421..8f6411c 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c
@@ -38,6 +38,8 @@ * status etc. */ +#define pr_fmt(fmt) "IPv6: " fmt + #include <linux/errno.h> #include <linux/types.h> #include <linux/kernel.h> @@ -66,6 +68,7 @@ #include <net/sock.h> #include <net/snmp.h> +#include <net/af_ieee802154.h> #include <net/ipv6.h> #include <net/protocol.h> #include <net/ndisc.h> @@ -326,11 +329,11 @@ WARN_ON(idev->mc_list != NULL); #ifdef NET_REFCNT_DEBUG - printk(KERN_DEBUG "in6_dev_finish_destroy: %s\n", dev ? dev->name : "NIL"); + pr_debug("%s: %s\n", __func__, dev ? dev->name : "NIL"); #endif dev_put(dev); if (!idev->dead) { - pr_warning("Freeing alive inet6 device %p\n", idev); + pr_warn("Freeing alive inet6 device %p\n", idev); return; } snmp6_free_dev(idev); @@ -371,7 +374,7 @@ if (snmp6_alloc_dev(ndev) < 0) { ADBG((KERN_WARNING - "%s(): cannot allocate memory for statistics; dev=%s.\n", + "%s: cannot allocate memory for statistics; dev=%s.\n", __func__, dev->name)); neigh_parms_release(&nd_tbl, ndev->nd_parms); dev_put(dev); @@ -381,7 +384,7 @@ if (snmp6_register_dev(ndev) < 0) { ADBG((KERN_WARNING - "%s(): cannot create /proc/net/dev_snmp6/%s\n", + "%s: cannot create /proc/net/dev_snmp6/%s\n", __func__, dev->name)); neigh_parms_release(&nd_tbl, ndev->nd_parms); ndev->dead = 1; @@ -399,9 +402,7 @@ #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) { - printk(KERN_INFO - "%s: Disabled Multicast RS\n", - dev->name); + pr_info("%s: Disabled Multicast RS\n", dev->name); ndev->cnf.rtr_solicits = 0; } #endif @@ -541,7 +542,7 @@ WARN_ON(!hlist_unhashed(&ifp->addr_lst)); #ifdef NET_REFCNT_DEBUG - printk(KERN_DEBUG "inet6_ifa_finish_destroy\n"); + pr_debug("%s\n", __func__); #endif in6_dev_put(ifp->idev); @@ -550,7 +551,7 @@ pr_notice("Timer is still running, when freeing ifa=%p\n", ifp); if (ifp->state != INET6_IFADDR_STATE_DEAD) { - pr_warning("Freeing alive inet6 address %p\n", ifp); + pr_warn("Freeing alive inet6 address %p\n", ifp); return; } dst_release(&ifp->rt->dst); @@ -840,8 +841,7 @@ in6_dev_hold(idev); if (idev->cnf.use_tempaddr <= 0) { write_unlock(&idev->lock); - printk(KERN_INFO - "ipv6_create_tempaddr(): use_tempaddr is disabled.\n"); + pr_info("%s: use_tempaddr is disabled\n", __func__); in6_dev_put(idev); ret = -1; goto out; @@ -851,8 +851,8 @@ idev->cnf.use_tempaddr = -1; /*XXX*/ spin_unlock_bh(&ifp->lock); write_unlock(&idev->lock); - printk(KERN_WARNING - "ipv6_create_tempaddr(): regeneration time exceeded. disabled temporary address support.\n"); + pr_warn("%s: regeneration time exceeded - disabled temporary address support\n", + __func__); in6_dev_put(idev); ret = -1; goto out; @@ -862,8 +862,8 @@ if (__ipv6_try_regen_rndid(idev, tmpaddr) < 0) { spin_unlock_bh(&ifp->lock); write_unlock(&idev->lock); - printk(KERN_WARNING - "ipv6_create_tempaddr(): regeneration of randomized interface id failed.\n"); + pr_warn("%s: regeneration of randomized interface id failed\n", + __func__); in6_ifa_put(ifp); in6_dev_put(idev); ret = -1; @@ -913,8 +913,7 @@ if (!ift || IS_ERR(ift)) { in6_ifa_put(ifp); in6_dev_put(idev); - printk(KERN_INFO - "ipv6_create_tempaddr(): retry temporary address regeneration.\n"); + pr_info("%s: retry temporary address regeneration\n", __func__); tmpaddr = &addr; write_lock(&idev->lock); goto retry; @@ -1414,9 +1413,8 @@ return; } - if (net_ratelimit()) - printk(KERN_INFO "%s: IPv6 duplicate address %pI6c detected!\n", - ifp->idev->dev->name, &ifp->addr); + net_info_ratelimited("%s: IPv6 duplicate address %pI6c detected!\n", + ifp->idev->dev->name, &ifp->addr); if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6) { struct in6_addr addr; @@ -1429,7 +1427,7 @@ /* DAD failed for link-local based on MAC address */ idev->cnf.disable_ipv6 = 1; - printk(KERN_INFO "%s: IPv6 being disabled!\n", + pr_info("%s: IPv6 being disabled!\n", ifp->idev->dev->name); } } @@ -1514,6 +1512,14 @@ return 0; } +static int addrconf_ifid_eui64(u8 *eui, struct net_device *dev) +{ + if (dev->addr_len != IEEE802154_ADDR_LEN) + return -1; + memcpy(eui, dev->dev_addr, 8); + return 0; +} + static int addrconf_ifid_arcnet(u8 *eui, struct net_device *dev) { /* XXX: inherit EUI-64 from other interface -- yoshfuji */ @@ -1567,7 +1573,6 @@ switch (dev->type) { case ARPHRD_ETHER: case ARPHRD_FDDI: - case ARPHRD_IEEE802_TR: return addrconf_ifid_eui48(eui, dev); case ARPHRD_ARCNET: return addrconf_ifid_arcnet(eui, dev); @@ -1577,6 +1582,8 @@ return addrconf_ifid_sit(eui, dev); case ARPHRD_IPGRE: return addrconf_ifid_gre(eui, dev); + case ARPHRD_IEEE802154: + return addrconf_ifid_eui64(eui, dev); } return -1; } @@ -1650,9 +1657,8 @@ idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - idev->cnf.max_desync_factor * HZ; if (time_before(expires, jiffies)) { - printk(KERN_WARNING - "ipv6_regen_rndid(): too short regeneration interval; timer disabled for %s.\n", - idev->dev->name); + pr_warn("%s: too short regeneration interval; timer disabled for %s\n", + __func__, idev->dev->name); goto out; } @@ -1836,16 +1842,15 @@ prefered_lft = ntohl(pinfo->prefered); if (prefered_lft > valid_lft) { - if (net_ratelimit()) - printk(KERN_WARNING "addrconf: prefix option has invalid lifetime\n"); + net_warn_ratelimited("addrconf: prefix option has invalid lifetime\n"); return; } in6_dev = in6_dev_get(dev); if (in6_dev == NULL) { - if (net_ratelimit()) - printk(KERN_DEBUG "addrconf: device %s not configured\n", dev->name); + net_dbg_ratelimited("addrconf: device %s not configured\n", + dev->name); return; } @@ -1920,9 +1925,8 @@ } goto ok; } - if (net_ratelimit()) - printk(KERN_DEBUG "IPv6 addrconf: prefix with wrong length %d\n", - pinfo->prefix_len); + net_dbg_ratelimited("IPv6 addrconf: prefix with wrong length %d\n", + pinfo->prefix_len); in6_dev_put(in6_dev); return; @@ -2400,7 +2404,7 @@ ASSERT_RTNL(); if ((idev = ipv6_find_idev(dev)) == NULL) { - printk(KERN_DEBUG "init loopback: add_dev failed\n"); + pr_debug("%s: add_dev failed\n", __func__); return; } @@ -2436,9 +2440,9 @@ if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_FDDI) && - (dev->type != ARPHRD_IEEE802_TR) && (dev->type != ARPHRD_ARCNET) && - (dev->type != ARPHRD_INFINIBAND)) { + (dev->type != ARPHRD_INFINIBAND) && + (dev->type != ARPHRD_IEEE802154)) { /* Alas, we support only Ethernet autoconfiguration. */ return; } @@ -2468,7 +2472,7 @@ */ if ((idev = ipv6_find_idev(dev)) == NULL) { - printk(KERN_DEBUG "init sit: add_dev failed\n"); + pr_debug("%s: add_dev failed\n", __func__); return; } @@ -2498,12 +2502,12 @@ struct inet6_dev *idev; struct in6_addr addr; - pr_info("ipv6: addrconf_gre_config(%s)\n", dev->name); + pr_info("%s(%s)\n", __func__, dev->name); ASSERT_RTNL(); if ((idev = ipv6_find_idev(dev)) == NULL) { - printk(KERN_DEBUG "init gre: add_dev failed\n"); + pr_debug("%s: add_dev failed\n", __func__); return; } @@ -2543,7 +2547,7 @@ if (!ipv6_inherit_linklocal(idev, link_dev)) return; } - printk(KERN_DEBUG "init ip6-ip6: add_linklocal failed\n"); + pr_debug("init ip6-ip6: add_linklocal failed\n"); } /* @@ -2559,7 +2563,7 @@ idev = addrconf_add_dev(dev); if (IS_ERR(idev)) { - printk(KERN_DEBUG "init ip6-ip6: add_dev failed\n"); + pr_debug("init ip6-ip6: add_dev failed\n"); return; } ip6_tnl_add_linklocal(idev); @@ -2590,9 +2594,7 @@ if (event == NETDEV_UP) { if (!addrconf_qdisc_ok(dev)) { /* device is not ready yet. */ - printk(KERN_INFO - "ADDRCONF(NETDEV_UP): %s: " - "link is not ready\n", + pr_info("ADDRCONF(NETDEV_UP): %s: link is not ready\n", dev->name); break; } @@ -2617,10 +2619,8 @@ idev->if_flags |= IF_READY; } - printk(KERN_INFO - "ADDRCONF(NETDEV_CHANGE): %s: " - "link becomes ready\n", - dev->name); + pr_info("ADDRCONF(NETDEV_CHANGE): %s: link becomes ready\n", + dev->name); run_pending = 1; } @@ -2891,8 +2891,7 @@ * Note: we do not support deprecated "all on-link" * assumption any longer. */ - printk(KERN_DEBUG "%s: no IPv6 routers present\n", - idev->dev->name); + pr_debug("%s: no IPv6 routers present\n", idev->dev->name); } out: @@ -4748,8 +4747,8 @@ err = ipv6_addr_label_init(); if (err < 0) { - printk(KERN_CRIT "IPv6 Addrconf:" - " cannot initialize default policy table: %d.\n", err); + pr_crit("%s: cannot initialize default policy table: %d\n", + __func__, err); goto out; }
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index 2d8ddba..eb6a636 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c
@@ -129,7 +129,7 @@ ip6addrlbl_free(container_of(h, struct ip6addrlbl_entry, rcu)); } -static inline int ip6addrlbl_hold(struct ip6addrlbl_entry *p) +static bool ip6addrlbl_hold(struct ip6addrlbl_entry *p) { return atomic_inc_not_zero(&p->refcnt); } @@ -141,20 +141,20 @@ } /* Find label */ -static int __ip6addrlbl_match(struct net *net, - struct ip6addrlbl_entry *p, - const struct in6_addr *addr, - int addrtype, int ifindex) +static bool __ip6addrlbl_match(struct net *net, + const struct ip6addrlbl_entry *p, + const struct in6_addr *addr, + int addrtype, int ifindex) { if (!net_eq(ip6addrlbl_net(p), net)) - return 0; + return false; if (p->ifindex && p->ifindex != ifindex) - return 0; + return false; if (p->addrtype && p->addrtype != addrtype) - return 0; + return false; if (!ipv6_prefix_equal(addr, &p->prefix, p->prefixlen)) - return 0; - return 1; + return false; + return true; } static struct ip6addrlbl_entry *__ipv6_addr_label(struct net *net, @@ -350,7 +350,7 @@ int err = 0; int i; - ADDRLABEL(KERN_DEBUG "%s()\n", __func__); + ADDRLABEL(KERN_DEBUG "%s\n", __func__); for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) { int ret = ip6addrlbl_add(net, @@ -456,8 +456,8 @@ return err; } -static inline void ip6addrlbl_putmsg(struct nlmsghdr *nlh, - int prefixlen, int ifindex, u32 lseq) +static void ip6addrlbl_putmsg(struct nlmsghdr *nlh, + int prefixlen, int ifindex, u32 lseq) { struct ifaddrlblmsg *ifal = nlmsg_data(nlh); ifal->ifal_family = AF_INET6;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 0ad046c7..e22e6d8 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c
@@ -18,6 +18,7 @@ * 2 of the License, or (at your option) any later version. */ +#define pr_fmt(fmt) "IPv6: " fmt #include <linux/module.h> #include <linux/capability.h> @@ -77,7 +78,7 @@ .autoconf = 1, }; -static int disable_ipv6_mod = 0; +static int disable_ipv6_mod; module_param_named(disable, disable_ipv6_mod, int, 0444); MODULE_PARM_DESC(disable, "Disable IPv6 module such that it is non-functional"); @@ -256,7 +257,7 @@ /* bind for INET6 API */ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { - struct sockaddr_in6 *addr=(struct sockaddr_in6 *)uaddr; + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)uaddr; struct sock *sk = sock->sk; struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); @@ -390,7 +391,6 @@ rcu_read_unlock(); goto out; } - EXPORT_SYMBOL(inet6_bind); int inet6_release(struct socket *sock) @@ -408,7 +408,6 @@ return inet_release(sock); } - EXPORT_SYMBOL(inet6_release); void inet6_destroy_sock(struct sock *sk) @@ -419,10 +418,12 @@ /* Release rx options */ - if ((skb = xchg(&np->pktoptions, NULL)) != NULL) + skb = xchg(&np->pktoptions, NULL); + if (skb != NULL) kfree_skb(skb); - if ((skb = xchg(&np->rxpmtu, NULL)) != NULL) + skb = xchg(&np->rxpmtu, NULL); + if (skb != NULL) kfree_skb(skb); /* Free flowlabels */ @@ -430,10 +431,10 @@ /* Free tx options */ - if ((opt = xchg(&np->opt, NULL)) != NULL) + opt = xchg(&np->opt, NULL); + if (opt != NULL) sock_kfree_s(sk, opt, opt->tot_len); } - EXPORT_SYMBOL_GPL(inet6_destroy_sock); /* @@ -443,7 +444,7 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) { - struct sockaddr_in6 *sin=(struct sockaddr_in6 *)uaddr; + struct sockaddr_in6 *sin = (struct sockaddr_in6 *)uaddr; struct sock *sk = sock->sk; struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); @@ -474,7 +475,6 @@ *uaddr_len = sizeof(*sin); return 0; } - EXPORT_SYMBOL(inet6_getname); int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) @@ -482,8 +482,7 @@ struct sock *sk = sock->sk; struct net *net = sock_net(sk); - switch(cmd) - { + switch (cmd) { case SIOCGSTAMP: return sock_get_timestamp(sk, (struct timeval __user *)arg); @@ -509,7 +508,6 @@ /*NOTREACHED*/ return 0; } - EXPORT_SYMBOL(inet6_ioctl); const struct proto_ops inet6_stream_ops = { @@ -615,25 +613,21 @@ return ret; out_permanent: - printk(KERN_ERR "Attempt to override permanent protocol %d.\n", - protocol); + pr_err("Attempt to override permanent protocol %d\n", protocol); goto out; out_illegal: - printk(KERN_ERR - "Ignoring attempt to register invalid socket type %d.\n", + pr_err("Ignoring attempt to register invalid socket type %d\n", p->type); goto out; } - EXPORT_SYMBOL(inet6_register_protosw); void inet6_unregister_protosw(struct inet_protosw *p) { if (INET_PROTOSW_PERMANENT & p->flags) { - printk(KERN_ERR - "Attempt to unregister permanent protocol %d.\n", + pr_err("Attempt to unregister permanent protocol %d\n", p->protocol); } else { spin_lock_bh(&inetsw6_lock); @@ -643,7 +637,6 @@ synchronize_net(); } } - EXPORT_SYMBOL(inet6_unregister_protosw); int inet6_sk_rebuild_header(struct sock *sk) @@ -683,13 +676,12 @@ return 0; } - EXPORT_SYMBOL_GPL(inet6_sk_rebuild_header); -int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb) +bool ipv6_opt_accepted(const struct sock *sk, const struct sk_buff *skb) { - struct ipv6_pinfo *np = inet6_sk(sk); - struct inet6_skb_parm *opt = IP6CB(skb); + const struct ipv6_pinfo *np = inet6_sk(sk); + const struct inet6_skb_parm *opt = IP6CB(skb); if (np->rxopt.all) { if ((opt->hop && (np->rxopt.bits.hopopts || @@ -701,11 +693,10 @@ np->rxopt.bits.osrcrt)) || ((opt->dst1 || opt->dst0) && (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts))) - return 1; + return true; } - return 0; + return false; } - EXPORT_SYMBOL_GPL(ipv6_opt_accepted); static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto) @@ -1070,13 +1061,11 @@ BUILD_BUG_ON(sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb)); /* Register the socket-side information for inet6_create. */ - for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) + for (r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) INIT_LIST_HEAD(r); if (disable_ipv6_mod) { - printk(KERN_INFO - "IPv6: Loaded, but administratively disabled, " - "reboot required to enable\n"); + pr_info("Loaded, but administratively disabled, reboot required to enable\n"); goto out; }
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 2ae79db..f1a4a2c 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c
@@ -24,6 +24,8 @@ * This file is derived from net/ipv4/ah.c. */ +#define pr_fmt(fmt) "IPv6: " fmt + #include <crypto/hash.h> #include <linux/module.h> #include <linux/slab.h> @@ -111,7 +113,7 @@ __alignof__(struct scatterlist)); } -static int zero_out_mutable_opts(struct ipv6_opt_hdr *opthdr) +static bool zero_out_mutable_opts(struct ipv6_opt_hdr *opthdr) { u8 *opt = (u8 *)opthdr; int len = ipv6_optlen(opthdr); @@ -125,7 +127,7 @@ switch (opt[off]) { - case IPV6_TLV_PAD0: + case IPV6_TLV_PAD1: optlen = 1; break; default: @@ -143,10 +145,10 @@ len -= optlen; } if (len == 0) - return 1; + return true; bad: - return 0; + return false; } #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) @@ -169,7 +171,7 @@ switch (opt[off]) { - case IPV6_TLV_PAD0: + case IPV6_TLV_PAD1: optlen = 1; break; default: @@ -189,8 +191,8 @@ hao = (struct ipv6_destopt_hao *)&opt[off]; if (hao->length != sizeof(hao->addr)) { - if (net_ratelimit()) - printk(KERN_WARNING "destopt hao: invalid header length: %u\n", hao->length); + net_warn_ratelimited("destopt hao: invalid header length: %u\n", + hao->length); goto bad; } final_addr = hao->addr; @@ -659,9 +661,9 @@ if (aalg_desc->uinfo.auth.icv_fullbits/8 != crypto_ahash_digestsize(ahash)) { - printk(KERN_INFO "AH: %s digestsize %u != %hu\n", - x->aalg->alg_name, crypto_ahash_digestsize(ahash), - aalg_desc->uinfo.auth.icv_fullbits/8); + pr_info("AH: %s digestsize %u != %hu\n", + x->aalg->alg_name, crypto_ahash_digestsize(ahash), + aalg_desc->uinfo.auth.icv_fullbits/8); goto error; } @@ -727,12 +729,12 @@ static int __init ah6_init(void) { if (xfrm_register_type(&ah6_type, AF_INET6) < 0) { - printk(KERN_INFO "ipv6 ah init: can't add xfrm type\n"); + pr_info("%s: can't add xfrm type\n", __func__); return -EAGAIN; } if (inet6_add_protocol(&ah6_protocol, IPPROTO_AH) < 0) { - printk(KERN_INFO "ipv6 ah init: can't add protocol\n"); + pr_info("%s: can't add protocol\n", __func__); xfrm_unregister_type(&ah6_type, AF_INET6); return -EAGAIN; } @@ -743,10 +745,10 @@ static void __exit ah6_fini(void) { if (inet6_del_protocol(&ah6_protocol, IPPROTO_AH) < 0) - printk(KERN_INFO "ipv6 ah close: can't remove protocol\n"); + pr_info("%s: can't remove protocol\n", __func__); if (xfrm_unregister_type(&ah6_type, AF_INET6) < 0) - printk(KERN_INFO "ipv6 ah close: can't remove xfrm type\n"); + pr_info("%s: can't remove xfrm type\n", __func__); }
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index db00d27..cdf02be 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c
@@ -342,7 +342,7 @@ * check if the interface has this anycast address * called with rcu_read_lock() */ -static int ipv6_chk_acast_dev(struct net_device *dev, const struct in6_addr *addr) +static bool ipv6_chk_acast_dev(struct net_device *dev, const struct in6_addr *addr) { struct inet6_dev *idev; struct ifacaddr6 *aca; @@ -356,16 +356,16 @@ read_unlock_bh(&idev->lock); return aca != NULL; } - return 0; + return false; } /* * check if given interface (or any, if dev==0) has this anycast address */ -int ipv6_chk_acast_addr(struct net *net, struct net_device *dev, - const struct in6_addr *addr) +bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev, + const struct in6_addr *addr) { - int found = 0; + bool found = false; rcu_read_lock(); if (dev) @@ -373,7 +373,7 @@ else for_each_netdev_rcu(net, dev) if (ipv6_chk_acast_dev(dev, addr)) { - found = 1; + found = true; break; } rcu_read_unlock();
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index b8b61ac..be2b67d6 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c
@@ -34,9 +34,9 @@ #include <linux/errqueue.h> #include <asm/uaccess.h> -static inline int ipv6_mapped_addr_any(const struct in6_addr *a) +static bool ipv6_mapped_addr_any(const struct in6_addr *a) { - return (ipv6_addr_v4mapped(a) && (a->s6_addr32[3] == 0)); + return ipv6_addr_v4mapped(a) && (a->s6_addr32[3] == 0); } int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 1ac7938..1e62b755 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c
@@ -24,6 +24,8 @@ * This file is derived from net/ipv4/esp.c */ +#define pr_fmt(fmt) "IPv6: " fmt + #include <crypto/aead.h> #include <crypto/authenc.h> #include <linux/err.h> @@ -442,8 +444,8 @@ esph->spi, IPPROTO_ESP, AF_INET6); if (!x) return; - printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n", - ntohl(esph->spi), &iph->daddr); + pr_debug("pmtu discovery on SA ESP/%08x/%pI6\n", + ntohl(esph->spi), &iph->daddr); xfrm_state_put(x); } @@ -651,11 +653,11 @@ static int __init esp6_init(void) { if (xfrm_register_type(&esp6_type, AF_INET6) < 0) { - printk(KERN_INFO "ipv6 esp init: can't add xfrm type\n"); + pr_info("%s: can't add xfrm type\n", __func__); return -EAGAIN; } if (inet6_add_protocol(&esp6_protocol, IPPROTO_ESP) < 0) { - printk(KERN_INFO "ipv6 esp init: can't add protocol\n"); + pr_info("%s: can't add protocol\n", __func__); xfrm_unregister_type(&esp6_type, AF_INET6); return -EAGAIN; } @@ -666,9 +668,9 @@ static void __exit esp6_fini(void) { if (inet6_del_protocol(&esp6_protocol, IPPROTO_ESP) < 0) - printk(KERN_INFO "ipv6 esp close: can't remove protocol\n"); + pr_info("%s: can't remove protocol\n", __func__); if (xfrm_unregister_type(&esp6_type, AF_INET6) < 0) - printk(KERN_INFO "ipv6 esp close: can't remove xfrm type\n"); + pr_info("%s: can't remove xfrm type\n", __func__); } module_init(esp6_init);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index a93bd23..6447dc4 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c
@@ -75,7 +75,7 @@ return offset; switch (opttype) { - case IPV6_TLV_PAD0: + case IPV6_TLV_PAD1: optlen = 1; break; default: @@ -96,14 +96,14 @@ /* * Parsing tlv encoded headers. * - * Parsing function "func" returns 1, if parsing succeed - * and 0, if it failed. + * Parsing function "func" returns true, if parsing succeed + * and false, if it failed. * It MUST NOT touch skb->h. */ struct tlvtype_proc { int type; - int (*func)(struct sk_buff *skb, int offset); + bool (*func)(struct sk_buff *skb, int offset); }; /********************* @@ -112,11 +112,11 @@ /* An unknown option is detected, decide what to do */ -static int ip6_tlvopt_unknown(struct sk_buff *skb, int optoff) +static bool ip6_tlvopt_unknown(struct sk_buff *skb, int optoff) { switch ((skb_network_header(skb)[optoff] & 0xC0) >> 6) { case 0: /* ignore */ - return 1; + return true; case 1: /* drop packet */ break; @@ -129,21 +129,22 @@ break; case 2: /* send ICMP PARM PROB regardless and drop packet */ icmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff); - return 0; + return false; } kfree_skb(skb); - return 0; + return false; } /* Parse tlv encoded option header (hop-by-hop or destination) */ -static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff *skb) +static bool ip6_parse_tlv(const struct tlvtype_proc *procs, struct sk_buff *skb) { - struct tlvtype_proc *curr; + const struct tlvtype_proc *curr; const unsigned char *nh = skb_network_header(skb); int off = skb_network_header_len(skb); int len = (skb_transport_header(skb)[1] + 1) << 3; + int padlen = 0; if (skb_transport_offset(skb) + len > skb_headlen(skb)) goto bad; @@ -156,8 +157,11 @@ int i; switch (nh[off]) { - case IPV6_TLV_PAD0: + case IPV6_TLV_PAD1: optlen = 1; + padlen++; + if (padlen > 7) + goto bad; break; case IPV6_TLV_PADN: @@ -166,7 +170,8 @@ * of 8. 7 is therefore the highest valid value. * See also RFC 4942, Section 2.1.9.5. */ - if (optlen > 7) + padlen += optlen; + if (padlen > 7) goto bad; /* RFC 4942 recommends receiving hosts to * actively check PadN payload to contain @@ -186,25 +191,33 @@ /* type specific length/alignment checks will be performed in the func(). */ - if (curr->func(skb, off) == 0) - return 0; + if (curr->func(skb, off) == false) + return false; break; } } if (curr->type < 0) { if (ip6_tlvopt_unknown(skb, off) == 0) - return 0; + return false; } + padlen = 0; break; } off += optlen; len -= optlen; } + /* This case will not be caught by above check since its padding + * length is smaller than 7: + * 1 byte NH + 1 byte Length + 6 bytes Padding + */ + if ((padlen == 6) && ((off - skb_network_header_len(skb)) == 8)) + goto bad; + if (len == 0) - return 1; + return true; bad: kfree_skb(skb); - return 0; + return false; } /***************************** @@ -212,7 +225,7 @@ *****************************/ #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) -static int ipv6_dest_hao(struct sk_buff *skb, int optoff) +static bool ipv6_dest_hao(struct sk_buff *skb, int optoff) { struct ipv6_destopt_hao *hao; struct inet6_skb_parm *opt = IP6CB(skb); @@ -266,15 +279,15 @@ if (skb->tstamp.tv64 == 0) __net_timestamp(skb); - return 1; + return true; discard: kfree_skb(skb); - return 0; + return false; } #endif -static struct tlvtype_proc tlvprocdestopt_lst[] = { +static const struct tlvtype_proc tlvprocdestopt_lst[] = { #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) { .type = IPV6_TLV_HAO, @@ -579,23 +592,23 @@ /* Router Alert as of RFC 2711 */ -static int ipv6_hop_ra(struct sk_buff *skb, int optoff) +static bool ipv6_hop_ra(struct sk_buff *skb, int optoff) { const unsigned char *nh = skb_network_header(skb); if (nh[optoff + 1] == 2) { IP6CB(skb)->ra = optoff; - return 1; + return true; } LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n", nh[optoff + 1]); kfree_skb(skb); - return 0; + return false; } /* Jumbo payload */ -static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff) +static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff) { const unsigned char *nh = skb_network_header(skb); struct net *net = ipv6_skb_net(skb); @@ -614,13 +627,13 @@ IP6_INC_STATS_BH(net, ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); - return 0; + return false; } if (ipv6_hdr(skb)->payload_len) { IP6_INC_STATS_BH(net, ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); - return 0; + return false; } if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { @@ -632,14 +645,14 @@ if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) goto drop; - return 1; + return true; drop: kfree_skb(skb); - return 0; + return false; } -static struct tlvtype_proc tlvprochopopt_lst[] = { +static const struct tlvtype_proc tlvprochopopt_lst[] = { { .type = IPV6_TLV_ROUTERALERT, .func = ipv6_hop_ra,
diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c index 7b1a884..f73d59a 100644 --- a/net/ipv6/exthdrs_core.c +++ b/net/ipv6/exthdrs_core.c
@@ -9,7 +9,7 @@ * find out if nexthdr is a well-known extension header or a protocol */ -int ipv6_ext_hdr(u8 nexthdr) +bool ipv6_ext_hdr(u8 nexthdr) { /* * find out if nexthdr is an extension header or a protocol
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index cc079d8..091a297 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c
@@ -29,6 +29,8 @@ * Kazunori MIYAZAWA @USAGI: change output process to use ip6_append_data */ +#define pr_fmt(fmt) "IPv6: " fmt + #include <linux/module.h> #include <linux/errno.h> #include <linux/types.h> @@ -129,7 +131,7 @@ * --ANK (980726) */ -static int is_ineligible(struct sk_buff *skb) +static bool is_ineligible(const struct sk_buff *skb) { int ptr = (u8 *)(ipv6_hdr(skb) + 1) - skb->data; int len = skb->len - ptr; @@ -137,11 +139,11 @@ __be16 frag_off; if (len < 0) - return 1; + return true; ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr, &frag_off); if (ptr < 0) - return 0; + return false; if (nexthdr == IPPROTO_ICMPV6) { u8 _type, *tp; tp = skb_header_pointer(skb, @@ -149,9 +151,9 @@ sizeof(_type), &_type); if (tp == NULL || !(*tp & ICMPV6_INFOMSG_MASK)) - return 1; + return true; } - return 0; + return false; } /* @@ -206,14 +208,14 @@ * highest-order two bits set to 10 */ -static __inline__ int opt_unrec(struct sk_buff *skb, __u32 offset) +static bool opt_unrec(struct sk_buff *skb, __u32 offset) { u8 _optval, *op; offset += skb_network_offset(skb); op = skb_header_pointer(skb, offset, sizeof(_optval), &_optval); if (op == NULL) - return 1; + return true; return (*op & 0xC0) == 0x80; } @@ -820,9 +822,7 @@ err = inet_ctl_sock_create(&sk, PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, net); if (err < 0) { - printk(KERN_ERR - "Failed to initialize the ICMP6 control socket " - "(err %d).\n", + pr_err("Failed to initialize the ICMP6 control socket (err %d)\n", err); goto fail; } @@ -881,7 +881,7 @@ return 0; fail: - printk(KERN_ERR "Failed to register ICMP6 protocol\n"); + pr_err("Failed to register ICMP6 protocol\n"); unregister_pernet_subsys(&icmpv6_sk_ops); return err; }
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 9371743..0c220a4 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c
@@ -18,6 +18,9 @@ * routing table. * Ville Nuorvala: Fixed routing subtrees. */ + +#define pr_fmt(fmt) "IPv6: " fmt + #include <linux/errno.h> #include <linux/types.h> #include <linux/net.h> @@ -38,7 +41,7 @@ #define RT6_DEBUG 2 #if RT6_DEBUG >= 3 -#define RT6_TRACE(x...) printk(KERN_DEBUG x) +#define RT6_TRACE(x...) pr_debug(x) #else #define RT6_TRACE(x...) do { ; } while (0) #endif @@ -451,12 +454,10 @@ !ipv6_prefix_equal(&key->addr, addr, fn->fn_bit)) { if (!allow_create) { if (replace_required) { - pr_warn("IPv6: Can't replace route, " - "no match found\n"); + pr_warn("Can't replace route, no match found\n"); return ERR_PTR(-ENOENT); } - pr_warn("IPv6: NLM_F_CREATE should be set " - "when creating new route\n"); + pr_warn("NLM_F_CREATE should be set when creating new route\n"); } goto insert_above; } @@ -499,11 +500,10 @@ * That would keep IPv6 consistent with IPv4 */ if (replace_required) { - pr_warn("IPv6: Can't replace route, no match found\n"); + pr_warn("Can't replace route, no match found\n"); return ERR_PTR(-ENOENT); } - pr_warn("IPv6: NLM_F_CREATE should be set " - "when creating new route\n"); + pr_warn("NLM_F_CREATE should be set when creating new route\n"); } /* * We walked to the bottom of tree. @@ -696,7 +696,7 @@ */ if (!replace) { if (!add) - pr_warn("IPv6: NLM_F_CREATE should be set when creating new route\n"); + pr_warn("NLM_F_CREATE should be set when creating new route\n"); add: rt->dst.rt6_next = iter; @@ -715,7 +715,7 @@ if (!found) { if (add) goto add; - pr_warn("IPv6: NLM_F_REPLACE set, but no existing node found!\n"); + pr_warn("NLM_F_REPLACE set, but no existing node found!\n"); return -ENOENT; } *ins = rt; @@ -768,7 +768,7 @@ replace_required = 1; } if (!allow_create && !replace_required) - pr_warn("IPv6: RTM_NEWROUTE with no NLM_F_CREATE or NLM_F_REPLACE\n"); + pr_warn("RTM_NEWROUTE with no NLM_F_CREATE or NLM_F_REPLACE\n"); fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr), rt->rt6i_dst.plen, offsetof(struct rt6_info, rt6i_dst), @@ -1420,7 +1420,8 @@ res = fib6_del(rt, &info); if (res) { #if RT6_DEBUG >= 2 - printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res); + pr_debug("%s: del failed: rt=%p@%p err=%d\n", + __func__, rt, rt->rt6i_node, res); #endif continue; }
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index cb43df6..9772fbd 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c
@@ -433,32 +433,32 @@ return 0; } -static int ipv6_hdr_cmp(struct ipv6_opt_hdr *h1, struct ipv6_opt_hdr *h2) +static bool ipv6_hdr_cmp(struct ipv6_opt_hdr *h1, struct ipv6_opt_hdr *h2) { if (h1 == h2) - return 0; + return false; if (h1 == NULL || h2 == NULL) - return 1; + return true; if (h1->hdrlen != h2->hdrlen) - return 1; + return true; return memcmp(h1+1, h2+1, ((h1->hdrlen+1)<<3) - sizeof(*h1)); } -static int ipv6_opt_cmp(struct ipv6_txoptions *o1, struct ipv6_txoptions *o2) +static bool ipv6_opt_cmp(struct ipv6_txoptions *o1, struct ipv6_txoptions *o2) { if (o1 == o2) - return 0; + return false; if (o1 == NULL || o2 == NULL) - return 1; + return true; if (o1->opt_nflen != o2->opt_nflen) - return 1; + return true; if (ipv6_hdr_cmp(o1->hopopt, o2->hopopt)) - return 1; + return true; if (ipv6_hdr_cmp(o1->dst0opt, o2->dst0opt)) - return 1; + return true; if (ipv6_hdr_cmp((struct ipv6_opt_hdr *)o1->srcrt, (struct ipv6_opt_hdr *)o2->srcrt)) - return 1; - return 0; + return true; + return false; } static inline void fl_link(struct ipv6_pinfo *np, struct ipv6_fl_socklist *sfl,
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 1ca5d45..21a15df 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c
@@ -170,7 +170,8 @@ { const struct inet6_protocol *ipprot; unsigned int nhoff; - int nexthdr, raw; + int nexthdr; + bool raw; u8 hash; struct inet6_dev *idev; struct net *net = dev_net(skb_dst(skb)->dev); @@ -251,7 +252,7 @@ int ip6_mc_input(struct sk_buff *skb) { const struct ipv6hdr *hdr; - int deliver; + bool deliver; IP6_UPD_PO_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_INMCAST, @@ -287,7 +288,7 @@ * is for MLD (0x0000). */ if ((ptr[2] | ptr[3]) == 0) { - deliver = 0; + deliver = false; if (!ipv6_ext_hdr(nexthdr)) { /* BUG */ @@ -312,7 +313,7 @@ case ICMPV6_MGM_REPORT: case ICMPV6_MGM_REDUCTION: case ICMPV6_MLD2_REPORT: - deliver = 1; + deliver = true; break; } goto out;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index d8e05af2..d99fdc6 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c
@@ -252,8 +252,7 @@ dst->dev, dst_output); } - if (net_ratelimit()) - printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); + net_dbg_ratelimited("IPv6: sending pkt_too_big to self\n"); skb->dev = dst->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS); @@ -644,7 +643,10 @@ /* We must not fragment if the socket is set to force MTU discovery * or if the skb it not generated by a local socket. */ - if (!skb->local_df && skb->len > mtu) { + if (unlikely(!skb->local_df && skb->len > mtu)) { + if (skb->sk && dst_allfrag(skb_dst(skb))) + sk_nocaps_add(skb->sk, NETIF_F_GSO_MASK); + skb->dev = skb_dst(skb)->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), @@ -789,6 +791,10 @@ } slow_path: + if ((skb->ip_summed == CHECKSUM_PARTIAL) && + skb_checksum_help(skb)) + goto fail; + left = skb->len - hlen; /* Space per frame */ ptr = hlen; /* Where to start from */ @@ -1199,7 +1205,6 @@ int copy; int err; int offset = 0; - int csummode = CHECKSUM_NONE; __u8 tx_flags = 0; if (flags&MSG_PROBE) @@ -1412,7 +1417,7 @@ /* * Fill in the control structures */ - skb->ip_summed = csummode; + skb->ip_summed = CHECKSUM_NONE; skb->csum = 0; /* reserve for fragmentation and ipsec header */ skb_reserve(skb, hh_len + sizeof(struct frag_hdr) + @@ -1455,7 +1460,6 @@ transhdrlen = 0; exthdrlen = 0; dst_exthdrlen = 0; - csummode = CHECKSUM_NONE; /* * Put the packet on the pending queue
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 5df487c..c9015fad 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c
@@ -18,6 +18,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/capability.h> #include <linux/errno.h> @@ -60,7 +62,7 @@ MODULE_ALIAS_NETDEV("ip6tnl0"); #ifdef IP6_TNL_DEBUG -#define IP6_TNL_TRACE(x...) printk(KERN_DEBUG "%s:" x "\n", __func__) +#define IP6_TNL_TRACE(x...) pr_debug("%s:" x "\n", __func__) #else #define IP6_TNL_TRACE(x...) do {;} while(0) #endif @@ -460,19 +462,14 @@ struct ipv6_tlv_tnl_enc_lim *tel; __u32 mtu; case ICMPV6_DEST_UNREACH: - if (net_ratelimit()) - printk(KERN_WARNING - "%s: Path to destination invalid " - "or inactive!\n", t->parms.name); + net_warn_ratelimited("%s: Path to destination invalid or inactive!\n", + t->parms.name); rel_msg = 1; break; case ICMPV6_TIME_EXCEED: if ((*code) == ICMPV6_EXC_HOPLIMIT) { - if (net_ratelimit()) - printk(KERN_WARNING - "%s: Too small hop limit or " - "routing loop in tunnel!\n", - t->parms.name); + net_warn_ratelimited("%s: Too small hop limit or routing loop in tunnel!\n", + t->parms.name); rel_msg = 1; } break; @@ -484,17 +481,13 @@ if (teli && teli == *info - 2) { tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli]; if (tel->encap_limit == 0) { - if (net_ratelimit()) - printk(KERN_WARNING - "%s: Too small encapsulation " - "limit or routing loop in " - "tunnel!\n", t->parms.name); + net_warn_ratelimited("%s: Too small encapsulation limit or routing loop in tunnel!\n", + t->parms.name); rel_msg = 1; } - } else if (net_ratelimit()) { - printk(KERN_WARNING - "%s: Recipient unable to parse tunneled " - "packet!\n ", t->parms.name); + } else { + net_warn_ratelimited("%s: Recipient unable to parse tunneled packet!\n", + t->parms.name); } break; case ICMPV6_PKT_TOOBIG: @@ -825,7 +818,7 @@ * 0 else **/ -static inline int +static inline bool ip6_tnl_addr_conflict(const struct ip6_tnl *t, const struct ipv6hdr *hdr) { return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr); @@ -845,15 +838,12 @@ ldev = dev_get_by_index_rcu(net, p->link); if (unlikely(!ipv6_chk_addr(net, &p->laddr, ldev, 0))) - printk(KERN_WARNING - "%s xmit: Local address not yet configured!\n", - p->name); + pr_warn("%s xmit: Local address not yet configured!\n", + p->name); else if (!ipv6_addr_is_multicast(&p->raddr) && unlikely(ipv6_chk_addr(net, &p->raddr, NULL, 0))) - printk(KERN_WARNING - "%s xmit: Routing loop! " - "Remote address found on this node!\n", - p->name); + pr_warn("%s xmit: Routing loop! Remote address found on this node!\n", + p->name); else ret = 1; rcu_read_unlock(); @@ -919,10 +909,8 @@ if (tdev == dev) { stats->collisions++; - if (net_ratelimit()) - printk(KERN_WARNING - "%s: Local routing loop detected!\n", - t->parms.name); + net_warn_ratelimited("%s: Local routing loop detected!\n", + t->parms.name); goto tx_err_dst_release; } mtu = dst_mtu(dst) - sizeof (*ipv6h); @@ -1553,13 +1541,13 @@ err = xfrm6_tunnel_register(&ip4ip6_handler, AF_INET); if (err < 0) { - printk(KERN_ERR "ip6_tunnel init: can't register ip4ip6\n"); + pr_err("%s: can't register ip4ip6\n", __func__); goto out_ip4ip6; } err = xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6); if (err < 0) { - printk(KERN_ERR "ip6_tunnel init: can't register ip6ip6\n"); + pr_err("%s: can't register ip6ip6\n", __func__); goto out_ip6ip6; } @@ -1580,10 +1568,10 @@ static void __exit ip6_tunnel_cleanup(void) { if (xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET)) - printk(KERN_INFO "ip6_tunnel close: can't deregister ip4ip6\n"); + pr_info("%s: can't deregister ip4ip6\n", __func__); if (xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6)) - printk(KERN_INFO "ip6_tunnel close: can't deregister ip6ip6\n"); + pr_info("%s: can't deregister ip6ip6\n", __func__); unregister_pernet_device(&ip6_tnl_net_ops); }
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index efc0098..b15dc08 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c
@@ -1147,8 +1147,7 @@ */ ret = sock_queue_rcv_skb(mrt->mroute6_sk, skb); if (ret < 0) { - if (net_ratelimit()) - printk(KERN_WARNING "mroute6: pending queue full, dropping entries.\n"); + net_warn_ratelimited("mroute6: pending queue full, dropping entries\n"); kfree_skb(skb); } @@ -1351,7 +1350,7 @@ goto reg_notif_fail; #ifdef CONFIG_IPV6_PIMSM_V2 if (inet6_add_protocol(&pim6_protocol, IPPROTO_PIM) < 0) { - printk(KERN_ERR "ip6_mr_init: can't add PIM protocol\n"); + pr_err("%s: can't add PIM protocol\n", __func__); err = -EAGAIN; goto add_proto_fail; }
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index bba658d..5cb75bf 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c
@@ -30,6 +30,9 @@ * The decompression of IP datagram MUST be done after the reassembly, * AH/ESP processing. */ + +#define pr_fmt(fmt) "IPv6: " fmt + #include <linux/module.h> #include <net/ip.h> #include <net/xfrm.h> @@ -69,8 +72,8 @@ if (!x) return; - printk(KERN_DEBUG "pmtu discovery on SA IPCOMP/%08x/%pI6\n", - spi, &iph->daddr); + pr_debug("pmtu discovery on SA IPCOMP/%08x/%pI6\n", + spi, &iph->daddr); xfrm_state_put(x); } @@ -190,11 +193,11 @@ static int __init ipcomp6_init(void) { if (xfrm_register_type(&ipcomp6_type, AF_INET6) < 0) { - printk(KERN_INFO "ipcomp6 init: can't add xfrm type\n"); + pr_info("%s: can't add xfrm type\n", __func__); return -EAGAIN; } if (inet6_add_protocol(&ipcomp6_protocol, IPPROTO_COMP) < 0) { - printk(KERN_INFO "ipcomp6 init: can't add protocol\n"); + pr_info("%s: can't add protocol\n", __func__); xfrm_unregister_type(&ipcomp6_type, AF_INET6); return -EAGAIN; } @@ -204,9 +207,9 @@ static void __exit ipcomp6_fini(void) { if (inet6_del_protocol(&ipcomp6_protocol, IPPROTO_COMP) < 0) - printk(KERN_INFO "ipv6 ipcomp close: can't remove protocol\n"); + pr_info("%s: can't remove protocol\n", __func__); if (xfrm_unregister_type(&ipcomp6_type, AF_INET6) < 0) - printk(KERN_INFO "ipv6 ipcomp close: can't remove xfrm type\n"); + pr_info("%s: can't remove xfrm type\n", __func__); } module_init(ipcomp6_init);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 7dfb89f..6d0f5dc8 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c
@@ -606,13 +606,13 @@ return err; } -int inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr, - const struct in6_addr *src_addr) +bool inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr, + const struct in6_addr *src_addr) { struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_mc_socklist *mc; struct ip6_sf_socklist *psl; - int rv = 1; + bool rv = true; rcu_read_lock(); for_each_pmc_rcu(np, mc) { @@ -621,7 +621,7 @@ } if (!mc) { rcu_read_unlock(); - return 1; + return true; } read_lock(&mc->sflock); psl = mc->sflist; @@ -635,9 +635,9 @@ break; } if (mc->sfmode == MCAST_INCLUDE && i >= psl->sl_count) - rv = 0; + rv = false; if (mc->sfmode == MCAST_EXCLUDE && i < psl->sl_count) - rv = 0; + rv = false; } read_unlock(&mc->sflock); rcu_read_unlock(); @@ -931,15 +931,15 @@ /* * identify MLD packets for MLD filter exceptions */ -int ipv6_is_mld(struct sk_buff *skb, int nexthdr) +bool ipv6_is_mld(struct sk_buff *skb, int nexthdr) { struct icmp6hdr *pic; if (nexthdr != IPPROTO_ICMPV6) - return 0; + return false; if (!pskb_may_pull(skb, sizeof(struct icmp6hdr))) - return 0; + return false; pic = icmp6_hdr(skb); @@ -948,22 +948,22 @@ case ICMPV6_MGM_REPORT: case ICMPV6_MGM_REDUCTION: case ICMPV6_MLD2_REPORT: - return 1; + return true; default: break; } - return 0; + return false; } /* * check if the interface/address pair is valid */ -int ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group, - const struct in6_addr *src_addr) +bool ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group, + const struct in6_addr *src_addr) { struct inet6_dev *idev; struct ifmcaddr6 *mc; - int rv = 0; + bool rv = false; rcu_read_lock(); idev = __in6_dev_get(dev); @@ -990,7 +990,7 @@ rv = mc->mca_sfcount[MCAST_EXCLUDE] !=0; spin_unlock_bh(&mc->mca_lock); } else - rv = 1; /* don't filter unspecified source */ + rv = true; /* don't filter unspecified source */ } read_unlock_bh(&idev->lock); } @@ -1046,8 +1046,8 @@ } /* mark EXCLUDE-mode sources */ -static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, - const struct in6_addr *srcs) +static bool mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, + const struct in6_addr *srcs) { struct ip6_sf_list *psf; int i, scount; @@ -1070,12 +1070,12 @@ } pmc->mca_flags &= ~MAF_GSQUERY; if (scount == nsrcs) /* all sources excluded */ - return 0; - return 1; + return false; + return true; } -static int mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, - const struct in6_addr *srcs) +static bool mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, + const struct in6_addr *srcs) { struct ip6_sf_list *psf; int i, scount; @@ -1099,10 +1099,10 @@ } if (!scount) { pmc->mca_flags &= ~MAF_GSQUERY; - return 0; + return false; } pmc->mca_flags |= MAF_GSQUERY; - return 1; + return true; } /* called with rcu_read_lock() */ @@ -1276,17 +1276,17 @@ return 0; } -static int is_in(struct ifmcaddr6 *pmc, struct ip6_sf_list *psf, int type, - int gdeleted, int sdeleted) +static bool is_in(struct ifmcaddr6 *pmc, struct ip6_sf_list *psf, int type, + int gdeleted, int sdeleted) { switch (type) { case MLD2_MODE_IS_INCLUDE: case MLD2_MODE_IS_EXCLUDE: if (gdeleted || sdeleted) - return 0; + return false; if (!((pmc->mca_flags & MAF_GSQUERY) && !psf->sf_gsresp)) { if (pmc->mca_sfmode == MCAST_INCLUDE) - return 1; + return true; /* don't include if this source is excluded * in all filters */ @@ -1295,29 +1295,29 @@ return pmc->mca_sfcount[MCAST_EXCLUDE] == psf->sf_count[MCAST_EXCLUDE]; } - return 0; + return false; case MLD2_CHANGE_TO_INCLUDE: if (gdeleted || sdeleted) - return 0; + return false; return psf->sf_count[MCAST_INCLUDE] != 0; case MLD2_CHANGE_TO_EXCLUDE: if (gdeleted || sdeleted) - return 0; + return false; if (pmc->mca_sfcount[MCAST_EXCLUDE] == 0 || psf->sf_count[MCAST_INCLUDE]) - return 0; + return false; return pmc->mca_sfcount[MCAST_EXCLUDE] == psf->sf_count[MCAST_EXCLUDE]; case MLD2_ALLOW_NEW_SOURCES: if (gdeleted || !psf->sf_crcount) - return 0; + return false; return (pmc->mca_sfmode == MCAST_INCLUDE) ^ sdeleted; case MLD2_BLOCK_OLD_SOURCES: if (pmc->mca_sfmode == MCAST_INCLUDE) return gdeleted || (psf->sf_crcount && sdeleted); return psf->sf_crcount && !gdeleted && !sdeleted; } - return 0; + return false; } static int @@ -2627,8 +2627,7 @@ err = inet_ctl_sock_create(&net->ipv6.igmp_sk, PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, net); if (err < 0) { - printk(KERN_ERR - "Failed to initialize the IGMP6 control socket (err %d).\n", + pr_err("Failed to initialize the IGMP6 control socket (err %d)\n", err); goto out; }
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c index 7e1e0fb..5b087c3 100644 --- a/net/ipv6/mip6.c +++ b/net/ipv6/mip6.c
@@ -22,6 +22,8 @@ * Masahide NAKAMURA @USAGI */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/skbuff.h> #include <linux/time.h> @@ -44,7 +46,7 @@ if (!data) return NULL; if (padlen == 1) { - data[0] = IPV6_TLV_PAD0; + data[0] = IPV6_TLV_PAD1; } else if (padlen > 1) { data[0] = IPV6_TLV_PADN; data[1] = padlen - 2; @@ -307,13 +309,12 @@ static int mip6_destopt_init_state(struct xfrm_state *x) { if (x->id.spi) { - printk(KERN_INFO "%s: spi is not 0: %u\n", __func__, - x->id.spi); + pr_info("%s: spi is not 0: %u\n", __func__, x->id.spi); return -EINVAL; } if (x->props.mode != XFRM_MODE_ROUTEOPTIMIZATION) { - printk(KERN_INFO "%s: state's mode is not %u: %u\n", - __func__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode); + pr_info("%s: state's mode is not %u: %u\n", + __func__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode); return -EINVAL; } @@ -443,13 +444,12 @@ static int mip6_rthdr_init_state(struct xfrm_state *x) { if (x->id.spi) { - printk(KERN_INFO "%s: spi is not 0: %u\n", __func__, - x->id.spi); + pr_info("%s: spi is not 0: %u\n", __func__, x->id.spi); return -EINVAL; } if (x->props.mode != XFRM_MODE_ROUTEOPTIMIZATION) { - printk(KERN_INFO "%s: state's mode is not %u: %u\n", - __func__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode); + pr_info("%s: state's mode is not %u: %u\n", + __func__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode); return -EINVAL; } @@ -481,18 +481,18 @@ static int __init mip6_init(void) { - printk(KERN_INFO "Mobile IPv6\n"); + pr_info("Mobile IPv6\n"); if (xfrm_register_type(&mip6_destopt_type, AF_INET6) < 0) { - printk(KERN_INFO "%s: can't add xfrm type(destopt)\n", __func__); + pr_info("%s: can't add xfrm type(destopt)\n", __func__); goto mip6_destopt_xfrm_fail; } if (xfrm_register_type(&mip6_rthdr_type, AF_INET6) < 0) { - printk(KERN_INFO "%s: can't add xfrm type(rthdr)\n", __func__); + pr_info("%s: can't add xfrm type(rthdr)\n", __func__); goto mip6_rthdr_xfrm_fail; } if (rawv6_mh_filter_register(mip6_mh_filter) < 0) { - printk(KERN_INFO "%s: can't add rawv6 mh filter\n", __func__); + pr_info("%s: can't add rawv6 mh filter\n", __func__); goto mip6_rawv6_mh_fail; } @@ -510,11 +510,11 @@ static void __exit mip6_fini(void) { if (rawv6_mh_filter_unregister(mip6_mh_filter) < 0) - printk(KERN_INFO "%s: can't remove rawv6 mh filter\n", __func__); + pr_info("%s: can't remove rawv6 mh filter\n", __func__); if (xfrm_unregister_type(&mip6_rthdr_type, AF_INET6) < 0) - printk(KERN_INFO "%s: can't remove xfrm type(rthdr)\n", __func__); + pr_info("%s: can't remove xfrm type(rthdr)\n", __func__); if (xfrm_unregister_type(&mip6_destopt_type, AF_INET6) < 0) - printk(KERN_INFO "%s: can't remove xfrm type(destopt)\n", __func__); + pr_info("%s: can't remove xfrm type(destopt)\n", __func__); } module_init(mip6_init);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 35615c6..54f62d3 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c
@@ -27,27 +27,7 @@ * YOSHIFUJI Hideaki @USAGI : Verify ND options properly */ -/* Set to 3 to get tracing... */ -#define ND_DEBUG 1 - -#define ND_PRINTK(fmt, args...) do { if (net_ratelimit()) { printk(fmt, ## args); } } while(0) -#define ND_NOPRINTK(x...) do { ; } while(0) -#define ND_PRINTK0 ND_PRINTK -#define ND_PRINTK1 ND_NOPRINTK -#define ND_PRINTK2 ND_NOPRINTK -#define ND_PRINTK3 ND_NOPRINTK -#if ND_DEBUG >= 1 -#undef ND_PRINTK1 -#define ND_PRINTK1 ND_PRINTK -#endif -#if ND_DEBUG >= 2 -#undef ND_PRINTK2 -#define ND_PRINTK2 ND_PRINTK -#endif -#if ND_DEBUG >= 3 -#undef ND_PRINTK3 -#define ND_PRINTK3 ND_PRINTK -#endif +#define pr_fmt(fmt) "ICMPv6: " fmt #include <linux/module.h> #include <linux/errno.h> @@ -92,6 +72,15 @@ #include <linux/netfilter.h> #include <linux/netfilter_ipv6.h> +/* Set to 3 to get tracing... */ +#define ND_DEBUG 1 + +#define ND_PRINTK(val, level, fmt, ...) \ +do { \ + if (val <= ND_DEBUG) \ + net_##level##_ratelimited(fmt, ##__VA_ARGS__); \ +} while (0) + static u32 ndisc_hash(const void *pkey, const struct net_device *dev, __u32 *hash_rnd); @@ -265,10 +254,9 @@ case ND_OPT_MTU: case ND_OPT_REDIRECT_HDR: if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) { - ND_PRINTK2(KERN_WARNING - "%s(): duplicated ND6 option found: type=%d\n", - __func__, - nd_opt->nd_opt_type); + ND_PRINTK(2, warn, + "%s: duplicated ND6 option found: type=%d\n", + __func__, nd_opt->nd_opt_type); } else { ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt; } @@ -296,10 +284,11 @@ * to accommodate future extension to the * protocol. */ - ND_PRINTK2(KERN_NOTICE - "%s(): ignored unsupported option; type=%d, len=%d\n", - __func__, - nd_opt->nd_opt_type, nd_opt->nd_opt_len); + ND_PRINTK(2, notice, + "%s: ignored unsupported option; type=%d, len=%d\n", + __func__, + nd_opt->nd_opt_type, + nd_opt->nd_opt_len); } } opt_len -= l; @@ -327,9 +316,6 @@ case ARPHRD_FDDI: ipv6_eth_mc_map(addr, buf); return 0; - case ARPHRD_IEEE802_TR: - ipv6_tr_mc_map(addr,buf); - return 0; case ARPHRD_ARCNET: ipv6_arcnet_mc_map(addr, buf); return 0; @@ -362,7 +348,7 @@ struct net_device *dev = neigh->dev; struct inet6_dev *in6_dev; struct neigh_parms *parms; - int is_multicast = ipv6_addr_is_multicast(addr); + bool is_multicast = ipv6_addr_is_multicast(addr); in6_dev = in6_dev_get(dev); if (in6_dev == NULL) { @@ -458,9 +444,8 @@ len + hlen + tlen), 1, &err); if (!skb) { - ND_PRINTK0(KERN_ERR - "ICMPv6 ND: %s() failed to allocate an skb, err=%d.\n", - __func__, err); + ND_PRINTK(0, err, "ND: %s failed to allocate an skb, err=%d\n", + __func__, err); return NULL; } @@ -696,8 +681,9 @@ if ((probes -= neigh->parms->ucast_probes) < 0) { if (!(neigh->nud_state & NUD_VALID)) { - ND_PRINTK1(KERN_DEBUG "%s(): trying to ucast probe in NUD_INVALID: %pI6\n", - __func__, target); + ND_PRINTK(1, dbg, + "%s: trying to ucast probe in NUD_INVALID: %pI6\n", + __func__, target); } ndisc_send_ns(dev, neigh, target, target, saddr); } else if ((probes -= neigh->parms->app_probes) < 0) { @@ -739,12 +725,11 @@ struct inet6_dev *idev = NULL; struct neighbour *neigh; int dad = ipv6_addr_any(saddr); - int inc; + bool inc; int is_router = -1; if (ipv6_addr_is_multicast(&msg->target)) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 NS: multicast target address"); + ND_PRINTK(2, warn, "NS: multicast target address\n"); return; } @@ -757,22 +742,20 @@ daddr->s6_addr32[1] == htonl(0x00000000) && daddr->s6_addr32[2] == htonl(0x00000001) && daddr->s6_addr [12] == 0xff )) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 NS: bad DAD packet (wrong destination)\n"); + ND_PRINTK(2, warn, "NS: bad DAD packet (wrong destination)\n"); return; } if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 NS: invalid ND options\n"); + ND_PRINTK(2, warn, "NS: invalid ND options\n"); return; } if (ndopts.nd_opts_src_lladdr) { lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr, dev); if (!lladdr) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 NS: invalid link-layer address length\n"); + ND_PRINTK(2, warn, + "NS: invalid link-layer address length\n"); return; } @@ -782,8 +765,8 @@ * in the message. */ if (dad) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 NS: bad DAD packet (link-layer address option)\n"); + ND_PRINTK(2, warn, + "NS: bad DAD packet (link-layer address option)\n"); return; } } @@ -795,20 +778,6 @@ if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) { if (dad) { - if (dev->type == ARPHRD_IEEE802_TR) { - const unsigned char *sadr; - sadr = skb_mac_header(skb); - if (((sadr[8] ^ dev->dev_addr[0]) & 0x7f) == 0 && - sadr[9] == dev->dev_addr[1] && - sadr[10] == dev->dev_addr[2] && - sadr[11] == dev->dev_addr[3] && - sadr[12] == dev->dev_addr[4] && - sadr[13] == dev->dev_addr[5]) { - /* looped-back to us */ - goto out; - } - } - /* * We are colliding with another node * who is doing DAD @@ -915,34 +884,30 @@ struct neighbour *neigh; if (skb->len < sizeof(struct nd_msg)) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 NA: packet too short\n"); + ND_PRINTK(2, warn, "NA: packet too short\n"); return; } if (ipv6_addr_is_multicast(&msg->target)) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 NA: target address is multicast.\n"); + ND_PRINTK(2, warn, "NA: target address is multicast\n"); return; } if (ipv6_addr_is_multicast(daddr) && msg->icmph.icmp6_solicited) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 NA: solicited NA is multicasted.\n"); + ND_PRINTK(2, warn, "NA: solicited NA is multicasted\n"); return; } if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 NS: invalid ND option\n"); + ND_PRINTK(2, warn, "NS: invalid ND option\n"); return; } if (ndopts.nd_opts_tgt_lladdr) { lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr, dev); if (!lladdr) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 NA: invalid link-layer address length\n"); + ND_PRINTK(2, warn, + "NA: invalid link-layer address length\n"); return; } } @@ -963,9 +928,9 @@ unsolicited advertisement. */ if (skb->pkt_type != PACKET_LOOPBACK) - ND_PRINTK1(KERN_WARNING - "ICMPv6 NA: someone advertises our address %pI6 on %s!\n", - &ifp->addr, ifp->idev->dev->name); + ND_PRINTK(1, warn, + "NA: someone advertises our address %pI6 on %s!\n", + &ifp->addr, ifp->idev->dev->name); in6_ifa_put(ifp); return; } @@ -1027,8 +992,7 @@ idev = __in6_dev_get(skb->dev); if (!idev) { - if (net_ratelimit()) - ND_PRINTK1("ICMP6 RS: can't find in6 device\n"); + ND_PRINTK(1, err, "RS: can't find in6 device\n"); return; } @@ -1045,8 +1009,7 @@ /* Parse ND options */ if (!ndisc_parse_options(rs_msg->opt, ndoptlen, &ndopts)) { - if (net_ratelimit()) - ND_PRINTK2("ICMP6 NS: invalid ND option, ignored\n"); + ND_PRINTK(2, notice, "NS: invalid ND option, ignored\n"); goto out; } @@ -1144,20 +1107,17 @@ optlen = (skb->tail - skb->transport_header) - sizeof(struct ra_msg); if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 RA: source address is not link-local.\n"); + ND_PRINTK(2, warn, "RA: source address is not link-local\n"); return; } if (optlen < 0) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 RA: packet too short\n"); + ND_PRINTK(2, warn, "RA: packet too short\n"); return; } #ifdef CONFIG_IPV6_NDISC_NODETYPE if (skb->ndisc_nodetype == NDISC_NODETYPE_HOST) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 RA: from host or unauthorized router\n"); + ND_PRINTK(2, warn, "RA: from host or unauthorized router\n"); return; } #endif @@ -1168,15 +1128,13 @@ in6_dev = __in6_dev_get(skb->dev); if (in6_dev == NULL) { - ND_PRINTK0(KERN_ERR - "ICMPv6 RA: can't find inet6 device for %s.\n", - skb->dev->name); + ND_PRINTK(0, err, "RA: can't find inet6 device for %s\n", + skb->dev->name); return; } if (!ndisc_parse_options(opt, optlen, &ndopts)) { - ND_PRINTK2(KERN_WARNING - "ICMP6 RA: invalid ND options\n"); + ND_PRINTK(2, warn, "RA: invalid ND options\n"); return; } @@ -1229,9 +1187,9 @@ if (rt) { neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr); if (!neigh) { - ND_PRINTK0(KERN_ERR - "ICMPv6 RA: %s() got default router without neighbour.\n", - __func__); + ND_PRINTK(0, err, + "RA: %s got default router without neighbour\n", + __func__); dst_release(&rt->dst); return; } @@ -1242,22 +1200,21 @@ } if (rt == NULL && lifetime) { - ND_PRINTK3(KERN_DEBUG - "ICMPv6 RA: adding default router.\n"); + ND_PRINTK(3, dbg, "RA: adding default router\n"); rt = rt6_add_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev, pref); if (rt == NULL) { - ND_PRINTK0(KERN_ERR - "ICMPv6 RA: %s() failed to add default route.\n", - __func__); + ND_PRINTK(0, err, + "RA: %s failed to add default route\n", + __func__); return; } neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr); if (neigh == NULL) { - ND_PRINTK0(KERN_ERR - "ICMPv6 RA: %s() got default router without neighbour.\n", - __func__); + ND_PRINTK(0, err, + "RA: %s got default router without neighbour\n", + __func__); dst_release(&rt->dst); return; } @@ -1325,8 +1282,8 @@ lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr, skb->dev); if (!lladdr) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 RA: invalid link-layer address length\n"); + ND_PRINTK(2, warn, + "RA: invalid link-layer address length\n"); goto out; } } @@ -1390,9 +1347,7 @@ mtu = ntohl(n); if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 RA: invalid mtu: %d\n", - mtu); + ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu); } else if (in6_dev->cnf.mtu6 != mtu) { in6_dev->cnf.mtu6 = mtu; @@ -1413,8 +1368,7 @@ } if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 RA: invalid RA options"); + ND_PRINTK(2, warn, "RA: invalid RA options\n"); } out: if (rt) @@ -1439,15 +1393,15 @@ switch (skb->ndisc_nodetype) { case NDISC_NODETYPE_HOST: case NDISC_NODETYPE_NODEFAULT: - ND_PRINTK2(KERN_WARNING - "ICMPv6 Redirect: from host or unauthorized router\n"); + ND_PRINTK(2, warn, + "Redirect: from host or unauthorized router\n"); return; } #endif if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 Redirect: source address is not link-local.\n"); + ND_PRINTK(2, warn, + "Redirect: source address is not link-local\n"); return; } @@ -1455,8 +1409,7 @@ optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr); if (optlen < 0) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 Redirect: packet too short\n"); + ND_PRINTK(2, warn, "Redirect: packet too short\n"); return; } @@ -1465,8 +1418,8 @@ dest = target + 1; if (ipv6_addr_is_multicast(dest)) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 Redirect: destination address is multicast.\n"); + ND_PRINTK(2, warn, + "Redirect: destination address is multicast\n"); return; } @@ -1474,8 +1427,8 @@ on_link = 1; } else if (ipv6_addr_type(target) != (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 Redirect: target address is not link-local unicast.\n"); + ND_PRINTK(2, warn, + "Redirect: target address is not link-local unicast\n"); return; } @@ -1491,16 +1444,15 @@ */ if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 Redirect: invalid ND options\n"); + ND_PRINTK(2, warn, "Redirect: invalid ND options\n"); return; } if (ndopts.nd_opts_tgt_lladdr) { lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr, skb->dev); if (!lladdr) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 Redirect: invalid link-layer address length\n"); + ND_PRINTK(2, warn, + "Redirect: invalid link-layer address length\n"); return; } } @@ -1535,16 +1487,15 @@ u8 ha_buf[MAX_ADDR_LEN], *ha = NULL; if (ipv6_get_lladdr(dev, &saddr_buf, IFA_F_TENTATIVE)) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 Redirect: no link-local address on %s\n", - dev->name); + ND_PRINTK(2, warn, "Redirect: no link-local address on %s\n", + dev->name); return; } if (!ipv6_addr_equal(&ipv6_hdr(skb)->daddr, target) && ipv6_addr_type(target) != (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 Redirect: target address is not link-local unicast.\n"); + ND_PRINTK(2, warn, + "Redirect: target address is not link-local unicast\n"); return; } @@ -1563,8 +1514,8 @@ rt = (struct rt6_info *) dst; if (rt->rt6i_flags & RTF_GATEWAY) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 Redirect: destination is not a neighbour.\n"); + ND_PRINTK(2, warn, + "Redirect: destination is not a neighbour\n"); goto release; } if (!rt->rt6i_peer) @@ -1575,8 +1526,8 @@ if (dev->addr_len) { struct neighbour *neigh = dst_neigh_lookup(skb_dst(skb), target); if (!neigh) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 Redirect: no neigh for target address\n"); + ND_PRINTK(2, warn, + "Redirect: no neigh for target address\n"); goto release; } @@ -1604,9 +1555,9 @@ len + hlen + tlen), 1, &err); if (buff == NULL) { - ND_PRINTK0(KERN_ERR - "ICMPv6 Redirect: %s() failed to allocate an skb, err=%d.\n", - __func__, err); + ND_PRINTK(0, err, + "Redirect: %s failed to allocate an skb, err=%d\n", + __func__, err); goto release; } @@ -1691,16 +1642,14 @@ __skb_push(skb, skb->data - skb_transport_header(skb)); if (ipv6_hdr(skb)->hop_limit != 255) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 NDISC: invalid hop-limit: %d\n", - ipv6_hdr(skb)->hop_limit); + ND_PRINTK(2, warn, "NDISC: invalid hop-limit: %d\n", + ipv6_hdr(skb)->hop_limit); return 0; } if (msg->icmph.icmp6_code != 0) { - ND_PRINTK2(KERN_WARNING - "ICMPv6 NDISC: invalid ICMPv6 code: %d\n", - msg->icmph.icmp6_code); + ND_PRINTK(2, warn, "NDISC: invalid ICMPv6 code: %d\n", + msg->icmph.icmp6_code); return 0; } @@ -1767,11 +1716,7 @@ static int warned; if (strcmp(warncomm, current->comm) && warned < 5) { strcpy(warncomm, current->comm); - printk(KERN_WARNING - "process `%s' is using deprecated sysctl (%s) " - "net.ipv6.neigh.%s.%s; " - "Use net.ipv6.neigh.%s.%s_ms " - "instead.\n", + pr_warn("process `%s' is using deprecated sysctl (%s) net.ipv6.neigh.%s.%s - use net.ipv6.neigh.%s.%s_ms instead\n", warncomm, func, dev_name, ctl->procname, dev_name, ctl->procname); @@ -1825,9 +1770,9 @@ err = inet_ctl_sock_create(&sk, PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, net); if (err < 0) { - ND_PRINTK0(KERN_ERR - "ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n", - err); + ND_PRINTK(0, err, + "NDISC: Failed to initialize the control socket (err %d)\n", + err); return err; }
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index d4e350f..d7cb045 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c
@@ -133,7 +133,7 @@ int protohdr; unsigned short _frag_off; - protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off); + protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off, NULL); if (protohdr < 0) { if (_frag_off == 0) *hotdrop = true; @@ -181,8 +181,7 @@ static unsigned int ip6t_error(struct sk_buff *skb, const struct xt_action_param *par) { - if (net_ratelimit()) - pr_info("error: `%s'\n", (const char *)par->targinfo); + net_info_ratelimited("error: `%s'\n", (const char *)par->targinfo); return NF_DROP; } @@ -362,6 +361,7 @@ const struct xt_entry_match *ematch; IP_NF_ASSERT(e); + acpar.thoff = 0; if (!ip6_packet_match(skb, indev, outdev, &e->ipv6, &acpar.thoff, &acpar.fragoff, &acpar.hotdrop)) { no_match: @@ -2278,6 +2278,10 @@ * if target < 0. "last header" is transport protocol header, ESP, or * "No next header". * + * Note that *offset is used as input/output parameter. an if it is not zero, + * then it must be a valid offset to an inner IPv6 header. This can be used + * to explore inner IPv6 header, eg. ICMPv6 error messages. + * * If target header is found, its offset is set in *offset and return protocol * number. Otherwise, return -1. * @@ -2289,17 +2293,33 @@ * *offset is meaningless and fragment offset is stored in *fragoff if fragoff * isn't NULL. * + * if flags is not NULL and it's a fragment, then the frag flag IP6T_FH_F_FRAG + * will be set. If it's an AH header, the IP6T_FH_F_AUTH flag is set and + * target < 0, then this function will stop at the AH header. */ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, - int target, unsigned short *fragoff) + int target, unsigned short *fragoff, int *flags) { unsigned int start = skb_network_offset(skb) + sizeof(struct ipv6hdr); u8 nexthdr = ipv6_hdr(skb)->nexthdr; - unsigned int len = skb->len - start; + unsigned int len; if (fragoff) *fragoff = 0; + if (*offset) { + struct ipv6hdr _ip6, *ip6; + + ip6 = skb_header_pointer(skb, *offset, sizeof(_ip6), &_ip6); + if (!ip6 || (ip6->version != 6)) { + printk(KERN_ERR "IPv6 header not found\n"); + return -EBADMSG; + } + start = *offset + sizeof(struct ipv6hdr); + nexthdr = ip6->nexthdr; + } + len = skb->len - start; + while (nexthdr != target) { struct ipv6_opt_hdr _hdr, *hp; unsigned int hdrlen; @@ -2316,6 +2336,9 @@ if (nexthdr == NEXTHDR_FRAGMENT) { unsigned short _frag_off; __be16 *fp; + + if (flags) /* Indicate that this is a fragment */ + *flags |= IP6T_FH_F_FRAG; fp = skb_header_pointer(skb, start+offsetof(struct frag_hdr, frag_off), @@ -2336,9 +2359,11 @@ return -ENOENT; } hdrlen = 8; - } else if (nexthdr == NEXTHDR_AUTH) + } else if (nexthdr == NEXTHDR_AUTH) { + if (flags && (*flags & IP6T_FH_F_AUTH) && (target < 0)) + break; hdrlen = (hp->hdrlen + 2) << 2; - else + } else hdrlen = ipv6_optlen(hp); nexthdr = hp->nexthdr;
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index aad2fa41..fd4fb34 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -114,8 +114,7 @@ GFP_ATOMIC); if (!nskb) { - if (net_ratelimit()) - pr_debug("cannot alloc skb\n"); + net_dbg_ratelimited("cannot alloc skb\n"); dst_release(dst); return; } @@ -210,8 +209,7 @@ send_reset(net, skb); break; default: - if (net_ratelimit()) - pr_info("case %u not handled yet\n", reject->with); + net_info_ratelimited("case %u not handled yet\n", reject->with); break; }
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c index 89cccc5..04099ab 100644 --- a/net/ipv6/netfilter/ip6t_ah.c +++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -41,11 +41,11 @@ struct ip_auth_hdr _ah; const struct ip_auth_hdr *ah; const struct ip6t_ah *ahinfo = par->matchinfo; - unsigned int ptr; + unsigned int ptr = 0; unsigned int hdrlen = 0; int err; - err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL); + err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL, NULL); if (err < 0) { if (err != -ENOENT) par->hotdrop = true;
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c index eda898f..3b5735e 100644 --- a/net/ipv6/netfilter/ip6t_frag.c +++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -40,10 +40,10 @@ struct frag_hdr _frag; const struct frag_hdr *fh; const struct ip6t_frag *fraginfo = par->matchinfo; - unsigned int ptr; + unsigned int ptr = 0; int err; - err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL); + err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL, NULL); if (err < 0) { if (err != -ENOENT) par->hotdrop = true;
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c index 59df051..01df142 100644 --- a/net/ipv6/netfilter/ip6t_hbh.c +++ b/net/ipv6/netfilter/ip6t_hbh.c
@@ -50,7 +50,7 @@ const struct ipv6_opt_hdr *oh; const struct ip6t_opts *optinfo = par->matchinfo; unsigned int temp; - unsigned int ptr; + unsigned int ptr = 0; unsigned int hdrlen = 0; bool ret = false; u8 _opttype; @@ -62,7 +62,7 @@ err = ipv6_find_hdr(skb, &ptr, (par->match == &hbh_mt6_reg[0]) ? - NEXTHDR_HOP : NEXTHDR_DEST, NULL); + NEXTHDR_HOP : NEXTHDR_DEST, NULL, NULL); if (err < 0) { if (err != -ENOENT) par->hotdrop = true;
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c index d8488c5..2c99b94 100644 --- a/net/ipv6/netfilter/ip6t_rt.c +++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -42,14 +42,14 @@ const struct ipv6_rt_hdr *rh; const struct ip6t_rt *rtinfo = par->matchinfo; unsigned int temp; - unsigned int ptr; + unsigned int ptr = 0; unsigned int hdrlen = 0; bool ret = false; struct in6_addr _addr; const struct in6_addr *ap; int err; - err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL); + err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL, NULL); if (err < 0) { if (err != -ENOENT) par->hotdrop = true;
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index 00d1917..4d78240 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -42,8 +42,7 @@ /* root is playing with raw sockets. */ if (skb->len < sizeof(struct iphdr) || ip_hdrlen(skb) < sizeof(struct iphdr)) { - if (net_ratelimit()) - pr_warning("ip6t_hook: happy cracking.\n"); + net_warn_ratelimited("ip6t_hook: happy cracking\n"); return NF_ACCEPT; } #endif
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index fe925e4..3224ef9 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -232,8 +232,7 @@ { /* root is playing with raw sockets. */ if (skb->len < sizeof(struct ipv6hdr)) { - if (net_ratelimit()) - pr_notice("ipv6_conntrack_local: packet too short\n"); + net_notice_ratelimited("ipv6_conntrack_local: packet too short\n"); return NF_ACCEPT; } return __ipv6_conntrack_in(dev_net(out), hooknum, skb, okfn);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 48a2be1..c9c78c2 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -444,12 +444,11 @@ return head; out_oversize: - if (net_ratelimit()) - printk(KERN_DEBUG "nf_ct_frag6_reasm: payload len = %d\n", payload_len); + net_dbg_ratelimited("nf_ct_frag6_reasm: payload len = %d\n", + payload_len); goto out_fail; out_oom: - if (net_ratelimit()) - printk(KERN_DEBUG "nf_ct_frag6_reasm: no memory for reassembly\n"); + net_dbg_ratelimited("nf_ct_frag6_reasm: no memory for reassembly\n"); out_fail: return NULL; }
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 5bddea7..93d6983 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c
@@ -72,7 +72,7 @@ const struct in6_addr *rmt_addr, int dif) { struct hlist_node *node; - int is_multicast = ipv6_addr_is_multicast(loc_addr); + bool is_multicast = ipv6_addr_is_multicast(loc_addr); sk_for_each_from(sk, node) if (inet_sk(sk)->inet_num == num) { @@ -153,12 +153,12 @@ * * Caller owns SKB so we must make clones. */ -static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) +static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) { const struct in6_addr *saddr; const struct in6_addr *daddr; struct sock *sk; - int delivered = 0; + bool delivered = false; __u8 hash; struct net *net; @@ -179,7 +179,7 @@ while (sk) { int filtered; - delivered = 1; + delivered = true; switch (nexthdr) { case IPPROTO_ICMPV6: filtered = icmpv6_filter(sk, skb); @@ -225,7 +225,7 @@ return delivered; } -int raw6_local_deliver(struct sk_buff *skb, int nexthdr) +bool raw6_local_deliver(struct sk_buff *skb, int nexthdr) { struct sock *raw_sk;
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 54c5d2b..4ff9af6 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c
@@ -134,15 +134,16 @@ return inet6_hash_frag(fq->id, &fq->saddr, &fq->daddr, ip6_frags.rnd); } -int ip6_frag_match(struct inet_frag_queue *q, void *a) +bool ip6_frag_match(struct inet_frag_queue *q, void *a) { struct frag_queue *fq; struct ip6_create_arg *arg = a; fq = container_of(q, struct frag_queue, q); - return (fq->id == arg->id && fq->user == arg->user && - ipv6_addr_equal(&fq->saddr, arg->src) && - ipv6_addr_equal(&fq->daddr, arg->dst)); + return fq->id == arg->id && + fq->user == arg->user && + ipv6_addr_equal(&fq->saddr, arg->src) && + ipv6_addr_equal(&fq->daddr, arg->dst); } EXPORT_SYMBOL(ip6_frag_match); @@ -414,6 +415,7 @@ struct sk_buff *fp, *head = fq->q.fragments; int payload_len; unsigned int nhoff; + int sum_truesize; fq_kill(fq); @@ -483,20 +485,33 @@ head->mac_header += sizeof(struct frag_hdr); head->network_header += sizeof(struct frag_hdr); - skb_shinfo(head)->frag_list = head->next; skb_reset_transport_header(head); skb_push(head, head->data - skb_network_header(head)); - for (fp=head->next; fp; fp = fp->next) { - head->data_len += fp->len; - head->len += fp->len; + sum_truesize = head->truesize; + for (fp = head->next; fp;) { + bool headstolen; + int delta; + struct sk_buff *next = fp->next; + + sum_truesize += fp->truesize; if (head->ip_summed != fp->ip_summed) head->ip_summed = CHECKSUM_NONE; else if (head->ip_summed == CHECKSUM_COMPLETE) head->csum = csum_add(head->csum, fp->csum); - head->truesize += fp->truesize; + + if (skb_try_coalesce(head, fp, &headstolen, &delta)) { + kfree_skb_partial(fp, headstolen); + } else { + if (!skb_shinfo(head)->frag_list) + skb_shinfo(head)->frag_list = fp; + head->data_len += fp->len; + head->len += fp->len; + head->truesize += fp->truesize; + } + fp = next; } - atomic_sub(head->truesize, &fq->q.net->mem); + atomic_sub(sum_truesize, &fq->q.net->mem); head->next = NULL; head->dev = dev; @@ -518,12 +533,10 @@ return 1; out_oversize: - if (net_ratelimit()) - printk(KERN_DEBUG "ip6_frag_reasm: payload len = %d\n", payload_len); + net_dbg_ratelimited("ip6_frag_reasm: payload len = %d\n", payload_len); goto out_fail; out_oom: - if (net_ratelimit()) - printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n"); + net_dbg_ratelimited("ip6_frag_reasm: no memory for reassembly\n"); out_fail: rcu_read_lock(); IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 0aefc36..999a982 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c
@@ -24,6 +24,8 @@ * Fixed routing subtrees. */ +#define pr_fmt(fmt) "IPv6: " fmt + #include <linux/capability.h> #include <linux/errno.h> #include <linux/export.h> @@ -331,22 +333,22 @@ } } -static __inline__ int rt6_check_expired(const struct rt6_info *rt) +static bool rt6_check_expired(const struct rt6_info *rt) { struct rt6_info *ort = NULL; if (rt->rt6i_flags & RTF_EXPIRES) { if (time_after(jiffies, rt->dst.expires)) - return 1; + return true; } else if (rt->dst.from) { ort = (struct rt6_info *) rt->dst.from; return (ort->rt6i_flags & RTF_EXPIRES) && time_after(jiffies, ort->dst.expires); } - return 0; + return false; } -static inline int rt6_need_strict(const struct in6_addr *daddr) +static bool rt6_need_strict(const struct in6_addr *daddr) { return ipv6_addr_type(daddr) & (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); @@ -794,9 +796,7 @@ goto retry; } - if (net_ratelimit()) - printk(KERN_WARNING - "ipv6: Neighbour table overflow.\n"); + net_warn_ratelimited("Neighbour table overflow\n"); dst_free(&rt->dst); return NULL; } @@ -1282,7 +1282,7 @@ !(cfg->fc_nlinfo.nlh->nlmsg_flags & NLM_F_CREATE)) { table = fib6_get_table(net, cfg->fc_table); if (!table) { - printk(KERN_WARNING "IPv6: NLM_F_CREATE should be specified when creating new route\n"); + pr_warn("NLM_F_CREATE should be specified when creating new route\n"); table = fib6_new_table(net, cfg->fc_table); } } else { @@ -1643,9 +1643,7 @@ rt = ip6_route_redirect(dest, src, saddr, neigh->dev); if (rt == net->ipv6.ip6_null_entry) { - if (net_ratelimit()) - printk(KERN_DEBUG "rt6_redirect: source isn't a valid nexthop " - "for redirect target\n"); + net_dbg_ratelimited("rt6_redirect: source isn't a valid nexthop for redirect target\n"); goto out; } @@ -2106,9 +2104,7 @@ int err; if (!rt) { - if (net_ratelimit()) - pr_warning("IPv6: Maximum number of routes reached," - " consider increasing route/max_size.\n"); + net_warn_ratelimited("Maximum number of routes reached, consider increasing route/max_size\n"); return ERR_PTR(-ENOMEM); }
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index e5fef943..6041571 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c
@@ -17,6 +17,8 @@ * Fred Templin <fred.l.templin@boeing.com>: isatap support */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/capability.h> #include <linux/errno.h> @@ -702,8 +704,7 @@ neigh = dst_neigh_lookup(skb_dst(skb), &iph6->daddr); if (neigh == NULL) { - if (net_ratelimit()) - printk(KERN_DEBUG "sit: nexthop == NULL\n"); + net_dbg_ratelimited("sit: nexthop == NULL\n"); goto tx_error; } @@ -732,8 +733,7 @@ neigh = dst_neigh_lookup(skb_dst(skb), &iph6->daddr); if (neigh == NULL) { - if (net_ratelimit()) - printk(KERN_DEBUG "sit: nexthop == NULL\n"); + net_dbg_ratelimited("sit: nexthop == NULL\n"); goto tx_error; } @@ -1303,7 +1303,7 @@ { int err; - printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n"); + pr_info("IPv6 over IPv4 tunneling driver\n"); err = register_pernet_device(&sit_net_ops); if (err < 0) @@ -1311,7 +1311,7 @@ err = xfrm4_tunnel_register(&sit_handler, AF_INET6); if (err < 0) { unregister_pernet_device(&sit_net_ops); - printk(KERN_INFO "sit init: Can't add protocol\n"); + pr_info("%s: can't add protocol\n", __func__); } return err; }
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 078d039..554d599 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c
@@ -723,12 +723,10 @@ NULL, NULL, skb); if (genhash || memcmp(hash_location, newhash, 16) != 0) { - if (net_ratelimit()) { - printk(KERN_INFO "MD5 Hash %s for [%pI6c]:%u->[%pI6c]:%u\n", - genhash ? "failed" : "mismatch", - &ip6h->saddr, ntohs(th->source), - &ip6h->daddr, ntohs(th->dest)); - } + net_info_ratelimited("MD5 Hash %s for [%pI6c]:%u->[%pI6c]:%u\n", + genhash ? "failed" : "mismatch", + &ip6h->saddr, ntohs(th->source), + &ip6h->daddr, ntohs(th->dest)); return 1; } return 0; @@ -1057,7 +1055,7 @@ struct tcp_sock *tp = tcp_sk(sk); __u32 isn = TCP_SKB_CB(skb)->when; struct dst_entry *dst = NULL; - int want_cookie = 0; + bool want_cookie = false; if (skb->protocol == htons(ETH_P_IP)) return tcp_v4_conn_request(sk, skb); @@ -1118,7 +1116,7 @@ while (l-- > 0) *c++ ^= *hash_location++; - want_cookie = 0; /* not our kind of cookie */ + want_cookie = false; /* not our kind of cookie */ tmp_ext.cookie_out_never = 0; /* false */ tmp_ext.cookie_plus = tmp_opt.cookie_plus; } else if (!tp->rx_opt.cookie_in_always) {
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c index 4f3cec1..4b0f50d 100644 --- a/net/ipv6/tunnel6.c +++ b/net/ipv6/tunnel6.c
@@ -19,6 +19,8 @@ * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> */ +#define pr_fmt(fmt) "IPv6: " fmt + #include <linux/icmpv6.h> #include <linux/init.h> #include <linux/module.h> @@ -160,11 +162,11 @@ static int __init tunnel6_init(void) { if (inet6_add_protocol(&tunnel6_protocol, IPPROTO_IPV6)) { - printk(KERN_ERR "tunnel6 init(): can't add protocol\n"); + pr_err("%s: can't add protocol\n", __func__); return -EAGAIN; } if (inet6_add_protocol(&tunnel46_protocol, IPPROTO_IPIP)) { - printk(KERN_ERR "tunnel6 init(): can't add protocol\n"); + pr_err("%s: can't add protocol\n", __func__); inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6); return -EAGAIN; } @@ -174,9 +176,9 @@ static void __exit tunnel6_fini(void) { if (inet6_del_protocol(&tunnel46_protocol, IPPROTO_IPIP)) - printk(KERN_ERR "tunnel6 close: can't remove protocol\n"); + pr_err("%s: can't remove protocol\n", __func__); if (inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6)) - printk(KERN_ERR "tunnel6 close: can't remove protocol\n"); + pr_err("%s: can't remove protocol\n", __func__); } module_init(tunnel6_init);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index c1d91a7..f05099f 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c
@@ -103,7 +103,7 @@ { unsigned int hash2_nulladdr = udp6_portaddr_hash(sock_net(sk), &in6addr_any, snum); - unsigned int hash2_partial = + unsigned int hash2_partial = udp6_portaddr_hash(sock_net(sk), &inet6_sk(sk)->rcv_saddr, 0); /* precompute partial secondary hash */ @@ -349,7 +349,7 @@ bool slow; if (addr_len) - *addr_len=sizeof(struct sockaddr_in6); + *addr_len = sizeof(struct sockaddr_in6); if (flags & MSG_ERRQUEUE) return ipv6_recv_error(sk, msg, len); @@ -1379,7 +1379,7 @@ * do checksum of UDP packets sent as multiple IP fragments. */ offset = skb_checksum_start_offset(skb); - csum = skb_checksum(skb, offset, skb->len- offset, 0); + csum = skb_checksum(skb, offset, skb->len - offset, 0); offset += skb->csum_offset; *(__sum16 *)(skb->data + offset) = csum_fold(csum); skb->ip_summed = CHECKSUM_NONE;
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 96802266..dfd6faa 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c
@@ -983,10 +983,6 @@ goto out; switch (idef->ipx_dlink_type) { - case IPX_FRAME_TR_8022: - printk(KERN_WARNING "IPX frame type 802.2TR is " - "obsolete Use 802.2 instead.\n"); - /* fall through */ case IPX_FRAME_8022: dlink_type = htons(ETH_P_802_2); datalink = p8022_datalink; @@ -996,10 +992,7 @@ dlink_type = htons(ETH_P_IPX); datalink = pEII_datalink; break; - } else - printk(KERN_WARNING "IPX frame type EtherII over " - "token-ring is obsolete. Use SNAP " - "instead.\n"); + } /* fall through */ case IPX_FRAME_SNAP: dlink_type = htons(ETH_P_SNAP); @@ -1275,7 +1268,6 @@ case ETH_P_802_2: rc = "802.2"; break; case ETH_P_SNAP: rc = "SNAP"; break; case ETH_P_802_3: rc = "802.3"; break; - case ETH_P_TR_802_2: rc = "802.2TR"; break; } return rc; @@ -1909,9 +1901,7 @@ (const unsigned short __user *)argp); break; case SIOCGSTAMP: - rc = -EINVAL; - if (sk) - rc = sock_get_timestamp(sk, argp); + rc = sock_get_timestamp(sk, argp); break; case SIOCGIFDSTADDR: case SIOCSIFDSTADDR:
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 456b52d..32b2155 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c
@@ -18,6 +18,8 @@ * published by the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/string.h> #include <linux/list.h> @@ -86,12 +88,6 @@ /* Default trace flags */ #define L2TP_DEFAULT_DEBUG_FLAGS 0 -#define PRINTK(_mask, _type, _lvl, _fmt, args...) \ - do { \ - if ((_mask) & (_type)) \ - printk(_lvl "L2TP: " _fmt, ##args); \ - } while (0) - /* Private data stored for received packets in the skb. */ struct l2tp_skb_cb { @@ -141,14 +137,20 @@ l2tp_tunnel_free(tunnel); } #ifdef L2TP_REFCNT_DEBUG -#define l2tp_tunnel_inc_refcount(_t) do { \ - printk(KERN_DEBUG "l2tp_tunnel_inc_refcount: %s:%d %s: cnt=%d\n", __func__, __LINE__, (_t)->name, atomic_read(&_t->ref_count)); \ - l2tp_tunnel_inc_refcount_1(_t); \ - } while (0) -#define l2tp_tunnel_dec_refcount(_t) do { \ - printk(KERN_DEBUG "l2tp_tunnel_dec_refcount: %s:%d %s: cnt=%d\n", __func__, __LINE__, (_t)->name, atomic_read(&_t->ref_count)); \ - l2tp_tunnel_dec_refcount_1(_t); \ - } while (0) +#define l2tp_tunnel_inc_refcount(_t) \ +do { \ + pr_debug("l2tp_tunnel_inc_refcount: %s:%d %s: cnt=%d\n", \ + __func__, __LINE__, (_t)->name, \ + atomic_read(&_t->ref_count)); \ + l2tp_tunnel_inc_refcount_1(_t); \ +} while (0) +#define l2tp_tunnel_dec_refcount(_t) +do { \ + pr_debug("l2tp_tunnel_dec_refcount: %s:%d %s: cnt=%d\n", \ + __func__, __LINE__, (_t)->name, \ + atomic_read(&_t->ref_count)); \ + l2tp_tunnel_dec_refcount_1(_t); \ +} while (0) #else #define l2tp_tunnel_inc_refcount(t) l2tp_tunnel_inc_refcount_1(t) #define l2tp_tunnel_dec_refcount(t) l2tp_tunnel_dec_refcount_1(t) @@ -337,10 +339,10 @@ skb_queue_walk_safe(&session->reorder_q, skbp, tmp) { if (L2TP_SKB_CB(skbp)->ns > ns) { __skb_queue_before(&session->reorder_q, skbp, skb); - PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, - "%s: pkt %hu, inserted before %hu, reorder_q len=%d\n", - session->name, ns, L2TP_SKB_CB(skbp)->ns, - skb_queue_len(&session->reorder_q)); + l2tp_dbg(session, L2TP_MSG_SEQ, + "%s: pkt %hu, inserted before %hu, reorder_q len=%d\n", + session->name, ns, L2TP_SKB_CB(skbp)->ns, + skb_queue_len(&session->reorder_q)); u64_stats_update_begin(&sstats->syncp); sstats->rx_oos_packets++; u64_stats_update_end(&sstats->syncp); @@ -386,8 +388,8 @@ else session->nr &= 0xffffff; - PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, - "%s: updated nr to %hu\n", session->name, session->nr); + l2tp_dbg(session, L2TP_MSG_SEQ, "%s: updated nr to %hu\n", + session->name, session->nr); } /* call private receive handler */ @@ -422,12 +424,12 @@ sstats->rx_seq_discards++; sstats->rx_errors++; u64_stats_update_end(&sstats->syncp); - PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, - "%s: oos pkt %u len %d discarded (too old), " - "waiting for %u, reorder_q_len=%d\n", - session->name, L2TP_SKB_CB(skb)->ns, - L2TP_SKB_CB(skb)->length, session->nr, - skb_queue_len(&session->reorder_q)); + l2tp_dbg(session, L2TP_MSG_SEQ, + "%s: oos pkt %u len %d discarded (too old), waiting for %u, reorder_q_len=%d\n", + session->name, L2TP_SKB_CB(skb)->ns, + L2TP_SKB_CB(skb)->length, session->nr, + skb_queue_len(&session->reorder_q)); + session->reorder_skip = 1; __skb_unlink(skb, &session->reorder_q); kfree_skb(skb); if (session->deref) @@ -436,13 +438,20 @@ } if (L2TP_SKB_CB(skb)->has_seq) { + if (session->reorder_skip) { + l2tp_dbg(session, L2TP_MSG_SEQ, + "%s: advancing nr to next pkt: %u -> %u", + session->name, session->nr, + L2TP_SKB_CB(skb)->ns); + session->reorder_skip = 0; + session->nr = L2TP_SKB_CB(skb)->ns; + } if (L2TP_SKB_CB(skb)->ns != session->nr) { - PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, - "%s: holding oos pkt %u len %d, " - "waiting for %u, reorder_q_len=%d\n", - session->name, L2TP_SKB_CB(skb)->ns, - L2TP_SKB_CB(skb)->length, session->nr, - skb_queue_len(&session->reorder_q)); + l2tp_dbg(session, L2TP_MSG_SEQ, + "%s: holding oos pkt %u len %d, waiting for %u, reorder_q_len=%d\n", + session->name, L2TP_SKB_CB(skb)->ns, + L2TP_SKB_CB(skb)->length, session->nr, + skb_queue_len(&session->reorder_q)); goto out; } } @@ -586,9 +595,10 @@ /* Parse and check optional cookie */ if (session->peer_cookie_len > 0) { if (memcmp(ptr, &session->peer_cookie[0], session->peer_cookie_len)) { - PRINTK(tunnel->debug, L2TP_MSG_DATA, KERN_INFO, - "%s: cookie mismatch (%u/%u). Discarding.\n", - tunnel->name, tunnel->tunnel_id, session->session_id); + l2tp_info(tunnel, L2TP_MSG_DATA, + "%s: cookie mismatch (%u/%u). Discarding.\n", + tunnel->name, tunnel->tunnel_id, + session->session_id); u64_stats_update_begin(&sstats->syncp); sstats->rx_cookie_discards++; u64_stats_update_end(&sstats->syncp); @@ -617,9 +627,9 @@ L2TP_SKB_CB(skb)->ns = ns; L2TP_SKB_CB(skb)->has_seq = 1; - PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, - "%s: recv data ns=%u, nr=%u, session nr=%u\n", - session->name, ns, nr, session->nr); + l2tp_dbg(session, L2TP_MSG_SEQ, + "%s: recv data ns=%u, nr=%u, session nr=%u\n", + session->name, ns, nr, session->nr); } } else if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) { u32 l2h = ntohl(*(__be32 *) ptr); @@ -631,9 +641,9 @@ L2TP_SKB_CB(skb)->ns = ns; L2TP_SKB_CB(skb)->has_seq = 1; - PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, - "%s: recv data ns=%u, session nr=%u\n", - session->name, ns, session->nr); + l2tp_dbg(session, L2TP_MSG_SEQ, + "%s: recv data ns=%u, session nr=%u\n", + session->name, ns, session->nr); } } @@ -646,9 +656,9 @@ * configure it so. */ if ((!session->lns_mode) && (!session->send_seq)) { - PRINTK(session->debug, L2TP_MSG_SEQ, KERN_INFO, - "%s: requested to enable seq numbers by LNS\n", - session->name); + l2tp_info(session, L2TP_MSG_SEQ, + "%s: requested to enable seq numbers by LNS\n", + session->name); session->send_seq = -1; l2tp_session_set_header_len(session, tunnel->version); } @@ -657,9 +667,9 @@ * If user has configured mandatory sequence numbers, discard. */ if (session->recv_seq) { - PRINTK(session->debug, L2TP_MSG_SEQ, KERN_WARNING, - "%s: recv data has no seq numbers when required. " - "Discarding\n", session->name); + l2tp_warn(session, L2TP_MSG_SEQ, + "%s: recv data has no seq numbers when required. Discarding.\n", + session->name); u64_stats_update_begin(&sstats->syncp); sstats->rx_seq_discards++; u64_stats_update_end(&sstats->syncp); @@ -672,15 +682,15 @@ * LAC is broken. Discard the frame. */ if ((!session->lns_mode) && (session->send_seq)) { - PRINTK(session->debug, L2TP_MSG_SEQ, KERN_INFO, - "%s: requested to disable seq numbers by LNS\n", - session->name); + l2tp_info(session, L2TP_MSG_SEQ, + "%s: requested to disable seq numbers by LNS\n", + session->name); session->send_seq = 0; l2tp_session_set_header_len(session, tunnel->version); } else if (session->send_seq) { - PRINTK(session->debug, L2TP_MSG_SEQ, KERN_WARNING, - "%s: recv data has no seq numbers when required. " - "Discarding\n", session->name); + l2tp_warn(session, L2TP_MSG_SEQ, + "%s: recv data has no seq numbers when required. Discarding.\n", + session->name); u64_stats_update_begin(&sstats->syncp); sstats->rx_seq_discards++; u64_stats_update_end(&sstats->syncp); @@ -740,12 +750,11 @@ u64_stats_update_begin(&sstats->syncp); sstats->rx_seq_discards++; u64_stats_update_end(&sstats->syncp); - PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, - "%s: oos pkt %u len %d discarded, " - "waiting for %u, reorder_q_len=%d\n", - session->name, L2TP_SKB_CB(skb)->ns, - L2TP_SKB_CB(skb)->length, session->nr, - skb_queue_len(&session->reorder_q)); + l2tp_dbg(session, L2TP_MSG_SEQ, + "%s: oos pkt %u len %d discarded, waiting for %u, reorder_q_len=%d\n", + session->name, L2TP_SKB_CB(skb)->ns, + L2TP_SKB_CB(skb)->length, session->nr, + skb_queue_len(&session->reorder_q)); goto discard; } skb_queue_tail(&session->reorder_q, skb); @@ -791,7 +800,6 @@ unsigned char *ptr, *optr; u16 hdrflags; u32 tunnel_id, session_id; - int offset; u16 version; int length; struct l2tp_stats *tstats; @@ -804,8 +812,9 @@ /* Short packet? */ if (!pskb_may_pull(skb, L2TP_HDR_SIZE_SEQ)) { - PRINTK(tunnel->debug, L2TP_MSG_DATA, KERN_INFO, - "%s: recv short packet (len=%d)\n", tunnel->name, skb->len); + l2tp_info(tunnel, L2TP_MSG_DATA, + "%s: recv short packet (len=%d)\n", + tunnel->name, skb->len); goto error; } @@ -815,14 +824,8 @@ if (!pskb_may_pull(skb, length)) goto error; - printk(KERN_DEBUG "%s: recv: ", tunnel->name); - - offset = 0; - do { - printk(" %02X", skb->data[offset]); - } while (++offset < length); - - printk("\n"); + pr_debug("%s: recv\n", tunnel->name); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, skb->data, length); } /* Point to L2TP header */ @@ -834,9 +837,9 @@ /* Check protocol version */ version = hdrflags & L2TP_HDR_VER_MASK; if (version != tunnel->version) { - PRINTK(tunnel->debug, L2TP_MSG_DATA, KERN_INFO, - "%s: recv protocol version mismatch: got %d expected %d\n", - tunnel->name, version, tunnel->version); + l2tp_info(tunnel, L2TP_MSG_DATA, + "%s: recv protocol version mismatch: got %d expected %d\n", + tunnel->name, version, tunnel->version); goto error; } @@ -845,8 +848,9 @@ /* If type is control packet, it is handled by userspace. */ if (hdrflags & L2TP_HDRFLAG_T) { - PRINTK(tunnel->debug, L2TP_MSG_DATA, KERN_DEBUG, - "%s: recv control packet, len=%d\n", tunnel->name, length); + l2tp_dbg(tunnel, L2TP_MSG_DATA, + "%s: recv control packet, len=%d\n", + tunnel->name, length); goto error; } @@ -874,9 +878,9 @@ session = l2tp_session_find(tunnel->l2tp_net, tunnel, session_id); if (!session || !session->recv_skb) { /* Not found? Pass to userspace to deal with */ - PRINTK(tunnel->debug, L2TP_MSG_DATA, KERN_INFO, - "%s: no session found (%u/%u). Passing up.\n", - tunnel->name, tunnel_id, session_id); + l2tp_info(tunnel, L2TP_MSG_DATA, + "%s: no session found (%u/%u). Passing up.\n", + tunnel->name, tunnel_id, session_id); goto error; } @@ -916,8 +920,8 @@ if (tunnel == NULL) goto pass_up; - PRINTK(tunnel->debug, L2TP_MSG_DATA, KERN_DEBUG, - "%s: received %d bytes\n", tunnel->name, skb->len); + l2tp_dbg(tunnel, L2TP_MSG_DATA, "%s: received %d bytes\n", + tunnel->name, skb->len); if (l2tp_udp_recv_core(tunnel, skb, tunnel->recv_payload_hook)) goto pass_up_put; @@ -959,8 +963,8 @@ *bufp++ = 0; session->ns++; session->ns &= 0xffff; - PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, - "%s: updated ns to %u\n", session->name, session->ns); + l2tp_dbg(session, L2TP_MSG_SEQ, "%s: updated ns to %u\n", + session->name, session->ns); } return bufp - optr; @@ -996,8 +1000,9 @@ l2h = 0x40000000 | session->ns; session->ns++; session->ns &= 0xffffff; - PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, - "%s: updated ns to %u\n", session->name, session->ns); + l2tp_dbg(session, L2TP_MSG_SEQ, + "%s: updated ns to %u\n", + session->name, session->ns); } *((__be32 *) bufp) = htonl(l2h); @@ -1020,27 +1025,19 @@ /* Debug */ if (session->send_seq) - PRINTK(session->debug, L2TP_MSG_DATA, KERN_DEBUG, - "%s: send %Zd bytes, ns=%u\n", session->name, - data_len, session->ns - 1); + l2tp_dbg(session, L2TP_MSG_DATA, "%s: send %Zd bytes, ns=%u\n", + session->name, data_len, session->ns - 1); else - PRINTK(session->debug, L2TP_MSG_DATA, KERN_DEBUG, - "%s: send %Zd bytes\n", session->name, data_len); + l2tp_dbg(session, L2TP_MSG_DATA, "%s: send %Zd bytes\n", + session->name, data_len); if (session->debug & L2TP_MSG_DATA) { - int i; int uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0; unsigned char *datap = skb->data + uhlen; - printk(KERN_DEBUG "%s: xmit:", session->name); - for (i = 0; i < (len - uhlen); i++) { - printk(" %02X", *datap++); - if (i == 31) { - printk(" ..."); - break; - } - } - printk("\n"); + pr_debug("%s: xmit\n", session->name); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, + datap, min_t(size_t, 32, len - uhlen)); } /* Queue the packet to IP for output */ @@ -1239,8 +1236,7 @@ if (tunnel == NULL) goto end; - PRINTK(tunnel->debug, L2TP_MSG_CONTROL, KERN_INFO, - "%s: closing...\n", tunnel->name); + l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: closing...\n", tunnel->name); /* Close all sessions */ l2tp_tunnel_closeall(tunnel); @@ -1282,8 +1278,8 @@ BUG_ON(tunnel == NULL); - PRINTK(tunnel->debug, L2TP_MSG_CONTROL, KERN_INFO, - "%s: closing all sessions...\n", tunnel->name); + l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: closing all sessions...\n", + tunnel->name); write_lock_bh(&tunnel->hlist_lock); for (hash = 0; hash < L2TP_HASH_SIZE; hash++) { @@ -1291,8 +1287,8 @@ hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) { session = hlist_entry(walk, struct l2tp_session, hlist); - PRINTK(session->debug, L2TP_MSG_CONTROL, KERN_INFO, - "%s: closing session\n", session->name); + l2tp_info(session, L2TP_MSG_CONTROL, + "%s: closing session\n", session->name); hlist_del_init(&session->hlist); @@ -1345,8 +1341,7 @@ BUG_ON(atomic_read(&tunnel->ref_count) != 0); BUG_ON(tunnel->sock != NULL); - PRINTK(tunnel->debug, L2TP_MSG_CONTROL, KERN_INFO, - "%s: free...\n", tunnel->name); + l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: free...\n", tunnel->name); /* Remove from tunnel list */ spin_lock_bh(&pn->l2tp_tunnel_list_lock); @@ -1527,7 +1522,7 @@ err = -EBADF; sock = sockfd_lookup(fd, &err); if (!sock) { - printk(KERN_ERR "tunl %hu: sockfd_lookup(fd=%d) returned %d\n", + pr_err("tunl %hu: sockfd_lookup(fd=%d) returned %d\n", tunnel_id, fd, err); goto err; } @@ -1543,7 +1538,7 @@ case L2TP_ENCAPTYPE_UDP: err = -EPROTONOSUPPORT; if (sk->sk_protocol != IPPROTO_UDP) { - printk(KERN_ERR "tunl %hu: fd %d wrong protocol, got %d, expected %d\n", + pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n", tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP); goto err; } @@ -1551,7 +1546,7 @@ case L2TP_ENCAPTYPE_IP: err = -EPROTONOSUPPORT; if (sk->sk_protocol != IPPROTO_L2TP) { - printk(KERN_ERR "tunl %hu: fd %d wrong protocol, got %d, expected %d\n", + pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n", tunnel_id, fd, sk->sk_protocol, IPPROTO_L2TP); goto err; } @@ -1753,7 +1748,7 @@ session->session_id = session_id; session->peer_session_id = peer_session_id; - session->nr = 1; + session->nr = 0; sprintf(&session->name[0], "sess %u/%u", tunnel->tunnel_id, session->session_id); @@ -1859,7 +1854,7 @@ if (rc) goto out; - printk(KERN_INFO "L2TP core driver, %s\n", L2TP_DRV_VERSION); + pr_info("L2TP core driver, %s\n", L2TP_DRV_VERSION); out: return rc;
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index 0bf60fc..a38ec6c 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h
@@ -123,6 +123,7 @@ * categories */ int reorder_timeout; /* configured reorder timeout * (in jiffies) */ + int reorder_skip; /* set if skip to next nr */ int mtu; int mru; enum l2tp_pwtype pwtype; @@ -260,17 +261,36 @@ } #ifdef L2TP_REFCNT_DEBUG -#define l2tp_session_inc_refcount(_s) do { \ - printk(KERN_DEBUG "l2tp_session_inc_refcount: %s:%d %s: cnt=%d\n", __func__, __LINE__, (_s)->name, atomic_read(&_s->ref_count)); \ - l2tp_session_inc_refcount_1(_s); \ - } while (0) -#define l2tp_session_dec_refcount(_s) do { \ - printk(KERN_DEBUG "l2tp_session_dec_refcount: %s:%d %s: cnt=%d\n", __func__, __LINE__, (_s)->name, atomic_read(&_s->ref_count)); \ - l2tp_session_dec_refcount_1(_s); \ - } while (0) +#define l2tp_session_inc_refcount(_s) \ +do { \ + pr_debug("l2tp_session_inc_refcount: %s:%d %s: cnt=%d\n", \ + __func__, __LINE__, (_s)->name, \ + atomic_read(&_s->ref_count)); \ + l2tp_session_inc_refcount_1(_s); \ +} while (0) +#define l2tp_session_dec_refcount(_s) \ +do { \ + pr_debug("l2tp_session_dec_refcount: %s:%d %s: cnt=%d\n", \ + __func__, __LINE__, (_s)->name, \ + atomic_read(&_s->ref_count)); \ + l2tp_session_dec_refcount_1(_s); \ +} while (0) #else #define l2tp_session_inc_refcount(s) l2tp_session_inc_refcount_1(s) #define l2tp_session_dec_refcount(s) l2tp_session_dec_refcount_1(s) #endif +#define l2tp_printk(ptr, type, func, fmt, ...) \ +do { \ + if (((ptr)->debug) & (type)) \ + func(fmt, ##__VA_ARGS__); \ +} while (0) + +#define l2tp_warn(ptr, type, fmt, ...) \ + l2tp_printk(ptr, type, pr_warn, fmt, ##__VA_ARGS__) +#define l2tp_info(ptr, type, fmt, ...) \ + l2tp_printk(ptr, type, pr_info, fmt, ##__VA_ARGS__) +#define l2tp_dbg(ptr, type, fmt, ...) \ + l2tp_printk(ptr, type, pr_debug, fmt, ##__VA_ARGS__) + #endif /* _L2TP_CORE_H_ */
diff --git a/net/l2tp/l2tp_debugfs.c b/net/l2tp/l2tp_debugfs.c index c0d57ba..c3813bc 100644 --- a/net/l2tp/l2tp_debugfs.c +++ b/net/l2tp/l2tp_debugfs.c
@@ -9,6 +9,8 @@ * 2 of the License, or (at your option) any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/skbuff.h> #include <linux/socket.h> @@ -325,11 +327,11 @@ if (tunnels == NULL) rc = -EIO; - printk(KERN_INFO "L2TP debugfs support\n"); + pr_info("L2TP debugfs support\n"); out: if (rc) - printk(KERN_WARNING "l2tp debugfs: unable to init\n"); + pr_warn("unable to init\n"); return rc; }
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 63fe5f3..443591d 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c
@@ -9,6 +9,8 @@ * 2 of the License, or (at your option) any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/skbuff.h> #include <linux/socket.h> @@ -115,21 +117,14 @@ if (session->debug & L2TP_MSG_DATA) { unsigned int length; - int offset; u8 *ptr = skb->data; length = min(32u, skb->len); if (!pskb_may_pull(skb, length)) goto error; - printk(KERN_DEBUG "%s: eth recv: ", session->name); - - offset = 0; - do { - printk(" %02X", ptr[offset]); - } while (++offset < length); - - printk("\n"); + pr_debug("%s: eth recv\n", session->name); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); } if (!pskb_may_pull(skb, sizeof(ETH_HLEN))) @@ -308,7 +303,7 @@ if (err) goto out_unreg; - printk(KERN_INFO "L2TP ethernet pseudowire support (L2TPv3)\n"); + pr_info("L2TP ethernet pseudowire support (L2TPv3)\n"); return 0;
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index c89a32f..889f5d1 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c
@@ -9,6 +9,8 @@ * 2 of the License, or (at your option) any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/icmp.h> #include <linux/module.h> #include <linux/skbuff.h> @@ -120,7 +122,6 @@ struct l2tp_session *session; struct l2tp_tunnel *tunnel = NULL; int length; - int offset; /* Point to L2TP header */ optr = ptr = skb->data; @@ -155,14 +156,8 @@ if (!pskb_may_pull(skb, length)) goto discard; - printk(KERN_DEBUG "%s: ip recv: ", tunnel->name); - - offset = 0; - do { - printk(" %02X", ptr[offset]); - } while (++offset < length); - - printk("\n"); + pr_debug("%s: ip recv\n", tunnel->name); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); } l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, tunnel->recv_payload_hook); @@ -593,7 +588,7 @@ { int err; - printk(KERN_INFO "L2TP IP encapsulation support (L2TPv3)\n"); + pr_info("L2TP IP encapsulation support (L2TPv3)\n"); err = proto_register(&l2tp_ip_prot, 1); if (err != 0)
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index 88f0abe..0291d8d 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c
@@ -9,6 +9,8 @@ * 2 of the License, or (at your option) any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/icmp.h> #include <linux/module.h> #include <linux/skbuff.h> @@ -133,7 +135,6 @@ struct l2tp_session *session; struct l2tp_tunnel *tunnel = NULL; int length; - int offset; /* Point to L2TP header */ optr = ptr = skb->data; @@ -168,14 +169,8 @@ if (!pskb_may_pull(skb, length)) goto discard; - printk(KERN_DEBUG "%s: ip recv: ", tunnel->name); - - offset = 0; - do { - printk(" %02X", ptr[offset]); - } while (++offset < length); - - printk("\n"); + pr_debug("%s: ip recv\n", tunnel->name); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); } l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, @@ -752,7 +747,7 @@ { int err; - printk(KERN_INFO "L2TP IP encapsulation support for IPv6 (L2TPv3)\n"); + pr_info("L2TP IP encapsulation support for IPv6 (L2TPv3)\n"); err = proto_register(&l2tp_ip6_prot, 1); if (err != 0)
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index 24edad0..85772643 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c
@@ -14,6 +14,8 @@ * published by the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <net/sock.h> #include <net/genetlink.h> #include <net/udp.h> @@ -902,7 +904,7 @@ { int err; - printk(KERN_INFO "L2TP netlink interface\n"); + pr_info("L2TP netlink interface\n"); err = genl_register_family_with_ops(&l2tp_nl_family, l2tp_nl_ops, ARRAY_SIZE(l2tp_nl_ops));
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 9f2c421..8ef6b94 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c
@@ -57,6 +57,8 @@ * http://openl2tp.sourceforge.net. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/string.h> #include <linux/list.h> @@ -106,12 +108,6 @@ /* Space for UDP, L2TP and PPP headers */ #define PPPOL2TP_HEADER_OVERHEAD 40 -#define PRINTK(_mask, _type, _lvl, _fmt, args...) \ - do { \ - if ((_mask) & (_type)) \ - printk(_lvl "PPPOL2TP: " _fmt, ##args); \ - } while (0) - /* Number of bytes to build transmit L2TP headers. * Unfortunately the size is different depending on whether sequence numbers * are enabled. @@ -236,9 +232,9 @@ if (sk->sk_state & PPPOX_BOUND) { struct pppox_sock *po; - PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG, - "%s: recv %d byte data frame, passing to ppp\n", - session->name, data_len); + l2tp_dbg(session, PPPOL2TP_MSG_DATA, + "%s: recv %d byte data frame, passing to ppp\n", + session->name, data_len); /* We need to forget all info related to the L2TP packet * gathered in the skb as we are going to reuse the same @@ -259,8 +255,8 @@ po = pppox_sk(sk); ppp_input(&po->chan, skb); } else { - PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_INFO, - "%s: socket not bound\n", session->name); + l2tp_info(session, PPPOL2TP_MSG_DATA, "%s: socket not bound\n", + session->name); /* Not bound. Nothing we can do, so discard. */ session->stats.rx_errors++; @@ -270,8 +266,7 @@ return; no_sock: - PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_INFO, - "%s: no socket\n", session->name); + l2tp_info(session, PPPOL2TP_MSG_DATA, "%s: no socket\n", session->name); kfree_skb(skb); } @@ -827,8 +822,8 @@ /* This is how we get the session context from the socket. */ sk->sk_user_data = session; sk->sk_state = PPPOX_CONNECTED; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: created\n", session->name); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: created\n", + session->name); end: release_sock(sk); @@ -881,8 +876,8 @@ ps = l2tp_session_priv(session); ps->tunnel_sock = tunnel->sock; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: created\n", session->name); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: created\n", + session->name); error = 0; @@ -1058,9 +1053,9 @@ struct l2tp_tunnel *tunnel = session->tunnel; struct pppol2tp_ioc_stats stats; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_DEBUG, - "%s: pppol2tp_session_ioctl(cmd=%#x, arg=%#lx)\n", - session->name, cmd, arg); + l2tp_dbg(session, PPPOL2TP_MSG_CONTROL, + "%s: pppol2tp_session_ioctl(cmd=%#x, arg=%#lx)\n", + session->name, cmd, arg); sk = ps->sock; sock_hold(sk); @@ -1078,8 +1073,8 @@ if (copy_to_user((void __user *) arg, &ifr, sizeof(struct ifreq))) break; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: get mtu=%d\n", session->name, session->mtu); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: get mtu=%d\n", + session->name, session->mtu); err = 0; break; @@ -1094,8 +1089,8 @@ session->mtu = ifr.ifr_mtu; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: set mtu=%d\n", session->name, session->mtu); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: set mtu=%d\n", + session->name, session->mtu); err = 0; break; @@ -1108,8 +1103,8 @@ if (put_user(session->mru, (int __user *) arg)) break; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: get mru=%d\n", session->name, session->mru); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: get mru=%d\n", + session->name, session->mru); err = 0; break; @@ -1123,8 +1118,8 @@ break; session->mru = val; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: set mru=%d\n", session->name, session->mru); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: set mru=%d\n", + session->name, session->mru); err = 0; break; @@ -1133,8 +1128,8 @@ if (put_user(ps->flags, (int __user *) arg)) break; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: get flags=%d\n", session->name, ps->flags); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: get flags=%d\n", + session->name, ps->flags); err = 0; break; @@ -1143,8 +1138,8 @@ if (get_user(val, (int __user *) arg)) break; ps->flags = val; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: set flags=%d\n", session->name, ps->flags); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: set flags=%d\n", + session->name, ps->flags); err = 0; break; @@ -1160,8 +1155,8 @@ if (copy_to_user((void __user *) arg, &stats, sizeof(stats))) break; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: get L2TP stats\n", session->name); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: get L2TP stats\n", + session->name); err = 0; break; @@ -1188,9 +1183,9 @@ struct sock *sk; struct pppol2tp_ioc_stats stats; - PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_DEBUG, - "%s: pppol2tp_tunnel_ioctl(cmd=%#x, arg=%#lx)\n", - tunnel->name, cmd, arg); + l2tp_dbg(tunnel, PPPOL2TP_MSG_CONTROL, + "%s: pppol2tp_tunnel_ioctl(cmd=%#x, arg=%#lx)\n", + tunnel->name, cmd, arg); sk = tunnel->sock; sock_hold(sk); @@ -1224,8 +1219,8 @@ err = -EFAULT; break; } - PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: get L2TP stats\n", tunnel->name); + l2tp_info(tunnel, PPPOL2TP_MSG_CONTROL, "%s: get L2TP stats\n", + tunnel->name); err = 0; break; @@ -1314,8 +1309,8 @@ switch (optname) { case PPPOL2TP_SO_DEBUG: tunnel->debug = val; - PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: set debug=%x\n", tunnel->name, tunnel->debug); + l2tp_info(tunnel, PPPOL2TP_MSG_CONTROL, "%s: set debug=%x\n", + tunnel->name, tunnel->debug); break; default: @@ -1342,8 +1337,9 @@ break; } session->recv_seq = val ? -1 : 0; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: set recv_seq=%d\n", session->name, session->recv_seq); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, + "%s: set recv_seq=%d\n", + session->name, session->recv_seq); break; case PPPOL2TP_SO_SENDSEQ: @@ -1358,8 +1354,9 @@ po->chan.hdrlen = val ? PPPOL2TP_L2TP_HDR_SIZE_SEQ : PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; } - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: set send_seq=%d\n", session->name, session->send_seq); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, + "%s: set send_seq=%d\n", + session->name, session->send_seq); break; case PPPOL2TP_SO_LNSMODE: @@ -1368,20 +1365,22 @@ break; } session->lns_mode = val ? -1 : 0; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: set lns_mode=%d\n", session->name, session->lns_mode); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, + "%s: set lns_mode=%d\n", + session->name, session->lns_mode); break; case PPPOL2TP_SO_DEBUG: session->debug = val; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: set debug=%x\n", session->name, session->debug); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: set debug=%x\n", + session->name, session->debug); break; case PPPOL2TP_SO_REORDERTO: session->reorder_timeout = msecs_to_jiffies(val); - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: set reorder_timeout=%d\n", session->name, session->reorder_timeout); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, + "%s: set reorder_timeout=%d\n", + session->name, session->reorder_timeout); break; default: @@ -1460,8 +1459,8 @@ switch (optname) { case PPPOL2TP_SO_DEBUG: *val = tunnel->debug; - PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: get debug=%x\n", tunnel->name, tunnel->debug); + l2tp_info(tunnel, PPPOL2TP_MSG_CONTROL, "%s: get debug=%x\n", + tunnel->name, tunnel->debug); break; default: @@ -1483,32 +1482,32 @@ switch (optname) { case PPPOL2TP_SO_RECVSEQ: *val = session->recv_seq; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: get recv_seq=%d\n", session->name, *val); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, + "%s: get recv_seq=%d\n", session->name, *val); break; case PPPOL2TP_SO_SENDSEQ: *val = session->send_seq; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: get send_seq=%d\n", session->name, *val); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, + "%s: get send_seq=%d\n", session->name, *val); break; case PPPOL2TP_SO_LNSMODE: *val = session->lns_mode; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: get lns_mode=%d\n", session->name, *val); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, + "%s: get lns_mode=%d\n", session->name, *val); break; case PPPOL2TP_SO_DEBUG: *val = session->debug; - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: get debug=%d\n", session->name, *val); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: get debug=%d\n", + session->name, *val); break; case PPPOL2TP_SO_REORDERTO: *val = (int) jiffies_to_msecs(session->reorder_timeout); - PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, - "%s: get reorder_timeout=%d\n", session->name, *val); + l2tp_info(session, PPPOL2TP_MSG_CONTROL, + "%s: get reorder_timeout=%d\n", session->name, *val); break; default: @@ -1871,8 +1870,7 @@ goto out_unregister_pppox; #endif - printk(KERN_INFO "PPPoL2TP kernel driver, %s\n", - PPPOL2TP_DRV_VERSION); + pr_info("PPPoL2TP kernel driver, %s\n", PPPOL2TP_DRV_VERSION); out: return err;
diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c index ab3d35f..3cdaa04 100644 --- a/net/lapb/lapb_iface.c +++ b/net/lapb/lapb_iface.c
@@ -15,6 +15,8 @@ * 2000-10-29 Henner Eisen lapb_data_indication() return status. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/errno.h> #include <linux/types.h> @@ -279,9 +281,7 @@ lapb_establish_data_link(lapb); -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S0 -> S1\n", lapb->dev); -#endif + lapb_dbg(0, "(%p) S0 -> S1\n", lapb->dev); lapb->state = LAPB_STATE_1; rc = LAPB_OK; @@ -305,12 +305,8 @@ goto out_put; case LAPB_STATE_1: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S1 TX DISC(1)\n", lapb->dev); -#endif -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S1 -> S0\n", lapb->dev); -#endif + lapb_dbg(1, "(%p) S1 TX DISC(1)\n", lapb->dev); + lapb_dbg(0, "(%p) S1 -> S0\n", lapb->dev); lapb_send_control(lapb, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND); lapb->state = LAPB_STATE_0; lapb_start_t1timer(lapb); @@ -329,12 +325,8 @@ lapb_stop_t2timer(lapb); lapb->state = LAPB_STATE_2; -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S3 DISC(1)\n", lapb->dev); -#endif -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S3 -> S2\n", lapb->dev); -#endif + lapb_dbg(1, "(%p) S3 DISC(1)\n", lapb->dev); + lapb_dbg(0, "(%p) S3 -> S2\n", lapb->dev); rc = LAPB_OK; out_put:
diff --git a/net/lapb/lapb_in.c b/net/lapb/lapb_in.c index f4e3c1a..5dba899 100644 --- a/net/lapb/lapb_in.c +++ b/net/lapb/lapb_in.c
@@ -15,6 +15,8 @@ * 2000-10-29 Henner Eisen lapb_data_indication() return status. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -44,25 +46,16 @@ { switch (frame->type) { case LAPB_SABM: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S0 RX SABM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S0 RX SABM(%d)\n", lapb->dev, frame->pf); if (lapb->mode & LAPB_EXTENDED) { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S0 TX DM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S0 TX DM(%d)\n", + lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); } else { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n", - lapb->dev, frame->pf); -#endif -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S0 -> S3\n", lapb->dev); -#endif + lapb_dbg(1, "(%p) S0 TX UA(%d)\n", + lapb->dev, frame->pf); + lapb_dbg(0, "(%p) S0 -> S3\n", lapb->dev); lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); lapb_stop_t1timer(lapb); @@ -78,18 +71,11 @@ break; case LAPB_SABME: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S0 RX SABME(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S0 RX SABME(%d)\n", lapb->dev, frame->pf); if (lapb->mode & LAPB_EXTENDED) { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n", - lapb->dev, frame->pf); -#endif -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S0 -> S3\n", lapb->dev); -#endif + lapb_dbg(1, "(%p) S0 TX UA(%d)\n", + lapb->dev, frame->pf); + lapb_dbg(0, "(%p) S0 -> S3\n", lapb->dev); lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); lapb_stop_t1timer(lapb); @@ -102,22 +88,16 @@ lapb->va = 0; lapb_connect_indication(lapb, LAPB_OK); } else { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S0 TX DM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S0 TX DM(%d)\n", + lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); } break; case LAPB_DISC: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S0 RX DISC(%d)\n", - lapb->dev, frame->pf); - printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S0 RX DISC(%d)\n", lapb->dev, frame->pf); + lapb_dbg(1, "(%p) S0 TX UA(%d)\n", lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); break; @@ -137,68 +117,45 @@ { switch (frame->type) { case LAPB_SABM: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S1 RX SABM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S1 RX SABM(%d)\n", lapb->dev, frame->pf); if (lapb->mode & LAPB_EXTENDED) { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S1 TX DM(%d)\n", + lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); } else { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S1 TX UA(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S1 TX UA(%d)\n", + lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); } break; case LAPB_SABME: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S1 RX SABME(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S1 RX SABME(%d)\n", lapb->dev, frame->pf); if (lapb->mode & LAPB_EXTENDED) { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S1 TX UA(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S1 TX UA(%d)\n", + lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); } else { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S1 TX DM(%d)\n", + lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); } break; case LAPB_DISC: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S1 RX DISC(%d)\n", - lapb->dev, frame->pf); - printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S1 RX DISC(%d)\n", lapb->dev, frame->pf); + lapb_dbg(1, "(%p) S1 TX DM(%d)\n", lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); break; case LAPB_UA: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S1 RX UA(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S1 RX UA(%d)\n", lapb->dev, frame->pf); if (frame->pf) { -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S1 -> S3\n", lapb->dev); -#endif + lapb_dbg(0, "(%p) S1 -> S3\n", lapb->dev); lapb_stop_t1timer(lapb); lapb_stop_t2timer(lapb); lapb->state = LAPB_STATE_3; @@ -212,14 +169,9 @@ break; case LAPB_DM: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S1 RX DM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S1 RX DM(%d)\n", lapb->dev, frame->pf); if (frame->pf) { -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S1 -> S0\n", lapb->dev); -#endif + lapb_dbg(0, "(%p) S1 -> S0\n", lapb->dev); lapb_clear_queues(lapb); lapb->state = LAPB_STATE_0; lapb_start_t1timer(lapb); @@ -242,34 +194,22 @@ switch (frame->type) { case LAPB_SABM: case LAPB_SABME: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S2 RX {SABM,SABME}(%d)\n", - lapb->dev, frame->pf); - printk(KERN_DEBUG "lapb: (%p) S2 TX DM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S2 RX {SABM,SABME}(%d)\n", + lapb->dev, frame->pf); + lapb_dbg(1, "(%p) S2 TX DM(%d)\n", lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); break; case LAPB_DISC: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S2 RX DISC(%d)\n", - lapb->dev, frame->pf); - printk(KERN_DEBUG "lapb: (%p) S2 TX UA(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S2 RX DISC(%d)\n", lapb->dev, frame->pf); + lapb_dbg(1, "(%p) S2 TX UA(%d)\n", lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); break; case LAPB_UA: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S2 RX UA(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S2 RX UA(%d)\n", lapb->dev, frame->pf); if (frame->pf) { -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S2 -> S0\n", lapb->dev); -#endif + lapb_dbg(0, "(%p) S2 -> S0\n", lapb->dev); lapb->state = LAPB_STATE_0; lapb_start_t1timer(lapb); lapb_stop_t2timer(lapb); @@ -278,14 +218,9 @@ break; case LAPB_DM: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S2 RX DM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S2 RX DM(%d)\n", lapb->dev, frame->pf); if (frame->pf) { -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S2 -> S0\n", lapb->dev); -#endif + lapb_dbg(0, "(%p) S2 -> S0\n", lapb->dev); lapb->state = LAPB_STATE_0; lapb_start_t1timer(lapb); lapb_stop_t2timer(lapb); @@ -297,12 +232,9 @@ case LAPB_REJ: case LAPB_RNR: case LAPB_RR: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S2 RX {I,REJ,RNR,RR}(%d)\n", + lapb_dbg(1, "(%p) S2 RX {I,REJ,RNR,RR}(%d)\n", lapb->dev, frame->pf); - printk(KERN_DEBUG "lapb: (%p) S2 RX DM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S2 RX DM(%d)\n", lapb->dev, frame->pf); if (frame->pf) lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); @@ -325,22 +257,15 @@ switch (frame->type) { case LAPB_SABM: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S3 RX SABM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S3 RX SABM(%d)\n", lapb->dev, frame->pf); if (lapb->mode & LAPB_EXTENDED) { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S3 TX DM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S3 TX DM(%d)\n", + lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); } else { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S3 TX UA(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S3 TX UA(%d)\n", + lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); lapb_stop_t1timer(lapb); @@ -355,15 +280,10 @@ break; case LAPB_SABME: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S3 RX SABME(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S3 RX SABME(%d)\n", lapb->dev, frame->pf); if (lapb->mode & LAPB_EXTENDED) { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S3 TX UA(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S3 TX UA(%d)\n", + lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); lapb_stop_t1timer(lapb); @@ -375,23 +295,16 @@ lapb->va = 0; lapb_requeue_frames(lapb); } else { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S3 TX DM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S3 TX DM(%d)\n", + lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); } break; case LAPB_DISC: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S3 RX DISC(%d)\n", - lapb->dev, frame->pf); -#endif -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n", lapb->dev); -#endif + lapb_dbg(1, "(%p) S3 RX DISC(%d)\n", lapb->dev, frame->pf); + lapb_dbg(0, "(%p) S3 -> S0\n", lapb->dev); lapb_clear_queues(lapb); lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); lapb_start_t1timer(lapb); @@ -401,13 +314,8 @@ break; case LAPB_DM: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S3 RX DM(%d)\n", - lapb->dev, frame->pf); -#endif -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n", lapb->dev); -#endif + lapb_dbg(1, "(%p) S3 RX DM(%d)\n", lapb->dev, frame->pf); + lapb_dbg(0, "(%p) S3 -> S0\n", lapb->dev); lapb_clear_queues(lapb); lapb->state = LAPB_STATE_0; lapb_start_t1timer(lapb); @@ -416,10 +324,8 @@ break; case LAPB_RNR: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S3 RX RNR(%d) R%d\n", - lapb->dev, frame->pf, frame->nr); -#endif + lapb_dbg(1, "(%p) S3 RX RNR(%d) R%d\n", + lapb->dev, frame->pf, frame->nr); lapb->condition |= LAPB_PEER_RX_BUSY_CONDITION; lapb_check_need_response(lapb, frame->cr, frame->pf); if (lapb_validate_nr(lapb, frame->nr)) { @@ -428,9 +334,7 @@ lapb->frmr_data = *frame; lapb->frmr_type = LAPB_FRMR_Z; lapb_transmit_frmr(lapb); -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev); -#endif + lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev); lapb_start_t1timer(lapb); lapb_stop_t2timer(lapb); lapb->state = LAPB_STATE_4; @@ -439,10 +343,8 @@ break; case LAPB_RR: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S3 RX RR(%d) R%d\n", - lapb->dev, frame->pf, frame->nr); -#endif + lapb_dbg(1, "(%p) S3 RX RR(%d) R%d\n", + lapb->dev, frame->pf, frame->nr); lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION; lapb_check_need_response(lapb, frame->cr, frame->pf); if (lapb_validate_nr(lapb, frame->nr)) { @@ -451,9 +353,7 @@ lapb->frmr_data = *frame; lapb->frmr_type = LAPB_FRMR_Z; lapb_transmit_frmr(lapb); -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev); -#endif + lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev); lapb_start_t1timer(lapb); lapb_stop_t2timer(lapb); lapb->state = LAPB_STATE_4; @@ -462,10 +362,8 @@ break; case LAPB_REJ: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S3 RX REJ(%d) R%d\n", - lapb->dev, frame->pf, frame->nr); -#endif + lapb_dbg(1, "(%p) S3 RX REJ(%d) R%d\n", + lapb->dev, frame->pf, frame->nr); lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION; lapb_check_need_response(lapb, frame->cr, frame->pf); if (lapb_validate_nr(lapb, frame->nr)) { @@ -477,9 +375,7 @@ lapb->frmr_data = *frame; lapb->frmr_type = LAPB_FRMR_Z; lapb_transmit_frmr(lapb); -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev); -#endif + lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev); lapb_start_t1timer(lapb); lapb_stop_t2timer(lapb); lapb->state = LAPB_STATE_4; @@ -488,17 +384,13 @@ break; case LAPB_I: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S3 RX I(%d) S%d R%d\n", - lapb->dev, frame->pf, frame->ns, frame->nr); -#endif + lapb_dbg(1, "(%p) S3 RX I(%d) S%d R%d\n", + lapb->dev, frame->pf, frame->ns, frame->nr); if (!lapb_validate_nr(lapb, frame->nr)) { lapb->frmr_data = *frame; lapb->frmr_type = LAPB_FRMR_Z; lapb_transmit_frmr(lapb); -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev); -#endif + lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev); lapb_start_t1timer(lapb); lapb_stop_t2timer(lapb); lapb->state = LAPB_STATE_4; @@ -522,7 +414,7 @@ * a frame lost on the wire. */ if (cn == NET_RX_DROP) { - printk(KERN_DEBUG "LAPB: rx congestion\n"); + pr_debug("rx congestion\n"); break; } lapb->vr = (lapb->vr + 1) % modulus; @@ -541,11 +433,8 @@ if (frame->pf) lapb_enquiry_response(lapb); } else { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG - "lapb: (%p) S3 TX REJ(%d) R%d\n", - lapb->dev, frame->pf, lapb->vr); -#endif + lapb_dbg(1, "(%p) S3 TX REJ(%d) R%d\n", + lapb->dev, frame->pf, lapb->vr); lapb->condition |= LAPB_REJECT_CONDITION; lapb_send_control(lapb, LAPB_REJ, frame->pf, LAPB_RESPONSE); @@ -555,31 +444,22 @@ break; case LAPB_FRMR: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S3 RX FRMR(%d) %02X " - "%02X %02X %02X %02X\n", lapb->dev, frame->pf, - skb->data[0], skb->data[1], skb->data[2], - skb->data[3], skb->data[4]); -#endif + lapb_dbg(1, "(%p) S3 RX FRMR(%d) %02X %02X %02X %02X %02X\n", + lapb->dev, frame->pf, + skb->data[0], skb->data[1], skb->data[2], + skb->data[3], skb->data[4]); lapb_establish_data_link(lapb); -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S3 -> S1\n", lapb->dev); -#endif + lapb_dbg(0, "(%p) S3 -> S1\n", lapb->dev); lapb_requeue_frames(lapb); lapb->state = LAPB_STATE_1; break; case LAPB_ILLEGAL: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S3 RX ILLEGAL(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S3 RX ILLEGAL(%d)\n", lapb->dev, frame->pf); lapb->frmr_data = *frame; lapb->frmr_type = LAPB_FRMR_W; lapb_transmit_frmr(lapb); -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev); -#endif + lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev); lapb_start_t1timer(lapb); lapb_stop_t2timer(lapb); lapb->state = LAPB_STATE_4; @@ -600,25 +480,16 @@ { switch (frame->type) { case LAPB_SABM: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 RX SABM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S4 RX SABM(%d)\n", lapb->dev, frame->pf); if (lapb->mode & LAPB_EXTENDED) { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S4 TX DM(%d)\n", + lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); } else { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n", - lapb->dev, frame->pf); -#endif -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->dev); -#endif + lapb_dbg(1, "(%p) S4 TX UA(%d)\n", + lapb->dev, frame->pf); + lapb_dbg(0, "(%p) S4 -> S3\n", lapb->dev); lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); lapb_stop_t1timer(lapb); @@ -634,18 +505,11 @@ break; case LAPB_SABME: -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 RX SABME(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S4 RX SABME(%d)\n", lapb->dev, frame->pf); if (lapb->mode & LAPB_EXTENDED) { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n", - lapb->dev, frame->pf); -#endif -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->dev); -#endif + lapb_dbg(1, "(%p) S4 TX UA(%d)\n", + lapb->dev, frame->pf); + lapb_dbg(0, "(%p) S4 -> S3\n", lapb->dev); lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); lapb_stop_t1timer(lapb); @@ -658,10 +522,8 @@ lapb->va = 0; lapb_connect_indication(lapb, LAPB_OK); } else { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n", - lapb->dev, frame->pf); -#endif + lapb_dbg(1, "(%p) S4 TX DM(%d)\n", + lapb->dev, frame->pf); lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); }
diff --git a/net/lapb/lapb_out.c b/net/lapb/lapb_out.c index baab276..ba4d015 100644 --- a/net/lapb/lapb_out.c +++ b/net/lapb/lapb_out.c
@@ -14,6 +14,8 @@ * LAPB 002 Jonathan Naylor New timer architecture. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -60,10 +62,8 @@ *frame |= lapb->vs << 1; } -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S%d TX I(%d) S%d R%d\n", - lapb->dev, lapb->state, poll_bit, lapb->vs, lapb->vr); -#endif + lapb_dbg(1, "(%p) S%d TX I(%d) S%d R%d\n", + lapb->dev, lapb->state, poll_bit, lapb->vs, lapb->vr); lapb_transmit_buffer(lapb, skb, LAPB_COMMAND); } @@ -148,11 +148,9 @@ } } -#if LAPB_DEBUG > 2 - printk(KERN_DEBUG "lapb: (%p) S%d TX %02X %02X %02X\n", - lapb->dev, lapb->state, - skb->data[0], skb->data[1], skb->data[2]); -#endif + lapb_dbg(2, "(%p) S%d TX %02X %02X %02X\n", + lapb->dev, lapb->state, + skb->data[0], skb->data[1], skb->data[2]); if (!lapb_data_transmit(lapb, skb)) kfree_skb(skb); @@ -164,16 +162,10 @@ lapb->n2count = 0; if (lapb->mode & LAPB_EXTENDED) { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S%d TX SABME(1)\n", - lapb->dev, lapb->state); -#endif + lapb_dbg(1, "(%p) S%d TX SABME(1)\n", lapb->dev, lapb->state); lapb_send_control(lapb, LAPB_SABME, LAPB_POLLON, LAPB_COMMAND); } else { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S%d TX SABM(1)\n", - lapb->dev, lapb->state); -#endif + lapb_dbg(1, "(%p) S%d TX SABM(1)\n", lapb->dev, lapb->state); lapb_send_control(lapb, LAPB_SABM, LAPB_POLLON, LAPB_COMMAND); } @@ -183,10 +175,8 @@ void lapb_enquiry_response(struct lapb_cb *lapb) { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S%d TX RR(1) R%d\n", - lapb->dev, lapb->state, lapb->vr); -#endif + lapb_dbg(1, "(%p) S%d TX RR(1) R%d\n", + lapb->dev, lapb->state, lapb->vr); lapb_send_control(lapb, LAPB_RR, LAPB_POLLON, LAPB_RESPONSE); @@ -195,10 +185,8 @@ void lapb_timeout_response(struct lapb_cb *lapb) { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S%d TX RR(0) R%d\n", - lapb->dev, lapb->state, lapb->vr); -#endif + lapb_dbg(1, "(%p) S%d TX RR(0) R%d\n", + lapb->dev, lapb->state, lapb->vr); lapb_send_control(lapb, LAPB_RR, LAPB_POLLOFF, LAPB_RESPONSE); lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
diff --git a/net/lapb/lapb_subr.c b/net/lapb/lapb_subr.c index 066225b..9d0a426 100644 --- a/net/lapb/lapb_subr.c +++ b/net/lapb/lapb_subr.c
@@ -13,6 +13,8 @@ * LAPB 001 Jonathan Naylor Started Coding */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -111,11 +113,9 @@ { frame->type = LAPB_ILLEGAL; -#if LAPB_DEBUG > 2 - printk(KERN_DEBUG "lapb: (%p) S%d RX %02X %02X %02X\n", - lapb->dev, lapb->state, - skb->data[0], skb->data[1], skb->data[2]); -#endif + lapb_dbg(2, "(%p) S%d RX %02X %02X %02X\n", + lapb->dev, lapb->state, + skb->data[0], skb->data[1], skb->data[2]); /* We always need to look at 2 bytes, sometimes we need * to look at 3 and those cases are handled below. @@ -284,12 +284,10 @@ dptr++; *dptr++ = lapb->frmr_type; -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S%d TX FRMR %02X %02X %02X %02X %02X\n", - lapb->dev, lapb->state, - skb->data[1], skb->data[2], skb->data[3], - skb->data[4], skb->data[5]); -#endif + lapb_dbg(1, "(%p) S%d TX FRMR %02X %02X %02X %02X %02X\n", + lapb->dev, lapb->state, + skb->data[1], skb->data[2], skb->data[3], + skb->data[4], skb->data[5]); } else { dptr = skb_put(skb, 4); *dptr++ = LAPB_FRMR; @@ -301,11 +299,9 @@ dptr++; *dptr++ = lapb->frmr_type; -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S%d TX FRMR %02X %02X %02X\n", - lapb->dev, lapb->state, skb->data[1], - skb->data[2], skb->data[3]); -#endif + lapb_dbg(1, "(%p) S%d TX FRMR %02X %02X %02X\n", + lapb->dev, lapb->state, skb->data[1], + skb->data[2], skb->data[3]); } lapb_transmit_buffer(lapb, skb, LAPB_RESPONSE);
diff --git a/net/lapb/lapb_timer.c b/net/lapb/lapb_timer.c index f8cd641..54563ad 100644 --- a/net/lapb/lapb_timer.c +++ b/net/lapb/lapb_timer.c
@@ -14,6 +14,8 @@ * LAPB 002 Jonathan Naylor New timer architecture. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -105,21 +107,17 @@ lapb_clear_queues(lapb); lapb->state = LAPB_STATE_0; lapb_disconnect_indication(lapb, LAPB_TIMEDOUT); -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S1 -> S0\n", lapb->dev); -#endif + lapb_dbg(0, "(%p) S1 -> S0\n", lapb->dev); return; } else { lapb->n2count++; if (lapb->mode & LAPB_EXTENDED) { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S1 TX SABME(1)\n", lapb->dev); -#endif + lapb_dbg(1, "(%p) S1 TX SABME(1)\n", + lapb->dev); lapb_send_control(lapb, LAPB_SABME, LAPB_POLLON, LAPB_COMMAND); } else { -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S1 TX SABM(1)\n", lapb->dev); -#endif + lapb_dbg(1, "(%p) S1 TX SABM(1)\n", + lapb->dev); lapb_send_control(lapb, LAPB_SABM, LAPB_POLLON, LAPB_COMMAND); } } @@ -133,15 +131,11 @@ lapb_clear_queues(lapb); lapb->state = LAPB_STATE_0; lapb_disconnect_confirmation(lapb, LAPB_TIMEDOUT); -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S2 -> S0\n", lapb->dev); -#endif + lapb_dbg(0, "(%p) S2 -> S0\n", lapb->dev); return; } else { lapb->n2count++; -#if LAPB_DEBUG > 1 - printk(KERN_DEBUG "lapb: (%p) S2 TX DISC(1)\n", lapb->dev); -#endif + lapb_dbg(1, "(%p) S2 TX DISC(1)\n", lapb->dev); lapb_send_control(lapb, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND); } break; @@ -155,9 +149,7 @@ lapb->state = LAPB_STATE_0; lapb_stop_t2timer(lapb); lapb_disconnect_indication(lapb, LAPB_TIMEDOUT); -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n", lapb->dev); -#endif + lapb_dbg(0, "(%p) S3 -> S0\n", lapb->dev); return; } else { lapb->n2count++; @@ -173,9 +165,7 @@ lapb_clear_queues(lapb); lapb->state = LAPB_STATE_0; lapb_disconnect_indication(lapb, LAPB_TIMEDOUT); -#if LAPB_DEBUG > 0 - printk(KERN_DEBUG "lapb: (%p) S4 -> S0\n", lapb->dev); -#endif + lapb_dbg(0, "(%p) S4 -> S0\n", lapb->dev); return; } else { lapb->n2count++;
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 17bc85d..fe5453c 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c
@@ -71,8 +71,7 @@ */ static inline __be16 llc_proto_type(u16 arphrd) { - return arphrd == ARPHRD_IEEE802_TR ? - htons(ETH_P_TR_802_2) : htons(ETH_P_802_2); + return htons(ETH_P_802_2); } /** @@ -806,10 +805,9 @@ sk_wait_data(sk, &timeo); if ((flags & MSG_PEEK) && peek_seq != llc->copied_seq) { - if (net_ratelimit()) - printk(KERN_DEBUG "LLC(%s:%d): Application " - "bug, race in MSG_PEEK.\n", - current->comm, task_pid_nr(current)); + net_dbg_ratelimited("LLC(%s:%d): Application bug, race in MSG_PEEK\n", + current->comm, + task_pid_nr(current)); peek_seq = llc->copied_seq; } continue; @@ -840,7 +838,7 @@ if (!(flags & MSG_PEEK)) { spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags); - sk_eat_skb(sk, skb, 0); + sk_eat_skb(sk, skb, false); spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags); *seq = 0; } @@ -863,7 +861,7 @@ if (!(flags & MSG_PEEK)) { spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags); - sk_eat_skb(sk, skb, 0); + sk_eat_skb(sk, skb, false); spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags); *seq = 0; }
diff --git a/net/llc/llc_output.c b/net/llc/llc_output.c index b658cba8..2dae8a5 100644 --- a/net/llc/llc_output.c +++ b/net/llc/llc_output.c
@@ -14,9 +14,7 @@ */ #include <linux/if_arp.h> -#include <linux/if_tr.h> #include <linux/netdevice.h> -#include <linux/trdevice.h> #include <linux/skbuff.h> #include <linux/export.h> #include <net/llc.h> @@ -37,7 +35,6 @@ int rc = -EINVAL; switch (skb->dev->type) { - case ARPHRD_IEEE802_TR: case ARPHRD_ETHER: case ARPHRD_LOOPBACK: rc = dev_hard_header(skb, skb->dev, ETH_P_802_2, da, sa,
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index 94e7fca..7c5073b 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c
@@ -31,10 +31,6 @@ case ARPHRD_ETHER: case ARPHRD_LOOPBACK: return sizeof(struct ethhdr); -#if defined(CONFIG_TR) || defined(CONFIG_TR_MODULE) - case ARPHRD_IEEE802_TR: - return sizeof(struct trh_hdr); -#endif } return 0; }
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index a070d4f..26ddb69 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c
@@ -260,11 +260,8 @@ (buf_size > IEEE80211_MAX_AMPDU_BUF)) { status = WLAN_STATUS_INVALID_QOS_PARAM; #ifdef CONFIG_MAC80211_HT_DEBUG - if (net_ratelimit()) - printk(KERN_DEBUG "AddBA Req with bad params from " - "%pM on tid %u. policy %d, buffer size %d\n", - mgmt->sa, tid, ba_policy, - buf_size); + net_dbg_ratelimited("AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n", + mgmt->sa, tid, ba_policy, buf_size); #endif /* CONFIG_MAC80211_HT_DEBUG */ goto end_no_lock; } @@ -281,10 +278,8 @@ if (sta->ampdu_mlme.tid_rx[tid]) { #ifdef CONFIG_MAC80211_HT_DEBUG - if (net_ratelimit()) - printk(KERN_DEBUG "unexpected AddBA Req from " - "%pM on tid %u\n", - mgmt->sa, tid); + net_dbg_ratelimited("unexpected AddBA Req from %pM on tid %u\n", + mgmt->sa, tid); #endif /* CONFIG_MAC80211_HT_DEBUG */ /* delete existing Rx BA session on the same tid */
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 0221270..495831e 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c
@@ -1093,7 +1093,7 @@ } else sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (compare_ether_addr(mac, sdata->vif.addr) == 0) + if (ether_addr_equal(mac, sdata->vif.addr)) return -EINVAL; if (is_multicast_ether_addr(mac))
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 9b60336..6f8615c 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c
@@ -306,10 +306,10 @@ initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11; #ifdef CONFIG_MAC80211_HT_DEBUG - if (net_ratelimit()) - printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n", - mgmt->sa, initiator ? "initiator" : "recipient", tid, - le16_to_cpu(mgmt->u.action.u.delba.reason_code)); + net_dbg_ratelimited("delba from %pM (%s) tid %d reason code %d\n", + mgmt->sa, initiator ? "initiator" : "recipient", + tid, + le16_to_cpu(mgmt->u.action.u.delba.reason_code)); #endif /* CONFIG_MAC80211_HT_DEBUG */ if (initiator == WLAN_BACK_INITIATOR)
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 11ac1ff..33d9d0c 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c
@@ -66,7 +66,7 @@ skb_reset_tail_pointer(skb); skb_reserve(skb, sdata->local->hw.extra_tx_headroom); - if (compare_ether_addr(ifibss->bssid, bssid)) + if (!ether_addr_equal(ifibss->bssid, bssid)) sta_info_flush(sdata->local, sdata); /* if merging, indicate to driver that we leave the old IBSS */ @@ -308,9 +308,8 @@ * allow new one to be added. */ if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { - if (net_ratelimit()) - printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n", - sdata->name, addr); + net_dbg_ratelimited("%s: No room for a new IBSS STA entry %pM\n", + sdata->name, addr); rcu_read_lock(); return NULL; } @@ -320,7 +319,7 @@ return NULL; } - if (compare_ether_addr(bssid, sdata->u.ibss.bssid)) { + if (!ether_addr_equal(bssid, sdata->u.ibss.bssid)) { rcu_read_lock(); return NULL; } @@ -406,7 +405,7 @@ return; if (sdata->vif.type == NL80211_IFTYPE_ADHOC && - compare_ether_addr(mgmt->bssid, sdata->u.ibss.bssid) == 0) { + ether_addr_equal(mgmt->bssid, sdata->u.ibss.bssid)) { rcu_read_lock(); sta = sta_info_get(sdata, mgmt->sa); @@ -511,7 +510,7 @@ goto put_bss; /* same BSSID */ - if (compare_ether_addr(cbss->bssid, sdata->u.ibss.bssid) == 0) + if (ether_addr_equal(cbss->bssid, sdata->u.ibss.bssid)) goto put_bss; if (rx_status->flag & RX_FLAG_MACTIME_MPDU) { @@ -587,16 +586,15 @@ * allow new one to be added. */ if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { - if (net_ratelimit()) - printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n", - sdata->name, addr); + net_dbg_ratelimited("%s: No room for a new IBSS STA entry %pM\n", + sdata->name, addr); return; } if (ifibss->state == IEEE80211_IBSS_MLME_SEARCH) return; - if (compare_ether_addr(bssid, sdata->u.ibss.bssid)) + if (!ether_addr_equal(bssid, sdata->u.ibss.bssid)) return; sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); @@ -834,7 +832,7 @@ if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) return; - if (compare_ether_addr(mgmt->bssid, ifibss->bssid) != 0 && + if (!ether_addr_equal(mgmt->bssid, ifibss->bssid) && !is_broadcast_ether_addr(mgmt->bssid)) return;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ae046b5..3f3cd50 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h
@@ -1195,7 +1195,7 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) { - return compare_ether_addr(raddr, addr) == 0 || + return ether_addr_equal(raddr, addr) || is_broadcast_ether_addr(raddr); }
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index c550945..d4c19a7 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c
@@ -127,7 +127,7 @@ * The remaining checks are only performed for interfaces * with the same MAC address. */ - if (compare_ether_addr(dev->dev_addr, ndev->dev_addr)) + if (!ether_addr_equal(dev->dev_addr, ndev->dev_addr)) continue; /*
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index d3a9a6c..2913113 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c
@@ -217,7 +217,7 @@ kmem_cache_free(rm_cache, p); --entries; } else if ((seqnum == p->seqnum) && - (compare_ether_addr(sa, p->sa) == 0)) + (ether_addr_equal(sa, p->sa))) return -1; } @@ -651,7 +651,7 @@ /* ignore ProbeResp to foreign address */ if (stype == IEEE80211_STYPE_PROBE_RESP && - compare_ether_addr(mgmt->da, sdata->vif.addr)) + !ether_addr_equal(mgmt->da, sdata->vif.addr)) return; baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 70ac7d1..9b59658 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c
@@ -422,7 +422,7 @@ new_metric = MAX_METRIC; exp_time = TU_TO_EXP_TIME(orig_lifetime); - if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0) { + if (ether_addr_equal(orig_addr, sdata->vif.addr)) { /* This MP is the originator, we are not interested in this * frame, except for updating transmitter's path info. */ @@ -472,7 +472,7 @@ /* Update and check transmitter routing info */ ta = mgmt->sa; - if (compare_ether_addr(orig_addr, ta) == 0) + if (ether_addr_equal(orig_addr, ta)) fresh_info = false; else { fresh_info = true; @@ -533,7 +533,7 @@ mhwmp_dbg("received PREQ from %pM", orig_addr); - if (compare_ether_addr(target_addr, sdata->vif.addr) == 0) { + if (ether_addr_equal(target_addr, sdata->vif.addr)) { mhwmp_dbg("PREQ is for us"); forward = false; reply = true; @@ -634,7 +634,7 @@ mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem)); orig_addr = PREP_IE_ORIG_ADDR(prep_elem); - if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0) + if (ether_addr_equal(orig_addr, sdata->vif.addr)) /* destination, no forwarding required */ return; @@ -712,7 +712,7 @@ spin_lock_bh(&mpath->state_lock); sta = next_hop_deref_protected(mpath); if (mpath->flags & MESH_PATH_ACTIVE && - compare_ether_addr(ta, sta->sta.addr) == 0 && + ether_addr_equal(ta, sta->sta.addr) && (!(mpath->flags & MESH_PATH_SN_VALID) || SN_GT(target_sn, mpath->sn))) { mpath->flags &= ~MESH_PATH_ACTIVE; @@ -759,7 +759,7 @@ metric = le32_to_cpu(rann->rann_metric); /* Ignore our own RANNs */ - if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0) + if (ether_addr_equal(orig_addr, sdata->vif.addr)) return; mhwmp_dbg("received RANN from %pM via neighbour %pM (is_gate=%d)", @@ -1102,7 +1102,7 @@ if (time_after(jiffies, mpath->exp_time - msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && - !compare_ether_addr(sdata->vif.addr, hdr->addr4) && + ether_addr_equal(sdata->vif.addr, hdr->addr4) && !(mpath->flags & MESH_PATH_RESOLVING) && !(mpath->flags & MESH_PATH_FIXED)) mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index baa6096..b39224d 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c
@@ -348,7 +348,7 @@ hlist_for_each_entry_rcu(node, n, bucket, list) { mpath = node->mpath; if (mpath->sdata == sdata && - compare_ether_addr(dst, mpath->dst) == 0) { + ether_addr_equal(dst, mpath->dst)) { if (MPATH_EXPIRED(mpath)) { spin_lock_bh(&mpath->state_lock); mpath->flags &= ~MESH_PATH_ACTIVE; @@ -517,7 +517,7 @@ int err = 0; u32 hash_idx; - if (compare_ether_addr(dst, sdata->vif.addr) == 0) + if (ether_addr_equal(dst, sdata->vif.addr)) /* never add ourselves as neighbours */ return -ENOTSUPP; @@ -561,7 +561,7 @@ hlist_for_each_entry(node, n, bucket, list) { mpath = node->mpath; if (mpath->sdata == sdata && - compare_ether_addr(dst, mpath->dst) == 0) + ether_addr_equal(dst, mpath->dst)) goto err_exists; } @@ -652,7 +652,7 @@ int err = 0; u32 hash_idx; - if (compare_ether_addr(dst, sdata->vif.addr) == 0) + if (ether_addr_equal(dst, sdata->vif.addr)) /* never add ourselves as neighbours */ return -ENOTSUPP; @@ -690,7 +690,7 @@ hlist_for_each_entry(node, n, bucket, list) { mpath = node->mpath; if (mpath->sdata == sdata && - compare_ether_addr(dst, mpath->dst) == 0) + ether_addr_equal(dst, mpath->dst)) goto err_exists; } @@ -884,7 +884,7 @@ hlist_for_each_entry(node, n, bucket, list) { mpath = node->mpath; if (mpath->sdata == sdata && - compare_ether_addr(addr, mpath->dst) == 0) { + ether_addr_equal(addr, mpath->dst)) { __mesh_path_del(tbl, node); goto enddel; }
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index dbd4bd9..b3b3c26 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c
@@ -1567,9 +1567,9 @@ } #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - if (beacon && net_ratelimit()) - printk(KERN_DEBUG "%s: detected beacon loss from AP " - "- sending probe request\n", sdata->name); + if (beacon) + net_dbg_ratelimited("%s: detected beacon loss from AP - sending probe request\n", + sdata->name); #endif /* @@ -1776,7 +1776,7 @@ memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN); - if (compare_ether_addr(bssid, mgmt->bssid)) + if (!ether_addr_equal(bssid, mgmt->bssid)) return RX_MGMT_NONE; auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); @@ -1853,7 +1853,7 @@ return RX_MGMT_NONE; if (!ifmgd->associated || - compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid)) + !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) return RX_MGMT_NONE; bssid = ifmgd->associated->bssid; @@ -1886,7 +1886,7 @@ return RX_MGMT_NONE; if (!ifmgd->associated || - compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid)) + !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) return RX_MGMT_NONE; reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); @@ -2113,7 +2113,7 @@ if (!assoc_data) return RX_MGMT_NONE; - if (compare_ether_addr(assoc_data->bss->bssid, mgmt->bssid)) + if (!ether_addr_equal(assoc_data->bss->bssid, mgmt->bssid)) return RX_MGMT_NONE; /* @@ -2193,8 +2193,7 @@ bool need_ps = false; if (sdata->u.mgd.associated && - compare_ether_addr(mgmt->bssid, sdata->u.mgd.associated->bssid) - == 0) { + ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) { bss = (void *)sdata->u.mgd.associated->priv; /* not previously set so we may need to recalc */ need_ps = !bss->dtim_period; @@ -2249,7 +2248,7 @@ ASSERT_MGD_MTX(ifmgd); - if (compare_ether_addr(mgmt->da, sdata->vif.addr)) + if (!ether_addr_equal(mgmt->da, sdata->vif.addr)) return; /* ignore ProbeResp to foreign address */ baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; @@ -2262,12 +2261,11 @@ ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); if (ifmgd->associated && - compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid) == 0) + ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) ieee80211_reset_ap_probe(sdata); if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies && - compare_ether_addr(mgmt->bssid, ifmgd->auth_data->bss->bssid) - == 0) { + ether_addr_equal(mgmt->bssid, ifmgd->auth_data->bss->bssid)) { /* got probe response, continue with auth */ printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name); ifmgd->auth_data->tries = 0; @@ -2324,8 +2322,7 @@ return; if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon && - compare_ether_addr(mgmt->bssid, ifmgd->assoc_data->bss->bssid) - == 0) { + ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) { ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); @@ -2340,7 +2337,7 @@ } if (!ifmgd->associated || - compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid)) + !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) return; bssid = ifmgd->associated->bssid; @@ -2407,10 +2404,8 @@ if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: cancelling probereq poll due " - "to a received beacon\n", sdata->name); - } + net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n", + sdata->name); #endif ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; mutex_lock(&local->iflist_mtx); @@ -3166,7 +3161,7 @@ return err; } } else - WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, cbss->bssid)); + WARN_ON_ONCE(!ether_addr_equal(ifmgd->bssid, cbss->bssid)); return 0; } @@ -3306,7 +3301,7 @@ bool match; /* keep sta info, bssid if matching */ - match = compare_ether_addr(ifmgd->bssid, req->bss->bssid) == 0; + match = ether_addr_equal(ifmgd->bssid, req->bss->bssid); ieee80211_destroy_auth_data(sdata, match); } @@ -3466,7 +3461,7 @@ sdata->name, req->bssid, req->reason_code); if (ifmgd->associated && - compare_ether_addr(ifmgd->associated->bssid, req->bssid) == 0) + ether_addr_equal(ifmgd->associated->bssid, req->bssid)) ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, req->reason_code, true, frame_buf); else
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 489093b..7bcecf7 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c
@@ -492,12 +492,12 @@ if (ieee80211_has_tods(hdr->frame_control) || !ieee80211_has_fromds(hdr->frame_control)) return RX_DROP_MONITOR; - if (compare_ether_addr(hdr->addr3, dev_addr) == 0) + if (ether_addr_equal(hdr->addr3, dev_addr)) return RX_DROP_MONITOR; } else { if (!ieee80211_has_a4(hdr->frame_control)) return RX_DROP_MONITOR; - if (compare_ether_addr(hdr->addr4, dev_addr) == 0) + if (ether_addr_equal(hdr->addr4, dev_addr)) return RX_DROP_MONITOR; } } @@ -1275,7 +1275,7 @@ if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) { u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, NL80211_IFTYPE_ADHOC); - if (compare_ether_addr(bssid, rx->sdata->u.ibss.bssid) == 0) { + if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid)) { sta->last_rx = jiffies; if (ieee80211_is_data(hdr->frame_control)) { sta->last_rx_rate_idx = status->rate_idx; @@ -1438,8 +1438,8 @@ */ if (((hdr->frame_control ^ f_hdr->frame_control) & cpu_to_le16(IEEE80211_FCTL_FTYPE)) || - compare_ether_addr(hdr->addr1, f_hdr->addr1) != 0 || - compare_ether_addr(hdr->addr2, f_hdr->addr2) != 0) + !ether_addr_equal(hdr->addr1, f_hdr->addr1) || + !ether_addr_equal(hdr->addr2, f_hdr->addr2)) continue; if (time_after(jiffies, entry->first_frag_time + 2 * HZ)) { @@ -1714,8 +1714,8 @@ * of whether the frame was encrypted or not. */ if (ehdr->h_proto == rx->sdata->control_port_protocol && - (compare_ether_addr(ehdr->h_dest, rx->sdata->vif.addr) == 0 || - compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0)) + (ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) || + ether_addr_equal(ehdr->h_dest, pae_group_addr))) return true; if (ieee80211_802_1x_port_control(rx) || @@ -1752,9 +1752,9 @@ * local net stack and back to the wireless medium */ xmit_skb = skb_copy(skb, GFP_ATOMIC); - if (!xmit_skb && net_ratelimit()) - printk(KERN_DEBUG "%s: failed to clone " - "multicast frame\n", dev->name); + if (!xmit_skb) + net_dbg_ratelimited("%s: failed to clone multicast frame\n", + dev->name); } else { dsta = sta_info_get(sdata, skb->data); if (dsta) { @@ -1925,7 +1925,7 @@ mpp_path_add(proxied_addr, mpp_addr, sdata); } else { spin_lock_bh(&mppath->state_lock); - if (compare_ether_addr(mppath->mpp, mpp_addr) != 0) + if (!ether_addr_equal(mppath->mpp, mpp_addr)) memcpy(mppath->mpp, mpp_addr, ETH_ALEN); spin_unlock_bh(&mppath->state_lock); } @@ -1934,7 +1934,7 @@ /* Frame has reached destination. Don't forward */ if (!is_multicast_ether_addr(hdr->addr1) && - compare_ether_addr(sdata->vif.addr, hdr->addr3) == 0) + ether_addr_equal(sdata->vif.addr, hdr->addr3)) return RX_CONTINUE; q = ieee80211_select_queue_80211(local, skb, hdr); @@ -1957,9 +1957,8 @@ fwd_skb = skb_copy(skb, GFP_ATOMIC); if (!fwd_skb) { - if (net_ratelimit()) - printk(KERN_DEBUG "%s: failed to clone mesh frame\n", - sdata->name); + net_dbg_ratelimited("%s: failed to clone mesh frame\n", + sdata->name); goto out; } @@ -2122,13 +2121,13 @@ struct sk_buff *skb; struct ieee80211_mgmt *resp; - if (compare_ether_addr(mgmt->da, sdata->vif.addr) != 0) { + if (!ether_addr_equal(mgmt->da, sdata->vif.addr)) { /* Not to own unicast address */ return; } - if (compare_ether_addr(mgmt->sa, sdata->u.mgd.bssid) != 0 || - compare_ether_addr(mgmt->bssid, sdata->u.mgd.bssid) != 0) { + if (!ether_addr_equal(mgmt->sa, sdata->u.mgd.bssid) || + !ether_addr_equal(mgmt->bssid, sdata->u.mgd.bssid)) { /* Not from the current AP or not associated yet. */ return; } @@ -2338,7 +2337,7 @@ if (sdata->vif.type != NL80211_IFTYPE_STATION) break; - if (compare_ether_addr(mgmt->bssid, sdata->u.mgd.bssid)) + if (!ether_addr_equal(mgmt->bssid, sdata->u.mgd.bssid)) break; goto queue; @@ -2772,7 +2771,7 @@ if (!bssid && !sdata->u.mgd.use_4addr) return 0; if (!multicast && - compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) { + !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { if (!(sdata->dev->flags & IFF_PROMISC) || sdata->u.mgd.use_4addr) return 0; @@ -2790,8 +2789,7 @@ return 0; status->rx_flags &= ~IEEE80211_RX_RA_MATCH; } else if (!multicast && - compare_ether_addr(sdata->vif.addr, - hdr->addr1) != 0) { + !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { if (!(sdata->dev->flags & IFF_PROMISC)) return 0; status->rx_flags &= ~IEEE80211_RX_RA_MATCH; @@ -2807,8 +2805,7 @@ break; case NL80211_IFTYPE_MESH_POINT: if (!multicast && - compare_ether_addr(sdata->vif.addr, - hdr->addr1) != 0) { + !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { if (!(sdata->dev->flags & IFF_PROMISC)) return 0; @@ -2818,8 +2815,7 @@ case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_AP: if (!bssid) { - if (compare_ether_addr(sdata->vif.addr, - hdr->addr1)) + if (!ether_addr_equal(sdata->vif.addr, hdr->addr1)) return 0; } else if (!ieee80211_bssid_match(bssid, sdata->vif.addr)) { @@ -2841,7 +2837,7 @@ case NL80211_IFTYPE_WDS: if (bssid || !ieee80211_is_data(hdr->frame_control)) return 0; - if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) + if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2)) return 0; break; default:
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 8282284..169da07 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c
@@ -194,7 +194,7 @@ presp = ieee80211_is_probe_resp(fc); if (presp) { /* ignore ProbeResp to foreign address */ - if (compare_ether_addr(mgmt->da, sdata->vif.addr)) + if (!ether_addr_equal(mgmt->da, sdata->vif.addr)) return RX_DROP_MONITOR; presp = true;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 97a9d66..f5b1638 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c
@@ -102,7 +102,7 @@ lockdep_is_held(&local->sta_mtx)); while (sta) { if (sta->sdata == sdata && - compare_ether_addr(sta->sta.addr, addr) == 0) + ether_addr_equal(sta->sta.addr, addr)) break; sta = rcu_dereference_check(sta->hnext, lockdep_is_held(&local->sta_mtx)); @@ -125,7 +125,7 @@ while (sta) { if ((sta->sdata == sdata || (sta->sdata->bss && sta->sdata->bss == sdata->bss)) && - compare_ether_addr(sta->sta.addr, addr) == 0) + ether_addr_equal(sta->sta.addr, addr)) break; sta = rcu_dereference_check(sta->hnext, lockdep_is_held(&local->sta_mtx)); @@ -302,7 +302,7 @@ if (unlikely(!ieee80211_sdata_running(sdata))) return -ENETDOWN; - if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->vif.addr) == 0 || + if (WARN_ON(ether_addr_equal(sta->sta.addr, sdata->vif.addr) || is_multicast_ether_addr(sta->sta.addr))) return -EINVAL; @@ -912,7 +912,7 @@ */ for_each_sta_info(hw_to_local(hw), addr, sta, nxt) { if (localaddr && - compare_ether_addr(sta->sdata->vif.addr, localaddr) != 0) + !ether_addr_equal(sta->sdata->vif.addr, localaddr)) continue; if (!sta->uploaded) return NULL;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 663dc90..3bb24a1 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h
@@ -502,7 +502,7 @@ nxt = _sta ? rcu_dereference(_sta->hnext) : NULL \ ) \ /* compare address and run code only if it matches */ \ - if (compare_ether_addr(_sta->sta.addr, (_addr)) == 0) + if (ether_addr_equal(_sta->sta.addr, (_addr))) /* * Get STA info by index, BROKEN!
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 05f257a..28cfa98 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c
@@ -384,7 +384,7 @@ for_each_sta_info(local, hdr->addr1, sta, tmp) { /* skip wrong virtual interface */ - if (compare_ether_addr(hdr->addr2, sta->sdata->vif.addr)) + if (!ether_addr_equal(hdr->addr2, sta->sdata->vif.addr)) continue; if (info->flags & IEEE80211_TX_STATUS_EOSP)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d67d36f..5f827a6 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c
@@ -413,9 +413,8 @@ if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= AP_MAX_BC_BUFFER) { #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - if (net_ratelimit()) - printk(KERN_DEBUG "%s: BC TX buffer full - dropping the oldest frame\n", - tx->sdata->name); + net_dbg_ratelimited("%s: BC TX buffer full - dropping the oldest frame\n", + tx->sdata->name); #endif dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); } else @@ -476,10 +475,8 @@ if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) { struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]); #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - if (net_ratelimit()) - printk(KERN_DEBUG "%s: STA %pM TX buffer for " - "AC %d full - dropping oldest frame\n", - tx->sdata->name, sta->sta.addr, ac); + net_dbg_ratelimited("%s: STA %pM TX buffer for AC %d full - dropping oldest frame\n", + tx->sdata->name, sta->sta.addr, ac); #endif dev_kfree_skb(old); } else @@ -1665,7 +1662,7 @@ skb->len >= len_rthdr + hdrlen + sizeof(rfc1042_header) + 2) { u8 *payload = (u8 *)hdr + hdrlen; - if (compare_ether_addr(payload, rfc1042_header) == 0) + if (ether_addr_equal(payload, rfc1042_header)) skb->protocol = cpu_to_be16((payload[6] << 8) | payload[7]); } @@ -1698,7 +1695,7 @@ tmp_sdata->vif.type == NL80211_IFTYPE_AP_VLAN || tmp_sdata->vif.type == NL80211_IFTYPE_WDS) continue; - if (compare_ether_addr(tmp_sdata->vif.addr, hdr->addr2) == 0) { + if (ether_addr_equal(tmp_sdata->vif.addr, hdr->addr2)) { sdata = tmp_sdata; break; } @@ -1815,9 +1812,8 @@ * is being proxied by a portal (i.e. portal address * differs from proxied address) */ - if (compare_ether_addr(sdata->vif.addr, - skb->data + ETH_ALEN) == 0 && - !(mppath && compare_ether_addr(mppath->mpp, skb->data))) { + if (ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN) && + !(mppath && !ether_addr_equal(mppath->mpp, skb->data))) { hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, skb->data, skb->data + ETH_ALEN); rcu_read_unlock(); @@ -1964,12 +1960,10 @@ if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) && !is_multicast_ether_addr(hdr.addr1) && !authorized && (cpu_to_be16(ethertype) != sdata->control_port_protocol || - compare_ether_addr(sdata->vif.addr, skb->data + ETH_ALEN)))) { + !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - if (net_ratelimit()) - printk(KERN_DEBUG "%s: dropped frame to %pM" - " (unauthorized port)\n", dev->name, - hdr.addr1); + net_dbg_ratelimited("%s: dropped frame to %pM (unauthorized port)\n", + dev->name, hdr.addr1); #endif I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
diff --git a/net/mac802154/Kconfig b/net/mac802154/Kconfig new file mode 100644 index 0000000..a967dda --- /dev/null +++ b/net/mac802154/Kconfig
@@ -0,0 +1,16 @@ +config MAC802154 + tristate "Generic IEEE 802.15.4 Soft Networking Stack (mac802154)" + depends on IEEE802154 && EXPERIMENTAL + select CRC_CCITT + ---help--- + This option enables the hardware independent IEEE 802.15.4 + networking stack for SoftMAC devices (the ones implementing + only PHY level of IEEE 802.15.4 standard). + + Note: this implementation is neither certified, nor feature + complete! Compatibility with other implementations hasn't + been tested yet! + + If you plan to use HardMAC IEEE 802.15.4 devices, you can + say N here. Alternatievly you can say M to compile it as + module.
diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile new file mode 100644 index 0000000..ec1bd3f --- /dev/null +++ b/net/mac802154/Makefile
@@ -0,0 +1,2 @@ +obj-$(CONFIG_MAC802154) += mac802154.o +mac802154-objs := ieee802154_dev.o rx.o tx.o mac_cmd.o mib.o monitor.o
diff --git a/net/mac802154/ieee802154_dev.c b/net/mac802154/ieee802154_dev.c new file mode 100644 index 0000000..e3edfb0 --- /dev/null +++ b/net/mac802154/ieee802154_dev.c
@@ -0,0 +1,294 @@ +/* + * Copyright (C) 2007-2012 Siemens AG + * + * Written by: + * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> + * + * Based on the code from 'linux-zigbee.sourceforge.net' project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/netdevice.h> + +#include <net/netlink.h> +#include <linux/nl802154.h> +#include <net/mac802154.h> +#include <net/route.h> +#include <net/wpan-phy.h> + +#include "mac802154.h" + +int mac802154_slave_open(struct net_device *dev) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct mac802154_priv *ipriv = priv->hw; + int res = 0; + + if (ipriv->open_count++ == 0) { + res = ipriv->ops->start(&ipriv->hw); + WARN_ON(res); + if (res) + goto err; + } + + if (ipriv->ops->ieee_addr) { + res = ipriv->ops->ieee_addr(&ipriv->hw, dev->dev_addr); + WARN_ON(res); + if (res) + goto err; + mac802154_dev_set_ieee_addr(dev); + } + + netif_start_queue(dev); + return 0; +err: + priv->hw->open_count--; + + return res; +} + +int mac802154_slave_close(struct net_device *dev) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct mac802154_priv *ipriv = priv->hw; + + netif_stop_queue(dev); + + if (!--ipriv->open_count) + ipriv->ops->stop(&ipriv->hw); + + return 0; +} + +static int +mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) +{ + struct mac802154_sub_if_data *priv; + struct mac802154_priv *ipriv; + int err; + + ipriv = wpan_phy_priv(phy); + + priv = netdev_priv(dev); + priv->dev = dev; + priv->hw = ipriv; + + dev->needed_headroom = ipriv->hw.extra_tx_headroom; + + SET_NETDEV_DEV(dev, &ipriv->phy->dev); + + mutex_lock(&ipriv->slaves_mtx); + if (!ipriv->running) { + mutex_unlock(&ipriv->slaves_mtx); + return -ENODEV; + } + mutex_unlock(&ipriv->slaves_mtx); + + err = register_netdev(dev); + if (err < 0) + return err; + + rtnl_lock(); + mutex_lock(&ipriv->slaves_mtx); + list_add_tail_rcu(&priv->list, &ipriv->slaves); + mutex_unlock(&ipriv->slaves_mtx); + rtnl_unlock(); + + return 0; +} + +static void +mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev) +{ + struct mac802154_sub_if_data *sdata; + ASSERT_RTNL(); + + sdata = netdev_priv(dev); + + BUG_ON(sdata->hw->phy != phy); + + mutex_lock(&sdata->hw->slaves_mtx); + list_del_rcu(&sdata->list); + mutex_unlock(&sdata->hw->slaves_mtx); + + synchronize_rcu(); + unregister_netdevice(sdata->dev); +} + +static struct net_device * +mac802154_add_iface(struct wpan_phy *phy, const char *name, int type) +{ + struct net_device *dev; + int err = -ENOMEM; + + switch (type) { + case IEEE802154_DEV_MONITOR: + dev = alloc_netdev(sizeof(struct mac802154_sub_if_data), + name, mac802154_monitor_setup); + break; + default: + dev = NULL; + err = -EINVAL; + break; + } + if (!dev) + goto err; + + err = mac802154_netdev_register(phy, dev); + if (err) + goto err_free; + + dev_hold(dev); /* we return an incremented device refcount */ + return dev; + +err_free: + free_netdev(dev); +err: + return ERR_PTR(err); +} + +struct ieee802154_dev * +ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops) +{ + struct wpan_phy *phy; + struct mac802154_priv *priv; + size_t priv_size; + + if (!ops || !ops->xmit || !ops->ed || !ops->start || + !ops->stop || !ops->set_channel) { + printk(KERN_ERR + "undefined IEEE802.15.4 device operations\n"); + return NULL; + } + + /* Ensure 32-byte alignment of our private data and hw private data. + * We use the wpan_phy priv data for both our mac802154_priv and for + * the driver's private data + * + * in memory it'll be like this: + * + * +-----------------------+ + * | struct wpan_phy | + * +-----------------------+ + * | struct mac802154_priv | + * +-----------------------+ + * | driver's private data | + * +-----------------------+ + * + * Due to ieee802154 layer isn't aware of driver and MAC structures, + * so lets allign them here. + */ + + priv_size = ALIGN(sizeof(*priv), NETDEV_ALIGN) + priv_data_len; + + phy = wpan_phy_alloc(priv_size); + if (!phy) { + printk(KERN_ERR + "failure to allocate master IEEE802.15.4 device\n"); + return NULL; + } + + priv = wpan_phy_priv(phy); + priv->hw.phy = priv->phy = phy; + priv->hw.priv = (char *)priv + ALIGN(sizeof(*priv), NETDEV_ALIGN); + priv->ops = ops; + + INIT_LIST_HEAD(&priv->slaves); + mutex_init(&priv->slaves_mtx); + + return &priv->hw; +} +EXPORT_SYMBOL(ieee802154_alloc_device); + +void ieee802154_free_device(struct ieee802154_dev *hw) +{ + struct mac802154_priv *priv = mac802154_to_priv(hw); + + BUG_ON(!list_empty(&priv->slaves)); + + wpan_phy_free(priv->phy); + + mutex_destroy(&priv->slaves_mtx); +} +EXPORT_SYMBOL(ieee802154_free_device); + +int ieee802154_register_device(struct ieee802154_dev *dev) +{ + struct mac802154_priv *priv = mac802154_to_priv(dev); + int rc = -ENOMEM; + + priv->dev_workqueue = + create_singlethread_workqueue(wpan_phy_name(priv->phy)); + if (!priv->dev_workqueue) + goto out; + + wpan_phy_set_dev(priv->phy, priv->hw.parent); + + priv->phy->add_iface = mac802154_add_iface; + priv->phy->del_iface = mac802154_del_iface; + + rc = wpan_phy_register(priv->phy); + if (rc < 0) + goto out_wq; + + rtnl_lock(); + + mutex_lock(&priv->slaves_mtx); + priv->running = MAC802154_DEVICE_RUN; + mutex_unlock(&priv->slaves_mtx); + + rtnl_unlock(); + + return 0; + +out_wq: + destroy_workqueue(priv->dev_workqueue); +out: + return rc; +} +EXPORT_SYMBOL(ieee802154_register_device); + +void ieee802154_unregister_device(struct ieee802154_dev *dev) +{ + struct mac802154_priv *priv = mac802154_to_priv(dev); + struct mac802154_sub_if_data *sdata, *next; + + flush_workqueue(priv->dev_workqueue); + destroy_workqueue(priv->dev_workqueue); + + rtnl_lock(); + + mutex_lock(&priv->slaves_mtx); + priv->running = MAC802154_DEVICE_STOPPED; + mutex_unlock(&priv->slaves_mtx); + + list_for_each_entry_safe(sdata, next, &priv->slaves, list) { + mutex_lock(&sdata->hw->slaves_mtx); + list_del(&sdata->list); + mutex_unlock(&sdata->hw->slaves_mtx); + + unregister_netdevice(sdata->dev); + } + + rtnl_unlock(); + + wpan_phy_unregister(priv->phy); +} +EXPORT_SYMBOL(ieee802154_unregister_device); + +MODULE_DESCRIPTION("IEEE 802.15.4 implementation"); +MODULE_LICENSE("GPL v2");
diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h new file mode 100644 index 0000000..789d9c9 --- /dev/null +++ b/net/mac802154/mac802154.h
@@ -0,0 +1,109 @@ +/* + * Copyright (C) 2007-2012 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Written by: + * Pavel Smolenskiy <pavel.smolenskiy@gmail.com> + * Maxim Gorbachyov <maxim.gorbachev@siemens.com> + * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> + * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> + */ +#ifndef MAC802154_H +#define MAC802154_H + +/* mac802154 device private data */ +struct mac802154_priv { + struct ieee802154_dev hw; + struct ieee802154_ops *ops; + + /* ieee802154 phy */ + struct wpan_phy *phy; + + int open_count; + + /* As in mac80211 slaves list is modified: + * 1) under the RTNL + * 2) protected by slaves_mtx; + * 3) in an RCU manner + * + * So atomic readers can use any of this protection methods. + */ + struct list_head slaves; + struct mutex slaves_mtx; + + /* This one is used for scanning and other jobs not to be interfered + * with serial driver. + */ + struct workqueue_struct *dev_workqueue; + + /* SoftMAC device is registered and running. One can add subinterfaces. + * This flag should be modified under slaves_mtx and RTNL, so you can + * read them using any of protection methods. + */ + bool running; +}; + +#define MAC802154_DEVICE_STOPPED 0x00 +#define MAC802154_DEVICE_RUN 0x01 + +/* Slave interface definition. + * + * Slaves represent typical network interfaces available from userspace. + * Each ieee802154 device/transceiver may have several slaves and able + * to be associated with several networks at the same time. + */ +struct mac802154_sub_if_data { + struct list_head list; /* the ieee802154_priv->slaves list */ + + struct mac802154_priv *hw; + struct net_device *dev; + + int type; + + spinlock_t mib_lock; + + __le16 pan_id; + __le16 short_addr; + + u8 chan; + u8 page; + + /* MAC BSN field */ + u8 bsn; + /* MAC DSN field */ + u8 dsn; +}; + +#define mac802154_to_priv(_hw) container_of(_hw, struct mac802154_priv, hw) + +#define MAC802154_MAX_XMIT_ATTEMPTS 3 + +#define MAC802154_CHAN_NONE (~(u8)0) /* No channel is assigned */ + +extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; + +int mac802154_slave_open(struct net_device *dev); +int mac802154_slave_close(struct net_device *dev); + +void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb); +void mac802154_monitor_setup(struct net_device *dev); + +netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, + u8 page, u8 chan); + +/* MIB callbacks */ +void mac802154_dev_set_ieee_addr(struct net_device *dev); + +#endif /* MAC802154_H */
diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c new file mode 100644 index 0000000..7a5d0e0 --- /dev/null +++ b/net/mac802154/mac_cmd.c
@@ -0,0 +1,45 @@ +/* + * MAC commands interface + * + * Copyright 2007-2012 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Written by: + * Sergey Lapin <slapin@ossfans.org> + * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> + * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> + */ + +#include <linux/skbuff.h> +#include <linux/if_arp.h> + +#include <net/ieee802154_netdev.h> +#include <net/wpan-phy.h> +#include <net/mac802154.h> + +#include "mac802154.h" + +struct wpan_phy *mac802154_get_phy(const struct net_device *dev) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + + BUG_ON(dev->type != ARPHRD_IEEE802154); + + return to_phy(get_device(&priv->hw->phy->dev)); +} + +struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced = { + .get_phy = mac802154_get_phy, +};
diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c new file mode 100644 index 0000000..ab59821 --- /dev/null +++ b/net/mac802154/mib.c
@@ -0,0 +1,93 @@ +/* + * Copyright 2007-2012 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Written by: + * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> + * Sergey Lapin <slapin@ossfans.org> + * Maxim Gorbachyov <maxim.gorbachev@siemens.com> + * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> + */ + +#include <linux/if_arp.h> + +#include <net/mac802154.h> +#include <net/wpan-phy.h> + +#include "mac802154.h" + +struct hw_addr_filt_notify_work { + struct work_struct work; + struct net_device *dev; + unsigned long changed; +}; + +struct mac802154_priv *mac802154_slave_get_priv(struct net_device *dev) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + + BUG_ON(dev->type != ARPHRD_IEEE802154); + + return priv->hw; +} + +static void hw_addr_notify(struct work_struct *work) +{ + struct hw_addr_filt_notify_work *nw = container_of(work, + struct hw_addr_filt_notify_work, work); + struct mac802154_priv *hw = mac802154_slave_get_priv(nw->dev); + int res; + + res = hw->ops->set_hw_addr_filt(&hw->hw, + &hw->hw.hw_filt, + nw->changed); + if (res) + pr_debug("failed changed mask %lx\n", nw->changed); + + kfree(nw); + + return; +} + +static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct hw_addr_filt_notify_work *work; + + work = kzalloc(sizeof(*work), GFP_ATOMIC); + if (!work) + return; + + INIT_WORK(&work->work, hw_addr_notify); + work->dev = dev; + work->changed = changed; + queue_work(priv->hw->dev_workqueue, &work->work); + + return; +} + +void mac802154_dev_set_ieee_addr(struct net_device *dev) +{ + struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct mac802154_priv *mac = priv->hw; + + if (mac->ops->set_hw_addr_filt && + memcmp(mac->hw.hw_filt.ieee_addr, + dev->dev_addr, IEEE802154_ADDR_LEN)) { + memcpy(mac->hw.hw_filt.ieee_addr, + dev->dev_addr, IEEE802154_ADDR_LEN); + set_hw_addr_filt(dev, IEEE802515_AFILT_IEEEADDR_CHANGED); + } +}
diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c new file mode 100644 index 0000000..434a26f --- /dev/null +++ b/net/mac802154/monitor.c
@@ -0,0 +1,116 @@ +/* + * Copyright 2007, 2008, 2009 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Written by: + * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> + * Sergey Lapin <slapin@ossfans.org> + * Maxim Gorbachyov <maxim.gorbachev@siemens.com> + * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> + */ + +#include <linux/netdevice.h> +#include <linux/skbuff.h> +#include <linux/if_arp.h> +#include <linux/crc-ccitt.h> + +#include <net/ieee802154.h> +#include <net/mac802154.h> +#include <net/netlink.h> +#include <net/wpan-phy.h> +#include <linux/nl802154.h> + +#include "mac802154.h" + +static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct mac802154_sub_if_data *priv; + u8 chan, page; + + priv = netdev_priv(dev); + + /* FIXME: locking */ + chan = priv->hw->phy->current_channel; + page = priv->hw->phy->current_page; + + if (chan == MAC802154_CHAN_NONE) /* not initialized */ + return NETDEV_TX_OK; + + if (WARN_ON(page >= WPAN_NUM_PAGES) || + WARN_ON(chan >= WPAN_NUM_CHANNELS)) + return NETDEV_TX_OK; + + skb->skb_iif = dev->ifindex; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + return mac802154_tx(priv->hw, skb, page, chan); +} + + +void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb) +{ + struct sk_buff *skb2; + struct mac802154_sub_if_data *sdata; + u16 crc = crc_ccitt(0, skb->data, skb->len); + u8 *data; + + rcu_read_lock(); + list_for_each_entry_rcu(sdata, &priv->slaves, list) { + if (sdata->type != IEEE802154_DEV_MONITOR) + continue; + + skb2 = skb_clone(skb, GFP_ATOMIC); + skb2->dev = sdata->dev; + skb2->pkt_type = PACKET_HOST; + data = skb_put(skb2, 2); + data[0] = crc & 0xff; + data[1] = crc >> 8; + + netif_rx_ni(skb2); + } + rcu_read_unlock(); +} + +static const struct net_device_ops mac802154_monitor_ops = { + .ndo_open = mac802154_slave_open, + .ndo_stop = mac802154_slave_close, + .ndo_start_xmit = mac802154_monitor_xmit, +}; + +void mac802154_monitor_setup(struct net_device *dev) +{ + struct mac802154_sub_if_data *priv; + + dev->addr_len = 0; + dev->hard_header_len = 0; + dev->needed_tailroom = 2; /* room for FCS */ + dev->mtu = IEEE802154_MTU; + dev->tx_queue_len = 10; + dev->type = ARPHRD_IEEE802154_MONITOR; + dev->flags = IFF_NOARP | IFF_BROADCAST; + dev->watchdog_timeo = 0; + + dev->destructor = free_netdev; + dev->netdev_ops = &mac802154_monitor_ops; + dev->ml_priv = &mac802154_mlme_reduced; + + priv = netdev_priv(dev); + priv->type = IEEE802154_DEV_MONITOR; + + priv->chan = MAC802154_CHAN_NONE; /* not initialized */ + priv->page = 0; +}
diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c new file mode 100644 index 0000000..4a7d76d --- /dev/null +++ b/net/mac802154/rx.c
@@ -0,0 +1,114 @@ +/* + * Copyright (C) 2007-2012 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Written by: + * Pavel Smolenskiy <pavel.smolenskiy@gmail.com> + * Maxim Gorbachyov <maxim.gorbachev@siemens.com> + * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> + * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/workqueue.h> +#include <linux/netdevice.h> +#include <linux/crc-ccitt.h> + +#include <net/mac802154.h> +#include <net/ieee802154_netdev.h> + +#include "mac802154.h" + +/* The IEEE 802.15.4 standard defines 4 MAC packet types: + * - beacon frame + * - MAC command frame + * - acknowledgement frame + * - data frame + * + * and only the data frame should be pushed to the upper layers, other types + * are just internal MAC layer management information. So only data packets + * are going to be sent to the networking queue, all other will be processed + * right here by using the device workqueue. + */ +struct rx_work { + struct sk_buff *skb; + struct work_struct work; + struct ieee802154_dev *dev; + u8 lqi; +}; + +static void +mac802154_subif_rx(struct ieee802154_dev *hw, struct sk_buff *skb, u8 lqi) +{ + struct mac802154_priv *priv = mac802154_to_priv(hw); + + mac_cb(skb)->lqi = lqi; + skb->protocol = htons(ETH_P_IEEE802154); + skb_reset_mac_header(skb); + + BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb) > sizeof(skb->cb)); + + if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { + u16 crc; + + if (skb->len < 2) { + pr_debug("got invalid frame\n"); + goto out; + } + crc = crc_ccitt(0, skb->data, skb->len); + if (crc) { + pr_debug("CRC mismatch\n"); + goto out; + } + skb_trim(skb, skb->len - 2); /* CRC */ + } + + mac802154_monitors_rx(priv, skb); +out: + dev_kfree_skb(skb); + return; +} + +static void mac802154_rx_worker(struct work_struct *work) +{ + struct rx_work *rw = container_of(work, struct rx_work, work); + struct sk_buff *skb = rw->skb; + + mac802154_subif_rx(rw->dev, skb, rw->lqi); + kfree(rw); +} + +void +ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, u8 lqi) +{ + struct mac802154_priv *priv = mac802154_to_priv(dev); + struct rx_work *work; + + if (!skb) + return; + + work = kzalloc(sizeof(struct rx_work), GFP_ATOMIC); + if (!work) + return; + + INIT_WORK(&work->work, mac802154_rx_worker); + work->skb = skb; + work->dev = dev; + work->lqi = lqi; + + queue_work(priv->dev_workqueue, &work->work); +} +EXPORT_SYMBOL(ieee802154_rx_irqsafe);
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c new file mode 100644 index 0000000..8781d8f9 --- /dev/null +++ b/net/mac802154/tx.c
@@ -0,0 +1,116 @@ +/* + * Copyright 2007-2012 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Written by: + * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> + * Sergey Lapin <slapin@ossfans.org> + * Maxim Gorbachyov <maxim.gorbachev@siemens.com> + * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> + */ + +#include <linux/netdevice.h> +#include <linux/if_arp.h> +#include <linux/crc-ccitt.h> + +#include <net/mac802154.h> +#include <net/wpan-phy.h> + +#include "mac802154.h" + +/* IEEE 802.15.4 transceivers can sleep during the xmit session, so process + * packets through the workqueue. + */ +struct xmit_work { + struct sk_buff *skb; + struct work_struct work; + struct mac802154_priv *priv; + u8 chan; + u8 page; + u8 xmit_attempts; +}; + +static void mac802154_xmit_worker(struct work_struct *work) +{ + struct xmit_work *xw = container_of(work, struct xmit_work, work); + int res; + + mutex_lock(&xw->priv->phy->pib_lock); + if (xw->priv->phy->current_channel != xw->chan || + xw->priv->phy->current_page != xw->page) { + res = xw->priv->ops->set_channel(&xw->priv->hw, + xw->page, + xw->chan); + if (res) { + pr_debug("set_channel failed\n"); + goto out; + } + } + + res = xw->priv->ops->xmit(&xw->priv->hw, xw->skb); + +out: + mutex_unlock(&xw->priv->phy->pib_lock); + + if (res) { + if (xw->xmit_attempts++ < MAC802154_MAX_XMIT_ATTEMPTS) { + queue_work(xw->priv->dev_workqueue, &xw->work); + return; + } else + pr_debug("transmission failed for %d times", + MAC802154_MAX_XMIT_ATTEMPTS); + } + + dev_kfree_skb(xw->skb); + + kfree(xw); +} + +netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, + u8 page, u8 chan) +{ + struct xmit_work *work; + + if (!(priv->phy->channels_supported[page] & (1 << chan))) + WARN_ON(1); + return NETDEV_TX_OK; + + if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { + u16 crc = crc_ccitt(0, skb->data, skb->len); + u8 *data = skb_put(skb, 2); + data[0] = crc & 0xff; + data[1] = crc >> 8; + } + + if (skb_cow_head(skb, priv->hw.extra_tx_headroom)) { + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + + work = kzalloc(sizeof(struct xmit_work), GFP_ATOMIC); + if (!work) + return NETDEV_TX_BUSY; + + INIT_WORK(&work->work, mac802154_xmit_worker); + work->skb = skb; + work->priv = priv; + work->page = page; + work->chan = chan; + work->xmit_attempts = 0; + + queue_work(priv->dev_workqueue, &work->work); + + return NETDEV_TX_OK; +}
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 0c6f67e..209c1ed 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig
@@ -509,6 +509,21 @@ since you can easily create immortal packets that loop forever on the network. +config NETFILTER_XT_TARGET_HMARK + tristate '"HMARK" target support' + depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n) + depends on NETFILTER_ADVANCED + ---help--- + This option adds the "HMARK" target. + + The target allows you to create rules in the "raw" and "mangle" tables + which set the skbuff mark by means of hash calculation within a given + range. The nfmark can influence the routing method (see "Use netfilter + MARK value as routing key") and can also be used by other subsystems to + change their behaviour. + + To compile it as a module, choose M here. If unsure, say N. + config NETFILTER_XT_TARGET_IDLETIMER tristate "IDLETIMER target support" depends on NETFILTER_ADVANCED
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index ca36765..4e7960cc 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o +obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o obj-$(CONFIG_NETFILTER_XT_TARGET_LOG) += xt_LOG.o obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c index 0bb16c46..d7eaf10 100644 --- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c +++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
@@ -111,7 +111,7 @@ return -EAGAIN; case MAC_FILLED: return data->ether == NULL || - compare_ether_addr(data->ether, elem->ether) == 0; + ether_addr_equal(data->ether, elem->ether); } return 0; } @@ -225,7 +225,7 @@ return -EAGAIN; case MAC_FILLED: return (data->ether == NULL || - compare_ether_addr(data->ether, elem->ether) == 0) && + ether_addr_equal(data->ether, elem->ether)) && !bitmap_expired(map, data->id); } return 0;
diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c index 507fe93..a68dbd4 100644 --- a/net/netfilter/ipset/ip_set_hash_ip.c +++ b/net/netfilter/ipset/ip_set_hash_ip.c
@@ -368,6 +368,7 @@ { u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; u8 netmask, hbits; + size_t hsize; struct ip_set_hash *h; if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) @@ -409,9 +410,12 @@ h->timeout = IPSET_NO_TIMEOUT; hbits = htable_bits(hashsize); - h->table = ip_set_alloc( - sizeof(struct htable) - + jhash_size(hbits) * sizeof(struct hbucket)); + hsize = htable_size(hbits); + if (hsize == 0) { + kfree(h); + return -ENOMEM; + } + h->table = ip_set_alloc(hsize); if (!h->table) { kfree(h); return -ENOMEM;
diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c index 68f284c9..92722bb 100644 --- a/net/netfilter/ipset/ip_set_hash_ipport.c +++ b/net/netfilter/ipset/ip_set_hash_ipport.c
@@ -452,6 +452,7 @@ struct ip_set_hash *h; u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; u8 hbits; + size_t hsize; if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) return -IPSET_ERR_INVALID_FAMILY; @@ -479,9 +480,12 @@ h->timeout = IPSET_NO_TIMEOUT; hbits = htable_bits(hashsize); - h->table = ip_set_alloc( - sizeof(struct htable) - + jhash_size(hbits) * sizeof(struct hbucket)); + hsize = htable_size(hbits); + if (hsize == 0) { + kfree(h); + return -ENOMEM; + } + h->table = ip_set_alloc(hsize); if (!h->table) { kfree(h); return -ENOMEM;
diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c index 1eec4b9..0637ce0 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportip.c +++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
@@ -470,6 +470,7 @@ struct ip_set_hash *h; u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; u8 hbits; + size_t hsize; if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) return -IPSET_ERR_INVALID_FAMILY; @@ -497,9 +498,12 @@ h->timeout = IPSET_NO_TIMEOUT; hbits = htable_bits(hashsize); - h->table = ip_set_alloc( - sizeof(struct htable) - + jhash_size(hbits) * sizeof(struct hbucket)); + hsize = htable_size(hbits); + if (hsize == 0) { + kfree(h); + return -ENOMEM; + } + h->table = ip_set_alloc(hsize); if (!h->table) { kfree(h); return -ENOMEM;
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c index 62d66ec..1ce21ca9 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
@@ -619,6 +619,7 @@ struct ip_set_hash *h; u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; u8 hbits; + size_t hsize; if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) return -IPSET_ERR_INVALID_FAMILY; @@ -648,9 +649,12 @@ h->timeout = IPSET_NO_TIMEOUT; hbits = htable_bits(hashsize); - h->table = ip_set_alloc( - sizeof(struct htable) - + jhash_size(hbits) * sizeof(struct hbucket)); + hsize = htable_size(hbits); + if (hsize == 0) { + kfree(h); + return -ENOMEM; + } + h->table = ip_set_alloc(hsize); if (!h->table) { kfree(h); return -ENOMEM;
diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c index 6607a81..c57a6a0 100644 --- a/net/netfilter/ipset/ip_set_hash_net.c +++ b/net/netfilter/ipset/ip_set_hash_net.c
@@ -463,6 +463,7 @@ u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; struct ip_set_hash *h; u8 hbits; + size_t hsize; if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) return -IPSET_ERR_INVALID_FAMILY; @@ -492,9 +493,12 @@ h->timeout = IPSET_NO_TIMEOUT; hbits = htable_bits(hashsize); - h->table = ip_set_alloc( - sizeof(struct htable) - + jhash_size(hbits) * sizeof(struct hbucket)); + hsize = htable_size(hbits); + if (hsize == 0) { + kfree(h); + return -ENOMEM; + } + h->table = ip_set_alloc(hsize); if (!h->table) { kfree(h); return -ENOMEM;
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c index 6093f3d..ee863943 100644 --- a/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -726,6 +726,7 @@ struct ip_set_hash *h; u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; u8 hbits; + size_t hsize; if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) return -IPSET_ERR_INVALID_FAMILY; @@ -756,9 +757,12 @@ h->ahash_max = AHASH_MAX_SIZE; hbits = htable_bits(hashsize); - h->table = ip_set_alloc( - sizeof(struct htable) - + jhash_size(hbits) * sizeof(struct hbucket)); + hsize = htable_size(hbits); + if (hsize == 0) { + kfree(h); + return -ENOMEM; + } + h->table = ip_set_alloc(hsize); if (!h->table) { kfree(h); return -ENOMEM;
diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c index ae3c644..fc3143a 100644 --- a/net/netfilter/ipset/ip_set_hash_netport.c +++ b/net/netfilter/ipset/ip_set_hash_netport.c
@@ -575,6 +575,7 @@ struct ip_set_hash *h; u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; u8 hbits; + size_t hsize; if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) return -IPSET_ERR_INVALID_FAMILY; @@ -604,9 +605,12 @@ h->timeout = IPSET_NO_TIMEOUT; hbits = htable_bits(hashsize); - h->table = ip_set_alloc( - sizeof(struct htable) - + jhash_size(hbits) * sizeof(struct hbucket)); + hsize = htable_size(hbits); + if (hsize == 0) { + kfree(h); + return -ENOMEM; + } + h->table = ip_set_alloc(hsize); if (!h->table) { kfree(h); return -ENOMEM;
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c index 13fd2c5..f2de8c5 100644 --- a/net/netfilter/nf_conntrack_amanda.c +++ b/net/netfilter/nf_conntrack_amanda.c
@@ -107,8 +107,7 @@ /* No data? */ dataoff = protoff + sizeof(struct udphdr); if (dataoff >= skb->len) { - if (net_ratelimit()) - printk(KERN_ERR "amanda_help: skblen = %u\n", skb->len); + net_err_ratelimited("amanda_help: skblen = %u\n", skb->len); return NF_ACCEPT; }
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 32c5909..ac3af97 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c
@@ -683,10 +683,7 @@ unlikely(atomic_read(&net->ct.count) > nf_conntrack_max)) { if (!early_drop(net, hash_bucket(hash, net))) { atomic_dec(&net->ct.count); - if (net_ratelimit()) - printk(KERN_WARNING - "nf_conntrack: table full, dropping" - " packet.\n"); + net_warn_ratelimited("nf_conntrack: table full, dropping packet\n"); return ERR_PTR(-ENOMEM); } }
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index 4147ba3..45cf602 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c
@@ -424,9 +424,7 @@ } if (net->ct.expect_count >= nf_ct_expect_max) { - if (net_ratelimit()) - printk(KERN_WARNING - "nf_conntrack: expectation table full\n"); + net_warn_ratelimited("nf_conntrack: expectation table full\n"); ret = -EMFILE; } out:
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index 471b054..46d69d7 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -605,8 +605,7 @@ drop: spin_unlock_bh(&nf_h323_lock); - if (net_ratelimit()) - pr_info("nf_ct_h245: packet dropped\n"); + net_info_ratelimited("nf_ct_h245: packet dropped\n"); return NF_DROP; } @@ -1156,8 +1155,7 @@ drop: spin_unlock_bh(&nf_h323_lock); - if (net_ratelimit()) - pr_info("nf_ct_q931: packet dropped\n"); + net_info_ratelimited("nf_ct_q931: packet dropped\n"); return NF_DROP; } @@ -1731,8 +1729,7 @@ drop: spin_unlock_bh(&nf_h323_lock); - if (net_ratelimit()) - pr_info("nf_ct_ras: packet dropped\n"); + net_info_ratelimited("nf_ct_ras: packet dropped\n"); return NF_DROP; } @@ -1833,4 +1830,6 @@ MODULE_DESCRIPTION("H.323 connection tracking helper"); MODULE_LICENSE("GPL"); MODULE_ALIAS("ip_conntrack_h323"); -MODULE_ALIAS_NFCT_HELPER("h323"); +MODULE_ALIAS_NFCT_HELPER("RAS"); +MODULE_ALIAS_NFCT_HELPER("Q.931"); +MODULE_ALIAS_NFCT_HELPER("H.245");
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c index 4f9390b..81366c1 100644 --- a/net/netfilter/nf_conntrack_irc.c +++ b/net/netfilter/nf_conntrack_irc.c
@@ -185,11 +185,9 @@ tuple = &ct->tuplehash[dir].tuple; if (tuple->src.u3.ip != dcc_ip && tuple->dst.u3.ip != dcc_ip) { - if (net_ratelimit()) - printk(KERN_WARNING - "Forged DCC command from %pI4: %pI4:%u\n", - &tuple->src.u3.ip, - &dcc_ip, dcc_port); + net_warn_ratelimited("Forged DCC command from %pI4: %pI4:%u\n", + &tuple->src.u3.ip, + &dcc_ip, dcc_port); continue; }
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 4dfbfa8..21ff1a9 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -952,7 +952,8 @@ spin_unlock_bh(&ct->lock); if (LOG_INVALID(net, IPPROTO_TCP)) nf_log_packet(pf, 0, skb, NULL, NULL, NULL, - "nf_ct_tcp: invalid packet ignored "); + "nf_ct_tcp: invalid packet ignored in " + "state %s ", tcp_conntrack_names[old_state]); return NF_ACCEPT; case TCP_CONNTRACK_MAX: /* Invalid packet */
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 8d6bcf3..4162437 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c
@@ -395,8 +395,7 @@ nla_put_failure: if (skb) kfree_skb(skb); - if (net_ratelimit()) - printk(KERN_ERR "nf_queue: error creating packet message\n"); + net_err_ratelimited("nf_queue: error creating packet message\n"); return NULL; } @@ -433,10 +432,8 @@ } if (queue->queue_total >= queue->queue_maxlen) { queue->queue_dropped++; - if (net_ratelimit()) - printk(KERN_WARNING "nf_queue: full at %d entries, " - "dropping packets(s).\n", - queue->queue_total); + net_warn_ratelimited("nf_queue: full at %d entries, dropping packets(s)\n", + queue->queue_total); goto err_out_free_nskb; } entry->id = ++queue->id_sequence;
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index 3746d8b..a51de9b 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c
@@ -17,7 +17,6 @@ #include <net/netfilter/nf_conntrack_l4proto.h> #include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_ecache.h> -#include <net/netfilter/nf_conntrack_l4proto.h> #include <net/netfilter/nf_conntrack_timeout.h> #include <net/netfilter/nf_conntrack_zones.h>
diff --git a/net/netfilter/xt_HMARK.c b/net/netfilter/xt_HMARK.c new file mode 100644 index 0000000..0a96a43 --- /dev/null +++ b/net/netfilter/xt_HMARK.c
@@ -0,0 +1,362 @@ +/* + * xt_HMARK - Netfilter module to set mark by means of hashing + * + * (C) 2012 by Hans Schillstrom <hans.schillstrom@ericsson.com> + * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org> + * + * 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/skbuff.h> +#include <linux/icmp.h> + +#include <linux/netfilter/x_tables.h> +#include <linux/netfilter/xt_HMARK.h> + +#include <net/ip.h> +#if IS_ENABLED(CONFIG_NF_CONNTRACK) +#include <net/netfilter/nf_conntrack.h> +#endif +#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) +#include <net/ipv6.h> +#include <linux/netfilter_ipv6/ip6_tables.h> +#endif + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Hans Schillstrom <hans.schillstrom@ericsson.com>"); +MODULE_DESCRIPTION("Xtables: packet marking using hash calculation"); +MODULE_ALIAS("ipt_HMARK"); +MODULE_ALIAS("ip6t_HMARK"); + +struct hmark_tuple { + u32 src; + u32 dst; + union hmark_ports uports; + uint8_t proto; +}; + +static inline u32 hmark_addr6_mask(const __u32 *addr32, const __u32 *mask) +{ + return (addr32[0] & mask[0]) ^ + (addr32[1] & mask[1]) ^ + (addr32[2] & mask[2]) ^ + (addr32[3] & mask[3]); +} + +static inline u32 +hmark_addr_mask(int l3num, const __u32 *addr32, const __u32 *mask) +{ + switch (l3num) { + case AF_INET: + return *addr32 & *mask; + case AF_INET6: + return hmark_addr6_mask(addr32, mask); + } + return 0; +} + +static int +hmark_ct_set_htuple(const struct sk_buff *skb, struct hmark_tuple *t, + const struct xt_hmark_info *info) +{ +#if IS_ENABLED(CONFIG_NF_CONNTRACK) + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = nf_ct_get(skb, &ctinfo); + struct nf_conntrack_tuple *otuple; + struct nf_conntrack_tuple *rtuple; + + if (ct == NULL || nf_ct_is_untracked(ct)) + return -1; + + otuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; + rtuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; + + t->src = hmark_addr_mask(otuple->src.l3num, otuple->src.u3.all, + info->src_mask.all); + t->dst = hmark_addr_mask(otuple->src.l3num, rtuple->src.u3.all, + info->dst_mask.all); + + if (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)) + return 0; + + t->proto = nf_ct_protonum(ct); + if (t->proto != IPPROTO_ICMP) { + t->uports.p16.src = otuple->src.u.all; + t->uports.p16.dst = rtuple->src.u.all; + t->uports.v32 = (t->uports.v32 & info->port_mask.v32) | + info->port_set.v32; + if (t->uports.p16.dst < t->uports.p16.src) + swap(t->uports.p16.dst, t->uports.p16.src); + } + + return 0; +#else + return -1; +#endif +} + +static inline u32 +hmark_hash(struct hmark_tuple *t, const struct xt_hmark_info *info) +{ + u32 hash; + + if (t->dst < t->src) + swap(t->src, t->dst); + + hash = jhash_3words(t->src, t->dst, t->uports.v32, info->hashrnd); + hash = hash ^ (t->proto & info->proto_mask); + + return (((u64)hash * info->hmodulus) >> 32) + info->hoffset; +} + +static void +hmark_set_tuple_ports(const struct sk_buff *skb, unsigned int nhoff, + struct hmark_tuple *t, const struct xt_hmark_info *info) +{ + int protoff; + + protoff = proto_ports_offset(t->proto); + if (protoff < 0) + return; + + nhoff += protoff; + if (skb_copy_bits(skb, nhoff, &t->uports, sizeof(t->uports)) < 0) + return; + + t->uports.v32 = (t->uports.v32 & info->port_mask.v32) | + info->port_set.v32; + + if (t->uports.p16.dst < t->uports.p16.src) + swap(t->uports.p16.dst, t->uports.p16.src); +} + +#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) +static int get_inner6_hdr(const struct sk_buff *skb, int *offset) +{ + struct icmp6hdr *icmp6h, _ih6; + + icmp6h = skb_header_pointer(skb, *offset, sizeof(_ih6), &_ih6); + if (icmp6h == NULL) + return 0; + + if (icmp6h->icmp6_type && icmp6h->icmp6_type < 128) { + *offset += sizeof(struct icmp6hdr); + return 1; + } + return 0; +} + +static int +hmark_pkt_set_htuple_ipv6(const struct sk_buff *skb, struct hmark_tuple *t, + const struct xt_hmark_info *info) +{ + struct ipv6hdr *ip6, _ip6; + int flag = IP6T_FH_F_AUTH; + unsigned int nhoff = 0; + u16 fragoff = 0; + int nexthdr; + + ip6 = (struct ipv6hdr *) (skb->data + skb_network_offset(skb)); + nexthdr = ipv6_find_hdr(skb, &nhoff, -1, &fragoff, &flag); + if (nexthdr < 0) + return 0; + /* No need to check for icmp errors on fragments */ + if ((flag & IP6T_FH_F_FRAG) || (nexthdr != IPPROTO_ICMPV6)) + goto noicmp; + /* Use inner header in case of ICMP errors */ + if (get_inner6_hdr(skb, &nhoff)) { + ip6 = skb_header_pointer(skb, nhoff, sizeof(_ip6), &_ip6); + if (ip6 == NULL) + return -1; + /* If AH present, use SPI like in ESP. */ + flag = IP6T_FH_F_AUTH; + nexthdr = ipv6_find_hdr(skb, &nhoff, -1, &fragoff, &flag); + if (nexthdr < 0) + return -1; + } +noicmp: + t->src = hmark_addr6_mask(ip6->saddr.s6_addr32, info->src_mask.all); + t->dst = hmark_addr6_mask(ip6->daddr.s6_addr32, info->dst_mask.all); + + if (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)) + return 0; + + t->proto = nexthdr; + if (t->proto == IPPROTO_ICMPV6) + return 0; + + if (flag & IP6T_FH_F_FRAG) + return 0; + + hmark_set_tuple_ports(skb, nhoff, t, info); + return 0; +} + +static unsigned int +hmark_tg_v6(struct sk_buff *skb, const struct xt_action_param *par) +{ + const struct xt_hmark_info *info = par->targinfo; + struct hmark_tuple t; + + memset(&t, 0, sizeof(struct hmark_tuple)); + + if (info->flags & XT_HMARK_FLAG(XT_HMARK_CT)) { + if (hmark_ct_set_htuple(skb, &t, info) < 0) + return XT_CONTINUE; + } else { + if (hmark_pkt_set_htuple_ipv6(skb, &t, info) < 0) + return XT_CONTINUE; + } + + skb->mark = hmark_hash(&t, info); + return XT_CONTINUE; +} +#endif + +static int get_inner_hdr(const struct sk_buff *skb, int iphsz, int *nhoff) +{ + const struct icmphdr *icmph; + struct icmphdr _ih; + + /* Not enough header? */ + icmph = skb_header_pointer(skb, *nhoff + iphsz, sizeof(_ih), &_ih); + if (icmph == NULL || icmph->type > NR_ICMP_TYPES) + return 0; + + /* Error message? */ + if (icmph->type != ICMP_DEST_UNREACH && + icmph->type != ICMP_SOURCE_QUENCH && + icmph->type != ICMP_TIME_EXCEEDED && + icmph->type != ICMP_PARAMETERPROB && + icmph->type != ICMP_REDIRECT) + return 0; + + *nhoff += iphsz + sizeof(_ih); + return 1; +} + +static int +hmark_pkt_set_htuple_ipv4(const struct sk_buff *skb, struct hmark_tuple *t, + const struct xt_hmark_info *info) +{ + struct iphdr *ip, _ip; + int nhoff = skb_network_offset(skb); + + ip = (struct iphdr *) (skb->data + nhoff); + if (ip->protocol == IPPROTO_ICMP) { + /* Use inner header in case of ICMP errors */ + if (get_inner_hdr(skb, ip->ihl * 4, &nhoff)) { + ip = skb_header_pointer(skb, nhoff, sizeof(_ip), &_ip); + if (ip == NULL) + return -1; + } + } + + t->src = (__force u32) ip->saddr; + t->dst = (__force u32) ip->daddr; + + t->src &= info->src_mask.ip; + t->dst &= info->dst_mask.ip; + + if (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)) + return 0; + + t->proto = ip->protocol; + + /* ICMP has no ports, skip */ + if (t->proto == IPPROTO_ICMP) + return 0; + + /* follow-up fragments don't contain ports, skip all fragments */ + if (ip->frag_off & htons(IP_MF | IP_OFFSET)) + return 0; + + hmark_set_tuple_ports(skb, (ip->ihl * 4) + nhoff, t, info); + + return 0; +} + +static unsigned int +hmark_tg_v4(struct sk_buff *skb, const struct xt_action_param *par) +{ + const struct xt_hmark_info *info = par->targinfo; + struct hmark_tuple t; + + memset(&t, 0, sizeof(struct hmark_tuple)); + + if (info->flags & XT_HMARK_FLAG(XT_HMARK_CT)) { + if (hmark_ct_set_htuple(skb, &t, info) < 0) + return XT_CONTINUE; + } else { + if (hmark_pkt_set_htuple_ipv4(skb, &t, info) < 0) + return XT_CONTINUE; + } + + skb->mark = hmark_hash(&t, info); + return XT_CONTINUE; +} + +static int hmark_tg_check(const struct xt_tgchk_param *par) +{ + const struct xt_hmark_info *info = par->targinfo; + + if (!info->hmodulus) { + pr_info("xt_HMARK: hash modulus can't be zero\n"); + return -EINVAL; + } + if (info->proto_mask && + (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3))) { + pr_info("xt_HMARK: proto mask must be zero with L3 mode\n"); + return -EINVAL; + } + if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI_MASK) && + (info->flags & (XT_HMARK_FLAG(XT_HMARK_SPORT_MASK) | + XT_HMARK_FLAG(XT_HMARK_DPORT_MASK)))) { + pr_info("xt_HMARK: spi-mask and port-mask can't be combined\n"); + return -EINVAL; + } + if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI) && + (info->flags & (XT_HMARK_FLAG(XT_HMARK_SPORT) | + XT_HMARK_FLAG(XT_HMARK_DPORT)))) { + pr_info("xt_HMARK: spi-set and port-set can't be combined\n"); + return -EINVAL; + } + return 0; +} + +static struct xt_target hmark_tg_reg[] __read_mostly = { + { + .name = "HMARK", + .family = NFPROTO_IPV4, + .target = hmark_tg_v4, + .targetsize = sizeof(struct xt_hmark_info), + .checkentry = hmark_tg_check, + .me = THIS_MODULE, + }, +#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) + { + .name = "HMARK", + .family = NFPROTO_IPV6, + .target = hmark_tg_v6, + .targetsize = sizeof(struct xt_hmark_info), + .checkentry = hmark_tg_check, + .me = THIS_MODULE, + }, +#endif +}; + +static int __init hmark_tg_init(void) +{ + return xt_register_targets(hmark_tg_reg, ARRAY_SIZE(hmark_tg_reg)); +} + +static void __exit hmark_tg_exit(void) +{ + xt_unregister_targets(hmark_tg_reg, ARRAY_SIZE(hmark_tg_reg)); +} + +module_init(hmark_tg_init); +module_exit(hmark_tg_exit);
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index 190ad37..71a266d 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c
@@ -67,15 +67,13 @@ if (info->mss == XT_TCPMSS_CLAMP_PMTU) { if (dst_mtu(skb_dst(skb)) <= minlen) { - if (net_ratelimit()) - pr_err("unknown or invalid path-MTU (%u)\n", - dst_mtu(skb_dst(skb))); + net_err_ratelimited("unknown or invalid path-MTU (%u)\n", + dst_mtu(skb_dst(skb))); return -1; } if (in_mtu <= minlen) { - if (net_ratelimit()) - pr_err("unknown or invalid path-MTU (%u)\n", - in_mtu); + net_err_ratelimited("unknown or invalid path-MTU (%u)\n", + in_mtu); return -1; } newmss = min(dst_mtu(skb_dst(skb)), in_mtu) - minlen;
diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c index 35a959a..146033a 100644 --- a/net/netfilter/xt_TPROXY.c +++ b/net/netfilter/xt_TPROXY.c
@@ -282,10 +282,10 @@ struct sock *sk; const struct in6_addr *laddr; __be16 lport; - int thoff; + int thoff = 0; int tproto; - tproto = ipv6_find_hdr(skb, &thoff, -1, NULL); + tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL); if (tproto < 0) { pr_debug("unable to find transport header in IPv6 packet, dropping\n"); return NF_DROP;
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index d95f9c9..26a668a8 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c
@@ -171,8 +171,7 @@ if (ht->cfg.max && ht->count >= ht->cfg.max) { /* FIXME: do something. question is what.. */ - if (net_ratelimit()) - pr_err("max count of %u reached\n", ht->cfg.max); + net_err_ratelimited("max count of %u reached\n", ht->cfg.max); ent = NULL; } else ent = kmem_cache_alloc(hashlimit_cachep, GFP_ATOMIC); @@ -388,9 +387,20 @@ #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) +/* in byte mode, the lowest possible rate is one packet/second. + * credit_cap is used as a counter that tells us how many times we can + * refill the "credits available" counter when it becomes empty. + */ +#define MAX_CPJ_BYTES (0xFFFFFFFF / HZ) +#define CREDITS_PER_JIFFY_BYTES POW2_BELOW32(MAX_CPJ_BYTES) + +static u32 xt_hashlimit_len_to_chunks(u32 len) +{ + return (len >> XT_HASHLIMIT_BYTE_SHIFT) + 1; +} + /* Precision saver. */ -static inline u_int32_t -user2credits(u_int32_t user) +static u32 user2credits(u32 user) { /* If multiplying would overflow... */ if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) @@ -400,12 +410,53 @@ return (user * HZ * CREDITS_PER_JIFFY) / XT_HASHLIMIT_SCALE; } -static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now) +static u32 user2credits_byte(u32 user) { - dh->rateinfo.credit += (now - dh->rateinfo.prev) * CREDITS_PER_JIFFY; - if (dh->rateinfo.credit > dh->rateinfo.credit_cap) - dh->rateinfo.credit = dh->rateinfo.credit_cap; + u64 us = user; + us *= HZ * CREDITS_PER_JIFFY_BYTES; + return (u32) (us >> 32); +} + +static void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now, u32 mode) +{ + unsigned long delta = now - dh->rateinfo.prev; + u32 cap; + + if (delta == 0) + return; + dh->rateinfo.prev = now; + + if (mode & XT_HASHLIMIT_BYTES) { + u32 tmp = dh->rateinfo.credit; + dh->rateinfo.credit += CREDITS_PER_JIFFY_BYTES * delta; + cap = CREDITS_PER_JIFFY_BYTES * HZ; + if (tmp >= dh->rateinfo.credit) {/* overflow */ + dh->rateinfo.credit = cap; + return; + } + } else { + dh->rateinfo.credit += delta * CREDITS_PER_JIFFY; + cap = dh->rateinfo.credit_cap; + } + if (dh->rateinfo.credit > cap) + dh->rateinfo.credit = cap; +} + +static void rateinfo_init(struct dsthash_ent *dh, + struct xt_hashlimit_htable *hinfo) +{ + dh->rateinfo.prev = jiffies; + if (hinfo->cfg.mode & XT_HASHLIMIT_BYTES) { + dh->rateinfo.credit = CREDITS_PER_JIFFY_BYTES * HZ; + dh->rateinfo.cost = user2credits_byte(hinfo->cfg.avg); + dh->rateinfo.credit_cap = hinfo->cfg.burst; + } else { + dh->rateinfo.credit = user2credits(hinfo->cfg.avg * + hinfo->cfg.burst); + dh->rateinfo.cost = user2credits(hinfo->cfg.avg); + dh->rateinfo.credit_cap = dh->rateinfo.credit; + } } static inline __be32 maskl(__be32 a, unsigned int l) @@ -511,6 +562,21 @@ return 0; } +static u32 hashlimit_byte_cost(unsigned int len, struct dsthash_ent *dh) +{ + u64 tmp = xt_hashlimit_len_to_chunks(len); + tmp = tmp * dh->rateinfo.cost; + + if (unlikely(tmp > CREDITS_PER_JIFFY_BYTES * HZ)) + tmp = CREDITS_PER_JIFFY_BYTES * HZ; + + if (dh->rateinfo.credit < tmp && dh->rateinfo.credit_cap) { + dh->rateinfo.credit_cap--; + dh->rateinfo.credit = CREDITS_PER_JIFFY_BYTES * HZ; + } + return (u32) tmp; +} + static bool hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) { @@ -519,6 +585,7 @@ unsigned long now = jiffies; struct dsthash_ent *dh; struct dsthash_dst dst; + u32 cost; if (hashlimit_init_dst(hinfo, &dst, skb, par->thoff) < 0) goto hotdrop; @@ -532,21 +599,21 @@ goto hotdrop; } dh->expires = jiffies + msecs_to_jiffies(hinfo->cfg.expire); - dh->rateinfo.prev = jiffies; - dh->rateinfo.credit = user2credits(hinfo->cfg.avg * - hinfo->cfg.burst); - dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg * - hinfo->cfg.burst); - dh->rateinfo.cost = user2credits(hinfo->cfg.avg); + rateinfo_init(dh, hinfo); } else { /* update expiration timeout */ dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire); - rateinfo_recalc(dh, now); + rateinfo_recalc(dh, now, hinfo->cfg.mode); } - if (dh->rateinfo.credit >= dh->rateinfo.cost) { + if (info->cfg.mode & XT_HASHLIMIT_BYTES) + cost = hashlimit_byte_cost(skb->len, dh); + else + cost = dh->rateinfo.cost; + + if (dh->rateinfo.credit >= cost) { /* below the limit */ - dh->rateinfo.credit -= dh->rateinfo.cost; + dh->rateinfo.credit -= cost; spin_unlock(&dh->lock); rcu_read_unlock_bh(); return !(info->cfg.mode & XT_HASHLIMIT_INVERT); @@ -568,14 +635,6 @@ struct xt_hashlimit_mtinfo1 *info = par->matchinfo; int ret; - /* Check for overflow. */ - if (info->cfg.burst == 0 || - user2credits(info->cfg.avg * info->cfg.burst) < - user2credits(info->cfg.avg)) { - pr_info("overflow, try lower: %u/%u\n", - info->cfg.avg, info->cfg.burst); - return -ERANGE; - } if (info->cfg.gc_interval == 0 || info->cfg.expire == 0) return -EINVAL; if (info->name[sizeof(info->name)-1] != '\0') @@ -588,6 +647,26 @@ return -EINVAL; } + if (info->cfg.mode & ~XT_HASHLIMIT_ALL) { + pr_info("Unknown mode mask %X, kernel too old?\n", + info->cfg.mode); + return -EINVAL; + } + + /* Check for overflow. */ + if (info->cfg.mode & XT_HASHLIMIT_BYTES) { + if (user2credits_byte(info->cfg.avg) == 0) { + pr_info("overflow, rate too high: %u\n", info->cfg.avg); + return -EINVAL; + } + } else if (info->cfg.burst == 0 || + user2credits(info->cfg.avg * info->cfg.burst) < + user2credits(info->cfg.avg)) { + pr_info("overflow, try lower: %u/%u\n", + info->cfg.avg, info->cfg.burst); + return -ERANGE; + } + mutex_lock(&hashlimit_mutex); info->hinfo = htable_find_get(net, info->name, par->family); if (info->hinfo == NULL) { @@ -680,10 +759,11 @@ struct seq_file *s) { int res; + const struct xt_hashlimit_htable *ht = s->private; spin_lock(&ent->lock); /* recalculate to show accurate numbers */ - rateinfo_recalc(ent, jiffies); + rateinfo_recalc(ent, jiffies, ht->cfg.mode); switch (family) { case NFPROTO_IPV4:
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c index 32b7a57..5c22ce8 100644 --- a/net/netfilter/xt_limit.c +++ b/net/netfilter/xt_limit.c
@@ -88,8 +88,7 @@ } /* Precision saver. */ -static u_int32_t -user2credits(u_int32_t user) +static u32 user2credits(u32 user) { /* If multiplying would overflow... */ if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) @@ -123,7 +122,7 @@ 128. */ priv->prev = jiffies; priv->credit = user2credits(r->avg * r->burst); /* Credits full. */ - r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */ + r->credit_cap = priv->credit; /* Credits full. */ r->cost = user2credits(r->avg); } return 0;
diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c index 8160f6b..d5b4fd4 100644 --- a/net/netfilter/xt_mac.c +++ b/net/netfilter/xt_mac.c
@@ -36,7 +36,7 @@ return false; if (skb_mac_header(skb) + ETH_HLEN > skb->data) return false; - ret = compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr) == 0; + ret = ether_addr_equal(eth_hdr(skb)->h_source, info->srcaddr); ret ^= info->invert; return ret; }
diff --git a/net/netfilter/xt_set.c b/net/netfilter/xt_set.c index 0ec8138..035960e 100644 --- a/net/netfilter/xt_set.c +++ b/net/netfilter/xt_set.c
@@ -44,6 +44,14 @@ .cmdflags = cfs, \ .timeout = t, \ } +#define ADT_MOPT(n, f, d, fs, cfs, t) \ +struct ip_set_adt_opt n = { \ + .family = f, \ + .dim = d, \ + .flags = fs, \ + .cmdflags = cfs, \ + .timeout = t, \ +} /* Revision 0 interface: backward compatible with netfilter/iptables */ @@ -296,11 +304,14 @@ set_target_v2(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_set_info_target_v2 *info = par->targinfo; - ADT_OPT(add_opt, par->family, info->add_set.dim, - info->add_set.flags, info->flags, info->timeout); + ADT_MOPT(add_opt, par->family, info->add_set.dim, + info->add_set.flags, info->flags, info->timeout); ADT_OPT(del_opt, par->family, info->del_set.dim, info->del_set.flags, 0, UINT_MAX); + /* Normalize to fit into jiffies */ + if (add_opt.timeout > UINT_MAX/MSEC_PER_SEC) + add_opt.timeout = UINT_MAX/MSEC_PER_SEC; if (info->add_set.index != IPSET_INVALID_ID) ip_set_add(info->add_set.index, skb, par, &add_opt); if (info->del_set.index != IPSET_INVALID_ID)
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c index 72bb07f..9ea482d 100644 --- a/net/netfilter/xt_socket.c +++ b/net/netfilter/xt_socket.c
@@ -263,10 +263,10 @@ struct sock *sk; struct in6_addr *daddr, *saddr; __be16 dport, sport; - int thoff, tproto; + int thoff = 0, tproto; const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo; - tproto = ipv6_find_hdr(skb, &thoff, -1, NULL); + tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL); if (tproto < 0) { pr_debug("unable to find transport header in IPv6 packet, dropping\n"); return NF_DROP;
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index f86de29..2c74daa 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c
@@ -321,7 +321,7 @@ return -ENOMEM; nskb = __vlan_put_tag(nskb, vlan_tx_tag_get(nskb)); - if (!skb) + if (!nskb) return -ENOMEM; nskb->vlan_tci = 0; @@ -421,6 +421,19 @@ return validate_actions(actions, key, depth + 1); } +static int validate_tp_port(const struct sw_flow_key *flow_key) +{ + if (flow_key->eth.type == htons(ETH_P_IP)) { + if (flow_key->ipv4.tp.src && flow_key->ipv4.tp.dst) + return 0; + } else if (flow_key->eth.type == htons(ETH_P_IPV6)) { + if (flow_key->ipv6.tp.src && flow_key->ipv6.tp.dst) + return 0; + } + + return -EINVAL; +} + static int validate_set(const struct nlattr *a, const struct sw_flow_key *flow_key) { @@ -462,18 +475,13 @@ if (flow_key->ip.proto != IPPROTO_TCP) return -EINVAL; - if (!flow_key->ipv4.tp.src || !flow_key->ipv4.tp.dst) - return -EINVAL; - - break; + return validate_tp_port(flow_key); case OVS_KEY_ATTR_UDP: if (flow_key->ip.proto != IPPROTO_UDP) return -EINVAL; - if (!flow_key->ipv4.tp.src || !flow_key->ipv4.tp.dst) - return -EINVAL; - break; + return validate_tp_port(flow_key); default: return -EINVAL; @@ -1647,10 +1655,9 @@ reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq, OVS_VPORT_CMD_NEW); if (IS_ERR(reply)) { - err = PTR_ERR(reply); netlink_set_err(init_net.genl_sock, 0, - ovs_dp_vport_multicast_group.id, err); - return 0; + ovs_dp_vport_multicast_group.id, PTR_ERR(reply)); + goto exit_unlock; } genl_notify(reply, genl_info_net(info), info->snd_pid,
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 7cb4163..6d4d809 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c
@@ -183,7 +183,8 @@ u8 tcp_flags = 0; if (flow->key.eth.type == htons(ETH_P_IP) && - flow->key.ip.proto == IPPROTO_TCP) { + flow->key.ip.proto == IPPROTO_TCP && + likely(skb->len >= skb_transport_offset(skb) + sizeof(struct tcphdr))) { u8 *tcp = (u8 *)tcp_hdr(skb); tcp_flags = *(tcp + TCP_FLAGS_OFFSET) & TCP_FLAG_MASK; }
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index 5920bda..3fd6c0d 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c
@@ -157,9 +157,9 @@ int len; if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) { - if (net_ratelimit()) - pr_warn("%s: dropped over-mtu packet: %d > %d\n", - ovs_dp_name(vport->dp), packet_length(skb), mtu); + net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n", + ovs_dp_name(vport->dp), + packet_length(skb), mtu); goto error; }
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 75b58f8..e7a8976 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig
@@ -250,6 +250,28 @@ If unsure, say N. +config NET_SCH_CODEL + tristate "Controlled Delay AQM (CODEL)" + help + Say Y here if you want to use the Controlled Delay (CODEL) + packet scheduling algorithm. + + To compile this driver as a module, choose M here: the module + will be called sch_codel. + + If unsure, say N. + +config NET_SCH_FQ_CODEL + tristate "Fair Queue Controlled Delay AQM (FQ_CODEL)" + help + Say Y here if you want to use the FQ Controlled Delay (FQ_CODEL) + packet scheduling algorithm. + + To compile this driver as a module, choose M here: the module + will be called sch_fq_codel. + + If unsure, say N. + config NET_SCH_INGRESS tristate "Ingress Qdisc" depends on NET_CLS_ACT
diff --git a/net/sched/Makefile b/net/sched/Makefile index 8cdf4e2..5940a19 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile
@@ -37,6 +37,8 @@ obj-$(CONFIG_NET_SCH_MQPRIO) += sch_mqprio.o obj-$(CONFIG_NET_SCH_CHOKE) += sch_choke.o obj-$(CONFIG_NET_SCH_QFQ) += sch_qfq.o +obj-$(CONFIG_NET_SCH_CODEL) += sch_codel.o +obj-$(CONFIG_NET_SCH_FQ_CODEL) += sch_fq_codel.o obj-$(CONFIG_NET_CLS_U32) += cls_u32.o obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 882124ceb..2c8ad7c 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c
@@ -397,7 +397,7 @@ while (len > 1) { switch (xh[off]) { - case IPV6_TLV_PAD0: + case IPV6_TLV_PAD1: optlen = 1; break; case IPV6_TLV_JUMBO:
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 0beba0e..60e281a 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c
@@ -1,5 +1,5 @@ /* - * net/sched/ipt.c iptables target interface + * net/sched/ipt.c iptables target interface * *TODO: Add other tables. For now we only support the ipv4 table targets * @@ -235,9 +235,8 @@ result = TC_ACT_PIPE; break; default: - if (net_ratelimit()) - pr_notice("tc filter: Bogus netfilter code" - " %d assume ACCEPT\n", ret); + net_notice_ratelimited("tc filter: Bogus netfilter code %d assume ACCEPT\n", + ret); result = TC_POLICE_OK; break; }
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index d583aea..fe81cc1 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c
@@ -174,9 +174,8 @@ } if (!(dev->flags & IFF_UP)) { - if (net_ratelimit()) - pr_notice("tc mirred to Houston: device %s is down\n", - dev->name); + net_notice_ratelimited("tc mirred to Houston: device %s is down\n", + dev->name); goto out; }
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 591b006..d45373f 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c
@@ -234,8 +234,7 @@ return -1; deadloop: - if (net_ratelimit()) - pr_warning("cls_u32: dead loop\n"); + net_warn_ratelimited("cls_u32: dead loop\n"); return -1; }
diff --git a/net/sched/ematch.c b/net/sched/ematch.c index aca233c..3a633de 100644 --- a/net/sched/ematch.c +++ b/net/sched/ematch.c
@@ -537,9 +537,7 @@ return res; stack_overflow: - if (net_ratelimit()) - pr_warning("tc ematch: local stack overflow," - " increase NET_EMATCH_STACK\n"); + net_warn_ratelimited("tc ematch: local stack overflow, increase NET_EMATCH_STACK\n"); return -1; } EXPORT_SYMBOL(__tcf_em_tree_match);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index d2daefc..085ce53 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c
@@ -1691,12 +1691,10 @@ tp = otp; if (verd++ >= MAX_REC_LOOP) { - if (net_ratelimit()) - pr_notice("%s: packet reclassify loop" - " rule prio %u protocol %02x\n", - tp->q->ops->id, - tp->prio & 0xffff, - ntohs(tp->protocol)); + net_notice_ratelimited("%s: packet reclassify loop rule prio %u protocol %02x\n", + tp->q->ops->id, + tp->prio & 0xffff, + ntohs(tp->protocol)); return TC_ACT_SHOT; } skb->tc_verd = SET_TC_VERD(skb->tc_verd, verd);
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index a77a4fb..8522a47 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c
@@ -423,8 +423,6 @@ } return ret; } - qdisc_bstats_update(sch, skb); - bstats_update(&flow->bstats, skb); /* * Okay, this may seem weird. We pretend we've dropped the packet if * it goes via ATM. The reason for this is that the outer qdisc @@ -472,6 +470,8 @@ if (unlikely(!skb)) break; + qdisc_bstats_update(sch, skb); + bstats_update(&flow->bstats, skb); pr_debug("atm_tc_dequeue: sending on class %p\n", flow); /* remove any LL header somebody else has attached */ skb_pull(skb, skb_network_offset(skb));
diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c new file mode 100644 index 0000000..2f9ab17 --- /dev/null +++ b/net/sched/sch_codel.c
@@ -0,0 +1,276 @@ +/* + * Codel - The Controlled-Delay Active Queue Management algorithm + * + * Copyright (C) 2011-2012 Kathleen Nichols <nichols@pollere.com> + * Copyright (C) 2011-2012 Van Jacobson <van@pollere.net> + * + * Implemented on linux by : + * Copyright (C) 2012 Michael D. Taht <dave.taht@bufferbloat.net> + * Copyright (C) 2012 Eric Dumazet <edumazet@google.com> + * + * 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, + * without modification. + * 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. The names of the authors may not 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. + * + * 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/slab.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/skbuff.h> +#include <linux/prefetch.h> +#include <net/pkt_sched.h> +#include <net/codel.h> + + +#define DEFAULT_CODEL_LIMIT 1000 + +struct codel_sched_data { + struct codel_params params; + struct codel_vars vars; + struct codel_stats stats; + u32 drop_overlimit; +}; + +/* This is the specific function called from codel_dequeue() + * to dequeue a packet from queue. Note: backlog is handled in + * codel, we dont need to reduce it here. + */ +static struct sk_buff *dequeue(struct codel_vars *vars, struct Qdisc *sch) +{ + struct sk_buff *skb = __skb_dequeue(&sch->q); + + prefetch(&skb->end); /* we'll need skb_shinfo() */ + return skb; +} + +static struct sk_buff *codel_qdisc_dequeue(struct Qdisc *sch) +{ + struct codel_sched_data *q = qdisc_priv(sch); + struct sk_buff *skb; + + skb = codel_dequeue(sch, &q->params, &q->vars, &q->stats, dequeue); + + /* We cant call qdisc_tree_decrease_qlen() if our qlen is 0, + * or HTB crashes. Defer it for next round. + */ + if (q->stats.drop_count && sch->q.qlen) { + qdisc_tree_decrease_qlen(sch, q->stats.drop_count); + q->stats.drop_count = 0; + } + if (skb) + qdisc_bstats_update(sch, skb); + return skb; +} + +static int codel_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch) +{ + struct codel_sched_data *q; + + if (likely(qdisc_qlen(sch) < sch->limit)) { + codel_set_enqueue_time(skb); + return qdisc_enqueue_tail(skb, sch); + } + q = qdisc_priv(sch); + q->drop_overlimit++; + return qdisc_drop(skb, sch); +} + +static const struct nla_policy codel_policy[TCA_CODEL_MAX + 1] = { + [TCA_CODEL_TARGET] = { .type = NLA_U32 }, + [TCA_CODEL_LIMIT] = { .type = NLA_U32 }, + [TCA_CODEL_INTERVAL] = { .type = NLA_U32 }, + [TCA_CODEL_ECN] = { .type = NLA_U32 }, +}; + +static int codel_change(struct Qdisc *sch, struct nlattr *opt) +{ + struct codel_sched_data *q = qdisc_priv(sch); + struct nlattr *tb[TCA_CODEL_MAX + 1]; + unsigned int qlen; + int err; + + if (!opt) + return -EINVAL; + + err = nla_parse_nested(tb, TCA_CODEL_MAX, opt, codel_policy); + if (err < 0) + return err; + + sch_tree_lock(sch); + + if (tb[TCA_CODEL_TARGET]) { + u32 target = nla_get_u32(tb[TCA_CODEL_TARGET]); + + q->params.target = ((u64)target * NSEC_PER_USEC) >> CODEL_SHIFT; + } + + if (tb[TCA_CODEL_INTERVAL]) { + u32 interval = nla_get_u32(tb[TCA_CODEL_INTERVAL]); + + q->params.interval = ((u64)interval * NSEC_PER_USEC) >> CODEL_SHIFT; + } + + if (tb[TCA_CODEL_LIMIT]) + sch->limit = nla_get_u32(tb[TCA_CODEL_LIMIT]); + + if (tb[TCA_CODEL_ECN]) + q->params.ecn = !!nla_get_u32(tb[TCA_CODEL_ECN]); + + qlen = sch->q.qlen; + while (sch->q.qlen > sch->limit) { + struct sk_buff *skb = __skb_dequeue(&sch->q); + + sch->qstats.backlog -= qdisc_pkt_len(skb); + qdisc_drop(skb, sch); + } + qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen); + + sch_tree_unlock(sch); + return 0; +} + +static int codel_init(struct Qdisc *sch, struct nlattr *opt) +{ + struct codel_sched_data *q = qdisc_priv(sch); + + sch->limit = DEFAULT_CODEL_LIMIT; + + codel_params_init(&q->params); + codel_vars_init(&q->vars); + codel_stats_init(&q->stats); + + if (opt) { + int err = codel_change(sch, opt); + + if (err) + return err; + } + + if (sch->limit >= 1) + sch->flags |= TCQ_F_CAN_BYPASS; + else + sch->flags &= ~TCQ_F_CAN_BYPASS; + + return 0; +} + +static int codel_dump(struct Qdisc *sch, struct sk_buff *skb) +{ + struct codel_sched_data *q = qdisc_priv(sch); + struct nlattr *opts; + + opts = nla_nest_start(skb, TCA_OPTIONS); + if (opts == NULL) + goto nla_put_failure; + + if (nla_put_u32(skb, TCA_CODEL_TARGET, + codel_time_to_us(q->params.target)) || + nla_put_u32(skb, TCA_CODEL_LIMIT, + sch->limit) || + nla_put_u32(skb, TCA_CODEL_INTERVAL, + codel_time_to_us(q->params.interval)) || + nla_put_u32(skb, TCA_CODEL_ECN, + q->params.ecn)) + goto nla_put_failure; + + return nla_nest_end(skb, opts); + +nla_put_failure: + nla_nest_cancel(skb, opts); + return -1; +} + +static int codel_dump_stats(struct Qdisc *sch, struct gnet_dump *d) +{ + const struct codel_sched_data *q = qdisc_priv(sch); + struct tc_codel_xstats st = { + .maxpacket = q->stats.maxpacket, + .count = q->vars.count, + .lastcount = q->vars.lastcount, + .drop_overlimit = q->drop_overlimit, + .ldelay = codel_time_to_us(q->vars.ldelay), + .dropping = q->vars.dropping, + .ecn_mark = q->stats.ecn_mark, + }; + + if (q->vars.dropping) { + codel_tdiff_t delta = q->vars.drop_next - codel_get_time(); + + if (delta >= 0) + st.drop_next = codel_time_to_us(delta); + else + st.drop_next = -codel_time_to_us(-delta); + } + + return gnet_stats_copy_app(d, &st, sizeof(st)); +} + +static void codel_reset(struct Qdisc *sch) +{ + struct codel_sched_data *q = qdisc_priv(sch); + + qdisc_reset_queue(sch); + codel_vars_init(&q->vars); +} + +static struct Qdisc_ops codel_qdisc_ops __read_mostly = { + .id = "codel", + .priv_size = sizeof(struct codel_sched_data), + + .enqueue = codel_qdisc_enqueue, + .dequeue = codel_qdisc_dequeue, + .peek = qdisc_peek_dequeued, + .init = codel_init, + .reset = codel_reset, + .change = codel_change, + .dump = codel_dump, + .dump_stats = codel_dump_stats, + .owner = THIS_MODULE, +}; + +static int __init codel_module_init(void) +{ + return register_qdisc(&codel_qdisc_ops); +} + +static void __exit codel_module_exit(void) +{ + unregister_qdisc(&codel_qdisc_ops); +} + +module_init(codel_module_init) +module_exit(codel_module_exit) + +MODULE_DESCRIPTION("Controlled Delay queue discipline"); +MODULE_AUTHOR("Dave Taht"); +MODULE_AUTHOR("Eric Dumazet"); +MODULE_LICENSE("Dual BSD/GPL");
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c index c218987..9ce0b4f 100644 --- a/net/sched/sch_drr.c +++ b/net/sched/sch_drr.c
@@ -376,8 +376,6 @@ cl->deficit = cl->quantum; } - bstats_update(&cl->bstats, skb); - sch->q.qlen++; return err; } @@ -403,6 +401,8 @@ skb = qdisc_dequeue_peeked(cl->qdisc); if (cl->qdisc->q.qlen == 0) list_del(&cl->alist); + + bstats_update(&cl->bstats, skb); qdisc_bstats_update(sch, skb); sch->q.qlen--; return skb;
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c new file mode 100644 index 0000000..9fc1c62 --- /dev/null +++ b/net/sched/sch_fq_codel.c
@@ -0,0 +1,626 @@ +/* + * Fair Queue CoDel discipline + * + * 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. + * + * Copyright (C) 2012 Eric Dumazet <edumazet@google.com> + */ + +#include <linux/module.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/jiffies.h> +#include <linux/string.h> +#include <linux/in.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/skbuff.h> +#include <linux/jhash.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> +#include <net/netlink.h> +#include <net/pkt_sched.h> +#include <net/flow_keys.h> +#include <net/codel.h> + +/* Fair Queue CoDel. + * + * Principles : + * Packets are classified (internal classifier or external) on flows. + * This is a Stochastic model (as we use a hash, several flows + * might be hashed on same slot) + * Each flow has a CoDel managed queue. + * Flows are linked onto two (Round Robin) lists, + * so that new flows have priority on old ones. + * + * For a given flow, packets are not reordered (CoDel uses a FIFO) + * head drops only. + * ECN capability is on by default. + * Low memory footprint (64 bytes per flow) + */ + +struct fq_codel_flow { + struct sk_buff *head; + struct sk_buff *tail; + struct list_head flowchain; + int deficit; + u32 dropped; /* number of drops (or ECN marks) on this flow */ + struct codel_vars cvars; +}; /* please try to keep this structure <= 64 bytes */ + +struct fq_codel_sched_data { + struct tcf_proto *filter_list; /* optional external classifier */ + struct fq_codel_flow *flows; /* Flows table [flows_cnt] */ + u32 *backlogs; /* backlog table [flows_cnt] */ + u32 flows_cnt; /* number of flows */ + u32 perturbation; /* hash perturbation */ + u32 quantum; /* psched_mtu(qdisc_dev(sch)); */ + struct codel_params cparams; + struct codel_stats cstats; + u32 drop_overlimit; + u32 new_flow_count; + + struct list_head new_flows; /* list of new flows */ + struct list_head old_flows; /* list of old flows */ +}; + +static unsigned int fq_codel_hash(const struct fq_codel_sched_data *q, + const struct sk_buff *skb) +{ + struct flow_keys keys; + unsigned int hash; + + skb_flow_dissect(skb, &keys); + hash = jhash_3words((__force u32)keys.dst, + (__force u32)keys.src ^ keys.ip_proto, + (__force u32)keys.ports, q->perturbation); + return ((u64)hash * q->flows_cnt) >> 32; +} + +static unsigned int fq_codel_classify(struct sk_buff *skb, struct Qdisc *sch, + int *qerr) +{ + struct fq_codel_sched_data *q = qdisc_priv(sch); + struct tcf_result res; + int result; + + if (TC_H_MAJ(skb->priority) == sch->handle && + TC_H_MIN(skb->priority) > 0 && + TC_H_MIN(skb->priority) <= q->flows_cnt) + return TC_H_MIN(skb->priority); + + if (!q->filter_list) + return fq_codel_hash(q, skb) + 1; + + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; + result = tc_classify(skb, q->filter_list, &res); + if (result >= 0) { +#ifdef CONFIG_NET_CLS_ACT + switch (result) { + case TC_ACT_STOLEN: + case TC_ACT_QUEUED: + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; + case TC_ACT_SHOT: + return 0; + } +#endif + if (TC_H_MIN(res.classid) <= q->flows_cnt) + return TC_H_MIN(res.classid); + } + return 0; +} + +/* helper functions : might be changed when/if skb use a standard list_head */ + +/* remove one skb from head of slot queue */ +static inline struct sk_buff *dequeue_head(struct fq_codel_flow *flow) +{ + struct sk_buff *skb = flow->head; + + flow->head = skb->next; + skb->next = NULL; + return skb; +} + +/* add skb to flow queue (tail add) */ +static inline void flow_queue_add(struct fq_codel_flow *flow, + struct sk_buff *skb) +{ + if (flow->head == NULL) + flow->head = skb; + else + flow->tail->next = skb; + flow->tail = skb; + skb->next = NULL; +} + +static unsigned int fq_codel_drop(struct Qdisc *sch) +{ + struct fq_codel_sched_data *q = qdisc_priv(sch); + struct sk_buff *skb; + unsigned int maxbacklog = 0, idx = 0, i, len; + struct fq_codel_flow *flow; + + /* Queue is full! Find the fat flow and drop packet from it. + * This might sound expensive, but with 1024 flows, we scan + * 4KB of memory, and we dont need to handle a complex tree + * in fast path (packet queue/enqueue) with many cache misses. + */ + for (i = 0; i < q->flows_cnt; i++) { + if (q->backlogs[i] > maxbacklog) { + maxbacklog = q->backlogs[i]; + idx = i; + } + } + flow = &q->flows[idx]; + skb = dequeue_head(flow); + len = qdisc_pkt_len(skb); + q->backlogs[idx] -= len; + kfree_skb(skb); + sch->q.qlen--; + sch->qstats.drops++; + sch->qstats.backlog -= len; + flow->dropped++; + return idx; +} + +static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch) +{ + struct fq_codel_sched_data *q = qdisc_priv(sch); + unsigned int idx; + struct fq_codel_flow *flow; + int uninitialized_var(ret); + + idx = fq_codel_classify(skb, sch, &ret); + if (idx == 0) { + if (ret & __NET_XMIT_BYPASS) + sch->qstats.drops++; + kfree_skb(skb); + return ret; + } + idx--; + + codel_set_enqueue_time(skb); + flow = &q->flows[idx]; + flow_queue_add(flow, skb); + q->backlogs[idx] += qdisc_pkt_len(skb); + sch->qstats.backlog += qdisc_pkt_len(skb); + + if (list_empty(&flow->flowchain)) { + list_add_tail(&flow->flowchain, &q->new_flows); + codel_vars_init(&flow->cvars); + q->new_flow_count++; + flow->deficit = q->quantum; + flow->dropped = 0; + } + if (++sch->q.qlen < sch->limit) + return NET_XMIT_SUCCESS; + + q->drop_overlimit++; + /* Return Congestion Notification only if we dropped a packet + * from this flow. + */ + if (fq_codel_drop(sch) == idx) + return NET_XMIT_CN; + + /* As we dropped a packet, better let upper stack know this */ + qdisc_tree_decrease_qlen(sch, 1); + return NET_XMIT_SUCCESS; +} + +/* This is the specific function called from codel_dequeue() + * to dequeue a packet from queue. Note: backlog is handled in + * codel, we dont need to reduce it here. + */ +static struct sk_buff *dequeue(struct codel_vars *vars, struct Qdisc *sch) +{ + struct fq_codel_sched_data *q = qdisc_priv(sch); + struct fq_codel_flow *flow; + struct sk_buff *skb = NULL; + + flow = container_of(vars, struct fq_codel_flow, cvars); + if (flow->head) { + skb = dequeue_head(flow); + q->backlogs[flow - q->flows] -= qdisc_pkt_len(skb); + sch->q.qlen--; + } + return skb; +} + +static struct sk_buff *fq_codel_dequeue(struct Qdisc *sch) +{ + struct fq_codel_sched_data *q = qdisc_priv(sch); + struct sk_buff *skb; + struct fq_codel_flow *flow; + struct list_head *head; + u32 prev_drop_count, prev_ecn_mark; + +begin: + head = &q->new_flows; + if (list_empty(head)) { + head = &q->old_flows; + if (list_empty(head)) + return NULL; + } + flow = list_first_entry(head, struct fq_codel_flow, flowchain); + + if (flow->deficit <= 0) { + flow->deficit += q->quantum; + list_move_tail(&flow->flowchain, &q->old_flows); + goto begin; + } + + prev_drop_count = q->cstats.drop_count; + prev_ecn_mark = q->cstats.ecn_mark; + + skb = codel_dequeue(sch, &q->cparams, &flow->cvars, &q->cstats, + dequeue); + + flow->dropped += q->cstats.drop_count - prev_drop_count; + flow->dropped += q->cstats.ecn_mark - prev_ecn_mark; + + if (!skb) { + /* force a pass through old_flows to prevent starvation */ + if ((head == &q->new_flows) && !list_empty(&q->old_flows)) + list_move_tail(&flow->flowchain, &q->old_flows); + else + list_del_init(&flow->flowchain); + goto begin; + } + qdisc_bstats_update(sch, skb); + flow->deficit -= qdisc_pkt_len(skb); + /* We cant call qdisc_tree_decrease_qlen() if our qlen is 0, + * or HTB crashes. Defer it for next round. + */ + if (q->cstats.drop_count && sch->q.qlen) { + qdisc_tree_decrease_qlen(sch, q->cstats.drop_count); + q->cstats.drop_count = 0; + } + return skb; +} + +static void fq_codel_reset(struct Qdisc *sch) +{ + struct sk_buff *skb; + + while ((skb = fq_codel_dequeue(sch)) != NULL) + kfree_skb(skb); +} + +static const struct nla_policy fq_codel_policy[TCA_FQ_CODEL_MAX + 1] = { + [TCA_FQ_CODEL_TARGET] = { .type = NLA_U32 }, + [TCA_FQ_CODEL_LIMIT] = { .type = NLA_U32 }, + [TCA_FQ_CODEL_INTERVAL] = { .type = NLA_U32 }, + [TCA_FQ_CODEL_ECN] = { .type = NLA_U32 }, + [TCA_FQ_CODEL_FLOWS] = { .type = NLA_U32 }, + [TCA_FQ_CODEL_QUANTUM] = { .type = NLA_U32 }, +}; + +static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt) +{ + struct fq_codel_sched_data *q = qdisc_priv(sch); + struct nlattr *tb[TCA_FQ_CODEL_MAX + 1]; + int err; + + if (!opt) + return -EINVAL; + + err = nla_parse_nested(tb, TCA_FQ_CODEL_MAX, opt, fq_codel_policy); + if (err < 0) + return err; + if (tb[TCA_FQ_CODEL_FLOWS]) { + if (q->flows) + return -EINVAL; + q->flows_cnt = nla_get_u32(tb[TCA_FQ_CODEL_FLOWS]); + if (!q->flows_cnt || + q->flows_cnt > 65536) + return -EINVAL; + } + sch_tree_lock(sch); + + if (tb[TCA_FQ_CODEL_TARGET]) { + u64 target = nla_get_u32(tb[TCA_FQ_CODEL_TARGET]); + + q->cparams.target = (target * NSEC_PER_USEC) >> CODEL_SHIFT; + } + + if (tb[TCA_FQ_CODEL_INTERVAL]) { + u64 interval = nla_get_u32(tb[TCA_FQ_CODEL_INTERVAL]); + + q->cparams.interval = (interval * NSEC_PER_USEC) >> CODEL_SHIFT; + } + + if (tb[TCA_FQ_CODEL_LIMIT]) + sch->limit = nla_get_u32(tb[TCA_FQ_CODEL_LIMIT]); + + if (tb[TCA_FQ_CODEL_ECN]) + q->cparams.ecn = !!nla_get_u32(tb[TCA_FQ_CODEL_ECN]); + + if (tb[TCA_FQ_CODEL_QUANTUM]) + q->quantum = max(256U, nla_get_u32(tb[TCA_FQ_CODEL_QUANTUM])); + + while (sch->q.qlen > sch->limit) { + struct sk_buff *skb = fq_codel_dequeue(sch); + + kfree_skb(skb); + q->cstats.drop_count++; + } + qdisc_tree_decrease_qlen(sch, q->cstats.drop_count); + q->cstats.drop_count = 0; + + sch_tree_unlock(sch); + return 0; +} + +static void *fq_codel_zalloc(size_t sz) +{ + void *ptr = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN); + + if (!ptr) + ptr = vzalloc(sz); + return ptr; +} + +static void fq_codel_free(void *addr) +{ + if (addr) { + if (is_vmalloc_addr(addr)) + vfree(addr); + else + kfree(addr); + } +} + +static void fq_codel_destroy(struct Qdisc *sch) +{ + struct fq_codel_sched_data *q = qdisc_priv(sch); + + tcf_destroy_chain(&q->filter_list); + fq_codel_free(q->backlogs); + fq_codel_free(q->flows); +} + +static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt) +{ + struct fq_codel_sched_data *q = qdisc_priv(sch); + int i; + + sch->limit = 10*1024; + q->flows_cnt = 1024; + q->quantum = psched_mtu(qdisc_dev(sch)); + q->perturbation = net_random(); + INIT_LIST_HEAD(&q->new_flows); + INIT_LIST_HEAD(&q->old_flows); + codel_params_init(&q->cparams); + codel_stats_init(&q->cstats); + q->cparams.ecn = true; + + if (opt) { + int err = fq_codel_change(sch, opt); + if (err) + return err; + } + + if (!q->flows) { + q->flows = fq_codel_zalloc(q->flows_cnt * + sizeof(struct fq_codel_flow)); + if (!q->flows) + return -ENOMEM; + q->backlogs = fq_codel_zalloc(q->flows_cnt * sizeof(u32)); + if (!q->backlogs) { + fq_codel_free(q->flows); + return -ENOMEM; + } + for (i = 0; i < q->flows_cnt; i++) { + struct fq_codel_flow *flow = q->flows + i; + + INIT_LIST_HEAD(&flow->flowchain); + } + } + if (sch->limit >= 1) + sch->flags |= TCQ_F_CAN_BYPASS; + else + sch->flags &= ~TCQ_F_CAN_BYPASS; + return 0; +} + +static int fq_codel_dump(struct Qdisc *sch, struct sk_buff *skb) +{ + struct fq_codel_sched_data *q = qdisc_priv(sch); + struct nlattr *opts; + + opts = nla_nest_start(skb, TCA_OPTIONS); + if (opts == NULL) + goto nla_put_failure; + + if (nla_put_u32(skb, TCA_FQ_CODEL_TARGET, + codel_time_to_us(q->cparams.target)) || + nla_put_u32(skb, TCA_FQ_CODEL_LIMIT, + sch->limit) || + nla_put_u32(skb, TCA_FQ_CODEL_INTERVAL, + codel_time_to_us(q->cparams.interval)) || + nla_put_u32(skb, TCA_FQ_CODEL_ECN, + q->cparams.ecn) || + nla_put_u32(skb, TCA_FQ_CODEL_QUANTUM, + q->quantum) || + nla_put_u32(skb, TCA_FQ_CODEL_FLOWS, + q->flows_cnt)) + goto nla_put_failure; + + nla_nest_end(skb, opts); + return skb->len; + +nla_put_failure: + return -1; +} + +static int fq_codel_dump_stats(struct Qdisc *sch, struct gnet_dump *d) +{ + struct fq_codel_sched_data *q = qdisc_priv(sch); + struct tc_fq_codel_xstats st = { + .type = TCA_FQ_CODEL_XSTATS_QDISC, + }; + struct list_head *pos; + + st.qdisc_stats.maxpacket = q->cstats.maxpacket; + st.qdisc_stats.drop_overlimit = q->drop_overlimit; + st.qdisc_stats.ecn_mark = q->cstats.ecn_mark; + st.qdisc_stats.new_flow_count = q->new_flow_count; + + list_for_each(pos, &q->new_flows) + st.qdisc_stats.new_flows_len++; + + list_for_each(pos, &q->old_flows) + st.qdisc_stats.old_flows_len++; + + return gnet_stats_copy_app(d, &st, sizeof(st)); +} + +static struct Qdisc *fq_codel_leaf(struct Qdisc *sch, unsigned long arg) +{ + return NULL; +} + +static unsigned long fq_codel_get(struct Qdisc *sch, u32 classid) +{ + return 0; +} + +static unsigned long fq_codel_bind(struct Qdisc *sch, unsigned long parent, + u32 classid) +{ + /* we cannot bypass queue discipline anymore */ + sch->flags &= ~TCQ_F_CAN_BYPASS; + return 0; +} + +static void fq_codel_put(struct Qdisc *q, unsigned long cl) +{ +} + +static struct tcf_proto **fq_codel_find_tcf(struct Qdisc *sch, unsigned long cl) +{ + struct fq_codel_sched_data *q = qdisc_priv(sch); + + if (cl) + return NULL; + return &q->filter_list; +} + +static int fq_codel_dump_class(struct Qdisc *sch, unsigned long cl, + struct sk_buff *skb, struct tcmsg *tcm) +{ + tcm->tcm_handle |= TC_H_MIN(cl); + return 0; +} + +static int fq_codel_dump_class_stats(struct Qdisc *sch, unsigned long cl, + struct gnet_dump *d) +{ + struct fq_codel_sched_data *q = qdisc_priv(sch); + u32 idx = cl - 1; + struct gnet_stats_queue qs = { 0 }; + struct tc_fq_codel_xstats xstats; + + if (idx < q->flows_cnt) { + const struct fq_codel_flow *flow = &q->flows[idx]; + const struct sk_buff *skb = flow->head; + + memset(&xstats, 0, sizeof(xstats)); + xstats.type = TCA_FQ_CODEL_XSTATS_CLASS; + xstats.class_stats.deficit = flow->deficit; + xstats.class_stats.ldelay = + codel_time_to_us(flow->cvars.ldelay); + xstats.class_stats.count = flow->cvars.count; + xstats.class_stats.lastcount = flow->cvars.lastcount; + xstats.class_stats.dropping = flow->cvars.dropping; + if (flow->cvars.dropping) { + codel_tdiff_t delta = flow->cvars.drop_next - + codel_get_time(); + + xstats.class_stats.drop_next = (delta >= 0) ? + codel_time_to_us(delta) : + -codel_time_to_us(-delta); + } + while (skb) { + qs.qlen++; + skb = skb->next; + } + qs.backlog = q->backlogs[idx]; + qs.drops = flow->dropped; + } + if (gnet_stats_copy_queue(d, &qs) < 0) + return -1; + if (idx < q->flows_cnt) + return gnet_stats_copy_app(d, &xstats, sizeof(xstats)); + return 0; +} + +static void fq_codel_walk(struct Qdisc *sch, struct qdisc_walker *arg) +{ + struct fq_codel_sched_data *q = qdisc_priv(sch); + unsigned int i; + + if (arg->stop) + return; + + for (i = 0; i < q->flows_cnt; i++) { + if (list_empty(&q->flows[i].flowchain) || + arg->count < arg->skip) { + arg->count++; + continue; + } + if (arg->fn(sch, i + 1, arg) < 0) { + arg->stop = 1; + break; + } + arg->count++; + } +} + +static const struct Qdisc_class_ops fq_codel_class_ops = { + .leaf = fq_codel_leaf, + .get = fq_codel_get, + .put = fq_codel_put, + .tcf_chain = fq_codel_find_tcf, + .bind_tcf = fq_codel_bind, + .unbind_tcf = fq_codel_put, + .dump = fq_codel_dump_class, + .dump_stats = fq_codel_dump_class_stats, + .walk = fq_codel_walk, +}; + +static struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = { + .cl_ops = &fq_codel_class_ops, + .id = "fq_codel", + .priv_size = sizeof(struct fq_codel_sched_data), + .enqueue = fq_codel_enqueue, + .dequeue = fq_codel_dequeue, + .peek = qdisc_peek_dequeued, + .drop = fq_codel_drop, + .init = fq_codel_init, + .reset = fq_codel_reset, + .destroy = fq_codel_destroy, + .change = fq_codel_change, + .dump = fq_codel_dump, + .dump_stats = fq_codel_dump_stats, + .owner = THIS_MODULE, +}; + +static int __init fq_codel_module_init(void) +{ + return register_qdisc(&fq_codel_qdisc_ops); +} + +static void __exit fq_codel_module_exit(void) +{ + unregister_qdisc(&fq_codel_qdisc_ops); +} + +module_init(fq_codel_module_init) +module_exit(fq_codel_module_exit) +MODULE_AUTHOR("Eric Dumazet"); +MODULE_LICENSE("GPL");
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 0eb1202..511323e 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c
@@ -86,9 +86,8 @@ * deadloop is detected. Return OK to try the next skb. */ kfree_skb(skb); - if (net_ratelimit()) - pr_warning("Dead loop on netdevice %s, fix it urgently!\n", - dev_queue->dev->name); + net_warn_ratelimited("Dead loop on netdevice %s, fix it urgently!\n", + dev_queue->dev->name); ret = qdisc_qlen(q); } else { /* @@ -136,9 +135,9 @@ ret = handle_dev_cpu_collision(skb, txq, q); } else { /* Driver returned NETDEV_TX_BUSY - requeue skb */ - if (unlikely (ret != NETDEV_TX_BUSY && net_ratelimit())) - pr_warning("BUG %s code %d qlen %d\n", - dev->name, ret, q->q.qlen); + if (unlikely(ret != NETDEV_TX_BUSY)) + net_warn_ratelimited("BUG %s code %d qlen %d\n", + dev->name, ret, q->q.qlen); ret = dev_requeue_skb(skb, q); }
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index ab620bf..e901583 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c
@@ -255,10 +255,8 @@ u16 dp = tc_index_to_dp(skb); if (dp >= t->DPs || (q = t->tab[dp]) == NULL) { - if (net_ratelimit()) - pr_warning("GRED: Unable to relocate VQ 0x%x " - "after dequeue, screwing up " - "backlog.\n", tc_index_to_dp(skb)); + net_warn_ratelimited("GRED: Unable to relocate VQ 0x%x after dequeue, screwing up backlog\n", + tc_index_to_dp(skb)); } else { q->backlog -= qdisc_pkt_len(skb); @@ -287,10 +285,8 @@ u16 dp = tc_index_to_dp(skb); if (dp >= t->DPs || (q = t->tab[dp]) == NULL) { - if (net_ratelimit()) - pr_warning("GRED: Unable to relocate VQ 0x%x " - "while dropping, screwing up " - "backlog.\n", tc_index_to_dp(skb)); + net_warn_ratelimited("GRED: Unable to relocate VQ 0x%x while dropping, screwing up backlog\n", + tc_index_to_dp(skb)); } else { q->backlog -= len; q->stats.other++;
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 8db3e2c..6c2ec45 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c
@@ -1609,7 +1609,6 @@ if (cl->qdisc->q.qlen == 1) set_active(cl, qdisc_pkt_len(skb)); - bstats_update(&cl->bstats, skb); sch->q.qlen++; return NET_XMIT_SUCCESS; @@ -1657,6 +1656,7 @@ return NULL; } + bstats_update(&cl->bstats, skb); update_vf(cl, qdisc_pkt_len(skb), cur_time); if (realtime) cl->cl_cumul += qdisc_pkt_len(skb);
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index acae5b0..9d75b77 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c
@@ -574,7 +574,6 @@ } return ret; } else { - bstats_update(&cl->bstats, skb); htb_activate(q, cl); } @@ -835,6 +834,7 @@ } while (cl != start); if (likely(skb != NULL)) { + bstats_update(&cl->bstats, skb); cl->un.leaf.deficit[level] -= qdisc_pkt_len(skb); if (cl->un.leaf.deficit[level] < 0) { cl->un.leaf.deficit[level] += cl->quantum;
diff --git a/net/sctp/output.c b/net/sctp/output.c index 69534c5..f1b7d4b 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c
@@ -377,9 +377,7 @@ */ skb_set_owner_w(nskb, sk); - /* The 'obsolete' field of dst is set to 2 when a dst is freed. */ - if (!dst || (dst->obsolete > 1)) { - dst_release(dst); + if (!sctp_transport_dst_check(tp)) { sctp_transport_route(tp, NULL, sctp_sk(sk)); if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) { sctp_assoc_sync_pmtu(asoc);
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index fbb374c..c96d1a8 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c
@@ -1161,9 +1161,8 @@ break; case SCTP_DISPOSITION_VIOLATION: - if (net_ratelimit()) - pr_err("protocol violation state %d chunkid %d\n", - state, subtype.chunk); + net_err_ratelimited("protocol violation state %d chunkid %d\n", + state, subtype.chunk); break; case SCTP_DISPOSITION_NOT_IMPL:
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index a147b4d..9fca103 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c
@@ -1129,17 +1129,15 @@ /* This should never happen, but lets log it if so. */ if (unlikely(!link)) { if (from_addr.sa.sa_family == AF_INET6) { - if (net_ratelimit()) - pr_warn("%s association %p could not find address %pI6\n", - __func__, - asoc, - &from_addr.v6.sin6_addr); + net_warn_ratelimited("%s association %p could not find address %pI6\n", + __func__, + asoc, + &from_addr.v6.sin6_addr); } else { - if (net_ratelimit()) - pr_warn("%s association %p could not find address %pI4\n", - __func__, - asoc, - &from_addr.v4.sin_addr.s_addr); + net_warn_ratelimited("%s association %p could not find address %pI4\n", + __func__, + asoc, + &from_addr.v4.sin_addr.s_addr); } return SCTP_DISPOSITION_DISCARD; }
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 92ba71d..b3b8a8d 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c
@@ -5840,10 +5840,8 @@ if (!sctp_sk(sk)->hmac && sctp_hmac_alg) { tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) { - if (net_ratelimit()) { - pr_info("failed to load transform for %s: %ld\n", - sctp_hmac_alg, PTR_ERR(tfm)); - } + net_info_ratelimited("failed to load transform for %s: %ld\n", + sctp_hmac_alg, PTR_ERR(tfm)); return -ENOSYS; } sctp_sk(sk)->hmac = tfm;
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 3889330..b026ba0 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c
@@ -226,23 +226,6 @@ transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; } -/* this is a complete rip-off from __sk_dst_check - * the cookie is always 0 since this is how it's used in the - * pmtu code - */ -static struct dst_entry *sctp_transport_dst_check(struct sctp_transport *t) -{ - struct dst_entry *dst = t->dst; - - if (dst && dst->obsolete && dst->ops->check(dst, 0) == NULL) { - dst_release(t->dst); - t->dst = NULL; - return NULL; - } - - return dst; -} - void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu) { struct dst_entry *dst;
diff --git a/net/socket.c b/net/socket.c index d3aaa4f..2a2898ce 100644 --- a/net/socket.c +++ b/net/socket.c
@@ -1234,8 +1234,7 @@ */ sock = sock_alloc(); if (!sock) { - if (net_ratelimit()) - printk(KERN_WARNING "socket: no more sockets\n"); + net_warn_ratelimited("socket: no more sockets\n"); return -ENFILE; /* Not exactly a match, but its the closest posix thing */ }
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c index ca8cad8..782bfe1 100644 --- a/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/net/sunrpc/auth_gss/gss_mech_switch.c
@@ -242,12 +242,13 @@ int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr) { struct gss_api_mech *pos = NULL; - int i = 0; + int j, i = 0; spin_lock(®istered_mechs_lock); list_for_each_entry(pos, ®istered_mechs, gm_list) { - array_ptr[i] = pos->gm_pfs->pseudoflavor; - i++; + for (j=0; j < pos->gm_pf_num; j++) { + array_ptr[i++] = pos->gm_pfs[j].pseudoflavor; + } } spin_unlock(®istered_mechs_lock); return i;
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index adf2990..7fee13b 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c
@@ -127,9 +127,7 @@ { static uint32_t clntid; char name[15]; - struct qstr q = { - .name = name, - }; + struct qstr q = { .name = name }; struct dentry *dir, *dentry; int error;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 3b62cf2..fd24239 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c
@@ -1059,12 +1059,9 @@ struct dentry *rpc_d_lookup_sb(const struct super_block *sb, const unsigned char *dir_name) { - struct qstr dir = { - .name = dir_name, - .len = strlen(dir_name), - .hash = full_name_hash(dir_name, strlen(dir_name)), - }; + struct qstr dir = QSTR_INIT(dir_name, strlen(dir_name)); + dir.hash = full_name_hash(dir.name, dir.len); return d_lookup(sb->s_root, &dir); } EXPORT_SYMBOL_GPL(rpc_d_lookup_sb);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 4153846..017c011 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c
@@ -1041,23 +1041,21 @@ * Printk the given error with the address of the client that caused it. */ static __printf(2, 3) -int svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) +void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) { + struct va_format vaf; va_list args; - int r; char buf[RPC_MAX_ADDRBUFLEN]; - if (!net_ratelimit()) - return 0; - - printk(KERN_WARNING "svc: %s: ", - svc_print_addr(rqstp, buf, sizeof(buf))); - va_start(args, fmt); - r = vprintk(fmt, args); - va_end(args); - return r; + vaf.fmt = fmt; + vaf.va = &args; + + net_warn_ratelimited("svc: %s: %pV", + svc_print_addr(rqstp, buf, sizeof(buf)), &vaf); + + va_end(args); } /*
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 4bda09d..b98ee35 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c
@@ -544,14 +544,11 @@ struct svc_xprt *xprt = NULL; spin_lock_bh(&serv->sv_lock); if (!list_empty(&serv->sv_tempsocks)) { - if (net_ratelimit()) { - /* Try to help the admin */ - printk(KERN_NOTICE "%s: too many open " - "connections, consider increasing %s\n", - serv->sv_name, serv->sv_maxconn ? - "the max number of connections." : - "the number of threads."); - } + /* Try to help the admin */ + net_notice_ratelimited("%s: too many open connections, consider increasing the %s\n", + serv->sv_name, serv->sv_maxconn ? + "max number of connections" : + "number of threads"); /* * Always select the oldest connection. It's not fair, * but so is life
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index f0132b2..a6de09d 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c
@@ -617,11 +617,8 @@ rqstp->rq_prot = IPPROTO_UDP; if (!svc_udp_get_dest_address(rqstp, cmh)) { - if (net_ratelimit()) - printk(KERN_WARNING - "svc: received unknown control message %d/%d; " - "dropping RPC reply datagram\n", - cmh->cmsg_level, cmh->cmsg_type); + net_warn_ratelimited("svc: received unknown control message %d/%d; dropping RPC reply datagram\n", + cmh->cmsg_level, cmh->cmsg_type); skb_free_datagram_locked(svsk->sk_sk, skb); return 0; } @@ -871,18 +868,17 @@ if (err == -ENOMEM) printk(KERN_WARNING "%s: no more sockets!\n", serv->sv_name); - else if (err != -EAGAIN && net_ratelimit()) - printk(KERN_WARNING "%s: accept failed (err %d)!\n", - serv->sv_name, -err); + else if (err != -EAGAIN) + net_warn_ratelimited("%s: accept failed (err %d)!\n", + serv->sv_name, -err); return NULL; } set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags); err = kernel_getpeername(newsock, sin, &slen); if (err < 0) { - if (net_ratelimit()) - printk(KERN_WARNING "%s: peername failed (err %d)!\n", - serv->sv_name, -err); + net_warn_ratelimited("%s: peername failed (err %d)!\n", + serv->sv_name, -err); goto failed; /* aborted connection or whatever */ } @@ -1012,19 +1008,15 @@ * bit set in the fragment length header. * But apparently no known nfs clients send fragmented * records. */ - if (net_ratelimit()) - printk(KERN_NOTICE "RPC: multiple fragments " - "per record not supported\n"); + net_notice_ratelimited("RPC: multiple fragments per record not supported\n"); goto err_delete; } svsk->sk_reclen &= RPC_FRAGMENT_SIZE_MASK; dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen); if (svsk->sk_reclen > serv->sv_max_mesg) { - if (net_ratelimit()) - printk(KERN_NOTICE "RPC: " - "fragment too large: 0x%08lx\n", - (unsigned long)svsk->sk_reclen); + net_notice_ratelimited("RPC: fragment too large: 0x%08lx\n", + (unsigned long)svsk->sk_reclen); goto err_delete; } }
diff --git a/net/sysctl_net.c b/net/sysctl_net.c index f3e813a..e3a6e37 100644 --- a/net/sysctl_net.c +++ b/net/sysctl_net.c
@@ -26,10 +26,6 @@ #include <linux/if_ether.h> #endif -#ifdef CONFIG_TR -#include <linux/if_tr.h> -#endif - static struct ctl_table_set * net_ctl_header_lookup(struct ctl_table_root *root, struct nsproxy *namespaces) {
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 30f20fe4..d2a19b0f 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c
@@ -473,7 +473,7 @@ /* fixed already - and no change */ if (wdev->wext.ibss.bssid && bssid && - compare_ether_addr(bssid, wdev->wext.ibss.bssid) == 0) + ether_addr_equal(bssid, wdev->wext.ibss.bssid)) return 0; wdev_lock(wdev);
diff --git a/net/wireless/lib80211_crypt_ccmp.c b/net/wireless/lib80211_crypt_ccmp.c index 755738d..1526c21 100644 --- a/net/wireless/lib80211_crypt_ccmp.c +++ b/net/wireless/lib80211_crypt_ccmp.c
@@ -304,10 +304,8 @@ pos = skb->data + hdr_len; keyidx = pos[3]; if (!(keyidx & (1 << 5))) { - if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: received packet without ExtIV" - " flag from %pM\n", hdr->addr2); - } + net_dbg_ratelimited("CCMP: received packet without ExtIV flag from %pM\n", + hdr->addr2); key->dot11RSNAStatsCCMPFormatErrors++; return -2; } @@ -318,11 +316,8 @@ return -6; } if (!key->key_set) { - if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: received packet from %pM" - " with keyid=%d that does not have a configured" - " key\n", hdr->addr2, keyidx); - } + net_dbg_ratelimited("CCMP: received packet from %pM with keyid=%d that does not have a configured key\n", + hdr->addr2, keyidx); return -3; } @@ -336,15 +331,11 @@ if (ccmp_replay_check(pn, key->rx_pn)) { #ifdef CONFIG_LIB80211_DEBUG - if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: replay detected: STA=%pM " - "previous PN %02x%02x%02x%02x%02x%02x " - "received PN %02x%02x%02x%02x%02x%02x\n", - hdr->addr2, - key->rx_pn[0], key->rx_pn[1], key->rx_pn[2], - key->rx_pn[3], key->rx_pn[4], key->rx_pn[5], - pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]); - } + net_dbg_ratelimited("CCMP: replay detected: STA=%pM previous PN %02x%02x%02x%02x%02x%02x received PN %02x%02x%02x%02x%02x%02x\n", + hdr->addr2, + key->rx_pn[0], key->rx_pn[1], key->rx_pn[2], + key->rx_pn[3], key->rx_pn[4], key->rx_pn[5], + pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]); #endif key->dot11RSNAStatsCCMPReplays++; return -4; @@ -370,10 +361,8 @@ } if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { - if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: decrypt failed: STA=" - "%pM\n", hdr->addr2); - } + net_dbg_ratelimited("CCMP: decrypt failed: STA=%pM\n", + hdr->addr2); key->dot11RSNAStatsCCMPDecryptErrors++; return -5; }
diff --git a/net/wireless/lib80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c index 3873484..d475cfc 100644 --- a/net/wireless/lib80211_crypt_tkip.c +++ b/net/wireless/lib80211_crypt_tkip.c
@@ -360,12 +360,9 @@ struct scatterlist sg; if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { - if (net_ratelimit()) { - struct ieee80211_hdr *hdr = - (struct ieee80211_hdr *)skb->data; - printk(KERN_DEBUG ": TKIP countermeasures: dropped " - "TX packet to %pM\n", hdr->addr1); - } + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + net_dbg_ratelimited("TKIP countermeasures: dropped TX packet to %pM\n", + hdr->addr1); return -1; } @@ -420,10 +417,8 @@ hdr = (struct ieee80211_hdr *)skb->data; if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { - if (net_ratelimit()) { - printk(KERN_DEBUG ": TKIP countermeasures: dropped " - "received packet from %pM\n", hdr->addr2); - } + net_dbg_ratelimited("TKIP countermeasures: dropped received packet from %pM\n", + hdr->addr2); return -1; } @@ -433,10 +428,8 @@ pos = skb->data + hdr_len; keyidx = pos[3]; if (!(keyidx & (1 << 5))) { - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: received packet without ExtIV" - " flag from %pM\n", hdr->addr2); - } + net_dbg_ratelimited("TKIP: received packet without ExtIV flag from %pM\n", + hdr->addr2); return -2; } keyidx >>= 6; @@ -446,11 +439,8 @@ return -6; } if (!tkey->key_set) { - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: received packet from %pM" - " with keyid=%d that does not have a configured" - " key\n", hdr->addr2, keyidx); - } + net_dbg_ratelimited("TKIP: received packet from %pM with keyid=%d that does not have a configured key\n", + hdr->addr2, keyidx); return -3; } iv16 = (pos[0] << 8) | pos[2]; @@ -459,12 +449,9 @@ if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) { #ifdef CONFIG_LIB80211_DEBUG - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: replay detected: STA=%pM" - " previous TSC %08x%04x received TSC " - "%08x%04x\n", hdr->addr2, - tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); - } + net_dbg_ratelimited("TKIP: replay detected: STA=%pM previous TSC %08x%04x received TSC %08x%04x\n", + hdr->addr2, tkey->rx_iv32, tkey->rx_iv16, + iv32, iv16); #endif tkey->dot11RSNAStatsTKIPReplays++; return -4; @@ -481,11 +468,8 @@ crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16); sg_init_one(&sg, pos, plen + 4); if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { - if (net_ratelimit()) { - printk(KERN_DEBUG ": TKIP: failed to decrypt " - "received packet from %pM\n", - hdr->addr2); - } + net_dbg_ratelimited("TKIP: failed to decrypt received packet from %pM\n", + hdr->addr2); return -7; } @@ -501,10 +485,8 @@ tkey->rx_phase1_done = 0; } #ifdef CONFIG_LIB80211_DEBUG - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: ICV error detected: STA=" - "%pM\n", hdr->addr2); - } + net_dbg_ratelimited("TKIP: ICV error detected: STA=%pM\n", + hdr->addr2); #endif tkey->dot11RSNAStatsTKIPICVErrors++; return -5;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 6801d96..eb90988 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c
@@ -101,7 +101,7 @@ ASSERT_WDEV_LOCK(wdev); if (wdev->current_bss && - compare_ether_addr(wdev->current_bss->pub.bssid, bssid) == 0) { + ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { cfg80211_unhold_bss(wdev->current_bss); cfg80211_put_bss(&wdev->current_bss->pub); wdev->current_bss = NULL; @@ -116,7 +116,7 @@ reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); - from_ap = compare_ether_addr(mgmt->sa, dev->dev_addr) != 0; + from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr); __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); } else if (wdev->sme_state == CFG80211_SME_CONNECTING) { __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0, @@ -155,7 +155,7 @@ return; if (wdev->current_bss && - compare_ether_addr(wdev->current_bss->pub.bssid, bssid) == 0) { + ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { cfg80211_sme_disassoc(dev, wdev->current_bss); cfg80211_unhold_bss(wdev->current_bss); cfg80211_put_bss(&wdev->current_bss->pub); @@ -166,7 +166,7 @@ reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); - from_ap = compare_ether_addr(mgmt->sa, dev->dev_addr) != 0; + from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr); __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); } EXPORT_SYMBOL(__cfg80211_send_disassoc); @@ -286,7 +286,7 @@ return -EINVAL; if (wdev->current_bss && - compare_ether_addr(bssid, wdev->current_bss->pub.bssid) == 0) + ether_addr_equal(bssid, wdev->current_bss->pub.bssid)) return -EALREADY; memset(&req, 0, sizeof(req)); @@ -363,7 +363,7 @@ memset(&req, 0, sizeof(req)); if (wdev->current_bss && prev_bssid && - compare_ether_addr(wdev->current_bss->pub.bssid, prev_bssid) == 0) { + ether_addr_equal(wdev->current_bss->pub.bssid, prev_bssid)) { /* * Trying to reassociate: Allow this to proceed and let the old * association to be dropped when the new one is completed. @@ -447,8 +447,7 @@ if (local_state_change) { if (wdev->current_bss && - compare_ether_addr(wdev->current_bss->pub.bssid, bssid) - == 0) { + ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { cfg80211_unhold_bss(wdev->current_bss); cfg80211_put_bss(&wdev->current_bss->pub); wdev->current_bss = NULL; @@ -497,7 +496,7 @@ req.local_state_change = local_state_change; req.ie = ie; req.ie_len = ie_len; - if (compare_ether_addr(wdev->current_bss->pub.bssid, bssid) == 0) + if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) req.bss = &wdev->current_bss->pub; else return -ENOTCONN; @@ -760,8 +759,8 @@ break; } - if (compare_ether_addr(wdev->current_bss->pub.bssid, - mgmt->bssid)) { + if (!ether_addr_equal(wdev->current_bss->pub.bssid, + mgmt->bssid)) { err = -ENOTCONN; break; } @@ -774,8 +773,8 @@ break; /* for station, check that DA is the AP */ - if (compare_ether_addr(wdev->current_bss->pub.bssid, - mgmt->da)) { + if (!ether_addr_equal(wdev->current_bss->pub.bssid, + mgmt->da)) { err = -ENOTCONN; break; } @@ -783,11 +782,11 @@ case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: case NL80211_IFTYPE_AP_VLAN: - if (compare_ether_addr(mgmt->bssid, dev->dev_addr)) + if (!ether_addr_equal(mgmt->bssid, dev->dev_addr)) err = -EINVAL; break; case NL80211_IFTYPE_MESH_POINT: - if (compare_ether_addr(mgmt->sa, mgmt->bssid)) { + if (!ether_addr_equal(mgmt->sa, mgmt->bssid)) { err = -EINVAL; break; } @@ -806,7 +805,7 @@ return err; } - if (compare_ether_addr(mgmt->sa, dev->dev_addr) != 0) + if (!ether_addr_equal(mgmt->sa, dev->dev_addr)) return -EINVAL; /* Transmit the Action frame as requested by user space */
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 9dee87c..af2b1ca 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c
@@ -281,7 +281,7 @@ { const u8 *ssidie; - if (bssid && compare_ether_addr(a->bssid, bssid)) + if (bssid && !ether_addr_equal(a->bssid, bssid)) return false; if (!ssid)
diff --git a/net/wireless/util.c b/net/wireless/util.c index 177df03..55d9946 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c
@@ -370,7 +370,7 @@ iftype != NL80211_IFTYPE_P2P_CLIENT && iftype != NL80211_IFTYPE_MESH_POINT) || (is_multicast_ether_addr(dst) && - !compare_ether_addr(src, addr))) + ether_addr_equal(src, addr))) return -1; if (iftype == NL80211_IFTYPE_MESH_POINT) { struct ieee80211s_hdr *meshdr = @@ -398,9 +398,9 @@ payload = skb->data + hdrlen; ethertype = (payload[6] << 8) | payload[7]; - if (likely((compare_ether_addr(payload, rfc1042_header) == 0 && + if (likely((ether_addr_equal(payload, rfc1042_header) && ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || - compare_ether_addr(payload, bridge_tunnel_header) == 0)) { + ether_addr_equal(payload, bridge_tunnel_header))) { /* remove RFC1042 or Bridge-Tunnel encapsulation and * replace EtherType */ skb_pull(skb, hdrlen + 6); @@ -609,10 +609,9 @@ payload = frame->data; ethertype = (payload[6] << 8) | payload[7]; - if (likely((compare_ether_addr(payload, rfc1042_header) == 0 && + if (likely((ether_addr_equal(payload, rfc1042_header) && ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || - compare_ether_addr(payload, - bridge_tunnel_header) == 0)) { + ether_addr_equal(payload, bridge_tunnel_header))) { /* remove RFC1042 or Bridge-Tunnel * encapsulation and replace EtherType */ skb_pull(frame, 6);
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index 7c01c2f..7decbd3 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c
@@ -276,7 +276,7 @@ /* fixed already - and no change */ if (wdev->wext.connect.bssid && bssid && - compare_ether_addr(bssid, wdev->wext.connect.bssid) == 0) + ether_addr_equal(bssid, wdev->wext.connect.bssid)) goto out; err = __cfg80211_disconnect(rdev, dev,
diff --git a/net/wireless/wext-spy.c b/net/wireless/wext-spy.c index 5d643a5..33bef22 100644 --- a/net/wireless/wext-spy.c +++ b/net/wireless/wext-spy.c
@@ -203,7 +203,7 @@ /* Update all records that match */ for (i = 0; i < spydata->spy_number; i++) - if (!compare_ether_addr(address, spydata->spy_address[i])) { + if (ether_addr_equal(address, spydata->spy_address[i])) { memcpy(&(spydata->spy_stat[i]), wstats, sizeof(struct iw_quality)); match = i;
diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig index 6d08167..ce90b8d 100644 --- a/net/xfrm/Kconfig +++ b/net/xfrm/Kconfig
@@ -3,12 +3,17 @@ # config XFRM bool - select CRYPTO depends on NET +config XFRM_ALGO + tristate + select XFRM + select CRYPTO + config XFRM_USER tristate "Transformation user configuration interface" - depends on INET && XFRM + depends on INET + select XFRM_ALGO ---help--- Support for Transformation(XFRM) user configuration interface like IPsec used by native Linux tools. @@ -48,13 +53,13 @@ config XFRM_IPCOMP tristate - select XFRM + select XFRM_ALGO select CRYPTO select CRYPTO_DEFLATE config NET_KEY tristate "PF_KEY sockets" - select XFRM + select XFRM_ALGO ---help--- PF_KEYv2 socket family, compatible to KAME ones. They are required if you are going to use IPsec tools ported
diff --git a/net/xfrm/Makefile b/net/xfrm/Makefile index aa429ee..c0e9619 100644 --- a/net/xfrm/Makefile +++ b/net/xfrm/Makefile
@@ -3,8 +3,9 @@ # obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_hash.o \ - xfrm_input.o xfrm_output.o xfrm_algo.o \ + xfrm_input.o xfrm_output.o \ xfrm_sysctl.o xfrm_replay.o obj-$(CONFIG_XFRM_STATISTICS) += xfrm_proc.o +obj-$(CONFIG_XFRM_ALGO) += xfrm_algo.o obj-$(CONFIG_XFRM_USER) += xfrm_user.o obj-$(CONFIG_XFRM_IPCOMP) += xfrm_ipcomp.o
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index 791ab2e..4ce2d93 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c
@@ -15,9 +15,6 @@ #include <linux/crypto.h> #include <linux/scatterlist.h> #include <net/xfrm.h> -#if defined(CONFIG_INET_AH) || defined(CONFIG_INET_AH_MODULE) || defined(CONFIG_INET6_AH) || defined(CONFIG_INET6_AH_MODULE) -#include <net/ah.h> -#endif #if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE) #include <net/esp.h> #endif @@ -752,3 +749,5 @@ } EXPORT_SYMBOL_GPL(pskb_put); #endif + +MODULE_LICENSE("GPL");
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 7661576..3c87a1c 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c
@@ -56,7 +56,7 @@ static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, int dir); -static inline int +static inline bool __xfrm4_selector_match(const struct xfrm_selector *sel, const struct flowi *fl) { const struct flowi4 *fl4 = &fl->u.ip4; @@ -69,7 +69,7 @@ (fl4->flowi4_oif == sel->ifindex || !sel->ifindex); } -static inline int +static inline bool __xfrm6_selector_match(const struct xfrm_selector *sel, const struct flowi *fl) { const struct flowi6 *fl6 = &fl->u.ip6; @@ -82,8 +82,8 @@ (fl6->flowi6_oif == sel->ifindex || !sel->ifindex); } -int xfrm_selector_match(const struct xfrm_selector *sel, const struct flowi *fl, - unsigned short family) +bool xfrm_selector_match(const struct xfrm_selector *sel, const struct flowi *fl, + unsigned short family) { switch (family) { case AF_INET: @@ -91,7 +91,7 @@ case AF_INET6: return __xfrm6_selector_match(sel, fl); } - return 0; + return false; } static inline struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, @@ -877,7 +877,8 @@ u8 type, u16 family, int dir) { const struct xfrm_selector *sel = &pol->selector; - int match, ret = -ESRCH; + int ret = -ESRCH; + bool match; if (pol->family != family || (fl->flowi_mark & pol->mark.m) != pol->mark.v || @@ -1006,8 +1007,8 @@ read_lock_bh(&xfrm_policy_lock); if ((pol = sk->sk_policy[dir]) != NULL) { - int match = xfrm_selector_match(&pol->selector, fl, - sk->sk_family); + bool match = xfrm_selector_match(&pol->selector, fl, + sk->sk_family); int err = 0; if (match) { @@ -2767,8 +2768,8 @@ #endif #ifdef CONFIG_XFRM_MIGRATE -static int xfrm_migrate_selector_match(const struct xfrm_selector *sel_cmp, - const struct xfrm_selector *sel_tgt) +static bool xfrm_migrate_selector_match(const struct xfrm_selector *sel_cmp, + const struct xfrm_selector *sel_tgt) { if (sel_cmp->proto == IPSEC_ULPROTO_ANY) { if (sel_tgt->family == sel_cmp->family && @@ -2778,14 +2779,14 @@ sel_cmp->family) == 0 && sel_tgt->prefixlen_d == sel_cmp->prefixlen_d && sel_tgt->prefixlen_s == sel_cmp->prefixlen_s) { - return 1; + return true; } } else { if (memcmp(sel_tgt, sel_cmp, sizeof(*sel_tgt)) == 0) { - return 1; + return true; } } - return 0; + return false; } static struct xfrm_policy * xfrm_migrate_policy_find(const struct xfrm_selector *sel,
diff --git a/scripts/Makefile b/scripts/Makefile index df7678f..3626666 100644 --- a/scripts/Makefile +++ b/scripts/Makefile
@@ -8,6 +8,8 @@ # conmakehash: Create arrays for initializing the kernel console tables # docproc: Used in Documentation/DocBook +HOST_EXTRACFLAGS += -I$(srctree)/tools/include + hostprogs-$(CONFIG_KALLSYMS) += kallsyms hostprogs-$(CONFIG_LOGO) += pnmtologo hostprogs-$(CONFIG_VT) += conmakehash
diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c index 64417a7..d8c670c 100644 --- a/sound/pci/echoaudio/echoaudio_dsp.c +++ b/sound/pci/echoaudio/echoaudio_dsp.c
@@ -475,7 +475,7 @@ const struct firmware *fw; int box_type, err; - if (snd_BUG_ON(!chip->dsp_code_to_load || !chip->comm_page)) + if (snd_BUG_ON(!chip->comm_page)) return -EPERM; /* See if the ASIC is present and working - only if the DSP is already loaded */
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 7a8fcc4..841475c 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c
@@ -5444,10 +5444,6 @@ list_for_each_entry(codec, &bus->codec_list, list) { if (hda_codec_is_power_on(codec)) hda_call_codec_suspend(codec); - else /* forcibly change the power to D3 even if not used */ - hda_set_power_state(codec, - codec->afg ? codec->afg : codec->mfg, - AC_PWRST_D3); if (codec->patch_ops.post_suspend) codec->patch_ops.post_suspend(codec); }
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index c19e71a..1f35052 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c
@@ -783,11 +783,13 @@ { struct azx *chip = bus->private_data; unsigned long timeout; + unsigned long loopcounter; int do_poll = 0; again: timeout = jiffies + msecs_to_jiffies(1000); - for (;;) { + + for (loopcounter = 0;; loopcounter++) { if (chip->polling_mode || do_poll) { spin_lock_irq(&chip->reg_lock); azx_update_rirb(chip); @@ -803,7 +805,7 @@ } if (time_after(jiffies, timeout)) break; - if (bus->needs_damn_long_delay) + if (bus->needs_damn_long_delay || loopcounter > 3000) msleep(2); /* temporary workaround */ else { udelay(10); @@ -2351,6 +2353,17 @@ * power management */ +static int snd_hda_codecs_inuse(struct hda_bus *bus) +{ + struct hda_codec *codec; + + list_for_each_entry(codec, &bus->codec_list, list) { + if (snd_hda_codec_needs_resume(codec)) + return 1; + } + return 0; +} + static int azx_suspend(struct pci_dev *pci, pm_message_t state) { struct snd_card *card = pci_get_drvdata(pci); @@ -2397,7 +2410,8 @@ return -EIO; azx_init_pci(chip); - azx_init_chip(chip, 1); + if (snd_hda_codecs_inuse(chip->bus)) + azx_init_chip(chip, 1); snd_hda_resume(chip->bus); snd_power_change_state(card, SNDRV_CTL_POWER_D0);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 818f90b..7810913 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c
@@ -5405,6 +5405,8 @@ SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", ALC882_FIXUP_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), + SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G", + ALC882_FIXUP_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G), SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), @@ -5438,6 +5440,7 @@ SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), + SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3", ALC889_FIXUP_CD), SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), @@ -5638,13 +5641,13 @@ snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); } #endif - alc_auto_parse_customize_define(codec); - alc_fix_pll_init(codec, 0x20, 0x0a, 10); alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + alc_auto_parse_customize_define(codec); + /* automatic parse from the BIOS config */ err = alc262_parse_auto_config(codec); if (err < 0) @@ -6249,8 +6252,6 @@ spec->mixer_nid = 0x0b; - alc_auto_parse_customize_define(codec); - err = alc_codec_rename_from_preset(codec); if (err < 0) goto error; @@ -6283,6 +6284,8 @@ alc269_fixup_tbl, alc269_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + alc_auto_parse_customize_define(codec); + /* automatic parse from the BIOS config */ err = alc269_parse_auto_config(codec); if (err < 0) @@ -6859,8 +6862,6 @@ /* handle multiple HPs as is */ spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; - alc_auto_parse_customize_define(codec); - alc_fix_pll_init(codec, 0x20, 0x04, 15); err = alc_codec_rename_from_preset(codec); @@ -6877,6 +6878,9 @@ alc_pick_fixup(codec, alc662_fixup_models, alc662_fixup_tbl, alc662_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + + alc_auto_parse_customize_define(codec); + /* automatic parse from the BIOS config */ err = alc662_parse_auto_config(codec); if (err < 0)
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 4742cac..2cb1e08f 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c
@@ -4415,9 +4415,9 @@ def_conf = get_defcfg_connect(def_conf); /* skip any ports that don't have jacks since presence * detection is useless */ - if (def_conf != AC_JACK_PORT_COMPLEX) { - if (def_conf != AC_JACK_PORT_NONE) - stac_toggle_power_map(codec, nid, 1); + if (def_conf != AC_JACK_PORT_NONE && + !is_jack_detectable(codec, nid)) { + stac_toggle_power_map(codec, nid, 1); continue; } if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) {
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index b68cdec..0b2aea2 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c
@@ -5170,6 +5170,7 @@ strcpy(hw->name, "HDSP hwdep interface"); hw->ops.ioctl = snd_hdsp_hwdep_ioctl; + hw->ops.ioctl_compat = snd_hdsp_hwdep_ioctl; return 0; }
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c index df3ac73..b39ad35 100644 --- a/sound/soc/blackfin/bf5xx-ssm2602.c +++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -99,6 +99,7 @@ .platform_name = "bfin-i2s-pcm-audio", .codec_name = "ssm2602.0-001b", .ops = &bf5xx_ssm2602_ops, + .dai_fmt = BF5XX_SSM2602_DAIFMT, }, { .name = "ssm2602", @@ -108,6 +109,7 @@ .platform_name = "bfin-i2s-pcm-audio", .codec_name = "ssm2602.0-001b", .ops = &bf5xx_ssm2602_ops, + .dai_fmt = BF5XX_SSM2602_DAIFMT, }, };
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 07c44b7..3686417 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c
@@ -568,22 +568,22 @@ attn_tlv), SOC_SINGLE_TLV("SPK-IP Mono Volume", - CS42L73_SPKMIPMA, 0, 0x3E, 1, attn_tlv), + CS42L73_SPKMIPMA, 0, 0x3F, 1, attn_tlv), SOC_SINGLE_TLV("SPK-XSP Mono Volume", - CS42L73_SPKMXSPA, 0, 0x3E, 1, attn_tlv), + CS42L73_SPKMXSPA, 0, 0x3F, 1, attn_tlv), SOC_SINGLE_TLV("SPK-ASP Mono Volume", - CS42L73_SPKMASPA, 0, 0x3E, 1, attn_tlv), + CS42L73_SPKMASPA, 0, 0x3F, 1, attn_tlv), SOC_SINGLE_TLV("SPK-VSP Mono Volume", - CS42L73_SPKMVSPMA, 0, 0x3E, 1, attn_tlv), + CS42L73_SPKMVSPMA, 0, 0x3F, 1, attn_tlv), SOC_SINGLE_TLV("ESL-IP Mono Volume", - CS42L73_ESLMIPMA, 0, 0x3E, 1, attn_tlv), + CS42L73_ESLMIPMA, 0, 0x3F, 1, attn_tlv), SOC_SINGLE_TLV("ESL-XSP Mono Volume", - CS42L73_ESLMXSPA, 0, 0x3E, 1, attn_tlv), + CS42L73_ESLMXSPA, 0, 0x3F, 1, attn_tlv), SOC_SINGLE_TLV("ESL-ASP Mono Volume", - CS42L73_ESLMASPA, 0, 0x3E, 1, attn_tlv), + CS42L73_ESLMASPA, 0, 0x3F, 1, attn_tlv), SOC_SINGLE_TLV("ESL-VSP Mono Volume", - CS42L73_ESLMVSPMA, 0, 0x3E, 1, attn_tlv), + CS42L73_ESLMVSPMA, 0, 0x3F, 1, attn_tlv), SOC_ENUM("IP Digital Swap/Mono Select", ip_swap_enum),
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 16d55f9..df1e07f 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c
@@ -472,7 +472,7 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0xff7f; + u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0x17f; switch (level) { case SND_SOC_BIAS_ON: @@ -491,7 +491,7 @@ case SND_SOC_BIAS_OFF: /* everything off, dac mute, inactive */ snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0); - snd_soc_write(codec, TLV320AIC23_PWR, 0xffff); + snd_soc_write(codec, TLV320AIC23_PWR, 0x1ff); break; } codec->dapm.bias_level = level;
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 8c4c959..aa12c6b 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c
@@ -60,7 +60,7 @@ }; struct wm8350_data { - struct snd_soc_codec codec; + struct wm8350 *wm8350; struct wm8350_output out1; struct wm8350_output out2; struct wm8350_jack_data hpl; @@ -1309,7 +1309,7 @@ struct wm8350_jack_data *jack, u16 mask) { - struct wm8350 *wm8350 = priv->codec.control_data; + struct wm8350 *wm8350 = priv->wm8350; u16 reg; int report; @@ -1342,7 +1342,7 @@ static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) { struct wm8350_data *priv = data; - struct wm8350 *wm8350 = priv->codec.control_data; + struct wm8350 *wm8350 = priv->wm8350; struct wm8350_jack_data *jack = NULL; switch (irq - wm8350->irq_base) { @@ -1427,7 +1427,7 @@ static irqreturn_t wm8350_mic_handler(int irq, void *data) { struct wm8350_data *priv = data; - struct wm8350 *wm8350 = priv->codec.control_data; + struct wm8350 *wm8350 = priv->wm8350; u16 reg; int report = 0; @@ -1536,6 +1536,8 @@ return -ENOMEM; snd_soc_codec_set_drvdata(codec, priv); + priv->wm8350 = wm8350; + for (i = 0; i < ARRAY_SIZE(supply_names); i++) priv->supplies[i].supply = supply_names[i]; @@ -1544,7 +1546,6 @@ if (ret != 0) return ret; - wm8350->codec.codec = codec; codec->control_data = wm8350; /* Put the codec into reset if it wasn't already */
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6c1fe3a..2de12eb 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c
@@ -1144,7 +1144,7 @@ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA, 0); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, + snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA, 0);
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index f13f288..6c028c4 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c
@@ -1035,7 +1035,7 @@ enum snd_soc_bias_level level) { struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); - int val; + int mask, val; switch (level) { case SND_SOC_BIAS_STANDBY: @@ -1047,6 +1047,13 @@ case SND_SOC_BIAS_ON: /* Turn off any unneded single ended outputs */ val = 0; + mask = 0; + + if (hubs->lineout1_se) + mask |= WM8993_LINEOUT1N_ENA | WM8993_LINEOUT1P_ENA; + + if (hubs->lineout2_se) + mask |= WM8993_LINEOUT2N_ENA | WM8993_LINEOUT2P_ENA; if (hubs->lineout1_se && hubs->lineout1n_ena) val |= WM8993_LINEOUT1N_ENA; @@ -1061,11 +1068,7 @@ val |= WM8993_LINEOUT2P_ENA; snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3, - WM8993_LINEOUT1N_ENA | - WM8993_LINEOUT1P_ENA | - WM8993_LINEOUT2N_ENA | - WM8993_LINEOUT2P_ENA, - val); + mask, val); /* Remove the input clamps */ snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG,
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index a59bd35..5a649da 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c
@@ -401,6 +401,10 @@ } out: + /* free preallocated buffers in case of error */ + if (ret) + omap_pcm_free_dma_buffers(pcm); + return ret; }
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index 7218507..79fbeea9 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -166,7 +166,7 @@ static __devinit int s3c2412_iis_dev_probe(struct platform_device *pdev) { - return snd_soc_register_dai(&pdev->dev, &s3c2412_i2s_dai); + return s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai); } static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev)
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c index 9d9ad8d..8526e1e 100644 --- a/sound/soc/sh/migor.c +++ b/sound/soc/sh/migor.c
@@ -35,7 +35,7 @@ return codec_freq; } -static struct clk_ops siumckb_clk_ops = { +static struct sh_clk_ops siumckb_clk_ops = { .recalc = siumckb_recalc, };
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 1d6a80c..c88d974 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c
@@ -3625,10 +3625,10 @@ int i, ret; num_routes = of_property_count_strings(np, propname); - if (num_routes & 1) { + if (num_routes < 0 || num_routes & 1) { dev_err(card->dev, - "Property '%s's length is not even\n", - propname); + "Property '%s' does not exist or its length is not even\n", + propname); return -EINVAL; } num_routes /= 2;
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 9bf3fc7..92271d3 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile
@@ -774,10 +774,10 @@ # over the general rule for .o $(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Iutil/ -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $< + $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Iutil/ -w $< $(OUTPUT)util/%-bison.o: $(OUTPUT)util/%-bison.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -Iutil/ -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $< + $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -Iutil/ -w $< $(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index c941bb6..1e5e9b2 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c
@@ -283,6 +283,8 @@ { struct perf_event_attr *attr = &evsel->attr; struct xyarray *group_fd = NULL; + bool exclude_guest_missing = false; + int ret; if (group && evsel != first) group_fd = first->fd; @@ -293,16 +295,39 @@ attr->inherit = !no_inherit; - if (system_wide) - return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, +retry: + if (exclude_guest_missing) + evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; + + if (system_wide) { + ret = perf_evsel__open_per_cpu(evsel, evsel_list->cpus, group, group_fd); + if (ret) + goto check_ret; + return 0; + } + if (!target_pid && !target_tid && (!group || evsel == first)) { attr->disabled = 1; attr->enable_on_exec = 1; } - return perf_evsel__open_per_thread(evsel, evsel_list->threads, - group, group_fd); + ret = perf_evsel__open_per_thread(evsel, evsel_list->threads, + group, group_fd); + if (!ret) + return 0; + /* fall through */ +check_ret: + if (ret && errno == EINVAL) { + if (!exclude_guest_missing && + (evsel->attr.exclude_guest || evsel->attr.exclude_host)) { + pr_debug("Old kernel, cannot exclude " + "guest or host samples.\n"); + exclude_guest_missing = true; + goto retry; + } + } + return ret; } /* @@ -463,8 +488,13 @@ list_for_each_entry(counter, &evsel_list->entries, node) { if (create_perf_stat_counter(counter, first) < 0) { + /* + * PPC returns ENXIO for HW counters until 2.6.37 + * (behavior changed with commit b0a873e). + */ if (errno == EINVAL || errno == ENOSYS || - errno == ENOENT || errno == EOPNOTSUPP) { + errno == ENOENT || errno == EOPNOTSUPP || + errno == ENXIO) { if (verbose) ui__warning("%s event is not supported by the kernel.\n", event_name(counter));
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 4c7c2d7..c0b70c6 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c
@@ -296,7 +296,7 @@ if (mkdir_p(filename, 0755)) goto out_free; - snprintf(filename + len, sizeof(filename) - len, "/%s", sbuild_id); + snprintf(filename + len, size - len, "/%s", sbuild_id); if (access(filename, F_OK)) { if (is_kallsyms) {