mirror of https://gitee.com/openkylin/linux.git
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1244 commits) pkt_sched: Rename PSCHED_US2NS and PSCHED_NS2US ipv4: Fix fib_trie rebalancing Bluetooth: Fix issue with uninitialized nsh.type in DTL-1 driver Bluetooth: Fix Kconfig issue with RFKILL integration PIM-SM: namespace changes ipv4: update ARPD help text net: use a deferred timer in rt_check_expire ieee802154: fix kconfig bool/tristate muckup bonding: initialization rework bonding: use is_zero_ether_addr bonding: network device names are case sensative bonding: elminate bad refcount code bonding: fix style issues bonding: fix destructor bonding: remove bonding read/write semaphore bonding: initialize before registration bonding: bond_create always called with default parameters x_tables: Convert printk to pr_err netfilter: conntrack: optional reliable conntrack event delivery list_nulls: add hlist_nulls_add_head and hlist_nulls_del ...
This commit is contained in:
commit
2ed0e21b30
4
CREDITS
4
CREDITS
|
@ -1253,6 +1253,10 @@ S: 8124 Constitution Apt. 7
|
||||||
S: Sterling Heights, Michigan 48313
|
S: Sterling Heights, Michigan 48313
|
||||||
S: USA
|
S: USA
|
||||||
|
|
||||||
|
N: Wolfgang Grandegger
|
||||||
|
E: wg@grandegger.com
|
||||||
|
D: Controller Area Network (device drivers)
|
||||||
|
|
||||||
N: William Greathouse
|
N: William Greathouse
|
||||||
E: wgreathouse@smva.com
|
E: wgreathouse@smva.com
|
||||||
E: wgreathouse@myfavoritei.com
|
E: wgreathouse@myfavoritei.com
|
||||||
|
|
|
@ -145,7 +145,6 @@ usage should require reading the full document.
|
||||||
interface in STA mode at first!
|
interface in STA mode at first!
|
||||||
</para>
|
</para>
|
||||||
!Finclude/net/mac80211.h ieee80211_if_init_conf
|
!Finclude/net/mac80211.h ieee80211_if_init_conf
|
||||||
!Finclude/net/mac80211.h ieee80211_if_conf
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
<chapter id="rx-tx">
|
<chapter id="rx-tx">
|
||||||
|
|
|
@ -438,6 +438,13 @@ Why: Superseded by tdfxfb. I2C/DDC support used to live in a separate
|
||||||
Who: Jean Delvare <khali@linux-fr.org>
|
Who: Jean Delvare <khali@linux-fr.org>
|
||||||
Krzysztof Helt <krzysztof.h1@wp.pl>
|
Krzysztof Helt <krzysztof.h1@wp.pl>
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
What: CONFIG_RFKILL_INPUT
|
||||||
|
When: 2.6.33
|
||||||
|
Why: Should be implemented in userspace, policy daemon.
|
||||||
|
Who: Johannes Berg <johannes@sipsolutions.net>
|
||||||
|
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
What: CONFIG_X86_OLD_MCE
|
What: CONFIG_X86_OLD_MCE
|
||||||
|
|
|
@ -22,16 +22,11 @@ README.gigaset
|
||||||
- info on the drivers for Siemens Gigaset ISDN adapters.
|
- info on the drivers for Siemens Gigaset ISDN adapters.
|
||||||
README.icn
|
README.icn
|
||||||
- info on the ICN-ISDN-card and its driver.
|
- info on the ICN-ISDN-card and its driver.
|
||||||
|
>>>>>>> 93af7aca44f0e82e67bda10a0fb73d383edcc8bd:Documentation/isdn/00-INDEX
|
||||||
README.HiSax
|
README.HiSax
|
||||||
- info on the HiSax driver which replaces the old teles.
|
- info on the HiSax driver which replaces the old teles.
|
||||||
README.hfc-pci
|
README.audio
|
||||||
- info on hfc-pci based cards.
|
- info for running audio over ISDN.
|
||||||
README.pcbit
|
|
||||||
- info on the PCBIT-D ISDN adapter and driver.
|
|
||||||
README.syncppp
|
|
||||||
- info on running Sync PPP over ISDN.
|
|
||||||
syncPPP.FAQ
|
|
||||||
- frequently asked questions about running PPP over ISDN.
|
|
||||||
README.avmb1
|
README.avmb1
|
||||||
- info on driver for AVM-B1 ISDN card.
|
- info on driver for AVM-B1 ISDN card.
|
||||||
README.act2000
|
README.act2000
|
||||||
|
@ -42,10 +37,28 @@ README.concap
|
||||||
- info on "CONCAP" encapsulation protocol interface used for X.25.
|
- info on "CONCAP" encapsulation protocol interface used for X.25.
|
||||||
README.diversion
|
README.diversion
|
||||||
- info on module for isdn diversion services.
|
- info on module for isdn diversion services.
|
||||||
|
README.fax
|
||||||
|
- info for using Fax over ISDN.
|
||||||
|
README.gigaset
|
||||||
|
- info on the drivers for Siemens Gigaset ISDN adapters
|
||||||
|
README.hfc-pci
|
||||||
|
- info on hfc-pci based cards.
|
||||||
|
README.hysdn
|
||||||
|
- info on driver for Hypercope active HYSDN cards
|
||||||
|
README.icn
|
||||||
|
- info on the ICN-ISDN-card and its driver.
|
||||||
|
README.mISDN
|
||||||
|
- info on the Modular ISDN subsystem (mISDN)
|
||||||
|
README.pcbit
|
||||||
|
- info on the PCBIT-D ISDN adapter and driver.
|
||||||
README.sc
|
README.sc
|
||||||
- info on driver for Spellcaster cards.
|
- info on driver for Spellcaster cards.
|
||||||
|
README.syncppp
|
||||||
|
- info on running Sync PPP over ISDN.
|
||||||
README.x25
|
README.x25
|
||||||
- info for running X.25 over ISDN.
|
- info for running X.25 over ISDN.
|
||||||
|
syncPPP.FAQ
|
||||||
|
- frequently asked questions about running PPP over ISDN.
|
||||||
README.hysdn
|
README.hysdn
|
||||||
- info on driver for Hypercope active HYSDN cards
|
- info on driver for Hypercope active HYSDN cards
|
||||||
README.mISDN
|
README.mISDN
|
||||||
|
|
|
@ -45,7 +45,7 @@ From then on, Kernel CAPI may call the registered callback functions for the
|
||||||
device.
|
device.
|
||||||
|
|
||||||
If the device becomes unusable for any reason (shutdown, disconnect ...), the
|
If the device becomes unusable for any reason (shutdown, disconnect ...), the
|
||||||
driver has to call capi_ctr_reseted(). This will prevent further calls to the
|
driver has to call capi_ctr_down(). This will prevent further calls to the
|
||||||
callback functions by Kernel CAPI.
|
callback functions by Kernel CAPI.
|
||||||
|
|
||||||
|
|
||||||
|
@ -114,20 +114,36 @@ char *driver_name
|
||||||
int (*load_firmware)(struct capi_ctr *ctrlr, capiloaddata *ldata)
|
int (*load_firmware)(struct capi_ctr *ctrlr, capiloaddata *ldata)
|
||||||
(optional) pointer to a callback function for sending firmware and
|
(optional) pointer to a callback function for sending firmware and
|
||||||
configuration data to the device
|
configuration data to the device
|
||||||
|
Return value: 0 on success, error code on error
|
||||||
|
Called in process context.
|
||||||
|
|
||||||
void (*reset_ctr)(struct capi_ctr *ctrlr)
|
void (*reset_ctr)(struct capi_ctr *ctrlr)
|
||||||
pointer to a callback function for performing a reset on the device,
|
(optional) pointer to a callback function for performing a reset on
|
||||||
releasing all registered applications
|
the device, releasing all registered applications
|
||||||
|
Called in process context.
|
||||||
|
|
||||||
void (*register_appl)(struct capi_ctr *ctrlr, u16 applid,
|
void (*register_appl)(struct capi_ctr *ctrlr, u16 applid,
|
||||||
capi_register_params *rparam)
|
capi_register_params *rparam)
|
||||||
void (*release_appl)(struct capi_ctr *ctrlr, u16 applid)
|
void (*release_appl)(struct capi_ctr *ctrlr, u16 applid)
|
||||||
pointers to callback functions for registration and deregistration of
|
pointers to callback functions for registration and deregistration of
|
||||||
applications with the device
|
applications with the device
|
||||||
|
Calls to these functions are serialized by Kernel CAPI so that only
|
||||||
|
one call to any of them is active at any time.
|
||||||
|
|
||||||
u16 (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb)
|
u16 (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb)
|
||||||
pointer to a callback function for sending a CAPI message to the
|
pointer to a callback function for sending a CAPI message to the
|
||||||
device
|
device
|
||||||
|
Return value: CAPI error code
|
||||||
|
If the method returns 0 (CAPI_NOERROR) the driver has taken ownership
|
||||||
|
of the skb and the caller may no longer access it. If it returns a
|
||||||
|
non-zero (error) value then ownership of the skb returns to the caller
|
||||||
|
who may reuse or free it.
|
||||||
|
The return value should only be used to signal problems with respect
|
||||||
|
to accepting or queueing the message. Errors occurring during the
|
||||||
|
actual processing of the message should be signaled with an
|
||||||
|
appropriate reply message.
|
||||||
|
Calls to this function are not serialized by Kernel CAPI, ie. it must
|
||||||
|
be prepared to be re-entered.
|
||||||
|
|
||||||
char *(*procinfo)(struct capi_ctr *ctrlr)
|
char *(*procinfo)(struct capi_ctr *ctrlr)
|
||||||
pointer to a callback function returning the entry for the device in
|
pointer to a callback function returning the entry for the device in
|
||||||
|
@ -138,6 +154,8 @@ read_proc_t *ctr_read_proc
|
||||||
system entry, /proc/capi/controllers/<n>; will be called with a
|
system entry, /proc/capi/controllers/<n>; will be called with a
|
||||||
pointer to the device's capi_ctr structure as the last (data) argument
|
pointer to the device's capi_ctr structure as the last (data) argument
|
||||||
|
|
||||||
|
Note: Callback functions are never called in interrupt context.
|
||||||
|
|
||||||
- to be filled in before calling capi_ctr_ready():
|
- to be filled in before calling capi_ctr_ready():
|
||||||
|
|
||||||
u8 manu[CAPI_MANUFACTURER_LEN]
|
u8 manu[CAPI_MANUFACTURER_LEN]
|
||||||
|
@ -153,6 +171,45 @@ u8 serial[CAPI_SERIAL_LEN]
|
||||||
value to return for CAPI_GET_SERIAL
|
value to return for CAPI_GET_SERIAL
|
||||||
|
|
||||||
|
|
||||||
|
4.3 The _cmsg Structure
|
||||||
|
|
||||||
|
(declared in <linux/isdn/capiutil.h>)
|
||||||
|
|
||||||
|
The _cmsg structure stores the contents of a CAPI 2.0 message in an easily
|
||||||
|
accessible form. It contains members for all possible CAPI 2.0 parameters, of
|
||||||
|
which only those appearing in the message type currently being processed are
|
||||||
|
actually used. Unused members should be set to zero.
|
||||||
|
|
||||||
|
Members are named after the CAPI 2.0 standard names of the parameters they
|
||||||
|
represent. See <linux/isdn/capiutil.h> for the exact spelling. Member data
|
||||||
|
types are:
|
||||||
|
|
||||||
|
u8 for CAPI parameters of type 'byte'
|
||||||
|
|
||||||
|
u16 for CAPI parameters of type 'word'
|
||||||
|
|
||||||
|
u32 for CAPI parameters of type 'dword'
|
||||||
|
|
||||||
|
_cstruct for CAPI parameters of type 'struct' not containing any
|
||||||
|
variably-sized (struct) subparameters (eg. 'Called Party Number')
|
||||||
|
The member is a pointer to a buffer containing the parameter in
|
||||||
|
CAPI encoding (length + content). It may also be NULL, which will
|
||||||
|
be taken to represent an empty (zero length) parameter.
|
||||||
|
|
||||||
|
_cmstruct for CAPI parameters of type 'struct' containing 'struct'
|
||||||
|
subparameters ('Additional Info' and 'B Protocol')
|
||||||
|
The representation is a single byte containing one of the values:
|
||||||
|
CAPI_DEFAULT: the parameter is empty
|
||||||
|
CAPI_COMPOSE: the values of the subparameters are stored
|
||||||
|
individually in the corresponding _cmsg structure members
|
||||||
|
|
||||||
|
Functions capi_cmsg2message() and capi_message2cmsg() are provided to convert
|
||||||
|
messages between their transport encoding described in the CAPI 2.0 standard
|
||||||
|
and their _cmsg structure representation. Note that capi_cmsg2message() does
|
||||||
|
not know or check the size of its destination buffer. The caller must make
|
||||||
|
sure it is big enough to accomodate the resulting CAPI message.
|
||||||
|
|
||||||
|
|
||||||
5. Lower Layer Interface Functions
|
5. Lower Layer Interface Functions
|
||||||
|
|
||||||
(declared in <linux/isdn/capilli.h>)
|
(declared in <linux/isdn/capilli.h>)
|
||||||
|
@ -166,7 +223,7 @@ int detach_capi_ctr(struct capi_ctr *ctrlr)
|
||||||
register/unregister a device (controller) with Kernel CAPI
|
register/unregister a device (controller) with Kernel CAPI
|
||||||
|
|
||||||
void capi_ctr_ready(struct capi_ctr *ctrlr)
|
void capi_ctr_ready(struct capi_ctr *ctrlr)
|
||||||
void capi_ctr_reseted(struct capi_ctr *ctrlr)
|
void capi_ctr_down(struct capi_ctr *ctrlr)
|
||||||
signal controller ready/not ready
|
signal controller ready/not ready
|
||||||
|
|
||||||
void capi_ctr_suspend_output(struct capi_ctr *ctrlr)
|
void capi_ctr_suspend_output(struct capi_ctr *ctrlr)
|
||||||
|
@ -211,3 +268,32 @@ CAPIMSG_CONTROL(m) CAPIMSG_SETCONTROL(m, contr) Controller/PLCI/NCCI
|
||||||
(u32)
|
(u32)
|
||||||
CAPIMSG_DATALEN(m) CAPIMSG_SETDATALEN(m, len) Data Length (u16)
|
CAPIMSG_DATALEN(m) CAPIMSG_SETDATALEN(m, len) Data Length (u16)
|
||||||
|
|
||||||
|
|
||||||
|
Library functions for working with _cmsg structures
|
||||||
|
(from <linux/isdn/capiutil.h>):
|
||||||
|
|
||||||
|
unsigned capi_cmsg2message(_cmsg *cmsg, u8 *msg)
|
||||||
|
Assembles a CAPI 2.0 message from the parameters in *cmsg, storing the
|
||||||
|
result in *msg.
|
||||||
|
|
||||||
|
unsigned capi_message2cmsg(_cmsg *cmsg, u8 *msg)
|
||||||
|
Disassembles the CAPI 2.0 message in *msg, storing the parameters in
|
||||||
|
*cmsg.
|
||||||
|
|
||||||
|
unsigned capi_cmsg_header(_cmsg *cmsg, u16 ApplId, u8 Command, u8 Subcommand,
|
||||||
|
u16 Messagenumber, u32 Controller)
|
||||||
|
Fills the header part and address field of the _cmsg structure *cmsg
|
||||||
|
with the given values, zeroing the remainder of the structure so only
|
||||||
|
parameters with non-default values need to be changed before sending
|
||||||
|
the message.
|
||||||
|
|
||||||
|
void capi_cmsg_answer(_cmsg *cmsg)
|
||||||
|
Sets the low bit of the Subcommand field in *cmsg, thereby converting
|
||||||
|
_REQ to _CONF and _IND to _RESP.
|
||||||
|
|
||||||
|
char *capi_cmd2str(u8 Command, u8 Subcommand)
|
||||||
|
Returns the CAPI 2.0 message name corresponding to the given command
|
||||||
|
and subcommand values, as a static ASCII string. The return value may
|
||||||
|
be NULL if the command/subcommand is not one of those defined in the
|
||||||
|
CAPI 2.0 standard.
|
||||||
|
|
||||||
|
|
|
@ -149,10 +149,8 @@ GigaSet 307x Device Driver
|
||||||
configuration files and chat scripts in the gigaset-VERSION/ppp directory
|
configuration files and chat scripts in the gigaset-VERSION/ppp directory
|
||||||
in the driver packages from http://sourceforge.net/projects/gigaset307x/.
|
in the driver packages from http://sourceforge.net/projects/gigaset307x/.
|
||||||
Please note that the USB drivers are not able to change the state of the
|
Please note that the USB drivers are not able to change the state of the
|
||||||
control lines (the M105 driver can be configured to use some undocumented
|
control lines. This means you must use "Stupid Mode" if you are using
|
||||||
control requests, if you really need the control lines, though). This means
|
wvdial or you should use the nocrtscts option of pppd.
|
||||||
you must use "Stupid Mode" if you are using wvdial or you should use the
|
|
||||||
nocrtscts option of pppd.
|
|
||||||
You must also assure that the ppp_async module is loaded with the parameter
|
You must also assure that the ppp_async module is loaded with the parameter
|
||||||
flag_time=0. You can do this e.g. by adding a line like
|
flag_time=0. You can do this e.g. by adding a line like
|
||||||
|
|
||||||
|
@ -190,20 +188,19 @@ GigaSet 307x Device Driver
|
||||||
You can also use /sys/class/tty/ttyGxy/cidmode for changing the CID mode
|
You can also use /sys/class/tty/ttyGxy/cidmode for changing the CID mode
|
||||||
setting (ttyGxy is ttyGU0 or ttyGB0).
|
setting (ttyGxy is ttyGU0 or ttyGB0).
|
||||||
|
|
||||||
2.6. M105 Undocumented USB Requests
|
2.6. Unregistered Wireless Devices (M101/M105)
|
||||||
------------------------------
|
-----------------------------------------
|
||||||
|
The main purpose of the ser_gigaset and usb_gigaset drivers is to allow
|
||||||
The Gigaset M105 USB data box understands a couple of useful, but
|
the M101 and M105 wireless devices to be used as ISDN devices for ISDN
|
||||||
undocumented USB commands. These requests are not used in normal
|
connections through a Gigaset base. Therefore they assume that the device
|
||||||
operation (for wireless access to the base), but are needed for access
|
is registered to a DECT base.
|
||||||
to the M105's own configuration mode (registration to the base, baudrate
|
|
||||||
and line format settings, device status queries) via the gigacontr
|
|
||||||
utility. Their use is controlled by the kernel configuration option
|
|
||||||
"Support for undocumented USB requests" (CONFIG_GIGASET_UNDOCREQ). If you
|
|
||||||
encounter error code -ENOTTY when trying to use some features of the
|
|
||||||
M105, try setting that option to "y" via 'make {x,menu}config' and
|
|
||||||
recompiling the driver.
|
|
||||||
|
|
||||||
|
If the M101/M105 device is not registered to a base, initialization of
|
||||||
|
the device fails, and a corresponding error message is logged by the
|
||||||
|
driver. In that situation, a restricted set of functions is available
|
||||||
|
which includes, in particular, those necessary for registering the device
|
||||||
|
to a base or for switching it between Fixed Part and Portable Part
|
||||||
|
modes.
|
||||||
|
|
||||||
3. Troubleshooting
|
3. Troubleshooting
|
||||||
---------------
|
---------------
|
||||||
|
@ -234,11 +231,12 @@ GigaSet 307x Device Driver
|
||||||
Select Unimodem mode for all DECT data adapters. (see section 2.4.)
|
Select Unimodem mode for all DECT data adapters. (see section 2.4.)
|
||||||
|
|
||||||
Problem:
|
Problem:
|
||||||
You want to configure your USB DECT data adapter (M105) but gigacontr
|
Messages like this:
|
||||||
reports an error: "/dev/ttyGU0: Inappropriate ioctl for device".
|
usb_gigaset 3-2:1.0: Could not initialize the device.
|
||||||
|
appear in your syslog.
|
||||||
Solution:
|
Solution:
|
||||||
Recompile the usb_gigaset driver with the kernel configuration option
|
Check whether your M10x wireless device is correctly registered to the
|
||||||
CONFIG_GIGASET_UNDOCREQ set to 'y'. (see section 2.6.)
|
Gigaset base. (see section 2.6.)
|
||||||
|
|
||||||
3.2. Telling the driver to provide more information
|
3.2. Telling the driver to provide more information
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
|
|
@ -36,10 +36,15 @@ This file contains
|
||||||
6.2 local loopback of sent frames
|
6.2 local loopback of sent frames
|
||||||
6.3 CAN controller hardware filters
|
6.3 CAN controller hardware filters
|
||||||
6.4 The virtual CAN driver (vcan)
|
6.4 The virtual CAN driver (vcan)
|
||||||
6.5 currently supported CAN hardware
|
6.5 The CAN network device driver interface
|
||||||
6.6 todo
|
6.5.1 Netlink interface to set/get devices properties
|
||||||
|
6.5.2 Setting the CAN bit-timing
|
||||||
|
6.5.3 Starting and stopping the CAN network device
|
||||||
|
6.6 supported CAN hardware
|
||||||
|
|
||||||
7 Credits
|
7 Socket CAN resources
|
||||||
|
|
||||||
|
8 Credits
|
||||||
|
|
||||||
============================================================================
|
============================================================================
|
||||||
|
|
||||||
|
@ -234,6 +239,8 @@ solution for a couple of reasons:
|
||||||
the user application using the common CAN filter mechanisms. Inside
|
the user application using the common CAN filter mechanisms. Inside
|
||||||
this filter definition the (interested) type of errors may be
|
this filter definition the (interested) type of errors may be
|
||||||
selected. The reception of error frames is disabled by default.
|
selected. The reception of error frames is disabled by default.
|
||||||
|
The format of the CAN error frame is briefly decribed in the Linux
|
||||||
|
header file "include/linux/can/error.h".
|
||||||
|
|
||||||
4. How to use Socket CAN
|
4. How to use Socket CAN
|
||||||
------------------------
|
------------------------
|
||||||
|
@ -605,61 +612,213 @@ solution for a couple of reasons:
|
||||||
removal of vcan network devices can be managed with the ip(8) tool:
|
removal of vcan network devices can be managed with the ip(8) tool:
|
||||||
|
|
||||||
- Create a virtual CAN network interface:
|
- Create a virtual CAN network interface:
|
||||||
ip link add type vcan
|
$ ip link add type vcan
|
||||||
|
|
||||||
- Create a virtual CAN network interface with a specific name 'vcan42':
|
- Create a virtual CAN network interface with a specific name 'vcan42':
|
||||||
ip link add dev vcan42 type vcan
|
$ ip link add dev vcan42 type vcan
|
||||||
|
|
||||||
- Remove a (virtual CAN) network interface 'vcan42':
|
- Remove a (virtual CAN) network interface 'vcan42':
|
||||||
ip link del vcan42
|
$ ip link del vcan42
|
||||||
|
|
||||||
The tool 'vcan' from the SocketCAN SVN repository on BerliOS is obsolete.
|
6.5 The CAN network device driver interface
|
||||||
|
|
||||||
Virtual CAN network device creation in older Kernels:
|
The CAN network device driver interface provides a generic interface
|
||||||
In Linux Kernel versions < 2.6.24 the vcan driver creates 4 vcan
|
to setup, configure and monitor CAN network devices. The user can then
|
||||||
netdevices at module load time by default. This value can be changed
|
configure the CAN device, like setting the bit-timing parameters, via
|
||||||
with the module parameter 'numdev'. E.g. 'modprobe vcan numdev=8'
|
the netlink interface using the program "ip" from the "IPROUTE2"
|
||||||
|
utility suite. The following chapter describes briefly how to use it.
|
||||||
|
Furthermore, the interface uses a common data structure and exports a
|
||||||
|
set of common functions, which all real CAN network device drivers
|
||||||
|
should use. Please have a look to the SJA1000 or MSCAN driver to
|
||||||
|
understand how to use them. The name of the module is can-dev.ko.
|
||||||
|
|
||||||
6.5 currently supported CAN hardware
|
6.5.1 Netlink interface to set/get devices properties
|
||||||
|
|
||||||
On the project website http://developer.berlios.de/projects/socketcan
|
The CAN device must be configured via netlink interface. The supported
|
||||||
there are different drivers available:
|
netlink message types are defined and briefly described in
|
||||||
|
"include/linux/can/netlink.h". CAN link support for the program "ip"
|
||||||
|
of the IPROUTE2 utility suite is avaiable and it can be used as shown
|
||||||
|
below:
|
||||||
|
|
||||||
vcan: Virtual CAN interface driver (if no real hardware is available)
|
- Setting CAN device properties:
|
||||||
sja1000: Philips SJA1000 CAN controller (recommended)
|
|
||||||
i82527: Intel i82527 CAN controller
|
|
||||||
mscan: Motorola/Freescale CAN controller (e.g. inside SOC MPC5200)
|
|
||||||
ccan: CCAN controller core (e.g. inside SOC h7202)
|
|
||||||
slcan: For a bunch of CAN adaptors that are attached via a
|
|
||||||
serial line ASCII protocol (for serial / USB adaptors)
|
|
||||||
|
|
||||||
Additionally the different CAN adaptors (ISA/PCI/PCMCIA/USB/Parport)
|
$ ip link set can0 type can help
|
||||||
from PEAK Systemtechnik support the CAN netdevice driver model
|
Usage: ip link set DEVICE type can
|
||||||
since Linux driver v6.0: http://www.peak-system.com/linux/index.htm
|
[ bitrate BITRATE [ sample-point SAMPLE-POINT] ] |
|
||||||
|
[ tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1
|
||||||
|
phase-seg2 PHASE-SEG2 [ sjw SJW ] ]
|
||||||
|
|
||||||
Please check the Mailing Lists on the berlios OSS project website.
|
[ loopback { on | off } ]
|
||||||
|
[ listen-only { on | off } ]
|
||||||
|
[ triple-sampling { on | off } ]
|
||||||
|
|
||||||
6.6 todo
|
[ restart-ms TIME-MS ]
|
||||||
|
[ restart ]
|
||||||
|
|
||||||
The configuration interface for CAN network drivers is still an open
|
Where: BITRATE := { 1..1000000 }
|
||||||
issue that has not been finalized in the socketcan project. Also the
|
SAMPLE-POINT := { 0.000..0.999 }
|
||||||
idea of having a library module (candev.ko) that holds functions
|
TQ := { NUMBER }
|
||||||
that are needed by all CAN netdevices is not ready to ship.
|
PROP-SEG := { 1..8 }
|
||||||
Your contribution is welcome.
|
PHASE-SEG1 := { 1..8 }
|
||||||
|
PHASE-SEG2 := { 1..8 }
|
||||||
|
SJW := { 1..4 }
|
||||||
|
RESTART-MS := { 0 | NUMBER }
|
||||||
|
|
||||||
7. Credits
|
- Display CAN device details and statistics:
|
||||||
|
|
||||||
|
$ ip -details -statistics link show can0
|
||||||
|
2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP qlen 10
|
||||||
|
link/can
|
||||||
|
can <TRIPLE-SAMPLING> state ERROR-ACTIVE restart-ms 100
|
||||||
|
bitrate 125000 sample_point 0.875
|
||||||
|
tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
|
||||||
|
sja1000: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
|
||||||
|
clock 8000000
|
||||||
|
re-started bus-errors arbit-lost error-warn error-pass bus-off
|
||||||
|
41 17457 0 41 42 41
|
||||||
|
RX: bytes packets errors dropped overrun mcast
|
||||||
|
140859 17608 17457 0 0 0
|
||||||
|
TX: bytes packets errors dropped carrier collsns
|
||||||
|
861 112 0 41 0 0
|
||||||
|
|
||||||
|
More info to the above output:
|
||||||
|
|
||||||
|
"<TRIPLE-SAMPLING>"
|
||||||
|
Shows the list of selected CAN controller modes: LOOPBACK,
|
||||||
|
LISTEN-ONLY, or TRIPLE-SAMPLING.
|
||||||
|
|
||||||
|
"state ERROR-ACTIVE"
|
||||||
|
The current state of the CAN controller: "ERROR-ACTIVE",
|
||||||
|
"ERROR-WARNING", "ERROR-PASSIVE", "BUS-OFF" or "STOPPED"
|
||||||
|
|
||||||
|
"restart-ms 100"
|
||||||
|
Automatic restart delay time. If set to a non-zero value, a
|
||||||
|
restart of the CAN controller will be triggered automatically
|
||||||
|
in case of a bus-off condition after the specified delay time
|
||||||
|
in milliseconds. By default it's off.
|
||||||
|
|
||||||
|
"bitrate 125000 sample_point 0.875"
|
||||||
|
Shows the real bit-rate in bits/sec and the sample-point in the
|
||||||
|
range 0.000..0.999. If the calculation of bit-timing parameters
|
||||||
|
is enabled in the kernel (CONFIG_CAN_CALC_BITTIMING=y), the
|
||||||
|
bit-timing can be defined by setting the "bitrate" argument.
|
||||||
|
Optionally the "sample-point" can be specified. By default it's
|
||||||
|
0.000 assuming CIA-recommended sample-points.
|
||||||
|
|
||||||
|
"tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1"
|
||||||
|
Shows the time quanta in ns, propagation segment, phase buffer
|
||||||
|
segment 1 and 2 and the synchronisation jump width in units of
|
||||||
|
tq. They allow to define the CAN bit-timing in a hardware
|
||||||
|
independent format as proposed by the Bosch CAN 2.0 spec (see
|
||||||
|
chapter 8 of http://www.semiconductors.bosch.de/pdf/can2spec.pdf).
|
||||||
|
|
||||||
|
"sja1000: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
|
||||||
|
clock 8000000"
|
||||||
|
Shows the bit-timing constants of the CAN controller, here the
|
||||||
|
"sja1000". The minimum and maximum values of the time segment 1
|
||||||
|
and 2, the synchronisation jump width in units of tq, the
|
||||||
|
bitrate pre-scaler and the CAN system clock frequency in Hz.
|
||||||
|
These constants could be used for user-defined (non-standard)
|
||||||
|
bit-timing calculation algorithms in user-space.
|
||||||
|
|
||||||
|
"re-started bus-errors arbit-lost error-warn error-pass bus-off"
|
||||||
|
Shows the number of restarts, bus and arbitration lost errors,
|
||||||
|
and the state changes to the error-warning, error-passive and
|
||||||
|
bus-off state. RX overrun errors are listed in the "overrun"
|
||||||
|
field of the standard network statistics.
|
||||||
|
|
||||||
|
6.5.2 Setting the CAN bit-timing
|
||||||
|
|
||||||
|
The CAN bit-timing parameters can always be defined in a hardware
|
||||||
|
independent format as proposed in the Bosch CAN 2.0 specification
|
||||||
|
specifying the arguments "tq", "prop_seg", "phase_seg1", "phase_seg2"
|
||||||
|
and "sjw":
|
||||||
|
|
||||||
|
$ ip link set canX type can tq 125 prop-seg 6 \
|
||||||
|
phase-seg1 7 phase-seg2 2 sjw 1
|
||||||
|
|
||||||
|
If the kernel option CONFIG_CAN_CALC_BITTIMING is enabled, CIA
|
||||||
|
recommended CAN bit-timing parameters will be calculated if the bit-
|
||||||
|
rate is specified with the argument "bitrate":
|
||||||
|
|
||||||
|
$ ip link set canX type can bitrate 125000
|
||||||
|
|
||||||
|
Note that this works fine for the most common CAN controllers with
|
||||||
|
standard bit-rates but may *fail* for exotic bit-rates or CAN system
|
||||||
|
clock frequencies. Disabling CONFIG_CAN_CALC_BITTIMING saves some
|
||||||
|
space and allows user-space tools to solely determine and set the
|
||||||
|
bit-timing parameters. The CAN controller specific bit-timing
|
||||||
|
constants can be used for that purpose. They are listed by the
|
||||||
|
following command:
|
||||||
|
|
||||||
|
$ ip -details link show can0
|
||||||
|
...
|
||||||
|
sja1000: clock 8000000 tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
|
||||||
|
|
||||||
|
6.5.3 Starting and stopping the CAN network device
|
||||||
|
|
||||||
|
A CAN network device is started or stopped as usual with the command
|
||||||
|
"ifconfig canX up/down" or "ip link set canX up/down". Be aware that
|
||||||
|
you *must* define proper bit-timing parameters for real CAN devices
|
||||||
|
before you can start it to avoid error-prone default settings:
|
||||||
|
|
||||||
|
$ ip link set canX up type can bitrate 125000
|
||||||
|
|
||||||
|
A device may enter the "bus-off" state if too much errors occurred on
|
||||||
|
the CAN bus. Then no more messages are received or sent. An automatic
|
||||||
|
bus-off recovery can be enabled by setting the "restart-ms" to a
|
||||||
|
non-zero value, e.g.:
|
||||||
|
|
||||||
|
$ ip link set canX type can restart-ms 100
|
||||||
|
|
||||||
|
Alternatively, the application may realize the "bus-off" condition
|
||||||
|
by monitoring CAN error frames and do a restart when appropriate with
|
||||||
|
the command:
|
||||||
|
|
||||||
|
$ ip link set canX type can restart
|
||||||
|
|
||||||
|
Note that a restart will also create a CAN error frame (see also
|
||||||
|
chapter 3.4).
|
||||||
|
|
||||||
|
6.6 Supported CAN hardware
|
||||||
|
|
||||||
|
Please check the "Kconfig" file in "drivers/net/can" to get an actual
|
||||||
|
list of the support CAN hardware. On the Socket CAN project website
|
||||||
|
(see chapter 7) there might be further drivers available, also for
|
||||||
|
older kernel versions.
|
||||||
|
|
||||||
|
7. Socket CAN resources
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
You can find further resources for Socket CAN like user space tools,
|
||||||
|
support for old kernel versions, more drivers, mailing lists, etc.
|
||||||
|
at the BerliOS OSS project website for Socket CAN:
|
||||||
|
|
||||||
|
http://developer.berlios.de/projects/socketcan
|
||||||
|
|
||||||
|
If you have questions, bug fixes, etc., don't hesitate to post them to
|
||||||
|
the Socketcan-Users mailing list. But please search the archives first.
|
||||||
|
|
||||||
|
8. Credits
|
||||||
----------
|
----------
|
||||||
|
|
||||||
Oliver Hartkopp (PF_CAN core, filters, drivers, bcm)
|
Oliver Hartkopp (PF_CAN core, filters, drivers, bcm, SJA1000 driver)
|
||||||
Urs Thuermann (PF_CAN core, kernel integration, socket interfaces, raw, vcan)
|
Urs Thuermann (PF_CAN core, kernel integration, socket interfaces, raw, vcan)
|
||||||
Jan Kizka (RT-SocketCAN core, Socket-API reconciliation)
|
Jan Kizka (RT-SocketCAN core, Socket-API reconciliation)
|
||||||
Wolfgang Grandegger (RT-SocketCAN core & drivers, Raw Socket-API reviews)
|
Wolfgang Grandegger (RT-SocketCAN core & drivers, Raw Socket-API reviews,
|
||||||
|
CAN device driver interface, MSCAN driver)
|
||||||
Robert Schwebel (design reviews, PTXdist integration)
|
Robert Schwebel (design reviews, PTXdist integration)
|
||||||
Marc Kleine-Budde (design reviews, Kernel 2.6 cleanups, drivers)
|
Marc Kleine-Budde (design reviews, Kernel 2.6 cleanups, drivers)
|
||||||
Benedikt Spranger (reviews)
|
Benedikt Spranger (reviews)
|
||||||
Thomas Gleixner (LKML reviews, coding style, posting hints)
|
Thomas Gleixner (LKML reviews, coding style, posting hints)
|
||||||
Andrey Volkov (kernel subtree structure, ioctls, mscan driver)
|
Andrey Volkov (kernel subtree structure, ioctls, MSCAN driver)
|
||||||
Matthias Brukner (first SJA1000 CAN netdevice implementation Q2/2003)
|
Matthias Brukner (first SJA1000 CAN netdevice implementation Q2/2003)
|
||||||
Klaus Hitschler (PEAK driver integration)
|
Klaus Hitschler (PEAK driver integration)
|
||||||
Uwe Koppe (CAN netdevices with PF_PACKET approach)
|
Uwe Koppe (CAN netdevices with PF_PACKET approach)
|
||||||
Michael Schulze (driver layer loopback requirement, RT CAN drivers review)
|
Michael Schulze (driver layer loopback requirement, RT CAN drivers review)
|
||||||
|
Pavel Pisa (Bit-timing calculation)
|
||||||
|
Sascha Hauer (SJA1000 platform driver)
|
||||||
|
Sebastian Haas (SJA1000 EMS PCI driver)
|
||||||
|
Markus Plessing (SJA1000 EMS PCI driver)
|
||||||
|
Per Dalen (SJA1000 Kvaser PCI driver)
|
||||||
|
Sam Ravnborg (reviews, coding style, kbuild help)
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
|
||||||
|
Linux IEEE 802.15.4 implementation
|
||||||
|
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
============
|
||||||
|
|
||||||
|
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 protocols for organizing Low-Rate Wireless Personal Area Networks.
|
||||||
|
|
||||||
|
Currently only IEEE 802.15.4 layer is implemented. We have choosen
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
Socket API
|
||||||
|
==========
|
||||||
|
|
||||||
|
int sd = socket(PF_IEEE802154, SOCK_DGRAM, 0);
|
||||||
|
.....
|
||||||
|
|
||||||
|
The address family, socket addresses etc. are defined in the
|
||||||
|
include/net/ieee802154/af_ieee802154.h header or in the special header
|
||||||
|
in our userspace package (see either linux-zigbee sourceforge download page
|
||||||
|
or git tree at git://linux-zigbee.git.sourceforge.net/gitroot/linux-zigbee).
|
||||||
|
|
||||||
|
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/ieee802154/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
|
||||||
|
=============
|
||||||
|
|
||||||
|
Like with WiFi, there are several types of devices implementing IEEE 802.15.4.
|
||||||
|
1) 'HardMAC'. The MAC layer is implemented in the device itself, the device
|
||||||
|
exports MLME and data API.
|
||||||
|
2) 'SoftMAC' or just radio. These types of devices are just radio transceivers
|
||||||
|
possibly with some kinds of acceleration like automatic CRC computation and
|
||||||
|
comparation, automagic ACK handling, address matching, etc.
|
||||||
|
|
||||||
|
Those types of devices require different approach to be hooked into Linux kernel.
|
||||||
|
|
||||||
|
|
||||||
|
HardMAC
|
||||||
|
=======
|
||||||
|
|
||||||
|
See the header include/net/ieee802154/netdevice.h. You have to implement Linux
|
||||||
|
net_device, with .type = ARPHRD_IEEE802154. Data is exchanged with socket family
|
||||||
|
code via plain sk_buffs. The control block of sk_buffs will contain additional
|
||||||
|
info as described in the struct ieee802154_mac_cb.
|
||||||
|
|
||||||
|
To hook the MLME interface you have to populate the ml_priv field of your
|
||||||
|
net_device with a pointer to struct ieee802154_mlme_ops instance. All fields are
|
||||||
|
required.
|
||||||
|
|
||||||
|
We provide an example of simple HardMAC driver at drivers/ieee802154/fakehard.c
|
||||||
|
|
||||||
|
|
||||||
|
SoftMAC
|
||||||
|
=======
|
||||||
|
|
||||||
|
We are going to provide intermediate layer impelementing IEEE 802.15.4 MAC
|
||||||
|
in software. This is currently WIP.
|
||||||
|
|
||||||
|
See header include/net/ieee802154/mac802154.h and several drivers in
|
||||||
|
drivers/ieee802154/
|
|
@ -168,7 +168,16 @@ tcp_dsack - BOOLEAN
|
||||||
Allows TCP to send "duplicate" SACKs.
|
Allows TCP to send "duplicate" SACKs.
|
||||||
|
|
||||||
tcp_ecn - BOOLEAN
|
tcp_ecn - BOOLEAN
|
||||||
Enable Explicit Congestion Notification in TCP.
|
Enable Explicit Congestion Notification (ECN) in TCP. ECN is only
|
||||||
|
used when both ends of the TCP flow support it. It is useful to
|
||||||
|
avoid losses due to congestion (when the bottleneck router supports
|
||||||
|
ECN).
|
||||||
|
Possible values are:
|
||||||
|
0 disable ECN
|
||||||
|
1 ECN enabled
|
||||||
|
2 Only server-side ECN enabled. If the other end does
|
||||||
|
not support ECN, behavior is like with ECN disabled.
|
||||||
|
Default: 2
|
||||||
|
|
||||||
tcp_fack - BOOLEAN
|
tcp_fack - BOOLEAN
|
||||||
Enable FACK congestion avoidance and fast retransmission.
|
Enable FACK congestion avoidance and fast retransmission.
|
||||||
|
@ -1048,6 +1057,13 @@ disable_ipv6 - BOOLEAN
|
||||||
address.
|
address.
|
||||||
Default: FALSE (enable IPv6 operation)
|
Default: FALSE (enable IPv6 operation)
|
||||||
|
|
||||||
|
When this value is changed from 1 to 0 (IPv6 is being enabled),
|
||||||
|
it will dynamically create a link-local address on the given
|
||||||
|
interface and start Duplicate Address Detection, if necessary.
|
||||||
|
|
||||||
|
When this value is changed from 0 to 1 (IPv6 is being disabled),
|
||||||
|
it will dynamically delete all address on the given interface.
|
||||||
|
|
||||||
accept_dad - INTEGER
|
accept_dad - INTEGER
|
||||||
Whether to accept DAD (Duplicate Address Detection).
|
Whether to accept DAD (Duplicate Address Detection).
|
||||||
0: Disable DAD
|
0: Disable DAD
|
||||||
|
|
|
@ -33,3 +33,40 @@ disable
|
||||||
|
|
||||||
A reboot is required to enable IPv6.
|
A reboot is required to enable IPv6.
|
||||||
|
|
||||||
|
autoconf
|
||||||
|
|
||||||
|
Specifies whether to enable IPv6 address autoconfiguration
|
||||||
|
on all interfaces. This might be used when one does not wish
|
||||||
|
for addresses to be automatically generated from prefixes
|
||||||
|
received in Router Advertisements.
|
||||||
|
|
||||||
|
The possible values and their effects are:
|
||||||
|
|
||||||
|
0
|
||||||
|
IPv6 address autoconfiguration is disabled on all interfaces.
|
||||||
|
|
||||||
|
Only the IPv6 loopback address (::1) and link-local addresses
|
||||||
|
will be added to interfaces.
|
||||||
|
|
||||||
|
1
|
||||||
|
IPv6 address autoconfiguration is enabled on all interfaces.
|
||||||
|
|
||||||
|
This is the default value.
|
||||||
|
|
||||||
|
disable_ipv6
|
||||||
|
|
||||||
|
Specifies whether to disable IPv6 on all interfaces.
|
||||||
|
This might be used when no IPv6 addresses are desired.
|
||||||
|
|
||||||
|
The possible values and their effects are:
|
||||||
|
|
||||||
|
0
|
||||||
|
IPv6 is enabled on all interfaces.
|
||||||
|
|
||||||
|
This is the default value.
|
||||||
|
|
||||||
|
1
|
||||||
|
IPv6 is disabled on all interfaces.
|
||||||
|
|
||||||
|
No IPv6 addresses will be added to interfaces.
|
||||||
|
|
||||||
|
|
|
@ -12,38 +12,22 @@ following format:
|
||||||
The radiotap format is discussed in
|
The radiotap format is discussed in
|
||||||
./Documentation/networking/radiotap-headers.txt.
|
./Documentation/networking/radiotap-headers.txt.
|
||||||
|
|
||||||
Despite 13 radiotap argument types are currently defined, most only make sense
|
Despite many radiotap parameters being currently defined, most only make sense
|
||||||
to appear on received packets. The following information is parsed from the
|
to appear on received packets. The following information is parsed from the
|
||||||
radiotap headers and used to control injection:
|
radiotap headers and used to control injection:
|
||||||
|
|
||||||
* IEEE80211_RADIOTAP_RATE
|
|
||||||
|
|
||||||
rate in 500kbps units, automatic if invalid or not present
|
|
||||||
|
|
||||||
|
|
||||||
* IEEE80211_RADIOTAP_ANTENNA
|
|
||||||
|
|
||||||
antenna to use, automatic if not present
|
|
||||||
|
|
||||||
|
|
||||||
* IEEE80211_RADIOTAP_DBM_TX_POWER
|
|
||||||
|
|
||||||
transmit power in dBm, automatic if not present
|
|
||||||
|
|
||||||
|
|
||||||
* IEEE80211_RADIOTAP_FLAGS
|
* IEEE80211_RADIOTAP_FLAGS
|
||||||
|
|
||||||
IEEE80211_RADIOTAP_F_FCS: FCS will be removed and recalculated
|
IEEE80211_RADIOTAP_F_FCS: FCS will be removed and recalculated
|
||||||
IEEE80211_RADIOTAP_F_WEP: frame will be encrypted if key available
|
IEEE80211_RADIOTAP_F_WEP: frame will be encrypted if key available
|
||||||
IEEE80211_RADIOTAP_F_FRAG: frame will be fragmented if longer than the
|
IEEE80211_RADIOTAP_F_FRAG: frame will be fragmented if longer than the
|
||||||
current fragmentation threshold. Note that
|
current fragmentation threshold.
|
||||||
this flag is only reliable when software
|
|
||||||
fragmentation is enabled)
|
|
||||||
|
|
||||||
The injection code can also skip all other currently defined radiotap fields
|
The injection code can also skip all other currently defined radiotap fields
|
||||||
facilitating replay of captured radiotap headers directly.
|
facilitating replay of captured radiotap headers directly.
|
||||||
|
|
||||||
Here is an example valid radiotap header defining these three parameters
|
Here is an example valid radiotap header defining some parameters
|
||||||
|
|
||||||
0x00, 0x00, // <-- radiotap version
|
0x00, 0x00, // <-- radiotap version
|
||||||
0x0b, 0x00, // <- radiotap header length
|
0x0b, 0x00, // <- radiotap header length
|
||||||
|
@ -72,8 +56,8 @@ interface), along the following lines:
|
||||||
...
|
...
|
||||||
r = pcap_inject(ppcap, u8aSendBuffer, nLength);
|
r = pcap_inject(ppcap, u8aSendBuffer, nLength);
|
||||||
|
|
||||||
You can also find sources for a complete inject test applet here:
|
You can also find a link to a complete inject application here:
|
||||||
|
|
||||||
http://penumbra.warmcat.com/_twk/tiki-index.php?page=packetspammer
|
http://wireless.kernel.org/en/users/Documentation/packetspammer
|
||||||
|
|
||||||
Andy Green <andy@warmcat.com>
|
Andy Green <andy@warmcat.com>
|
||||||
|
|
|
@ -38,9 +38,6 @@ ifinfomsg::if_flags & IFF_LOWER_UP:
|
||||||
ifinfomsg::if_flags & IFF_DORMANT:
|
ifinfomsg::if_flags & IFF_DORMANT:
|
||||||
Driver has signaled netif_dormant_on()
|
Driver has signaled netif_dormant_on()
|
||||||
|
|
||||||
These interface flags can also be queried without netlink using the
|
|
||||||
SIOCGIFFLAGS ioctl.
|
|
||||||
|
|
||||||
TLV IFLA_OPERSTATE
|
TLV IFLA_OPERSTATE
|
||||||
|
|
||||||
contains RFC2863 state of the interface in numeric representation:
|
contains RFC2863 state of the interface in numeric representation:
|
||||||
|
|
|
@ -4,16 +4,18 @@
|
||||||
|
|
||||||
This file documents the CONFIG_PACKET_MMAP option available with the PACKET
|
This file documents the CONFIG_PACKET_MMAP option available with the PACKET
|
||||||
socket interface on 2.4 and 2.6 kernels. This type of sockets is used for
|
socket interface on 2.4 and 2.6 kernels. This type of sockets is used for
|
||||||
capture network traffic with utilities like tcpdump or any other that uses
|
capture network traffic with utilities like tcpdump or any other that needs
|
||||||
the libpcap library.
|
raw access to network interface.
|
||||||
|
|
||||||
You can find the latest version of this document at
|
|
||||||
|
|
||||||
|
You can find the latest version of this document at:
|
||||||
http://pusa.uv.es/~ulisses/packet_mmap/
|
http://pusa.uv.es/~ulisses/packet_mmap/
|
||||||
|
|
||||||
Please send me your comments to
|
Howto can be found at:
|
||||||
|
http://wiki.gnu-log.net (packet_mmap)
|
||||||
|
|
||||||
|
Please send your comments to
|
||||||
Ulisses Alonso Camaró <uaca@i.hate.spam.alumni.uv.es>
|
Ulisses Alonso Camaró <uaca@i.hate.spam.alumni.uv.es>
|
||||||
|
Johann Baudy <johann.baudy@gnu-log.net>
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
+ Why use PACKET_MMAP
|
+ Why use PACKET_MMAP
|
||||||
|
@ -25,19 +27,24 @@ to capture each packet, it requires two if you want to get packet's
|
||||||
timestamp (like libpcap always does).
|
timestamp (like libpcap always does).
|
||||||
|
|
||||||
In the other hand PACKET_MMAP is very efficient. PACKET_MMAP provides a size
|
In the other hand PACKET_MMAP is very efficient. PACKET_MMAP provides a size
|
||||||
configurable circular buffer mapped in user space. This way reading packets just
|
configurable circular buffer mapped in user space that can be used to either
|
||||||
needs to wait for them, most of the time there is no need to issue a single
|
send or receive packets. This way reading packets just needs to wait for them,
|
||||||
system call. By using a shared buffer between the kernel and the user
|
most of the time there is no need to issue a single system call. Concerning
|
||||||
also has the benefit of minimizing packet copies.
|
transmission, multiple packets can be sent through one system call to get the
|
||||||
|
highest bandwidth.
|
||||||
|
By using a shared buffer between the kernel and the user also has the benefit
|
||||||
|
of minimizing packet copies.
|
||||||
|
|
||||||
It's fine to use PACKET_MMAP to improve the performance of the capture process,
|
It's fine to use PACKET_MMAP to improve the performance of the capture and
|
||||||
but it isn't everything. At least, if you are capturing at high speeds (this
|
transmission process, but it isn't everything. At least, if you are capturing
|
||||||
is relative to the cpu speed), you should check if the device driver of your
|
at high speeds (this is relative to the cpu speed), you should check if the
|
||||||
network interface card supports some sort of interrupt load mitigation or
|
device driver of your network interface card supports some sort of interrupt
|
||||||
(even better) if it supports NAPI, also make sure it is enabled.
|
load mitigation or (even better) if it supports NAPI, also make sure it is
|
||||||
|
enabled. For transmission, check the MTU (Maximum Transmission Unit) used and
|
||||||
|
supported by devices of your network.
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
+ How to use CONFIG_PACKET_MMAP
|
+ How to use CONFIG_PACKET_MMAP to improve capture process
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
From the user standpoint, you should use the higher level libpcap library, which
|
From the user standpoint, you should use the higher level libpcap library, which
|
||||||
|
@ -57,7 +64,7 @@ the low level details or want to improve libpcap by including PACKET_MMAP
|
||||||
support.
|
support.
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
+ How to use CONFIG_PACKET_MMAP directly
|
+ How to use CONFIG_PACKET_MMAP directly to improve capture process
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
From the system calls stand point, the use of PACKET_MMAP involves
|
From the system calls stand point, the use of PACKET_MMAP involves
|
||||||
|
@ -66,6 +73,7 @@ the following process:
|
||||||
|
|
||||||
[setup] socket() -------> creation of the capture socket
|
[setup] socket() -------> creation of the capture socket
|
||||||
setsockopt() ---> allocation of the circular buffer (ring)
|
setsockopt() ---> allocation of the circular buffer (ring)
|
||||||
|
option: PACKET_RX_RING
|
||||||
mmap() ---------> mapping of the allocated buffer to the
|
mmap() ---------> mapping of the allocated buffer to the
|
||||||
user process
|
user process
|
||||||
|
|
||||||
|
@ -96,6 +104,65 @@ Next I will describe PACKET_MMAP settings and it's constraints,
|
||||||
also the mapping of the circular buffer in the user process and
|
also the mapping of the circular buffer in the user process and
|
||||||
the use of this buffer.
|
the use of this buffer.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
+ How to use CONFIG_PACKET_MMAP directly to improve transmission process
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
Transmission process is similar to capture as shown below.
|
||||||
|
|
||||||
|
[setup] socket() -------> creation of the transmission socket
|
||||||
|
setsockopt() ---> allocation of the circular buffer (ring)
|
||||||
|
option: PACKET_TX_RING
|
||||||
|
bind() ---------> bind transmission socket with a network interface
|
||||||
|
mmap() ---------> mapping of the allocated buffer to the
|
||||||
|
user process
|
||||||
|
|
||||||
|
[transmission] poll() ---------> wait for free packets (optional)
|
||||||
|
send() ---------> send all packets that are set as ready in
|
||||||
|
the ring
|
||||||
|
The flag MSG_DONTWAIT can be used to return
|
||||||
|
before end of transfer.
|
||||||
|
|
||||||
|
[shutdown] close() --------> destruction of the transmission socket and
|
||||||
|
deallocation of all associated resources.
|
||||||
|
|
||||||
|
Binding the socket to your network interface is mandatory (with zero copy) to
|
||||||
|
know the header size of frames used in the circular buffer.
|
||||||
|
|
||||||
|
As capture, each frame contains two parts:
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
| struct tpacket_hdr | Header. It contains the status of
|
||||||
|
| | of this frame
|
||||||
|
|--------------------|
|
||||||
|
| data buffer |
|
||||||
|
. . Data that will be sent over the network interface.
|
||||||
|
. .
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
bind() associates the socket to your network interface thanks to
|
||||||
|
sll_ifindex parameter of struct sockaddr_ll.
|
||||||
|
|
||||||
|
Initialization example:
|
||||||
|
|
||||||
|
struct sockaddr_ll my_addr;
|
||||||
|
struct ifreq s_ifr;
|
||||||
|
...
|
||||||
|
|
||||||
|
strncpy (s_ifr.ifr_name, "eth0", sizeof(s_ifr.ifr_name));
|
||||||
|
|
||||||
|
/* get interface index of eth0 */
|
||||||
|
ioctl(this->socket, SIOCGIFINDEX, &s_ifr);
|
||||||
|
|
||||||
|
/* fill sockaddr_ll struct to prepare binding */
|
||||||
|
my_addr.sll_family = AF_PACKET;
|
||||||
|
my_addr.sll_protocol = ETH_P_ALL;
|
||||||
|
my_addr.sll_ifindex = s_ifr.ifr_ifindex;
|
||||||
|
|
||||||
|
/* bind socket to eth0 */
|
||||||
|
bind(this->socket, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_ll));
|
||||||
|
|
||||||
|
A complete tutorial is available at: http://wiki.gnu-log.net/
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
+ PACKET_MMAP settings
|
+ PACKET_MMAP settings
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -103,7 +170,10 @@ the use of this buffer.
|
||||||
|
|
||||||
To setup PACKET_MMAP from user level code is done with a call like
|
To setup PACKET_MMAP from user level code is done with a call like
|
||||||
|
|
||||||
|
- Capture process
|
||||||
setsockopt(fd, SOL_PACKET, PACKET_RX_RING, (void *) &req, sizeof(req))
|
setsockopt(fd, SOL_PACKET, PACKET_RX_RING, (void *) &req, sizeof(req))
|
||||||
|
- Transmission process
|
||||||
|
setsockopt(fd, SOL_PACKET, PACKET_TX_RING, (void *) &req, sizeof(req))
|
||||||
|
|
||||||
The most significant argument in the previous call is the req parameter,
|
The most significant argument in the previous call is the req parameter,
|
||||||
this parameter must to have the following structure:
|
this parameter must to have the following structure:
|
||||||
|
@ -117,11 +187,11 @@ this parameter must to have the following structure:
|
||||||
};
|
};
|
||||||
|
|
||||||
This structure is defined in /usr/include/linux/if_packet.h and establishes a
|
This structure is defined in /usr/include/linux/if_packet.h and establishes a
|
||||||
circular buffer (ring) of unswappable memory mapped in the capture process.
|
circular buffer (ring) of unswappable memory.
|
||||||
Being mapped in the capture process allows reading the captured frames and
|
Being mapped in the capture process allows reading the captured frames and
|
||||||
related meta-information like timestamps without requiring a system call.
|
related meta-information like timestamps without requiring a system call.
|
||||||
|
|
||||||
Captured frames are grouped in blocks. Each block is a physically contiguous
|
Frames are grouped in blocks. Each block is a physically contiguous
|
||||||
region of memory and holds tp_block_size/tp_frame_size frames. The total number
|
region of memory and holds tp_block_size/tp_frame_size frames. The total number
|
||||||
of blocks is tp_block_nr. Note that tp_frame_nr is a redundant parameter because
|
of blocks is tp_block_nr. Note that tp_frame_nr is a redundant parameter because
|
||||||
|
|
||||||
|
@ -336,6 +406,7 @@ struct tpacket_hdr). If this field is 0 means that the frame is ready
|
||||||
to be used for the kernel, If not, there is a frame the user can read
|
to be used for the kernel, If not, there is a frame the user can read
|
||||||
and the following flags apply:
|
and the following flags apply:
|
||||||
|
|
||||||
|
+++ Capture process:
|
||||||
from include/linux/if_packet.h
|
from include/linux/if_packet.h
|
||||||
|
|
||||||
#define TP_STATUS_COPY 2
|
#define TP_STATUS_COPY 2
|
||||||
|
@ -391,6 +462,37 @@ packets are in the ring:
|
||||||
It doesn't incur in a race condition to first check the status value and
|
It doesn't incur in a race condition to first check the status value and
|
||||||
then poll for frames.
|
then poll for frames.
|
||||||
|
|
||||||
|
|
||||||
|
++ Transmission process
|
||||||
|
Those defines are also used for transmission:
|
||||||
|
|
||||||
|
#define TP_STATUS_AVAILABLE 0 // Frame is available
|
||||||
|
#define TP_STATUS_SEND_REQUEST 1 // Frame will be sent on next send()
|
||||||
|
#define TP_STATUS_SENDING 2 // Frame is currently in transmission
|
||||||
|
#define TP_STATUS_WRONG_FORMAT 4 // Frame format is not correct
|
||||||
|
|
||||||
|
First, the kernel initializes all frames to TP_STATUS_AVAILABLE. To send a
|
||||||
|
packet, the user fills a data buffer of an available frame, sets tp_len to
|
||||||
|
current data buffer size and sets its status field to TP_STATUS_SEND_REQUEST.
|
||||||
|
This can be done on multiple frames. Once the user is ready to transmit, it
|
||||||
|
calls send(). Then all buffers with status equal to TP_STATUS_SEND_REQUEST are
|
||||||
|
forwarded to the network device. The kernel updates each status of sent
|
||||||
|
frames with TP_STATUS_SENDING until the end of transfer.
|
||||||
|
At the end of each transfer, buffer status returns to TP_STATUS_AVAILABLE.
|
||||||
|
|
||||||
|
header->tp_len = in_i_size;
|
||||||
|
header->tp_status = TP_STATUS_SEND_REQUEST;
|
||||||
|
retval = send(this->socket, NULL, 0, 0);
|
||||||
|
|
||||||
|
The user can also use poll() to check if a buffer is available:
|
||||||
|
(status == TP_STATUS_SENDING)
|
||||||
|
|
||||||
|
struct pollfd pfd;
|
||||||
|
pfd.fd = fd;
|
||||||
|
pfd.revents = 0;
|
||||||
|
pfd.events = POLLOUT;
|
||||||
|
retval = poll(&pfd, 1, timeout);
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
+ THANKS
|
+ THANKS
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
Memory mapped SJA1000 CAN controller from NXP (formerly Philips)
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible : should be "nxp,sja1000".
|
||||||
|
|
||||||
|
- reg : should specify the chip select, address offset and size required
|
||||||
|
to map the registers of the SJA1000. The size is usually 0x80.
|
||||||
|
|
||||||
|
- interrupts: property with a value describing the interrupt source
|
||||||
|
(number and sensitivity) required for the SJA1000.
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
|
||||||
|
- nxp,external-clock-frequency : Frequency of the external oscillator
|
||||||
|
clock in Hz. Note that the internal clock frequency used by the
|
||||||
|
SJA1000 is half of that value. If not specified, a default value
|
||||||
|
of 16000000 (16 MHz) is used.
|
||||||
|
|
||||||
|
- nxp,tx-output-mode : operation mode of the TX output control logic:
|
||||||
|
<0x0> : bi-phase output mode
|
||||||
|
<0x1> : normal output mode (default)
|
||||||
|
<0x2> : test output mode
|
||||||
|
<0x3> : clock output mode
|
||||||
|
|
||||||
|
- nxp,tx-output-config : TX output pin configuration:
|
||||||
|
<0x01> : TX0 invert
|
||||||
|
<0x02> : TX0 pull-down (default)
|
||||||
|
<0x04> : TX0 pull-up
|
||||||
|
<0x06> : TX0 push-pull
|
||||||
|
<0x08> : TX1 invert
|
||||||
|
<0x10> : TX1 pull-down
|
||||||
|
<0x20> : TX1 pull-up
|
||||||
|
<0x30> : TX1 push-pull
|
||||||
|
|
||||||
|
- nxp,clock-out-frequency : clock frequency in Hz on the CLKOUT pin.
|
||||||
|
If not specified or if the specified value is 0, the CLKOUT pin
|
||||||
|
will be disabled.
|
||||||
|
|
||||||
|
- nxp,no-comparator-bypass : Allows to disable the CAN input comperator.
|
||||||
|
|
||||||
|
For futher information, please have a look to the SJA1000 data sheet.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
can@3,100 {
|
||||||
|
compatible = "nxp,sja1000";
|
||||||
|
reg = <3 0x100 0x80>;
|
||||||
|
interrupts = <2 0>;
|
||||||
|
interrupt-parent = <&mpic>;
|
||||||
|
nxp,external-clock-frequency = <16000000>;
|
||||||
|
};
|
||||||
|
|
|
@ -1,575 +1,136 @@
|
||||||
rfkill - RF switch subsystem support
|
rfkill - RF kill switch support
|
||||||
====================================
|
===============================
|
||||||
|
|
||||||
1 Introduction
|
1. Introduction
|
||||||
2 Implementation details
|
2. Implementation details
|
||||||
3 Kernel driver guidelines
|
3. Kernel driver guidelines
|
||||||
3.1 wireless device drivers
|
4. Kernel API
|
||||||
3.2 platform/switch drivers
|
5. Userspace support
|
||||||
3.3 input device drivers
|
|
||||||
4 Kernel API
|
|
||||||
5 Userspace support
|
|
||||||
|
|
||||||
|
|
||||||
1. Introduction:
|
1. Introduction
|
||||||
|
|
||||||
The rfkill switch subsystem exists to add a generic interface to circuitry that
|
The rfkill subsystem provides a generic interface to disabling any radio
|
||||||
can enable or disable the signal output of a wireless *transmitter* of any
|
transmitter in the system. When a transmitter is blocked, it shall not
|
||||||
type. By far, the most common use is to disable radio-frequency transmitters.
|
radiate any power.
|
||||||
|
|
||||||
Note that disabling the signal output means that the the transmitter is to be
|
The subsystem also provides the ability to react on button presses and
|
||||||
made to not emit any energy when "blocked". rfkill is not about blocking data
|
disable all transmitters of a certain type (or all). This is intended for
|
||||||
transmissions, it is about blocking energy emission.
|
situations where transmitters need to be turned off, for example on
|
||||||
|
aircraft.
|
||||||
|
|
||||||
The rfkill subsystem offers support for keys and switches often found on
|
|
||||||
laptops to enable wireless devices like WiFi and Bluetooth, so that these keys
|
|
||||||
and switches actually perform an action in all wireless devices of a given type
|
|
||||||
attached to the system.
|
|
||||||
|
|
||||||
The buttons to enable and disable the wireless transmitters are important in
|
|
||||||
situations where the user is for example using his laptop on a location where
|
|
||||||
radio-frequency transmitters _must_ be disabled (e.g. airplanes).
|
|
||||||
|
|
||||||
Because of this requirement, userspace support for the keys should not be made
|
2. Implementation details
|
||||||
mandatory. Because userspace might want to perform some additional smarter
|
|
||||||
tasks when the key is pressed, rfkill provides userspace the possibility to
|
|
||||||
take over the task to handle the key events.
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
2: Implementation details
|
|
||||||
|
|
||||||
The rfkill subsystem is composed of various components: the rfkill class, the
|
The rfkill subsystem is composed of various components: the rfkill class, the
|
||||||
rfkill-input module (an input layer handler), and some specific input layer
|
rfkill-input module (an input layer handler), and some specific input layer
|
||||||
events.
|
events.
|
||||||
|
|
||||||
The rfkill class provides kernel drivers with an interface that allows them to
|
The rfkill class is provided for kernel drivers to register their radio
|
||||||
know when they should enable or disable a wireless network device transmitter.
|
transmitter with the kernel, provide methods for turning it on and off and,
|
||||||
This is enabled by the CONFIG_RFKILL Kconfig option.
|
optionally, letting the system know about hardware-disabled states that may
|
||||||
|
be implemented on the device. This code is enabled with the CONFIG_RFKILL
|
||||||
|
Kconfig option, which drivers can "select".
|
||||||
|
|
||||||
The rfkill class support makes sure userspace will be notified of all state
|
The rfkill class code also notifies userspace of state changes, this is
|
||||||
changes on rfkill devices through uevents. It provides a notification chain
|
achieved via uevents. It also provides some sysfs files for userspace to
|
||||||
for interested parties in the kernel to also get notified of rfkill state
|
check the status of radio transmitters. See the "Userspace support" section
|
||||||
changes in other drivers. It creates several sysfs entries which can be used
|
below.
|
||||||
by userspace. See section "Userspace support".
|
|
||||||
|
|
||||||
The rfkill-input module provides the kernel with the ability to implement a
|
|
||||||
basic response when the user presses a key or button (or toggles a switch)
|
|
||||||
related to rfkill functionality. It is an in-kernel implementation of default
|
|
||||||
policy of reacting to rfkill-related input events and neither mandatory nor
|
|
||||||
required for wireless drivers to operate. It is enabled by the
|
|
||||||
CONFIG_RFKILL_INPUT Kconfig option.
|
|
||||||
|
|
||||||
rfkill-input is a rfkill-related events input layer handler. This handler will
|
The rfkill-input code implements a basic response to rfkill buttons -- it
|
||||||
listen to all rfkill key events and will change the rfkill state of the
|
implements turning on/off all devices of a certain class (or all).
|
||||||
wireless devices accordingly. With this option enabled userspace could either
|
|
||||||
do nothing or simply perform monitoring tasks.
|
|
||||||
|
|
||||||
The rfkill-input module also provides EPO (emergency power-off) functionality
|
When the device is hard-blocked (either by a call to rfkill_set_hw_state()
|
||||||
for all wireless transmitters. This function cannot be overridden, and it is
|
or from query_hw_block) set_block() will be invoked but drivers can well
|
||||||
always active. rfkill EPO is related to *_RFKILL_ALL input layer events.
|
ignore the method call since they can use the return value of the function
|
||||||
|
rfkill_set_hw_state() to sync the software state instead of keeping track
|
||||||
|
of calls to set_block().
|
||||||
|
|
||||||
|
|
||||||
Important terms for the rfkill subsystem:
|
The entire functionality is spread over more than one subsystem:
|
||||||
|
|
||||||
In order to avoid confusion, we avoid the term "switch" in rfkill when it is
|
* The kernel input layer generates KEY_WWAN, KEY_WLAN etc. and
|
||||||
referring to an electronic control circuit that enables or disables a
|
SW_RFKILL_ALL -- when the user presses a button. Drivers for radio
|
||||||
transmitter. We reserve it for the physical device a human manipulates
|
transmitters generally do not register to the input layer, unless the
|
||||||
(which is an input device, by the way):
|
device really provides an input device (i.e. a button that has no
|
||||||
|
effect other than generating a button press event)
|
||||||
|
|
||||||
rfkill switch:
|
* The rfkill-input code hooks up to these events and switches the soft-block
|
||||||
|
of the various radio transmitters, depending on the button type.
|
||||||
|
|
||||||
A physical device a human manipulates. Its state can be perceived by
|
* The rfkill drivers turn off/on their transmitters as requested.
|
||||||
the kernel either directly (through a GPIO pin, ACPI GPE) or by its
|
|
||||||
effect on a rfkill line of a wireless device.
|
|
||||||
|
|
||||||
rfkill controller:
|
* The rfkill class will generate userspace notifications (uevents) to tell
|
||||||
|
userspace what the current state is.
|
||||||
|
|
||||||
A hardware circuit that controls the state of a rfkill line, which a
|
|
||||||
kernel driver can interact with *to modify* that state (i.e. it has
|
|
||||||
either write-only or read/write access).
|
|
||||||
|
|
||||||
rfkill line:
|
|
||||||
|
|
||||||
An input channel (hardware or software) of a wireless device, which
|
3. Kernel driver guidelines
|
||||||
causes a wireless transmitter to stop emitting energy (BLOCK) when it
|
|
||||||
is active. Point of view is extremely important here: rfkill lines are
|
|
||||||
always seen from the PoV of a wireless device (and its driver).
|
|
||||||
|
|
||||||
soft rfkill line/software rfkill line:
|
|
||||||
|
|
||||||
A rfkill line the wireless device driver can directly change the state
|
Drivers for radio transmitters normally implement only the rfkill class.
|
||||||
of. Related to rfkill_state RFKILL_STATE_SOFT_BLOCKED.
|
These drivers may not unblock the transmitter based on own decisions, they
|
||||||
|
should act on information provided by the rfkill class only.
|
||||||
|
|
||||||
hard rfkill line/hardware rfkill line:
|
Platform drivers might implement input devices if the rfkill button is just
|
||||||
|
that, a button. If that button influences the hardware then you need to
|
||||||
|
implement an rfkill class instead. This also applies if the platform provides
|
||||||
|
a way to turn on/off the transmitter(s).
|
||||||
|
|
||||||
A rfkill line that works fully in hardware or firmware, and that cannot
|
During suspend/hibernation, transmitters should only be left enabled when
|
||||||
be overridden by the kernel driver. The hardware device or the
|
wake-on wlan or similar functionality requires it and the device wasn't
|
||||||
firmware just exports its status to the driver, but it is read-only.
|
blocked before suspend/hibernate. Note that it may be necessary to update
|
||||||
Related to rfkill_state RFKILL_STATE_HARD_BLOCKED.
|
the rfkill subsystem's idea of what the current state is at resume time if
|
||||||
|
the state may have changed over suspend.
|
||||||
|
|
||||||
The enum rfkill_state describes the rfkill state of a transmitter:
|
|
||||||
|
|
||||||
When a rfkill line or rfkill controller is in the RFKILL_STATE_UNBLOCKED state,
|
|
||||||
the wireless transmitter (radio TX circuit for example) is *enabled*. When the
|
|
||||||
it is in the RFKILL_STATE_SOFT_BLOCKED or RFKILL_STATE_HARD_BLOCKED, the
|
|
||||||
wireless transmitter is to be *blocked* from operating.
|
|
||||||
|
|
||||||
RFKILL_STATE_SOFT_BLOCKED indicates that a call to toggle_radio() can change
|
4. Kernel API
|
||||||
that state. RFKILL_STATE_HARD_BLOCKED indicates that a call to toggle_radio()
|
|
||||||
will not be able to change the state and will return with a suitable error if
|
|
||||||
attempts are made to set the state to RFKILL_STATE_UNBLOCKED.
|
|
||||||
|
|
||||||
RFKILL_STATE_HARD_BLOCKED is used by drivers to signal that the device is
|
|
||||||
locked in the BLOCKED state by a hardwire rfkill line (typically an input pin
|
|
||||||
that, when active, forces the transmitter to be disabled) which the driver
|
|
||||||
CANNOT override.
|
|
||||||
|
|
||||||
Full rfkill functionality requires two different subsystems to cooperate: the
|
|
||||||
input layer and the rfkill class. The input layer issues *commands* to the
|
|
||||||
entire system requesting that devices registered to the rfkill class change
|
|
||||||
state. The way this interaction happens is not complex, but it is not obvious
|
|
||||||
either:
|
|
||||||
|
|
||||||
Kernel Input layer:
|
|
||||||
|
|
||||||
* Generates KEY_WWAN, KEY_WLAN, KEY_BLUETOOTH, SW_RFKILL_ALL, and
|
|
||||||
other such events when the user presses certain keys, buttons, or
|
|
||||||
toggles certain physical switches.
|
|
||||||
|
|
||||||
THE INPUT LAYER IS NEVER USED TO PROPAGATE STATUS, NOTIFICATIONS OR THE
|
|
||||||
KIND OF STUFF AN ON-SCREEN-DISPLAY APPLICATION WOULD REPORT. It is
|
|
||||||
used to issue *commands* for the system to change behaviour, and these
|
|
||||||
commands may or may not be carried out by some kernel driver or
|
|
||||||
userspace application. It follows that doing user feedback based only
|
|
||||||
on input events is broken, as there is no guarantee that an input event
|
|
||||||
will be acted upon.
|
|
||||||
|
|
||||||
Most wireless communication device drivers implementing rfkill
|
|
||||||
functionality MUST NOT generate these events, and have no reason to
|
|
||||||
register themselves with the input layer. Doing otherwise is a common
|
|
||||||
misconception. There is an API to propagate rfkill status change
|
|
||||||
information, and it is NOT the input layer.
|
|
||||||
|
|
||||||
rfkill class:
|
|
||||||
|
|
||||||
* Calls a hook in a driver to effectively change the wireless
|
|
||||||
transmitter state;
|
|
||||||
* Keeps track of the wireless transmitter state (with help from
|
|
||||||
the driver);
|
|
||||||
* Generates userspace notifications (uevents) and a call to a
|
|
||||||
notification chain (kernel) when there is a wireless transmitter
|
|
||||||
state change;
|
|
||||||
* Connects a wireless communications driver with the common rfkill
|
|
||||||
control system, which, for example, allows actions such as
|
|
||||||
"switch all bluetooth devices offline" to be carried out by
|
|
||||||
userspace or by rfkill-input.
|
|
||||||
|
|
||||||
THE RFKILL CLASS NEVER ISSUES INPUT EVENTS. THE RFKILL CLASS DOES
|
|
||||||
NOT LISTEN TO INPUT EVENTS. NO DRIVER USING THE RFKILL CLASS SHALL
|
|
||||||
EVER LISTEN TO, OR ACT ON RFKILL INPUT EVENTS. Doing otherwise is
|
|
||||||
a layering violation.
|
|
||||||
|
|
||||||
Most wireless data communication drivers in the kernel have just to
|
|
||||||
implement the rfkill class API to work properly. Interfacing to the
|
|
||||||
input layer is not often required (and is very often a *bug*) on
|
|
||||||
wireless drivers.
|
|
||||||
|
|
||||||
Platform drivers often have to attach to the input layer to *issue*
|
|
||||||
(but never to listen to) rfkill events for rfkill switches, and also to
|
|
||||||
the rfkill class to export a control interface for the platform rfkill
|
|
||||||
controllers to the rfkill subsystem. This does NOT mean the rfkill
|
|
||||||
switch is attached to a rfkill class (doing so is almost always wrong).
|
|
||||||
It just means the same kernel module is the driver for different
|
|
||||||
devices (rfkill switches and rfkill controllers).
|
|
||||||
|
|
||||||
|
|
||||||
Userspace input handlers (uevents) or kernel input handlers (rfkill-input):
|
|
||||||
|
|
||||||
* Implements the policy of what should happen when one of the input
|
|
||||||
layer events related to rfkill operation is received.
|
|
||||||
* Uses the sysfs interface (userspace) or private rfkill API calls
|
|
||||||
to tell the devices registered with the rfkill class to change
|
|
||||||
their state (i.e. translates the input layer event into real
|
|
||||||
action).
|
|
||||||
|
|
||||||
* rfkill-input implements EPO by handling EV_SW SW_RFKILL_ALL 0
|
|
||||||
(power off all transmitters) in a special way: it ignores any
|
|
||||||
overrides and local state cache and forces all transmitters to the
|
|
||||||
RFKILL_STATE_SOFT_BLOCKED state (including those which are already
|
|
||||||
supposed to be BLOCKED).
|
|
||||||
* rfkill EPO will remain active until rfkill-input receives an
|
|
||||||
EV_SW SW_RFKILL_ALL 1 event. While the EPO is active, transmitters
|
|
||||||
are locked in the blocked state (rfkill will refuse to unblock them).
|
|
||||||
* rfkill-input implements different policies that the user can
|
|
||||||
select for handling EV_SW SW_RFKILL_ALL 1. It will unlock rfkill,
|
|
||||||
and either do nothing (leave transmitters blocked, but now unlocked),
|
|
||||||
restore the transmitters to their state before the EPO, or unblock
|
|
||||||
them all.
|
|
||||||
|
|
||||||
Userspace uevent handler or kernel platform-specific drivers hooked to the
|
|
||||||
rfkill notifier chain:
|
|
||||||
|
|
||||||
* Taps into the rfkill notifier chain or to KOBJ_CHANGE uevents,
|
|
||||||
in order to know when a device that is registered with the rfkill
|
|
||||||
class changes state;
|
|
||||||
* Issues feedback notifications to the user;
|
|
||||||
* In the rare platforms where this is required, synthesizes an input
|
|
||||||
event to command all *OTHER* rfkill devices to also change their
|
|
||||||
statues when a specific rfkill device changes state.
|
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
3: Kernel driver guidelines
|
|
||||||
|
|
||||||
Remember: point-of-view is everything for a driver that connects to the rfkill
|
|
||||||
subsystem. All the details below must be measured/perceived from the point of
|
|
||||||
view of the specific driver being modified.
|
|
||||||
|
|
||||||
The first thing one needs to know is whether his driver should be talking to
|
|
||||||
the rfkill class or to the input layer. In rare cases (platform drivers), it
|
|
||||||
could happen that you need to do both, as platform drivers often handle a
|
|
||||||
variety of devices in the same driver.
|
|
||||||
|
|
||||||
Do not mistake input devices for rfkill controllers. The only type of "rfkill
|
|
||||||
switch" device that is to be registered with the rfkill class are those
|
|
||||||
directly controlling the circuits that cause a wireless transmitter to stop
|
|
||||||
working (or the software equivalent of them), i.e. what we call a rfkill
|
|
||||||
controller. Every other kind of "rfkill switch" is just an input device and
|
|
||||||
MUST NOT be registered with the rfkill class.
|
|
||||||
|
|
||||||
A driver should register a device with the rfkill class when ALL of the
|
|
||||||
following conditions are met (they define a rfkill controller):
|
|
||||||
|
|
||||||
1. The device is/controls a data communications wireless transmitter;
|
|
||||||
|
|
||||||
2. The kernel can interact with the hardware/firmware to CHANGE the wireless
|
|
||||||
transmitter state (block/unblock TX operation);
|
|
||||||
|
|
||||||
3. The transmitter can be made to not emit any energy when "blocked":
|
|
||||||
rfkill is not about blocking data transmissions, it is about blocking
|
|
||||||
energy emission;
|
|
||||||
|
|
||||||
A driver should register a device with the input subsystem to issue
|
|
||||||
rfkill-related events (KEY_WLAN, KEY_BLUETOOTH, KEY_WWAN, KEY_WIMAX,
|
|
||||||
SW_RFKILL_ALL, etc) when ALL of the folowing conditions are met:
|
|
||||||
|
|
||||||
1. It is directly related to some physical device the user interacts with, to
|
|
||||||
command the O.S./firmware/hardware to enable/disable a data communications
|
|
||||||
wireless transmitter.
|
|
||||||
|
|
||||||
Examples of the physical device are: buttons, keys and switches the user
|
|
||||||
will press/touch/slide/switch to enable or disable the wireless
|
|
||||||
communication device.
|
|
||||||
|
|
||||||
2. It is NOT slaved to another device, i.e. there is no other device that
|
|
||||||
issues rfkill-related input events in preference to this one.
|
|
||||||
|
|
||||||
Please refer to the corner cases and examples section for more details.
|
|
||||||
|
|
||||||
When in doubt, do not issue input events. For drivers that should generate
|
|
||||||
input events in some platforms, but not in others (e.g. b43), the best solution
|
|
||||||
is to NEVER generate input events in the first place. That work should be
|
|
||||||
deferred to a platform-specific kernel module (which will know when to generate
|
|
||||||
events through the rfkill notifier chain) or to userspace. This avoids the
|
|
||||||
usual maintenance problems with DMI whitelisting.
|
|
||||||
|
|
||||||
|
|
||||||
Corner cases and examples:
|
|
||||||
====================================
|
|
||||||
|
|
||||||
1. If the device is an input device that, because of hardware or firmware,
|
|
||||||
causes wireless transmitters to be blocked regardless of the kernel's will, it
|
|
||||||
is still just an input device, and NOT to be registered with the rfkill class.
|
|
||||||
|
|
||||||
2. If the wireless transmitter switch control is read-only, it is an input
|
|
||||||
device and not to be registered with the rfkill class (and maybe not to be made
|
|
||||||
an input layer event source either, see below).
|
|
||||||
|
|
||||||
3. If there is some other device driver *closer* to the actual hardware the
|
|
||||||
user interacted with (the button/switch/key) to issue an input event, THAT is
|
|
||||||
the device driver that should be issuing input events.
|
|
||||||
|
|
||||||
E.g:
|
|
||||||
[RFKILL slider switch] -- [GPIO hardware] -- [WLAN card rf-kill input]
|
|
||||||
(platform driver) (wireless card driver)
|
|
||||||
|
|
||||||
The user is closer to the RFKILL slide switch plaform driver, so the driver
|
|
||||||
which must issue input events is the platform driver looking at the GPIO
|
|
||||||
hardware, and NEVER the wireless card driver (which is just a slave). It is
|
|
||||||
very likely that there are other leaves than just the WLAN card rf-kill input
|
|
||||||
(e.g. a bluetooth card, etc)...
|
|
||||||
|
|
||||||
On the other hand, some embedded devices do this:
|
|
||||||
|
|
||||||
[RFKILL slider switch] -- [WLAN card rf-kill input]
|
|
||||||
(wireless card driver)
|
|
||||||
|
|
||||||
In this situation, the wireless card driver *could* register itself as an input
|
|
||||||
device and issue rf-kill related input events... but in order to AVOID the need
|
|
||||||
for DMI whitelisting, the wireless card driver does NOT do it. Userspace (HAL)
|
|
||||||
or a platform driver (that exists only on these embedded devices) will do the
|
|
||||||
dirty job of issuing the input events.
|
|
||||||
|
|
||||||
|
|
||||||
COMMON MISTAKES in kernel drivers, related to rfkill:
|
|
||||||
====================================
|
|
||||||
|
|
||||||
1. NEVER confuse input device keys and buttons with input device switches.
|
|
||||||
|
|
||||||
1a. Switches are always set or reset. They report the current state
|
|
||||||
(on position or off position).
|
|
||||||
|
|
||||||
1b. Keys and buttons are either in the pressed or not-pressed state, and
|
|
||||||
that's it. A "button" that latches down when you press it, and
|
|
||||||
unlatches when you press it again is in fact a switch as far as input
|
|
||||||
devices go.
|
|
||||||
|
|
||||||
Add the SW_* events you need for switches, do NOT try to emulate a button using
|
|
||||||
KEY_* events just because there is no such SW_* event yet. Do NOT try to use,
|
|
||||||
for example, KEY_BLUETOOTH when you should be using SW_BLUETOOTH instead.
|
|
||||||
|
|
||||||
2. Input device switches (sources of EV_SW events) DO store their current state
|
|
||||||
(so you *must* initialize it by issuing a gratuitous input layer event on
|
|
||||||
driver start-up and also when resuming from sleep), and that state CAN be
|
|
||||||
queried from userspace through IOCTLs. There is no sysfs interface for this,
|
|
||||||
but that doesn't mean you should break things trying to hook it to the rfkill
|
|
||||||
class to get a sysfs interface :-)
|
|
||||||
|
|
||||||
3. Do not issue *_RFKILL_ALL events by default, unless you are sure it is the
|
|
||||||
correct event for your switch/button. These events are emergency power-off
|
|
||||||
events when they are trying to turn the transmitters off. An example of an
|
|
||||||
input device which SHOULD generate *_RFKILL_ALL events is the wireless-kill
|
|
||||||
switch in a laptop which is NOT a hotkey, but a real sliding/rocker switch.
|
|
||||||
An example of an input device which SHOULD NOT generate *_RFKILL_ALL events by
|
|
||||||
default, is any sort of hot key that is type-specific (e.g. the one for WLAN).
|
|
||||||
|
|
||||||
|
|
||||||
3.1 Guidelines for wireless device drivers
|
|
||||||
------------------------------------------
|
|
||||||
|
|
||||||
(in this text, rfkill->foo means the foo field of struct rfkill).
|
|
||||||
|
|
||||||
1. Each independent transmitter in a wireless device (usually there is only one
|
|
||||||
transmitter per device) should have a SINGLE rfkill class attached to it.
|
|
||||||
|
|
||||||
2. If the device does not have any sort of hardware assistance to allow the
|
|
||||||
driver to rfkill the device, the driver should emulate it by taking all actions
|
|
||||||
required to silence the transmitter.
|
|
||||||
|
|
||||||
3. If it is impossible to silence the transmitter (i.e. it still emits energy,
|
|
||||||
even if it is just in brief pulses, when there is no data to transmit and there
|
|
||||||
is no hardware support to turn it off) do NOT lie to the users. Do not attach
|
|
||||||
it to a rfkill class. The rfkill subsystem does not deal with data
|
|
||||||
transmission, it deals with energy emission. If the transmitter is emitting
|
|
||||||
energy, it is not blocked in rfkill terms.
|
|
||||||
|
|
||||||
4. It doesn't matter if the device has multiple rfkill input lines affecting
|
|
||||||
the same transmitter, their combined state is to be exported as a single state
|
|
||||||
per transmitter (see rule 1).
|
|
||||||
|
|
||||||
This rule exists because users of the rfkill subsystem expect to get (and set,
|
|
||||||
when possible) the overall transmitter rfkill state, not of a particular rfkill
|
|
||||||
line.
|
|
||||||
|
|
||||||
5. The wireless device driver MUST NOT leave the transmitter enabled during
|
|
||||||
suspend and hibernation unless:
|
|
||||||
|
|
||||||
5.1. The transmitter has to be enabled for some sort of functionality
|
|
||||||
like wake-on-wireless-packet or autonomous packed forwarding in a mesh
|
|
||||||
network, and that functionality is enabled for this suspend/hibernation
|
|
||||||
cycle.
|
|
||||||
|
|
||||||
AND
|
|
||||||
|
|
||||||
5.2. The device was not on a user-requested BLOCKED state before
|
|
||||||
the suspend (i.e. the driver must NOT unblock a device, not even
|
|
||||||
to support wake-on-wireless-packet or remain in the mesh).
|
|
||||||
|
|
||||||
In other words, there is absolutely no allowed scenario where a driver can
|
|
||||||
automatically take action to unblock a rfkill controller (obviously, this deals
|
|
||||||
with scenarios where soft-blocking or both soft and hard blocking is happening.
|
|
||||||
Scenarios where hardware rfkill lines are the only ones blocking the
|
|
||||||
transmitter are outside of this rule, since the wireless device driver does not
|
|
||||||
control its input hardware rfkill lines in the first place).
|
|
||||||
|
|
||||||
6. During resume, rfkill will try to restore its previous state.
|
|
||||||
|
|
||||||
7. After a rfkill class is suspended, it will *not* call rfkill->toggle_radio
|
|
||||||
until it is resumed.
|
|
||||||
|
|
||||||
|
|
||||||
Example of a WLAN wireless driver connected to the rfkill subsystem:
|
|
||||||
--------------------------------------------------------------------
|
|
||||||
|
|
||||||
A certain WLAN card has one input pin that causes it to block the transmitter
|
|
||||||
and makes the status of that input pin available (only for reading!) to the
|
|
||||||
kernel driver. This is a hard rfkill input line (it cannot be overridden by
|
|
||||||
the kernel driver).
|
|
||||||
|
|
||||||
The card also has one PCI register that, if manipulated by the driver, causes
|
|
||||||
it to block the transmitter. This is a soft rfkill input line.
|
|
||||||
|
|
||||||
It has also a thermal protection circuitry that shuts down its transmitter if
|
|
||||||
the card overheats, and makes the status of that protection available (only for
|
|
||||||
reading!) to the kernel driver. This is also a hard rfkill input line.
|
|
||||||
|
|
||||||
If either one of these rfkill lines are active, the transmitter is blocked by
|
|
||||||
the hardware and forced offline.
|
|
||||||
|
|
||||||
The driver should allocate and attach to its struct device *ONE* instance of
|
|
||||||
the rfkill class (there is only one transmitter).
|
|
||||||
|
|
||||||
It can implement the get_state() hook, and return RFKILL_STATE_HARD_BLOCKED if
|
|
||||||
either one of its two hard rfkill input lines are active. If the two hard
|
|
||||||
rfkill lines are inactive, it must return RFKILL_STATE_SOFT_BLOCKED if its soft
|
|
||||||
rfkill input line is active. Only if none of the rfkill input lines are
|
|
||||||
active, will it return RFKILL_STATE_UNBLOCKED.
|
|
||||||
|
|
||||||
Since the device has a hardware rfkill line, it IS subject to state changes
|
|
||||||
external to rfkill. Therefore, the driver must make sure that it calls
|
|
||||||
rfkill_force_state() to keep the status always up-to-date, and it must do a
|
|
||||||
rfkill_force_state() on resume from sleep.
|
|
||||||
|
|
||||||
Every time the driver gets a notification from the card that one of its rfkill
|
|
||||||
lines changed state (polling might be needed on badly designed cards that don't
|
|
||||||
generate interrupts for such events), it recomputes the rfkill state as per
|
|
||||||
above, and calls rfkill_force_state() to update it.
|
|
||||||
|
|
||||||
The driver should implement the toggle_radio() hook, that:
|
|
||||||
|
|
||||||
1. Returns an error if one of the hardware rfkill lines are active, and the
|
|
||||||
caller asked for RFKILL_STATE_UNBLOCKED.
|
|
||||||
|
|
||||||
2. Activates the soft rfkill line if the caller asked for state
|
|
||||||
RFKILL_STATE_SOFT_BLOCKED. It should do this even if one of the hard rfkill
|
|
||||||
lines are active, effectively double-blocking the transmitter.
|
|
||||||
|
|
||||||
3. Deactivates the soft rfkill line if none of the hardware rfkill lines are
|
|
||||||
active and the caller asked for RFKILL_STATE_UNBLOCKED.
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
4: Kernel API
|
|
||||||
|
|
||||||
To build a driver with rfkill subsystem support, the driver should depend on
|
To build a driver with rfkill subsystem support, the driver should depend on
|
||||||
(or select) the Kconfig symbol RFKILL; it should _not_ depend on RKFILL_INPUT.
|
(or select) the Kconfig symbol RFKILL.
|
||||||
|
|
||||||
The hardware the driver talks to may be write-only (where the current state
|
The hardware the driver talks to may be write-only (where the current state
|
||||||
of the hardware is unknown), or read-write (where the hardware can be queried
|
of the hardware is unknown), or read-write (where the hardware can be queried
|
||||||
about its current state).
|
about its current state).
|
||||||
|
|
||||||
The rfkill class will call the get_state hook of a device every time it needs
|
Calling rfkill_set_hw_state() when a state change happens is required from
|
||||||
to know the *real* current state of the hardware. This can happen often, but
|
rfkill drivers that control devices that can be hard-blocked unless they also
|
||||||
it does not do any polling, so it is not enough on hardware that is subject
|
assign the poll_hw_block() callback (then the rfkill core will poll the
|
||||||
to state changes outside of the rfkill subsystem.
|
device). Don't do this unless you cannot get the event in any other way.
|
||||||
|
|
||||||
Therefore, calling rfkill_force_state() when a state change happens is
|
|
||||||
mandatory when the device has a hardware rfkill line, or when something else
|
|
||||||
like the firmware could cause its state to be changed without going through the
|
|
||||||
rfkill class.
|
|
||||||
|
|
||||||
Some hardware provides events when its status changes. In these cases, it is
|
|
||||||
best for the driver to not provide a get_state hook, and instead register the
|
|
||||||
rfkill class *already* with the correct status, and keep it updated using
|
|
||||||
rfkill_force_state() when it gets an event from the hardware.
|
|
||||||
|
|
||||||
rfkill_force_state() must be used on the device resume handlers to update the
|
5. Userspace support
|
||||||
rfkill status, should there be any chance of the device status changing during
|
|
||||||
the sleep.
|
|
||||||
|
|
||||||
There is no provision for a statically-allocated rfkill struct. You must
|
The following sysfs entries exist for every rfkill device:
|
||||||
use rfkill_allocate() to allocate one.
|
|
||||||
|
|
||||||
You should:
|
|
||||||
- rfkill_allocate()
|
|
||||||
- modify rfkill fields (flags, name)
|
|
||||||
- modify state to the current hardware state (THIS IS THE ONLY TIME
|
|
||||||
YOU CAN ACCESS state DIRECTLY)
|
|
||||||
- rfkill_register()
|
|
||||||
|
|
||||||
The only way to set a device to the RFKILL_STATE_HARD_BLOCKED state is through
|
|
||||||
a suitable return of get_state() or through rfkill_force_state().
|
|
||||||
|
|
||||||
When a device is in the RFKILL_STATE_HARD_BLOCKED state, the only way to switch
|
|
||||||
it to a different state is through a suitable return of get_state() or through
|
|
||||||
rfkill_force_state().
|
|
||||||
|
|
||||||
If toggle_radio() is called to set a device to state RFKILL_STATE_SOFT_BLOCKED
|
|
||||||
when that device is already at the RFKILL_STATE_HARD_BLOCKED state, it should
|
|
||||||
not return an error. Instead, it should try to double-block the transmitter,
|
|
||||||
so that its state will change from RFKILL_STATE_HARD_BLOCKED to
|
|
||||||
RFKILL_STATE_SOFT_BLOCKED should the hardware blocking cease.
|
|
||||||
|
|
||||||
Please refer to the source for more documentation.
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
5: Userspace support
|
|
||||||
|
|
||||||
rfkill devices issue uevents (with an action of "change"), with the following
|
|
||||||
environment variables set:
|
|
||||||
|
|
||||||
RFKILL_NAME
|
|
||||||
RFKILL_STATE
|
|
||||||
RFKILL_TYPE
|
|
||||||
|
|
||||||
The ABI for these variables is defined by the sysfs attributes. It is best
|
|
||||||
to take a quick look at the source to make sure of the possible values.
|
|
||||||
|
|
||||||
It is expected that HAL will trap those, and bridge them to DBUS, etc. These
|
|
||||||
events CAN and SHOULD be used to give feedback to the user about the rfkill
|
|
||||||
status of the system.
|
|
||||||
|
|
||||||
Input devices may issue events that are related to rfkill. These are the
|
|
||||||
various KEY_* events and SW_* events supported by rfkill-input.c.
|
|
||||||
|
|
||||||
******IMPORTANT******
|
|
||||||
When rfkill-input is ACTIVE, userspace is NOT TO CHANGE THE STATE OF AN RFKILL
|
|
||||||
SWITCH IN RESPONSE TO AN INPUT EVENT also handled by rfkill-input, unless it
|
|
||||||
has set to true the user_claim attribute for that particular switch. This rule
|
|
||||||
is *absolute*; do NOT violate it.
|
|
||||||
******IMPORTANT******
|
|
||||||
|
|
||||||
Userspace must not assume it is the only source of control for rfkill switches.
|
|
||||||
Their state CAN and WILL change due to firmware actions, direct user actions,
|
|
||||||
and the rfkill-input EPO override for *_RFKILL_ALL.
|
|
||||||
|
|
||||||
When rfkill-input is not active, userspace must initiate a rfkill status
|
|
||||||
change by writing to the "state" attribute in order for anything to happen.
|
|
||||||
|
|
||||||
Take particular care to implement EV_SW SW_RFKILL_ALL properly. When that
|
|
||||||
switch is set to OFF, *every* rfkill device *MUST* be immediately put into the
|
|
||||||
RFKILL_STATE_SOFT_BLOCKED state, no questions asked.
|
|
||||||
|
|
||||||
The following sysfs entries will be created:
|
|
||||||
|
|
||||||
name: Name assigned by driver to this key (interface or driver name).
|
name: Name assigned by driver to this key (interface or driver name).
|
||||||
type: Name of the key type ("wlan", "bluetooth", etc).
|
type: Name of the key type ("wlan", "bluetooth", etc).
|
||||||
state: Current state of the transmitter
|
state: Current state of the transmitter
|
||||||
0: RFKILL_STATE_SOFT_BLOCKED
|
0: RFKILL_STATE_SOFT_BLOCKED
|
||||||
transmitter is forced off, but one can override it
|
transmitter is turned off by software
|
||||||
by a write to the state attribute;
|
|
||||||
1: RFKILL_STATE_UNBLOCKED
|
1: RFKILL_STATE_UNBLOCKED
|
||||||
transmiter is NOT forced off, and may operate if
|
transmitter is (potentially) active
|
||||||
all other conditions for such operation are met
|
|
||||||
(such as interface is up and configured, etc);
|
|
||||||
2: RFKILL_STATE_HARD_BLOCKED
|
2: RFKILL_STATE_HARD_BLOCKED
|
||||||
transmitter is forced off by something outside of
|
transmitter is forced off by something outside of
|
||||||
the driver's control. One cannot set a device to
|
the driver's control.
|
||||||
this state through writes to the state attribute;
|
claim: 0: Kernel handles events (currently always reads that value)
|
||||||
claim: 1: Userspace handles events, 0: Kernel handles events
|
|
||||||
|
|
||||||
Both the "state" and "claim" entries are also writable. For the "state" entry
|
rfkill devices also issue uevents (with an action of "change"), with the
|
||||||
this means that when 1 or 0 is written, the device rfkill state (if not yet in
|
following environment variables set:
|
||||||
the requested state), will be will be toggled accordingly.
|
|
||||||
|
|
||||||
For the "claim" entry writing 1 to it means that the kernel no longer handles
|
RFKILL_NAME
|
||||||
key events even though RFKILL_INPUT input was enabled. When "claim" has been
|
RFKILL_STATE
|
||||||
set to 0, userspace should make sure that it listens for the input events or
|
RFKILL_TYPE
|
||||||
check the sysfs "state" entry regularly to correctly perform the required tasks
|
|
||||||
when the rkfill key is pressed.
|
|
||||||
|
|
||||||
A note about input devices and EV_SW events:
|
The contents of these variables corresponds to the "name", "state" and
|
||||||
|
"type" sysfs files explained above.
|
||||||
|
|
||||||
In order to know the current state of an input device switch (like
|
An alternative userspace interface exists as a misc device /dev/rfkill,
|
||||||
SW_RFKILL_ALL), you will need to use an IOCTL. That information is not
|
which allows userspace to obtain and set the state of rfkill devices and
|
||||||
available through sysfs in a generic way at this time, and it is not available
|
sets of devices. It also notifies userspace about device addition and
|
||||||
through the rfkill class AT ALL.
|
removal. The API is a simple read/write API that is defined in
|
||||||
|
linux/rfkill.h.
|
||||||
|
|
38
MAINTAINERS
38
MAINTAINERS
|
@ -947,6 +947,12 @@ P: Luis R. Rodriguez
|
||||||
M: lrodriguez@atheros.com
|
M: lrodriguez@atheros.com
|
||||||
P: Jouni Malinen
|
P: Jouni Malinen
|
||||||
M: jmalinen@atheros.com
|
M: jmalinen@atheros.com
|
||||||
|
P: Sujith Manoharan
|
||||||
|
M: Sujith.Manoharan@atheros.com
|
||||||
|
P: Vasanthakumar Thiagarajan
|
||||||
|
M: vasanth@atheros.com
|
||||||
|
P: Senthil Balasubramanian
|
||||||
|
M: senthilkumar@atheros.com
|
||||||
L: linux-wireless@vger.kernel.org
|
L: linux-wireless@vger.kernel.org
|
||||||
L: ath9k-devel@lists.ath9k.org
|
L: ath9k-devel@lists.ath9k.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
@ -1339,6 +1345,13 @@ F: drivers/net/can/
|
||||||
F: include/linux/can/
|
F: include/linux/can/
|
||||||
F: include/linux/can.h
|
F: include/linux/can.h
|
||||||
|
|
||||||
|
CAN NETWORK DRIVERS
|
||||||
|
P: Wolfgang Grandegger
|
||||||
|
M: wg@grandegger.com
|
||||||
|
L: socketcan-core@lists.berlios.de (subscribers-only)
|
||||||
|
W: http://developer.berlios.de/projects/socketcan/
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
CELL BROADBAND ENGINE ARCHITECTURE
|
CELL BROADBAND ENGINE ARCHITECTURE
|
||||||
P: Arnd Bergmann
|
P: Arnd Bergmann
|
||||||
M: arnd@arndb.de
|
M: arnd@arndb.de
|
||||||
|
@ -2843,6 +2856,18 @@ L: linux1394-devel@lists.sourceforge.net
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/ieee1394/raw1394*
|
F: drivers/ieee1394/raw1394*
|
||||||
|
|
||||||
|
IEEE 802.15.4 SUBSYSTEM
|
||||||
|
P: Dmitry Eremin-Solenikov
|
||||||
|
M: dbaryshkov@gmail.com
|
||||||
|
P: Sergey Lapin
|
||||||
|
M: slapin@ossfans.org
|
||||||
|
L: linux-zigbee-devel@lists.sourceforge.net
|
||||||
|
W: http://apps.sourceforge.net/trac/linux-zigbee
|
||||||
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lumag/lowpan.git
|
||||||
|
S: Maintained
|
||||||
|
F: net/ieee802154/
|
||||||
|
F: drivers/ieee801254/
|
||||||
|
|
||||||
INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
|
INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
|
||||||
P: Mimi Zohar
|
P: Mimi Zohar
|
||||||
M: zohar@us.ibm.com
|
M: zohar@us.ibm.com
|
||||||
|
@ -3136,6 +3161,7 @@ M: samuel@sortiz.org
|
||||||
L: irda-users@lists.sourceforge.net (subscribers-only)
|
L: irda-users@lists.sourceforge.net (subscribers-only)
|
||||||
W: http://irda.sourceforge.net/
|
W: http://irda.sourceforge.net/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/irda-2.6.git
|
||||||
F: Documentation/networking/irda.txt
|
F: Documentation/networking/irda.txt
|
||||||
F: drivers/net/irda/
|
F: drivers/net/irda/
|
||||||
F: include/net/irda/
|
F: include/net/irda/
|
||||||
|
@ -4621,8 +4647,8 @@ S: Maintained
|
||||||
F: drivers/ata/sata_promise.*
|
F: drivers/ata/sata_promise.*
|
||||||
|
|
||||||
PS3 NETWORK SUPPORT
|
PS3 NETWORK SUPPORT
|
||||||
P: Masakazu Mokuno
|
P: Geoff Levand
|
||||||
M: mokuno@sm.sony.co.jp
|
M: geoffrey.levand@am.sony.com
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
L: cbe-oss-dev@ozlabs.org
|
L: cbe-oss-dev@ozlabs.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
@ -4823,7 +4849,7 @@ F: drivers/net/r6040.c
|
||||||
RDS - RELIABLE DATAGRAM SOCKETS
|
RDS - RELIABLE DATAGRAM SOCKETS
|
||||||
P: Andy Grover
|
P: Andy Grover
|
||||||
M: andy.grover@oracle.com
|
M: andy.grover@oracle.com
|
||||||
L: rds-devel@oss.oracle.com
|
L: rds-devel@oss.oracle.com (moderated for non-subscribers)
|
||||||
S: Supported
|
S: Supported
|
||||||
F: net/rds/
|
F: net/rds/
|
||||||
|
|
||||||
|
@ -4863,9 +4889,9 @@ S: Supported
|
||||||
F: fs/reiserfs/
|
F: fs/reiserfs/
|
||||||
|
|
||||||
RFKILL
|
RFKILL
|
||||||
P: Ivo van Doorn
|
P: Johannes Berg
|
||||||
M: IvDoorn@gmail.com
|
M: johannes@sipsolutions.net
|
||||||
L: netdev@vger.kernel.org
|
L: linux-wireless@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F Documentation/rfkill.txt
|
F Documentation/rfkill.txt
|
||||||
F: net/rfkill/
|
F: net/rfkill/
|
||||||
|
|
|
@ -120,4 +120,6 @@
|
||||||
#define EOWNERDEAD 136 /* Owner died */
|
#define EOWNERDEAD 136 /* Owner died */
|
||||||
#define ENOTRECOVERABLE 137 /* State not recoverable */
|
#define ENOTRECOVERABLE 137 /* State not recoverable */
|
||||||
|
|
||||||
|
#define ERFKILL 138 /* Operation not possible due to RF-kill */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -536,7 +536,7 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void restart_syscall(struct pt_regs *regs)
|
static inline void setup_syscall_restart(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
regs->ARM_r0 = regs->ARM_ORIG_r0;
|
regs->ARM_r0 = regs->ARM_ORIG_r0;
|
||||||
regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
|
regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
|
||||||
|
@ -571,7 +571,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
|
||||||
}
|
}
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case -ERESTARTNOINTR:
|
case -ERESTARTNOINTR:
|
||||||
restart_syscall(regs);
|
setup_syscall_restart(regs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,7 +695,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
|
||||||
if (regs->ARM_r0 == -ERESTARTNOHAND ||
|
if (regs->ARM_r0 == -ERESTARTNOHAND ||
|
||||||
regs->ARM_r0 == -ERESTARTSYS ||
|
regs->ARM_r0 == -ERESTARTSYS ||
|
||||||
regs->ARM_r0 == -ERESTARTNOINTR) {
|
regs->ARM_r0 == -ERESTARTNOINTR) {
|
||||||
restart_syscall(regs);
|
setup_syscall_restart(regs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
single_step_set(current);
|
single_step_set(current);
|
||||||
|
|
|
@ -35,21 +35,25 @@ static void tosa_bt_off(struct tosa_bt_data *data)
|
||||||
gpio_set_value(data->gpio_reset, 0);
|
gpio_set_value(data->gpio_reset, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tosa_bt_toggle_radio(void *data, enum rfkill_state state)
|
static int tosa_bt_set_block(void *data, bool blocked)
|
||||||
{
|
{
|
||||||
pr_info("BT_RADIO going: %s\n",
|
pr_info("BT_RADIO going: %s\n", blocked ? "off" : "on");
|
||||||
state == RFKILL_STATE_ON ? "on" : "off");
|
|
||||||
|
|
||||||
if (state == RFKILL_STATE_ON) {
|
if (!blocked) {
|
||||||
pr_info("TOSA_BT: going ON\n");
|
pr_info("TOSA_BT: going ON\n");
|
||||||
tosa_bt_on(data);
|
tosa_bt_on(data);
|
||||||
} else {
|
} else {
|
||||||
pr_info("TOSA_BT: going OFF\n");
|
pr_info("TOSA_BT: going OFF\n");
|
||||||
tosa_bt_off(data);
|
tosa_bt_off(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct rfkill_ops tosa_bt_rfkill_ops = {
|
||||||
|
.set_block = tosa_bt_set_block,
|
||||||
|
};
|
||||||
|
|
||||||
static int tosa_bt_probe(struct platform_device *dev)
|
static int tosa_bt_probe(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -70,18 +74,14 @@ static int tosa_bt_probe(struct platform_device *dev)
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err_pwr_dir;
|
goto err_pwr_dir;
|
||||||
|
|
||||||
rfk = rfkill_allocate(&dev->dev, RFKILL_TYPE_BLUETOOTH);
|
rfk = rfkill_alloc("tosa-bt", &dev->dev, RFKILL_TYPE_BLUETOOTH,
|
||||||
|
&tosa_bt_rfkill_ops, data);
|
||||||
if (!rfk) {
|
if (!rfk) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto err_rfk_alloc;
|
goto err_rfk_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rfk->name = "tosa-bt";
|
rfkill_set_led_trigger_name(rfk, "tosa-bt");
|
||||||
rfk->toggle_radio = tosa_bt_toggle_radio;
|
|
||||||
rfk->data = data;
|
|
||||||
#ifdef CONFIG_RFKILL_LEDS
|
|
||||||
rfk->led_trigger.name = "tosa-bt";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rc = rfkill_register(rfk);
|
rc = rfkill_register(rfk);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -92,9 +92,7 @@ static int tosa_bt_probe(struct platform_device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_rfkill:
|
err_rfkill:
|
||||||
if (rfk)
|
rfkill_destroy(rfk);
|
||||||
rfkill_free(rfk);
|
|
||||||
rfk = NULL;
|
|
||||||
err_rfk_alloc:
|
err_rfk_alloc:
|
||||||
tosa_bt_off(data);
|
tosa_bt_off(data);
|
||||||
err_pwr_dir:
|
err_pwr_dir:
|
||||||
|
@ -113,8 +111,10 @@ static int __devexit tosa_bt_remove(struct platform_device *dev)
|
||||||
|
|
||||||
platform_set_drvdata(dev, NULL);
|
platform_set_drvdata(dev, NULL);
|
||||||
|
|
||||||
if (rfk)
|
if (rfk) {
|
||||||
rfkill_unregister(rfk);
|
rfkill_unregister(rfk);
|
||||||
|
rfkill_destroy(rfk);
|
||||||
|
}
|
||||||
rfk = NULL;
|
rfk = NULL;
|
||||||
|
|
||||||
tosa_bt_off(data);
|
tosa_bt_off(data);
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/pda_power.h>
|
#include <linux/pda_power.h>
|
||||||
#include <linux/rfkill.h>
|
|
||||||
#include <linux/spi/spi.h>
|
#include <linux/spi/spi.h>
|
||||||
|
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
|
|
|
@ -212,7 +212,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void restart_syscall(struct pt_regs *regs)
|
static inline void setup_syscall_restart(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
if (regs->r12 == -ERESTART_RESTARTBLOCK)
|
if (regs->r12 == -ERESTART_RESTARTBLOCK)
|
||||||
regs->r8 = __NR_restart_syscall;
|
regs->r8 = __NR_restart_syscall;
|
||||||
|
@ -296,7 +296,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int syscall)
|
||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case -ERESTARTNOINTR:
|
case -ERESTARTNOINTR:
|
||||||
restart_syscall(regs);
|
setup_syscall_restart(regs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,8 @@
|
||||||
#define EOWNERDEAD 165 /* Owner died */
|
#define EOWNERDEAD 165 /* Owner died */
|
||||||
#define ENOTRECOVERABLE 166 /* State not recoverable */
|
#define ENOTRECOVERABLE 166 /* State not recoverable */
|
||||||
|
|
||||||
|
#define ERFKILL 167 /* Operation not possible due to RF-kill */
|
||||||
|
|
||||||
#define EDQUOT 1133 /* Quota exceeded */
|
#define EDQUOT 1133 /* Quota exceeded */
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
|
@ -120,5 +120,6 @@
|
||||||
#define EOWNERDEAD 254 /* Owner died */
|
#define EOWNERDEAD 254 /* Owner died */
|
||||||
#define ENOTRECOVERABLE 255 /* State not recoverable */
|
#define ENOTRECOVERABLE 255 /* State not recoverable */
|
||||||
|
|
||||||
|
#define ERFKILL 256 /* Operation not possible due to RF-kill */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -675,6 +675,8 @@ struct ucc_slow_pram {
|
||||||
#define UCC_GETH_UPSMR_RMM 0x00001000
|
#define UCC_GETH_UPSMR_RMM 0x00001000
|
||||||
#define UCC_GETH_UPSMR_CAM 0x00000400
|
#define UCC_GETH_UPSMR_CAM 0x00000400
|
||||||
#define UCC_GETH_UPSMR_BRO 0x00000200
|
#define UCC_GETH_UPSMR_BRO 0x00000200
|
||||||
|
#define UCC_GETH_UPSMR_SMM 0x00000080
|
||||||
|
#define UCC_GETH_UPSMR_SGMM 0x00000020
|
||||||
|
|
||||||
/* UCC Transmit On Demand Register (UTODR) */
|
/* UCC Transmit On Demand Register (UTODR) */
|
||||||
#define UCC_SLOW_TOD 0x8000
|
#define UCC_SLOW_TOD 0x8000
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/fsl_devices.h>
|
#include <linux/fsl_devices.h>
|
||||||
#include <linux/mdio-bitbang.h>
|
#include <linux/mdio-bitbang.h>
|
||||||
|
#include <linux/of_mdio.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
@ -115,7 +116,7 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev,
|
||||||
struct mii_bus *bus;
|
struct mii_bus *bus;
|
||||||
struct resource res;
|
struct resource res;
|
||||||
struct device_node *node;
|
struct device_node *node;
|
||||||
int ret, i;
|
int ret;
|
||||||
|
|
||||||
node = of_get_parent(ofdev->node);
|
node = of_get_parent(ofdev->node);
|
||||||
of_node_put(node);
|
of_node_put(node);
|
||||||
|
@ -130,17 +131,13 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev,
|
||||||
if (!bus)
|
if (!bus)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
bus->phy_mask = 0;
|
|
||||||
bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
|
||||||
|
|
||||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
|
||||||
bus->irq[i] = -1;
|
|
||||||
|
|
||||||
bus->name = "ep8248e-mdio-bitbang";
|
bus->name = "ep8248e-mdio-bitbang";
|
||||||
bus->parent = &ofdev->dev;
|
bus->parent = &ofdev->dev;
|
||||||
snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
|
snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
|
||||||
|
|
||||||
return mdiobus_register(bus);
|
return of_mdiobus_register(bus, ofdev->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ep8248e_mdio_remove(struct of_device *ofdev)
|
static int ep8248e_mdio_remove(struct of_device *ofdev)
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/phy.h>
|
#include <linux/phy.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/of_mdio.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
|
|
||||||
#define DELAY 1
|
#define DELAY 1
|
||||||
|
@ -39,6 +39,7 @@ static void __iomem *gpio_regs;
|
||||||
struct gpio_priv {
|
struct gpio_priv {
|
||||||
int mdc_pin;
|
int mdc_pin;
|
||||||
int mdio_pin;
|
int mdio_pin;
|
||||||
|
int mdio_irqs[PHY_MAX_ADDR];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MDC_PIN(bus) (((struct gpio_priv *)bus->priv)->mdc_pin)
|
#define MDC_PIN(bus) (((struct gpio_priv *)bus->priv)->mdc_pin)
|
||||||
|
@ -218,12 +219,11 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
|
||||||
const struct of_device_id *match)
|
const struct of_device_id *match)
|
||||||
{
|
{
|
||||||
struct device *dev = &ofdev->dev;
|
struct device *dev = &ofdev->dev;
|
||||||
struct device_node *phy_dn, *np = ofdev->node;
|
struct device_node *np = ofdev->node;
|
||||||
struct mii_bus *new_bus;
|
struct mii_bus *new_bus;
|
||||||
struct gpio_priv *priv;
|
struct gpio_priv *priv;
|
||||||
const unsigned int *prop;
|
const unsigned int *prop;
|
||||||
int err;
|
int err;
|
||||||
int i;
|
|
||||||
|
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL);
|
priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL);
|
||||||
|
@ -244,27 +244,7 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
|
||||||
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", *prop);
|
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", *prop);
|
||||||
new_bus->priv = priv;
|
new_bus->priv = priv;
|
||||||
|
|
||||||
new_bus->phy_mask = 0;
|
new_bus->irq = priv->mdio_irqs;
|
||||||
|
|
||||||
new_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
|
|
||||||
|
|
||||||
if (!new_bus->irq)
|
|
||||||
goto out_free_bus;
|
|
||||||
|
|
||||||
for (i = 0; i < PHY_MAX_ADDR; i++)
|
|
||||||
new_bus->irq[i] = NO_IRQ;
|
|
||||||
|
|
||||||
for (phy_dn = of_get_next_child(np, NULL);
|
|
||||||
phy_dn != NULL;
|
|
||||||
phy_dn = of_get_next_child(np, phy_dn)) {
|
|
||||||
const unsigned int *ip, *regp;
|
|
||||||
|
|
||||||
ip = of_get_property(phy_dn, "interrupts", NULL);
|
|
||||||
regp = of_get_property(phy_dn, "reg", NULL);
|
|
||||||
if (!ip || !regp || *regp >= PHY_MAX_ADDR)
|
|
||||||
continue;
|
|
||||||
new_bus->irq[*regp] = irq_create_mapping(NULL, *ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
prop = of_get_property(np, "mdc-pin", NULL);
|
prop = of_get_property(np, "mdc-pin", NULL);
|
||||||
priv->mdc_pin = *prop;
|
priv->mdc_pin = *prop;
|
||||||
|
@ -275,7 +255,7 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
|
||||||
new_bus->parent = dev;
|
new_bus->parent = dev;
|
||||||
dev_set_drvdata(dev, new_bus);
|
dev_set_drvdata(dev, new_bus);
|
||||||
|
|
||||||
err = mdiobus_register(new_bus);
|
err = of_mdiobus_register(new_bus, np);
|
||||||
|
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
printk(KERN_ERR "%s: Cannot register as MDIO bus, err %d\n",
|
printk(KERN_ERR "%s: Cannot register as MDIO bus, err %d\n",
|
||||||
|
@ -286,8 +266,6 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_free_irq:
|
out_free_irq:
|
||||||
kfree(new_bus->irq);
|
|
||||||
out_free_bus:
|
|
||||||
kfree(new_bus);
|
kfree(new_bus);
|
||||||
out_free_priv:
|
out_free_priv:
|
||||||
kfree(priv);
|
kfree(priv);
|
||||||
|
|
|
@ -110,4 +110,6 @@
|
||||||
#define EOWNERDEAD 132 /* Owner died */
|
#define EOWNERDEAD 132 /* Owner died */
|
||||||
#define ENOTRECOVERABLE 133 /* State not recoverable */
|
#define ENOTRECOVERABLE 133 /* State not recoverable */
|
||||||
|
|
||||||
|
#define ERFKILL 134 /* Operation not possible due to RF-kill */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -107,3 +107,4 @@ obj-$(CONFIG_SSB) += ssb/
|
||||||
obj-$(CONFIG_VIRTIO) += virtio/
|
obj-$(CONFIG_VIRTIO) += virtio/
|
||||||
obj-$(CONFIG_STAGING) += staging/
|
obj-$(CONFIG_STAGING) += staging/
|
||||||
obj-y += platform/
|
obj-y += platform/
|
||||||
|
obj-y += ieee802154/
|
||||||
|
|
|
@ -34,13 +34,6 @@ new_skb(ulong len)
|
||||||
skb_reset_mac_header(skb);
|
skb_reset_mac_header(skb);
|
||||||
skb_reset_network_header(skb);
|
skb_reset_network_header(skb);
|
||||||
skb->protocol = __constant_htons(ETH_P_AOE);
|
skb->protocol = __constant_htons(ETH_P_AOE);
|
||||||
skb->priority = 0;
|
|
||||||
skb->next = skb->prev = NULL;
|
|
||||||
|
|
||||||
/* tell the network layer not to perform IP checksums
|
|
||||||
* or to get the NIC to do it
|
|
||||||
*/
|
|
||||||
skb->ip_summed = CHECKSUM_NONE;
|
|
||||||
}
|
}
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
|
|
|
@ -415,6 +415,8 @@ static int dtl1_hci_send_frame(struct sk_buff *skb)
|
||||||
hdev->stat.sco_tx++;
|
hdev->stat.sco_tx++;
|
||||||
nsh.type = 0x83;
|
nsh.type = 0x83;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return -EILSEQ;
|
||||||
};
|
};
|
||||||
|
|
||||||
nsh.zero = 0;
|
nsh.zero = 0;
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#include <net/bluetooth/bluetooth.h>
|
#include <net/bluetooth/bluetooth.h>
|
||||||
#include <net/bluetooth/hci_core.h>
|
#include <net/bluetooth/hci_core.h>
|
||||||
|
|
||||||
#define VERSION "1.2"
|
#define VERSION "1.3"
|
||||||
|
|
||||||
static int minor = MISC_DYNAMIC_MINOR;
|
static int minor = MISC_DYNAMIC_MINOR;
|
||||||
|
|
||||||
|
@ -51,14 +51,8 @@ struct vhci_data {
|
||||||
|
|
||||||
wait_queue_head_t read_wait;
|
wait_queue_head_t read_wait;
|
||||||
struct sk_buff_head readq;
|
struct sk_buff_head readq;
|
||||||
|
|
||||||
struct fasync_struct *fasync;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define VHCI_FASYNC 0x0010
|
|
||||||
|
|
||||||
static struct miscdevice vhci_miscdev;
|
|
||||||
|
|
||||||
static int vhci_open_dev(struct hci_dev *hdev)
|
static int vhci_open_dev(struct hci_dev *hdev)
|
||||||
{
|
{
|
||||||
set_bit(HCI_RUNNING, &hdev->flags);
|
set_bit(HCI_RUNNING, &hdev->flags);
|
||||||
|
@ -105,9 +99,6 @@ static int vhci_send_frame(struct sk_buff *skb)
|
||||||
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
|
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
|
||||||
skb_queue_tail(&data->readq, skb);
|
skb_queue_tail(&data->readq, skb);
|
||||||
|
|
||||||
if (data->flags & VHCI_FASYNC)
|
|
||||||
kill_fasync(&data->fasync, SIGIO, POLL_IN);
|
|
||||||
|
|
||||||
wake_up_interruptible(&data->read_wait);
|
wake_up_interruptible(&data->read_wait);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -179,41 +170,31 @@ static inline ssize_t vhci_put_user(struct vhci_data *data,
|
||||||
static ssize_t vhci_read(struct file *file,
|
static ssize_t vhci_read(struct file *file,
|
||||||
char __user *buf, size_t count, loff_t *pos)
|
char __user *buf, size_t count, loff_t *pos)
|
||||||
{
|
{
|
||||||
DECLARE_WAITQUEUE(wait, current);
|
|
||||||
struct vhci_data *data = file->private_data;
|
struct vhci_data *data = file->private_data;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
ssize_t ret = 0;
|
ssize_t ret = 0;
|
||||||
|
|
||||||
add_wait_queue(&data->read_wait, &wait);
|
|
||||||
while (count) {
|
while (count) {
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
|
||||||
|
|
||||||
skb = skb_dequeue(&data->readq);
|
skb = skb_dequeue(&data->readq);
|
||||||
if (!skb) {
|
if (skb) {
|
||||||
if (file->f_flags & O_NONBLOCK) {
|
ret = vhci_put_user(data, skb, buf, count);
|
||||||
ret = -EAGAIN;
|
if (ret < 0)
|
||||||
break;
|
skb_queue_head(&data->readq, skb);
|
||||||
}
|
else
|
||||||
|
kfree_skb(skb);
|
||||||
if (signal_pending(current)) {
|
break;
|
||||||
ret = -ERESTARTSYS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
schedule();
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (access_ok(VERIFY_WRITE, buf, count))
|
if (file->f_flags & O_NONBLOCK) {
|
||||||
ret = vhci_put_user(data, skb, buf, count);
|
ret = -EAGAIN;
|
||||||
else
|
break;
|
||||||
ret = -EFAULT;
|
}
|
||||||
|
|
||||||
kfree_skb(skb);
|
ret = wait_event_interruptible(data->read_wait,
|
||||||
break;
|
!skb_queue_empty(&data->readq));
|
||||||
|
if (ret < 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
set_current_state(TASK_RUNNING);
|
|
||||||
remove_wait_queue(&data->read_wait, &wait);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -223,9 +204,6 @@ static ssize_t vhci_write(struct file *file,
|
||||||
{
|
{
|
||||||
struct vhci_data *data = file->private_data;
|
struct vhci_data *data = file->private_data;
|
||||||
|
|
||||||
if (!access_ok(VERIFY_READ, buf, count))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
return vhci_get_user(data, buf, count);
|
return vhci_get_user(data, buf, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,11 +237,9 @@ static int vhci_open(struct inode *inode, struct file *file)
|
||||||
skb_queue_head_init(&data->readq);
|
skb_queue_head_init(&data->readq);
|
||||||
init_waitqueue_head(&data->read_wait);
|
init_waitqueue_head(&data->read_wait);
|
||||||
|
|
||||||
lock_kernel();
|
|
||||||
hdev = hci_alloc_dev();
|
hdev = hci_alloc_dev();
|
||||||
if (!hdev) {
|
if (!hdev) {
|
||||||
kfree(data);
|
kfree(data);
|
||||||
unlock_kernel();
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,12 +260,10 @@ static int vhci_open(struct inode *inode, struct file *file)
|
||||||
BT_ERR("Can't register HCI device");
|
BT_ERR("Can't register HCI device");
|
||||||
kfree(data);
|
kfree(data);
|
||||||
hci_free_dev(hdev);
|
hci_free_dev(hdev);
|
||||||
unlock_kernel();
|
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
file->private_data = data;
|
file->private_data = data;
|
||||||
unlock_kernel();
|
|
||||||
|
|
||||||
return nonseekable_open(inode, file);
|
return nonseekable_open(inode, file);
|
||||||
}
|
}
|
||||||
|
@ -310,48 +284,25 @@ static int vhci_release(struct inode *inode, struct file *file)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vhci_fasync(int fd, struct file *file, int on)
|
|
||||||
{
|
|
||||||
struct vhci_data *data = file->private_data;
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
lock_kernel();
|
|
||||||
err = fasync_helper(fd, file, on, &data->fasync);
|
|
||||||
if (err < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (on)
|
|
||||||
data->flags |= VHCI_FASYNC;
|
|
||||||
else
|
|
||||||
data->flags &= ~VHCI_FASYNC;
|
|
||||||
|
|
||||||
out:
|
|
||||||
unlock_kernel();
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations vhci_fops = {
|
static const struct file_operations vhci_fops = {
|
||||||
.owner = THIS_MODULE,
|
|
||||||
.read = vhci_read,
|
.read = vhci_read,
|
||||||
.write = vhci_write,
|
.write = vhci_write,
|
||||||
.poll = vhci_poll,
|
.poll = vhci_poll,
|
||||||
.ioctl = vhci_ioctl,
|
.ioctl = vhci_ioctl,
|
||||||
.open = vhci_open,
|
.open = vhci_open,
|
||||||
.release = vhci_release,
|
.release = vhci_release,
|
||||||
.fasync = vhci_fasync,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct miscdevice vhci_miscdev= {
|
static struct miscdevice vhci_miscdev= {
|
||||||
.name = "vhci",
|
.name = "vhci",
|
||||||
.fops = &vhci_fops,
|
.fops = &vhci_fops,
|
||||||
|
.minor = MISC_DYNAMIC_MINOR,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init vhci_init(void)
|
static int __init vhci_init(void)
|
||||||
{
|
{
|
||||||
BT_INFO("Virtual HCI driver ver %s", VERSION);
|
BT_INFO("Virtual HCI driver ver %s", VERSION);
|
||||||
|
|
||||||
vhci_miscdev.minor = minor;
|
|
||||||
|
|
||||||
if (misc_register(&vhci_miscdev) < 0) {
|
if (misc_register(&vhci_miscdev) < 0) {
|
||||||
BT_ERR("Can't register misc device with minor %d", minor);
|
BT_ERR("Can't register misc device with minor %d", minor);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -369,9 +320,6 @@ static void __exit vhci_exit(void)
|
||||||
module_init(vhci_init);
|
module_init(vhci_init);
|
||||||
module_exit(vhci_exit);
|
module_exit(vhci_exit);
|
||||||
|
|
||||||
module_param(minor, int, 0444);
|
|
||||||
MODULE_PARM_DESC(minor, "Miscellaneous minor device number");
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
|
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
|
||||||
MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
|
MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
|
||||||
MODULE_VERSION(VERSION);
|
MODULE_VERSION(VERSION);
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
menuconfig IEEE802154_DRIVERS
|
||||||
|
tristate "IEEE 802.15.4 drivers"
|
||||||
|
depends on NETDEVICES && IEEE802154
|
||||||
|
default y
|
||||||
|
---help---
|
||||||
|
Say Y here to get to see options for IEEE 802.15.4 Low-Rate
|
||||||
|
Wireless Personal Area Network device drivers. This option alone
|
||||||
|
does not add any kernel code.
|
||||||
|
|
||||||
|
If you say N, all options in this submenu will be skipped and
|
||||||
|
disabled.
|
||||||
|
|
||||||
|
config IEEE802154_FAKEHARD
|
||||||
|
tristate "Fake LR-WPAN driver with several interconnected devices"
|
||||||
|
depends on IEEE802154_DRIVERS
|
||||||
|
---help---
|
||||||
|
Say Y here to enable the fake driver that serves as an example
|
||||||
|
of HardMAC device driver.
|
||||||
|
|
||||||
|
This driver can also be built as a module. To do so say M here.
|
||||||
|
The module will be called 'fakehard'.
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o
|
||||||
|
|
||||||
|
EXTRA_CFLAGS += -DDEBUG -DCONFIG_FFD
|
|
@ -0,0 +1,270 @@
|
||||||
|
/*
|
||||||
|
* Sample driver for HardMAC IEEE 802.15.4 devices
|
||||||
|
*
|
||||||
|
* Copyright (C) 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 <dmitry.baryshkov@siemens.com>
|
||||||
|
*/
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/if_arp.h>
|
||||||
|
|
||||||
|
#include <net/ieee802154/af_ieee802154.h>
|
||||||
|
#include <net/ieee802154/netdevice.h>
|
||||||
|
#include <net/ieee802154/mac_def.h>
|
||||||
|
#include <net/ieee802154/nl802154.h>
|
||||||
|
|
||||||
|
static u16 fake_get_pan_id(struct net_device *dev)
|
||||||
|
{
|
||||||
|
BUG_ON(dev->type != ARPHRD_IEEE802154);
|
||||||
|
|
||||||
|
return 0xeba1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u16 fake_get_short_addr(struct net_device *dev)
|
||||||
|
{
|
||||||
|
BUG_ON(dev->type != ARPHRD_IEEE802154);
|
||||||
|
|
||||||
|
return 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 fake_get_dsn(struct net_device *dev)
|
||||||
|
{
|
||||||
|
BUG_ON(dev->type != ARPHRD_IEEE802154);
|
||||||
|
|
||||||
|
return 0x00; /* DSN are implemented in HW, so return just 0 */
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 fake_get_bsn(struct net_device *dev)
|
||||||
|
{
|
||||||
|
BUG_ON(dev->type != ARPHRD_IEEE802154);
|
||||||
|
|
||||||
|
return 0x00; /* BSN are implemented in HW, so return just 0 */
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fake_assoc_req(struct net_device *dev,
|
||||||
|
struct ieee802154_addr *addr, u8 channel, u8 cap)
|
||||||
|
{
|
||||||
|
/* We simply emulate it here */
|
||||||
|
return ieee802154_nl_assoc_confirm(dev, fake_get_short_addr(dev),
|
||||||
|
IEEE802154_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fake_assoc_resp(struct net_device *dev,
|
||||||
|
struct ieee802154_addr *addr, u16 short_addr, u8 status)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fake_disassoc_req(struct net_device *dev,
|
||||||
|
struct ieee802154_addr *addr, u8 reason)
|
||||||
|
{
|
||||||
|
return ieee802154_nl_disassoc_confirm(dev, IEEE802154_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr,
|
||||||
|
u8 channel,
|
||||||
|
u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx,
|
||||||
|
u8 coord_realign)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fake_scan_req(struct net_device *dev, u8 type, u32 channels,
|
||||||
|
u8 duration)
|
||||||
|
{
|
||||||
|
u8 edl[27] = {};
|
||||||
|
return ieee802154_nl_scan_confirm(dev, IEEE802154_SUCCESS, type,
|
||||||
|
channels,
|
||||||
|
type == IEEE802154_MAC_SCAN_ED ? edl : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ieee802154_mlme_ops fake_mlme = {
|
||||||
|
.assoc_req = fake_assoc_req,
|
||||||
|
.assoc_resp = fake_assoc_resp,
|
||||||
|
.disassoc_req = fake_disassoc_req,
|
||||||
|
.start_req = fake_start_req,
|
||||||
|
.scan_req = fake_scan_req,
|
||||||
|
|
||||||
|
.get_pan_id = fake_get_pan_id,
|
||||||
|
.get_short_addr = fake_get_short_addr,
|
||||||
|
.get_dsn = fake_get_dsn,
|
||||||
|
.get_bsn = fake_get_bsn,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ieee802154_fake_open(struct net_device *dev)
|
||||||
|
{
|
||||||
|
netif_start_queue(dev);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ieee802154_fake_close(struct net_device *dev)
|
||||||
|
{
|
||||||
|
netif_stop_queue(dev);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ieee802154_fake_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
|
{
|
||||||
|
skb->iif = dev->ifindex;
|
||||||
|
skb->dev = dev;
|
||||||
|
dev->stats.tx_packets++;
|
||||||
|
dev->stats.tx_bytes += skb->len;
|
||||||
|
|
||||||
|
dev->trans_start = jiffies;
|
||||||
|
|
||||||
|
/* FIXME: do hardware work here ... */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ieee802154_fake_ioctl(struct net_device *dev, struct ifreq *ifr,
|
||||||
|
int cmd)
|
||||||
|
{
|
||||||
|
struct sockaddr_ieee802154 *sa =
|
||||||
|
(struct sockaddr_ieee802154 *)&ifr->ifr_addr;
|
||||||
|
u16 pan_id, short_addr;
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case SIOCGIFADDR:
|
||||||
|
/* FIXME: fixed here, get from device IRL */
|
||||||
|
pan_id = fake_get_pan_id(dev);
|
||||||
|
short_addr = fake_get_short_addr(dev);
|
||||||
|
if (pan_id == IEEE802154_PANID_BROADCAST ||
|
||||||
|
short_addr == IEEE802154_ADDR_BROADCAST)
|
||||||
|
return -EADDRNOTAVAIL;
|
||||||
|
|
||||||
|
sa->family = AF_IEEE802154;
|
||||||
|
sa->addr.addr_type = IEEE802154_ADDR_SHORT;
|
||||||
|
sa->addr.pan_id = pan_id;
|
||||||
|
sa->addr.short_addr = short_addr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -ENOIOCTLCMD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ieee802154_fake_mac_addr(struct net_device *dev, void *p)
|
||||||
|
{
|
||||||
|
return -EBUSY; /* HW address is built into the device */
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct net_device_ops fake_ops = {
|
||||||
|
.ndo_open = ieee802154_fake_open,
|
||||||
|
.ndo_stop = ieee802154_fake_close,
|
||||||
|
.ndo_start_xmit = ieee802154_fake_xmit,
|
||||||
|
.ndo_do_ioctl = ieee802154_fake_ioctl,
|
||||||
|
.ndo_set_mac_address = ieee802154_fake_mac_addr,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void ieee802154_fake_setup(struct net_device *dev)
|
||||||
|
{
|
||||||
|
dev->addr_len = IEEE802154_ADDR_LEN;
|
||||||
|
memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN);
|
||||||
|
dev->features = NETIF_F_NO_CSUM;
|
||||||
|
dev->needed_tailroom = 2; /* FCS */
|
||||||
|
dev->mtu = 127;
|
||||||
|
dev->tx_queue_len = 10;
|
||||||
|
dev->type = ARPHRD_IEEE802154;
|
||||||
|
dev->flags = IFF_NOARP | IFF_BROADCAST;
|
||||||
|
dev->watchdog_timeo = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int __devinit ieee802154fake_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct net_device *dev =
|
||||||
|
alloc_netdev(0, "hardwpan%d", ieee802154_fake_setup);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!dev)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
memcpy(dev->dev_addr, "\xba\xbe\xca\xfe\xde\xad\xbe\xef",
|
||||||
|
dev->addr_len);
|
||||||
|
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
|
||||||
|
|
||||||
|
dev->netdev_ops = &fake_ops;
|
||||||
|
dev->ml_priv = &fake_mlme;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the name is a format string the caller wants us to do a
|
||||||
|
* name allocation.
|
||||||
|
*/
|
||||||
|
if (strchr(dev->name, '%')) {
|
||||||
|
err = dev_alloc_name(dev, dev->name);
|
||||||
|
if (err < 0)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
SET_NETDEV_DEV(dev, &pdev->dev);
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, dev);
|
||||||
|
|
||||||
|
err = register_netdev(dev);
|
||||||
|
if (err < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
|
||||||
|
dev_info(&pdev->dev, "Added ieee802154 HardMAC hardware\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
unregister_netdev(dev);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __devexit ieee802154fake_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct net_device *dev = platform_get_drvdata(pdev);
|
||||||
|
unregister_netdev(dev);
|
||||||
|
free_netdev(dev);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct platform_device *ieee802154fake_dev;
|
||||||
|
|
||||||
|
static struct platform_driver ieee802154fake_driver = {
|
||||||
|
.probe = ieee802154fake_probe,
|
||||||
|
.remove = __devexit_p(ieee802154fake_remove),
|
||||||
|
.driver = {
|
||||||
|
.name = "ieee802154hardmac",
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static __init int fake_init(void)
|
||||||
|
{
|
||||||
|
ieee802154fake_dev = platform_device_register_simple(
|
||||||
|
"ieee802154hardmac", -1, NULL, 0);
|
||||||
|
return platform_driver_register(&ieee802154fake_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __exit void fake_exit(void)
|
||||||
|
{
|
||||||
|
platform_driver_unregister(&ieee802154fake_driver);
|
||||||
|
platform_device_unregister(ieee802154fake_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(fake_init);
|
||||||
|
module_exit(fake_exit);
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -1394,8 +1394,8 @@ void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb,
|
||||||
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
||||||
int e = skb_queue_empty(&priv->cm.skb_queue);
|
int e = skb_queue_empty(&priv->cm.skb_queue);
|
||||||
|
|
||||||
if (skb->dst)
|
if (skb_dst(skb))
|
||||||
skb->dst->ops->update_pmtu(skb->dst, mtu);
|
skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
|
||||||
|
|
||||||
skb_queue_tail(&priv->cm.skb_queue, skb);
|
skb_queue_tail(&priv->cm.skb_queue, skb);
|
||||||
if (e)
|
if (e)
|
||||||
|
@ -1455,13 +1455,15 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
|
||||||
struct net_device *dev = to_net_dev(d);
|
struct net_device *dev = to_net_dev(d);
|
||||||
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
||||||
|
|
||||||
|
if (!rtnl_trylock())
|
||||||
|
return restart_syscall();
|
||||||
|
|
||||||
/* flush paths if we switch modes so that connections are restarted */
|
/* flush paths if we switch modes so that connections are restarted */
|
||||||
if (IPOIB_CM_SUPPORTED(dev->dev_addr) && !strcmp(buf, "connected\n")) {
|
if (IPOIB_CM_SUPPORTED(dev->dev_addr) && !strcmp(buf, "connected\n")) {
|
||||||
set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
|
set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
|
||||||
ipoib_warn(priv, "enabling connected mode "
|
ipoib_warn(priv, "enabling connected mode "
|
||||||
"will cause multicast packet drops\n");
|
"will cause multicast packet drops\n");
|
||||||
|
|
||||||
rtnl_lock();
|
|
||||||
dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO);
|
dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO);
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
|
priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
|
||||||
|
@ -1473,7 +1475,6 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
|
||||||
if (!strcmp(buf, "datagram\n")) {
|
if (!strcmp(buf, "datagram\n")) {
|
||||||
clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
|
clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
|
||||||
|
|
||||||
rtnl_lock();
|
|
||||||
if (test_bit(IPOIB_FLAG_CSUM, &priv->flags)) {
|
if (test_bit(IPOIB_FLAG_CSUM, &priv->flags)) {
|
||||||
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
|
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
|
||||||
if (priv->hca_caps & IB_DEVICE_UD_TSO)
|
if (priv->hca_caps & IB_DEVICE_UD_TSO)
|
||||||
|
@ -1485,6 +1486,7 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
rtnl_unlock();
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -561,7 +561,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
|
||||||
struct ipoib_neigh *neigh;
|
struct ipoib_neigh *neigh;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
neigh = ipoib_neigh_alloc(skb->dst->neighbour, skb->dev);
|
neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour, skb->dev);
|
||||||
if (!neigh) {
|
if (!neigh) {
|
||||||
++dev->stats.tx_dropped;
|
++dev->stats.tx_dropped;
|
||||||
dev_kfree_skb_any(skb);
|
dev_kfree_skb_any(skb);
|
||||||
|
@ -570,9 +570,9 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
|
||||||
|
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
|
|
||||||
path = __path_find(dev, skb->dst->neighbour->ha + 4);
|
path = __path_find(dev, skb_dst(skb)->neighbour->ha + 4);
|
||||||
if (!path) {
|
if (!path) {
|
||||||
path = path_rec_create(dev, skb->dst->neighbour->ha + 4);
|
path = path_rec_create(dev, skb_dst(skb)->neighbour->ha + 4);
|
||||||
if (!path)
|
if (!path)
|
||||||
goto err_path;
|
goto err_path;
|
||||||
|
|
||||||
|
@ -605,7 +605,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
|
||||||
goto err_drop;
|
goto err_drop;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb->dst->neighbour->ha));
|
ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha));
|
||||||
} else {
|
} else {
|
||||||
neigh->ah = NULL;
|
neigh->ah = NULL;
|
||||||
|
|
||||||
|
@ -635,15 +635,15 @@ static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
|
||||||
struct ipoib_dev_priv *priv = netdev_priv(skb->dev);
|
struct ipoib_dev_priv *priv = netdev_priv(skb->dev);
|
||||||
|
|
||||||
/* Look up path record for unicasts */
|
/* Look up path record for unicasts */
|
||||||
if (skb->dst->neighbour->ha[4] != 0xff) {
|
if (skb_dst(skb)->neighbour->ha[4] != 0xff) {
|
||||||
neigh_add_path(skb, dev);
|
neigh_add_path(skb, dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add in the P_Key for multicasts */
|
/* Add in the P_Key for multicasts */
|
||||||
skb->dst->neighbour->ha[8] = (priv->pkey >> 8) & 0xff;
|
skb_dst(skb)->neighbour->ha[8] = (priv->pkey >> 8) & 0xff;
|
||||||
skb->dst->neighbour->ha[9] = priv->pkey & 0xff;
|
skb_dst(skb)->neighbour->ha[9] = priv->pkey & 0xff;
|
||||||
ipoib_mcast_send(dev, skb->dst->neighbour->ha + 4, skb);
|
ipoib_mcast_send(dev, skb_dst(skb)->neighbour->ha + 4, skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
|
static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
|
||||||
|
@ -708,16 +708,16 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
struct ipoib_neigh *neigh;
|
struct ipoib_neigh *neigh;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (likely(skb->dst && skb->dst->neighbour)) {
|
if (likely(skb_dst(skb) && skb_dst(skb)->neighbour)) {
|
||||||
if (unlikely(!*to_ipoib_neigh(skb->dst->neighbour))) {
|
if (unlikely(!*to_ipoib_neigh(skb_dst(skb)->neighbour))) {
|
||||||
ipoib_path_lookup(skb, dev);
|
ipoib_path_lookup(skb, dev);
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
neigh = *to_ipoib_neigh(skb->dst->neighbour);
|
neigh = *to_ipoib_neigh(skb_dst(skb)->neighbour);
|
||||||
|
|
||||||
if (unlikely((memcmp(&neigh->dgid.raw,
|
if (unlikely((memcmp(&neigh->dgid.raw,
|
||||||
skb->dst->neighbour->ha + 4,
|
skb_dst(skb)->neighbour->ha + 4,
|
||||||
sizeof(union ib_gid))) ||
|
sizeof(union ib_gid))) ||
|
||||||
(neigh->dev != dev))) {
|
(neigh->dev != dev))) {
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
|
@ -743,7 +743,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
} else if (neigh->ah) {
|
} else if (neigh->ah) {
|
||||||
ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb->dst->neighbour->ha));
|
ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha));
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -772,7 +772,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
if ((be16_to_cpup((__be16 *) skb->data) != ETH_P_ARP) &&
|
if ((be16_to_cpup((__be16 *) skb->data) != ETH_P_ARP) &&
|
||||||
(be16_to_cpup((__be16 *) skb->data) != ETH_P_RARP)) {
|
(be16_to_cpup((__be16 *) skb->data) != ETH_P_RARP)) {
|
||||||
ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n",
|
ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n",
|
||||||
skb->dst ? "neigh" : "dst",
|
skb_dst(skb) ? "neigh" : "dst",
|
||||||
be16_to_cpup((__be16 *) skb->data),
|
be16_to_cpup((__be16 *) skb->data),
|
||||||
IPOIB_QPN(phdr->hwaddr),
|
IPOIB_QPN(phdr->hwaddr),
|
||||||
phdr->hwaddr + 4);
|
phdr->hwaddr + 4);
|
||||||
|
@ -817,7 +817,7 @@ static int ipoib_hard_header(struct sk_buff *skb,
|
||||||
* destination address onto the front of the skb so we can
|
* destination address onto the front of the skb so we can
|
||||||
* figure out where to send the packet later.
|
* figure out where to send the packet later.
|
||||||
*/
|
*/
|
||||||
if ((!skb->dst || !skb->dst->neighbour) && daddr) {
|
if ((!skb_dst(skb) || !skb_dst(skb)->neighbour) && daddr) {
|
||||||
struct ipoib_pseudoheader *phdr =
|
struct ipoib_pseudoheader *phdr =
|
||||||
(struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
|
(struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
|
||||||
memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);
|
memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);
|
||||||
|
@ -1053,6 +1053,7 @@ static void ipoib_setup(struct net_device *dev)
|
||||||
dev->tx_queue_len = ipoib_sendq_size * 2;
|
dev->tx_queue_len = ipoib_sendq_size * 2;
|
||||||
dev->features = (NETIF_F_VLAN_CHALLENGED |
|
dev->features = (NETIF_F_VLAN_CHALLENGED |
|
||||||
NETIF_F_HIGHDMA);
|
NETIF_F_HIGHDMA);
|
||||||
|
dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
|
||||||
|
|
||||||
memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN);
|
memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN);
|
||||||
|
|
||||||
|
|
|
@ -261,7 +261,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
|
||||||
|
|
||||||
skb->dev = dev;
|
skb->dev = dev;
|
||||||
|
|
||||||
if (!skb->dst || !skb->dst->neighbour) {
|
if (!skb_dst(skb) || !skb_dst(skb)->neighbour) {
|
||||||
/* put pseudoheader back on for next time */
|
/* put pseudoheader back on for next time */
|
||||||
skb_push(skb, sizeof (struct ipoib_pseudoheader));
|
skb_push(skb, sizeof (struct ipoib_pseudoheader));
|
||||||
}
|
}
|
||||||
|
@ -707,10 +707,10 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (mcast && mcast->ah) {
|
if (mcast && mcast->ah) {
|
||||||
if (skb->dst &&
|
if (skb_dst(skb) &&
|
||||||
skb->dst->neighbour &&
|
skb_dst(skb)->neighbour &&
|
||||||
!*to_ipoib_neigh(skb->dst->neighbour)) {
|
!*to_ipoib_neigh(skb_dst(skb)->neighbour)) {
|
||||||
struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour,
|
struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour,
|
||||||
skb->dev);
|
skb->dev);
|
||||||
|
|
||||||
if (neigh) {
|
if (neigh) {
|
||||||
|
|
|
@ -61,7 +61,8 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
|
||||||
|
|
||||||
ppriv = netdev_priv(pdev);
|
ppriv = netdev_priv(pdev);
|
||||||
|
|
||||||
rtnl_lock();
|
if (!rtnl_trylock())
|
||||||
|
return restart_syscall();
|
||||||
mutex_lock(&ppriv->vlan_mutex);
|
mutex_lock(&ppriv->vlan_mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -167,7 +168,8 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
|
||||||
|
|
||||||
ppriv = netdev_priv(pdev);
|
ppriv = netdev_priv(pdev);
|
||||||
|
|
||||||
rtnl_lock();
|
if (!rtnl_trylock())
|
||||||
|
return restart_syscall();
|
||||||
mutex_lock(&ppriv->vlan_mutex);
|
mutex_lock(&ppriv->vlan_mutex);
|
||||||
list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) {
|
list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) {
|
||||||
if (priv->pkey == pkey) {
|
if (priv->pkey == pkey) {
|
||||||
|
|
|
@ -61,4 +61,6 @@ source "drivers/isdn/hardware/Kconfig"
|
||||||
|
|
||||||
endif # ISDN_CAPI
|
endif # ISDN_CAPI
|
||||||
|
|
||||||
|
source "drivers/isdn/gigaset/Kconfig"
|
||||||
|
|
||||||
endif # ISDN
|
endif # ISDN
|
||||||
|
|
|
@ -490,7 +490,14 @@ static void pars_2_message(_cmsg * cmsg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------*/
|
/**
|
||||||
|
* capi_cmsg2message() - assemble CAPI 2.0 message from _cmsg structure
|
||||||
|
* @cmsg: _cmsg structure
|
||||||
|
* @msg: buffer for assembled message
|
||||||
|
*
|
||||||
|
* Return value: 0 for success
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned capi_cmsg2message(_cmsg * cmsg, u8 * msg)
|
unsigned capi_cmsg2message(_cmsg * cmsg, u8 * msg)
|
||||||
{
|
{
|
||||||
cmsg->m = msg;
|
cmsg->m = msg;
|
||||||
|
@ -553,7 +560,14 @@ static void message_2_pars(_cmsg * cmsg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------*/
|
/**
|
||||||
|
* capi_message2cmsg() - disassemble CAPI 2.0 message into _cmsg structure
|
||||||
|
* @cmsg: _cmsg structure
|
||||||
|
* @msg: buffer for assembled message
|
||||||
|
*
|
||||||
|
* Return value: 0 for success
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg)
|
unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg)
|
||||||
{
|
{
|
||||||
memset(cmsg, 0, sizeof(_cmsg));
|
memset(cmsg, 0, sizeof(_cmsg));
|
||||||
|
@ -573,7 +587,18 @@ unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------*/
|
/**
|
||||||
|
* capi_cmsg_header() - initialize header part of _cmsg structure
|
||||||
|
* @cmsg: _cmsg structure
|
||||||
|
* @_ApplId: ApplID field value
|
||||||
|
* @_Command: Command field value
|
||||||
|
* @_Subcommand: Subcommand field value
|
||||||
|
* @_Messagenumber: Message Number field value
|
||||||
|
* @_Controller: Controller/PLCI/NCCI field value
|
||||||
|
*
|
||||||
|
* Return value: 0 for success
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned capi_cmsg_header(_cmsg * cmsg, u16 _ApplId,
|
unsigned capi_cmsg_header(_cmsg * cmsg, u16 _ApplId,
|
||||||
u8 _Command, u8 _Subcommand,
|
u8 _Command, u8 _Subcommand,
|
||||||
u16 _Messagenumber, u32 _Controller)
|
u16 _Messagenumber, u32 _Controller)
|
||||||
|
@ -641,6 +666,14 @@ static char *mnames[] =
|
||||||
[0x4e] = "MANUFACTURER_RESP"
|
[0x4e] = "MANUFACTURER_RESP"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* capi_cmd2str() - convert CAPI 2.0 command/subcommand number to name
|
||||||
|
* @cmd: command number
|
||||||
|
* @subcmd: subcommand number
|
||||||
|
*
|
||||||
|
* Return value: static string, NULL if command/subcommand unknown
|
||||||
|
*/
|
||||||
|
|
||||||
char *capi_cmd2str(u8 cmd, u8 subcmd)
|
char *capi_cmd2str(u8 cmd, u8 subcmd)
|
||||||
{
|
{
|
||||||
return mnames[command_2_index(cmd, subcmd)];
|
return mnames[command_2_index(cmd, subcmd)];
|
||||||
|
@ -879,6 +912,11 @@ static _cdebbuf *cdebbuf_alloc(void)
|
||||||
return cdb;
|
return cdb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cdebbuf_free() - free CAPI debug buffer
|
||||||
|
* @cdb: buffer to free
|
||||||
|
*/
|
||||||
|
|
||||||
void cdebbuf_free(_cdebbuf *cdb)
|
void cdebbuf_free(_cdebbuf *cdb)
|
||||||
{
|
{
|
||||||
if (likely(cdb == g_debbuf)) {
|
if (likely(cdb == g_debbuf)) {
|
||||||
|
@ -891,6 +929,16 @@ void cdebbuf_free(_cdebbuf *cdb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* capi_message2str() - format CAPI 2.0 message for printing
|
||||||
|
* @msg: CAPI 2.0 message
|
||||||
|
*
|
||||||
|
* Allocates a CAPI debug buffer and fills it with a printable representation
|
||||||
|
* of the CAPI 2.0 message in @msg.
|
||||||
|
* Return value: allocated debug buffer, NULL on error
|
||||||
|
* The returned buffer should be freed by a call to cdebbuf_free() after use.
|
||||||
|
*/
|
||||||
|
|
||||||
_cdebbuf *capi_message2str(u8 * msg)
|
_cdebbuf *capi_message2str(u8 * msg)
|
||||||
{
|
{
|
||||||
_cdebbuf *cdb;
|
_cdebbuf *cdb;
|
||||||
|
@ -926,10 +974,23 @@ _cdebbuf *capi_message2str(u8 * msg)
|
||||||
return cdb;
|
return cdb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* capi_cmsg2str() - format _cmsg structure for printing
|
||||||
|
* @cmsg: _cmsg structure
|
||||||
|
*
|
||||||
|
* Allocates a CAPI debug buffer and fills it with a printable representation
|
||||||
|
* of the CAPI 2.0 message stored in @cmsg by a previous call to
|
||||||
|
* capi_cmsg2message() or capi_message2cmsg().
|
||||||
|
* Return value: allocated debug buffer, NULL on error
|
||||||
|
* The returned buffer should be freed by a call to cdebbuf_free() after use.
|
||||||
|
*/
|
||||||
|
|
||||||
_cdebbuf *capi_cmsg2str(_cmsg * cmsg)
|
_cdebbuf *capi_cmsg2str(_cmsg * cmsg)
|
||||||
{
|
{
|
||||||
_cdebbuf *cdb;
|
_cdebbuf *cdb;
|
||||||
|
|
||||||
|
if (!cmsg->m)
|
||||||
|
return NULL; /* no message */
|
||||||
cdb = cdebbuf_alloc();
|
cdb = cdebbuf_alloc();
|
||||||
if (!cdb)
|
if (!cdb)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -377,14 +377,14 @@ void capi_ctr_ready(struct capi_ctr * card)
|
||||||
EXPORT_SYMBOL(capi_ctr_ready);
|
EXPORT_SYMBOL(capi_ctr_ready);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* capi_ctr_reseted() - signal CAPI controller reset
|
* capi_ctr_down() - signal CAPI controller not ready
|
||||||
* @card: controller descriptor structure.
|
* @card: controller descriptor structure.
|
||||||
*
|
*
|
||||||
* Called by hardware driver to signal that the controller is down and
|
* Called by hardware driver to signal that the controller is down and
|
||||||
* unavailable for use.
|
* unavailable for use.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void capi_ctr_reseted(struct capi_ctr * card)
|
void capi_ctr_down(struct capi_ctr * card)
|
||||||
{
|
{
|
||||||
u16 appl;
|
u16 appl;
|
||||||
|
|
||||||
|
@ -413,7 +413,7 @@ void capi_ctr_reseted(struct capi_ctr * card)
|
||||||
notify_push(KCI_CONTRDOWN, card->cnr, 0, 0);
|
notify_push(KCI_CONTRDOWN, card->cnr, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(capi_ctr_reseted);
|
EXPORT_SYMBOL(capi_ctr_down);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* capi_ctr_suspend_output() - suspend controller
|
* capi_ctr_suspend_output() - suspend controller
|
||||||
|
@ -517,7 +517,7 @@ EXPORT_SYMBOL(attach_capi_ctr);
|
||||||
int detach_capi_ctr(struct capi_ctr *card)
|
int detach_capi_ctr(struct capi_ctr *card)
|
||||||
{
|
{
|
||||||
if (card->cardstate != CARD_DETECTED)
|
if (card->cardstate != CARD_DETECTED)
|
||||||
capi_ctr_reseted(card);
|
capi_ctr_down(card);
|
||||||
|
|
||||||
ncards--;
|
ncards--;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
menuconfig ISDN_DRV_GIGASET
|
menuconfig ISDN_DRV_GIGASET
|
||||||
tristate "Siemens Gigaset support"
|
tristate "Siemens Gigaset support"
|
||||||
|
depends on ISDN_I4L
|
||||||
select CRC_CCITT
|
select CRC_CCITT
|
||||||
select BITREVERSE
|
select BITREVERSE
|
||||||
help
|
help
|
||||||
|
@ -42,11 +43,4 @@ config GIGASET_DEBUG
|
||||||
This enables debugging code in the Gigaset drivers.
|
This enables debugging code in the Gigaset drivers.
|
||||||
If in doubt, say yes.
|
If in doubt, say yes.
|
||||||
|
|
||||||
config GIGASET_UNDOCREQ
|
|
||||||
bool "Support for undocumented USB requests"
|
|
||||||
help
|
|
||||||
This enables support for USB requests we only know from
|
|
||||||
reverse engineering (currently M105 only). If you need
|
|
||||||
features like configuration mode of M105, say yes.
|
|
||||||
|
|
||||||
endif # ISDN_DRV_GIGASET
|
endif # ISDN_DRV_GIGASET
|
||||||
|
|
|
@ -174,9 +174,8 @@ static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes,
|
||||||
|
|
||||||
if (unlikely(fcs != PPP_GOODFCS)) {
|
if (unlikely(fcs != PPP_GOODFCS)) {
|
||||||
dev_err(cs->dev,
|
dev_err(cs->dev,
|
||||||
"Packet checksum at %lu failed, "
|
"Checksum failed, %u bytes corrupted!\n",
|
||||||
"packet is corrupted (%u bytes)!\n",
|
skb->len);
|
||||||
bcs->rcvbytes, skb->len);
|
|
||||||
compskb = NULL;
|
compskb = NULL;
|
||||||
gigaset_rcv_error(compskb, cs, bcs);
|
gigaset_rcv_error(compskb, cs, bcs);
|
||||||
error = 1;
|
error = 1;
|
||||||
|
|
|
@ -565,8 +565,6 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs,
|
||||||
gig_dbg(DEBUG_INIT, "setting up bcs[%d]->at_state", channel);
|
gig_dbg(DEBUG_INIT, "setting up bcs[%d]->at_state", channel);
|
||||||
gigaset_at_init(&bcs->at_state, bcs, cs, -1);
|
gigaset_at_init(&bcs->at_state, bcs, cs, -1);
|
||||||
|
|
||||||
bcs->rcvbytes = 0;
|
|
||||||
|
|
||||||
#ifdef CONFIG_GIGASET_DEBUG
|
#ifdef CONFIG_GIGASET_DEBUG
|
||||||
bcs->emptycount = 0;
|
bcs->emptycount = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -672,14 +670,8 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
|
||||||
cs->tty = NULL;
|
cs->tty = NULL;
|
||||||
cs->tty_dev = NULL;
|
cs->tty_dev = NULL;
|
||||||
cs->cidmode = cidmode != 0;
|
cs->cidmode = cidmode != 0;
|
||||||
|
cs->tabnocid = gigaset_tab_nocid;
|
||||||
//if(onechannel) { //FIXME
|
cs->tabcid = gigaset_tab_cid;
|
||||||
cs->tabnocid = gigaset_tab_nocid_m10x;
|
|
||||||
cs->tabcid = gigaset_tab_cid_m10x;
|
|
||||||
//} else {
|
|
||||||
// cs->tabnocid = gigaset_tab_nocid;
|
|
||||||
// cs->tabcid = gigaset_tab_cid;
|
|
||||||
//}
|
|
||||||
|
|
||||||
init_waitqueue_head(&cs->waitqueue);
|
init_waitqueue_head(&cs->waitqueue);
|
||||||
cs->waiting = 0;
|
cs->waiting = 0;
|
||||||
|
|
|
@ -160,7 +160,7 @@
|
||||||
|
|
||||||
|
|
||||||
// 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid), 400: hup, 500: reset, 600: dial, 700: ring
|
// 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid), 400: hup, 500: reset, 600: dial, 700: ring
|
||||||
struct reply_t gigaset_tab_nocid_m10x[]= /* with dle mode */
|
struct reply_t gigaset_tab_nocid[] =
|
||||||
{
|
{
|
||||||
/* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */
|
/* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ struct reply_t gigaset_tab_nocid_m10x[]= /* with dle mode */
|
||||||
};
|
};
|
||||||
|
|
||||||
// 600: start dialing, 650: dial in progress, 800: connection is up, 700: ring, 400: hup, 750: accepted icall
|
// 600: start dialing, 650: dial in progress, 800: connection is up, 700: ring, 400: hup, 750: accepted icall
|
||||||
struct reply_t gigaset_tab_cid_m10x[] = /* for M10x */
|
struct reply_t gigaset_tab_cid[] =
|
||||||
{
|
{
|
||||||
/* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */
|
/* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */
|
||||||
|
|
||||||
|
|
|
@ -282,8 +282,8 @@ struct reply_t {
|
||||||
char *command; /* NULL==none */
|
char *command; /* NULL==none */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct reply_t gigaset_tab_cid_m10x[];
|
extern struct reply_t gigaset_tab_cid[];
|
||||||
extern struct reply_t gigaset_tab_nocid_m10x[];
|
extern struct reply_t gigaset_tab_nocid[];
|
||||||
|
|
||||||
struct inbuf_t {
|
struct inbuf_t {
|
||||||
unsigned char *rcvbuf; /* usb-gigaset receive buffer */
|
unsigned char *rcvbuf; /* usb-gigaset receive buffer */
|
||||||
|
@ -384,7 +384,6 @@ struct bc_state {
|
||||||
int trans_up; /* Counter of packages (upstream) */
|
int trans_up; /* Counter of packages (upstream) */
|
||||||
|
|
||||||
struct at_state_t at_state;
|
struct at_state_t at_state;
|
||||||
unsigned long rcvbytes;
|
|
||||||
|
|
||||||
__u16 fcs;
|
__u16 fcs;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
|
@ -544,11 +544,11 @@ int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid)
|
||||||
|
|
||||||
gig_dbg(DEBUG_ANY, "Register driver capabilities to LL");
|
gig_dbg(DEBUG_ANY, "Register driver capabilities to LL");
|
||||||
|
|
||||||
//iif->id[sizeof(iif->id) - 1]=0;
|
|
||||||
//strncpy(iif->id, isdnid, sizeof(iif->id) - 1);
|
|
||||||
if (snprintf(iif->id, sizeof iif->id, "%s_%u", isdnid, cs->minor_index)
|
if (snprintf(iif->id, sizeof iif->id, "%s_%u", isdnid, cs->minor_index)
|
||||||
>= sizeof iif->id)
|
>= sizeof iif->id) {
|
||||||
return -ENOMEM; //FIXME EINVAL/...??
|
pr_err("ID too long: %s\n", isdnid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
iif->owner = THIS_MODULE;
|
iif->owner = THIS_MODULE;
|
||||||
iif->channels = cs->channels;
|
iif->channels = cs->channels;
|
||||||
|
@ -568,8 +568,10 @@ int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid)
|
||||||
iif->rcvcallb_skb = NULL; /* Will be set by LL */
|
iif->rcvcallb_skb = NULL; /* Will be set by LL */
|
||||||
iif->statcallb = NULL; /* Will be set by LL */
|
iif->statcallb = NULL; /* Will be set by LL */
|
||||||
|
|
||||||
if (!register_isdn(iif))
|
if (!register_isdn(iif)) {
|
||||||
|
pr_err("register_isdn failed\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
cs->myid = iif->channels; /* Set my device id */
|
cs->myid = iif->channels; /* Set my device id */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -599,8 +599,7 @@ void gigaset_if_init(struct cardstate *cs)
|
||||||
if (!IS_ERR(cs->tty_dev))
|
if (!IS_ERR(cs->tty_dev))
|
||||||
dev_set_drvdata(cs->tty_dev, cs);
|
dev_set_drvdata(cs->tty_dev, cs);
|
||||||
else {
|
else {
|
||||||
dev_warn(cs->dev,
|
pr_warning("could not register device to the tty subsystem\n");
|
||||||
"could not register device to the tty subsystem\n");
|
|
||||||
cs->tty_dev = NULL;
|
cs->tty_dev = NULL;
|
||||||
}
|
}
|
||||||
mutex_unlock(&cs->mutex);
|
mutex_unlock(&cs->mutex);
|
||||||
|
|
|
@ -246,6 +246,10 @@ static inline void dump_bytes(enum debuglevel level, const char *tag,
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
static char dbgline[3 * 32 + 1];
|
static char dbgline[3 * 32 + 1];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
if (!(gigaset_debuglevel & level))
|
||||||
|
return;
|
||||||
|
|
||||||
while (count-- > 0) {
|
while (count-- > 0) {
|
||||||
if (i > sizeof(dbgline) - 4) {
|
if (i > sizeof(dbgline) - 4) {
|
||||||
dbgline[i] = '\0';
|
dbgline[i] = '\0';
|
||||||
|
|
|
@ -79,5 +79,5 @@ void gigaset_init_dev_sysfs(struct cardstate *cs)
|
||||||
|
|
||||||
gig_dbg(DEBUG_INIT, "setting up sysfs");
|
gig_dbg(DEBUG_INIT, "setting up sysfs");
|
||||||
if (device_create_file(cs->tty_dev, &dev_attr_cidmode))
|
if (device_create_file(cs->tty_dev, &dev_attr_cidmode))
|
||||||
dev_err(cs->dev, "could not create sysfs attribute\n");
|
pr_err("could not create sysfs attribute\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,8 +153,6 @@ static inline unsigned tiocm_to_gigaset(unsigned state)
|
||||||
return ((state & TIOCM_DTR) ? 1 : 0) | ((state & TIOCM_RTS) ? 2 : 0);
|
return ((state & TIOCM_DTR) ? 1 : 0) | ((state & TIOCM_RTS) ? 2 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_GIGASET_UNDOCREQ
|
|
||||||
/* WARNING: EXPERIMENTAL! */
|
|
||||||
static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
|
static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
|
||||||
unsigned new_state)
|
unsigned new_state)
|
||||||
{
|
{
|
||||||
|
@ -176,6 +174,11 @@ static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set M105 configuration value
|
||||||
|
* using undocumented device commands reverse engineered from USB traces
|
||||||
|
* of the Siemens Windows driver
|
||||||
|
*/
|
||||||
static int set_value(struct cardstate *cs, u8 req, u16 val)
|
static int set_value(struct cardstate *cs, u8 req, u16 val)
|
||||||
{
|
{
|
||||||
struct usb_device *udev = cs->hw.usb->udev;
|
struct usb_device *udev = cs->hw.usb->udev;
|
||||||
|
@ -205,8 +208,10 @@ static int set_value(struct cardstate *cs, u8 req, u16 val)
|
||||||
return r < 0 ? r : (r2 < 0 ? r2 : 0);
|
return r < 0 ? r : (r2 < 0 ? r2 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WARNING: HIGHLY EXPERIMENTAL! */
|
/*
|
||||||
// don't use this in an interrupt/BH
|
* set the baud rate on the internal serial adapter
|
||||||
|
* using the undocumented parameter setting command
|
||||||
|
*/
|
||||||
static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
|
static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
|
||||||
{
|
{
|
||||||
u16 val;
|
u16 val;
|
||||||
|
@ -237,8 +242,10 @@ static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
|
||||||
return set_value(cs, 1, val);
|
return set_value(cs, 1, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WARNING: HIGHLY EXPERIMENTAL! */
|
/*
|
||||||
// don't use this in an interrupt/BH
|
* set the line format on the internal serial adapter
|
||||||
|
* using the undocumented parameter setting command
|
||||||
|
*/
|
||||||
static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
|
static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
|
||||||
{
|
{
|
||||||
u16 val = 0;
|
u16 val = 0;
|
||||||
|
@ -274,24 +281,6 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
|
||||||
return set_value(cs, 3, val);
|
return set_value(cs, 3, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
|
|
||||||
unsigned new_state)
|
|
||||||
{
|
|
||||||
return -ENOTTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
|
|
||||||
{
|
|
||||||
return -ENOTTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
|
|
||||||
{
|
|
||||||
return -ENOTTY;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*================================================================================================================*/
|
/*================================================================================================================*/
|
||||||
static int gigaset_init_bchannel(struct bc_state *bcs)
|
static int gigaset_init_bchannel(struct bc_state *bcs)
|
||||||
|
@ -362,10 +351,8 @@ static void gigaset_modem_fill(unsigned long data)
|
||||||
} while (again);
|
} while (again);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* gigaset_read_int_callback
|
* Interrupt Input URB completion routine
|
||||||
*
|
|
||||||
* It is called if the data was received from the device.
|
|
||||||
*/
|
*/
|
||||||
static void gigaset_read_int_callback(struct urb *urb)
|
static void gigaset_read_int_callback(struct urb *urb)
|
||||||
{
|
{
|
||||||
|
@ -567,18 +554,19 @@ static int gigaset_chars_in_buffer(struct cardstate *cs)
|
||||||
return cs->cmdbytes;
|
return cs->cmdbytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set the break characters on the internal serial adapter
|
||||||
|
* using undocumented device commands reverse engineered from USB traces
|
||||||
|
* of the Siemens Windows driver
|
||||||
|
*/
|
||||||
static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])
|
static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_GIGASET_UNDOCREQ
|
|
||||||
struct usb_device *udev = cs->hw.usb->udev;
|
struct usb_device *udev = cs->hw.usb->udev;
|
||||||
|
|
||||||
gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf);
|
gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf);
|
||||||
memcpy(cs->hw.usb->bchars, buf, 6);
|
memcpy(cs->hw.usb->bchars, buf, 6);
|
||||||
return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41,
|
return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41,
|
||||||
0, 0, &buf, 6, 2000);
|
0, 0, &buf, 6, 2000);
|
||||||
#else
|
|
||||||
return -ENOTTY;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gigaset_freebcshw(struct bc_state *bcs)
|
static int gigaset_freebcshw(struct bc_state *bcs)
|
||||||
|
@ -625,7 +613,6 @@ static int gigaset_initcshw(struct cardstate *cs)
|
||||||
ucs->bchars[5] = 0x13;
|
ucs->bchars[5] = 0x13;
|
||||||
ucs->bulk_out_buffer = NULL;
|
ucs->bulk_out_buffer = NULL;
|
||||||
ucs->bulk_out_urb = NULL;
|
ucs->bulk_out_urb = NULL;
|
||||||
//ucs->urb_cmd_out = NULL;
|
|
||||||
ucs->read_urb = NULL;
|
ucs->read_urb = NULL;
|
||||||
tasklet_init(&cs->write_tasklet,
|
tasklet_init(&cs->write_tasklet,
|
||||||
&gigaset_modem_fill, (unsigned long) cs);
|
&gigaset_modem_fill, (unsigned long) cs);
|
||||||
|
@ -742,7 +729,7 @@ static int gigaset_probe(struct usb_interface *interface,
|
||||||
cs->dev = &interface->dev;
|
cs->dev = &interface->dev;
|
||||||
|
|
||||||
/* save address of controller structure */
|
/* save address of controller structure */
|
||||||
usb_set_intfdata(interface, cs); // dev_set_drvdata(&interface->dev, cs);
|
usb_set_intfdata(interface, cs);
|
||||||
|
|
||||||
endpoint = &hostif->endpoint[0].desc;
|
endpoint = &hostif->endpoint[0].desc;
|
||||||
|
|
||||||
|
@ -921,8 +908,7 @@ static const struct gigaset_ops ops = {
|
||||||
gigaset_m10x_input,
|
gigaset_m10x_input,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* usb_gigaset_init
|
|
||||||
* This function is called while kernel-module is loaded
|
* This function is called while kernel-module is loaded
|
||||||
*/
|
*/
|
||||||
static int __init usb_gigaset_init(void)
|
static int __init usb_gigaset_init(void)
|
||||||
|
@ -952,9 +938,7 @@ static int __init usb_gigaset_init(void)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/**
|
|
||||||
* usb_gigaset_exit
|
|
||||||
* This function is called while unloading the kernel-module
|
* This function is called while unloading the kernel-module
|
||||||
*/
|
*/
|
||||||
static void __exit usb_gigaset_exit(void)
|
static void __exit usb_gigaset_exit(void)
|
||||||
|
|
|
@ -330,7 +330,7 @@ void b1_reset_ctr(struct capi_ctr *ctrl)
|
||||||
spin_lock_irqsave(&card->lock, flags);
|
spin_lock_irqsave(&card->lock, flags);
|
||||||
capilib_release(&cinfo->ncci_head);
|
capilib_release(&cinfo->ncci_head);
|
||||||
spin_unlock_irqrestore(&card->lock, flags);
|
spin_unlock_irqrestore(&card->lock, flags);
|
||||||
capi_ctr_reseted(ctrl);
|
capi_ctr_down(ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void b1_register_appl(struct capi_ctr *ctrl,
|
void b1_register_appl(struct capi_ctr *ctrl,
|
||||||
|
|
|
@ -759,7 +759,7 @@ void b1dma_reset_ctr(struct capi_ctr *ctrl)
|
||||||
memset(cinfo->version, 0, sizeof(cinfo->version));
|
memset(cinfo->version, 0, sizeof(cinfo->version));
|
||||||
capilib_release(&cinfo->ncci_head);
|
capilib_release(&cinfo->ncci_head);
|
||||||
spin_unlock_irqrestore(&card->lock, flags);
|
spin_unlock_irqrestore(&card->lock, flags);
|
||||||
capi_ctr_reseted(ctrl);
|
capi_ctr_down(ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
|
|
@ -681,7 +681,7 @@ static irqreturn_t c4_handle_interrupt(avmcard *card)
|
||||||
spin_lock_irqsave(&card->lock, flags);
|
spin_lock_irqsave(&card->lock, flags);
|
||||||
capilib_release(&cinfo->ncci_head);
|
capilib_release(&cinfo->ncci_head);
|
||||||
spin_unlock_irqrestore(&card->lock, flags);
|
spin_unlock_irqrestore(&card->lock, flags);
|
||||||
capi_ctr_reseted(&cinfo->capi_ctrl);
|
capi_ctr_down(&cinfo->capi_ctrl);
|
||||||
}
|
}
|
||||||
card->nlogcontr = 0;
|
card->nlogcontr = 0;
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
@ -909,7 +909,7 @@ static void c4_reset_ctr(struct capi_ctr *ctrl)
|
||||||
for (i=0; i < card->nr_controllers; i++) {
|
for (i=0; i < card->nr_controllers; i++) {
|
||||||
cinfo = &card->ctrlinfo[i];
|
cinfo = &card->ctrlinfo[i];
|
||||||
memset(cinfo->version, 0, sizeof(cinfo->version));
|
memset(cinfo->version, 0, sizeof(cinfo->version));
|
||||||
capi_ctr_reseted(&cinfo->capi_ctrl);
|
capi_ctr_down(&cinfo->capi_ctrl);
|
||||||
}
|
}
|
||||||
card->nlogcontr = 0;
|
card->nlogcontr = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -339,7 +339,7 @@ static void t1isa_reset_ctr(struct capi_ctr *ctrl)
|
||||||
spin_lock_irqsave(&card->lock, flags);
|
spin_lock_irqsave(&card->lock, flags);
|
||||||
capilib_release(&cinfo->ncci_head);
|
capilib_release(&cinfo->ncci_head);
|
||||||
spin_unlock_irqrestore(&card->lock, flags);
|
spin_unlock_irqrestore(&card->lock, flags);
|
||||||
capi_ctr_reseted(ctrl);
|
capi_ctr_down(ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void t1isa_remove(struct pci_dev *pdev)
|
static void t1isa_remove(struct pci_dev *pdev)
|
||||||
|
|
|
@ -13,7 +13,7 @@ config MISDN_HFCPCI
|
||||||
|
|
||||||
config MISDN_HFCMULTI
|
config MISDN_HFCMULTI
|
||||||
tristate "Support for HFC multiport cards (HFC-4S/8S/E1)"
|
tristate "Support for HFC multiport cards (HFC-4S/8S/E1)"
|
||||||
depends on PCI
|
depends on PCI || 8xx
|
||||||
depends on MISDN
|
depends on MISDN
|
||||||
help
|
help
|
||||||
Enable support for cards with Cologne Chip AG's HFC multiport
|
Enable support for cards with Cologne Chip AG's HFC multiport
|
||||||
|
@ -23,6 +23,15 @@ config MISDN_HFCMULTI
|
||||||
* HFC-8S (8 S/T interfaces on one chip)
|
* HFC-8S (8 S/T interfaces on one chip)
|
||||||
* HFC-E1 (E1 interface for 2Mbit ISDN)
|
* HFC-E1 (E1 interface for 2Mbit ISDN)
|
||||||
|
|
||||||
|
config MISDN_HFCMULTI_8xx
|
||||||
|
boolean "Support for XHFC embedded board in HFC multiport driver"
|
||||||
|
depends on MISDN
|
||||||
|
depends on MISDN_HFCMULTI
|
||||||
|
depends on 8xx
|
||||||
|
default 8xx
|
||||||
|
help
|
||||||
|
Enable support for the XHFC embedded solution from Speech Design.
|
||||||
|
|
||||||
config MISDN_HFCUSB
|
config MISDN_HFCUSB
|
||||||
tristate "Support for HFC-S USB based TAs"
|
tristate "Support for HFC-S USB based TAs"
|
||||||
depends on USB
|
depends on USB
|
||||||
|
|
|
@ -17,6 +17,16 @@
|
||||||
#define PCI_ENA_REGIO 0x01
|
#define PCI_ENA_REGIO 0x01
|
||||||
#define PCI_ENA_MEMIO 0x02
|
#define PCI_ENA_MEMIO 0x02
|
||||||
|
|
||||||
|
#define XHFC_IRQ 4 /* SIU_IRQ2 */
|
||||||
|
#define XHFC_MEMBASE 0xFE000000
|
||||||
|
#define XHFC_MEMSIZE 0x00001000
|
||||||
|
#define XHFC_OFFSET 0x00001000
|
||||||
|
#define PA_XHFC_A0 0x0020 /* PA10 */
|
||||||
|
#define PB_XHFC_IRQ1 0x00000100 /* PB23 */
|
||||||
|
#define PB_XHFC_IRQ2 0x00000200 /* PB22 */
|
||||||
|
#define PB_XHFC_IRQ3 0x00000400 /* PB21 */
|
||||||
|
#define PB_XHFC_IRQ4 0x00000800 /* PB20 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE: some registers are assigned multiple times due to different modes
|
* NOTE: some registers are assigned multiple times due to different modes
|
||||||
* also registers are assigned differen for HFC-4s/8s and HFC-E1
|
* also registers are assigned differen for HFC-4s/8s and HFC-E1
|
||||||
|
@ -44,6 +54,7 @@ struct hfc_chan {
|
||||||
int conf; /* conference setting of TX slot */
|
int conf; /* conference setting of TX slot */
|
||||||
int txpending; /* if there is currently data in */
|
int txpending; /* if there is currently data in */
|
||||||
/* the FIFO 0=no, 1=yes, 2=splloop */
|
/* the FIFO 0=no, 1=yes, 2=splloop */
|
||||||
|
int Zfill; /* rx-fifo level on last hfcmulti_tx */
|
||||||
int rx_off; /* set to turn fifo receive off */
|
int rx_off; /* set to turn fifo receive off */
|
||||||
int coeff_count; /* curren coeff block */
|
int coeff_count; /* curren coeff block */
|
||||||
s32 *coeff; /* memory pointer to 8 coeff blocks */
|
s32 *coeff; /* memory pointer to 8 coeff blocks */
|
||||||
|
@ -62,6 +73,7 @@ struct hfcm_hw {
|
||||||
u_char r_sci_msk;
|
u_char r_sci_msk;
|
||||||
u_char r_tx0, r_tx1;
|
u_char r_tx0, r_tx1;
|
||||||
u_char a_st_ctrl0[8];
|
u_char a_st_ctrl0[8];
|
||||||
|
u_char r_bert_wd_md;
|
||||||
timer_t timer;
|
timer_t timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,6 +91,11 @@ struct hfcm_hw {
|
||||||
#define HFC_CFG_CRC4 10 /* disable CRC-4 Multiframe mode, */
|
#define HFC_CFG_CRC4 10 /* disable CRC-4 Multiframe mode, */
|
||||||
/* use double frame instead. */
|
/* use double frame instead. */
|
||||||
|
|
||||||
|
#define HFC_TYPE_E1 1 /* controller is HFC-E1 */
|
||||||
|
#define HFC_TYPE_4S 4 /* controller is HFC-4S */
|
||||||
|
#define HFC_TYPE_8S 8 /* controller is HFC-8S */
|
||||||
|
#define HFC_TYPE_XHFC 5 /* controller is XHFC */
|
||||||
|
|
||||||
#define HFC_CHIP_EXRAM_128 0 /* external ram 128k */
|
#define HFC_CHIP_EXRAM_128 0 /* external ram 128k */
|
||||||
#define HFC_CHIP_EXRAM_512 1 /* external ram 256k */
|
#define HFC_CHIP_EXRAM_512 1 /* external ram 256k */
|
||||||
#define HFC_CHIP_REVISION0 2 /* old fifo handling */
|
#define HFC_CHIP_REVISION0 2 /* old fifo handling */
|
||||||
|
@ -86,19 +103,22 @@ struct hfcm_hw {
|
||||||
#define HFC_CHIP_PCM_MASTER 4 /* PCM is master */
|
#define HFC_CHIP_PCM_MASTER 4 /* PCM is master */
|
||||||
#define HFC_CHIP_RX_SYNC 5 /* disable pll sync for pcm */
|
#define HFC_CHIP_RX_SYNC 5 /* disable pll sync for pcm */
|
||||||
#define HFC_CHIP_DTMF 6 /* DTMF decoding is enabled */
|
#define HFC_CHIP_DTMF 6 /* DTMF decoding is enabled */
|
||||||
#define HFC_CHIP_ULAW 7 /* ULAW mode */
|
#define HFC_CHIP_CONF 7 /* conference handling is enabled */
|
||||||
#define HFC_CHIP_CLOCK2 8 /* double clock mode */
|
#define HFC_CHIP_ULAW 8 /* ULAW mode */
|
||||||
#define HFC_CHIP_E1CLOCK_GET 9 /* always get clock from E1 interface */
|
#define HFC_CHIP_CLOCK2 9 /* double clock mode */
|
||||||
#define HFC_CHIP_E1CLOCK_PUT 10 /* always put clock from E1 interface */
|
#define HFC_CHIP_E1CLOCK_GET 10 /* always get clock from E1 interface */
|
||||||
#define HFC_CHIP_WATCHDOG 11 /* whether we should send signals */
|
#define HFC_CHIP_E1CLOCK_PUT 11 /* always put clock from E1 interface */
|
||||||
|
#define HFC_CHIP_WATCHDOG 12 /* whether we should send signals */
|
||||||
/* to the watchdog */
|
/* to the watchdog */
|
||||||
#define HFC_CHIP_B410P 12 /* whether we have a b410p with echocan in */
|
#define HFC_CHIP_B410P 13 /* whether we have a b410p with echocan in */
|
||||||
/* hw */
|
/* hw */
|
||||||
#define HFC_CHIP_PLXSD 13 /* whether we have a Speech-Design PLX */
|
#define HFC_CHIP_PLXSD 14 /* whether we have a Speech-Design PLX */
|
||||||
|
#define HFC_CHIP_EMBSD 15 /* whether we have a SD Embedded board */
|
||||||
|
|
||||||
#define HFC_IO_MODE_PCIMEM 0x00 /* normal memory mapped IO */
|
#define HFC_IO_MODE_PCIMEM 0x00 /* normal memory mapped IO */
|
||||||
#define HFC_IO_MODE_REGIO 0x01 /* PCI io access */
|
#define HFC_IO_MODE_REGIO 0x01 /* PCI io access */
|
||||||
#define HFC_IO_MODE_PLXSD 0x02 /* access HFC via PLX9030 */
|
#define HFC_IO_MODE_PLXSD 0x02 /* access HFC via PLX9030 */
|
||||||
|
#define HFC_IO_MODE_EMBSD 0x03 /* direct access */
|
||||||
|
|
||||||
/* table entry in the PCI devices list */
|
/* table entry in the PCI devices list */
|
||||||
struct hm_map {
|
struct hm_map {
|
||||||
|
@ -111,6 +131,7 @@ struct hm_map {
|
||||||
int opticalsupport;
|
int opticalsupport;
|
||||||
int dip_type;
|
int dip_type;
|
||||||
int io_mode;
|
int io_mode;
|
||||||
|
int irq;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hfc_multi {
|
struct hfc_multi {
|
||||||
|
@ -118,7 +139,7 @@ struct hfc_multi {
|
||||||
struct hm_map *mtyp;
|
struct hm_map *mtyp;
|
||||||
int id;
|
int id;
|
||||||
int pcm; /* id of pcm bus */
|
int pcm; /* id of pcm bus */
|
||||||
int type;
|
int ctype; /* controller type */
|
||||||
int ports;
|
int ports;
|
||||||
|
|
||||||
u_int irq; /* irq used by card */
|
u_int irq; /* irq used by card */
|
||||||
|
@ -158,10 +179,16 @@ struct hfc_multi {
|
||||||
int len);
|
int len);
|
||||||
void (*write_fifo)(struct hfc_multi *hc, u_char *data,
|
void (*write_fifo)(struct hfc_multi *hc, u_char *data,
|
||||||
int len);
|
int len);
|
||||||
u_long pci_origmembase, plx_origmembase, dsp_origmembase;
|
u_long pci_origmembase, plx_origmembase;
|
||||||
void __iomem *pci_membase; /* PCI memory */
|
void __iomem *pci_membase; /* PCI memory */
|
||||||
void __iomem *plx_membase; /* PLX memory */
|
void __iomem *plx_membase; /* PLX memory */
|
||||||
u_char *dsp_membase; /* DSP on PLX */
|
u_long xhfc_origmembase;
|
||||||
|
u_char *xhfc_membase;
|
||||||
|
u_long *xhfc_memaddr, *xhfc_memdata;
|
||||||
|
#ifdef CONFIG_MISDN_HFCMULTI_8xx
|
||||||
|
struct immap *immap;
|
||||||
|
#endif
|
||||||
|
u_long pb_irqmsk; /* Portbit mask to check the IRQ line */
|
||||||
u_long pci_iobase; /* PCI IO */
|
u_long pci_iobase; /* PCI IO */
|
||||||
struct hfcm_hw hw; /* remember data of write-only-registers */
|
struct hfcm_hw hw; /* remember data of write-only-registers */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
/*
|
||||||
|
* For License see notice in hfc_multi.c
|
||||||
|
*
|
||||||
|
* special IO and init functions for the embedded XHFC board
|
||||||
|
* from Speech Design
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <asm/8xx_immap.h>
|
||||||
|
|
||||||
|
/* Change this to the value used by your board */
|
||||||
|
#ifndef IMAP_ADDR
|
||||||
|
#define IMAP_ADDR 0xFFF00000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
#ifdef HFC_REGISTER_DEBUG
|
||||||
|
HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val,
|
||||||
|
const char *function, int line)
|
||||||
|
#else
|
||||||
|
HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
|
||||||
|
writeb(reg, hc->xhfc_memaddr);
|
||||||
|
hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
|
||||||
|
writeb(val, hc->xhfc_memdata);
|
||||||
|
}
|
||||||
|
static u_char
|
||||||
|
#ifdef HFC_REGISTER_DEBUG
|
||||||
|
HFC_inb_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line)
|
||||||
|
#else
|
||||||
|
HFC_inb_embsd(struct hfc_multi *hc, u_char reg)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
|
||||||
|
writeb(reg, hc->xhfc_memaddr);
|
||||||
|
hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
|
||||||
|
return readb(hc->xhfc_memdata);
|
||||||
|
}
|
||||||
|
static u_short
|
||||||
|
#ifdef HFC_REGISTER_DEBUG
|
||||||
|
HFC_inw_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line)
|
||||||
|
#else
|
||||||
|
HFC_inw_embsd(struct hfc_multi *hc, u_char reg)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
|
||||||
|
writeb(reg, hc->xhfc_memaddr);
|
||||||
|
hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
|
||||||
|
return readb(hc->xhfc_memdata);
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
#ifdef HFC_REGISTER_DEBUG
|
||||||
|
HFC_wait_embsd(struct hfc_multi *hc, const char *function, int line)
|
||||||
|
#else
|
||||||
|
HFC_wait_embsd(struct hfc_multi *hc)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
|
||||||
|
writeb(R_STATUS, hc->xhfc_memaddr);
|
||||||
|
hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
|
||||||
|
while (readb(hc->xhfc_memdata) & V_BUSY)
|
||||||
|
cpu_relax();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write fifo data (EMBSD) */
|
||||||
|
void
|
||||||
|
write_fifo_embsd(struct hfc_multi *hc, u_char *data, int len)
|
||||||
|
{
|
||||||
|
hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
|
||||||
|
*hc->xhfc_memaddr = A_FIFO_DATA0;
|
||||||
|
hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
|
||||||
|
while (len) {
|
||||||
|
*hc->xhfc_memdata = *data;
|
||||||
|
data++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read fifo data (EMBSD) */
|
||||||
|
void
|
||||||
|
read_fifo_embsd(struct hfc_multi *hc, u_char *data, int len)
|
||||||
|
{
|
||||||
|
hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
|
||||||
|
*hc->xhfc_memaddr = A_FIFO_DATA0;
|
||||||
|
hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
|
||||||
|
while (len) {
|
||||||
|
*data = (u_char)(*hc->xhfc_memdata);
|
||||||
|
data++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
setup_embedded(struct hfc_multi *hc, struct hm_map *m)
|
||||||
|
{
|
||||||
|
printk(KERN_INFO
|
||||||
|
"HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",
|
||||||
|
m->vendor_name, m->card_name, m->clock2 ? "double" : "normal");
|
||||||
|
|
||||||
|
hc->pci_dev = NULL;
|
||||||
|
if (m->clock2)
|
||||||
|
test_and_set_bit(HFC_CHIP_CLOCK2, &hc->chip);
|
||||||
|
|
||||||
|
hc->leds = m->leds;
|
||||||
|
hc->ledstate = 0xAFFEAFFE;
|
||||||
|
hc->opticalsupport = m->opticalsupport;
|
||||||
|
|
||||||
|
hc->pci_iobase = 0;
|
||||||
|
hc->pci_membase = 0;
|
||||||
|
hc->xhfc_membase = NULL;
|
||||||
|
hc->xhfc_memaddr = NULL;
|
||||||
|
hc->xhfc_memdata = NULL;
|
||||||
|
|
||||||
|
/* set memory access methods */
|
||||||
|
if (m->io_mode) /* use mode from card config */
|
||||||
|
hc->io_mode = m->io_mode;
|
||||||
|
switch (hc->io_mode) {
|
||||||
|
case HFC_IO_MODE_EMBSD:
|
||||||
|
test_and_set_bit(HFC_CHIP_EMBSD, &hc->chip);
|
||||||
|
hc->slots = 128; /* required */
|
||||||
|
/* fall through */
|
||||||
|
hc->HFC_outb = HFC_outb_embsd;
|
||||||
|
hc->HFC_inb = HFC_inb_embsd;
|
||||||
|
hc->HFC_inw = HFC_inw_embsd;
|
||||||
|
hc->HFC_wait = HFC_wait_embsd;
|
||||||
|
hc->read_fifo = read_fifo_embsd;
|
||||||
|
hc->write_fifo = write_fifo_embsd;
|
||||||
|
hc->xhfc_origmembase = XHFC_MEMBASE + XHFC_OFFSET * hc->id;
|
||||||
|
hc->xhfc_membase = (u_char *)ioremap(hc->xhfc_origmembase,
|
||||||
|
XHFC_MEMSIZE);
|
||||||
|
if (!hc->xhfc_membase) {
|
||||||
|
printk(KERN_WARNING
|
||||||
|
"HFC-multi: failed to remap xhfc address space. "
|
||||||
|
"(internal error)\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
hc->xhfc_memaddr = (u_long *)(hc->xhfc_membase + 4);
|
||||||
|
hc->xhfc_memdata = (u_long *)(hc->xhfc_membase);
|
||||||
|
printk(KERN_INFO
|
||||||
|
"HFC-multi: xhfc_membase:%#lx xhfc_origmembase:%#lx "
|
||||||
|
"xhfc_memaddr:%#lx xhfc_memdata:%#lx\n",
|
||||||
|
(u_long)hc->xhfc_membase, hc->xhfc_origmembase,
|
||||||
|
(u_long)hc->xhfc_memaddr, (u_long)hc->xhfc_memdata);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare the MPC8XX PortA 10 as output (address/data selector) */
|
||||||
|
hc->immap = (struct immap *)(IMAP_ADDR);
|
||||||
|
hc->immap->im_ioport.iop_papar &= ~(PA_XHFC_A0);
|
||||||
|
hc->immap->im_ioport.iop_paodr &= ~(PA_XHFC_A0);
|
||||||
|
hc->immap->im_ioport.iop_padir |= PA_XHFC_A0;
|
||||||
|
|
||||||
|
/* Prepare the MPC8xx PortB __X__ as input (ISDN__X__IRQ) */
|
||||||
|
hc->pb_irqmsk = (PB_XHFC_IRQ1 << hc->id);
|
||||||
|
hc->immap->im_cpm.cp_pbpar &= ~(hc->pb_irqmsk);
|
||||||
|
hc->immap->im_cpm.cp_pbodr &= ~(hc->pb_irqmsk);
|
||||||
|
hc->immap->im_cpm.cp_pbdir &= ~(hc->pb_irqmsk);
|
||||||
|
|
||||||
|
/* At this point the needed config is done */
|
||||||
|
/* fifos are still not enabled */
|
||||||
|
return 0;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -257,7 +257,7 @@ reset_hfcpci(struct hfc_pci *hc)
|
||||||
Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
|
Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
|
||||||
|
|
||||||
/* Clear already pending ints */
|
/* Clear already pending ints */
|
||||||
if (Read_hfc(hc, HFCPCI_INT_S1));
|
val = Read_hfc(hc, HFCPCI_INT_S1);
|
||||||
|
|
||||||
/* set NT/TE mode */
|
/* set NT/TE mode */
|
||||||
hfcpci_setmode(hc);
|
hfcpci_setmode(hc);
|
||||||
|
@ -452,7 +452,7 @@ hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz,
|
||||||
}
|
}
|
||||||
bz->za[new_f2].z2 = cpu_to_le16(new_z2);
|
bz->za[new_f2].z2 = cpu_to_le16(new_z2);
|
||||||
bz->f2 = new_f2; /* next buffer */
|
bz->f2 = new_f2; /* next buffer */
|
||||||
recv_Bchannel(bch);
|
recv_Bchannel(bch, MISDN_ID_ANY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,7 +499,8 @@ receive_dmsg(struct hfc_pci *hc)
|
||||||
df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) |
|
df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) |
|
||||||
(MAX_D_FRAMES + 1); /* next buffer */
|
(MAX_D_FRAMES + 1); /* next buffer */
|
||||||
df->za[df->f2 & D_FREG_MASK].z2 =
|
df->za[df->f2 & D_FREG_MASK].z2 =
|
||||||
cpu_to_le16((le16_to_cpu(zp->z2) + rcnt) & (D_FIFO_SIZE - 1));
|
cpu_to_le16((le16_to_cpu(zp->z2) + rcnt) &
|
||||||
|
(D_FIFO_SIZE - 1));
|
||||||
} else {
|
} else {
|
||||||
dch->rx_skb = mI_alloc_skb(rcnt - 3, GFP_ATOMIC);
|
dch->rx_skb = mI_alloc_skb(rcnt - 3, GFP_ATOMIC);
|
||||||
if (!dch->rx_skb) {
|
if (!dch->rx_skb) {
|
||||||
|
@ -541,35 +542,45 @@ receive_dmsg(struct hfc_pci *hc)
|
||||||
* check for transparent receive data and read max one 'poll' size if avail
|
* check for transparent receive data and read max one 'poll' size if avail
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata)
|
hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz,
|
||||||
|
struct bzfifo *txbz, u_char *bdata)
|
||||||
{
|
{
|
||||||
__le16 *z1r, *z2r;
|
__le16 *z1r, *z2r, *z1t, *z2t;
|
||||||
int new_z2, fcnt, maxlen;
|
int new_z2, fcnt_rx, fcnt_tx, maxlen;
|
||||||
u_char *ptr, *ptr1;
|
u_char *ptr, *ptr1;
|
||||||
|
|
||||||
z1r = &bz->za[MAX_B_FRAMES].z1; /* pointer to z reg */
|
z1r = &rxbz->za[MAX_B_FRAMES].z1; /* pointer to z reg */
|
||||||
z2r = z1r + 1;
|
z2r = z1r + 1;
|
||||||
|
z1t = &txbz->za[MAX_B_FRAMES].z1;
|
||||||
|
z2t = z1t + 1;
|
||||||
|
|
||||||
fcnt = le16_to_cpu(*z1r) - le16_to_cpu(*z2r);
|
fcnt_rx = le16_to_cpu(*z1r) - le16_to_cpu(*z2r);
|
||||||
if (!fcnt)
|
if (!fcnt_rx)
|
||||||
return; /* no data avail */
|
return; /* no data avail */
|
||||||
|
|
||||||
if (fcnt <= 0)
|
if (fcnt_rx <= 0)
|
||||||
fcnt += B_FIFO_SIZE; /* bytes actually buffered */
|
fcnt_rx += B_FIFO_SIZE; /* bytes actually buffered */
|
||||||
new_z2 = le16_to_cpu(*z2r) + fcnt; /* new position in fifo */
|
new_z2 = le16_to_cpu(*z2r) + fcnt_rx; /* new position in fifo */
|
||||||
if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL))
|
if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL))
|
||||||
new_z2 -= B_FIFO_SIZE; /* buffer wrap */
|
new_z2 -= B_FIFO_SIZE; /* buffer wrap */
|
||||||
|
|
||||||
if (fcnt > MAX_DATA_SIZE) { /* flush, if oversized */
|
if (fcnt_rx > MAX_DATA_SIZE) { /* flush, if oversized */
|
||||||
*z2r = cpu_to_le16(new_z2); /* new position */
|
*z2r = cpu_to_le16(new_z2); /* new position */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bch->rx_skb = mI_alloc_skb(fcnt, GFP_ATOMIC);
|
fcnt_tx = le16_to_cpu(*z2t) - le16_to_cpu(*z1t);
|
||||||
|
if (fcnt_tx <= 0)
|
||||||
|
fcnt_tx += B_FIFO_SIZE;
|
||||||
|
/* fcnt_tx contains available bytes in tx-fifo */
|
||||||
|
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 (bch->rx_skb) {
|
||||||
ptr = skb_put(bch->rx_skb, fcnt);
|
ptr = skb_put(bch->rx_skb, fcnt_rx);
|
||||||
if (le16_to_cpu(*z2r) + fcnt <= B_FIFO_SIZE + B_SUB_VAL)
|
if (le16_to_cpu(*z2r) + fcnt_rx <= B_FIFO_SIZE + B_SUB_VAL)
|
||||||
maxlen = fcnt; /* complete transfer */
|
maxlen = fcnt_rx; /* complete transfer */
|
||||||
else
|
else
|
||||||
maxlen = B_FIFO_SIZE + B_SUB_VAL - le16_to_cpu(*z2r);
|
maxlen = B_FIFO_SIZE + B_SUB_VAL - le16_to_cpu(*z2r);
|
||||||
/* maximum */
|
/* maximum */
|
||||||
|
@ -577,14 +588,14 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata)
|
||||||
ptr1 = bdata + (le16_to_cpu(*z2r) - B_SUB_VAL);
|
ptr1 = bdata + (le16_to_cpu(*z2r) - B_SUB_VAL);
|
||||||
/* start of data */
|
/* start of data */
|
||||||
memcpy(ptr, ptr1, maxlen); /* copy data */
|
memcpy(ptr, ptr1, maxlen); /* copy data */
|
||||||
fcnt -= maxlen;
|
fcnt_rx -= maxlen;
|
||||||
|
|
||||||
if (fcnt) { /* rest remaining */
|
if (fcnt_rx) { /* rest remaining */
|
||||||
ptr += maxlen;
|
ptr += maxlen;
|
||||||
ptr1 = bdata; /* start of buffer */
|
ptr1 = bdata; /* start of buffer */
|
||||||
memcpy(ptr, ptr1, fcnt); /* rest */
|
memcpy(ptr, ptr1, fcnt_rx); /* rest */
|
||||||
}
|
}
|
||||||
recv_Bchannel(bch);
|
recv_Bchannel(bch, fcnt_tx); /* bch, id */
|
||||||
} else
|
} else
|
||||||
printk(KERN_WARNING "HFCPCI: receive out of memory\n");
|
printk(KERN_WARNING "HFCPCI: receive out of memory\n");
|
||||||
|
|
||||||
|
@ -600,26 +611,28 @@ main_rec_hfcpci(struct bchannel *bch)
|
||||||
struct hfc_pci *hc = bch->hw;
|
struct hfc_pci *hc = bch->hw;
|
||||||
int rcnt, real_fifo;
|
int rcnt, real_fifo;
|
||||||
int receive = 0, count = 5;
|
int receive = 0, count = 5;
|
||||||
struct bzfifo *bz;
|
struct bzfifo *txbz, *rxbz;
|
||||||
u_char *bdata;
|
u_char *bdata;
|
||||||
struct zt *zp;
|
struct zt *zp;
|
||||||
|
|
||||||
if ((bch->nr & 2) && (!hc->hw.bswapped)) {
|
if ((bch->nr & 2) && (!hc->hw.bswapped)) {
|
||||||
bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2;
|
rxbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2;
|
||||||
|
txbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2;
|
||||||
bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b2;
|
bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b2;
|
||||||
real_fifo = 1;
|
real_fifo = 1;
|
||||||
} else {
|
} else {
|
||||||
bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1;
|
rxbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1;
|
||||||
|
txbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1;
|
||||||
bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b1;
|
bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b1;
|
||||||
real_fifo = 0;
|
real_fifo = 0;
|
||||||
}
|
}
|
||||||
Begin:
|
Begin:
|
||||||
count--;
|
count--;
|
||||||
if (bz->f1 != bz->f2) {
|
if (rxbz->f1 != rxbz->f2) {
|
||||||
if (bch->debug & DEBUG_HW_BCHANNEL)
|
if (bch->debug & DEBUG_HW_BCHANNEL)
|
||||||
printk(KERN_DEBUG "hfcpci rec ch(%x) f1(%d) f2(%d)\n",
|
printk(KERN_DEBUG "hfcpci rec ch(%x) f1(%d) f2(%d)\n",
|
||||||
bch->nr, bz->f1, bz->f2);
|
bch->nr, rxbz->f1, rxbz->f2);
|
||||||
zp = &bz->za[bz->f2];
|
zp = &rxbz->za[rxbz->f2];
|
||||||
|
|
||||||
rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2);
|
rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2);
|
||||||
if (rcnt < 0)
|
if (rcnt < 0)
|
||||||
|
@ -630,8 +643,8 @@ main_rec_hfcpci(struct bchannel *bch)
|
||||||
"hfcpci rec ch(%x) z1(%x) z2(%x) cnt(%d)\n",
|
"hfcpci rec ch(%x) z1(%x) z2(%x) cnt(%d)\n",
|
||||||
bch->nr, le16_to_cpu(zp->z1),
|
bch->nr, le16_to_cpu(zp->z1),
|
||||||
le16_to_cpu(zp->z2), rcnt);
|
le16_to_cpu(zp->z2), rcnt);
|
||||||
hfcpci_empty_bfifo(bch, bz, bdata, rcnt);
|
hfcpci_empty_bfifo(bch, rxbz, bdata, rcnt);
|
||||||
rcnt = bz->f1 - bz->f2;
|
rcnt = rxbz->f1 - rxbz->f2;
|
||||||
if (rcnt < 0)
|
if (rcnt < 0)
|
||||||
rcnt += MAX_B_FRAMES + 1;
|
rcnt += MAX_B_FRAMES + 1;
|
||||||
if (hc->hw.last_bfifo_cnt[real_fifo] > rcnt + 1) {
|
if (hc->hw.last_bfifo_cnt[real_fifo] > rcnt + 1) {
|
||||||
|
@ -644,7 +657,7 @@ main_rec_hfcpci(struct bchannel *bch)
|
||||||
else
|
else
|
||||||
receive = 0;
|
receive = 0;
|
||||||
} else if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
|
} else if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
|
||||||
hfcpci_empty_fifo_trans(bch, bz, bdata);
|
hfcpci_empty_fifo_trans(bch, rxbz, txbz, bdata);
|
||||||
return;
|
return;
|
||||||
} else
|
} else
|
||||||
receive = 0;
|
receive = 0;
|
||||||
|
@ -954,6 +967,7 @@ static void
|
||||||
ph_state_nt(struct dchannel *dch)
|
ph_state_nt(struct dchannel *dch)
|
||||||
{
|
{
|
||||||
struct hfc_pci *hc = dch->hw;
|
struct hfc_pci *hc = dch->hw;
|
||||||
|
u_char val;
|
||||||
|
|
||||||
if (dch->debug)
|
if (dch->debug)
|
||||||
printk(KERN_DEBUG "%s: NT newstate %x\n",
|
printk(KERN_DEBUG "%s: NT newstate %x\n",
|
||||||
|
@ -967,7 +981,7 @@ ph_state_nt(struct dchannel *dch)
|
||||||
hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
|
hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
|
||||||
Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
|
Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
|
||||||
/* Clear already pending ints */
|
/* Clear already pending ints */
|
||||||
if (Read_hfc(hc, HFCPCI_INT_S1));
|
val = Read_hfc(hc, HFCPCI_INT_S1);
|
||||||
Write_hfc(hc, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE);
|
Write_hfc(hc, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE);
|
||||||
udelay(10);
|
udelay(10);
|
||||||
Write_hfc(hc, HFCPCI_STATES, 4);
|
Write_hfc(hc, HFCPCI_STATES, 4);
|
||||||
|
@ -1256,8 +1270,7 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol)
|
||||||
rx_slot = (bc>>8) & 0xff;
|
rx_slot = (bc>>8) & 0xff;
|
||||||
tx_slot = (bc>>16) & 0xff;
|
tx_slot = (bc>>16) & 0xff;
|
||||||
bc = bc & 0xff;
|
bc = bc & 0xff;
|
||||||
} else if (test_bit(HFC_CFG_PCM, &hc->cfg) &&
|
} else if (test_bit(HFC_CFG_PCM, &hc->cfg) && (protocol > ISDN_P_NONE))
|
||||||
(protocol > ISDN_P_NONE))
|
|
||||||
printk(KERN_WARNING "%s: no pcm channel id but HFC_CFG_PCM\n",
|
printk(KERN_WARNING "%s: no pcm channel id but HFC_CFG_PCM\n",
|
||||||
__func__);
|
__func__);
|
||||||
if (hc->chanlimit > 1) {
|
if (hc->chanlimit > 1) {
|
||||||
|
@ -1315,8 +1328,8 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol)
|
||||||
case (ISDN_P_B_RAW):
|
case (ISDN_P_B_RAW):
|
||||||
bch->state = protocol;
|
bch->state = protocol;
|
||||||
bch->nr = bc;
|
bch->nr = bc;
|
||||||
hfcpci_clear_fifo_rx(hc, (fifo2 & 2)?1:0);
|
hfcpci_clear_fifo_rx(hc, (fifo2 & 2) ? 1 : 0);
|
||||||
hfcpci_clear_fifo_tx(hc, (fifo2 & 2)?1:0);
|
hfcpci_clear_fifo_tx(hc, (fifo2 & 2) ? 1 : 0);
|
||||||
if (bc & 2) {
|
if (bc & 2) {
|
||||||
hc->hw.sctrl |= SCTRL_B2_ENA;
|
hc->hw.sctrl |= SCTRL_B2_ENA;
|
||||||
hc->hw.sctrl_r |= SCTRL_B2_ENA;
|
hc->hw.sctrl_r |= SCTRL_B2_ENA;
|
||||||
|
@ -1350,8 +1363,8 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol)
|
||||||
case (ISDN_P_B_HDLC):
|
case (ISDN_P_B_HDLC):
|
||||||
bch->state = protocol;
|
bch->state = protocol;
|
||||||
bch->nr = bc;
|
bch->nr = bc;
|
||||||
hfcpci_clear_fifo_rx(hc, (fifo2 & 2)?1:0);
|
hfcpci_clear_fifo_rx(hc, (fifo2 & 2) ? 1 : 0);
|
||||||
hfcpci_clear_fifo_tx(hc, (fifo2 & 2)?1:0);
|
hfcpci_clear_fifo_tx(hc, (fifo2 & 2) ? 1 : 0);
|
||||||
if (bc & 2) {
|
if (bc & 2) {
|
||||||
hc->hw.sctrl |= SCTRL_B2_ENA;
|
hc->hw.sctrl |= SCTRL_B2_ENA;
|
||||||
hc->hw.sctrl_r |= SCTRL_B2_ENA;
|
hc->hw.sctrl_r |= SCTRL_B2_ENA;
|
||||||
|
@ -1445,7 +1458,7 @@ set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan)
|
||||||
switch (protocol) {
|
switch (protocol) {
|
||||||
case (ISDN_P_B_RAW):
|
case (ISDN_P_B_RAW):
|
||||||
bch->state = protocol;
|
bch->state = protocol;
|
||||||
hfcpci_clear_fifo_rx(hc, (chan & 2)?1:0);
|
hfcpci_clear_fifo_rx(hc, (chan & 2) ? 1 : 0);
|
||||||
if (chan & 2) {
|
if (chan & 2) {
|
||||||
hc->hw.sctrl_r |= SCTRL_B2_ENA;
|
hc->hw.sctrl_r |= SCTRL_B2_ENA;
|
||||||
hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX;
|
hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX;
|
||||||
|
@ -1470,7 +1483,7 @@ set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan)
|
||||||
break;
|
break;
|
||||||
case (ISDN_P_B_HDLC):
|
case (ISDN_P_B_HDLC):
|
||||||
bch->state = protocol;
|
bch->state = protocol;
|
||||||
hfcpci_clear_fifo_rx(hc, (chan & 2)?1:0);
|
hfcpci_clear_fifo_rx(hc, (chan & 2) ? 1 : 0);
|
||||||
if (chan & 2) {
|
if (chan & 2) {
|
||||||
hc->hw.sctrl_r |= SCTRL_B2_ENA;
|
hc->hw.sctrl_r |= SCTRL_B2_ENA;
|
||||||
hc->hw.last_bfifo_cnt[1] = 0;
|
hc->hw.last_bfifo_cnt[1] = 0;
|
||||||
|
@ -1793,10 +1806,9 @@ init_card(struct hfc_pci *hc)
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"HFC PCI: IRQ(%d) getting no interrupts "
|
"HFC PCI: IRQ(%d) getting no interrupts "
|
||||||
"during init %d\n", hc->irq, 4 - cnt);
|
"during init %d\n", hc->irq, 4 - cnt);
|
||||||
if (cnt == 1) {
|
if (cnt == 1)
|
||||||
spin_unlock_irqrestore(&hc->lock, flags);
|
break;
|
||||||
return -EIO;
|
else {
|
||||||
} else {
|
|
||||||
reset_hfcpci(hc);
|
reset_hfcpci(hc);
|
||||||
cnt--;
|
cnt--;
|
||||||
}
|
}
|
||||||
|
@ -2035,7 +2047,8 @@ setup_hw(struct hfc_pci *hc)
|
||||||
printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n");
|
printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
hc->hw.pci_io = (char __iomem *)(unsigned long)hc->pdev->resource[1].start;
|
hc->hw.pci_io =
|
||||||
|
(char __iomem *)(unsigned long)hc->pdev->resource[1].start;
|
||||||
|
|
||||||
if (!hc->hw.pci_io) {
|
if (!hc->hw.pci_io) {
|
||||||
printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");
|
printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");
|
||||||
|
@ -2277,7 +2290,7 @@ hfc_remove_pci(struct pci_dev *pdev)
|
||||||
release_card(card);
|
release_card(card);
|
||||||
else
|
else
|
||||||
if (debug)
|
if (debug)
|
||||||
printk(KERN_WARNING "%s: drvdata already removed\n",
|
printk(KERN_DEBUG "%s: drvdata already removed\n",
|
||||||
__func__);
|
__func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -947,7 +947,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
|
||||||
if (fifo->dch)
|
if (fifo->dch)
|
||||||
recv_Dchannel(fifo->dch);
|
recv_Dchannel(fifo->dch);
|
||||||
if (fifo->bch)
|
if (fifo->bch)
|
||||||
recv_Bchannel(fifo->bch);
|
recv_Bchannel(fifo->bch, MISDN_ID_ANY);
|
||||||
if (fifo->ech)
|
if (fifo->ech)
|
||||||
recv_Echannel(fifo->ech,
|
recv_Echannel(fifo->ech,
|
||||||
&hw->dch);
|
&hw->dch);
|
||||||
|
@ -969,7 +969,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
|
||||||
} else {
|
} else {
|
||||||
/* deliver transparent data to layer2 */
|
/* deliver transparent data to layer2 */
|
||||||
if (rx_skb->len >= poll)
|
if (rx_skb->len >= poll)
|
||||||
recv_Bchannel(fifo->bch);
|
recv_Bchannel(fifo->bch, MISDN_ID_ANY);
|
||||||
}
|
}
|
||||||
spin_unlock(&hw->lock);
|
spin_unlock(&hw->lock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,8 +82,9 @@ release_io_hfcpci(struct IsdnCardState *cs)
|
||||||
Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2);
|
Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2);
|
||||||
pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, 0); /* disable memory mapped ports + busmaster */
|
pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, 0); /* disable memory mapped ports + busmaster */
|
||||||
del_timer(&cs->hw.hfcpci.timer);
|
del_timer(&cs->hw.hfcpci.timer);
|
||||||
kfree(cs->hw.hfcpci.share_start);
|
pci_free_consistent(cs->hw.hfcpci.dev, 0x8000,
|
||||||
cs->hw.hfcpci.share_start = NULL;
|
cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma);
|
||||||
|
cs->hw.hfcpci.fifos = NULL;
|
||||||
iounmap((void *)cs->hw.hfcpci.pci_io);
|
iounmap((void *)cs->hw.hfcpci.pci_io);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1663,8 +1664,19 @@ setup_hfcpci(struct IsdnCard *card)
|
||||||
dev_hfcpci);
|
dev_hfcpci);
|
||||||
i++;
|
i++;
|
||||||
if (tmp_hfcpci) {
|
if (tmp_hfcpci) {
|
||||||
|
dma_addr_t dma_mask = DMA_BIT_MASK(32) & ~0x7fffUL;
|
||||||
if (pci_enable_device(tmp_hfcpci))
|
if (pci_enable_device(tmp_hfcpci))
|
||||||
continue;
|
continue;
|
||||||
|
if (pci_set_dma_mask(tmp_hfcpci, dma_mask)) {
|
||||||
|
printk(KERN_WARNING
|
||||||
|
"HiSax hfc_pci: No suitable DMA available.\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pci_set_consistent_dma_mask(tmp_hfcpci, dma_mask)) {
|
||||||
|
printk(KERN_WARNING
|
||||||
|
"HiSax hfc_pci: No suitable consistent DMA available.\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
pci_set_master(tmp_hfcpci);
|
pci_set_master(tmp_hfcpci);
|
||||||
if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK)))
|
if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK)))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1693,22 +1705,29 @@ setup_hfcpci(struct IsdnCard *card)
|
||||||
printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");
|
printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate memory for FIFOS */
|
/* Allocate memory for FIFOS */
|
||||||
/* Because the HFC-PCI needs a 32K physical alignment, we */
|
cs->hw.hfcpci.fifos = pci_alloc_consistent(cs->hw.hfcpci.dev,
|
||||||
/* need to allocate the double mem and align the address */
|
0x8000, &cs->hw.hfcpci.dma);
|
||||||
if (!(cs->hw.hfcpci.share_start = kmalloc(65536, GFP_KERNEL))) {
|
if (!cs->hw.hfcpci.fifos) {
|
||||||
printk(KERN_WARNING "HFC-PCI: Error allocating memory for FIFO!\n");
|
printk(KERN_WARNING "HFC-PCI: Error allocating FIFO memory!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
cs->hw.hfcpci.fifos = (void *)
|
if (cs->hw.hfcpci.dma & 0x7fff) {
|
||||||
(((ulong) cs->hw.hfcpci.share_start) & ~0x7FFF) + 0x8000;
|
printk(KERN_WARNING
|
||||||
pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u_int) virt_to_bus(cs->hw.hfcpci.fifos));
|
"HFC-PCI: Error DMA memory not on 32K boundary (%lx)\n",
|
||||||
|
(u_long)cs->hw.hfcpci.dma);
|
||||||
|
pci_free_consistent(cs->hw.hfcpci.dev, 0x8000,
|
||||||
|
cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u32)cs->hw.hfcpci.dma);
|
||||||
cs->hw.hfcpci.pci_io = ioremap((ulong) cs->hw.hfcpci.pci_io, 256);
|
cs->hw.hfcpci.pci_io = ioremap((ulong) cs->hw.hfcpci.pci_io, 256);
|
||||||
printk(KERN_INFO
|
printk(KERN_INFO
|
||||||
"HFC-PCI: defined at mem %p fifo %p(%#x) IRQ %d HZ %d\n",
|
"HFC-PCI: defined at mem %p fifo %p(%lx) IRQ %d HZ %d\n",
|
||||||
cs->hw.hfcpci.pci_io,
|
cs->hw.hfcpci.pci_io,
|
||||||
cs->hw.hfcpci.fifos,
|
cs->hw.hfcpci.fifos,
|
||||||
(u_int) virt_to_bus(cs->hw.hfcpci.fifos),
|
(u_long)cs->hw.hfcpci.dma,
|
||||||
cs->irq, HZ);
|
cs->irq, HZ);
|
||||||
|
|
||||||
spin_lock_irqsave(&cs->lock, flags);
|
spin_lock_irqsave(&cs->lock, flags);
|
||||||
|
|
|
@ -703,7 +703,7 @@ struct hfcPCI_hw {
|
||||||
int nt_timer;
|
int nt_timer;
|
||||||
struct pci_dev *dev;
|
struct pci_dev *dev;
|
||||||
unsigned char *pci_io; /* start of PCI IO memory */
|
unsigned char *pci_io; /* start of PCI IO memory */
|
||||||
void *share_start; /* shared memory for Fifos start */
|
dma_addr_t dma; /* dma handle for Fifos */
|
||||||
void *fifos; /* FIFO memory */
|
void *fifos; /* FIFO memory */
|
||||||
int last_bfifo_cnt[2]; /* marker saving last b-fifo frame count */
|
int last_bfifo_cnt[2]; /* marker saving last b-fifo frame count */
|
||||||
struct timer_list timer;
|
struct timer_list timer;
|
||||||
|
|
|
@ -67,7 +67,7 @@ hycapi_reset_ctr(struct capi_ctr *ctrl)
|
||||||
printk(KERN_NOTICE "HYCAPI hycapi_reset_ctr\n");
|
printk(KERN_NOTICE "HYCAPI hycapi_reset_ctr\n");
|
||||||
#endif
|
#endif
|
||||||
capilib_release(&cinfo->ncci_head);
|
capilib_release(&cinfo->ncci_head);
|
||||||
capi_ctr_reseted(ctrl);
|
capi_ctr_down(ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************
|
/******************************
|
||||||
|
@ -347,7 +347,7 @@ int hycapi_capi_stop(hysdn_card *card)
|
||||||
if(cinfo) {
|
if(cinfo) {
|
||||||
ctrl = &cinfo->capi_ctrl;
|
ctrl = &cinfo->capi_ctrl;
|
||||||
/* ctrl->suspend_output(ctrl); */
|
/* ctrl->suspend_output(ctrl); */
|
||||||
capi_ctr_reseted(ctrl);
|
capi_ctr_down(ctrl);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,5 +135,3 @@ source "drivers/isdn/act2000/Kconfig"
|
||||||
source "drivers/isdn/hysdn/Kconfig"
|
source "drivers/isdn/hysdn/Kconfig"
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
source "drivers/isdn/gigaset/Kconfig"
|
|
||||||
|
|
|
@ -1069,7 +1069,7 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
|
||||||
lp = isdn_net_get_locked_lp(nd);
|
lp = isdn_net_get_locked_lp(nd);
|
||||||
if (!lp) {
|
if (!lp) {
|
||||||
printk(KERN_WARNING "%s: all channels busy - requeuing!\n", ndev->name);
|
printk(KERN_WARNING "%s: all channels busy - requeuing!\n", ndev->name);
|
||||||
return 1;
|
return NETDEV_TX_BUSY;
|
||||||
}
|
}
|
||||||
/* we have our lp locked from now on */
|
/* we have our lp locked from now on */
|
||||||
|
|
||||||
|
@ -1273,14 +1273,14 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||||
spin_unlock_irqrestore(&dev->lock, flags);
|
spin_unlock_irqrestore(&dev->lock, flags);
|
||||||
isdn_net_dial(); /* Initiate dialing */
|
isdn_net_dial(); /* Initiate dialing */
|
||||||
netif_stop_queue(ndev);
|
netif_stop_queue(ndev);
|
||||||
return 1; /* let upper layer requeue skb packet */
|
return NETDEV_TX_BUSY; /* let upper layer requeue skb packet */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Initiate dialing */
|
/* Initiate dialing */
|
||||||
spin_unlock_irqrestore(&dev->lock, flags);
|
spin_unlock_irqrestore(&dev->lock, flags);
|
||||||
isdn_net_dial();
|
isdn_net_dial();
|
||||||
isdn_net_device_stop_queue(lp);
|
isdn_net_device_stop_queue(lp);
|
||||||
return 1;
|
return NETDEV_TX_BUSY;
|
||||||
} else {
|
} else {
|
||||||
isdn_net_unreachable(ndev, skb,
|
isdn_net_unreachable(ndev, skb,
|
||||||
"No phone number");
|
"No phone number");
|
||||||
|
|
|
@ -1592,7 +1592,7 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp)
|
||||||
int retval, line;
|
int retval, line;
|
||||||
|
|
||||||
line = tty->index;
|
line = tty->index;
|
||||||
if (line < 0 || line > ISDN_MAX_CHANNELS)
|
if (line < 0 || line >= ISDN_MAX_CHANNELS)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
info = &dev->mdm.info[line];
|
info = &dev->mdm.info[line];
|
||||||
if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open"))
|
if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open"))
|
||||||
|
|
|
@ -214,7 +214,7 @@ get_free_devid(void)
|
||||||
if (!test_and_set_bit(i, (u_long *)&device_ids))
|
if (!test_and_set_bit(i, (u_long *)&device_ids))
|
||||||
break;
|
break;
|
||||||
if (i > MAX_DEVICE_ID)
|
if (i > MAX_DEVICE_ID)
|
||||||
return -1;
|
return -EBUSY;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,10 +224,10 @@ mISDN_register_device(struct mISDNdevice *dev,
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
dev->id = get_free_devid();
|
err = get_free_devid();
|
||||||
err = -EBUSY;
|
if (err < 0)
|
||||||
if (dev->id < 0)
|
|
||||||
goto error1;
|
goto error1;
|
||||||
|
dev->id = err;
|
||||||
|
|
||||||
device_initialize(&dev->dev);
|
device_initialize(&dev->dev);
|
||||||
if (name && name[0])
|
if (name && name[0])
|
||||||
|
|
|
@ -112,9 +112,11 @@ struct dsp_conf {
|
||||||
|
|
||||||
#define DSP_DTMF_NPOINTS 102
|
#define DSP_DTMF_NPOINTS 102
|
||||||
|
|
||||||
#define ECHOCAN_BUFLEN (4*128)
|
#define ECHOCAN_BUFF_SIZE 0x400 /* must be 2**n */
|
||||||
|
#define ECHOCAN_BUFF_MASK 0x3ff /* -1 */
|
||||||
|
|
||||||
struct dsp_dtmf {
|
struct dsp_dtmf {
|
||||||
|
int enable; /* dtmf is enabled */
|
||||||
int treshold; /* above this is dtmf (square of) */
|
int treshold; /* above this is dtmf (square of) */
|
||||||
int software; /* dtmf uses software decoding */
|
int software; /* dtmf uses software decoding */
|
||||||
int hardware; /* dtmf uses hardware decoding */
|
int hardware; /* dtmf uses hardware decoding */
|
||||||
|
@ -123,7 +125,7 @@ struct dsp_dtmf {
|
||||||
/* buffers one full dtmf frame */
|
/* buffers one full dtmf frame */
|
||||||
u8 lastwhat, lastdigit;
|
u8 lastwhat, lastdigit;
|
||||||
int count;
|
int count;
|
||||||
u8 digits[16]; /* just the dtmf result */
|
u8 digits[16]; /* dtmf result */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -150,6 +152,15 @@ struct dsp_tone {
|
||||||
struct timer_list tl;
|
struct timer_list tl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/***************
|
||||||
|
* echo stuff *
|
||||||
|
***************/
|
||||||
|
|
||||||
|
struct dsp_echo {
|
||||||
|
int software; /* echo is generated by software */
|
||||||
|
int hardware; /* echo is generated by hardware */
|
||||||
|
};
|
||||||
|
|
||||||
/*****************
|
/*****************
|
||||||
* general stuff *
|
* general stuff *
|
||||||
*****************/
|
*****************/
|
||||||
|
@ -160,7 +171,7 @@ struct dsp {
|
||||||
struct mISDNchannel *up;
|
struct mISDNchannel *up;
|
||||||
unsigned char name[64];
|
unsigned char name[64];
|
||||||
int b_active;
|
int b_active;
|
||||||
int echo; /* echo is enabled */
|
struct dsp_echo echo;
|
||||||
int rx_disabled; /* what the user wants */
|
int rx_disabled; /* what the user wants */
|
||||||
int rx_is_off; /* what the card is */
|
int rx_is_off; /* what the card is */
|
||||||
int tx_mix;
|
int tx_mix;
|
||||||
|
@ -261,5 +272,5 @@ extern int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg);
|
||||||
extern void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data,
|
extern void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data,
|
||||||
int len);
|
int len);
|
||||||
extern void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data,
|
extern void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data,
|
||||||
int len);
|
int len, unsigned int txlen);
|
||||||
|
|
||||||
|
|
|
@ -210,9 +210,8 @@ dsp_audio_generate_seven(void)
|
||||||
j = 0;
|
j = 0;
|
||||||
for (k = 0; k < 256; k++) {
|
for (k = 0; k < 256; k++) {
|
||||||
if (dsp_audio_alaw_to_s32[k]
|
if (dsp_audio_alaw_to_s32[k]
|
||||||
< dsp_audio_alaw_to_s32[i]) {
|
< dsp_audio_alaw_to_s32[i])
|
||||||
j++;
|
j++;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sorted_alaw[j] = i;
|
sorted_alaw[j] = i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,8 +163,9 @@ dsp_cmx_debug(struct dsp *dsp)
|
||||||
|
|
||||||
printk(KERN_DEBUG "-----Current DSP\n");
|
printk(KERN_DEBUG "-----Current DSP\n");
|
||||||
list_for_each_entry(odsp, &dsp_ilist, list) {
|
list_for_each_entry(odsp, &dsp_ilist, list) {
|
||||||
printk(KERN_DEBUG "* %s echo=%d txmix=%d",
|
printk(KERN_DEBUG "* %s hardecho=%d softecho=%d txmix=%d",
|
||||||
odsp->name, odsp->echo, odsp->tx_mix);
|
odsp->name, odsp->echo.hardware, odsp->echo.software,
|
||||||
|
odsp->tx_mix);
|
||||||
if (odsp->conf)
|
if (odsp->conf)
|
||||||
printk(" (Conf %d)", odsp->conf->id);
|
printk(" (Conf %d)", odsp->conf->id);
|
||||||
if (dsp == odsp)
|
if (dsp == odsp)
|
||||||
|
@ -177,10 +178,12 @@ dsp_cmx_debug(struct dsp *dsp)
|
||||||
list_for_each_entry(member, &conf->mlist, list) {
|
list_for_each_entry(member, &conf->mlist, list) {
|
||||||
printk(KERN_DEBUG
|
printk(KERN_DEBUG
|
||||||
" - member = %s (slot_tx %d, bank_tx %d, "
|
" - member = %s (slot_tx %d, bank_tx %d, "
|
||||||
"slot_rx %d, bank_rx %d hfc_conf %d)%s\n",
|
"slot_rx %d, bank_rx %d hfc_conf %d "
|
||||||
|
"tx_data %d rx_is_off %d)%s\n",
|
||||||
member->dsp->name, member->dsp->pcm_slot_tx,
|
member->dsp->name, member->dsp->pcm_slot_tx,
|
||||||
member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx,
|
member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx,
|
||||||
member->dsp->pcm_bank_rx, member->dsp->hfc_conf,
|
member->dsp->pcm_bank_rx, member->dsp->hfc_conf,
|
||||||
|
member->dsp->tx_data, member->dsp->rx_is_off,
|
||||||
(member->dsp == dsp) ? " *this*" : "");
|
(member->dsp == dsp) ? " *this*" : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,7 +238,7 @@ dsp_cmx_add_conf_member(struct dsp *dsp, struct dsp_conf *conf)
|
||||||
|
|
||||||
member = kzalloc(sizeof(struct dsp_conf_member), GFP_ATOMIC);
|
member = kzalloc(sizeof(struct dsp_conf_member), GFP_ATOMIC);
|
||||||
if (!member) {
|
if (!member) {
|
||||||
printk(KERN_ERR "kmalloc struct dsp_conf_member failed\n");
|
printk(KERN_ERR "kzalloc struct dsp_conf_member failed\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
member->dsp = dsp;
|
member->dsp = dsp;
|
||||||
|
@ -314,7 +317,7 @@ static struct dsp_conf
|
||||||
|
|
||||||
conf = kzalloc(sizeof(struct dsp_conf), GFP_ATOMIC);
|
conf = kzalloc(sizeof(struct dsp_conf), GFP_ATOMIC);
|
||||||
if (!conf) {
|
if (!conf) {
|
||||||
printk(KERN_ERR "kmalloc struct dsp_conf failed\n");
|
printk(KERN_ERR "kzalloc struct dsp_conf failed\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
INIT_LIST_HEAD(&conf->mlist);
|
INIT_LIST_HEAD(&conf->mlist);
|
||||||
|
@ -385,7 +388,7 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
|
||||||
int freeunits[8];
|
int freeunits[8];
|
||||||
u_char freeslots[256];
|
u_char freeslots[256];
|
||||||
int same_hfc = -1, same_pcm = -1, current_conf = -1,
|
int same_hfc = -1, same_pcm = -1, current_conf = -1,
|
||||||
all_conf = 1;
|
all_conf = 1, tx_data = 0;
|
||||||
|
|
||||||
/* dsp gets updated (no conf) */
|
/* dsp gets updated (no conf) */
|
||||||
if (!conf) {
|
if (!conf) {
|
||||||
|
@ -409,7 +412,7 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
|
||||||
/* process hw echo */
|
/* process hw echo */
|
||||||
if (dsp->features.pcm_banks < 1)
|
if (dsp->features.pcm_banks < 1)
|
||||||
return;
|
return;
|
||||||
if (!dsp->echo) {
|
if (!dsp->echo.software && !dsp->echo.hardware) {
|
||||||
/* NO ECHO: remove PCM slot if assigned */
|
/* NO ECHO: remove PCM slot if assigned */
|
||||||
if (dsp->pcm_slot_tx >= 0 || dsp->pcm_slot_rx >= 0) {
|
if (dsp->pcm_slot_tx >= 0 || dsp->pcm_slot_rx >= 0) {
|
||||||
if (dsp_debug & DEBUG_DSP_CMX)
|
if (dsp_debug & DEBUG_DSP_CMX)
|
||||||
|
@ -427,10 +430,15 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* echo is enabled, find out if we use soft or hardware */
|
||||||
|
dsp->echo.software = dsp->tx_data;
|
||||||
|
dsp->echo.hardware = 0;
|
||||||
/* ECHO: already echo */
|
/* ECHO: already echo */
|
||||||
if (dsp->pcm_slot_tx >= 0 && dsp->pcm_slot_rx < 0 &&
|
if (dsp->pcm_slot_tx >= 0 && dsp->pcm_slot_rx < 0 &&
|
||||||
dsp->pcm_bank_tx == 2 && dsp->pcm_bank_rx == 2)
|
dsp->pcm_bank_tx == 2 && dsp->pcm_bank_rx == 2) {
|
||||||
|
dsp->echo.hardware = 1;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
/* ECHO: if slot already assigned */
|
/* ECHO: if slot already assigned */
|
||||||
if (dsp->pcm_slot_tx >= 0) {
|
if (dsp->pcm_slot_tx >= 0) {
|
||||||
dsp->pcm_slot_rx = dsp->pcm_slot_tx;
|
dsp->pcm_slot_rx = dsp->pcm_slot_tx;
|
||||||
|
@ -443,6 +451,7 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
|
||||||
dsp->pcm_slot_tx);
|
dsp->pcm_slot_tx);
|
||||||
dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
|
dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
|
||||||
dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
|
dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
|
||||||
|
dsp->echo.hardware = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* ECHO: find slot */
|
/* ECHO: find slot */
|
||||||
|
@ -472,6 +481,7 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
|
||||||
"%s no slot available for echo\n",
|
"%s no slot available for echo\n",
|
||||||
__func__);
|
__func__);
|
||||||
/* no more slots available */
|
/* no more slots available */
|
||||||
|
dsp->echo.software = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* assign free slot */
|
/* assign free slot */
|
||||||
|
@ -485,6 +495,7 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
|
||||||
__func__, dsp->name, dsp->pcm_slot_tx);
|
__func__, dsp->name, dsp->pcm_slot_tx);
|
||||||
dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
|
dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
|
||||||
dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
|
dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
|
||||||
|
dsp->echo.hardware = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,7 +565,7 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* check if member has echo turned on */
|
/* check if member has echo turned on */
|
||||||
if (member->dsp->echo) {
|
if (member->dsp->echo.hardware || member->dsp->echo.software) {
|
||||||
if (dsp_debug & DEBUG_DSP_CMX)
|
if (dsp_debug & DEBUG_DSP_CMX)
|
||||||
printk(KERN_DEBUG
|
printk(KERN_DEBUG
|
||||||
"%s dsp %s cannot form a conf, because "
|
"%s dsp %s cannot form a conf, because "
|
||||||
|
@ -592,10 +603,9 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
|
||||||
if (member->dsp->tx_data) {
|
if (member->dsp->tx_data) {
|
||||||
if (dsp_debug & DEBUG_DSP_CMX)
|
if (dsp_debug & DEBUG_DSP_CMX)
|
||||||
printk(KERN_DEBUG
|
printk(KERN_DEBUG
|
||||||
"%s dsp %s cannot form a conf, because "
|
"%s dsp %s tx_data is turned on\n",
|
||||||
"tx_data is turned on\n",
|
|
||||||
__func__, member->dsp->name);
|
__func__, member->dsp->name);
|
||||||
goto conf_software;
|
tx_data = 1;
|
||||||
}
|
}
|
||||||
/* check if pipeline exists */
|
/* check if pipeline exists */
|
||||||
if (member->dsp->pipeline.inuse) {
|
if (member->dsp->pipeline.inuse) {
|
||||||
|
@ -794,7 +804,7 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
|
||||||
nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
|
nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
|
||||||
nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
|
nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
|
||||||
conf->hardware = 1;
|
conf->hardware = 1;
|
||||||
conf->software = 0;
|
conf->software = tx_data;
|
||||||
return;
|
return;
|
||||||
/* if members have one bank (or on the same chip) */
|
/* if members have one bank (or on the same chip) */
|
||||||
} else {
|
} else {
|
||||||
|
@ -904,7 +914,7 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
|
||||||
nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
|
nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
|
||||||
nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
|
nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
|
||||||
conf->hardware = 1;
|
conf->hardware = 1;
|
||||||
conf->software = 0;
|
conf->software = tx_data;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -937,6 +947,10 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
|
||||||
if (current_conf >= 0) {
|
if (current_conf >= 0) {
|
||||||
join_members:
|
join_members:
|
||||||
list_for_each_entry(member, &conf->mlist, list) {
|
list_for_each_entry(member, &conf->mlist, list) {
|
||||||
|
/* if no conference engine on our chip, change to
|
||||||
|
* software */
|
||||||
|
if (!member->dsp->features.hfc_conf)
|
||||||
|
goto conf_software;
|
||||||
/* in case of hdlc, change to software */
|
/* in case of hdlc, change to software */
|
||||||
if (member->dsp->hdlc)
|
if (member->dsp->hdlc)
|
||||||
goto conf_software;
|
goto conf_software;
|
||||||
|
@ -1295,17 +1309,25 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
|
||||||
int r, rr, t, tt, o_r, o_rr;
|
int r, rr, t, tt, o_r, o_rr;
|
||||||
int preload = 0;
|
int preload = 0;
|
||||||
struct mISDNhead *hh, *thh;
|
struct mISDNhead *hh, *thh;
|
||||||
|
int tx_data_only = 0;
|
||||||
|
|
||||||
/* don't process if: */
|
/* don't process if: */
|
||||||
if (!dsp->b_active) { /* if not active */
|
if (!dsp->b_active) { /* if not active */
|
||||||
dsp->last_tx = 0;
|
dsp->last_tx = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (dsp->pcm_slot_tx >= 0 && /* connected to pcm slot */
|
if (((dsp->conf && dsp->conf->hardware) || /* hardware conf */
|
||||||
|
dsp->echo.hardware) && /* OR hardware echo */
|
||||||
dsp->tx_R == dsp->tx_W && /* AND no tx-data */
|
dsp->tx_R == dsp->tx_W && /* AND no tx-data */
|
||||||
!(dsp->tone.tone && dsp->tone.software)) { /* AND not soft tones */
|
!(dsp->tone.tone && dsp->tone.software)) { /* AND not soft tones */
|
||||||
dsp->last_tx = 0;
|
if (!dsp->tx_data) { /* no tx_data for user space required */
|
||||||
return;
|
dsp->last_tx = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (dsp->conf && dsp->conf->software && dsp->conf->hardware)
|
||||||
|
tx_data_only = 1;
|
||||||
|
if (dsp->conf->software && dsp->echo.hardware)
|
||||||
|
tx_data_only = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CMX_DEBUG
|
#ifdef CMX_DEBUG
|
||||||
|
@ -1367,7 +1389,8 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
|
||||||
while (r != rr && t != tt) {
|
while (r != rr && t != tt) {
|
||||||
#ifdef CMX_TX_DEBUG
|
#ifdef CMX_TX_DEBUG
|
||||||
if (strlen(debugbuf) < 48)
|
if (strlen(debugbuf) < 48)
|
||||||
sprintf(debugbuf+strlen(debugbuf), " %02x", p[t]);
|
sprintf(debugbuf+strlen(debugbuf), " %02x",
|
||||||
|
p[t]);
|
||||||
#endif
|
#endif
|
||||||
*d++ = p[t]; /* write tx_buff */
|
*d++ = p[t]; /* write tx_buff */
|
||||||
t = (t+1) & CMX_BUFF_MASK;
|
t = (t+1) & CMX_BUFF_MASK;
|
||||||
|
@ -1388,7 +1411,7 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
|
||||||
/* PROCESS DATA (one member / no conf) */
|
/* PROCESS DATA (one member / no conf) */
|
||||||
if (!conf || members <= 1) {
|
if (!conf || members <= 1) {
|
||||||
/* -> if echo is NOT enabled */
|
/* -> if echo is NOT enabled */
|
||||||
if (!dsp->echo) {
|
if (!dsp->echo.software) {
|
||||||
/* -> send tx-data if available or use 0-volume */
|
/* -> send tx-data if available or use 0-volume */
|
||||||
while (r != rr && t != tt) {
|
while (r != rr && t != tt) {
|
||||||
*d++ = p[t]; /* write tx_buff */
|
*d++ = p[t]; /* write tx_buff */
|
||||||
|
@ -1438,7 +1461,7 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
|
||||||
o_r = (o_rr - rr + r) & CMX_BUFF_MASK;
|
o_r = (o_rr - rr + r) & CMX_BUFF_MASK;
|
||||||
/* start rx-pointer at current read position*/
|
/* start rx-pointer at current read position*/
|
||||||
/* -> if echo is NOT enabled */
|
/* -> if echo is NOT enabled */
|
||||||
if (!dsp->echo) {
|
if (!dsp->echo.software) {
|
||||||
/*
|
/*
|
||||||
* -> copy other member's rx-data,
|
* -> copy other member's rx-data,
|
||||||
* if tx-data is available, mix
|
* if tx-data is available, mix
|
||||||
|
@ -1486,7 +1509,7 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
|
||||||
#endif
|
#endif
|
||||||
/* PROCESS DATA (three or more members) */
|
/* PROCESS DATA (three or more members) */
|
||||||
/* -> if echo is NOT enabled */
|
/* -> if echo is NOT enabled */
|
||||||
if (!dsp->echo) {
|
if (!dsp->echo.software) {
|
||||||
/*
|
/*
|
||||||
* -> substract rx-data from conf-data,
|
* -> substract rx-data from conf-data,
|
||||||
* if tx-data is available, mix
|
* if tx-data is available, mix
|
||||||
|
@ -1550,27 +1573,40 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
|
||||||
* becuase we want what we send, not what we filtered
|
* becuase we want what we send, not what we filtered
|
||||||
*/
|
*/
|
||||||
if (dsp->tx_data) {
|
if (dsp->tx_data) {
|
||||||
/* PREPARE RESULT */
|
if (tx_data_only) {
|
||||||
txskb = mI_alloc_skb(len, GFP_ATOMIC);
|
hh->prim = DL_DATA_REQ;
|
||||||
if (!txskb) {
|
hh->id = 0;
|
||||||
printk(KERN_ERR
|
/* queue and trigger */
|
||||||
"FATAL ERROR in mISDN_dsp.o: "
|
skb_queue_tail(&dsp->sendq, nskb);
|
||||||
"cannot alloc %d bytes\n", len);
|
schedule_work(&dsp->workq);
|
||||||
|
/* exit because only tx_data is used */
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
thh = mISDN_HEAD_P(txskb);
|
txskb = mI_alloc_skb(len, GFP_ATOMIC);
|
||||||
thh->prim = DL_DATA_REQ;
|
if (!txskb) {
|
||||||
thh->id = 0;
|
printk(KERN_ERR
|
||||||
memcpy(skb_put(txskb, len), nskb->data+preload, len);
|
"FATAL ERROR in mISDN_dsp.o: "
|
||||||
/* queue (trigger later) */
|
"cannot alloc %d bytes\n", len);
|
||||||
skb_queue_tail(&dsp->sendq, txskb);
|
} else {
|
||||||
|
thh = mISDN_HEAD_P(txskb);
|
||||||
|
thh->prim = DL_DATA_REQ;
|
||||||
|
thh->id = 0;
|
||||||
|
memcpy(skb_put(txskb, len), nskb->data+preload,
|
||||||
|
len);
|
||||||
|
/* queue (trigger later) */
|
||||||
|
skb_queue_tail(&dsp->sendq, txskb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* send data only to card, if we don't just calculated tx_data */
|
||||||
/* adjust volume */
|
/* adjust volume */
|
||||||
if (dsp->tx_volume)
|
if (dsp->tx_volume)
|
||||||
dsp_change_volume(nskb, dsp->tx_volume);
|
dsp_change_volume(nskb, dsp->tx_volume);
|
||||||
/* pipeline */
|
/* pipeline */
|
||||||
if (dsp->pipeline.inuse)
|
if (dsp->pipeline.inuse)
|
||||||
dsp_pipeline_process_tx(&dsp->pipeline, nskb->data, nskb->len);
|
dsp_pipeline_process_tx(&dsp->pipeline, nskb->data,
|
||||||
|
nskb->len);
|
||||||
/* crypt */
|
/* crypt */
|
||||||
if (dsp->bf_enable)
|
if (dsp->bf_enable)
|
||||||
dsp_bf_encrypt(dsp, nskb->data, nskb->len);
|
dsp_bf_encrypt(dsp, nskb->data, nskb->len);
|
||||||
|
@ -1592,7 +1628,8 @@ dsp_cmx_send(void *arg)
|
||||||
struct dsp_conf_member *member;
|
struct dsp_conf_member *member;
|
||||||
struct dsp *dsp;
|
struct dsp *dsp;
|
||||||
int mustmix, members;
|
int mustmix, members;
|
||||||
s32 mixbuffer[MAX_POLL+100], *c;
|
static s32 mixbuffer[MAX_POLL+100];
|
||||||
|
s32 *c;
|
||||||
u8 *p, *q;
|
u8 *p, *q;
|
||||||
int r, rr;
|
int r, rr;
|
||||||
int jittercheck = 0, delay, i;
|
int jittercheck = 0, delay, i;
|
||||||
|
@ -1890,10 +1927,8 @@ dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb)
|
||||||
|
|
||||||
/* no conf */
|
/* no conf */
|
||||||
if (!dsp->conf) {
|
if (!dsp->conf) {
|
||||||
/* in case of hardware (echo) */
|
/* in case of software echo */
|
||||||
if (dsp->pcm_slot_tx >= 0)
|
if (dsp->echo.software) {
|
||||||
return;
|
|
||||||
if (dsp->echo) {
|
|
||||||
nskb = skb_clone(skb, GFP_ATOMIC);
|
nskb = skb_clone(skb, GFP_ATOMIC);
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
hh = mISDN_HEAD_P(nskb);
|
hh = mISDN_HEAD_P(nskb);
|
||||||
|
@ -1909,7 +1944,7 @@ dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb)
|
||||||
if (dsp->conf->hardware)
|
if (dsp->conf->hardware)
|
||||||
return;
|
return;
|
||||||
list_for_each_entry(member, &dsp->conf->mlist, list) {
|
list_for_each_entry(member, &dsp->conf->mlist, list) {
|
||||||
if (dsp->echo || member->dsp != dsp) {
|
if (dsp->echo.software || member->dsp != dsp) {
|
||||||
nskb = skb_clone(skb, GFP_ATOMIC);
|
nskb = skb_clone(skb, GFP_ATOMIC);
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
hh = mISDN_HEAD_P(nskb);
|
hh = mISDN_HEAD_P(nskb);
|
||||||
|
|
|
@ -203,13 +203,13 @@ dsp_rx_off_member(struct dsp *dsp)
|
||||||
else if (dsp->dtmf.software)
|
else if (dsp->dtmf.software)
|
||||||
rx_off = 0;
|
rx_off = 0;
|
||||||
/* echo in software */
|
/* echo in software */
|
||||||
else if (dsp->echo && dsp->pcm_slot_tx < 0)
|
else if (dsp->echo.software)
|
||||||
rx_off = 0;
|
rx_off = 0;
|
||||||
/* bridge in software */
|
/* bridge in software */
|
||||||
else if (dsp->conf) {
|
else if (dsp->conf && dsp->conf->software)
|
||||||
if (dsp->conf->software)
|
rx_off = 0;
|
||||||
rx_off = 0;
|
/* data is not required by user space and not required
|
||||||
}
|
* for echo dtmf detection, soft-echo, soft-bridging */
|
||||||
|
|
||||||
if (rx_off == dsp->rx_is_off)
|
if (rx_off == dsp->rx_is_off)
|
||||||
return;
|
return;
|
||||||
|
@ -280,7 +280,7 @@ dsp_fill_empty(struct dsp *dsp)
|
||||||
static int
|
static int
|
||||||
dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
|
dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct sk_buff *nskb;
|
struct sk_buff *nskb;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int cont;
|
int cont;
|
||||||
u8 *data;
|
u8 *data;
|
||||||
|
@ -306,15 +306,18 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
|
||||||
"to %d\n", *((int *)data));
|
"to %d\n", *((int *)data));
|
||||||
dsp->dtmf.treshold = (*(int *)data) * 10000;
|
dsp->dtmf.treshold = (*(int *)data) * 10000;
|
||||||
}
|
}
|
||||||
|
dsp->dtmf.enable = 1;
|
||||||
/* init goertzel */
|
/* init goertzel */
|
||||||
dsp_dtmf_goertzel_init(dsp);
|
dsp_dtmf_goertzel_init(dsp);
|
||||||
|
|
||||||
/* check dtmf hardware */
|
/* check dtmf hardware */
|
||||||
dsp_dtmf_hardware(dsp);
|
dsp_dtmf_hardware(dsp);
|
||||||
|
dsp_rx_off(dsp);
|
||||||
break;
|
break;
|
||||||
case DTMF_TONE_STOP: /* turn off DTMF */
|
case DTMF_TONE_STOP: /* turn off DTMF */
|
||||||
if (dsp_debug & DEBUG_DSP_CORE)
|
if (dsp_debug & DEBUG_DSP_CORE)
|
||||||
printk(KERN_DEBUG "%s: stop dtmf\n", __func__);
|
printk(KERN_DEBUG "%s: stop dtmf\n", __func__);
|
||||||
|
dsp->dtmf.enable = 0;
|
||||||
dsp->dtmf.hardware = 0;
|
dsp->dtmf.hardware = 0;
|
||||||
dsp->dtmf.software = 0;
|
dsp->dtmf.software = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -414,7 +417,7 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
|
||||||
dsp_rx_off(dsp);
|
dsp_rx_off(dsp);
|
||||||
break;
|
break;
|
||||||
case DSP_ECHO_ON: /* enable echo */
|
case DSP_ECHO_ON: /* enable echo */
|
||||||
dsp->echo = 1; /* soft echo */
|
dsp->echo.software = 1; /* soft echo */
|
||||||
if (dsp_debug & DEBUG_DSP_CORE)
|
if (dsp_debug & DEBUG_DSP_CORE)
|
||||||
printk(KERN_DEBUG "%s: enable cmx-echo\n", __func__);
|
printk(KERN_DEBUG "%s: enable cmx-echo\n", __func__);
|
||||||
dsp_cmx_hardware(dsp->conf, dsp);
|
dsp_cmx_hardware(dsp->conf, dsp);
|
||||||
|
@ -423,7 +426,8 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
|
||||||
dsp_cmx_debug(dsp);
|
dsp_cmx_debug(dsp);
|
||||||
break;
|
break;
|
||||||
case DSP_ECHO_OFF: /* disable echo */
|
case DSP_ECHO_OFF: /* disable echo */
|
||||||
dsp->echo = 0;
|
dsp->echo.software = 0;
|
||||||
|
dsp->echo.hardware = 0;
|
||||||
if (dsp_debug & DEBUG_DSP_CORE)
|
if (dsp_debug & DEBUG_DSP_CORE)
|
||||||
printk(KERN_DEBUG "%s: disable cmx-echo\n", __func__);
|
printk(KERN_DEBUG "%s: disable cmx-echo\n", __func__);
|
||||||
dsp_cmx_hardware(dsp->conf, dsp);
|
dsp_cmx_hardware(dsp->conf, dsp);
|
||||||
|
@ -556,7 +560,7 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
|
||||||
dsp->pipeline.inuse = 1;
|
dsp->pipeline.inuse = 1;
|
||||||
dsp_cmx_hardware(dsp->conf, dsp);
|
dsp_cmx_hardware(dsp->conf, dsp);
|
||||||
ret = dsp_pipeline_build(&dsp->pipeline,
|
ret = dsp_pipeline_build(&dsp->pipeline,
|
||||||
len > 0 ? (char *)data : NULL);
|
len > 0 ? data : NULL);
|
||||||
dsp_cmx_hardware(dsp->conf, dsp);
|
dsp_cmx_hardware(dsp->conf, dsp);
|
||||||
dsp_rx_off(dsp);
|
dsp_rx_off(dsp);
|
||||||
}
|
}
|
||||||
|
@ -657,11 +661,10 @@ get_features(struct mISDNchannel *ch)
|
||||||
static int
|
static int
|
||||||
dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
|
dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct dsp *dsp = container_of(ch, struct dsp, ch);
|
struct dsp *dsp = container_of(ch, struct dsp, ch);
|
||||||
struct mISDNhead *hh;
|
struct mISDNhead *hh;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
u8 *digits;
|
u8 *digits = NULL;
|
||||||
int cont;
|
|
||||||
u_long flags;
|
u_long flags;
|
||||||
|
|
||||||
hh = mISDN_HEAD_P(skb);
|
hh = mISDN_HEAD_P(skb);
|
||||||
|
@ -704,50 +707,55 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dsp_lock, flags);
|
||||||
|
|
||||||
/* decrypt if enabled */
|
/* decrypt if enabled */
|
||||||
if (dsp->bf_enable)
|
if (dsp->bf_enable)
|
||||||
dsp_bf_decrypt(dsp, skb->data, skb->len);
|
dsp_bf_decrypt(dsp, skb->data, skb->len);
|
||||||
/* pipeline */
|
/* pipeline */
|
||||||
if (dsp->pipeline.inuse)
|
if (dsp->pipeline.inuse)
|
||||||
dsp_pipeline_process_rx(&dsp->pipeline, skb->data,
|
dsp_pipeline_process_rx(&dsp->pipeline, skb->data,
|
||||||
skb->len);
|
skb->len, hh->id);
|
||||||
/* change volume if requested */
|
/* change volume if requested */
|
||||||
if (dsp->rx_volume)
|
if (dsp->rx_volume)
|
||||||
dsp_change_volume(skb, dsp->rx_volume);
|
dsp_change_volume(skb, dsp->rx_volume);
|
||||||
|
|
||||||
/* check if dtmf soft decoding is turned on */
|
/* check if dtmf soft decoding is turned on */
|
||||||
if (dsp->dtmf.software) {
|
if (dsp->dtmf.software) {
|
||||||
digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
|
digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
|
||||||
skb->len, (dsp_options&DSP_OPT_ULAW)?1:0);
|
skb->len, (dsp_options&DSP_OPT_ULAW) ? 1 : 0);
|
||||||
|
}
|
||||||
|
/* we need to process receive data if software */
|
||||||
|
if (dsp->conf && dsp->conf->software) {
|
||||||
|
/* process data from card at cmx */
|
||||||
|
dsp_cmx_receive(dsp, skb);
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dsp_lock, flags);
|
||||||
|
|
||||||
|
/* send dtmf result, if any */
|
||||||
|
if (digits) {
|
||||||
while (*digits) {
|
while (*digits) {
|
||||||
|
int k;
|
||||||
struct sk_buff *nskb;
|
struct sk_buff *nskb;
|
||||||
if (dsp_debug & DEBUG_DSP_DTMF)
|
if (dsp_debug & DEBUG_DSP_DTMF)
|
||||||
printk(KERN_DEBUG "%s: digit"
|
printk(KERN_DEBUG "%s: digit"
|
||||||
"(%c) to layer %s\n",
|
"(%c) to layer %s\n",
|
||||||
__func__, *digits, dsp->name);
|
__func__, *digits, dsp->name);
|
||||||
cont = DTMF_TONE_VAL | *digits;
|
k = *digits | DTMF_TONE_VAL;
|
||||||
nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
|
nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
|
||||||
MISDN_ID_ANY, sizeof(int), &cont,
|
MISDN_ID_ANY, sizeof(int), &k,
|
||||||
GFP_ATOMIC);
|
GFP_ATOMIC);
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
if (dsp->up) {
|
if (dsp->up) {
|
||||||
if (dsp->up->send(
|
if (dsp->up->send(
|
||||||
dsp->up, nskb))
|
dsp->up, nskb))
|
||||||
dev_kfree_skb(nskb);
|
dev_kfree_skb(nskb);
|
||||||
} else
|
} else
|
||||||
dev_kfree_skb(nskb);
|
dev_kfree_skb(nskb);
|
||||||
}
|
}
|
||||||
digits++;
|
digits++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* we need to process receive data if software */
|
|
||||||
spin_lock_irqsave(&dsp_lock, flags);
|
|
||||||
if (dsp->pcm_slot_tx < 0 && dsp->pcm_slot_rx < 0) {
|
|
||||||
/* process data from card at cmx */
|
|
||||||
dsp_cmx_receive(dsp, skb);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&dsp_lock, flags);
|
|
||||||
|
|
||||||
if (dsp->rx_disabled) {
|
if (dsp->rx_disabled) {
|
||||||
/* if receive is not allowed */
|
/* if receive is not allowed */
|
||||||
break;
|
break;
|
||||||
|
@ -787,7 +795,7 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
|
||||||
if (dsp->up) {
|
if (dsp->up) {
|
||||||
if (dsp->up->send(
|
if (dsp->up->send(
|
||||||
dsp->up, nskb))
|
dsp->up, nskb))
|
||||||
dev_kfree_skb(nskb);
|
dev_kfree_skb(nskb);
|
||||||
} else
|
} else
|
||||||
dev_kfree_skb(nskb);
|
dev_kfree_skb(nskb);
|
||||||
}
|
}
|
||||||
|
@ -946,7 +954,7 @@ dsp_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (debug & DEBUG_DSP_CTRL)
|
if (debug & DEBUG_DSP_CTRL)
|
||||||
printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);
|
printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case OPEN_CHANNEL:
|
case OPEN_CHANNEL:
|
||||||
|
@ -1169,9 +1177,9 @@ static int dsp_init(void)
|
||||||
|
|
||||||
/* init conversion tables */
|
/* init conversion tables */
|
||||||
dsp_audio_generate_law_tables();
|
dsp_audio_generate_law_tables();
|
||||||
dsp_silence = (dsp_options&DSP_OPT_ULAW)?0xff:0x2a;
|
dsp_silence = (dsp_options&DSP_OPT_ULAW) ? 0xff : 0x2a;
|
||||||
dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW)?dsp_audio_ulaw_to_s32:
|
dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW) ?
|
||||||
dsp_audio_alaw_to_s32;
|
dsp_audio_ulaw_to_s32 : dsp_audio_alaw_to_s32;
|
||||||
dsp_audio_generate_s2law_table();
|
dsp_audio_generate_s2law_table();
|
||||||
dsp_audio_generate_seven();
|
dsp_audio_generate_seven();
|
||||||
dsp_audio_generate_mix_table();
|
dsp_audio_generate_mix_table();
|
||||||
|
|
|
@ -51,6 +51,9 @@ void dsp_dtmf_hardware(struct dsp *dsp)
|
||||||
{
|
{
|
||||||
int hardware = 1;
|
int hardware = 1;
|
||||||
|
|
||||||
|
if (!dsp->dtmf.enable)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!dsp->features.hfc_dtmf)
|
if (!dsp->features.hfc_dtmf)
|
||||||
hardware = 0;
|
hardware = 0;
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ int16_t amp)
|
||||||
&& det->tone_cycle_duration <= 475*8) {
|
&& det->tone_cycle_duration <= 475*8) {
|
||||||
det->good_cycles++;
|
det->good_cycles++;
|
||||||
if (det->good_cycles > 2)
|
if (det->good_cycles > 2)
|
||||||
det->hit = TRUE;
|
det->hit = TRUE;
|
||||||
}
|
}
|
||||||
det->tone_cycle_duration = 0;
|
det->tone_cycle_duration = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,20 +55,19 @@ static ssize_t
|
||||||
attr_show_args(struct device *dev, struct device_attribute *attr, char *buf)
|
attr_show_args(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct mISDN_dsp_element *elem = dev_get_drvdata(dev);
|
struct mISDN_dsp_element *elem = dev_get_drvdata(dev);
|
||||||
ssize_t len = 0;
|
int i;
|
||||||
int i = 0;
|
char *p = buf;
|
||||||
|
|
||||||
*buf = 0;
|
*buf = 0;
|
||||||
for (; i < elem->num_args; ++i)
|
for (i = 0; i < elem->num_args; i++)
|
||||||
len = sprintf(buf, "%sName: %s\n%s%s%sDescription: %s\n"
|
p += sprintf(p, "Name: %s\n%s%s%sDescription: %s\n\n",
|
||||||
"\n", buf,
|
|
||||||
elem->args[i].name,
|
elem->args[i].name,
|
||||||
elem->args[i].def ? "Default: " : "",
|
elem->args[i].def ? "Default: " : "",
|
||||||
elem->args[i].def ? elem->args[i].def : "",
|
elem->args[i].def ? elem->args[i].def : "",
|
||||||
elem->args[i].def ? "\n" : "",
|
elem->args[i].def ? "\n" : "",
|
||||||
elem->args[i].desc);
|
elem->args[i].desc);
|
||||||
|
|
||||||
return len;
|
return p - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct device_attribute element_attributes[] = {
|
static struct device_attribute element_attributes[] = {
|
||||||
|
@ -347,7 +346,8 @@ void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data, int len)
|
||||||
entry->elem->process_tx(entry->p, data, len);
|
entry->elem->process_tx(entry->p, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len)
|
void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len,
|
||||||
|
unsigned int txlen)
|
||||||
{
|
{
|
||||||
struct dsp_pipeline_entry *entry;
|
struct dsp_pipeline_entry *entry;
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len)
|
||||||
|
|
||||||
list_for_each_entry_reverse(entry, &pipeline->list, list)
|
list_for_each_entry_reverse(entry, &pipeline->list, list)
|
||||||
if (entry->elem->process_rx)
|
if (entry->elem->process_rx)
|
||||||
entry->elem->process_rx(entry->p, data, len);
|
entry->elem->process_rx(entry->p, data, len, txlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -253,18 +253,24 @@ static struct pattern {
|
||||||
{8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
|
{8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
|
||||||
|
|
||||||
{TONE_GERMAN_DIALPBX,
|
{TONE_GERMAN_DIALPBX,
|
||||||
{DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL},
|
{DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL,
|
||||||
{SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL},
|
NULL},
|
||||||
|
{SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL,
|
||||||
|
NULL},
|
||||||
{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
|
{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
|
||||||
|
|
||||||
{TONE_GERMAN_OLDDIALPBX,
|
{TONE_GERMAN_OLDDIALPBX,
|
||||||
{DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL},
|
{DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL,
|
||||||
{SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL},
|
NULL},
|
||||||
|
{SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL,
|
||||||
|
NULL},
|
||||||
{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
|
{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
|
||||||
|
|
||||||
{TONE_AMERICAN_DIALPBX,
|
{TONE_AMERICAN_DIALPBX,
|
||||||
{DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL, NULL},
|
{DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL,
|
||||||
{SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL, NULL},
|
NULL},
|
||||||
|
{SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL,
|
||||||
|
NULL},
|
||||||
{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
|
{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
|
||||||
|
|
||||||
{TONE_GERMAN_RINGING,
|
{TONE_GERMAN_RINGING,
|
||||||
|
@ -434,7 +440,7 @@ dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
|
||||||
|
|
||||||
/* unlocking is not required, because we don't expect a response */
|
/* unlocking is not required, because we don't expect a response */
|
||||||
nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
|
nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
|
||||||
(len)?HFC_SPL_LOOP_ON:HFC_SPL_LOOP_OFF, len, sample,
|
(len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
|
||||||
GFP_ATOMIC);
|
GFP_ATOMIC);
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
if (dsp->ch.peer) {
|
if (dsp->ch.peer) {
|
||||||
|
@ -498,8 +504,7 @@ dsp_tone(struct dsp *dsp, int tone)
|
||||||
|
|
||||||
/* we turn off the tone */
|
/* we turn off the tone */
|
||||||
if (!tone) {
|
if (!tone) {
|
||||||
if (dsp->features.hfc_loops)
|
if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
|
||||||
if (timer_pending(&tonet->tl))
|
|
||||||
del_timer(&tonet->tl);
|
del_timer(&tonet->tl);
|
||||||
if (dsp->features.hfc_loops)
|
if (dsp->features.hfc_loops)
|
||||||
dsp_tone_hw_message(dsp, NULL, 0);
|
dsp_tone_hw_message(dsp, NULL, 0);
|
||||||
|
|
|
@ -185,13 +185,13 @@ recv_Echannel(struct dchannel *ech, struct dchannel *dch)
|
||||||
EXPORT_SYMBOL(recv_Echannel);
|
EXPORT_SYMBOL(recv_Echannel);
|
||||||
|
|
||||||
void
|
void
|
||||||
recv_Bchannel(struct bchannel *bch)
|
recv_Bchannel(struct bchannel *bch, unsigned int id)
|
||||||
{
|
{
|
||||||
struct mISDNhead *hh;
|
struct mISDNhead *hh;
|
||||||
|
|
||||||
hh = mISDN_HEAD_P(bch->rx_skb);
|
hh = mISDN_HEAD_P(bch->rx_skb);
|
||||||
hh->prim = PH_DATA_IND;
|
hh->prim = PH_DATA_IND;
|
||||||
hh->id = MISDN_ID_ANY;
|
hh->id = id;
|
||||||
if (bch->rcount >= 64) {
|
if (bch->rcount >= 64) {
|
||||||
printk(KERN_WARNING "B-channel %p receive queue overflow, "
|
printk(KERN_WARNING "B-channel %p receive queue overflow, "
|
||||||
"fushing!\n", bch);
|
"fushing!\n", bch);
|
||||||
|
|
|
@ -76,7 +76,7 @@ struct l1oip {
|
||||||
struct sockaddr_in sin_local; /* local socket name */
|
struct sockaddr_in sin_local; /* local socket name */
|
||||||
struct sockaddr_in sin_remote; /* remote socket name */
|
struct sockaddr_in sin_remote; /* remote socket name */
|
||||||
struct msghdr sendmsg; /* ip message to send */
|
struct msghdr sendmsg; /* ip message to send */
|
||||||
struct iovec sendiov; /* iov for message */
|
struct kvec sendiov; /* iov for message */
|
||||||
|
|
||||||
/* frame */
|
/* frame */
|
||||||
struct l1oip_chan chan[128]; /* channel instances */
|
struct l1oip_chan chan[128]; /* channel instances */
|
||||||
|
|
|
@ -48,6 +48,7 @@ NOTE: The bytes are handled as they are law-encoded.
|
||||||
|
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <linux/mISDNif.h>
|
#include <linux/mISDNif.h>
|
||||||
|
#include <linux/in.h>
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "l1oip.h"
|
#include "l1oip.h"
|
||||||
|
|
||||||
|
|
|
@ -279,7 +279,6 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
|
||||||
int multi = 0;
|
int multi = 0;
|
||||||
u8 frame[len+32];
|
u8 frame[len+32];
|
||||||
struct socket *socket = NULL;
|
struct socket *socket = NULL;
|
||||||
mm_segment_t oldfs;
|
|
||||||
|
|
||||||
if (debug & DEBUG_L1OIP_MSG)
|
if (debug & DEBUG_L1OIP_MSG)
|
||||||
printk(KERN_DEBUG "%s: sending data to socket (len = %d)\n",
|
printk(KERN_DEBUG "%s: sending data to socket (len = %d)\n",
|
||||||
|
@ -308,8 +307,8 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
|
||||||
|
|
||||||
/* assemble frame */
|
/* assemble frame */
|
||||||
*p++ = (L1OIP_VERSION<<6) /* version and coding */
|
*p++ = (L1OIP_VERSION<<6) /* version and coding */
|
||||||
| (hc->pri?0x20:0x00) /* type */
|
| (hc->pri ? 0x20 : 0x00) /* type */
|
||||||
| (hc->id?0x10:0x00) /* id */
|
| (hc->id ? 0x10 : 0x00) /* id */
|
||||||
| localcodec;
|
| localcodec;
|
||||||
if (hc->id) {
|
if (hc->id) {
|
||||||
*p++ = hc->id>>24; /* id */
|
*p++ = hc->id>>24; /* id */
|
||||||
|
@ -317,7 +316,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
|
||||||
*p++ = hc->id>>8;
|
*p++ = hc->id>>8;
|
||||||
*p++ = hc->id;
|
*p++ = hc->id;
|
||||||
}
|
}
|
||||||
*p++ = (multi == 1)?0x80:0x00 + channel; /* m-flag, channel */
|
*p++ = (multi == 1) ? 0x80 : 0x00 + channel; /* m-flag, channel */
|
||||||
if (multi == 1)
|
if (multi == 1)
|
||||||
*p++ = len; /* length */
|
*p++ = len; /* length */
|
||||||
*p++ = timebase>>8; /* time base */
|
*p++ = timebase>>8; /* time base */
|
||||||
|
@ -352,10 +351,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
|
||||||
"= %d)\n", __func__, len);
|
"= %d)\n", __func__, len);
|
||||||
hc->sendiov.iov_base = frame;
|
hc->sendiov.iov_base = frame;
|
||||||
hc->sendiov.iov_len = len;
|
hc->sendiov.iov_len = len;
|
||||||
oldfs = get_fs();
|
len = kernel_sendmsg(socket, &hc->sendmsg, &hc->sendiov, 1, len);
|
||||||
set_fs(KERNEL_DS);
|
|
||||||
len = sock_sendmsg(socket, &hc->sendmsg, len);
|
|
||||||
set_fs(oldfs);
|
|
||||||
/* give socket back */
|
/* give socket back */
|
||||||
hc->socket = socket; /* no locking required */
|
hc->socket = socket; /* no locking required */
|
||||||
|
|
||||||
|
@ -401,12 +397,12 @@ l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prepare message */
|
/* prepare message */
|
||||||
nskb = mI_alloc_skb((remotecodec == 3)?(len<<1):len, GFP_ATOMIC);
|
nskb = mI_alloc_skb((remotecodec == 3) ? (len<<1) : len, GFP_ATOMIC);
|
||||||
if (!nskb) {
|
if (!nskb) {
|
||||||
printk(KERN_ERR "%s: No mem for skb.\n", __func__);
|
printk(KERN_ERR "%s: No mem for skb.\n", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p = skb_put(nskb, (remotecodec == 3)?(len<<1):len);
|
p = skb_put(nskb, (remotecodec == 3) ? (len<<1) : len);
|
||||||
|
|
||||||
if (remotecodec == 1 && ulaw)
|
if (remotecodec == 1 && ulaw)
|
||||||
l1oip_alaw_to_ulaw(buf, len, p);
|
l1oip_alaw_to_ulaw(buf, len, p);
|
||||||
|
@ -458,7 +454,7 @@ l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase,
|
||||||
hc->chan[channel].disorder_flag ^= 1;
|
hc->chan[channel].disorder_flag ^= 1;
|
||||||
if (nskb)
|
if (nskb)
|
||||||
#endif
|
#endif
|
||||||
queue_ch_frame(&bch->ch, PH_DATA_IND, rx_counter, nskb);
|
queue_ch_frame(&bch->ch, PH_DATA_IND, rx_counter, nskb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -660,21 +656,29 @@ l1oip_socket_thread(void *data)
|
||||||
struct l1oip *hc = (struct l1oip *)data;
|
struct l1oip *hc = (struct l1oip *)data;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct iovec iov;
|
|
||||||
mm_segment_t oldfs;
|
|
||||||
struct sockaddr_in sin_rx;
|
struct sockaddr_in sin_rx;
|
||||||
unsigned char recvbuf[1500];
|
unsigned char *recvbuf;
|
||||||
|
size_t recvbuf_size = 1500;
|
||||||
int recvlen;
|
int recvlen;
|
||||||
struct socket *socket = NULL;
|
struct socket *socket = NULL;
|
||||||
DECLARE_COMPLETION(wait);
|
DECLARE_COMPLETION(wait);
|
||||||
|
|
||||||
|
/* allocate buffer memory */
|
||||||
|
recvbuf = kmalloc(recvbuf_size, GFP_KERNEL);
|
||||||
|
if (!recvbuf) {
|
||||||
|
printk(KERN_ERR "%s: Failed to alloc recvbuf.\n", __func__);
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* make daemon */
|
/* make daemon */
|
||||||
allow_signal(SIGTERM);
|
allow_signal(SIGTERM);
|
||||||
|
|
||||||
/* create socket */
|
/* create socket */
|
||||||
if (sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &socket)) {
|
if (sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &socket)) {
|
||||||
printk(KERN_ERR "%s: Failed to create socket.\n", __func__);
|
printk(KERN_ERR "%s: Failed to create socket.\n", __func__);
|
||||||
return -EIO;
|
ret = -EIO;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set incoming address */
|
/* set incoming address */
|
||||||
|
@ -708,16 +712,12 @@ l1oip_socket_thread(void *data)
|
||||||
msg.msg_namelen = sizeof(sin_rx);
|
msg.msg_namelen = sizeof(sin_rx);
|
||||||
msg.msg_control = NULL;
|
msg.msg_control = NULL;
|
||||||
msg.msg_controllen = 0;
|
msg.msg_controllen = 0;
|
||||||
msg.msg_iov = &iov;
|
|
||||||
msg.msg_iovlen = 1;
|
|
||||||
|
|
||||||
/* build send message */
|
/* build send message */
|
||||||
hc->sendmsg.msg_name = &hc->sin_remote;
|
hc->sendmsg.msg_name = &hc->sin_remote;
|
||||||
hc->sendmsg.msg_namelen = sizeof(hc->sin_remote);
|
hc->sendmsg.msg_namelen = sizeof(hc->sin_remote);
|
||||||
hc->sendmsg.msg_control = NULL;
|
hc->sendmsg.msg_control = NULL;
|
||||||
hc->sendmsg.msg_controllen = 0;
|
hc->sendmsg.msg_controllen = 0;
|
||||||
hc->sendmsg.msg_iov = &hc->sendiov;
|
|
||||||
hc->sendmsg.msg_iovlen = 1;
|
|
||||||
|
|
||||||
/* give away socket */
|
/* give away socket */
|
||||||
spin_lock(&hc->socket_lock);
|
spin_lock(&hc->socket_lock);
|
||||||
|
@ -729,18 +729,18 @@ l1oip_socket_thread(void *data)
|
||||||
printk(KERN_DEBUG "%s: socket created and open\n",
|
printk(KERN_DEBUG "%s: socket created and open\n",
|
||||||
__func__);
|
__func__);
|
||||||
while (!signal_pending(current)) {
|
while (!signal_pending(current)) {
|
||||||
iov.iov_base = recvbuf;
|
struct kvec iov = {
|
||||||
iov.iov_len = sizeof(recvbuf);
|
.iov_base = recvbuf,
|
||||||
oldfs = get_fs();
|
.iov_len = sizeof(recvbuf),
|
||||||
set_fs(KERNEL_DS);
|
};
|
||||||
recvlen = sock_recvmsg(socket, &msg, sizeof(recvbuf), 0);
|
recvlen = kernel_recvmsg(socket, &msg, &iov, 1,
|
||||||
set_fs(oldfs);
|
sizeof(recvbuf), 0);
|
||||||
if (recvlen > 0) {
|
if (recvlen > 0) {
|
||||||
l1oip_socket_parse(hc, &sin_rx, recvbuf, recvlen);
|
l1oip_socket_parse(hc, &sin_rx, recvbuf, recvlen);
|
||||||
} else {
|
} else {
|
||||||
if (debug & DEBUG_L1OIP_SOCKET)
|
if (debug & DEBUG_L1OIP_SOCKET)
|
||||||
printk(KERN_WARNING "%s: broken pipe on socket\n",
|
printk(KERN_WARNING
|
||||||
__func__);
|
"%s: broken pipe on socket\n", __func__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -760,6 +760,9 @@ l1oip_socket_thread(void *data)
|
||||||
__func__);
|
__func__);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
/* free recvbuf */
|
||||||
|
kfree(recvbuf);
|
||||||
|
|
||||||
/* close socket */
|
/* close socket */
|
||||||
if (socket)
|
if (socket)
|
||||||
sock_release(socket);
|
sock_release(socket);
|
||||||
|
@ -912,7 +915,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
|
||||||
p = skb->data;
|
p = skb->data;
|
||||||
l = skb->len;
|
l = skb->len;
|
||||||
while (l) {
|
while (l) {
|
||||||
ll = (l < L1OIP_MAX_PERFRAME)?l:L1OIP_MAX_PERFRAME;
|
ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME;
|
||||||
l1oip_socket_send(hc, 0, dch->slot, 0,
|
l1oip_socket_send(hc, 0, dch->slot, 0,
|
||||||
hc->chan[dch->slot].tx_counter++, p, ll);
|
hc->chan[dch->slot].tx_counter++, p, ll);
|
||||||
p += ll;
|
p += ll;
|
||||||
|
@ -1160,7 +1163,7 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
|
||||||
p = skb->data;
|
p = skb->data;
|
||||||
l = skb->len;
|
l = skb->len;
|
||||||
while (l) {
|
while (l) {
|
||||||
ll = (l < L1OIP_MAX_PERFRAME)?l:L1OIP_MAX_PERFRAME;
|
ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME;
|
||||||
l1oip_socket_send(hc, hc->codec, bch->slot, 0,
|
l1oip_socket_send(hc, hc->codec, bch->slot, 0,
|
||||||
hc->chan[bch->slot].tx_counter, p, ll);
|
hc->chan[bch->slot].tx_counter, p, ll);
|
||||||
hc->chan[bch->slot].tx_counter += ll;
|
hc->chan[bch->slot].tx_counter += ll;
|
||||||
|
@ -1318,8 +1321,8 @@ init_card(struct l1oip *hc, int pri, int bundle)
|
||||||
spin_lock_init(&hc->socket_lock);
|
spin_lock_init(&hc->socket_lock);
|
||||||
hc->idx = l1oip_cnt;
|
hc->idx = l1oip_cnt;
|
||||||
hc->pri = pri;
|
hc->pri = pri;
|
||||||
hc->d_idx = pri?16:3;
|
hc->d_idx = pri ? 16 : 3;
|
||||||
hc->b_num = pri?30:2;
|
hc->b_num = pri ? 30 : 2;
|
||||||
hc->bundle = bundle;
|
hc->bundle = bundle;
|
||||||
if (hc->pri)
|
if (hc->pri)
|
||||||
sprintf(hc->name, "l1oip-e1.%d", l1oip_cnt + 1);
|
sprintf(hc->name, "l1oip-e1.%d", l1oip_cnt + 1);
|
||||||
|
@ -1504,9 +1507,9 @@ l1oip_init(void)
|
||||||
|
|
||||||
if (debug & DEBUG_L1OIP_INIT)
|
if (debug & DEBUG_L1OIP_INIT)
|
||||||
printk(KERN_DEBUG "%s: interface %d is %s with %s.\n",
|
printk(KERN_DEBUG "%s: interface %d is %s with %s.\n",
|
||||||
__func__, l1oip_cnt, pri?"PRI":"BRI",
|
__func__, l1oip_cnt, pri ? "PRI" : "BRI",
|
||||||
bundle?"bundled IP packet for all B-channels"
|
bundle ? "bundled IP packet for all B-channels" :
|
||||||
:"seperate IP packets for every B-channel");
|
"seperate IP packets for every B-channel");
|
||||||
|
|
||||||
hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC);
|
hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC);
|
||||||
if (!hc) {
|
if (!hc) {
|
||||||
|
|
|
@ -99,7 +99,7 @@ l2m_debug(struct FsmInst *fi, char *fmt, ...)
|
||||||
if (!(*debug & DEBUG_L2_FSM))
|
if (!(*debug & DEBUG_L2_FSM))
|
||||||
return;
|
return;
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
printk(KERN_DEBUG "l2 (tei %d): ", l2->tei);
|
printk(KERN_DEBUG "l2 (sapi %d tei %d): ", l2->sapi, l2->tei);
|
||||||
vprintk(fmt, va);
|
vprintk(fmt, va);
|
||||||
printk("\n");
|
printk("\n");
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
@ -1859,20 +1859,18 @@ ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
|
||||||
psapi >>= 2;
|
psapi >>= 2;
|
||||||
ptei >>= 1;
|
ptei >>= 1;
|
||||||
if (psapi != l2->sapi) {
|
if (psapi != l2->sapi) {
|
||||||
/* not our bussiness
|
/* not our bussiness */
|
||||||
* printk(KERN_DEBUG "%s: sapi %d/%d sapi mismatch\n",
|
if (*debug & DEBUG_L2)
|
||||||
* __func__,
|
printk(KERN_DEBUG "%s: sapi %d/%d mismatch\n",
|
||||||
* psapi, l2->sapi);
|
__func__, psapi, l2->sapi);
|
||||||
*/
|
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((ptei != l2->tei) && (ptei != GROUP_TEI)) {
|
if ((ptei != l2->tei) && (ptei != GROUP_TEI)) {
|
||||||
/* not our bussiness
|
/* not our bussiness */
|
||||||
* printk(KERN_DEBUG "%s: tei %d/%d sapi %d mismatch\n",
|
if (*debug & DEBUG_L2)
|
||||||
* __func__,
|
printk(KERN_DEBUG "%s: tei %d/%d mismatch\n",
|
||||||
* ptei, l2->tei, psapi);
|
__func__, ptei, l2->tei);
|
||||||
*/
|
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1927,8 +1925,8 @@ l2_send(struct mISDNchannel *ch, struct sk_buff *skb)
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
if (*debug & DEBUG_L2_RECV)
|
if (*debug & DEBUG_L2_RECV)
|
||||||
printk(KERN_DEBUG "%s: prim(%x) id(%x) tei(%d)\n",
|
printk(KERN_DEBUG "%s: prim(%x) id(%x) sapi(%d) tei(%d)\n",
|
||||||
__func__, hh->prim, hh->id, l2->tei);
|
__func__, hh->prim, hh->id, l2->sapi, l2->tei);
|
||||||
switch (hh->prim) {
|
switch (hh->prim) {
|
||||||
case PH_DATA_IND:
|
case PH_DATA_IND:
|
||||||
ret = ph_data_indication(l2, hh, skb);
|
ret = ph_data_indication(l2, hh, skb);
|
||||||
|
@ -2068,7 +2066,8 @@ l2_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct layer2 *
|
struct layer2 *
|
||||||
create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg)
|
create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei,
|
||||||
|
int sapi)
|
||||||
{
|
{
|
||||||
struct layer2 *l2;
|
struct layer2 *l2;
|
||||||
struct channel_req rq;
|
struct channel_req rq;
|
||||||
|
@ -2089,7 +2088,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg)
|
||||||
test_and_set_bit(FLG_LAPD, &l2->flag);
|
test_and_set_bit(FLG_LAPD, &l2->flag);
|
||||||
test_and_set_bit(FLG_LAPD_NET, &l2->flag);
|
test_and_set_bit(FLG_LAPD_NET, &l2->flag);
|
||||||
test_and_set_bit(FLG_MOD128, &l2->flag);
|
test_and_set_bit(FLG_MOD128, &l2->flag);
|
||||||
l2->sapi = 0;
|
l2->sapi = sapi;
|
||||||
l2->maxlen = MAX_DFRAME_LEN;
|
l2->maxlen = MAX_DFRAME_LEN;
|
||||||
if (test_bit(OPTION_L2_PMX, &options))
|
if (test_bit(OPTION_L2_PMX, &options))
|
||||||
l2->window = 7;
|
l2->window = 7;
|
||||||
|
@ -2099,7 +2098,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg)
|
||||||
test_and_set_bit(FLG_PTP, &l2->flag);
|
test_and_set_bit(FLG_PTP, &l2->flag);
|
||||||
if (test_bit(OPTION_L2_FIXEDTEI, &options))
|
if (test_bit(OPTION_L2_FIXEDTEI, &options))
|
||||||
test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
|
test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
|
||||||
l2->tei = (u_int)arg;
|
l2->tei = tei;
|
||||||
l2->T200 = 1000;
|
l2->T200 = 1000;
|
||||||
l2->N200 = 3;
|
l2->N200 = 3;
|
||||||
l2->T203 = 10000;
|
l2->T203 = 10000;
|
||||||
|
@ -2114,7 +2113,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg)
|
||||||
test_and_set_bit(FLG_LAPD, &l2->flag);
|
test_and_set_bit(FLG_LAPD, &l2->flag);
|
||||||
test_and_set_bit(FLG_MOD128, &l2->flag);
|
test_and_set_bit(FLG_MOD128, &l2->flag);
|
||||||
test_and_set_bit(FLG_ORIG, &l2->flag);
|
test_and_set_bit(FLG_ORIG, &l2->flag);
|
||||||
l2->sapi = 0;
|
l2->sapi = sapi;
|
||||||
l2->maxlen = MAX_DFRAME_LEN;
|
l2->maxlen = MAX_DFRAME_LEN;
|
||||||
if (test_bit(OPTION_L2_PMX, &options))
|
if (test_bit(OPTION_L2_PMX, &options))
|
||||||
l2->window = 7;
|
l2->window = 7;
|
||||||
|
@ -2124,7 +2123,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg)
|
||||||
test_and_set_bit(FLG_PTP, &l2->flag);
|
test_and_set_bit(FLG_PTP, &l2->flag);
|
||||||
if (test_bit(OPTION_L2_FIXEDTEI, &options))
|
if (test_bit(OPTION_L2_FIXEDTEI, &options))
|
||||||
test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
|
test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
|
||||||
l2->tei = (u_int)arg;
|
l2->tei = tei;
|
||||||
l2->T200 = 1000;
|
l2->T200 = 1000;
|
||||||
l2->N200 = 3;
|
l2->N200 = 3;
|
||||||
l2->T203 = 10000;
|
l2->T203 = 10000;
|
||||||
|
@ -2180,7 +2179,7 @@ x75create(struct channel_req *crq)
|
||||||
|
|
||||||
if (crq->protocol != ISDN_P_B_X75SLP)
|
if (crq->protocol != ISDN_P_B_X75SLP)
|
||||||
return -EPROTONOSUPPORT;
|
return -EPROTONOSUPPORT;
|
||||||
l2 = create_l2(crq->ch, crq->protocol, 0, 0);
|
l2 = create_l2(crq->ch, crq->protocol, 0, 0, 0);
|
||||||
if (!l2)
|
if (!l2)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
crq->ch = &l2->ch;
|
crq->ch = &l2->ch;
|
||||||
|
|
|
@ -90,7 +90,7 @@ enum {
|
||||||
#define L2_STATE_COUNT (ST_L2_8+1)
|
#define L2_STATE_COUNT (ST_L2_8+1)
|
||||||
|
|
||||||
extern struct layer2 *create_l2(struct mISDNchannel *, u_int,
|
extern struct layer2 *create_l2(struct mISDNchannel *, u_int,
|
||||||
u_long, u_long);
|
u_long, int, int);
|
||||||
extern int tei_l2(struct layer2 *, u_int, u_long arg);
|
extern int tei_l2(struct layer2 *, u_int, u_long arg);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -209,7 +209,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
|
||||||
|
|
||||||
if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
|
if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
goto drop;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(mISDN_HEAD_P(skb), skb->data, MISDN_HEADER_LEN);
|
memcpy(mISDN_HEAD_P(skb), skb->data, MISDN_HEADER_LEN);
|
||||||
|
@ -222,7 +222,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
|
||||||
} else { /* use default for L2 messages */
|
} else { /* use default for L2 messages */
|
||||||
if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
|
if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
|
||||||
(sk->sk_protocol == ISDN_P_LAPD_NT))
|
(sk->sk_protocol == ISDN_P_LAPD_NT))
|
||||||
mISDN_HEAD_ID(skb) = _pms(sk)->ch.nr;
|
mISDN_HEAD_ID(skb) = _pms(sk)->ch.nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*debug & DEBUG_SOCKET)
|
if (*debug & DEBUG_SOCKET)
|
||||||
|
@ -230,19 +230,21 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
|
||||||
__func__, mISDN_HEAD_ID(skb));
|
__func__, mISDN_HEAD_ID(skb));
|
||||||
|
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
if (!_pms(sk)->ch.peer ||
|
if (!_pms(sk)->ch.peer)
|
||||||
(err = _pms(sk)->ch.recv(_pms(sk)->ch.peer, skb)))
|
goto done;
|
||||||
goto drop;
|
err = _pms(sk)->ch.recv(_pms(sk)->ch.peer, skb);
|
||||||
|
if (err)
|
||||||
err = len;
|
goto done;
|
||||||
|
else {
|
||||||
|
skb = NULL;
|
||||||
|
err = len;
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
if (skb)
|
||||||
|
kfree_skb(skb);
|
||||||
release_sock(sk);
|
release_sock(sk);
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
drop:
|
|
||||||
kfree_skb(skb);
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -292,7 +294,7 @@ static int
|
||||||
data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
|
data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
|
||||||
{
|
{
|
||||||
struct mISDN_ctrl_req cq;
|
struct mISDN_ctrl_req cq;
|
||||||
int err = -EINVAL, val;
|
int err = -EINVAL, val[2];
|
||||||
struct mISDNchannel *bchan, *next;
|
struct mISDNchannel *bchan, *next;
|
||||||
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
@ -328,12 +330,27 @@ data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (get_user(val, (int __user *)p)) {
|
val[0] = cmd;
|
||||||
|
if (get_user(val[1], (int __user *)p)) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
|
err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
|
||||||
CONTROL_CHANNEL, &val);
|
CONTROL_CHANNEL, val);
|
||||||
|
break;
|
||||||
|
case IMHOLD_L1:
|
||||||
|
if (sk->sk_protocol != ISDN_P_LAPD_NT
|
||||||
|
&& sk->sk_protocol != ISDN_P_LAPD_TE) {
|
||||||
|
err = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
val[0] = cmd;
|
||||||
|
if (get_user(val[1], (int __user *)p)) {
|
||||||
|
err = -EFAULT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
|
||||||
|
CONTROL_CHANNEL, val);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
|
|
|
@ -122,8 +122,11 @@ da_deactivate(struct FsmInst *fi, int event, void *arg)
|
||||||
}
|
}
|
||||||
read_unlock_irqrestore(&mgr->lock, flags);
|
read_unlock_irqrestore(&mgr->lock, flags);
|
||||||
/* All TEI are inactiv */
|
/* All TEI are inactiv */
|
||||||
mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, NULL, 1);
|
if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
|
||||||
mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING);
|
mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
|
||||||
|
NULL, 1);
|
||||||
|
mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -132,9 +135,11 @@ da_ui(struct FsmInst *fi, int event, void *arg)
|
||||||
struct manager *mgr = fi->userdata;
|
struct manager *mgr = fi->userdata;
|
||||||
|
|
||||||
/* restart da timer */
|
/* restart da timer */
|
||||||
mISDN_FsmDelTimer(&mgr->datimer, 2);
|
if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
|
||||||
mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, NULL, 2);
|
mISDN_FsmDelTimer(&mgr->datimer, 2);
|
||||||
|
mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
|
||||||
|
NULL, 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -222,7 +227,7 @@ tei_debug(struct FsmInst *fi, char *fmt, ...)
|
||||||
if (!(*debug & DEBUG_L2_TEIFSM))
|
if (!(*debug & DEBUG_L2_TEIFSM))
|
||||||
return;
|
return;
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
printk(KERN_DEBUG "tei(%d): ", tm->l2->tei);
|
printk(KERN_DEBUG "sapi(%d) tei(%d): ", tm->l2->sapi, tm->l2->tei);
|
||||||
vprintk(fmt, va);
|
vprintk(fmt, va);
|
||||||
printk("\n");
|
printk("\n");
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
@ -421,7 +426,7 @@ findtei(struct manager *mgr, int tei)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, u_char tei)
|
put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, int tei)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
u_char bp[8];
|
u_char bp[8];
|
||||||
|
@ -435,9 +440,8 @@ put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, u_char tei)
|
||||||
bp[4] = ri >> 8;
|
bp[4] = ri >> 8;
|
||||||
bp[5] = ri & 0xff;
|
bp[5] = ri & 0xff;
|
||||||
bp[6] = m_id;
|
bp[6] = m_id;
|
||||||
bp[7] = (tei << 1) | 1;
|
bp[7] = ((tei << 1) & 0xff) | 1;
|
||||||
skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr),
|
skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr), 8, bp, GFP_ATOMIC);
|
||||||
8, bp, GFP_ATOMIC);
|
|
||||||
if (!skb) {
|
if (!skb) {
|
||||||
printk(KERN_WARNING "%s: no skb for tei msg\n", __func__);
|
printk(KERN_WARNING "%s: no skb for tei msg\n", __func__);
|
||||||
return;
|
return;
|
||||||
|
@ -772,7 +776,7 @@ tei_ph_data_ind(struct teimgr *tm, u_int mt, u_char *dp, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct layer2 *
|
static struct layer2 *
|
||||||
create_new_tei(struct manager *mgr, int tei)
|
create_new_tei(struct manager *mgr, int tei, int sapi)
|
||||||
{
|
{
|
||||||
u_long opt = 0;
|
u_long opt = 0;
|
||||||
u_long flags;
|
u_long flags;
|
||||||
|
@ -781,12 +785,12 @@ create_new_tei(struct manager *mgr, int tei)
|
||||||
|
|
||||||
if (!mgr->up)
|
if (!mgr->up)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (tei < 64)
|
if ((tei >= 0) && (tei < 64))
|
||||||
test_and_set_bit(OPTION_L2_FIXEDTEI, &opt);
|
test_and_set_bit(OPTION_L2_FIXEDTEI, &opt);
|
||||||
if (mgr->ch.st->dev->Dprotocols
|
if (mgr->ch.st->dev->Dprotocols
|
||||||
& ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1)))
|
& ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1)))
|
||||||
test_and_set_bit(OPTION_L2_PMX, &opt);
|
test_and_set_bit(OPTION_L2_PMX, &opt);
|
||||||
l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, (u_int)opt, (u_long)tei);
|
l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, opt, tei, sapi);
|
||||||
if (!l2) {
|
if (!l2) {
|
||||||
printk(KERN_WARNING "%s:no memory for layer2\n", __func__);
|
printk(KERN_WARNING "%s:no memory for layer2\n", __func__);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -834,12 +838,17 @@ new_tei_req(struct manager *mgr, u_char *dp)
|
||||||
ri += dp[1];
|
ri += dp[1];
|
||||||
if (!mgr->up)
|
if (!mgr->up)
|
||||||
goto denied;
|
goto denied;
|
||||||
tei = get_free_tei(mgr);
|
if (!(dp[3] & 1)) /* Extension bit != 1 */
|
||||||
|
goto denied;
|
||||||
|
if (dp[3] != 0xff)
|
||||||
|
tei = dp[3] >> 1; /* 3GPP TS 08.56 6.1.11.2 */
|
||||||
|
else
|
||||||
|
tei = get_free_tei(mgr);
|
||||||
if (tei < 0) {
|
if (tei < 0) {
|
||||||
printk(KERN_WARNING "%s:No free tei\n", __func__);
|
printk(KERN_WARNING "%s:No free tei\n", __func__);
|
||||||
goto denied;
|
goto denied;
|
||||||
}
|
}
|
||||||
l2 = create_new_tei(mgr, tei);
|
l2 = create_new_tei(mgr, tei, CTRL_SAPI);
|
||||||
if (!l2)
|
if (!l2)
|
||||||
goto denied;
|
goto denied;
|
||||||
else
|
else
|
||||||
|
@ -853,8 +862,7 @@ static int
|
||||||
ph_data_ind(struct manager *mgr, struct sk_buff *skb)
|
ph_data_ind(struct manager *mgr, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
struct layer2 *l2;
|
struct layer2 *l2, *nl2;
|
||||||
u_long flags;
|
|
||||||
u_char mt;
|
u_char mt;
|
||||||
|
|
||||||
if (skb->len < 8) {
|
if (skb->len < 8) {
|
||||||
|
@ -863,7 +871,6 @@ ph_data_ind(struct manager *mgr, struct sk_buff *skb)
|
||||||
__func__, skb->len);
|
__func__, skb->len);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (*debug & DEBUG_L2_TEI)
|
|
||||||
|
|
||||||
if ((skb->data[0] >> 2) != TEI_SAPI) /* not for us */
|
if ((skb->data[0] >> 2) != TEI_SAPI) /* not for us */
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -900,11 +907,9 @@ ph_data_ind(struct manager *mgr, struct sk_buff *skb)
|
||||||
new_tei_req(mgr, &skb->data[4]);
|
new_tei_req(mgr, &skb->data[4]);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
read_lock_irqsave(&mgr->lock, flags);
|
list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
|
||||||
list_for_each_entry(l2, &mgr->layer2, list) {
|
|
||||||
tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4);
|
tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4);
|
||||||
}
|
}
|
||||||
read_unlock_irqrestore(&mgr->lock, flags);
|
|
||||||
done:
|
done:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -971,8 +976,6 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
|
||||||
__func__, dev_name(&mgr->ch.st->dev->dev),
|
__func__, dev_name(&mgr->ch.st->dev->dev),
|
||||||
crq->protocol, crq->adr.dev, crq->adr.channel,
|
crq->protocol, crq->adr.dev, crq->adr.channel,
|
||||||
crq->adr.sapi, crq->adr.tei);
|
crq->adr.sapi, crq->adr.tei);
|
||||||
if (crq->adr.sapi != 0) /* not supported yet */
|
|
||||||
return -EINVAL;
|
|
||||||
if (crq->adr.tei > GROUP_TEI)
|
if (crq->adr.tei > GROUP_TEI)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (crq->adr.tei < 64)
|
if (crq->adr.tei < 64)
|
||||||
|
@ -1019,8 +1022,8 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
l2 = create_l2(crq->ch, crq->protocol, (u_int)opt,
|
l2 = create_l2(crq->ch, crq->protocol, opt,
|
||||||
(u_long)crq->adr.tei);
|
crq->adr.tei, crq->adr.sapi);
|
||||||
if (!l2)
|
if (!l2)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL);
|
l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL);
|
||||||
|
@ -1103,6 +1106,7 @@ free_teimanager(struct manager *mgr)
|
||||||
{
|
{
|
||||||
struct layer2 *l2, *nl2;
|
struct layer2 *l2, *nl2;
|
||||||
|
|
||||||
|
test_and_clear_bit(OPTION_L1_HOLD, &mgr->options);
|
||||||
if (test_bit(MGR_OPT_NETWORK, &mgr->options)) {
|
if (test_bit(MGR_OPT_NETWORK, &mgr->options)) {
|
||||||
/* not locked lock is taken in release tei */
|
/* not locked lock is taken in release tei */
|
||||||
mgr->up = NULL;
|
mgr->up = NULL;
|
||||||
|
@ -1133,13 +1137,26 @@ static int
|
||||||
ctrl_teimanager(struct manager *mgr, void *arg)
|
ctrl_teimanager(struct manager *mgr, void *arg)
|
||||||
{
|
{
|
||||||
/* currently we only have one option */
|
/* currently we only have one option */
|
||||||
int clean = *((int *)arg);
|
int *val = (int *)arg;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (clean)
|
switch (val[0]) {
|
||||||
test_and_set_bit(OPTION_L2_CLEANUP, &mgr->options);
|
case IMCLEAR_L2:
|
||||||
else
|
if (val[1])
|
||||||
test_and_clear_bit(OPTION_L2_CLEANUP, &mgr->options);
|
test_and_set_bit(OPTION_L2_CLEANUP, &mgr->options);
|
||||||
return 0;
|
else
|
||||||
|
test_and_clear_bit(OPTION_L2_CLEANUP, &mgr->options);
|
||||||
|
break;
|
||||||
|
case IMHOLD_L1:
|
||||||
|
if (val[1])
|
||||||
|
test_and_set_bit(OPTION_L1_HOLD, &mgr->options);
|
||||||
|
else
|
||||||
|
test_and_clear_bit(OPTION_L1_HOLD, &mgr->options);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = -EINVAL;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function does create a L2 for fixed TEI in NT Mode */
|
/* This function does create a L2 for fixed TEI in NT Mode */
|
||||||
|
@ -1147,7 +1164,7 @@ static int
|
||||||
check_data(struct manager *mgr, struct sk_buff *skb)
|
check_data(struct manager *mgr, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct mISDNhead *hh = mISDN_HEAD_P(skb);
|
struct mISDNhead *hh = mISDN_HEAD_P(skb);
|
||||||
int ret, tei;
|
int ret, tei, sapi;
|
||||||
struct layer2 *l2;
|
struct layer2 *l2;
|
||||||
|
|
||||||
if (*debug & DEBUG_L2_CTRL)
|
if (*debug & DEBUG_L2_CTRL)
|
||||||
|
@ -1159,20 +1176,27 @@ check_data(struct manager *mgr, struct sk_buff *skb)
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
if (skb->len != 3)
|
if (skb->len != 3)
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
if (skb->data[0] != 0)
|
if (skb->data[0] & 3) /* EA0 and CR must be 0 */
|
||||||
/* only SAPI 0 command */
|
return -EINVAL;
|
||||||
return -ENOTCONN;
|
sapi = skb->data[0] >> 2;
|
||||||
if (!(skb->data[1] & 1)) /* invalid EA1 */
|
if (!(skb->data[1] & 1)) /* invalid EA1 */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
tei = skb->data[1] >> 0;
|
tei = skb->data[1] >> 1;
|
||||||
if (tei > 63) /* not a fixed tei */
|
if (tei > 63) /* not a fixed tei */
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
if ((skb->data[2] & ~0x10) != SABME)
|
if ((skb->data[2] & ~0x10) != SABME)
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
/* We got a SABME for a fixed TEI */
|
/* We got a SABME for a fixed TEI */
|
||||||
l2 = create_new_tei(mgr, tei);
|
if (*debug & DEBUG_L2_CTRL)
|
||||||
if (!l2)
|
printk(KERN_DEBUG "%s: SABME sapi(%d) tei(%d)\n",
|
||||||
|
__func__, sapi, tei);
|
||||||
|
l2 = create_new_tei(mgr, tei, sapi);
|
||||||
|
if (!l2) {
|
||||||
|
if (*debug & DEBUG_L2_CTRL)
|
||||||
|
printk(KERN_DEBUG "%s: failed to create new tei\n",
|
||||||
|
__func__);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
ret = l2->ch.send(&l2->ch, skb);
|
ret = l2->ch.send(&l2->ch, skb);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -259,7 +259,7 @@ mISDN_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct file_operations mISDN_fops = {
|
static const struct file_operations mISDN_fops = {
|
||||||
.read = mISDN_read,
|
.read = mISDN_read,
|
||||||
.poll = mISDN_poll,
|
.poll = mISDN_poll,
|
||||||
.ioctl = mISDN_ioctl,
|
.ioctl = mISDN_ioctl,
|
||||||
|
|
|
@ -703,7 +703,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
|
||||||
|
|
||||||
printk (KERN_ERR "%s: no tx context available: %u\n",
|
printk (KERN_ERR "%s: no tx context available: %u\n",
|
||||||
__func__, priv->mpt_txfidx_tail);
|
__func__, priv->mpt_txfidx_tail);
|
||||||
return 1;
|
return NETDEV_TX_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
mf = mpt_get_msg_frame(LanCtx, mpt_dev);
|
mf = mpt_get_msg_frame(LanCtx, mpt_dev);
|
||||||
|
@ -713,7 +713,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
|
||||||
|
|
||||||
printk (KERN_ERR "%s: Unable to alloc request frame\n",
|
printk (KERN_ERR "%s: Unable to alloc request frame\n",
|
||||||
__func__);
|
__func__);
|
||||||
return 1;
|
return NETDEV_TX_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = priv->mpt_txfidx[priv->mpt_txfidx_tail--];
|
ctx = priv->mpt_txfidx[priv->mpt_txfidx_tail--];
|
||||||
|
|
|
@ -450,7 +450,8 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
"packet\n", sizeof(struct xpnet_pending_msg));
|
"packet\n", sizeof(struct xpnet_pending_msg));
|
||||||
|
|
||||||
dev->stats.tx_errors++;
|
dev->stats.tx_errors++;
|
||||||
return -ENOMEM;
|
dev_kfree_skb(skb);
|
||||||
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the beginning of the first cacheline and end of last */
|
/* get the beginning of the first cacheline and end of last */
|
||||||
|
|
|
@ -281,7 +281,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
|
||||||
autoirq = probe_irq_off(irq_mask);
|
autoirq = probe_irq_off(irq_mask);
|
||||||
|
|
||||||
if (autoirq == 0) {
|
if (autoirq == 0) {
|
||||||
printk(KERN_WARNING "%s probe at %#x failed to detect IRQ line.\n",
|
pr_warning("%s probe at %#x failed to detect IRQ line.\n",
|
||||||
mname, ioaddr);
|
mname, ioaddr);
|
||||||
release_region(ioaddr, EL1_IO_EXTENT);
|
release_region(ioaddr, EL1_IO_EXTENT);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
@ -297,16 +297,16 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
|
||||||
if (autoirq)
|
if (autoirq)
|
||||||
dev->irq = autoirq;
|
dev->irq = autoirq;
|
||||||
|
|
||||||
printk(KERN_INFO "%s: %s EtherLink at %#lx, using %sIRQ %d.\n",
|
pr_info("%s: %s EtherLink at %#lx, using %sIRQ %d.\n",
|
||||||
dev->name, mname, dev->base_addr,
|
dev->name, mname, dev->base_addr,
|
||||||
autoirq ? "auto":"assigned ", dev->irq);
|
autoirq ? "auto":"assigned ", dev->irq);
|
||||||
|
|
||||||
#ifdef CONFIG_IP_MULTICAST
|
#ifdef CONFIG_IP_MULTICAST
|
||||||
printk(KERN_WARNING "WARNING: Use of the 3c501 in a multicast kernel is NOT recommended.\n");
|
pr_warning("WARNING: Use of the 3c501 in a multicast kernel is NOT recommended.\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (el_debug)
|
if (el_debug)
|
||||||
printk(KERN_DEBUG "%s", version);
|
pr_debug("%s", version);
|
||||||
|
|
||||||
lp = netdev_priv(dev);
|
lp = netdev_priv(dev);
|
||||||
memset(lp, 0, sizeof(struct net_local));
|
memset(lp, 0, sizeof(struct net_local));
|
||||||
|
@ -343,7 +343,7 @@ static int el_open(struct net_device *dev)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (el_debug > 2)
|
if (el_debug > 2)
|
||||||
printk(KERN_DEBUG "%s: Doing el_open()...", dev->name);
|
pr_debug("%s: Doing el_open()...\n", dev->name);
|
||||||
|
|
||||||
retval = request_irq(dev->irq, &el_interrupt, 0, dev->name, dev);
|
retval = request_irq(dev->irq, &el_interrupt, 0, dev->name, dev);
|
||||||
if (retval)
|
if (retval)
|
||||||
|
@ -374,7 +374,7 @@ static void el_timeout(struct net_device *dev)
|
||||||
int ioaddr = dev->base_addr;
|
int ioaddr = dev->base_addr;
|
||||||
|
|
||||||
if (el_debug)
|
if (el_debug)
|
||||||
printk(KERN_DEBUG "%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",
|
pr_debug("%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",
|
||||||
dev->name, inb(TX_STATUS),
|
dev->name, inb(TX_STATUS),
|
||||||
inb(AX_STATUS), inb(RX_STATUS));
|
inb(AX_STATUS), inb(RX_STATUS));
|
||||||
dev->stats.tx_errors++;
|
dev->stats.tx_errors++;
|
||||||
|
@ -483,14 +483,13 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
lp->loading = 0;
|
lp->loading = 0;
|
||||||
dev->trans_start = jiffies;
|
dev->trans_start = jiffies;
|
||||||
if (el_debug > 2)
|
if (el_debug > 2)
|
||||||
printk(KERN_DEBUG " queued xmit.\n");
|
pr_debug(" queued xmit.\n");
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* A receive upset our load, despite our best efforts */
|
/* A receive upset our load, despite our best efforts */
|
||||||
if (el_debug > 2)
|
if (el_debug > 2)
|
||||||
printk(KERN_DEBUG "%s: burped during tx load.\n",
|
pr_debug("%s: burped during tx load.\n", dev->name);
|
||||||
dev->name);
|
|
||||||
spin_lock_irqsave(&lp->lock, flags);
|
spin_lock_irqsave(&lp->lock, flags);
|
||||||
} while (1);
|
} while (1);
|
||||||
}
|
}
|
||||||
|
@ -540,11 +539,10 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (el_debug > 3)
|
if (el_debug > 3)
|
||||||
printk(KERN_DEBUG "%s: el_interrupt() aux=%#02x",
|
pr_debug("%s: el_interrupt() aux=%#02x\n", dev->name, axsr);
|
||||||
dev->name, axsr);
|
|
||||||
|
|
||||||
if (lp->loading == 1 && !lp->txing)
|
if (lp->loading == 1 && !lp->txing)
|
||||||
printk(KERN_WARNING "%s: Inconsistent state loading while not in tx\n",
|
pr_warning("%s: Inconsistent state loading while not in tx\n",
|
||||||
dev->name);
|
dev->name);
|
||||||
|
|
||||||
if (lp->txing) {
|
if (lp->txing) {
|
||||||
|
@ -555,19 +553,17 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
||||||
int txsr = inb(TX_STATUS);
|
int txsr = inb(TX_STATUS);
|
||||||
|
|
||||||
if (lp->loading == 1) {
|
if (lp->loading == 1) {
|
||||||
if (el_debug > 2) {
|
if (el_debug > 2)
|
||||||
printk(KERN_DEBUG "%s: Interrupt while loading [",
|
pr_debug("%s: Interrupt while loading [txsr=%02x gp=%04x rp=%04x]\n",
|
||||||
dev->name);
|
dev->name, txsr, inw(GP_LOW), inw(RX_LOW));
|
||||||
printk(" txsr=%02x gp=%04x rp=%04x]\n",
|
|
||||||
txsr, inw(GP_LOW), inw(RX_LOW));
|
|
||||||
}
|
|
||||||
/* Force a reload */
|
/* Force a reload */
|
||||||
lp->loading = 2;
|
lp->loading = 2;
|
||||||
spin_unlock(&lp->lock);
|
spin_unlock(&lp->lock);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (el_debug > 6)
|
if (el_debug > 6)
|
||||||
printk(KERN_DEBUG " txsr=%02x gp=%04x rp=%04x",
|
pr_debug("%s: txsr=%02x gp=%04x rp=%04x\n", dev->name,
|
||||||
txsr, inw(GP_LOW), inw(RX_LOW));
|
txsr, inw(GP_LOW), inw(RX_LOW));
|
||||||
|
|
||||||
if ((axsr & 0x80) && (txsr & TX_READY) == 0) {
|
if ((axsr & 0x80) && (txsr & TX_READY) == 0) {
|
||||||
|
@ -576,7 +572,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
||||||
* on trying or reset immediately ?
|
* on trying or reset immediately ?
|
||||||
*/
|
*/
|
||||||
if (el_debug > 1)
|
if (el_debug > 1)
|
||||||
printk(KERN_DEBUG "%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x gp=%03x rp=%03x.\n",
|
pr_debug("%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x gp=%03x rp=%03x.\n",
|
||||||
dev->name, txsr, axsr,
|
dev->name, txsr, axsr,
|
||||||
inw(ioaddr + EL1_DATAPTR),
|
inw(ioaddr + EL1_DATAPTR),
|
||||||
inw(ioaddr + EL1_RXPTR));
|
inw(ioaddr + EL1_RXPTR));
|
||||||
|
@ -587,7 +583,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
||||||
* Timed out
|
* Timed out
|
||||||
*/
|
*/
|
||||||
if (el_debug)
|
if (el_debug)
|
||||||
printk(KERN_DEBUG "%s: Transmit failed 16 times, Ethernet jammed?\n", dev->name);
|
pr_debug("%s: Transmit failed 16 times, Ethernet jammed?\n", dev->name);
|
||||||
outb(AX_SYS, AX_CMD);
|
outb(AX_SYS, AX_CMD);
|
||||||
lp->txing = 0;
|
lp->txing = 0;
|
||||||
dev->stats.tx_aborted_errors++;
|
dev->stats.tx_aborted_errors++;
|
||||||
|
@ -598,7 +594,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (el_debug > 6)
|
if (el_debug > 6)
|
||||||
printk(KERN_DEBUG " retransmitting after a collision.\n");
|
pr_debug("%s: retransmitting after a collision.\n", dev->name);
|
||||||
/*
|
/*
|
||||||
* Poor little chip can't reset its own start
|
* Poor little chip can't reset its own start
|
||||||
* pointer
|
* pointer
|
||||||
|
@ -616,9 +612,8 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
||||||
*/
|
*/
|
||||||
dev->stats.tx_packets++;
|
dev->stats.tx_packets++;
|
||||||
if (el_debug > 6)
|
if (el_debug > 6)
|
||||||
printk(KERN_DEBUG " Tx succeeded %s\n",
|
pr_debug("%s: Tx succeeded %s\n", dev->name,
|
||||||
(txsr & TX_RDY) ? "." :
|
(txsr & TX_RDY) ? "." : "but tx is busy!");
|
||||||
"but tx is busy!");
|
|
||||||
/*
|
/*
|
||||||
* This is safe the interrupt is atomic WRT itself.
|
* This is safe the interrupt is atomic WRT itself.
|
||||||
*/
|
*/
|
||||||
|
@ -633,7 +628,8 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
||||||
|
|
||||||
int rxsr = inb(RX_STATUS);
|
int rxsr = inb(RX_STATUS);
|
||||||
if (el_debug > 5)
|
if (el_debug > 5)
|
||||||
printk(KERN_DEBUG " rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS), inw(RX_LOW));
|
pr_debug("%s: rxsr=%02x txsr=%02x rp=%04x\n",
|
||||||
|
dev->name, rxsr, inb(TX_STATUS), inw(RX_LOW));
|
||||||
/*
|
/*
|
||||||
* Just reading rx_status fixes most errors.
|
* Just reading rx_status fixes most errors.
|
||||||
*/
|
*/
|
||||||
|
@ -643,7 +639,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
||||||
/* Handled to avoid board lock-up. */
|
/* Handled to avoid board lock-up. */
|
||||||
dev->stats.rx_length_errors++;
|
dev->stats.rx_length_errors++;
|
||||||
if (el_debug > 5)
|
if (el_debug > 5)
|
||||||
printk(KERN_DEBUG " runt.\n");
|
pr_debug("%s: runt.\n", dev->name);
|
||||||
} else if (rxsr & RX_GOOD) {
|
} else if (rxsr & RX_GOOD) {
|
||||||
/*
|
/*
|
||||||
* Receive worked.
|
* Receive worked.
|
||||||
|
@ -654,12 +650,10 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
|
||||||
* Nothing? Something is broken!
|
* Nothing? Something is broken!
|
||||||
*/
|
*/
|
||||||
if (el_debug > 2)
|
if (el_debug > 2)
|
||||||
printk(KERN_DEBUG "%s: No packet seen, rxsr=%02x **resetting 3c501***\n",
|
pr_debug("%s: No packet seen, rxsr=%02x **resetting 3c501***\n",
|
||||||
dev->name, rxsr);
|
dev->name, rxsr);
|
||||||
el_reset(dev);
|
el_reset(dev);
|
||||||
}
|
}
|
||||||
if (el_debug > 3)
|
|
||||||
printk(KERN_DEBUG ".\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -695,11 +689,11 @@ static void el_receive(struct net_device *dev)
|
||||||
pkt_len = inw(RX_LOW);
|
pkt_len = inw(RX_LOW);
|
||||||
|
|
||||||
if (el_debug > 4)
|
if (el_debug > 4)
|
||||||
printk(KERN_DEBUG " el_receive %d.\n", pkt_len);
|
pr_debug(" el_receive %d.\n", pkt_len);
|
||||||
|
|
||||||
if (pkt_len < 60 || pkt_len > 1536) {
|
if (pkt_len < 60 || pkt_len > 1536) {
|
||||||
if (el_debug)
|
if (el_debug)
|
||||||
printk(KERN_DEBUG "%s: bogus packet, length=%d\n",
|
pr_debug("%s: bogus packet, length=%d\n",
|
||||||
dev->name, pkt_len);
|
dev->name, pkt_len);
|
||||||
dev->stats.rx_over_errors++;
|
dev->stats.rx_over_errors++;
|
||||||
return;
|
return;
|
||||||
|
@ -718,8 +712,7 @@ static void el_receive(struct net_device *dev)
|
||||||
|
|
||||||
outw(0x00, GP_LOW);
|
outw(0x00, GP_LOW);
|
||||||
if (skb == NULL) {
|
if (skb == NULL) {
|
||||||
printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n",
|
pr_info("%s: Memory squeeze, dropping packet.\n", dev->name);
|
||||||
dev->name);
|
|
||||||
dev->stats.rx_dropped++;
|
dev->stats.rx_dropped++;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
@ -753,7 +746,7 @@ static void el_reset(struct net_device *dev)
|
||||||
int ioaddr = dev->base_addr;
|
int ioaddr = dev->base_addr;
|
||||||
|
|
||||||
if (el_debug > 2)
|
if (el_debug > 2)
|
||||||
printk(KERN_INFO "3c501 reset...");
|
pr_info("3c501 reset...\n");
|
||||||
outb(AX_RESET, AX_CMD); /* Reset the chip */
|
outb(AX_RESET, AX_CMD); /* Reset the chip */
|
||||||
/* Aux control, irq and loopback enabled */
|
/* Aux control, irq and loopback enabled */
|
||||||
outb(AX_LOOP, AX_CMD);
|
outb(AX_LOOP, AX_CMD);
|
||||||
|
@ -787,7 +780,7 @@ static int el1_close(struct net_device *dev)
|
||||||
int ioaddr = dev->base_addr;
|
int ioaddr = dev->base_addr;
|
||||||
|
|
||||||
if (el_debug > 2)
|
if (el_debug > 2)
|
||||||
printk(KERN_INFO "%s: Shutting down Ethernet card at %#x.\n",
|
pr_info("%s: Shutting down Ethernet card at %#x.\n",
|
||||||
dev->name, ioaddr);
|
dev->name, ioaddr);
|
||||||
|
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
|
|
|
@ -234,16 +234,16 @@ el2_probe1(struct net_device *dev, int ioaddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ei_debug && version_printed++ == 0)
|
if (ei_debug && version_printed++ == 0)
|
||||||
printk(version);
|
pr_debug("%s", version);
|
||||||
|
|
||||||
dev->base_addr = ioaddr;
|
dev->base_addr = ioaddr;
|
||||||
|
|
||||||
printk("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);
|
pr_info("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);
|
||||||
|
|
||||||
/* Retrieve and print the ethernet address. */
|
/* Retrieve and print the ethernet address. */
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
dev->dev_addr[i] = inb(ioaddr + i);
|
dev->dev_addr[i] = inb(ioaddr + i);
|
||||||
printk("%pM", dev->dev_addr);
|
pr_cont("%pM", dev->dev_addr);
|
||||||
|
|
||||||
/* Map the 8390 back into the window. */
|
/* Map the 8390 back into the window. */
|
||||||
outb(ECNTRL_THIN, ioaddr + 0x406);
|
outb(ECNTRL_THIN, ioaddr + 0x406);
|
||||||
|
@ -256,7 +256,8 @@ el2_probe1(struct net_device *dev, int ioaddr)
|
||||||
outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
|
outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
|
||||||
|
|
||||||
/* Probe for, turn on and clear the board's shared memory. */
|
/* Probe for, turn on and clear the board's shared memory. */
|
||||||
if (ei_debug > 2) printk(" memory jumpers %2.2x ", membase_reg);
|
if (ei_debug > 2)
|
||||||
|
pr_cont(" memory jumpers %2.2x ", membase_reg);
|
||||||
outb(EGACFR_NORM, ioaddr + 0x405); /* Enable RAM */
|
outb(EGACFR_NORM, ioaddr + 0x405); /* Enable RAM */
|
||||||
|
|
||||||
/* This should be probed for (or set via an ioctl()) at run-time.
|
/* This should be probed for (or set via an ioctl()) at run-time.
|
||||||
|
@ -268,7 +269,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
|
||||||
#else
|
#else
|
||||||
ei_status.interface_num = dev->mem_end & 0xf;
|
ei_status.interface_num = dev->mem_end & 0xf;
|
||||||
#endif
|
#endif
|
||||||
printk(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex");
|
pr_cont(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex");
|
||||||
|
|
||||||
if ((membase_reg & 0xf0) == 0) {
|
if ((membase_reg & 0xf0) == 0) {
|
||||||
dev->mem_start = 0;
|
dev->mem_start = 0;
|
||||||
|
@ -292,7 +293,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
|
||||||
writel(test_val, mem_base + i);
|
writel(test_val, mem_base + i);
|
||||||
if (readl(mem_base) != 0xba5eba5e
|
if (readl(mem_base) != 0xba5eba5e
|
||||||
|| readl(mem_base + i) != test_val) {
|
|| readl(mem_base + i) != test_val) {
|
||||||
printk("3c503: memory failure or memory address conflict.\n");
|
pr_warning("3c503: memory failure or memory address conflict.\n");
|
||||||
dev->mem_start = 0;
|
dev->mem_start = 0;
|
||||||
ei_status.name = "3c503-PIO";
|
ei_status.name = "3c503-PIO";
|
||||||
iounmap(mem_base);
|
iounmap(mem_base);
|
||||||
|
@ -344,7 +345,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
|
||||||
if (dev->irq == 2)
|
if (dev->irq == 2)
|
||||||
dev->irq = 9;
|
dev->irq = 9;
|
||||||
else if (dev->irq > 5 && dev->irq != 9) {
|
else if (dev->irq > 5 && dev->irq != 9) {
|
||||||
printk("3c503: configured interrupt %d invalid, will use autoIRQ.\n",
|
pr_warning("3c503: configured interrupt %d invalid, will use autoIRQ.\n",
|
||||||
dev->irq);
|
dev->irq);
|
||||||
dev->irq = 0;
|
dev->irq = 0;
|
||||||
}
|
}
|
||||||
|
@ -359,7 +360,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
|
||||||
goto out1;
|
goto out1;
|
||||||
|
|
||||||
if (dev->mem_start)
|
if (dev->mem_start)
|
||||||
printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
|
pr_info("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
|
||||||
dev->name, ei_status.name, (wordlength+1)<<3,
|
dev->name, ei_status.name, (wordlength+1)<<3,
|
||||||
dev->mem_start, dev->mem_end-1);
|
dev->mem_start, dev->mem_end-1);
|
||||||
|
|
||||||
|
@ -367,7 +368,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
|
||||||
{
|
{
|
||||||
ei_status.tx_start_page = EL2_MB1_START_PG;
|
ei_status.tx_start_page = EL2_MB1_START_PG;
|
||||||
ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
|
ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
|
||||||
printk("\n%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
|
pr_info("%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
|
||||||
dev->name, ei_status.name, (wordlength+1)<<3);
|
dev->name, ei_status.name, (wordlength+1)<<3);
|
||||||
}
|
}
|
||||||
release_region(ioaddr + 0x400, 8);
|
release_region(ioaddr + 0x400, 8);
|
||||||
|
@ -435,15 +436,16 @@ static void
|
||||||
el2_reset_8390(struct net_device *dev)
|
el2_reset_8390(struct net_device *dev)
|
||||||
{
|
{
|
||||||
if (ei_debug > 1) {
|
if (ei_debug > 1) {
|
||||||
printk("%s: Resetting the 3c503 board...", dev->name);
|
pr_debug("%s: Resetting the 3c503 board...", dev->name);
|
||||||
printk("%#lx=%#02x %#lx=%#02x %#lx=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
|
pr_cont(" %#lx=%#02x %#lx=%#02x %#lx=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
|
||||||
E33G_CNTRL, inb(E33G_CNTRL), E33G_GACFR, inb(E33G_GACFR));
|
E33G_CNTRL, inb(E33G_CNTRL), E33G_GACFR, inb(E33G_GACFR));
|
||||||
}
|
}
|
||||||
outb_p(ECNTRL_RESET|ECNTRL_THIN, E33G_CNTRL);
|
outb_p(ECNTRL_RESET|ECNTRL_THIN, E33G_CNTRL);
|
||||||
ei_status.txing = 0;
|
ei_status.txing = 0;
|
||||||
outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
|
outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
|
||||||
el2_init_card(dev);
|
el2_init_card(dev);
|
||||||
if (ei_debug > 1) printk("done\n");
|
if (ei_debug > 1)
|
||||||
|
pr_cont("done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the 3c503 GA registers after a reset. */
|
/* Initialize the 3c503 GA registers after a reset. */
|
||||||
|
@ -529,7 +531,7 @@ el2_block_output(struct net_device *dev, int count,
|
||||||
{
|
{
|
||||||
if(!boguscount--)
|
if(!boguscount--)
|
||||||
{
|
{
|
||||||
printk("%s: FIFO blocked in el2_block_output.\n", dev->name);
|
pr_notice("%s: FIFO blocked in el2_block_output.\n", dev->name);
|
||||||
el2_reset_8390(dev);
|
el2_reset_8390(dev);
|
||||||
goto blocked;
|
goto blocked;
|
||||||
}
|
}
|
||||||
|
@ -581,7 +583,7 @@ el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_pag
|
||||||
{
|
{
|
||||||
if(!boguscount--)
|
if(!boguscount--)
|
||||||
{
|
{
|
||||||
printk("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name);
|
pr_notice("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name);
|
||||||
memset(hdr, 0x00, sizeof(struct e8390_pkt_hdr));
|
memset(hdr, 0x00, sizeof(struct e8390_pkt_hdr));
|
||||||
el2_reset_8390(dev);
|
el2_reset_8390(dev);
|
||||||
goto blocked;
|
goto blocked;
|
||||||
|
@ -645,7 +647,7 @@ el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring
|
||||||
{
|
{
|
||||||
if(!boguscount--)
|
if(!boguscount--)
|
||||||
{
|
{
|
||||||
printk("%s: FIFO blocked in el2_block_input.\n", dev->name);
|
pr_notice("%s: FIFO blocked in el2_block_input.\n", dev->name);
|
||||||
el2_reset_8390(dev);
|
el2_reset_8390(dev);
|
||||||
goto blocked;
|
goto blocked;
|
||||||
}
|
}
|
||||||
|
@ -707,7 +709,7 @@ init_module(void)
|
||||||
for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
|
for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
|
||||||
if (io[this_dev] == 0) {
|
if (io[this_dev] == 0) {
|
||||||
if (this_dev != 0) break; /* only autoprobe 1st one */
|
if (this_dev != 0) break; /* only autoprobe 1st one */
|
||||||
printk(KERN_NOTICE "3c503.c: Presently autoprobing (not recommended) for a single card.\n");
|
pr_notice("3c503.c: Presently autoprobing (not recommended) for a single card.\n");
|
||||||
}
|
}
|
||||||
dev = alloc_eip_netdev();
|
dev = alloc_eip_netdev();
|
||||||
if (!dev)
|
if (!dev)
|
||||||
|
@ -720,7 +722,7 @@ init_module(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
printk(KERN_WARNING "3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
|
pr_warning("3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (found)
|
if (found)
|
||||||
|
|
|
@ -126,26 +126,25 @@
|
||||||
*
|
*
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
|
|
||||||
static const char filename[] = __FILE__;
|
#define filename __FILE__
|
||||||
|
|
||||||
static const char timeout_msg[] = "*** timeout at %s:%s (line %d) ***\n";
|
#define timeout_msg "*** timeout at %s:%s (line %d) ***\n"
|
||||||
#define TIMEOUT_MSG(lineno) \
|
#define TIMEOUT_MSG(lineno) \
|
||||||
printk(timeout_msg, filename,__func__,(lineno))
|
pr_notice(timeout_msg, filename, __func__, (lineno))
|
||||||
|
|
||||||
static const char invalid_pcb_msg[] =
|
#define invalid_pcb_msg "*** invalid pcb length %d at %s:%s (line %d) ***\n"
|
||||||
"*** invalid pcb length %d at %s:%s (line %d) ***\n";
|
|
||||||
#define INVALID_PCB_MSG(len) \
|
#define INVALID_PCB_MSG(len) \
|
||||||
printk(invalid_pcb_msg, (len),filename,__func__,__LINE__)
|
pr_notice(invalid_pcb_msg, (len), filename, __func__, __LINE__)
|
||||||
|
|
||||||
static char search_msg[] __initdata = KERN_INFO "%s: Looking for 3c505 adapter at address %#x...";
|
#define search_msg "%s: Looking for 3c505 adapter at address %#x..."
|
||||||
|
|
||||||
static char stilllooking_msg[] __initdata = "still looking...";
|
#define stilllooking_msg "still looking..."
|
||||||
|
|
||||||
static char found_msg[] __initdata = "found.\n";
|
#define found_msg "found.\n"
|
||||||
|
|
||||||
static char notfound_msg[] __initdata = "not found (reason = %d)\n";
|
#define notfound_msg "not found (reason = %d)\n"
|
||||||
|
|
||||||
static char couldnot_msg[] __initdata = KERN_INFO "%s: 3c505 not found\n";
|
#define couldnot_msg "%s: 3c505 not found\n"
|
||||||
|
|
||||||
/*********************************************************
|
/*********************************************************
|
||||||
*
|
*
|
||||||
|
@ -284,7 +283,7 @@ static inline void adapter_reset(struct net_device *dev)
|
||||||
|
|
||||||
outb_control(orig_hcr, dev);
|
outb_control(orig_hcr, dev);
|
||||||
if (!start_receive(dev, &adapter->tx_pcb))
|
if (!start_receive(dev, &adapter->tx_pcb))
|
||||||
printk(KERN_ERR "%s: start receive command failed \n", dev->name);
|
pr_err("%s: start receive command failed\n", dev->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check to make sure that a DMA transfer hasn't timed out. This should
|
/* Check to make sure that a DMA transfer hasn't timed out. This should
|
||||||
|
@ -296,7 +295,9 @@ static inline void check_3c505_dma(struct net_device *dev)
|
||||||
elp_device *adapter = netdev_priv(dev);
|
elp_device *adapter = netdev_priv(dev);
|
||||||
if (adapter->dmaing && time_after(jiffies, adapter->current_dma.start_time + 10)) {
|
if (adapter->dmaing && time_after(jiffies, adapter->current_dma.start_time + 10)) {
|
||||||
unsigned long flags, f;
|
unsigned long flags, f;
|
||||||
printk(KERN_ERR "%s: DMA %s timed out, %d bytes left\n", dev->name, adapter->current_dma.direction ? "download" : "upload", get_dma_residue(dev->dma));
|
pr_err("%s: DMA %s timed out, %d bytes left\n", dev->name,
|
||||||
|
adapter->current_dma.direction ? "download" : "upload",
|
||||||
|
get_dma_residue(dev->dma));
|
||||||
spin_lock_irqsave(&adapter->lock, flags);
|
spin_lock_irqsave(&adapter->lock, flags);
|
||||||
adapter->dmaing = 0;
|
adapter->dmaing = 0;
|
||||||
adapter->busy = 0;
|
adapter->busy = 0;
|
||||||
|
@ -321,7 +322,7 @@ static inline bool send_pcb_slow(unsigned int base_addr, unsigned char byte)
|
||||||
if (inb_status(base_addr) & HCRE)
|
if (inb_status(base_addr) & HCRE)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
printk(KERN_WARNING "3c505: send_pcb_slow timed out\n");
|
pr_warning("3c505: send_pcb_slow timed out\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,7 +334,7 @@ static inline bool send_pcb_fast(unsigned int base_addr, unsigned char byte)
|
||||||
if (inb_status(base_addr) & HCRE)
|
if (inb_status(base_addr) & HCRE)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
printk(KERN_WARNING "3c505: send_pcb_fast timed out\n");
|
pr_warning("3c505: send_pcb_fast timed out\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,7 +387,7 @@ static bool send_pcb(struct net_device *dev, pcb_struct * pcb)
|
||||||
/* Avoid contention */
|
/* Avoid contention */
|
||||||
if (test_and_set_bit(1, &adapter->send_pcb_semaphore)) {
|
if (test_and_set_bit(1, &adapter->send_pcb_semaphore)) {
|
||||||
if (elp_debug >= 3) {
|
if (elp_debug >= 3) {
|
||||||
printk(KERN_DEBUG "%s: send_pcb entered while threaded\n", dev->name);
|
pr_debug("%s: send_pcb entered while threaded\n", dev->name);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -424,14 +425,15 @@ static bool send_pcb(struct net_device *dev, pcb_struct * pcb)
|
||||||
|
|
||||||
case ASF_PCB_NAK:
|
case ASF_PCB_NAK:
|
||||||
#ifdef ELP_DEBUG
|
#ifdef ELP_DEBUG
|
||||||
printk(KERN_DEBUG "%s: send_pcb got NAK\n", dev->name);
|
pr_debug("%s: send_pcb got NAK\n", dev->name);
|
||||||
#endif
|
#endif
|
||||||
goto abort;
|
goto abort;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elp_debug >= 1)
|
if (elp_debug >= 1)
|
||||||
printk(KERN_DEBUG "%s: timeout waiting for PCB acknowledge (status %02x)\n", dev->name, inb_status(dev->base_addr));
|
pr_debug("%s: timeout waiting for PCB acknowledge (status %02x)\n",
|
||||||
|
dev->name, inb_status(dev->base_addr));
|
||||||
goto abort;
|
goto abort;
|
||||||
|
|
||||||
sti_abort:
|
sti_abort:
|
||||||
|
@ -481,7 +483,7 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
|
||||||
while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout));
|
while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout));
|
||||||
if (time_after_eq(jiffies, timeout)) {
|
if (time_after_eq(jiffies, timeout)) {
|
||||||
TIMEOUT_MSG(__LINE__);
|
TIMEOUT_MSG(__LINE__);
|
||||||
printk(KERN_INFO "%s: status %02x\n", dev->name, stat);
|
pr_info("%s: status %02x\n", dev->name, stat);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pcb->length = inb_command(dev->base_addr);
|
pcb->length = inb_command(dev->base_addr);
|
||||||
|
@ -518,7 +520,7 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
|
||||||
/* safety check total length vs data length */
|
/* safety check total length vs data length */
|
||||||
if (total_length != (pcb->length + 2)) {
|
if (total_length != (pcb->length + 2)) {
|
||||||
if (elp_debug >= 2)
|
if (elp_debug >= 2)
|
||||||
printk(KERN_WARNING "%s: mangled PCB received\n", dev->name);
|
pr_warning("%s: mangled PCB received\n", dev->name);
|
||||||
set_hsf(dev, HSF_PCB_NAK);
|
set_hsf(dev, HSF_PCB_NAK);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -527,7 +529,7 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
|
||||||
if (test_and_set_bit(0, (void *) &adapter->busy)) {
|
if (test_and_set_bit(0, (void *) &adapter->busy)) {
|
||||||
if (backlog_next(adapter->rx_backlog.in) == adapter->rx_backlog.out) {
|
if (backlog_next(adapter->rx_backlog.in) == adapter->rx_backlog.out) {
|
||||||
set_hsf(dev, HSF_PCB_NAK);
|
set_hsf(dev, HSF_PCB_NAK);
|
||||||
printk(KERN_WARNING "%s: PCB rejected, transfer in progress and backlog full\n", dev->name);
|
pr_warning("%s: PCB rejected, transfer in progress and backlog full\n", dev->name);
|
||||||
pcb->command = 0;
|
pcb->command = 0;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -552,7 +554,7 @@ static bool start_receive(struct net_device *dev, pcb_struct * tx_pcb)
|
||||||
elp_device *adapter = netdev_priv(dev);
|
elp_device *adapter = netdev_priv(dev);
|
||||||
|
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: restarting receiver\n", dev->name);
|
pr_debug("%s: restarting receiver\n", dev->name);
|
||||||
tx_pcb->command = CMD_RECEIVE_PACKET;
|
tx_pcb->command = CMD_RECEIVE_PACKET;
|
||||||
tx_pcb->length = sizeof(struct Rcv_pkt);
|
tx_pcb->length = sizeof(struct Rcv_pkt);
|
||||||
tx_pcb->data.rcv_pkt.buf_seg
|
tx_pcb->data.rcv_pkt.buf_seg
|
||||||
|
@ -586,7 +588,7 @@ static void receive_packet(struct net_device *dev, int len)
|
||||||
skb = dev_alloc_skb(rlen + 2);
|
skb = dev_alloc_skb(rlen + 2);
|
||||||
|
|
||||||
if (!skb) {
|
if (!skb) {
|
||||||
printk(KERN_WARNING "%s: memory squeeze, dropping packet\n", dev->name);
|
pr_warning("%s: memory squeeze, dropping packet\n", dev->name);
|
||||||
target = adapter->dma_buffer;
|
target = adapter->dma_buffer;
|
||||||
adapter->current_dma.target = NULL;
|
adapter->current_dma.target = NULL;
|
||||||
/* FIXME: stats */
|
/* FIXME: stats */
|
||||||
|
@ -604,7 +606,8 @@ static void receive_packet(struct net_device *dev, int len)
|
||||||
|
|
||||||
/* if this happens, we die */
|
/* if this happens, we die */
|
||||||
if (test_and_set_bit(0, (void *) &adapter->dmaing))
|
if (test_and_set_bit(0, (void *) &adapter->dmaing))
|
||||||
printk(KERN_ERR "%s: rx blocked, DMA in progress, dir %d\n", dev->name, adapter->current_dma.direction);
|
pr_err("%s: rx blocked, DMA in progress, dir %d\n",
|
||||||
|
dev->name, adapter->current_dma.direction);
|
||||||
|
|
||||||
adapter->current_dma.direction = 0;
|
adapter->current_dma.direction = 0;
|
||||||
adapter->current_dma.length = rlen;
|
adapter->current_dma.length = rlen;
|
||||||
|
@ -623,14 +626,14 @@ static void receive_packet(struct net_device *dev, int len)
|
||||||
release_dma_lock(flags);
|
release_dma_lock(flags);
|
||||||
|
|
||||||
if (elp_debug >= 3) {
|
if (elp_debug >= 3) {
|
||||||
printk(KERN_DEBUG "%s: rx DMA transfer started\n", dev->name);
|
pr_debug("%s: rx DMA transfer started\n", dev->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adapter->rx_active)
|
if (adapter->rx_active)
|
||||||
adapter->rx_active--;
|
adapter->rx_active--;
|
||||||
|
|
||||||
if (!adapter->busy)
|
if (!adapter->busy)
|
||||||
printk(KERN_WARNING "%s: receive_packet called, busy not set.\n", dev->name);
|
pr_warning("%s: receive_packet called, busy not set.\n", dev->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
|
@ -655,12 +658,13 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
||||||
* has a DMA transfer finished?
|
* has a DMA transfer finished?
|
||||||
*/
|
*/
|
||||||
if (inb_status(dev->base_addr) & DONE) {
|
if (inb_status(dev->base_addr) & DONE) {
|
||||||
if (!adapter->dmaing) {
|
if (!adapter->dmaing)
|
||||||
printk(KERN_WARNING "%s: phantom DMA completed\n", dev->name);
|
pr_warning("%s: phantom DMA completed\n", dev->name);
|
||||||
}
|
|
||||||
if (elp_debug >= 3) {
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: %s DMA complete, status %02x\n", dev->name, adapter->current_dma.direction ? "tx" : "rx", inb_status(dev->base_addr));
|
pr_debug("%s: %s DMA complete, status %02x\n", dev->name,
|
||||||
}
|
adapter->current_dma.direction ? "tx" : "rx",
|
||||||
|
inb_status(dev->base_addr));
|
||||||
|
|
||||||
outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev);
|
outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev);
|
||||||
if (adapter->current_dma.direction) {
|
if (adapter->current_dma.direction) {
|
||||||
|
@ -682,7 +686,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
||||||
int t = adapter->rx_backlog.length[adapter->rx_backlog.out];
|
int t = adapter->rx_backlog.length[adapter->rx_backlog.out];
|
||||||
adapter->rx_backlog.out = backlog_next(adapter->rx_backlog.out);
|
adapter->rx_backlog.out = backlog_next(adapter->rx_backlog.out);
|
||||||
if (elp_debug >= 2)
|
if (elp_debug >= 2)
|
||||||
printk(KERN_DEBUG "%s: receiving backlogged packet (%d)\n", dev->name, t);
|
pr_debug("%s: receiving backlogged packet (%d)\n", dev->name, t);
|
||||||
receive_packet(dev, t);
|
receive_packet(dev, t);
|
||||||
} else {
|
} else {
|
||||||
adapter->busy = 0;
|
adapter->busy = 0;
|
||||||
|
@ -713,21 +717,23 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
||||||
len = adapter->irx_pcb.data.rcv_resp.pkt_len;
|
len = adapter->irx_pcb.data.rcv_resp.pkt_len;
|
||||||
dlen = adapter->irx_pcb.data.rcv_resp.buf_len;
|
dlen = adapter->irx_pcb.data.rcv_resp.buf_len;
|
||||||
if (adapter->irx_pcb.data.rcv_resp.timeout != 0) {
|
if (adapter->irx_pcb.data.rcv_resp.timeout != 0) {
|
||||||
printk(KERN_ERR "%s: interrupt - packet not received correctly\n", dev->name);
|
pr_err("%s: interrupt - packet not received correctly\n", dev->name);
|
||||||
} else {
|
} else {
|
||||||
if (elp_debug >= 3) {
|
if (elp_debug >= 3) {
|
||||||
printk(KERN_DEBUG "%s: interrupt - packet received of length %i (%i)\n", dev->name, len, dlen);
|
pr_debug("%s: interrupt - packet received of length %i (%i)\n",
|
||||||
|
dev->name, len, dlen);
|
||||||
}
|
}
|
||||||
if (adapter->irx_pcb.command == 0xff) {
|
if (adapter->irx_pcb.command == 0xff) {
|
||||||
if (elp_debug >= 2)
|
if (elp_debug >= 2)
|
||||||
printk(KERN_DEBUG "%s: adding packet to backlog (len = %d)\n", dev->name, dlen);
|
pr_debug("%s: adding packet to backlog (len = %d)\n",
|
||||||
|
dev->name, dlen);
|
||||||
adapter->rx_backlog.length[adapter->rx_backlog.in] = dlen;
|
adapter->rx_backlog.length[adapter->rx_backlog.in] = dlen;
|
||||||
adapter->rx_backlog.in = backlog_next(adapter->rx_backlog.in);
|
adapter->rx_backlog.in = backlog_next(adapter->rx_backlog.in);
|
||||||
} else {
|
} else {
|
||||||
receive_packet(dev, dlen);
|
receive_packet(dev, dlen);
|
||||||
}
|
}
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: packet received\n", dev->name);
|
pr_debug("%s: packet received\n", dev->name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -737,7 +743,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
||||||
case CMD_CONFIGURE_82586_RESPONSE:
|
case CMD_CONFIGURE_82586_RESPONSE:
|
||||||
adapter->got[CMD_CONFIGURE_82586] = 1;
|
adapter->got[CMD_CONFIGURE_82586] = 1;
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: interrupt - configure response received\n", dev->name);
|
pr_debug("%s: interrupt - configure response received\n", dev->name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -746,7 +752,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
||||||
case CMD_CONFIGURE_ADAPTER_RESPONSE:
|
case CMD_CONFIGURE_ADAPTER_RESPONSE:
|
||||||
adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1;
|
adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1;
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: Adapter memory configuration %s.\n", dev->name,
|
pr_debug("%s: Adapter memory configuration %s.\n", dev->name,
|
||||||
adapter->irx_pcb.data.failed ? "failed" : "succeeded");
|
adapter->irx_pcb.data.failed ? "failed" : "succeeded");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -756,7 +762,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
||||||
case CMD_LOAD_MULTICAST_RESPONSE:
|
case CMD_LOAD_MULTICAST_RESPONSE:
|
||||||
adapter->got[CMD_LOAD_MULTICAST_LIST] = 1;
|
adapter->got[CMD_LOAD_MULTICAST_LIST] = 1;
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: Multicast address list loading %s.\n", dev->name,
|
pr_debug("%s: Multicast address list loading %s.\n", dev->name,
|
||||||
adapter->irx_pcb.data.failed ? "failed" : "succeeded");
|
adapter->irx_pcb.data.failed ? "failed" : "succeeded");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -766,7 +772,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
||||||
case CMD_SET_ADDRESS_RESPONSE:
|
case CMD_SET_ADDRESS_RESPONSE:
|
||||||
adapter->got[CMD_SET_STATION_ADDRESS] = 1;
|
adapter->got[CMD_SET_STATION_ADDRESS] = 1;
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: Ethernet address setting %s.\n", dev->name,
|
pr_debug("%s: Ethernet address setting %s.\n", dev->name,
|
||||||
adapter->irx_pcb.data.failed ? "failed" : "succeeded");
|
adapter->irx_pcb.data.failed ? "failed" : "succeeded");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -783,7 +789,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
||||||
dev->stats.rx_over_errors += adapter->irx_pcb.data.netstat.err_res;
|
dev->stats.rx_over_errors += adapter->irx_pcb.data.netstat.err_res;
|
||||||
adapter->got[CMD_NETWORK_STATISTICS] = 1;
|
adapter->got[CMD_NETWORK_STATISTICS] = 1;
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: interrupt - statistics response received\n", dev->name);
|
pr_debug("%s: interrupt - statistics response received\n", dev->name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -791,17 +797,17 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
||||||
*/
|
*/
|
||||||
case CMD_TRANSMIT_PACKET_COMPLETE:
|
case CMD_TRANSMIT_PACKET_COMPLETE:
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: interrupt - packet sent\n", dev->name);
|
pr_debug("%s: interrupt - packet sent\n", dev->name);
|
||||||
if (!netif_running(dev))
|
if (!netif_running(dev))
|
||||||
break;
|
break;
|
||||||
switch (adapter->irx_pcb.data.xmit_resp.c_stat) {
|
switch (adapter->irx_pcb.data.xmit_resp.c_stat) {
|
||||||
case 0xffff:
|
case 0xffff:
|
||||||
dev->stats.tx_aborted_errors++;
|
dev->stats.tx_aborted_errors++;
|
||||||
printk(KERN_INFO "%s: transmit timed out, network cable problem?\n", dev->name);
|
pr_info("%s: transmit timed out, network cable problem?\n", dev->name);
|
||||||
break;
|
break;
|
||||||
case 0xfffe:
|
case 0xfffe:
|
||||||
dev->stats.tx_fifo_errors++;
|
dev->stats.tx_fifo_errors++;
|
||||||
printk(KERN_INFO "%s: transmit timed out, FIFO underrun\n", dev->name);
|
pr_info("%s: transmit timed out, FIFO underrun\n", dev->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
|
@ -811,11 +817,12 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
|
||||||
* some unknown PCB
|
* some unknown PCB
|
||||||
*/
|
*/
|
||||||
default:
|
default:
|
||||||
printk(KERN_DEBUG "%s: unknown PCB received - %2.2x\n", dev->name, adapter->irx_pcb.command);
|
pr_debug("%s: unknown PCB received - %2.2x\n",
|
||||||
|
dev->name, adapter->irx_pcb.command);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "%s: failed to read PCB on interrupt\n", dev->name);
|
pr_warning("%s: failed to read PCB on interrupt\n", dev->name);
|
||||||
adapter_reset(dev);
|
adapter_reset(dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -844,13 +851,13 @@ static int elp_open(struct net_device *dev)
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: request to open device\n", dev->name);
|
pr_debug("%s: request to open device\n", dev->name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* make sure we actually found the device
|
* make sure we actually found the device
|
||||||
*/
|
*/
|
||||||
if (adapter == NULL) {
|
if (adapter == NULL) {
|
||||||
printk(KERN_ERR "%s: Opening a non-existent physical device\n", dev->name);
|
pr_err("%s: Opening a non-existent physical device\n", dev->name);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -880,17 +887,17 @@ static int elp_open(struct net_device *dev)
|
||||||
* install our interrupt service routine
|
* install our interrupt service routine
|
||||||
*/
|
*/
|
||||||
if ((retval = request_irq(dev->irq, &elp_interrupt, 0, dev->name, dev))) {
|
if ((retval = request_irq(dev->irq, &elp_interrupt, 0, dev->name, dev))) {
|
||||||
printk(KERN_ERR "%s: could not allocate IRQ%d\n", dev->name, dev->irq);
|
pr_err("%s: could not allocate IRQ%d\n", dev->name, dev->irq);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
if ((retval = request_dma(dev->dma, dev->name))) {
|
if ((retval = request_dma(dev->dma, dev->name))) {
|
||||||
free_irq(dev->irq, dev);
|
free_irq(dev->irq, dev);
|
||||||
printk(KERN_ERR "%s: could not allocate DMA%d channel\n", dev->name, dev->dma);
|
pr_err("%s: could not allocate DMA%d channel\n", dev->name, dev->dma);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
adapter->dma_buffer = (void *) dma_mem_alloc(DMA_BUFFER_SIZE);
|
adapter->dma_buffer = (void *) dma_mem_alloc(DMA_BUFFER_SIZE);
|
||||||
if (!adapter->dma_buffer) {
|
if (!adapter->dma_buffer) {
|
||||||
printk(KERN_ERR "%s: could not allocate DMA buffer\n", dev->name);
|
pr_err("%s: could not allocate DMA buffer\n", dev->name);
|
||||||
free_dma(dev->dma);
|
free_dma(dev->dma);
|
||||||
free_irq(dev->irq, dev);
|
free_irq(dev->irq, dev);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -906,7 +913,7 @@ static int elp_open(struct net_device *dev)
|
||||||
* configure adapter memory: we need 10 multicast addresses, default==0
|
* configure adapter memory: we need 10 multicast addresses, default==0
|
||||||
*/
|
*/
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: sending 3c505 memory configuration command\n", dev->name);
|
pr_debug("%s: sending 3c505 memory configuration command\n", dev->name);
|
||||||
adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY;
|
adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY;
|
||||||
adapter->tx_pcb.data.memconf.cmd_q = 10;
|
adapter->tx_pcb.data.memconf.cmd_q = 10;
|
||||||
adapter->tx_pcb.data.memconf.rcv_q = 20;
|
adapter->tx_pcb.data.memconf.rcv_q = 20;
|
||||||
|
@ -917,7 +924,7 @@ static int elp_open(struct net_device *dev)
|
||||||
adapter->tx_pcb.length = sizeof(struct Memconf);
|
adapter->tx_pcb.length = sizeof(struct Memconf);
|
||||||
adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 0;
|
adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 0;
|
||||||
if (!send_pcb(dev, &adapter->tx_pcb))
|
if (!send_pcb(dev, &adapter->tx_pcb))
|
||||||
printk(KERN_ERR "%s: couldn't send memory configuration command\n", dev->name);
|
pr_err("%s: couldn't send memory configuration command\n", dev->name);
|
||||||
else {
|
else {
|
||||||
unsigned long timeout = jiffies + TIMEOUT;
|
unsigned long timeout = jiffies + TIMEOUT;
|
||||||
while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && time_before(jiffies, timeout));
|
while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && time_before(jiffies, timeout));
|
||||||
|
@ -930,13 +937,13 @@ static int elp_open(struct net_device *dev)
|
||||||
* configure adapter to receive broadcast messages and wait for response
|
* configure adapter to receive broadcast messages and wait for response
|
||||||
*/
|
*/
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: sending 82586 configure command\n", dev->name);
|
pr_debug("%s: sending 82586 configure command\n", dev->name);
|
||||||
adapter->tx_pcb.command = CMD_CONFIGURE_82586;
|
adapter->tx_pcb.command = CMD_CONFIGURE_82586;
|
||||||
adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
|
adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
|
||||||
adapter->tx_pcb.length = 2;
|
adapter->tx_pcb.length = 2;
|
||||||
adapter->got[CMD_CONFIGURE_82586] = 0;
|
adapter->got[CMD_CONFIGURE_82586] = 0;
|
||||||
if (!send_pcb(dev, &adapter->tx_pcb))
|
if (!send_pcb(dev, &adapter->tx_pcb))
|
||||||
printk(KERN_ERR "%s: couldn't send 82586 configure command\n", dev->name);
|
pr_err("%s: couldn't send 82586 configure command\n", dev->name);
|
||||||
else {
|
else {
|
||||||
unsigned long timeout = jiffies + TIMEOUT;
|
unsigned long timeout = jiffies + TIMEOUT;
|
||||||
while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout));
|
while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout));
|
||||||
|
@ -952,7 +959,7 @@ static int elp_open(struct net_device *dev)
|
||||||
*/
|
*/
|
||||||
prime_rx(dev);
|
prime_rx(dev);
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: %d receive PCBs active\n", dev->name, adapter->rx_active);
|
pr_debug("%s: %d receive PCBs active\n", dev->name, adapter->rx_active);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* device is now officially open!
|
* device is now officially open!
|
||||||
|
@ -982,7 +989,7 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb)
|
||||||
|
|
||||||
if (test_and_set_bit(0, (void *) &adapter->busy)) {
|
if (test_and_set_bit(0, (void *) &adapter->busy)) {
|
||||||
if (elp_debug >= 2)
|
if (elp_debug >= 2)
|
||||||
printk(KERN_DEBUG "%s: transmit blocked\n", dev->name);
|
pr_debug("%s: transmit blocked\n", dev->name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1004,7 +1011,7 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb)
|
||||||
}
|
}
|
||||||
/* if this happens, we die */
|
/* if this happens, we die */
|
||||||
if (test_and_set_bit(0, (void *) &adapter->dmaing))
|
if (test_and_set_bit(0, (void *) &adapter->dmaing))
|
||||||
printk(KERN_DEBUG "%s: tx: DMA %d in progress\n", dev->name, adapter->current_dma.direction);
|
pr_debug("%s: tx: DMA %d in progress\n", dev->name, adapter->current_dma.direction);
|
||||||
|
|
||||||
adapter->current_dma.direction = 1;
|
adapter->current_dma.direction = 1;
|
||||||
adapter->current_dma.start_time = jiffies;
|
adapter->current_dma.start_time = jiffies;
|
||||||
|
@ -1030,7 +1037,7 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb)
|
||||||
release_dma_lock(flags);
|
release_dma_lock(flags);
|
||||||
|
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: DMA transfer started\n", dev->name);
|
pr_debug("%s: DMA transfer started\n", dev->name);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1044,9 +1051,10 @@ static void elp_timeout(struct net_device *dev)
|
||||||
int stat;
|
int stat;
|
||||||
|
|
||||||
stat = inb_status(dev->base_addr);
|
stat = inb_status(dev->base_addr);
|
||||||
printk(KERN_WARNING "%s: transmit timed out, lost %s?\n", dev->name, (stat & ACRF) ? "interrupt" : "command");
|
pr_warning("%s: transmit timed out, lost %s?\n", dev->name,
|
||||||
|
(stat & ACRF) ? "interrupt" : "command");
|
||||||
if (elp_debug >= 1)
|
if (elp_debug >= 1)
|
||||||
printk(KERN_DEBUG "%s: status %#02x\n", dev->name, stat);
|
pr_debug("%s: status %#02x\n", dev->name, stat);
|
||||||
dev->trans_start = jiffies;
|
dev->trans_start = jiffies;
|
||||||
dev->stats.tx_dropped++;
|
dev->stats.tx_dropped++;
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
|
@ -1068,7 +1076,7 @@ static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
check_3c505_dma(dev);
|
check_3c505_dma(dev);
|
||||||
|
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: request to send packet of length %d\n", dev->name, (int) skb->len);
|
pr_debug("%s: request to send packet of length %d\n", dev->name, (int) skb->len);
|
||||||
|
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
|
|
||||||
|
@ -1077,13 +1085,13 @@ static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
*/
|
*/
|
||||||
if (!send_packet(dev, skb)) {
|
if (!send_packet(dev, skb)) {
|
||||||
if (elp_debug >= 2) {
|
if (elp_debug >= 2) {
|
||||||
printk(KERN_DEBUG "%s: failed to transmit packet\n", dev->name);
|
pr_debug("%s: failed to transmit packet\n", dev->name);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&adapter->lock, flags);
|
spin_unlock_irqrestore(&adapter->lock, flags);
|
||||||
return 1;
|
return NETDEV_TX_BUSY;
|
||||||
}
|
}
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: packet of length %d sent\n", dev->name, (int) skb->len);
|
pr_debug("%s: packet of length %d sent\n", dev->name, (int) skb->len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* start the transmit timeout
|
* start the transmit timeout
|
||||||
|
@ -1107,7 +1115,7 @@ static struct net_device_stats *elp_get_stats(struct net_device *dev)
|
||||||
elp_device *adapter = netdev_priv(dev);
|
elp_device *adapter = netdev_priv(dev);
|
||||||
|
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: request for stats\n", dev->name);
|
pr_debug("%s: request for stats\n", dev->name);
|
||||||
|
|
||||||
/* If the device is closed, just return the latest stats we have,
|
/* If the device is closed, just return the latest stats we have,
|
||||||
- we cannot ask from the adapter without interrupts */
|
- we cannot ask from the adapter without interrupts */
|
||||||
|
@ -1119,7 +1127,7 @@ static struct net_device_stats *elp_get_stats(struct net_device *dev)
|
||||||
adapter->tx_pcb.length = 0;
|
adapter->tx_pcb.length = 0;
|
||||||
adapter->got[CMD_NETWORK_STATISTICS] = 0;
|
adapter->got[CMD_NETWORK_STATISTICS] = 0;
|
||||||
if (!send_pcb(dev, &adapter->tx_pcb))
|
if (!send_pcb(dev, &adapter->tx_pcb))
|
||||||
printk(KERN_ERR "%s: couldn't send get statistics command\n", dev->name);
|
pr_err("%s: couldn't send get statistics command\n", dev->name);
|
||||||
else {
|
else {
|
||||||
unsigned long timeout = jiffies + TIMEOUT;
|
unsigned long timeout = jiffies + TIMEOUT;
|
||||||
while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && time_before(jiffies, timeout));
|
while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && time_before(jiffies, timeout));
|
||||||
|
@ -1169,7 +1177,7 @@ static int elp_close(struct net_device *dev)
|
||||||
elp_device *adapter = netdev_priv(dev);
|
elp_device *adapter = netdev_priv(dev);
|
||||||
|
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: request to close device\n", dev->name);
|
pr_debug("%s: request to close device\n", dev->name);
|
||||||
|
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
|
|
||||||
|
@ -1213,7 +1221,7 @@ static void elp_set_mc_list(struct net_device *dev)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: request to set multicast list\n", dev->name);
|
pr_debug("%s: request to set multicast list\n", dev->name);
|
||||||
|
|
||||||
spin_lock_irqsave(&adapter->lock, flags);
|
spin_lock_irqsave(&adapter->lock, flags);
|
||||||
|
|
||||||
|
@ -1228,7 +1236,7 @@ static void elp_set_mc_list(struct net_device *dev)
|
||||||
}
|
}
|
||||||
adapter->got[CMD_LOAD_MULTICAST_LIST] = 0;
|
adapter->got[CMD_LOAD_MULTICAST_LIST] = 0;
|
||||||
if (!send_pcb(dev, &adapter->tx_pcb))
|
if (!send_pcb(dev, &adapter->tx_pcb))
|
||||||
printk(KERN_ERR "%s: couldn't send set_multicast command\n", dev->name);
|
pr_err("%s: couldn't send set_multicast command\n", dev->name);
|
||||||
else {
|
else {
|
||||||
unsigned long timeout = jiffies + TIMEOUT;
|
unsigned long timeout = jiffies + TIMEOUT;
|
||||||
while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && time_before(jiffies, timeout));
|
while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && time_before(jiffies, timeout));
|
||||||
|
@ -1247,14 +1255,14 @@ static void elp_set_mc_list(struct net_device *dev)
|
||||||
* and wait for response
|
* and wait for response
|
||||||
*/
|
*/
|
||||||
if (elp_debug >= 3)
|
if (elp_debug >= 3)
|
||||||
printk(KERN_DEBUG "%s: sending 82586 configure command\n", dev->name);
|
pr_debug("%s: sending 82586 configure command\n", dev->name);
|
||||||
adapter->tx_pcb.command = CMD_CONFIGURE_82586;
|
adapter->tx_pcb.command = CMD_CONFIGURE_82586;
|
||||||
adapter->tx_pcb.length = 2;
|
adapter->tx_pcb.length = 2;
|
||||||
adapter->got[CMD_CONFIGURE_82586] = 0;
|
adapter->got[CMD_CONFIGURE_82586] = 0;
|
||||||
if (!send_pcb(dev, &adapter->tx_pcb))
|
if (!send_pcb(dev, &adapter->tx_pcb))
|
||||||
{
|
{
|
||||||
spin_unlock_irqrestore(&adapter->lock, flags);
|
spin_unlock_irqrestore(&adapter->lock, flags);
|
||||||
printk(KERN_ERR "%s: couldn't send 82586 configure command\n", dev->name);
|
pr_err("%s: couldn't send 82586 configure command\n", dev->name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unsigned long timeout = jiffies + TIMEOUT;
|
unsigned long timeout = jiffies + TIMEOUT;
|
||||||
|
@ -1283,17 +1291,17 @@ static int __init elp_sense(struct net_device *dev)
|
||||||
orig_HSR = inb_status(addr);
|
orig_HSR = inb_status(addr);
|
||||||
|
|
||||||
if (elp_debug > 0)
|
if (elp_debug > 0)
|
||||||
printk(search_msg, name, addr);
|
pr_debug(search_msg, name, addr);
|
||||||
|
|
||||||
if (orig_HSR == 0xff) {
|
if (orig_HSR == 0xff) {
|
||||||
if (elp_debug > 0)
|
if (elp_debug > 0)
|
||||||
printk(notfound_msg, 1);
|
pr_cont(notfound_msg, 1);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for a while; the adapter may still be booting up */
|
/* Wait for a while; the adapter may still be booting up */
|
||||||
if (elp_debug > 0)
|
if (elp_debug > 0)
|
||||||
printk(stilllooking_msg);
|
pr_cont(stilllooking_msg);
|
||||||
|
|
||||||
if (orig_HSR & DIR) {
|
if (orig_HSR & DIR) {
|
||||||
/* If HCR.DIR is up, we pull it down. HSR.DIR should follow. */
|
/* If HCR.DIR is up, we pull it down. HSR.DIR should follow. */
|
||||||
|
@ -1301,7 +1309,7 @@ static int __init elp_sense(struct net_device *dev)
|
||||||
msleep(300);
|
msleep(300);
|
||||||
if (inb_status(addr) & DIR) {
|
if (inb_status(addr) & DIR) {
|
||||||
if (elp_debug > 0)
|
if (elp_debug > 0)
|
||||||
printk(notfound_msg, 2);
|
pr_cont(notfound_msg, 2);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1310,7 +1318,7 @@ static int __init elp_sense(struct net_device *dev)
|
||||||
msleep(300);
|
msleep(300);
|
||||||
if (!(inb_status(addr) & DIR)) {
|
if (!(inb_status(addr) & DIR)) {
|
||||||
if (elp_debug > 0)
|
if (elp_debug > 0)
|
||||||
printk(notfound_msg, 3);
|
pr_cont(notfound_msg, 3);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1318,7 +1326,7 @@ static int __init elp_sense(struct net_device *dev)
|
||||||
* It certainly looks like a 3c505.
|
* It certainly looks like a 3c505.
|
||||||
*/
|
*/
|
||||||
if (elp_debug > 0)
|
if (elp_debug > 0)
|
||||||
printk(found_msg);
|
pr_cont(found_msg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
out:
|
out:
|
||||||
|
@ -1349,7 +1357,7 @@ static int __init elp_autodetect(struct net_device *dev)
|
||||||
|
|
||||||
/* could not find an adapter */
|
/* could not find an adapter */
|
||||||
if (elp_debug > 0)
|
if (elp_debug > 0)
|
||||||
printk(couldnot_msg, dev->name);
|
pr_debug(couldnot_msg, dev->name);
|
||||||
|
|
||||||
return 0; /* Because of this, the layer above will return -ENODEV */
|
return 0; /* Because of this, the layer above will return -ENODEV */
|
||||||
}
|
}
|
||||||
|
@ -1424,16 +1432,16 @@ static int __init elplus_setup(struct net_device *dev)
|
||||||
/* Nope, it's ignoring the command register. This means that
|
/* Nope, it's ignoring the command register. This means that
|
||||||
* either it's still booting up, or it's died.
|
* either it's still booting up, or it's died.
|
||||||
*/
|
*/
|
||||||
printk(KERN_ERR "%s: command register wouldn't drain, ", dev->name);
|
pr_err("%s: command register wouldn't drain, ", dev->name);
|
||||||
if ((inb_status(dev->base_addr) & 7) == 3) {
|
if ((inb_status(dev->base_addr) & 7) == 3) {
|
||||||
/* If the adapter status is 3, it *could* still be booting.
|
/* If the adapter status is 3, it *could* still be booting.
|
||||||
* Give it the benefit of the doubt for 10 seconds.
|
* Give it the benefit of the doubt for 10 seconds.
|
||||||
*/
|
*/
|
||||||
printk("assuming 3c505 still starting\n");
|
pr_cont("assuming 3c505 still starting\n");
|
||||||
timeout = jiffies + 10*HZ;
|
timeout = jiffies + 10*HZ;
|
||||||
while (time_before(jiffies, timeout) && (inb_status(dev->base_addr) & 7));
|
while (time_before(jiffies, timeout) && (inb_status(dev->base_addr) & 7));
|
||||||
if (inb_status(dev->base_addr) & 7) {
|
if (inb_status(dev->base_addr) & 7) {
|
||||||
printk(KERN_ERR "%s: 3c505 failed to start\n", dev->name);
|
pr_err("%s: 3c505 failed to start\n", dev->name);
|
||||||
} else {
|
} else {
|
||||||
okay = 1; /* It started */
|
okay = 1; /* It started */
|
||||||
}
|
}
|
||||||
|
@ -1441,7 +1449,7 @@ static int __init elplus_setup(struct net_device *dev)
|
||||||
/* Otherwise, it must just be in a strange
|
/* Otherwise, it must just be in a strange
|
||||||
* state. We probably need to kick it.
|
* state. We probably need to kick it.
|
||||||
*/
|
*/
|
||||||
printk("3c505 is sulking\n");
|
pr_cont("3c505 is sulking\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (tries = 0; tries < 5 && okay; tries++) {
|
for (tries = 0; tries < 5 && okay; tries++) {
|
||||||
|
@ -1454,18 +1462,19 @@ static int __init elplus_setup(struct net_device *dev)
|
||||||
adapter->tx_pcb.length = 0;
|
adapter->tx_pcb.length = 0;
|
||||||
cookie = probe_irq_on();
|
cookie = probe_irq_on();
|
||||||
if (!send_pcb(dev, &adapter->tx_pcb)) {
|
if (!send_pcb(dev, &adapter->tx_pcb)) {
|
||||||
printk(KERN_ERR "%s: could not send first PCB\n", dev->name);
|
pr_err("%s: could not send first PCB\n", dev->name);
|
||||||
probe_irq_off(cookie);
|
probe_irq_off(cookie);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!receive_pcb(dev, &adapter->rx_pcb)) {
|
if (!receive_pcb(dev, &adapter->rx_pcb)) {
|
||||||
printk(KERN_ERR "%s: could not read first PCB\n", dev->name);
|
pr_err("%s: could not read first PCB\n", dev->name);
|
||||||
probe_irq_off(cookie);
|
probe_irq_off(cookie);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ((adapter->rx_pcb.command != CMD_ADDRESS_RESPONSE) ||
|
if ((adapter->rx_pcb.command != CMD_ADDRESS_RESPONSE) ||
|
||||||
(adapter->rx_pcb.length != 6)) {
|
(adapter->rx_pcb.length != 6)) {
|
||||||
printk(KERN_ERR "%s: first PCB wrong (%d, %d)\n", dev->name, adapter->rx_pcb.command, adapter->rx_pcb.length);
|
pr_err("%s: first PCB wrong (%d, %d)\n", dev->name,
|
||||||
|
adapter->rx_pcb.command, adapter->rx_pcb.length);
|
||||||
probe_irq_off(cookie);
|
probe_irq_off(cookie);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1474,32 +1483,32 @@ static int __init elplus_setup(struct net_device *dev)
|
||||||
/* It's broken. Do a hard reset to re-initialise the board,
|
/* It's broken. Do a hard reset to re-initialise the board,
|
||||||
* and try again.
|
* and try again.
|
||||||
*/
|
*/
|
||||||
printk(KERN_INFO "%s: resetting adapter\n", dev->name);
|
pr_info("%s: resetting adapter\n", dev->name);
|
||||||
outb_control(adapter->hcr_val | FLSH | ATTN, dev);
|
outb_control(adapter->hcr_val | FLSH | ATTN, dev);
|
||||||
outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev);
|
outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev);
|
||||||
}
|
}
|
||||||
printk(KERN_ERR "%s: failed to initialise 3c505\n", dev->name);
|
pr_err("%s: failed to initialise 3c505\n", dev->name);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
okay:
|
okay:
|
||||||
if (dev->irq) { /* Is there a preset IRQ? */
|
if (dev->irq) { /* Is there a preset IRQ? */
|
||||||
int rpt = probe_irq_off(cookie);
|
int rpt = probe_irq_off(cookie);
|
||||||
if (dev->irq != rpt) {
|
if (dev->irq != rpt) {
|
||||||
printk(KERN_WARNING "%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt);
|
pr_warning("%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt);
|
||||||
}
|
}
|
||||||
/* if dev->irq == probe_irq_off(cookie), all is well */
|
/* if dev->irq == probe_irq_off(cookie), all is well */
|
||||||
} else /* No preset IRQ; just use what we can detect */
|
} else /* No preset IRQ; just use what we can detect */
|
||||||
dev->irq = probe_irq_off(cookie);
|
dev->irq = probe_irq_off(cookie);
|
||||||
switch (dev->irq) { /* Legal, sane? */
|
switch (dev->irq) { /* Legal, sane? */
|
||||||
case 0:
|
case 0:
|
||||||
printk(KERN_ERR "%s: IRQ probe failed: check 3c505 jumpers.\n",
|
pr_err("%s: IRQ probe failed: check 3c505 jumpers.\n",
|
||||||
dev->name);
|
dev->name);
|
||||||
goto out;
|
goto out;
|
||||||
case 1:
|
case 1:
|
||||||
case 6:
|
case 6:
|
||||||
case 8:
|
case 8:
|
||||||
case 13:
|
case 13:
|
||||||
printk(KERN_ERR "%s: Impossible IRQ %d reported by probe_irq_off().\n",
|
pr_err("%s: Impossible IRQ %d reported by probe_irq_off().\n",
|
||||||
dev->name, dev->irq);
|
dev->name, dev->irq);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1521,7 +1530,7 @@ static int __init elplus_setup(struct net_device *dev)
|
||||||
dev->dma = dev->mem_start & 7;
|
dev->dma = dev->mem_start & 7;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printk(KERN_WARNING "%s: warning, DMA channel not specified, using default\n", dev->name);
|
pr_warning("%s: warning, DMA channel not specified, using default\n", dev->name);
|
||||||
dev->dma = ELP_DMA;
|
dev->dma = ELP_DMA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1529,11 +1538,8 @@ static int __init elplus_setup(struct net_device *dev)
|
||||||
/*
|
/*
|
||||||
* print remainder of startup message
|
* print remainder of startup message
|
||||||
*/
|
*/
|
||||||
printk(KERN_INFO "%s: 3c505 at %#lx, irq %d, dma %d, "
|
pr_info("%s: 3c505 at %#lx, irq %d, dma %d, addr %pM, ",
|
||||||
"addr %pM, ",
|
dev->name, dev->base_addr, dev->irq, dev->dma, dev->dev_addr);
|
||||||
dev->name, dev->base_addr, dev->irq, dev->dma,
|
|
||||||
dev->dev_addr);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* read more information from the adapter
|
* read more information from the adapter
|
||||||
*/
|
*/
|
||||||
|
@ -1544,9 +1550,10 @@ static int __init elplus_setup(struct net_device *dev)
|
||||||
!receive_pcb(dev, &adapter->rx_pcb) ||
|
!receive_pcb(dev, &adapter->rx_pcb) ||
|
||||||
(adapter->rx_pcb.command != CMD_ADAPTER_INFO_RESPONSE) ||
|
(adapter->rx_pcb.command != CMD_ADAPTER_INFO_RESPONSE) ||
|
||||||
(adapter->rx_pcb.length != 10)) {
|
(adapter->rx_pcb.length != 10)) {
|
||||||
printk("not responding to second PCB\n");
|
pr_cont("not responding to second PCB\n");
|
||||||
}
|
}
|
||||||
printk("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers, adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz);
|
pr_cont("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers,
|
||||||
|
adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* reconfigure the adapter memory to better suit our purposes
|
* reconfigure the adapter memory to better suit our purposes
|
||||||
|
@ -1563,10 +1570,10 @@ static int __init elplus_setup(struct net_device *dev)
|
||||||
!receive_pcb(dev, &adapter->rx_pcb) ||
|
!receive_pcb(dev, &adapter->rx_pcb) ||
|
||||||
(adapter->rx_pcb.command != CMD_CONFIGURE_ADAPTER_RESPONSE) ||
|
(adapter->rx_pcb.command != CMD_CONFIGURE_ADAPTER_RESPONSE) ||
|
||||||
(adapter->rx_pcb.length != 2)) {
|
(adapter->rx_pcb.length != 2)) {
|
||||||
printk(KERN_ERR "%s: could not configure adapter memory\n", dev->name);
|
pr_err("%s: could not configure adapter memory\n", dev->name);
|
||||||
}
|
}
|
||||||
if (adapter->rx_pcb.data.configure) {
|
if (adapter->rx_pcb.data.configure) {
|
||||||
printk(KERN_ERR "%s: adapter configuration failed\n", dev->name);
|
pr_err("%s: adapter configuration failed\n", dev->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->netdev_ops = &elp_netdev_ops;
|
dev->netdev_ops = &elp_netdev_ops;
|
||||||
|
@ -1631,17 +1638,17 @@ int __init init_module(void)
|
||||||
dev->dma = dma[this_dev];
|
dev->dma = dma[this_dev];
|
||||||
} else {
|
} else {
|
||||||
dev->dma = ELP_DMA;
|
dev->dma = ELP_DMA;
|
||||||
printk(KERN_WARNING "3c505.c: warning, using default DMA channel,\n");
|
pr_warning("3c505.c: warning, using default DMA channel,\n");
|
||||||
}
|
}
|
||||||
if (io[this_dev] == 0) {
|
if (io[this_dev] == 0) {
|
||||||
if (this_dev) {
|
if (this_dev) {
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printk(KERN_NOTICE "3c505.c: module autoprobe not recommended, give io=xx.\n");
|
pr_notice("3c505.c: module autoprobe not recommended, give io=xx.\n");
|
||||||
}
|
}
|
||||||
if (elplus_setup(dev) != 0) {
|
if (elplus_setup(dev) != 0) {
|
||||||
printk(KERN_WARNING "3c505.c: Failed to register card at 0x%x.\n", io[this_dev]);
|
pr_warning("3c505.c: Failed to register card at 0x%x.\n", io[this_dev]);
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -364,7 +364,7 @@ static const struct net_device_ops netdev_ops = {
|
||||||
|
|
||||||
static int __init el16_probe1(struct net_device *dev, int ioaddr)
|
static int __init el16_probe1(struct net_device *dev, int ioaddr)
|
||||||
{
|
{
|
||||||
static unsigned char init_ID_done, version_printed;
|
static unsigned char init_ID_done;
|
||||||
int i, irq, irqval, retval;
|
int i, irq, irqval, retval;
|
||||||
struct net_local *lp;
|
struct net_local *lp;
|
||||||
|
|
||||||
|
@ -391,10 +391,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (net_debug && version_printed++ == 0)
|
pr_info("%s: 3c507 at %#x,", dev->name, ioaddr);
|
||||||
printk(version);
|
|
||||||
|
|
||||||
printk("%s: 3c507 at %#x,", dev->name, ioaddr);
|
|
||||||
|
|
||||||
/* We should make a few more checks here, like the first three octets of
|
/* We should make a few more checks here, like the first three octets of
|
||||||
the S.A. for the manufacturer's code. */
|
the S.A. for the manufacturer's code. */
|
||||||
|
@ -403,7 +400,8 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
|
||||||
|
|
||||||
irqval = request_irq(irq, &el16_interrupt, 0, DRV_NAME, dev);
|
irqval = request_irq(irq, &el16_interrupt, 0, DRV_NAME, dev);
|
||||||
if (irqval) {
|
if (irqval) {
|
||||||
printk(KERN_ERR "3c507: unable to get IRQ %d (irqval=%d).\n", irq, irqval);
|
pr_cont("\n");
|
||||||
|
pr_err("3c507: unable to get IRQ %d (irqval=%d).\n", irq, irqval);
|
||||||
retval = -EAGAIN;
|
retval = -EAGAIN;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -414,7 +412,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
|
||||||
outb(0x01, ioaddr + MISC_CTRL);
|
outb(0x01, ioaddr + MISC_CTRL);
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
dev->dev_addr[i] = inb(ioaddr + i);
|
dev->dev_addr[i] = inb(ioaddr + i);
|
||||||
printk(" %pM", dev->dev_addr);
|
pr_cont(" %pM", dev->dev_addr);
|
||||||
|
|
||||||
if (mem_start)
|
if (mem_start)
|
||||||
net_debug = mem_start & 7;
|
net_debug = mem_start & 7;
|
||||||
|
@ -443,18 +441,18 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
|
||||||
dev->if_port = (inb(ioaddr + ROM_CONFIG) & 0x80) ? 1 : 0;
|
dev->if_port = (inb(ioaddr + ROM_CONFIG) & 0x80) ? 1 : 0;
|
||||||
dev->irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
|
dev->irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
|
||||||
|
|
||||||
printk(", IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->irq,
|
pr_cont(", IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->irq,
|
||||||
dev->if_port ? "ex" : "in", dev->mem_start, dev->mem_end-1);
|
dev->if_port ? "ex" : "in", dev->mem_start, dev->mem_end-1);
|
||||||
|
|
||||||
if (net_debug)
|
if (net_debug)
|
||||||
printk(version);
|
pr_debug("%s", version);
|
||||||
|
|
||||||
lp = netdev_priv(dev);
|
lp = netdev_priv(dev);
|
||||||
memset(lp, 0, sizeof(*lp));
|
memset(lp, 0, sizeof(*lp));
|
||||||
spin_lock_init(&lp->lock);
|
spin_lock_init(&lp->lock);
|
||||||
lp->base = ioremap(dev->mem_start, RX_BUF_END);
|
lp->base = ioremap(dev->mem_start, RX_BUF_END);
|
||||||
if (!lp->base) {
|
if (!lp->base) {
|
||||||
printk(KERN_ERR "3c507: unable to remap memory\n");
|
pr_err("3c507: unable to remap memory\n");
|
||||||
retval = -EAGAIN;
|
retval = -EAGAIN;
|
||||||
goto out1;
|
goto out1;
|
||||||
}
|
}
|
||||||
|
@ -488,20 +486,20 @@ static void el16_tx_timeout (struct net_device *dev)
|
||||||
void __iomem *shmem = lp->base;
|
void __iomem *shmem = lp->base;
|
||||||
|
|
||||||
if (net_debug > 1)
|
if (net_debug > 1)
|
||||||
printk ("%s: transmit timed out, %s? ", dev->name,
|
pr_debug("%s: transmit timed out, %s? ", dev->name,
|
||||||
readw(shmem + iSCB_STATUS) & 0x8000 ? "IRQ conflict" :
|
readw(shmem + iSCB_STATUS) & 0x8000 ? "IRQ conflict" :
|
||||||
"network cable problem");
|
"network cable problem");
|
||||||
/* Try to restart the adaptor. */
|
/* Try to restart the adaptor. */
|
||||||
if (lp->last_restart == dev->stats.tx_packets) {
|
if (lp->last_restart == dev->stats.tx_packets) {
|
||||||
if (net_debug > 1)
|
if (net_debug > 1)
|
||||||
printk ("Resetting board.\n");
|
pr_cont("Resetting board.\n");
|
||||||
/* Completely reset the adaptor. */
|
/* Completely reset the adaptor. */
|
||||||
init_82586_mem (dev);
|
init_82586_mem (dev);
|
||||||
lp->tx_pkts_in_ring = 0;
|
lp->tx_pkts_in_ring = 0;
|
||||||
} else {
|
} else {
|
||||||
/* Issue the channel attention signal and hope it "gets better". */
|
/* Issue the channel attention signal and hope it "gets better". */
|
||||||
if (net_debug > 1)
|
if (net_debug > 1)
|
||||||
printk ("Kicking board.\n");
|
pr_cont("Kicking board.\n");
|
||||||
writew(0xf000 | CUC_START | RX_START, shmem + iSCB_CMD);
|
writew(0xf000 | CUC_START | RX_START, shmem + iSCB_CMD);
|
||||||
outb (0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */
|
outb (0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */
|
||||||
lp->last_restart = dev->stats.tx_packets;
|
lp->last_restart = dev->stats.tx_packets;
|
||||||
|
@ -553,7 +551,8 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
|
||||||
void __iomem *shmem;
|
void __iomem *shmem;
|
||||||
|
|
||||||
if (dev == NULL) {
|
if (dev == NULL) {
|
||||||
printk ("net_interrupt(): irq %d for unknown device.\n", irq);
|
pr_err("%s: net_interrupt(): irq %d for unknown device.\n",
|
||||||
|
dev->name, irq);
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,7 +565,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
|
||||||
status = readw(shmem+iSCB_STATUS);
|
status = readw(shmem+iSCB_STATUS);
|
||||||
|
|
||||||
if (net_debug > 4) {
|
if (net_debug > 4) {
|
||||||
printk("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
|
pr_debug("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable the 82586's input to the interrupt line. */
|
/* Disable the 82586's input to the interrupt line. */
|
||||||
|
@ -577,7 +576,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
|
||||||
unsigned short tx_status = readw(shmem+lp->tx_reap);
|
unsigned short tx_status = readw(shmem+lp->tx_reap);
|
||||||
if (!(tx_status & 0x8000)) {
|
if (!(tx_status & 0x8000)) {
|
||||||
if (net_debug > 5)
|
if (net_debug > 5)
|
||||||
printk("Tx command incomplete (%#x).\n", lp->tx_reap);
|
pr_debug("Tx command incomplete (%#x).\n", lp->tx_reap);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Tx unsuccessful or some interesting status bit set. */
|
/* Tx unsuccessful or some interesting status bit set. */
|
||||||
|
@ -591,7 +590,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
|
||||||
}
|
}
|
||||||
dev->stats.tx_packets++;
|
dev->stats.tx_packets++;
|
||||||
if (net_debug > 5)
|
if (net_debug > 5)
|
||||||
printk("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
|
pr_debug("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
|
||||||
lp->tx_reap += TX_BUF_SIZE;
|
lp->tx_reap += TX_BUF_SIZE;
|
||||||
if (lp->tx_reap > RX_BUF_START - TX_BUF_SIZE)
|
if (lp->tx_reap > RX_BUF_START - TX_BUF_SIZE)
|
||||||
lp->tx_reap = TX_BUF_START;
|
lp->tx_reap = TX_BUF_START;
|
||||||
|
@ -606,7 +605,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
|
||||||
|
|
||||||
if (status & 0x4000) { /* Packet received. */
|
if (status & 0x4000) { /* Packet received. */
|
||||||
if (net_debug > 5)
|
if (net_debug > 5)
|
||||||
printk("Received packet, rx_head %04x.\n", lp->rx_head);
|
pr_debug("Received packet, rx_head %04x.\n", lp->rx_head);
|
||||||
el16_rx(dev);
|
el16_rx(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,7 +614,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
|
||||||
|
|
||||||
if ((status & 0x0700) != 0x0200 && netif_running(dev)) {
|
if ((status & 0x0700) != 0x0200 && netif_running(dev)) {
|
||||||
if (net_debug)
|
if (net_debug)
|
||||||
printk("%s: Command unit stopped, status %04x, restarting.\n",
|
pr_debug("%s: Command unit stopped, status %04x, restarting.\n",
|
||||||
dev->name, status);
|
dev->name, status);
|
||||||
/* If this ever occurs we should really re-write the idle loop, reset
|
/* If this ever occurs we should really re-write the idle loop, reset
|
||||||
the Tx list, and do a complete restart of the command unit.
|
the Tx list, and do a complete restart of the command unit.
|
||||||
|
@ -627,7 +626,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
|
||||||
/* The Rx unit is not ready, it must be hung. Restart the receiver by
|
/* The Rx unit is not ready, it must be hung. Restart the receiver by
|
||||||
initializing the rx buffers, and issuing an Rx start command. */
|
initializing the rx buffers, and issuing an Rx start command. */
|
||||||
if (net_debug)
|
if (net_debug)
|
||||||
printk("%s: Rx unit stopped, status %04x, restarting.\n",
|
pr_debug("%s: Rx unit stopped, status %04x, restarting.\n",
|
||||||
dev->name, status);
|
dev->name, status);
|
||||||
init_rx_bufs(dev);
|
init_rx_bufs(dev);
|
||||||
writew(RX_BUF_START,shmem+iSCB_RFA);
|
writew(RX_BUF_START,shmem+iSCB_RFA);
|
||||||
|
@ -753,9 +752,8 @@ static void init_82586_mem(struct net_device *dev)
|
||||||
int boguscnt = 50;
|
int boguscnt = 50;
|
||||||
while (readw(shmem+iSCB_STATUS) == 0)
|
while (readw(shmem+iSCB_STATUS) == 0)
|
||||||
if (--boguscnt == 0) {
|
if (--boguscnt == 0) {
|
||||||
printk("%s: i82586 initialization timed out with status %04x, "
|
pr_warning("%s: i82586 initialization timed out with status %04x, cmd %04x.\n",
|
||||||
"cmd %04x.\n", dev->name,
|
dev->name, readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD));
|
||||||
readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Issue channel-attn -- the 82586 won't start. */
|
/* Issue channel-attn -- the 82586 won't start. */
|
||||||
|
@ -765,7 +763,7 @@ static void init_82586_mem(struct net_device *dev)
|
||||||
/* Disable loopback and enable interrupts. */
|
/* Disable loopback and enable interrupts. */
|
||||||
outb(0x84, ioaddr + MISC_CTRL);
|
outb(0x84, ioaddr + MISC_CTRL);
|
||||||
if (net_debug > 4)
|
if (net_debug > 4)
|
||||||
printk("%s: Initialized 82586, status %04x.\n", dev->name,
|
pr_debug("%s: Initialized 82586, status %04x.\n", dev->name,
|
||||||
readw(shmem+iSCB_STATUS));
|
readw(shmem+iSCB_STATUS));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -810,7 +808,7 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length
|
||||||
lp->tx_head = TX_BUF_START;
|
lp->tx_head = TX_BUF_START;
|
||||||
|
|
||||||
if (net_debug > 4) {
|
if (net_debug > 4) {
|
||||||
printk("%s: 3c507 @%x send length = %d, tx_block %3x, next %3x.\n",
|
pr_debug("%s: 3c507 @%x send length = %d, tx_block %3x, next %3x.\n",
|
||||||
dev->name, ioaddr, length, tx_block, lp->tx_head);
|
dev->name, ioaddr, length, tx_block, lp->tx_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -838,7 +836,7 @@ static void el16_rx(struct net_device *dev)
|
||||||
|
|
||||||
if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
|
if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
|
||||||
|| (pkt_len & 0xC000) != 0xC000) {
|
|| (pkt_len & 0xC000) != 0xC000) {
|
||||||
printk(KERN_ERR "%s: Rx frame at %#x corrupted, "
|
pr_err("%s: Rx frame at %#x corrupted, "
|
||||||
"status %04x cmd %04x next %04x "
|
"status %04x cmd %04x next %04x "
|
||||||
"data-buf @%04x %04x.\n",
|
"data-buf @%04x %04x.\n",
|
||||||
dev->name, rx_head, frame_status, rfd_cmd,
|
dev->name, rx_head, frame_status, rfd_cmd,
|
||||||
|
@ -858,8 +856,7 @@ static void el16_rx(struct net_device *dev)
|
||||||
pkt_len &= 0x3fff;
|
pkt_len &= 0x3fff;
|
||||||
skb = dev_alloc_skb(pkt_len+2);
|
skb = dev_alloc_skb(pkt_len+2);
|
||||||
if (skb == NULL) {
|
if (skb == NULL) {
|
||||||
printk(KERN_ERR "%s: Memory squeeze, "
|
pr_err("%s: Memory squeeze, dropping packet.\n",
|
||||||
"dropping packet.\n",
|
|
||||||
dev->name);
|
dev->name);
|
||||||
dev->stats.rx_dropped++;
|
dev->stats.rx_dropped++;
|
||||||
break;
|
break;
|
||||||
|
@ -926,7 +923,7 @@ MODULE_PARM_DESC(irq, "(ignored)");
|
||||||
int __init init_module(void)
|
int __init init_module(void)
|
||||||
{
|
{
|
||||||
if (io == 0)
|
if (io == 0)
|
||||||
printk("3c507: You should not use auto-probing with insmod!\n");
|
pr_notice("3c507: You should not use auto-probing with insmod!\n");
|
||||||
dev_3c507 = el16_probe(-1);
|
dev_3c507 = el16_probe(-1);
|
||||||
return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0;
|
return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,7 +257,7 @@ static int el3_isa_id_sequence(__be16 *phys_addr)
|
||||||
&& !memcmp(phys_addr, el3_devs[i]->dev_addr,
|
&& !memcmp(phys_addr, el3_devs[i]->dev_addr,
|
||||||
ETH_ALEN)) {
|
ETH_ALEN)) {
|
||||||
if (el3_debug > 3)
|
if (el3_debug > 3)
|
||||||
printk(KERN_DEBUG "3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
|
pr_debug("3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
|
||||||
phys_addr[0] & 0xff, phys_addr[0] >> 8,
|
phys_addr[0] & 0xff, phys_addr[0] >> 8,
|
||||||
phys_addr[1] & 0xff, phys_addr[1] >> 8,
|
phys_addr[1] & 0xff, phys_addr[1] >> 8,
|
||||||
phys_addr[2] & 0xff, phys_addr[2] >> 8);
|
phys_addr[2] & 0xff, phys_addr[2] >> 8);
|
||||||
|
@ -578,19 +578,18 @@ static int __devinit el3_common_init(struct net_device *dev)
|
||||||
|
|
||||||
err = register_netdev(dev);
|
err = register_netdev(dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_ERR "Failed to register 3c5x9 at %#3.3lx, IRQ %d.\n",
|
pr_err("Failed to register 3c5x9 at %#3.3lx, IRQ %d.\n",
|
||||||
dev->base_addr, dev->irq);
|
dev->base_addr, dev->irq);
|
||||||
release_region(dev->base_addr, EL3_IO_EXTENT);
|
release_region(dev->base_addr, EL3_IO_EXTENT);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(KERN_INFO "%s: 3c5x9 found at %#3.3lx, %s port, "
|
pr_info("%s: 3c5x9 found at %#3.3lx, %s port, address %pM, IRQ %d.\n",
|
||||||
"address %pM, IRQ %d.\n",
|
|
||||||
dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)],
|
dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)],
|
||||||
dev->dev_addr, dev->irq);
|
dev->dev_addr, dev->irq);
|
||||||
|
|
||||||
if (el3_debug > 0)
|
if (el3_debug > 0)
|
||||||
printk(KERN_INFO "%s", version);
|
pr_info("%s", version);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -629,8 +628,8 @@ static int __init el3_mca_probe(struct device *device)
|
||||||
irq = pos5 & 0x0f;
|
irq = pos5 & 0x0f;
|
||||||
|
|
||||||
|
|
||||||
printk(KERN_INFO "3c529: found %s at slot %d\n",
|
pr_info("3c529: found %s at slot %d\n",
|
||||||
el3_mca_adapter_names[mdev->index], slot + 1);
|
el3_mca_adapter_names[mdev->index], slot + 1);
|
||||||
|
|
||||||
/* claim the slot */
|
/* claim the slot */
|
||||||
strncpy(mdev->name, el3_mca_adapter_names[mdev->index],
|
strncpy(mdev->name, el3_mca_adapter_names[mdev->index],
|
||||||
|
@ -642,7 +641,7 @@ static int __init el3_mca_probe(struct device *device)
|
||||||
irq = mca_device_transform_irq(mdev, irq);
|
irq = mca_device_transform_irq(mdev, irq);
|
||||||
ioaddr = mca_device_transform_ioport(mdev, ioaddr);
|
ioaddr = mca_device_transform_ioport(mdev, ioaddr);
|
||||||
if (el3_debug > 2) {
|
if (el3_debug > 2) {
|
||||||
printk(KERN_DEBUG "3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port);
|
pr_debug("3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port);
|
||||||
}
|
}
|
||||||
EL3WINDOW(0);
|
EL3WINDOW(0);
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
|
@ -657,11 +656,11 @@ static int __init el3_mca_probe(struct device *device)
|
||||||
netdev_boot_setup_check(dev);
|
netdev_boot_setup_check(dev);
|
||||||
|
|
||||||
el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_MCA);
|
el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_MCA);
|
||||||
device->driver_data = dev;
|
dev_set_drvdata(device, dev);
|
||||||
err = el3_common_init(dev);
|
err = el3_common_init(dev);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
device->driver_data = NULL;
|
dev_set_drvdata(device, NULL);
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
@ -725,12 +724,12 @@ static int __init el3_eisa_probe (struct device *device)
|
||||||
|
|
||||||
/* This remove works for all device types.
|
/* This remove works for all device types.
|
||||||
*
|
*
|
||||||
* The net dev must be stored in the driver_data field */
|
* The net dev must be stored in the driver data field */
|
||||||
static int __devexit el3_device_remove (struct device *device)
|
static int __devexit el3_device_remove (struct device *device)
|
||||||
{
|
{
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
||||||
dev = device->driver_data;
|
dev = dev_get_drvdata(device);
|
||||||
|
|
||||||
el3_common_remove (dev);
|
el3_common_remove (dev);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -765,7 +764,7 @@ static ushort id_read_eeprom(int index)
|
||||||
word = (word << 1) + (inb(id_port) & 0x01);
|
word = (word << 1) + (inb(id_port) & 0x01);
|
||||||
|
|
||||||
if (el3_debug > 3)
|
if (el3_debug > 3)
|
||||||
printk(KERN_DEBUG " 3c509 EEPROM word %d %#4.4x.\n", index, word);
|
pr_debug(" 3c509 EEPROM word %d %#4.4x.\n", index, word);
|
||||||
|
|
||||||
return word;
|
return word;
|
||||||
}
|
}
|
||||||
|
@ -787,13 +786,13 @@ el3_open(struct net_device *dev)
|
||||||
|
|
||||||
EL3WINDOW(0);
|
EL3WINDOW(0);
|
||||||
if (el3_debug > 3)
|
if (el3_debug > 3)
|
||||||
printk(KERN_DEBUG "%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name,
|
pr_debug("%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name,
|
||||||
dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
|
dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
|
||||||
|
|
||||||
el3_up(dev);
|
el3_up(dev);
|
||||||
|
|
||||||
if (el3_debug > 3)
|
if (el3_debug > 3)
|
||||||
printk(KERN_DEBUG "%s: Opened 3c509 IRQ %d status %4.4x.\n",
|
pr_debug("%s: Opened 3c509 IRQ %d status %4.4x.\n",
|
||||||
dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
|
dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -805,8 +804,7 @@ el3_tx_timeout (struct net_device *dev)
|
||||||
int ioaddr = dev->base_addr;
|
int ioaddr = dev->base_addr;
|
||||||
|
|
||||||
/* Transmitter timeout, serious problems. */
|
/* Transmitter timeout, serious problems. */
|
||||||
printk(KERN_WARNING "%s: transmit timed out, Tx_status %2.2x status %4.4x "
|
pr_warning("%s: transmit timed out, Tx_status %2.2x status %4.4x Tx FIFO room %d.\n",
|
||||||
"Tx FIFO room %d.\n",
|
|
||||||
dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
|
dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
|
||||||
inw(ioaddr + TX_FREE));
|
inw(ioaddr + TX_FREE));
|
||||||
dev->stats.tx_errors++;
|
dev->stats.tx_errors++;
|
||||||
|
@ -830,7 +828,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
dev->stats.tx_bytes += skb->len;
|
dev->stats.tx_bytes += skb->len;
|
||||||
|
|
||||||
if (el3_debug > 4) {
|
if (el3_debug > 4) {
|
||||||
printk(KERN_DEBUG "%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
|
pr_debug("%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
|
||||||
dev->name, skb->len, inw(ioaddr + EL3_STATUS));
|
dev->name, skb->len, inw(ioaddr + EL3_STATUS));
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -839,7 +837,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
ushort status = inw(ioaddr + EL3_STATUS);
|
ushort status = inw(ioaddr + EL3_STATUS);
|
||||||
if (status & 0x0001 /* IRQ line active, missed one. */
|
if (status & 0x0001 /* IRQ line active, missed one. */
|
||||||
&& inw(ioaddr + EL3_STATUS) & 1) { /* Make sure. */
|
&& inw(ioaddr + EL3_STATUS) & 1) { /* Make sure. */
|
||||||
printk(KERN_DEBUG "%s: Missed interrupt, status then %04x now %04x"
|
pr_debug("%s: Missed interrupt, status then %04x now %04x"
|
||||||
" Tx %2.2x Rx %4.4x.\n", dev->name, status,
|
" Tx %2.2x Rx %4.4x.\n", dev->name, status,
|
||||||
inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
|
inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
|
||||||
inw(ioaddr + RX_STATUS));
|
inw(ioaddr + RX_STATUS));
|
||||||
|
@ -913,7 +911,7 @@ el3_interrupt(int irq, void *dev_id)
|
||||||
|
|
||||||
if (el3_debug > 4) {
|
if (el3_debug > 4) {
|
||||||
status = inw(ioaddr + EL3_STATUS);
|
status = inw(ioaddr + EL3_STATUS);
|
||||||
printk(KERN_DEBUG "%s: interrupt, status %4.4x.\n", dev->name, status);
|
pr_debug("%s: interrupt, status %4.4x.\n", dev->name, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((status = inw(ioaddr + EL3_STATUS)) &
|
while ((status = inw(ioaddr + EL3_STATUS)) &
|
||||||
|
@ -924,7 +922,7 @@ el3_interrupt(int irq, void *dev_id)
|
||||||
|
|
||||||
if (status & TxAvailable) {
|
if (status & TxAvailable) {
|
||||||
if (el3_debug > 5)
|
if (el3_debug > 5)
|
||||||
printk(KERN_DEBUG " TX room bit was handled.\n");
|
pr_debug(" TX room bit was handled.\n");
|
||||||
/* There's room in the FIFO for a full-sized packet. */
|
/* There's room in the FIFO for a full-sized packet. */
|
||||||
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
|
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
|
||||||
netif_wake_queue (dev);
|
netif_wake_queue (dev);
|
||||||
|
@ -962,7 +960,7 @@ el3_interrupt(int irq, void *dev_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (--i < 0) {
|
if (--i < 0) {
|
||||||
printk(KERN_ERR "%s: Infinite loop in interrupt, status %4.4x.\n",
|
pr_err("%s: Infinite loop in interrupt, status %4.4x.\n",
|
||||||
dev->name, status);
|
dev->name, status);
|
||||||
/* Clear all interrupts. */
|
/* Clear all interrupts. */
|
||||||
outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
|
outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
|
||||||
|
@ -973,7 +971,7 @@ el3_interrupt(int irq, void *dev_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (el3_debug > 4) {
|
if (el3_debug > 4) {
|
||||||
printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n", dev->name,
|
pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name,
|
||||||
inw(ioaddr + EL3_STATUS));
|
inw(ioaddr + EL3_STATUS));
|
||||||
}
|
}
|
||||||
spin_unlock(&lp->lock);
|
spin_unlock(&lp->lock);
|
||||||
|
@ -1021,7 +1019,7 @@ static void update_stats(struct net_device *dev)
|
||||||
int ioaddr = dev->base_addr;
|
int ioaddr = dev->base_addr;
|
||||||
|
|
||||||
if (el3_debug > 5)
|
if (el3_debug > 5)
|
||||||
printk(" Updating the statistics.\n");
|
pr_debug(" Updating the statistics.\n");
|
||||||
/* Turn off statistics updates while reading. */
|
/* Turn off statistics updates while reading. */
|
||||||
outw(StatsDisable, ioaddr + EL3_CMD);
|
outw(StatsDisable, ioaddr + EL3_CMD);
|
||||||
/* Switch to the stats window, and read everything. */
|
/* Switch to the stats window, and read everything. */
|
||||||
|
@ -1051,7 +1049,7 @@ el3_rx(struct net_device *dev)
|
||||||
short rx_status;
|
short rx_status;
|
||||||
|
|
||||||
if (el3_debug > 5)
|
if (el3_debug > 5)
|
||||||
printk(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
pr_debug(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
||||||
inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
|
inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
|
||||||
while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) {
|
while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) {
|
||||||
if (rx_status & 0x4000) { /* Error, update stats. */
|
if (rx_status & 0x4000) { /* Error, update stats. */
|
||||||
|
@ -1073,7 +1071,7 @@ el3_rx(struct net_device *dev)
|
||||||
|
|
||||||
skb = dev_alloc_skb(pkt_len+5);
|
skb = dev_alloc_skb(pkt_len+5);
|
||||||
if (el3_debug > 4)
|
if (el3_debug > 4)
|
||||||
printk("Receiving packet size %d status %4.4x.\n",
|
pr_debug("Receiving packet size %d status %4.4x.\n",
|
||||||
pkt_len, rx_status);
|
pkt_len, rx_status);
|
||||||
if (skb != NULL) {
|
if (skb != NULL) {
|
||||||
skb_reserve(skb, 2); /* Align IP on 16 byte */
|
skb_reserve(skb, 2); /* Align IP on 16 byte */
|
||||||
|
@ -1092,12 +1090,12 @@ el3_rx(struct net_device *dev)
|
||||||
outw(RxDiscard, ioaddr + EL3_CMD);
|
outw(RxDiscard, ioaddr + EL3_CMD);
|
||||||
dev->stats.rx_dropped++;
|
dev->stats.rx_dropped++;
|
||||||
if (el3_debug)
|
if (el3_debug)
|
||||||
printk("%s: Couldn't allocate a sk_buff of size %d.\n",
|
pr_debug("%s: Couldn't allocate a sk_buff of size %d.\n",
|
||||||
dev->name, pkt_len);
|
dev->name, pkt_len);
|
||||||
}
|
}
|
||||||
inw(ioaddr + EL3_STATUS); /* Delay. */
|
inw(ioaddr + EL3_STATUS); /* Delay. */
|
||||||
while (inw(ioaddr + EL3_STATUS) & 0x1000)
|
while (inw(ioaddr + EL3_STATUS) & 0x1000)
|
||||||
printk(KERN_DEBUG " Waiting for 3c509 to discard packet, status %x.\n",
|
pr_debug(" Waiting for 3c509 to discard packet, status %x.\n",
|
||||||
inw(ioaddr + EL3_STATUS) );
|
inw(ioaddr + EL3_STATUS) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1118,7 +1116,7 @@ set_multicast_list(struct net_device *dev)
|
||||||
static int old;
|
static int old;
|
||||||
if (old != dev->mc_count) {
|
if (old != dev->mc_count) {
|
||||||
old = dev->mc_count;
|
old = dev->mc_count;
|
||||||
printk("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);
|
pr_debug("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_lock_irqsave(&lp->lock, flags);
|
spin_lock_irqsave(&lp->lock, flags);
|
||||||
|
@ -1141,7 +1139,7 @@ el3_close(struct net_device *dev)
|
||||||
struct el3_private *lp = netdev_priv(dev);
|
struct el3_private *lp = netdev_priv(dev);
|
||||||
|
|
||||||
if (el3_debug > 2)
|
if (el3_debug > 2)
|
||||||
printk("%s: Shutting down ethercard.\n", dev->name);
|
pr_debug("%s: Shutting down ethercard.\n", dev->name);
|
||||||
|
|
||||||
el3_down(dev);
|
el3_down(dev);
|
||||||
|
|
||||||
|
@ -1388,30 +1386,30 @@ el3_up(struct net_device *dev)
|
||||||
EL3WINDOW(4);
|
EL3WINDOW(4);
|
||||||
net_diag = inw(ioaddr + WN4_NETDIAG);
|
net_diag = inw(ioaddr + WN4_NETDIAG);
|
||||||
net_diag = (net_diag | FD_ENABLE); /* temporarily assume full-duplex will be set */
|
net_diag = (net_diag | FD_ENABLE); /* temporarily assume full-duplex will be set */
|
||||||
printk("%s: ", dev->name);
|
pr_info("%s: ", dev->name);
|
||||||
switch (dev->if_port & 0x0c) {
|
switch (dev->if_port & 0x0c) {
|
||||||
case 12:
|
case 12:
|
||||||
/* force full-duplex mode if 3c5x9b */
|
/* force full-duplex mode if 3c5x9b */
|
||||||
if (sw_info & 0x000f) {
|
if (sw_info & 0x000f) {
|
||||||
printk("Forcing 3c5x9b full-duplex mode");
|
pr_cont("Forcing 3c5x9b full-duplex mode");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 8:
|
case 8:
|
||||||
/* set full-duplex mode based on eeprom config setting */
|
/* set full-duplex mode based on eeprom config setting */
|
||||||
if ((sw_info & 0x000f) && (sw_info & 0x8000)) {
|
if ((sw_info & 0x000f) && (sw_info & 0x8000)) {
|
||||||
printk("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)");
|
pr_cont("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
/* xcvr=(0 || 4) OR user has an old 3c5x9 non "B" model */
|
/* xcvr=(0 || 4) OR user has an old 3c5x9 non "B" model */
|
||||||
printk("Setting 3c5x9/3c5x9B half-duplex mode");
|
pr_cont("Setting 3c5x9/3c5x9B half-duplex mode");
|
||||||
net_diag = (net_diag & ~FD_ENABLE); /* disable full duplex */
|
net_diag = (net_diag & ~FD_ENABLE); /* disable full duplex */
|
||||||
}
|
}
|
||||||
|
|
||||||
outw(net_diag, ioaddr + WN4_NETDIAG);
|
outw(net_diag, ioaddr + WN4_NETDIAG);
|
||||||
printk(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info);
|
pr_cont(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info);
|
||||||
if (el3_debug > 3)
|
if (el3_debug > 3)
|
||||||
printk("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag);
|
pr_debug("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag);
|
||||||
/* Enable link beat and jabber check. */
|
/* Enable link beat and jabber check. */
|
||||||
outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
|
outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
|
||||||
}
|
}
|
||||||
|
@ -1455,7 +1453,7 @@ el3_suspend(struct device *pdev, pm_message_t state)
|
||||||
struct el3_private *lp;
|
struct el3_private *lp;
|
||||||
int ioaddr;
|
int ioaddr;
|
||||||
|
|
||||||
dev = pdev->driver_data;
|
dev = dev_get_drvdata(pdev);
|
||||||
lp = netdev_priv(dev);
|
lp = netdev_priv(dev);
|
||||||
ioaddr = dev->base_addr;
|
ioaddr = dev->base_addr;
|
||||||
|
|
||||||
|
@ -1479,7 +1477,7 @@ el3_resume(struct device *pdev)
|
||||||
struct el3_private *lp;
|
struct el3_private *lp;
|
||||||
int ioaddr;
|
int ioaddr;
|
||||||
|
|
||||||
dev = pdev->driver_data;
|
dev = dev_get_drvdata(pdev);
|
||||||
lp = netdev_priv(dev);
|
lp = netdev_priv(dev);
|
||||||
ioaddr = dev->base_addr;
|
ioaddr = dev->base_addr;
|
||||||
|
|
||||||
|
@ -1539,7 +1537,7 @@ static int __init el3_init_module(void)
|
||||||
}
|
}
|
||||||
if (id_port >= 0x200) {
|
if (id_port >= 0x200) {
|
||||||
id_port = 0;
|
id_port = 0;
|
||||||
printk(KERN_ERR "No I/O port available for 3c509 activation.\n");
|
pr_err("No I/O port available for 3c509 activation.\n");
|
||||||
} else {
|
} else {
|
||||||
ret = isa_register_driver(&el3_isa_driver, EL3_MAX_CARDS);
|
ret = isa_register_driver(&el3_isa_driver, EL3_MAX_CARDS);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
|
|
@ -420,7 +420,7 @@ int init_module(void)
|
||||||
if (debug >= 0)
|
if (debug >= 0)
|
||||||
corkscrew_debug = debug;
|
corkscrew_debug = debug;
|
||||||
if (corkscrew_debug)
|
if (corkscrew_debug)
|
||||||
printk(version);
|
pr_debug("%s", version);
|
||||||
while (corkscrew_scan(-1))
|
while (corkscrew_scan(-1))
|
||||||
found++;
|
found++;
|
||||||
return found ? 0 : -ENODEV;
|
return found ? 0 : -ENODEV;
|
||||||
|
@ -437,7 +437,7 @@ struct net_device *tc515_probe(int unit)
|
||||||
|
|
||||||
if (corkscrew_debug > 0 && !printed) {
|
if (corkscrew_debug > 0 && !printed) {
|
||||||
printed = 1;
|
printed = 1;
|
||||||
printk(version);
|
pr_debug("%s", version);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dev;
|
return dev;
|
||||||
|
@ -516,7 +516,7 @@ static struct net_device *corkscrew_scan(int unit)
|
||||||
if (pnp_device_attach(idev) < 0)
|
if (pnp_device_attach(idev) < 0)
|
||||||
continue;
|
continue;
|
||||||
if (pnp_activate_dev(idev) < 0) {
|
if (pnp_activate_dev(idev) < 0) {
|
||||||
printk("pnp activate failed (out of resources?)\n");
|
pr_warning("pnp activate failed (out of resources?)\n");
|
||||||
pnp_device_detach(idev);
|
pnp_device_detach(idev);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -531,9 +531,9 @@ static struct net_device *corkscrew_scan(int unit)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(corkscrew_debug)
|
if(corkscrew_debug)
|
||||||
printk ("ISAPNP reports %s at i/o 0x%x, irq %d\n",
|
pr_debug("ISAPNP reports %s at i/o 0x%x, irq %d\n",
|
||||||
(char*) corkscrew_isapnp_adapters[i].driver_data, ioaddr, irq);
|
(char*) corkscrew_isapnp_adapters[i].driver_data, ioaddr, irq);
|
||||||
printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
|
pr_info("3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
|
||||||
inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
|
inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
|
||||||
/* irq = inw(ioaddr + 0x2002) & 15; */ /* Use the irq from isapnp */
|
/* irq = inw(ioaddr + 0x2002) & 15; */ /* Use the irq from isapnp */
|
||||||
SET_NETDEV_DEV(dev, &idev->dev);
|
SET_NETDEV_DEV(dev, &idev->dev);
|
||||||
|
@ -552,7 +552,7 @@ static struct net_device *corkscrew_scan(int unit)
|
||||||
if (!check_device(ioaddr))
|
if (!check_device(ioaddr))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
|
pr_info("3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
|
||||||
inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
|
inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
|
||||||
err = corkscrew_setup(dev, ioaddr, NULL, cards_found++);
|
err = corkscrew_setup(dev, ioaddr, NULL, cards_found++);
|
||||||
if (!err)
|
if (!err)
|
||||||
|
@ -625,7 +625,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
|
||||||
list_add(&vp->list, &root_corkscrew_dev);
|
list_add(&vp->list, &root_corkscrew_dev);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
printk(KERN_INFO "%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
|
pr_info("%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
|
||||||
|
|
||||||
spin_lock_init(&vp->lock);
|
spin_lock_init(&vp->lock);
|
||||||
|
|
||||||
|
@ -648,19 +648,19 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
|
||||||
}
|
}
|
||||||
checksum = (checksum ^ (checksum >> 8)) & 0xff;
|
checksum = (checksum ^ (checksum >> 8)) & 0xff;
|
||||||
if (checksum != 0x00)
|
if (checksum != 0x00)
|
||||||
printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
|
pr_cont(" ***INVALID CHECKSUM %4.4x*** ", checksum);
|
||||||
printk(" %pM", dev->dev_addr);
|
pr_cont(" %pM", dev->dev_addr);
|
||||||
if (eeprom[16] == 0x11c7) { /* Corkscrew */
|
if (eeprom[16] == 0x11c7) { /* Corkscrew */
|
||||||
if (request_dma(dev->dma, "3c515")) {
|
if (request_dma(dev->dma, "3c515")) {
|
||||||
printk(", DMA %d allocation failed", dev->dma);
|
pr_cont(", DMA %d allocation failed", dev->dma);
|
||||||
dev->dma = 0;
|
dev->dma = 0;
|
||||||
} else
|
} else
|
||||||
printk(", DMA %d", dev->dma);
|
pr_cont(", DMA %d", dev->dma);
|
||||||
}
|
}
|
||||||
printk(", IRQ %d\n", dev->irq);
|
pr_cont(", IRQ %d\n", dev->irq);
|
||||||
/* Tell them about an invalid IRQ. */
|
/* Tell them about an invalid IRQ. */
|
||||||
if (corkscrew_debug && (dev->irq <= 0 || dev->irq > 15))
|
if (corkscrew_debug && (dev->irq <= 0 || dev->irq > 15))
|
||||||
printk(KERN_WARNING " *** Warning: this IRQ is unlikely to work! ***\n");
|
pr_warning(" *** Warning: this IRQ is unlikely to work! ***\n");
|
||||||
|
|
||||||
{
|
{
|
||||||
char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" };
|
char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" };
|
||||||
|
@ -669,9 +669,9 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
|
||||||
vp->available_media = inw(ioaddr + Wn3_Options);
|
vp->available_media = inw(ioaddr + Wn3_Options);
|
||||||
config = inl(ioaddr + Wn3_Config);
|
config = inl(ioaddr + Wn3_Config);
|
||||||
if (corkscrew_debug > 1)
|
if (corkscrew_debug > 1)
|
||||||
printk(KERN_INFO " Internal config register is %4.4x, transceivers %#x.\n",
|
pr_info(" Internal config register is %4.4x, transceivers %#x.\n",
|
||||||
config, inw(ioaddr + Wn3_Options));
|
config, inw(ioaddr + Wn3_Options));
|
||||||
printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
|
pr_info(" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
|
||||||
8 << config & Ram_size,
|
8 << config & Ram_size,
|
||||||
config & Ram_width ? "word" : "byte",
|
config & Ram_width ? "word" : "byte",
|
||||||
ram_split[(config & Ram_split) >> Ram_split_shift],
|
ram_split[(config & Ram_split) >> Ram_split_shift],
|
||||||
|
@ -682,7 +682,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
|
||||||
dev->if_port = vp->default_media;
|
dev->if_port = vp->default_media;
|
||||||
}
|
}
|
||||||
if (vp->media_override != 7) {
|
if (vp->media_override != 7) {
|
||||||
printk(KERN_INFO " Media override to transceiver type %d (%s).\n",
|
pr_info(" Media override to transceiver type %d (%s).\n",
|
||||||
vp->media_override,
|
vp->media_override,
|
||||||
media_tbl[vp->media_override].name);
|
media_tbl[vp->media_override].name);
|
||||||
dev->if_port = vp->media_override;
|
dev->if_port = vp->media_override;
|
||||||
|
@ -718,7 +718,7 @@ static int corkscrew_open(struct net_device *dev)
|
||||||
|
|
||||||
if (vp->media_override != 7) {
|
if (vp->media_override != 7) {
|
||||||
if (corkscrew_debug > 1)
|
if (corkscrew_debug > 1)
|
||||||
printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
|
pr_info("%s: Media override to transceiver %d (%s).\n",
|
||||||
dev->name, vp->media_override,
|
dev->name, vp->media_override,
|
||||||
media_tbl[vp->media_override].name);
|
media_tbl[vp->media_override].name);
|
||||||
dev->if_port = vp->media_override;
|
dev->if_port = vp->media_override;
|
||||||
|
@ -729,7 +729,7 @@ static int corkscrew_open(struct net_device *dev)
|
||||||
dev->if_port = media_tbl[dev->if_port].next;
|
dev->if_port = media_tbl[dev->if_port].next;
|
||||||
|
|
||||||
if (corkscrew_debug > 1)
|
if (corkscrew_debug > 1)
|
||||||
printk("%s: Initial media type %s.\n",
|
pr_debug("%s: Initial media type %s.\n",
|
||||||
dev->name, media_tbl[dev->if_port].name);
|
dev->name, media_tbl[dev->if_port].name);
|
||||||
|
|
||||||
init_timer(&vp->timer);
|
init_timer(&vp->timer);
|
||||||
|
@ -744,7 +744,7 @@ static int corkscrew_open(struct net_device *dev)
|
||||||
outl(config, ioaddr + Wn3_Config);
|
outl(config, ioaddr + Wn3_Config);
|
||||||
|
|
||||||
if (corkscrew_debug > 1) {
|
if (corkscrew_debug > 1) {
|
||||||
printk("%s: corkscrew_open() InternalConfig %8.8x.\n",
|
pr_debug("%s: corkscrew_open() InternalConfig %8.8x.\n",
|
||||||
dev->name, config);
|
dev->name, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -777,7 +777,7 @@ static int corkscrew_open(struct net_device *dev)
|
||||||
|
|
||||||
if (corkscrew_debug > 1) {
|
if (corkscrew_debug > 1) {
|
||||||
EL3WINDOW(4);
|
EL3WINDOW(4);
|
||||||
printk("%s: corkscrew_open() irq %d media status %4.4x.\n",
|
pr_debug("%s: corkscrew_open() irq %d media status %4.4x.\n",
|
||||||
dev->name, dev->irq, inw(ioaddr + Wn4_Media));
|
dev->name, dev->irq, inw(ioaddr + Wn4_Media));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -814,8 +814,7 @@ static int corkscrew_open(struct net_device *dev)
|
||||||
if (vp->full_bus_master_rx) { /* Boomerang bus master. */
|
if (vp->full_bus_master_rx) { /* Boomerang bus master. */
|
||||||
vp->cur_rx = vp->dirty_rx = 0;
|
vp->cur_rx = vp->dirty_rx = 0;
|
||||||
if (corkscrew_debug > 2)
|
if (corkscrew_debug > 2)
|
||||||
printk("%s: Filling in the Rx ring.\n",
|
pr_debug("%s: Filling in the Rx ring.\n", dev->name);
|
||||||
dev->name);
|
|
||||||
for (i = 0; i < RX_RING_SIZE; i++) {
|
for (i = 0; i < RX_RING_SIZE; i++) {
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
if (i < (RX_RING_SIZE - 1))
|
if (i < (RX_RING_SIZE - 1))
|
||||||
|
@ -877,7 +876,7 @@ static void corkscrew_timer(unsigned long data)
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
|
|
||||||
if (corkscrew_debug > 1)
|
if (corkscrew_debug > 1)
|
||||||
printk("%s: Media selection timer tick happened, %s.\n",
|
pr_debug("%s: Media selection timer tick happened, %s.\n",
|
||||||
dev->name, media_tbl[dev->if_port].name);
|
dev->name, media_tbl[dev->if_port].name);
|
||||||
|
|
||||||
spin_lock_irqsave(&vp->lock, flags);
|
spin_lock_irqsave(&vp->lock, flags);
|
||||||
|
@ -894,12 +893,12 @@ static void corkscrew_timer(unsigned long data)
|
||||||
if (media_status & Media_LnkBeat) {
|
if (media_status & Media_LnkBeat) {
|
||||||
ok = 1;
|
ok = 1;
|
||||||
if (corkscrew_debug > 1)
|
if (corkscrew_debug > 1)
|
||||||
printk("%s: Media %s has link beat, %x.\n",
|
pr_debug("%s: Media %s has link beat, %x.\n",
|
||||||
dev->name,
|
dev->name,
|
||||||
media_tbl[dev->if_port].name,
|
media_tbl[dev->if_port].name,
|
||||||
media_status);
|
media_status);
|
||||||
} else if (corkscrew_debug > 1)
|
} else if (corkscrew_debug > 1)
|
||||||
printk("%s: Media %s is has no link beat, %x.\n",
|
pr_debug("%s: Media %s is has no link beat, %x.\n",
|
||||||
dev->name,
|
dev->name,
|
||||||
media_tbl[dev->if_port].name,
|
media_tbl[dev->if_port].name,
|
||||||
media_status);
|
media_status);
|
||||||
|
@ -907,7 +906,7 @@ static void corkscrew_timer(unsigned long data)
|
||||||
break;
|
break;
|
||||||
default: /* Other media types handled by Tx timeouts. */
|
default: /* Other media types handled by Tx timeouts. */
|
||||||
if (corkscrew_debug > 1)
|
if (corkscrew_debug > 1)
|
||||||
printk("%s: Media %s is has no indication, %x.\n",
|
pr_debug("%s: Media %s is has no indication, %x.\n",
|
||||||
dev->name,
|
dev->name,
|
||||||
media_tbl[dev->if_port].name,
|
media_tbl[dev->if_port].name,
|
||||||
media_status);
|
media_status);
|
||||||
|
@ -925,12 +924,12 @@ static void corkscrew_timer(unsigned long data)
|
||||||
if (dev->if_port == 8) { /* Go back to default. */
|
if (dev->if_port == 8) { /* Go back to default. */
|
||||||
dev->if_port = vp->default_media;
|
dev->if_port = vp->default_media;
|
||||||
if (corkscrew_debug > 1)
|
if (corkscrew_debug > 1)
|
||||||
printk("%s: Media selection failing, using default %s port.\n",
|
pr_debug("%s: Media selection failing, using default %s port.\n",
|
||||||
dev->name,
|
dev->name,
|
||||||
media_tbl[dev->if_port].name);
|
media_tbl[dev->if_port].name);
|
||||||
} else {
|
} else {
|
||||||
if (corkscrew_debug > 1)
|
if (corkscrew_debug > 1)
|
||||||
printk("%s: Media selection failed, now trying %s port.\n",
|
pr_debug("%s: Media selection failed, now trying %s port.\n",
|
||||||
dev->name,
|
dev->name,
|
||||||
media_tbl[dev->if_port].name);
|
media_tbl[dev->if_port].name);
|
||||||
vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
|
vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
|
||||||
|
@ -953,7 +952,7 @@ static void corkscrew_timer(unsigned long data)
|
||||||
|
|
||||||
spin_unlock_irqrestore(&vp->lock, flags);
|
spin_unlock_irqrestore(&vp->lock, flags);
|
||||||
if (corkscrew_debug > 1)
|
if (corkscrew_debug > 1)
|
||||||
printk("%s: Media selection timer finished, %s.\n",
|
pr_debug("%s: Media selection timer finished, %s.\n",
|
||||||
dev->name, media_tbl[dev->if_port].name);
|
dev->name, media_tbl[dev->if_port].name);
|
||||||
|
|
||||||
#endif /* AUTOMEDIA */
|
#endif /* AUTOMEDIA */
|
||||||
|
@ -966,23 +965,21 @@ static void corkscrew_timeout(struct net_device *dev)
|
||||||
struct corkscrew_private *vp = netdev_priv(dev);
|
struct corkscrew_private *vp = netdev_priv(dev);
|
||||||
int ioaddr = dev->base_addr;
|
int ioaddr = dev->base_addr;
|
||||||
|
|
||||||
printk(KERN_WARNING
|
pr_warning("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
|
||||||
"%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
|
|
||||||
dev->name, inb(ioaddr + TxStatus),
|
dev->name, inb(ioaddr + TxStatus),
|
||||||
inw(ioaddr + EL3_STATUS));
|
inw(ioaddr + EL3_STATUS));
|
||||||
/* Slight code bloat to be user friendly. */
|
/* Slight code bloat to be user friendly. */
|
||||||
if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
|
if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
|
||||||
printk(KERN_WARNING
|
pr_warning("%s: Transmitter encountered 16 collisions --"
|
||||||
"%s: Transmitter encountered 16 collisions -- network"
|
|
||||||
" network cable problem?\n", dev->name);
|
" network cable problem?\n", dev->name);
|
||||||
#ifndef final_version
|
#ifndef final_version
|
||||||
printk(" Flags; bus-master %d, full %d; dirty %d current %d.\n",
|
pr_debug(" Flags; bus-master %d, full %d; dirty %d current %d.\n",
|
||||||
vp->full_bus_master_tx, vp->tx_full, vp->dirty_tx,
|
vp->full_bus_master_tx, vp->tx_full, vp->dirty_tx,
|
||||||
vp->cur_tx);
|
vp->cur_tx);
|
||||||
printk(" Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr),
|
pr_debug(" Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr),
|
||||||
&vp->tx_ring[0]);
|
&vp->tx_ring[0]);
|
||||||
for (i = 0; i < TX_RING_SIZE; i++) {
|
for (i = 0; i < TX_RING_SIZE; i++) {
|
||||||
printk(" %d: %p length %8.8x status %8.8x\n", i,
|
pr_debug(" %d: %p length %8.8x status %8.8x\n", i,
|
||||||
&vp->tx_ring[i],
|
&vp->tx_ring[i],
|
||||||
vp->tx_ring[i].length, vp->tx_ring[i].status);
|
vp->tx_ring[i].length, vp->tx_ring[i].status);
|
||||||
}
|
}
|
||||||
|
@ -1017,13 +1014,13 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (vp->tx_full) /* No room to transmit with */
|
if (vp->tx_full) /* No room to transmit with */
|
||||||
return 1;
|
return NETDEV_TX_BUSY;
|
||||||
if (vp->cur_tx != 0)
|
if (vp->cur_tx != 0)
|
||||||
prev_entry = &vp->tx_ring[(vp->cur_tx - 1) % TX_RING_SIZE];
|
prev_entry = &vp->tx_ring[(vp->cur_tx - 1) % TX_RING_SIZE];
|
||||||
else
|
else
|
||||||
prev_entry = NULL;
|
prev_entry = NULL;
|
||||||
if (corkscrew_debug > 3)
|
if (corkscrew_debug > 3)
|
||||||
printk("%s: Trying to send a packet, Tx index %d.\n",
|
pr_debug("%s: Trying to send a packet, Tx index %d.\n",
|
||||||
dev->name, vp->cur_tx);
|
dev->name, vp->cur_tx);
|
||||||
/* vp->tx_full = 1; */
|
/* vp->tx_full = 1; */
|
||||||
vp->tx_skbuff[entry] = skb;
|
vp->tx_skbuff[entry] = skb;
|
||||||
|
@ -1102,7 +1099,7 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
|
||||||
while (--i > 0 && (tx_status = inb(ioaddr + TxStatus)) > 0) {
|
while (--i > 0 && (tx_status = inb(ioaddr + TxStatus)) > 0) {
|
||||||
if (tx_status & 0x3C) { /* A Tx-disabling error occurred. */
|
if (tx_status & 0x3C) { /* A Tx-disabling error occurred. */
|
||||||
if (corkscrew_debug > 2)
|
if (corkscrew_debug > 2)
|
||||||
printk("%s: Tx error, status %2.2x.\n",
|
pr_debug("%s: Tx error, status %2.2x.\n",
|
||||||
dev->name, tx_status);
|
dev->name, tx_status);
|
||||||
if (tx_status & 0x04)
|
if (tx_status & 0x04)
|
||||||
dev->stats.tx_fifo_errors++;
|
dev->stats.tx_fifo_errors++;
|
||||||
|
@ -1143,7 +1140,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
|
||||||
status = inw(ioaddr + EL3_STATUS);
|
status = inw(ioaddr + EL3_STATUS);
|
||||||
|
|
||||||
if (corkscrew_debug > 4)
|
if (corkscrew_debug > 4)
|
||||||
printk("%s: interrupt, status %4.4x, timer %d.\n",
|
pr_debug("%s: interrupt, status %4.4x, timer %d.\n",
|
||||||
dev->name, status, latency);
|
dev->name, status, latency);
|
||||||
if ((status & 0xE000) != 0xE000) {
|
if ((status & 0xE000) != 0xE000) {
|
||||||
static int donedidthis;
|
static int donedidthis;
|
||||||
|
@ -1151,7 +1148,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
|
||||||
Ignore a single early interrupt, but don't hang the machine for
|
Ignore a single early interrupt, but don't hang the machine for
|
||||||
other interrupt problems. */
|
other interrupt problems. */
|
||||||
if (donedidthis++ > 100) {
|
if (donedidthis++ > 100) {
|
||||||
printk(KERN_ERR "%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
|
pr_err("%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
|
||||||
dev->name, status, netif_running(dev));
|
dev->name, status, netif_running(dev));
|
||||||
free_irq(dev->irq, dev);
|
free_irq(dev->irq, dev);
|
||||||
dev->irq = -1;
|
dev->irq = -1;
|
||||||
|
@ -1160,14 +1157,14 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (corkscrew_debug > 5)
|
if (corkscrew_debug > 5)
|
||||||
printk("%s: In interrupt loop, status %4.4x.\n",
|
pr_debug("%s: In interrupt loop, status %4.4x.\n",
|
||||||
dev->name, status);
|
dev->name, status);
|
||||||
if (status & RxComplete)
|
if (status & RxComplete)
|
||||||
corkscrew_rx(dev);
|
corkscrew_rx(dev);
|
||||||
|
|
||||||
if (status & TxAvailable) {
|
if (status & TxAvailable) {
|
||||||
if (corkscrew_debug > 5)
|
if (corkscrew_debug > 5)
|
||||||
printk(" TX room bit was handled.\n");
|
pr_debug(" TX room bit was handled.\n");
|
||||||
/* There's room in the FIFO for a full-sized packet. */
|
/* There's room in the FIFO for a full-sized packet. */
|
||||||
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
|
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
|
@ -1212,19 +1209,20 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
|
||||||
if (status & StatsFull) { /* Empty statistics. */
|
if (status & StatsFull) { /* Empty statistics. */
|
||||||
static int DoneDidThat;
|
static int DoneDidThat;
|
||||||
if (corkscrew_debug > 4)
|
if (corkscrew_debug > 4)
|
||||||
printk("%s: Updating stats.\n", dev->name);
|
pr_debug("%s: Updating stats.\n", dev->name);
|
||||||
update_stats(ioaddr, dev);
|
update_stats(ioaddr, dev);
|
||||||
/* DEBUG HACK: Disable statistics as an interrupt source. */
|
/* DEBUG HACK: Disable statistics as an interrupt source. */
|
||||||
/* This occurs when we have the wrong media type! */
|
/* This occurs when we have the wrong media type! */
|
||||||
if (DoneDidThat == 0 && inw(ioaddr + EL3_STATUS) & StatsFull) {
|
if (DoneDidThat == 0 && inw(ioaddr + EL3_STATUS) & StatsFull) {
|
||||||
int win, reg;
|
int win, reg;
|
||||||
printk("%s: Updating stats failed, disabling stats as an"
|
pr_notice("%s: Updating stats failed, disabling stats as an interrupt source.\n",
|
||||||
" interrupt source.\n", dev->name);
|
dev->name);
|
||||||
for (win = 0; win < 8; win++) {
|
for (win = 0; win < 8; win++) {
|
||||||
EL3WINDOW(win);
|
EL3WINDOW(win);
|
||||||
printk("\n Vortex window %d:", win);
|
pr_notice("Vortex window %d:", win);
|
||||||
for (reg = 0; reg < 16; reg++)
|
for (reg = 0; reg < 16; reg++)
|
||||||
printk(" %2.2x", inb(ioaddr + reg));
|
pr_cont(" %2.2x", inb(ioaddr + reg));
|
||||||
|
pr_cont("\n");
|
||||||
}
|
}
|
||||||
EL3WINDOW(7);
|
EL3WINDOW(7);
|
||||||
outw(SetIntrEnb | TxAvailable |
|
outw(SetIntrEnb | TxAvailable |
|
||||||
|
@ -1246,9 +1244,8 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (--i < 0) {
|
if (--i < 0) {
|
||||||
printk(KERN_ERR "%s: Too much work in interrupt, status %4.4x. "
|
pr_err("%s: Too much work in interrupt, status %4.4x. Disabling functions (%4.4x).\n",
|
||||||
"Disabling functions (%4.4x).\n", dev->name,
|
dev->name, status, SetStatusEnb | ((~status) & 0x7FE));
|
||||||
status, SetStatusEnb | ((~status) & 0x7FE));
|
|
||||||
/* Disable all pending interrupts. */
|
/* Disable all pending interrupts. */
|
||||||
outw(SetStatusEnb | ((~status) & 0x7FE), ioaddr + EL3_CMD);
|
outw(SetStatusEnb | ((~status) & 0x7FE), ioaddr + EL3_CMD);
|
||||||
outw(AckIntr | 0x7FF, ioaddr + EL3_CMD);
|
outw(AckIntr | 0x7FF, ioaddr + EL3_CMD);
|
||||||
|
@ -1262,7 +1259,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
|
||||||
spin_unlock(&lp->lock);
|
spin_unlock(&lp->lock);
|
||||||
|
|
||||||
if (corkscrew_debug > 4)
|
if (corkscrew_debug > 4)
|
||||||
printk("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
|
pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1273,13 +1270,13 @@ static int corkscrew_rx(struct net_device *dev)
|
||||||
short rx_status;
|
short rx_status;
|
||||||
|
|
||||||
if (corkscrew_debug > 5)
|
if (corkscrew_debug > 5)
|
||||||
printk(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
pr_debug(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
||||||
inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
|
inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
|
||||||
while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
|
while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
|
||||||
if (rx_status & 0x4000) { /* Error, update stats. */
|
if (rx_status & 0x4000) { /* Error, update stats. */
|
||||||
unsigned char rx_error = inb(ioaddr + RxErrors);
|
unsigned char rx_error = inb(ioaddr + RxErrors);
|
||||||
if (corkscrew_debug > 2)
|
if (corkscrew_debug > 2)
|
||||||
printk(" Rx error: status %2.2x.\n",
|
pr_debug(" Rx error: status %2.2x.\n",
|
||||||
rx_error);
|
rx_error);
|
||||||
dev->stats.rx_errors++;
|
dev->stats.rx_errors++;
|
||||||
if (rx_error & 0x01)
|
if (rx_error & 0x01)
|
||||||
|
@ -1299,7 +1296,7 @@ static int corkscrew_rx(struct net_device *dev)
|
||||||
|
|
||||||
skb = dev_alloc_skb(pkt_len + 5 + 2);
|
skb = dev_alloc_skb(pkt_len + 5 + 2);
|
||||||
if (corkscrew_debug > 4)
|
if (corkscrew_debug > 4)
|
||||||
printk("Receiving packet size %d status %4.4x.\n",
|
pr_debug("Receiving packet size %d status %4.4x.\n",
|
||||||
pkt_len, rx_status);
|
pkt_len, rx_status);
|
||||||
if (skb != NULL) {
|
if (skb != NULL) {
|
||||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
||||||
|
@ -1318,7 +1315,7 @@ static int corkscrew_rx(struct net_device *dev)
|
||||||
break;
|
break;
|
||||||
continue;
|
continue;
|
||||||
} else if (corkscrew_debug)
|
} else if (corkscrew_debug)
|
||||||
printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
|
pr_debug("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
|
||||||
}
|
}
|
||||||
outw(RxDiscard, ioaddr + EL3_CMD);
|
outw(RxDiscard, ioaddr + EL3_CMD);
|
||||||
dev->stats.rx_dropped++;
|
dev->stats.rx_dropped++;
|
||||||
|
@ -1338,13 +1335,13 @@ static int boomerang_rx(struct net_device *dev)
|
||||||
int rx_status;
|
int rx_status;
|
||||||
|
|
||||||
if (corkscrew_debug > 5)
|
if (corkscrew_debug > 5)
|
||||||
printk(" In boomerang_rx(), status %4.4x, rx_status %4.4x.\n",
|
pr_debug(" In boomerang_rx(), status %4.4x, rx_status %4.4x.\n",
|
||||||
inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
|
inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
|
||||||
while ((rx_status = vp->rx_ring[entry].status) & RxDComplete) {
|
while ((rx_status = vp->rx_ring[entry].status) & RxDComplete) {
|
||||||
if (rx_status & RxDError) { /* Error, update stats. */
|
if (rx_status & RxDError) { /* Error, update stats. */
|
||||||
unsigned char rx_error = rx_status >> 16;
|
unsigned char rx_error = rx_status >> 16;
|
||||||
if (corkscrew_debug > 2)
|
if (corkscrew_debug > 2)
|
||||||
printk(" Rx error: status %2.2x.\n",
|
pr_debug(" Rx error: status %2.2x.\n",
|
||||||
rx_error);
|
rx_error);
|
||||||
dev->stats.rx_errors++;
|
dev->stats.rx_errors++;
|
||||||
if (rx_error & 0x01)
|
if (rx_error & 0x01)
|
||||||
|
@ -1364,7 +1361,7 @@ static int boomerang_rx(struct net_device *dev)
|
||||||
|
|
||||||
dev->stats.rx_bytes += pkt_len;
|
dev->stats.rx_bytes += pkt_len;
|
||||||
if (corkscrew_debug > 4)
|
if (corkscrew_debug > 4)
|
||||||
printk("Receiving packet size %d status %4.4x.\n",
|
pr_debug("Receiving packet size %d status %4.4x.\n",
|
||||||
pkt_len, rx_status);
|
pkt_len, rx_status);
|
||||||
|
|
||||||
/* Check if the packet is long enough to just accept without
|
/* Check if the packet is long enough to just accept without
|
||||||
|
@ -1385,7 +1382,7 @@ static int boomerang_rx(struct net_device *dev)
|
||||||
temp = skb_put(skb, pkt_len);
|
temp = skb_put(skb, pkt_len);
|
||||||
/* Remove this checking code for final release. */
|
/* Remove this checking code for final release. */
|
||||||
if (isa_bus_to_virt(vp->rx_ring[entry].addr) != temp)
|
if (isa_bus_to_virt(vp->rx_ring[entry].addr) != temp)
|
||||||
printk("%s: Warning -- the skbuff addresses do not match"
|
pr_warning("%s: Warning -- the skbuff addresses do not match"
|
||||||
" in boomerang_rx: %p vs. %p / %p.\n",
|
" in boomerang_rx: %p vs. %p / %p.\n",
|
||||||
dev->name,
|
dev->name,
|
||||||
isa_bus_to_virt(vp->
|
isa_bus_to_virt(vp->
|
||||||
|
@ -1427,12 +1424,11 @@ static int corkscrew_close(struct net_device *dev)
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
|
|
||||||
if (corkscrew_debug > 1) {
|
if (corkscrew_debug > 1) {
|
||||||
printk("%s: corkscrew_close() status %4.4x, Tx status %2.2x.\n",
|
pr_debug("%s: corkscrew_close() status %4.4x, Tx status %2.2x.\n",
|
||||||
dev->name, inw(ioaddr + EL3_STATUS),
|
dev->name, inw(ioaddr + EL3_STATUS),
|
||||||
inb(ioaddr + TxStatus));
|
inb(ioaddr + TxStatus));
|
||||||
printk("%s: corkscrew close stats: rx_nocopy %d rx_copy %d"
|
pr_debug("%s: corkscrew close stats: rx_nocopy %d rx_copy %d tx_queued %d.\n",
|
||||||
" tx_queued %d.\n", dev->name, rx_nocopy, rx_copy,
|
dev->name, rx_nocopy, rx_copy, queued_packet);
|
||||||
queued_packet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
del_timer(&vp->timer);
|
del_timer(&vp->timer);
|
||||||
|
@ -1534,7 +1530,7 @@ static void set_rx_mode(struct net_device *dev)
|
||||||
|
|
||||||
if (dev->flags & IFF_PROMISC) {
|
if (dev->flags & IFF_PROMISC) {
|
||||||
if (corkscrew_debug > 3)
|
if (corkscrew_debug > 3)
|
||||||
printk("%s: Setting promiscuous mode.\n",
|
pr_debug("%s: Setting promiscuous mode.\n",
|
||||||
dev->name);
|
dev->name);
|
||||||
new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm;
|
new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm;
|
||||||
} else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
|
} else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
|
||||||
|
|
|
@ -176,7 +176,7 @@ sizeof(nop_cmd) = 8;
|
||||||
if(!p->scb->cmd) break; \
|
if(!p->scb->cmd) break; \
|
||||||
DELAY_16(); \
|
DELAY_16(); \
|
||||||
if(i == 1023) { \
|
if(i == 1023) { \
|
||||||
printk(KERN_WARNING "%s:%d: scb_cmd timed out .. resetting i82586\n",\
|
pr_warning("%s:%d: scb_cmd timed out .. resetting i82586\n",\
|
||||||
dev->name,__LINE__); \
|
dev->name,__LINE__); \
|
||||||
elmc_id_reset586(); } } }
|
elmc_id_reset586(); } } }
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ static int elmc_open(struct net_device *dev)
|
||||||
ret = request_irq(dev->irq, &elmc_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM,
|
ret = request_irq(dev->irq, &elmc_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM,
|
||||||
dev->name, dev);
|
dev->name, dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk(KERN_ERR "%s: couldn't get irq %d\n", dev->name, dev->irq);
|
pr_err("%s: couldn't get irq %d\n", dev->name, dev->irq);
|
||||||
elmc_id_reset586();
|
elmc_id_reset586();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -371,9 +371,9 @@ static void alloc586(struct net_device *dev)
|
||||||
|
|
||||||
DELAY(2);
|
DELAY(2);
|
||||||
|
|
||||||
if (p->iscp->busy) {
|
if (p->iscp->busy)
|
||||||
printk(KERN_ERR "%s: Init-Problems (alloc).\n", dev->name);
|
pr_err("%s: Init-Problems (alloc).\n", dev->name);
|
||||||
}
|
|
||||||
memset((char *) p->scb, 0, sizeof(struct scb_struct));
|
memset((char *) p->scb, 0, sizeof(struct scb_struct));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,7 +470,7 @@ static int __init do_elmc_probe(struct net_device *dev)
|
||||||
mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev);
|
mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev);
|
||||||
|
|
||||||
/* if we get this far, adapter has been found - carry on */
|
/* if we get this far, adapter has been found - carry on */
|
||||||
printk(KERN_INFO "%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
|
pr_info("%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
|
||||||
|
|
||||||
/* Now we extract configuration info from the card.
|
/* Now we extract configuration info from the card.
|
||||||
The 3c523 provides information in two of the POS registers, but
|
The 3c523 provides information in two of the POS registers, but
|
||||||
|
@ -507,7 +507,7 @@ static int __init do_elmc_probe(struct net_device *dev)
|
||||||
memset(pr, 0, sizeof(struct priv));
|
memset(pr, 0, sizeof(struct priv));
|
||||||
pr->slot = slot;
|
pr->slot = slot;
|
||||||
|
|
||||||
printk(KERN_INFO "%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
|
pr_info("%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
|
||||||
dev->base_addr);
|
dev->base_addr);
|
||||||
|
|
||||||
/* Determine if we're using the on-board transceiver (i.e. coax) or
|
/* Determine if we're using the on-board transceiver (i.e. coax) or
|
||||||
|
@ -529,7 +529,7 @@ static int __init do_elmc_probe(struct net_device *dev)
|
||||||
|
|
||||||
size = 0x4000; /* check for 16K mem */
|
size = 0x4000; /* check for 16K mem */
|
||||||
if (!check586(dev, dev->mem_start, size)) {
|
if (!check586(dev, dev->mem_start, size)) {
|
||||||
printk(KERN_ERR "%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
|
pr_err("%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
|
||||||
dev->mem_start);
|
dev->mem_start);
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
@ -546,7 +546,7 @@ static int __init do_elmc_probe(struct net_device *dev)
|
||||||
pr->num_recv_buffs = NUM_RECV_BUFFS_16;
|
pr->num_recv_buffs = NUM_RECV_BUFFS_16;
|
||||||
|
|
||||||
/* dump all the assorted information */
|
/* dump all the assorted information */
|
||||||
printk(KERN_INFO "%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->name,
|
pr_info("%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->name,
|
||||||
dev->irq, dev->if_port ? "ex" : "in",
|
dev->irq, dev->if_port ? "ex" : "in",
|
||||||
dev->mem_start, dev->mem_end - 1);
|
dev->mem_start, dev->mem_end - 1);
|
||||||
|
|
||||||
|
@ -555,7 +555,7 @@ static int __init do_elmc_probe(struct net_device *dev)
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
dev->dev_addr[i] = inb(dev->base_addr + i);
|
dev->dev_addr[i] = inb(dev->base_addr + i);
|
||||||
|
|
||||||
printk(KERN_INFO "%s: hardware address %pM\n",
|
pr_info("%s: hardware address %pM\n",
|
||||||
dev->name, dev->dev_addr);
|
dev->name, dev->dev_addr);
|
||||||
|
|
||||||
dev->netdev_ops = &netdev_ops;
|
dev->netdev_ops = &netdev_ops;
|
||||||
|
@ -660,7 +660,7 @@ static int init586(struct net_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cfg_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_COMPL | STAT_OK)) {
|
if ((cfg_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_COMPL | STAT_OK)) {
|
||||||
printk(KERN_WARNING "%s (elmc): configure command failed: %x\n", dev->name, cfg_cmd->cmd_status);
|
pr_warning("%s (elmc): configure command failed: %x\n", dev->name, cfg_cmd->cmd_status);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -686,7 +686,8 @@ static int init586(struct net_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ias_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_OK | STAT_COMPL)) {
|
if ((ias_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_OK | STAT_COMPL)) {
|
||||||
printk(KERN_WARNING "%s (elmc): individual address setup command failed: %04x\n", dev->name, ias_cmd->cmd_status);
|
pr_warning("%s (elmc): individual address setup command failed: %04x\n",
|
||||||
|
dev->name, ias_cmd->cmd_status);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -707,7 +708,7 @@ static int init586(struct net_device *dev)
|
||||||
s = jiffies;
|
s = jiffies;
|
||||||
while (!(tdr_cmd->cmd_status & STAT_COMPL)) {
|
while (!(tdr_cmd->cmd_status & STAT_COMPL)) {
|
||||||
if (time_after(jiffies, s + 30*HZ/100)) {
|
if (time_after(jiffies, s + 30*HZ/100)) {
|
||||||
printk(KERN_WARNING "%s: %d Problems while running the TDR.\n", dev->name, __LINE__);
|
pr_warning("%s: %d Problems while running the TDR.\n", dev->name, __LINE__);
|
||||||
result = 1;
|
result = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -723,14 +724,14 @@ static int init586(struct net_device *dev)
|
||||||
if (result & TDR_LNK_OK) {
|
if (result & TDR_LNK_OK) {
|
||||||
/* empty */
|
/* empty */
|
||||||
} else if (result & TDR_XCVR_PRB) {
|
} else if (result & TDR_XCVR_PRB) {
|
||||||
printk(KERN_WARNING "%s: TDR: Transceiver problem!\n", dev->name);
|
pr_warning("%s: TDR: Transceiver problem!\n", dev->name);
|
||||||
} else if (result & TDR_ET_OPN) {
|
} else if (result & TDR_ET_OPN) {
|
||||||
printk(KERN_WARNING "%s: TDR: No correct termination %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
|
pr_warning("%s: TDR: No correct termination %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
|
||||||
} else if (result & TDR_ET_SRT) {
|
} else if (result & TDR_ET_SRT) {
|
||||||
if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
|
if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
|
||||||
printk(KERN_WARNING "%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
|
pr_warning("%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "%s: TDR: Unknown status %04x\n", dev->name, result);
|
pr_warning("%s: TDR: Unknown status %04x\n", dev->name, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -774,11 +775,11 @@ static int init586(struct net_device *dev)
|
||||||
/* I don't understand this: do we really need memory after the init? */
|
/* I don't understand this: do we really need memory after the init? */
|
||||||
int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
|
int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
printk(KERN_ERR "%s: Ooooops, no memory for MC-Setup!\n", dev->name);
|
pr_err("%s: Ooooops, no memory for MC-Setup!\n", dev->name);
|
||||||
} else {
|
} else {
|
||||||
if (len < num_addrs) {
|
if (len < num_addrs) {
|
||||||
num_addrs = len;
|
num_addrs = len;
|
||||||
printk(KERN_WARNING "%s: Sorry, can only apply %d MC-Address(es).\n",
|
pr_warning("%s: Sorry, can only apply %d MC-Address(es).\n",
|
||||||
dev->name, num_addrs);
|
dev->name, num_addrs);
|
||||||
}
|
}
|
||||||
mc_cmd = (struct mcsetup_cmd_struct *) ptr;
|
mc_cmd = (struct mcsetup_cmd_struct *) ptr;
|
||||||
|
@ -799,7 +800,7 @@ static int init586(struct net_device *dev)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!(mc_cmd->cmd_status & STAT_COMPL)) {
|
if (!(mc_cmd->cmd_status & STAT_COMPL)) {
|
||||||
printk(KERN_WARNING "%s: Can't apply multicast-address-list.\n", dev->name);
|
pr_warning("%s: Can't apply multicast-address-list.\n", dev->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -812,7 +813,7 @@ static int init586(struct net_device *dev)
|
||||||
p->xmit_buffs[i] = (struct tbd_struct *) ptr; /* TBD */
|
p->xmit_buffs[i] = (struct tbd_struct *) ptr; /* TBD */
|
||||||
ptr = (char *) ptr + sizeof(struct tbd_struct);
|
ptr = (char *) ptr + sizeof(struct tbd_struct);
|
||||||
if ((void *) ptr > (void *) p->iscp) {
|
if ((void *) ptr > (void *) p->iscp) {
|
||||||
printk(KERN_ERR "%s: not enough shared-mem for your configuration!\n", dev->name);
|
pr_err("%s: not enough shared-mem for your configuration!\n", dev->name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
memset((char *) (p->xmit_cmds[i]), 0, sizeof(struct transmit_cmd_struct));
|
memset((char *) (p->xmit_cmds[i]), 0, sizeof(struct transmit_cmd_struct));
|
||||||
|
@ -936,7 +937,8 @@ elmc_interrupt(int irq, void *dev_id)
|
||||||
if (stat & STAT_CNA) {
|
if (stat & STAT_CNA) {
|
||||||
/* CU went 'not ready' */
|
/* CU went 'not ready' */
|
||||||
if (netif_running(dev)) {
|
if (netif_running(dev)) {
|
||||||
printk(KERN_WARNING "%s: oops! CU has left active state. stat: %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);
|
pr_warning("%s: oops! CU has left active state. stat: %04x/%04x.\n",
|
||||||
|
dev->name, (int) stat, (int) p->scb->status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -951,7 +953,8 @@ elmc_interrupt(int irq, void *dev_id)
|
||||||
p->scb->cmd = RUC_RESUME;
|
p->scb->cmd = RUC_RESUME;
|
||||||
elmc_attn586();
|
elmc_attn586();
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);
|
pr_warning("%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n",
|
||||||
|
dev->name, (int) stat, (int) p->scb->status);
|
||||||
elmc_rnr_int(dev);
|
elmc_rnr_int(dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -995,11 +998,11 @@ static void elmc_rcv_int(struct net_device *dev)
|
||||||
dev->stats.rx_dropped++;
|
dev->stats.rx_dropped++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "%s: received oversized frame.\n", dev->name);
|
pr_warning("%s: received oversized frame.\n", dev->name);
|
||||||
dev->stats.rx_dropped++;
|
dev->stats.rx_dropped++;
|
||||||
}
|
}
|
||||||
} else { /* frame !(ok), only with 'save-bad-frames' */
|
} else { /* frame !(ok), only with 'save-bad-frames' */
|
||||||
printk(KERN_WARNING "%s: oops! rfd-error-status: %04x\n", dev->name, status);
|
pr_warning("%s: oops! rfd-error-status: %04x\n", dev->name, status);
|
||||||
dev->stats.rx_errors++;
|
dev->stats.rx_errors++;
|
||||||
}
|
}
|
||||||
p->rfd_top->status = 0;
|
p->rfd_top->status = 0;
|
||||||
|
@ -1028,7 +1031,7 @@ static void elmc_rnr_int(struct net_device *dev)
|
||||||
alloc_rfa(dev, (char *) p->rfd_first);
|
alloc_rfa(dev, (char *) p->rfd_first);
|
||||||
startrecv586(dev); /* restart RU */
|
startrecv586(dev); /* restart RU */
|
||||||
|
|
||||||
printk(KERN_WARNING "%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->status);
|
pr_warning("%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->status);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1043,7 +1046,7 @@ static void elmc_xmt_int(struct net_device *dev)
|
||||||
|
|
||||||
status = p->xmit_cmds[p->xmit_last]->cmd_status;
|
status = p->xmit_cmds[p->xmit_last]->cmd_status;
|
||||||
if (!(status & STAT_COMPL)) {
|
if (!(status & STAT_COMPL)) {
|
||||||
printk(KERN_WARNING "%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
|
pr_warning("%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
|
||||||
}
|
}
|
||||||
if (status & STAT_OK) {
|
if (status & STAT_OK) {
|
||||||
dev->stats.tx_packets++;
|
dev->stats.tx_packets++;
|
||||||
|
@ -1051,18 +1054,18 @@ static void elmc_xmt_int(struct net_device *dev)
|
||||||
} else {
|
} else {
|
||||||
dev->stats.tx_errors++;
|
dev->stats.tx_errors++;
|
||||||
if (status & TCMD_LATECOLL) {
|
if (status & TCMD_LATECOLL) {
|
||||||
printk(KERN_WARNING "%s: late collision detected.\n", dev->name);
|
pr_warning("%s: late collision detected.\n", dev->name);
|
||||||
dev->stats.collisions++;
|
dev->stats.collisions++;
|
||||||
} else if (status & TCMD_NOCARRIER) {
|
} else if (status & TCMD_NOCARRIER) {
|
||||||
dev->stats.tx_carrier_errors++;
|
dev->stats.tx_carrier_errors++;
|
||||||
printk(KERN_WARNING "%s: no carrier detected.\n", dev->name);
|
pr_warning("%s: no carrier detected.\n", dev->name);
|
||||||
} else if (status & TCMD_LOSTCTS) {
|
} else if (status & TCMD_LOSTCTS) {
|
||||||
printk(KERN_WARNING "%s: loss of CTS detected.\n", dev->name);
|
pr_warning("%s: loss of CTS detected.\n", dev->name);
|
||||||
} else if (status & TCMD_UNDERRUN) {
|
} else if (status & TCMD_UNDERRUN) {
|
||||||
dev->stats.tx_fifo_errors++;
|
dev->stats.tx_fifo_errors++;
|
||||||
printk(KERN_WARNING "%s: DMA underrun detected.\n", dev->name);
|
pr_warning("%s: DMA underrun detected.\n", dev->name);
|
||||||
} else if (status & TCMD_MAXCOLL) {
|
} else if (status & TCMD_MAXCOLL) {
|
||||||
printk(KERN_WARNING "%s: Max. collisions exceeded.\n", dev->name);
|
pr_warning("%s: Max. collisions exceeded.\n", dev->name);
|
||||||
dev->stats.collisions += 16;
|
dev->stats.collisions += 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1099,10 +1102,11 @@ static void elmc_timeout(struct net_device *dev)
|
||||||
struct priv *p = netdev_priv(dev);
|
struct priv *p = netdev_priv(dev);
|
||||||
/* COMMAND-UNIT active? */
|
/* COMMAND-UNIT active? */
|
||||||
if (p->scb->status & CU_ACTIVE) {
|
if (p->scb->status & CU_ACTIVE) {
|
||||||
#ifdef DEBUG
|
pr_debug("%s: strange ... timeout with CU active?!?\n", dev->name);
|
||||||
printk("%s: strange ... timeout with CU active?!?\n", dev->name);
|
pr_debug("%s: X0: %04x N0: %04x N1: %04x %d\n", dev->name,
|
||||||
printk("%s: X0: %04x N0: %04x N1: %04x %d\n", dev->name, (int) p->xmit_cmds[0]->cmd_status, (int) p->nop_cmds[0]->cmd_status, (int) p->nop_cmds[1]->cmd_status, (int) p->nop_point);
|
(int)p->xmit_cmds[0]->cmd_status,
|
||||||
#endif
|
(int)p->nop_cmds[0]->cmd_status,
|
||||||
|
(int)p->nop_cmds[1]->cmd_status, (int)p->nop_point);
|
||||||
p->scb->cmd = CUC_ABORT;
|
p->scb->cmd = CUC_ABORT;
|
||||||
elmc_attn586();
|
elmc_attn586();
|
||||||
WAIT_4_SCB_CMD();
|
WAIT_4_SCB_CMD();
|
||||||
|
@ -1112,10 +1116,10 @@ static void elmc_timeout(struct net_device *dev)
|
||||||
WAIT_4_SCB_CMD();
|
WAIT_4_SCB_CMD();
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG
|
pr_debug("%s: xmitter timed out, try to restart! stat: %04x\n",
|
||||||
printk("%s: xmitter timed out, try to restart! stat: %04x\n", dev->name, p->scb->status);
|
dev->name, p->scb->status);
|
||||||
printk("%s: command-stats: %04x %04x\n", dev->name, p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status);
|
pr_debug("%s: command-stats: %04x %04x\n", dev->name,
|
||||||
#endif
|
p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status);
|
||||||
elmc_close(dev);
|
elmc_close(dev);
|
||||||
elmc_open(dev);
|
elmc_open(dev);
|
||||||
}
|
}
|
||||||
|
@ -1162,7 +1166,7 @@ static int elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == 15) {
|
if (i == 15) {
|
||||||
printk(KERN_WARNING "%s: Can't start transmit-command.\n", dev->name);
|
pr_warning("%s: Can't start transmit-command.\n", dev->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -1287,11 +1291,12 @@ int __init init_module(void)
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
if (io[this_dev]==0)
|
if (io[this_dev]==0)
|
||||||
break;
|
break;
|
||||||
printk(KERN_WARNING "3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
|
pr_warning("3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(found==0) {
|
if(found==0) {
|
||||||
if(io[0]==0) printk(KERN_NOTICE "3c523.c: No 3c523 cards found\n");
|
if (io[0]==0)
|
||||||
|
pr_notice("3c523.c: No 3c523 cards found\n");
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
} else return 0;
|
} else return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,8 +125,6 @@ static const char* cardname = DRV_NAME;
|
||||||
#define NET_DEBUG 2
|
#define NET_DEBUG 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#undef DEBUG_IRQ
|
|
||||||
|
|
||||||
static unsigned int mc32_debug = NET_DEBUG;
|
static unsigned int mc32_debug = NET_DEBUG;
|
||||||
|
|
||||||
/* The number of low I/O ports used by the ethercard. */
|
/* The number of low I/O ports used by the ethercard. */
|
||||||
|
@ -351,15 +349,15 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
||||||
/* Time to play MCA games */
|
/* Time to play MCA games */
|
||||||
|
|
||||||
if (mc32_debug && version_printed++ == 0)
|
if (mc32_debug && version_printed++ == 0)
|
||||||
printk(KERN_DEBUG "%s", version);
|
pr_debug("%s", version);
|
||||||
|
|
||||||
printk(KERN_INFO "%s: %s found in slot %d:", dev->name, cardname, slot);
|
pr_info("%s: %s found in slot %d: ", dev->name, cardname, slot);
|
||||||
|
|
||||||
POS = mca_read_stored_pos(slot, 2);
|
POS = mca_read_stored_pos(slot, 2);
|
||||||
|
|
||||||
if(!(POS&1))
|
if(!(POS&1))
|
||||||
{
|
{
|
||||||
printk(" disabled.\n");
|
pr_cont("disabled.\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,7 +368,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
||||||
POS = mca_read_stored_pos(slot, 4);
|
POS = mca_read_stored_pos(slot, 4);
|
||||||
if(!(POS&1))
|
if(!(POS&1))
|
||||||
{
|
{
|
||||||
printk("memory window disabled.\n");
|
pr_cont("memory window disabled.\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,7 +377,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
||||||
i=(POS>>4)&3;
|
i=(POS>>4)&3;
|
||||||
if(i==3)
|
if(i==3)
|
||||||
{
|
{
|
||||||
printk("invalid memory window.\n");
|
pr_cont("invalid memory window.\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,11 +390,11 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
||||||
|
|
||||||
if(!request_region(dev->base_addr, MC32_IO_EXTENT, cardname))
|
if(!request_region(dev->base_addr, MC32_IO_EXTENT, cardname))
|
||||||
{
|
{
|
||||||
printk("io 0x%3lX, which is busy.\n", dev->base_addr);
|
pr_cont("io 0x%3lX, which is busy.\n", dev->base_addr);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
printk("io 0x%3lX irq %d mem 0x%lX (%dK)\n",
|
pr_cont("io 0x%3lX irq %d mem 0x%lX (%dK)\n",
|
||||||
dev->base_addr, dev->irq, dev->mem_start, i/1024);
|
dev->base_addr, dev->irq, dev->mem_start, i/1024);
|
||||||
|
|
||||||
|
|
||||||
|
@ -416,7 +414,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
||||||
dev->dev_addr[i] = mca_read_pos(slot,3);
|
dev->dev_addr[i] = mca_read_pos(slot,3);
|
||||||
}
|
}
|
||||||
|
|
||||||
printk("%s: Address %pM", dev->name, dev->dev_addr);
|
pr_info("%s: Address %pM ", dev->name, dev->dev_addr);
|
||||||
|
|
||||||
mca_write_pos(slot, 6, 0);
|
mca_write_pos(slot, 6, 0);
|
||||||
mca_write_pos(slot, 7, 0);
|
mca_write_pos(slot, 7, 0);
|
||||||
|
@ -424,9 +422,9 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
||||||
POS = mca_read_stored_pos(slot, 4);
|
POS = mca_read_stored_pos(slot, 4);
|
||||||
|
|
||||||
if(POS&2)
|
if(POS&2)
|
||||||
printk(" : BNC port selected.\n");
|
pr_cont(": BNC port selected.\n");
|
||||||
else
|
else
|
||||||
printk(" : AUI port selected.\n");
|
pr_cont(": AUI port selected.\n");
|
||||||
|
|
||||||
POS=inb(dev->base_addr+HOST_CTRL);
|
POS=inb(dev->base_addr+HOST_CTRL);
|
||||||
POS|=HOST_CTRL_ATTN|HOST_CTRL_RESET;
|
POS|=HOST_CTRL_ATTN|HOST_CTRL_RESET;
|
||||||
|
@ -447,7 +445,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
||||||
err = request_irq(dev->irq, &mc32_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, DRV_NAME, dev);
|
err = request_irq(dev->irq, &mc32_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, DRV_NAME, dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
release_region(dev->base_addr, MC32_IO_EXTENT);
|
release_region(dev->base_addr, MC32_IO_EXTENT);
|
||||||
printk(KERN_ERR "%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
|
pr_err("%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
|
||||||
goto err_exit_ports;
|
goto err_exit_ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,7 +461,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
||||||
i++;
|
i++;
|
||||||
if(i == 1000)
|
if(i == 1000)
|
||||||
{
|
{
|
||||||
printk(KERN_ERR "%s: failed to boot adapter.\n", dev->name);
|
pr_err("%s: failed to boot adapter.\n", dev->name);
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto err_exit_irq;
|
goto err_exit_irq;
|
||||||
}
|
}
|
||||||
|
@ -475,10 +473,10 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
||||||
if(base>0)
|
if(base>0)
|
||||||
{
|
{
|
||||||
if(base < 0x0C)
|
if(base < 0x0C)
|
||||||
printk(KERN_ERR "%s: %s%s.\n", dev->name, failures[base-1],
|
pr_err("%s: %s%s.\n", dev->name, failures[base-1],
|
||||||
base<0x0A?" test failure":"");
|
base<0x0A?" test failure":"");
|
||||||
else
|
else
|
||||||
printk(KERN_ERR "%s: unknown failure %d.\n", dev->name, base);
|
pr_err("%s: unknown failure %d.\n", dev->name, base);
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto err_exit_irq;
|
goto err_exit_irq;
|
||||||
}
|
}
|
||||||
|
@ -494,7 +492,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
||||||
udelay(50);
|
udelay(50);
|
||||||
if(n>100)
|
if(n>100)
|
||||||
{
|
{
|
||||||
printk(KERN_ERR "%s: mailbox read fail (%d).\n", dev->name, i);
|
pr_err("%s: mailbox read fail (%d).\n", dev->name, i);
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto err_exit_irq;
|
goto err_exit_irq;
|
||||||
}
|
}
|
||||||
|
@ -527,7 +525,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
||||||
init_completion(&lp->execution_cmd);
|
init_completion(&lp->execution_cmd);
|
||||||
init_completion(&lp->xceiver_cmd);
|
init_completion(&lp->xceiver_cmd);
|
||||||
|
|
||||||
printk("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
|
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->name, lp->exec_box->data[12], lp->rx_len, lp->tx_len, lp->base);
|
||||||
|
|
||||||
dev->netdev_ops = &netdev_ops;
|
dev->netdev_ops = &netdev_ops;
|
||||||
|
@ -939,7 +937,7 @@ static int mc32_open(struct net_device *dev)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(mc32_command(dev, 8, descnumbuffs, 4)) {
|
if(mc32_command(dev, 8, descnumbuffs, 4)) {
|
||||||
printk("%s: %s rejected our buffer configuration!\n",
|
pr_info("%s: %s rejected our buffer configuration!\n",
|
||||||
dev->name, cardname);
|
dev->name, cardname);
|
||||||
mc32_close(dev);
|
mc32_close(dev);
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
|
@ -995,7 +993,7 @@ static int mc32_open(struct net_device *dev)
|
||||||
|
|
||||||
static void mc32_timeout(struct net_device *dev)
|
static void mc32_timeout(struct net_device *dev)
|
||||||
{
|
{
|
||||||
printk(KERN_WARNING "%s: transmit timed out?\n", dev->name);
|
pr_warning("%s: transmit timed out?\n", dev->name);
|
||||||
/* Try to restart the adaptor. */
|
/* Try to restart the adaptor. */
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
}
|
}
|
||||||
|
@ -1032,7 +1030,7 @@ static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev)
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
|
|
||||||
if(atomic_read(&lp->tx_count)==0) {
|
if(atomic_read(&lp->tx_count)==0) {
|
||||||
return 1;
|
return NETDEV_TX_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skb_padto(skb, ETH_ZLEN)) {
|
if (skb_padto(skb, ETH_ZLEN)) {
|
||||||
|
@ -1335,11 +1333,9 @@ static irqreturn_t mc32_interrupt(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
status=inb(ioaddr+HOST_CMD);
|
status=inb(ioaddr+HOST_CMD);
|
||||||
|
|
||||||
#ifdef DEBUG_IRQ
|
pr_debug("Status TX%d RX%d EX%d OV%d BC%d\n",
|
||||||
printk("Status TX%d RX%d EX%d OV%d BC%d\n",
|
|
||||||
(status&7), (status>>3)&7, (status>>6)&1,
|
(status&7), (status>>3)&7, (status>>6)&1,
|
||||||
(status>>7)&1, boguscount);
|
(status>>7)&1, boguscount);
|
||||||
#endif
|
|
||||||
|
|
||||||
switch(status&7)
|
switch(status&7)
|
||||||
{
|
{
|
||||||
|
@ -1354,7 +1350,7 @@ static irqreturn_t mc32_interrupt(int irq, void *dev_id)
|
||||||
complete(&lp->xceiver_cmd);
|
complete(&lp->xceiver_cmd);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk("%s: strange tx ack %d\n", dev->name, status&7);
|
pr_notice("%s: strange tx ack %d\n", dev->name, status&7);
|
||||||
}
|
}
|
||||||
status>>=3;
|
status>>=3;
|
||||||
switch(status&7)
|
switch(status&7)
|
||||||
|
@ -1376,7 +1372,7 @@ static irqreturn_t mc32_interrupt(int irq, void *dev_id)
|
||||||
mc32_start_transceiver(dev);
|
mc32_start_transceiver(dev);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk("%s: strange rx ack %d\n",
|
pr_notice("%s: strange rx ack %d\n",
|
||||||
dev->name, status&7);
|
dev->name, status&7);
|
||||||
}
|
}
|
||||||
status>>=3;
|
status>>=3;
|
||||||
|
|
|
@ -828,14 +828,14 @@ static int vortex_resume(struct pci_dev *pdev)
|
||||||
pci_restore_state(pdev);
|
pci_restore_state(pdev);
|
||||||
err = pci_enable_device(pdev);
|
err = pci_enable_device(pdev);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_WARNING "%s: Could not enable device \n",
|
pr_warning("%s: Could not enable device\n",
|
||||||
dev->name);
|
dev->name);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
pci_set_master(pdev);
|
pci_set_master(pdev);
|
||||||
if (request_irq(dev->irq, vp->full_bus_master_rx ?
|
if (request_irq(dev->irq, vp->full_bus_master_rx ?
|
||||||
&boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev)) {
|
&boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev)) {
|
||||||
printk(KERN_WARNING "%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
|
pr_warning("%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
|
||||||
pci_disable_device(pdev);
|
pci_disable_device(pdev);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
@ -894,7 +894,7 @@ static int __devexit vortex_eisa_remove(struct device *device)
|
||||||
dev = eisa_get_drvdata(edev);
|
dev = eisa_get_drvdata(edev);
|
||||||
|
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
printk("vortex_eisa_remove called for Compaq device!\n");
|
pr_err("vortex_eisa_remove called for Compaq device!\n");
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1051,7 +1051,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
struct eisa_device *edev = NULL;
|
struct eisa_device *edev = NULL;
|
||||||
|
|
||||||
if (!printed_version) {
|
if (!printed_version) {
|
||||||
printk (version);
|
pr_info("%s", version);
|
||||||
printed_version = 1;
|
printed_version = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1068,7 +1068,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
dev = alloc_etherdev(sizeof(*vp));
|
dev = alloc_etherdev(sizeof(*vp));
|
||||||
retval = -ENOMEM;
|
retval = -ENOMEM;
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
printk (KERN_ERR PFX "unable to allocate etherdev, aborting\n");
|
pr_err(PFX "unable to allocate etherdev, aborting\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
SET_NETDEV_DEV(dev, gendev);
|
SET_NETDEV_DEV(dev, gendev);
|
||||||
|
@ -1100,9 +1100,9 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
|
|
||||||
print_info = (vortex_debug > 1);
|
print_info = (vortex_debug > 1);
|
||||||
if (print_info)
|
if (print_info)
|
||||||
printk (KERN_INFO "See Documentation/networking/vortex.txt\n");
|
pr_info("See Documentation/networking/vortex.txt\n");
|
||||||
|
|
||||||
printk(KERN_INFO "%s: 3Com %s %s at %p.\n",
|
pr_info("%s: 3Com %s %s at %p.\n",
|
||||||
print_name,
|
print_name,
|
||||||
pdev ? "PCI" : "EISA",
|
pdev ? "PCI" : "EISA",
|
||||||
vci->name,
|
vci->name,
|
||||||
|
@ -1144,10 +1144,9 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
chip only. */
|
chip only. */
|
||||||
pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
|
pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
|
||||||
if (pci_latency < new_latency) {
|
if (pci_latency < new_latency) {
|
||||||
printk(KERN_INFO "%s: Overriding PCI latency"
|
pr_info("%s: Overriding PCI latency timer (CFLT) setting of %d, new value is %d.\n",
|
||||||
" timer (CFLT) setting of %d, new value is %d.\n",
|
|
||||||
print_name, pci_latency, new_latency);
|
print_name, pci_latency, new_latency);
|
||||||
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
|
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1236,17 +1235,17 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
checksum = (checksum ^ (checksum >> 8)) & 0xff;
|
checksum = (checksum ^ (checksum >> 8)) & 0xff;
|
||||||
}
|
}
|
||||||
if ((checksum != 0x00) && !(vci->drv_flags & IS_TORNADO))
|
if ((checksum != 0x00) && !(vci->drv_flags & IS_TORNADO))
|
||||||
printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
|
pr_cont(" ***INVALID CHECKSUM %4.4x*** ", checksum);
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
((__be16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
|
((__be16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
|
||||||
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
|
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
|
||||||
if (print_info)
|
if (print_info)
|
||||||
printk(" %pM", dev->dev_addr);
|
pr_cont(" %pM", dev->dev_addr);
|
||||||
/* Unfortunately an all zero eeprom passes the checksum and this
|
/* Unfortunately an all zero eeprom passes the checksum and this
|
||||||
gets found in the wild in failure cases. Crypto is hard 8) */
|
gets found in the wild in failure cases. Crypto is hard 8) */
|
||||||
if (!is_valid_ether_addr(dev->dev_addr)) {
|
if (!is_valid_ether_addr(dev->dev_addr)) {
|
||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
printk(KERN_ERR "*** EEPROM MAC address is invalid.\n");
|
pr_err("*** EEPROM MAC address is invalid.\n");
|
||||||
goto free_ring; /* With every pack */
|
goto free_ring; /* With every pack */
|
||||||
}
|
}
|
||||||
EL3WINDOW(2);
|
EL3WINDOW(2);
|
||||||
|
@ -1254,17 +1253,17 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
iowrite8(dev->dev_addr[i], ioaddr + i);
|
iowrite8(dev->dev_addr[i], ioaddr + i);
|
||||||
|
|
||||||
if (print_info)
|
if (print_info)
|
||||||
printk(", IRQ %d\n", dev->irq);
|
pr_cont(", IRQ %d\n", dev->irq);
|
||||||
/* Tell them about an invalid IRQ. */
|
/* Tell them about an invalid IRQ. */
|
||||||
if (dev->irq <= 0 || dev->irq >= nr_irqs)
|
if (dev->irq <= 0 || dev->irq >= nr_irqs)
|
||||||
printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n",
|
pr_warning(" *** Warning: IRQ %d is unlikely to work! ***\n",
|
||||||
dev->irq);
|
dev->irq);
|
||||||
|
|
||||||
EL3WINDOW(4);
|
EL3WINDOW(4);
|
||||||
step = (ioread8(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
|
step = (ioread8(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
|
||||||
if (print_info) {
|
if (print_info) {
|
||||||
printk(KERN_INFO " product code %02x%02x rev %02x.%d date %02d-"
|
pr_info(" product code %02x%02x rev %02x.%d date %02d-%02d-%02d\n",
|
||||||
"%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
|
eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
|
||||||
step, (eeprom[4]>>5) & 15, eeprom[4] & 31, eeprom[4]>>9);
|
step, (eeprom[4]>>5) & 15, eeprom[4] & 31, eeprom[4]>>9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1279,8 +1278,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print_info) {
|
if (print_info) {
|
||||||
printk(KERN_INFO "%s: CardBus functions mapped "
|
pr_info("%s: CardBus functions mapped %16.16llx->%p\n",
|
||||||
"%16.16llx->%p\n",
|
|
||||||
print_name,
|
print_name,
|
||||||
(unsigned long long)pci_resource_start(pdev, 2),
|
(unsigned long long)pci_resource_start(pdev, 2),
|
||||||
vp->cb_fn_base);
|
vp->cb_fn_base);
|
||||||
|
@ -1307,7 +1305,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
if (vp->info1 & 0x8000) {
|
if (vp->info1 & 0x8000) {
|
||||||
vp->full_duplex = 1;
|
vp->full_duplex = 1;
|
||||||
if (print_info)
|
if (print_info)
|
||||||
printk(KERN_INFO "Full duplex capable\n");
|
pr_info("Full duplex capable\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1319,9 +1317,9 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
vp->available_media = 0x40;
|
vp->available_media = 0x40;
|
||||||
config = ioread32(ioaddr + Wn3_Config);
|
config = ioread32(ioaddr + Wn3_Config);
|
||||||
if (print_info) {
|
if (print_info) {
|
||||||
printk(KERN_DEBUG " Internal config register is %4.4x, "
|
pr_debug(" Internal config register is %4.4x, transceivers %#x.\n",
|
||||||
"transceivers %#x.\n", config, ioread16(ioaddr + Wn3_Options));
|
config, ioread16(ioaddr + Wn3_Options));
|
||||||
printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
|
pr_info(" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
|
||||||
8 << RAM_SIZE(config),
|
8 << RAM_SIZE(config),
|
||||||
RAM_WIDTH(config) ? "word" : "byte",
|
RAM_WIDTH(config) ? "word" : "byte",
|
||||||
ram_split[RAM_SPLIT(config)],
|
ram_split[RAM_SPLIT(config)],
|
||||||
|
@ -1336,7 +1334,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vp->media_override != 7) {
|
if (vp->media_override != 7) {
|
||||||
printk(KERN_INFO "%s: Media override to transceiver type %d (%s).\n",
|
pr_info("%s: Media override to transceiver type %d (%s).\n",
|
||||||
print_name, vp->media_override,
|
print_name, vp->media_override,
|
||||||
media_tbl[vp->media_override].name);
|
media_tbl[vp->media_override].name);
|
||||||
dev->if_port = vp->media_override;
|
dev->if_port = vp->media_override;
|
||||||
|
@ -1369,8 +1367,8 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
if (mii_status && mii_status != 0xffff) {
|
if (mii_status && mii_status != 0xffff) {
|
||||||
vp->phys[phy_idx++] = phyx;
|
vp->phys[phy_idx++] = phyx;
|
||||||
if (print_info) {
|
if (print_info) {
|
||||||
printk(KERN_INFO " MII transceiver found at address %d,"
|
pr_info(" MII transceiver found at address %d, status %4x.\n",
|
||||||
" status %4x.\n", phyx, mii_status);
|
phyx, mii_status);
|
||||||
}
|
}
|
||||||
if ((mii_status & 0x0040) == 0)
|
if ((mii_status & 0x0040) == 0)
|
||||||
mii_preamble_required++;
|
mii_preamble_required++;
|
||||||
|
@ -1378,7 +1376,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
}
|
}
|
||||||
mii_preamble_required--;
|
mii_preamble_required--;
|
||||||
if (phy_idx == 0) {
|
if (phy_idx == 0) {
|
||||||
printk(KERN_WARNING" ***WARNING*** No MII transceivers found!\n");
|
pr_warning(" ***WARNING*** No MII transceivers found!\n");
|
||||||
vp->phys[0] = 24;
|
vp->phys[0] = 24;
|
||||||
} else {
|
} else {
|
||||||
vp->advertising = mdio_read(dev, vp->phys[0], MII_ADVERTISE);
|
vp->advertising = mdio_read(dev, vp->phys[0], MII_ADVERTISE);
|
||||||
|
@ -1394,7 +1392,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
if (vp->capabilities & CapBusMaster) {
|
if (vp->capabilities & CapBusMaster) {
|
||||||
vp->full_bus_master_tx = 1;
|
vp->full_bus_master_tx = 1;
|
||||||
if (print_info) {
|
if (print_info) {
|
||||||
printk(KERN_INFO " Enabling bus-master transmits and %s receives.\n",
|
pr_info(" Enabling bus-master transmits and %s receives.\n",
|
||||||
(vp->info2 & 1) ? "early" : "whole-frame" );
|
(vp->info2 & 1) ? "early" : "whole-frame" );
|
||||||
}
|
}
|
||||||
vp->full_bus_master_rx = (vp->info2 & 1) ? 1 : 2;
|
vp->full_bus_master_rx = (vp->info2 & 1) ? 1 : 2;
|
||||||
|
@ -1414,7 +1412,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
dev->netdev_ops = &vortex_netdev_ops;
|
dev->netdev_ops = &vortex_netdev_ops;
|
||||||
|
|
||||||
if (print_info) {
|
if (print_info) {
|
||||||
printk(KERN_INFO "%s: scatter/gather %sabled. h/w checksums %sabled\n",
|
pr_info("%s: scatter/gather %sabled. h/w checksums %sabled\n",
|
||||||
print_name,
|
print_name,
|
||||||
(dev->features & NETIF_F_SG) ? "en":"dis",
|
(dev->features & NETIF_F_SG) ? "en":"dis",
|
||||||
(dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
|
(dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
|
||||||
|
@ -1442,7 +1440,7 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
if (vp->must_free_region)
|
if (vp->must_free_region)
|
||||||
release_region(dev->base_addr, vci->io_size);
|
release_region(dev->base_addr, vci->io_size);
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
printk(KERN_ERR PFX "vortex_probe1 fails. Returns %d\n", retval);
|
pr_err(PFX "vortex_probe1 fails. Returns %d\n", retval);
|
||||||
out:
|
out:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -1464,13 +1462,13 @@ issue_and_wait(struct net_device *dev, int cmd)
|
||||||
for (i = 0; i < 100000; i++) {
|
for (i = 0; i < 100000; i++) {
|
||||||
if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) {
|
if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) {
|
||||||
if (vortex_debug > 1)
|
if (vortex_debug > 1)
|
||||||
printk(KERN_INFO "%s: command 0x%04x took %d usecs\n",
|
pr_info("%s: command 0x%04x took %d usecs\n",
|
||||||
dev->name, cmd, i * 10);
|
dev->name, cmd, i * 10);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
udelay(10);
|
udelay(10);
|
||||||
}
|
}
|
||||||
printk(KERN_ERR "%s: command 0x%04x did not complete! Status=0x%x\n",
|
pr_err("%s: command 0x%04x did not complete! Status=0x%x\n",
|
||||||
dev->name, cmd, ioread16(ioaddr + EL3_STATUS));
|
dev->name, cmd, ioread16(ioaddr + EL3_STATUS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1480,7 +1478,7 @@ vortex_set_duplex(struct net_device *dev)
|
||||||
struct vortex_private *vp = netdev_priv(dev);
|
struct vortex_private *vp = netdev_priv(dev);
|
||||||
void __iomem *ioaddr = vp->ioaddr;
|
void __iomem *ioaddr = vp->ioaddr;
|
||||||
|
|
||||||
printk(KERN_INFO "%s: setting %s-duplex.\n",
|
pr_info("%s: setting %s-duplex.\n",
|
||||||
dev->name, (vp->full_duplex) ? "full" : "half");
|
dev->name, (vp->full_duplex) ? "full" : "half");
|
||||||
|
|
||||||
EL3WINDOW(3);
|
EL3WINDOW(3);
|
||||||
|
@ -1522,7 +1520,7 @@ vortex_up(struct net_device *dev)
|
||||||
pci_restore_state(VORTEX_PCI(vp));
|
pci_restore_state(VORTEX_PCI(vp));
|
||||||
err = pci_enable_device(VORTEX_PCI(vp));
|
err = pci_enable_device(VORTEX_PCI(vp));
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_WARNING "%s: Could not enable device \n",
|
pr_warning("%s: Could not enable device\n",
|
||||||
dev->name);
|
dev->name);
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
@ -1533,14 +1531,14 @@ vortex_up(struct net_device *dev)
|
||||||
config = ioread32(ioaddr + Wn3_Config);
|
config = ioread32(ioaddr + Wn3_Config);
|
||||||
|
|
||||||
if (vp->media_override != 7) {
|
if (vp->media_override != 7) {
|
||||||
printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
|
pr_info("%s: Media override to transceiver %d (%s).\n",
|
||||||
dev->name, vp->media_override,
|
dev->name, vp->media_override,
|
||||||
media_tbl[vp->media_override].name);
|
media_tbl[vp->media_override].name);
|
||||||
dev->if_port = vp->media_override;
|
dev->if_port = vp->media_override;
|
||||||
} else if (vp->autoselect) {
|
} else if (vp->autoselect) {
|
||||||
if (vp->has_nway) {
|
if (vp->has_nway) {
|
||||||
if (vortex_debug > 1)
|
if (vortex_debug > 1)
|
||||||
printk(KERN_INFO "%s: using NWAY device table, not %d\n",
|
pr_info("%s: using NWAY device table, not %d\n",
|
||||||
dev->name, dev->if_port);
|
dev->name, dev->if_port);
|
||||||
dev->if_port = XCVR_NWAY;
|
dev->if_port = XCVR_NWAY;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1549,13 +1547,13 @@ vortex_up(struct net_device *dev)
|
||||||
while (! (vp->available_media & media_tbl[dev->if_port].mask))
|
while (! (vp->available_media & media_tbl[dev->if_port].mask))
|
||||||
dev->if_port = media_tbl[dev->if_port].next;
|
dev->if_port = media_tbl[dev->if_port].next;
|
||||||
if (vortex_debug > 1)
|
if (vortex_debug > 1)
|
||||||
printk(KERN_INFO "%s: first available media type: %s\n",
|
pr_info("%s: first available media type: %s\n",
|
||||||
dev->name, media_tbl[dev->if_port].name);
|
dev->name, media_tbl[dev->if_port].name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dev->if_port = vp->default_media;
|
dev->if_port = vp->default_media;
|
||||||
if (vortex_debug > 1)
|
if (vortex_debug > 1)
|
||||||
printk(KERN_INFO "%s: using default media %s\n",
|
pr_info("%s: using default media %s\n",
|
||||||
dev->name, media_tbl[dev->if_port].name);
|
dev->name, media_tbl[dev->if_port].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1570,13 +1568,13 @@ vortex_up(struct net_device *dev)
|
||||||
vp->rx_oom_timer.function = rx_oom_timer;
|
vp->rx_oom_timer.function = rx_oom_timer;
|
||||||
|
|
||||||
if (vortex_debug > 1)
|
if (vortex_debug > 1)
|
||||||
printk(KERN_DEBUG "%s: Initial media type %s.\n",
|
pr_debug("%s: Initial media type %s.\n",
|
||||||
dev->name, media_tbl[dev->if_port].name);
|
dev->name, media_tbl[dev->if_port].name);
|
||||||
|
|
||||||
vp->full_duplex = vp->mii.force_media;
|
vp->full_duplex = vp->mii.force_media;
|
||||||
config = BFINS(config, dev->if_port, 20, 4);
|
config = BFINS(config, dev->if_port, 20, 4);
|
||||||
if (vortex_debug > 6)
|
if (vortex_debug > 6)
|
||||||
printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config);
|
pr_debug("vortex_up(): writing 0x%x to InternalConfig\n", config);
|
||||||
iowrite32(config, ioaddr + Wn3_Config);
|
iowrite32(config, ioaddr + Wn3_Config);
|
||||||
|
|
||||||
if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
|
if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
|
||||||
|
@ -1602,7 +1600,7 @@ vortex_up(struct net_device *dev)
|
||||||
|
|
||||||
if (vortex_debug > 1) {
|
if (vortex_debug > 1) {
|
||||||
EL3WINDOW(4);
|
EL3WINDOW(4);
|
||||||
printk(KERN_DEBUG "%s: vortex_up() irq %d media status %4.4x.\n",
|
pr_debug("%s: vortex_up() irq %d media status %4.4x.\n",
|
||||||
dev->name, dev->irq, ioread16(ioaddr + Wn4_Media));
|
dev->name, dev->irq, ioread16(ioaddr + Wn4_Media));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1704,13 +1702,13 @@ vortex_open(struct net_device *dev)
|
||||||
/* Use the now-standard shared IRQ implementation. */
|
/* Use the now-standard shared IRQ implementation. */
|
||||||
if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ?
|
if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ?
|
||||||
&boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev))) {
|
&boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev))) {
|
||||||
printk(KERN_ERR "%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
|
pr_err("%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vp->full_bus_master_rx) { /* Boomerang bus master. */
|
if (vp->full_bus_master_rx) { /* Boomerang bus master. */
|
||||||
if (vortex_debug > 2)
|
if (vortex_debug > 2)
|
||||||
printk(KERN_DEBUG "%s: Filling in the Rx ring.\n", dev->name);
|
pr_debug("%s: Filling in the Rx ring.\n", dev->name);
|
||||||
for (i = 0; i < RX_RING_SIZE; i++) {
|
for (i = 0; i < RX_RING_SIZE; i++) {
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
vp->rx_ring[i].next = cpu_to_le32(vp->rx_ring_dma + sizeof(struct boom_rx_desc) * (i+1));
|
vp->rx_ring[i].next = cpu_to_le32(vp->rx_ring_dma + sizeof(struct boom_rx_desc) * (i+1));
|
||||||
|
@ -1728,7 +1726,7 @@ vortex_open(struct net_device *dev)
|
||||||
}
|
}
|
||||||
if (i != RX_RING_SIZE) {
|
if (i != RX_RING_SIZE) {
|
||||||
int j;
|
int j;
|
||||||
printk(KERN_EMERG "%s: no memory for rx ring\n", dev->name);
|
pr_emerg("%s: no memory for rx ring\n", dev->name);
|
||||||
for (j = 0; j < i; j++) {
|
for (j = 0; j < i; j++) {
|
||||||
if (vp->rx_skbuff[j]) {
|
if (vp->rx_skbuff[j]) {
|
||||||
dev_kfree_skb(vp->rx_skbuff[j]);
|
dev_kfree_skb(vp->rx_skbuff[j]);
|
||||||
|
@ -1750,7 +1748,7 @@ vortex_open(struct net_device *dev)
|
||||||
free_irq(dev->irq, dev);
|
free_irq(dev->irq, dev);
|
||||||
err:
|
err:
|
||||||
if (vortex_debug > 1)
|
if (vortex_debug > 1)
|
||||||
printk(KERN_ERR "%s: vortex_open() fails: returning %d\n", dev->name, retval);
|
pr_err("%s: vortex_open() fails: returning %d\n", dev->name, retval);
|
||||||
out:
|
out:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -1766,9 +1764,9 @@ vortex_timer(unsigned long data)
|
||||||
int media_status, old_window;
|
int media_status, old_window;
|
||||||
|
|
||||||
if (vortex_debug > 2) {
|
if (vortex_debug > 2) {
|
||||||
printk(KERN_DEBUG "%s: Media selection timer tick happened, %s.\n",
|
pr_debug("%s: Media selection timer tick happened, %s.\n",
|
||||||
dev->name, media_tbl[dev->if_port].name);
|
dev->name, media_tbl[dev->if_port].name);
|
||||||
printk(KERN_DEBUG "dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
|
pr_debug("dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
|
||||||
}
|
}
|
||||||
|
|
||||||
disable_irq_lockdep(dev->irq);
|
disable_irq_lockdep(dev->irq);
|
||||||
|
@ -1781,12 +1779,12 @@ vortex_timer(unsigned long data)
|
||||||
netif_carrier_on(dev);
|
netif_carrier_on(dev);
|
||||||
ok = 1;
|
ok = 1;
|
||||||
if (vortex_debug > 1)
|
if (vortex_debug > 1)
|
||||||
printk(KERN_DEBUG "%s: Media %s has link beat, %x.\n",
|
pr_debug("%s: Media %s has link beat, %x.\n",
|
||||||
dev->name, media_tbl[dev->if_port].name, media_status);
|
dev->name, media_tbl[dev->if_port].name, media_status);
|
||||||
} else {
|
} else {
|
||||||
netif_carrier_off(dev);
|
netif_carrier_off(dev);
|
||||||
if (vortex_debug > 1) {
|
if (vortex_debug > 1) {
|
||||||
printk(KERN_DEBUG "%s: Media %s has no link beat, %x.\n",
|
pr_debug("%s: Media %s has no link beat, %x.\n",
|
||||||
dev->name, media_tbl[dev->if_port].name, media_status);
|
dev->name, media_tbl[dev->if_port].name, media_status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1802,7 +1800,7 @@ vortex_timer(unsigned long data)
|
||||||
break;
|
break;
|
||||||
default: /* Other media types handled by Tx timeouts. */
|
default: /* Other media types handled by Tx timeouts. */
|
||||||
if (vortex_debug > 1)
|
if (vortex_debug > 1)
|
||||||
printk(KERN_DEBUG "%s: Media %s has no indication, %x.\n",
|
pr_debug("%s: Media %s has no indication, %x.\n",
|
||||||
dev->name, media_tbl[dev->if_port].name, media_status);
|
dev->name, media_tbl[dev->if_port].name, media_status);
|
||||||
ok = 1;
|
ok = 1;
|
||||||
}
|
}
|
||||||
|
@ -1822,13 +1820,11 @@ vortex_timer(unsigned long data)
|
||||||
if (dev->if_port == XCVR_Default) { /* Go back to default. */
|
if (dev->if_port == XCVR_Default) { /* Go back to default. */
|
||||||
dev->if_port = vp->default_media;
|
dev->if_port = vp->default_media;
|
||||||
if (vortex_debug > 1)
|
if (vortex_debug > 1)
|
||||||
printk(KERN_DEBUG "%s: Media selection failing, using default "
|
pr_debug("%s: Media selection failing, using default %s port.\n",
|
||||||
"%s port.\n",
|
|
||||||
dev->name, media_tbl[dev->if_port].name);
|
dev->name, media_tbl[dev->if_port].name);
|
||||||
} else {
|
} else {
|
||||||
if (vortex_debug > 1)
|
if (vortex_debug > 1)
|
||||||
printk(KERN_DEBUG "%s: Media selection failed, now trying "
|
pr_debug("%s: Media selection failed, now trying %s port.\n",
|
||||||
"%s port.\n",
|
|
||||||
dev->name, media_tbl[dev->if_port].name);
|
dev->name, media_tbl[dev->if_port].name);
|
||||||
next_tick = media_tbl[dev->if_port].wait;
|
next_tick = media_tbl[dev->if_port].wait;
|
||||||
}
|
}
|
||||||
|
@ -1843,13 +1839,13 @@ vortex_timer(unsigned long data)
|
||||||
iowrite16(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
|
iowrite16(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
|
||||||
ioaddr + EL3_CMD);
|
ioaddr + EL3_CMD);
|
||||||
if (vortex_debug > 1)
|
if (vortex_debug > 1)
|
||||||
printk(KERN_DEBUG "wrote 0x%08x to Wn3_Config\n", config);
|
pr_debug("wrote 0x%08x to Wn3_Config\n", config);
|
||||||
/* AKPM: FIXME: Should reset Rx & Tx here. P60 of 3c90xc.pdf */
|
/* AKPM: FIXME: Should reset Rx & Tx here. P60 of 3c90xc.pdf */
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_media_alone:
|
leave_media_alone:
|
||||||
if (vortex_debug > 2)
|
if (vortex_debug > 2)
|
||||||
printk(KERN_DEBUG "%s: Media selection timer finished, %s.\n",
|
pr_debug("%s: Media selection timer finished, %s.\n",
|
||||||
dev->name, media_tbl[dev->if_port].name);
|
dev->name, media_tbl[dev->if_port].name);
|
||||||
|
|
||||||
EL3WINDOW(old_window);
|
EL3WINDOW(old_window);
|
||||||
|
@ -1865,21 +1861,21 @@ static void vortex_tx_timeout(struct net_device *dev)
|
||||||
struct vortex_private *vp = netdev_priv(dev);
|
struct vortex_private *vp = netdev_priv(dev);
|
||||||
void __iomem *ioaddr = vp->ioaddr;
|
void __iomem *ioaddr = vp->ioaddr;
|
||||||
|
|
||||||
printk(KERN_ERR "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
|
pr_err("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
|
||||||
dev->name, ioread8(ioaddr + TxStatus),
|
dev->name, ioread8(ioaddr + TxStatus),
|
||||||
ioread16(ioaddr + EL3_STATUS));
|
ioread16(ioaddr + EL3_STATUS));
|
||||||
EL3WINDOW(4);
|
EL3WINDOW(4);
|
||||||
printk(KERN_ERR " diagnostics: net %04x media %04x dma %08x fifo %04x\n",
|
pr_err(" diagnostics: net %04x media %04x dma %08x fifo %04x\n",
|
||||||
ioread16(ioaddr + Wn4_NetDiag),
|
ioread16(ioaddr + Wn4_NetDiag),
|
||||||
ioread16(ioaddr + Wn4_Media),
|
ioread16(ioaddr + Wn4_Media),
|
||||||
ioread32(ioaddr + PktStatus),
|
ioread32(ioaddr + PktStatus),
|
||||||
ioread16(ioaddr + Wn4_FIFODiag));
|
ioread16(ioaddr + Wn4_FIFODiag));
|
||||||
/* Slight code bloat to be user friendly. */
|
/* Slight code bloat to be user friendly. */
|
||||||
if ((ioread8(ioaddr + TxStatus) & 0x88) == 0x88)
|
if ((ioread8(ioaddr + TxStatus) & 0x88) == 0x88)
|
||||||
printk(KERN_ERR "%s: Transmitter encountered 16 collisions --"
|
pr_err("%s: Transmitter encountered 16 collisions --"
|
||||||
" network cable problem?\n", dev->name);
|
" network cable problem?\n", dev->name);
|
||||||
if (ioread16(ioaddr + EL3_STATUS) & IntLatch) {
|
if (ioread16(ioaddr + EL3_STATUS) & IntLatch) {
|
||||||
printk(KERN_ERR "%s: Interrupt posted but not delivered --"
|
pr_err("%s: Interrupt posted but not delivered --"
|
||||||
" IRQ blocked by another device?\n", dev->name);
|
" IRQ blocked by another device?\n", dev->name);
|
||||||
/* Bad idea here.. but we might as well handle a few events. */
|
/* Bad idea here.. but we might as well handle a few events. */
|
||||||
{
|
{
|
||||||
|
@ -1903,7 +1899,7 @@ static void vortex_tx_timeout(struct net_device *dev)
|
||||||
|
|
||||||
dev->stats.tx_errors++;
|
dev->stats.tx_errors++;
|
||||||
if (vp->full_bus_master_tx) {
|
if (vp->full_bus_master_tx) {
|
||||||
printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name);
|
pr_debug("%s: Resetting the Tx ring pointer.\n", dev->name);
|
||||||
if (vp->cur_tx - vp->dirty_tx > 0 && ioread32(ioaddr + DownListPtr) == 0)
|
if (vp->cur_tx - vp->dirty_tx > 0 && ioread32(ioaddr + DownListPtr) == 0)
|
||||||
iowrite32(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
|
iowrite32(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
|
||||||
ioaddr + DownListPtr);
|
ioaddr + DownListPtr);
|
||||||
|
@ -1938,7 +1934,7 @@ vortex_error(struct net_device *dev, int status)
|
||||||
unsigned char tx_status = 0;
|
unsigned char tx_status = 0;
|
||||||
|
|
||||||
if (vortex_debug > 2) {
|
if (vortex_debug > 2) {
|
||||||
printk(KERN_ERR "%s: vortex_error(), status=0x%x\n", dev->name, status);
|
pr_err("%s: vortex_error(), status=0x%x\n", dev->name, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status & TxComplete) { /* Really "TxError" for us. */
|
if (status & TxComplete) { /* Really "TxError" for us. */
|
||||||
|
@ -1946,10 +1942,10 @@ vortex_error(struct net_device *dev, int status)
|
||||||
/* Presumably a tx-timeout. We must merely re-enable. */
|
/* Presumably a tx-timeout. We must merely re-enable. */
|
||||||
if (vortex_debug > 2
|
if (vortex_debug > 2
|
||||||
|| (tx_status != 0x88 && vortex_debug > 0)) {
|
|| (tx_status != 0x88 && vortex_debug > 0)) {
|
||||||
printk(KERN_ERR "%s: Transmit error, Tx status register %2.2x.\n",
|
pr_err("%s: Transmit error, Tx status register %2.2x.\n",
|
||||||
dev->name, tx_status);
|
dev->name, tx_status);
|
||||||
if (tx_status == 0x82) {
|
if (tx_status == 0x82) {
|
||||||
printk(KERN_ERR "Probably a duplex mismatch. See "
|
pr_err("Probably a duplex mismatch. See "
|
||||||
"Documentation/networking/vortex.txt\n");
|
"Documentation/networking/vortex.txt\n");
|
||||||
}
|
}
|
||||||
dump_tx_ring(dev);
|
dump_tx_ring(dev);
|
||||||
|
@ -1975,13 +1971,13 @@ vortex_error(struct net_device *dev, int status)
|
||||||
if (status & StatsFull) { /* Empty statistics. */
|
if (status & StatsFull) { /* Empty statistics. */
|
||||||
static int DoneDidThat;
|
static int DoneDidThat;
|
||||||
if (vortex_debug > 4)
|
if (vortex_debug > 4)
|
||||||
printk(KERN_DEBUG "%s: Updating stats.\n", dev->name);
|
pr_debug("%s: Updating stats.\n", dev->name);
|
||||||
update_stats(ioaddr, dev);
|
update_stats(ioaddr, dev);
|
||||||
/* HACK: Disable statistics as an interrupt source. */
|
/* HACK: Disable statistics as an interrupt source. */
|
||||||
/* This occurs when we have the wrong media type! */
|
/* This occurs when we have the wrong media type! */
|
||||||
if (DoneDidThat == 0 &&
|
if (DoneDidThat == 0 &&
|
||||||
ioread16(ioaddr + EL3_STATUS) & StatsFull) {
|
ioread16(ioaddr + EL3_STATUS) & StatsFull) {
|
||||||
printk(KERN_WARNING "%s: Updating statistics failed, disabling "
|
pr_warning("%s: Updating statistics failed, disabling "
|
||||||
"stats as an interrupt source.\n", dev->name);
|
"stats as an interrupt source.\n", dev->name);
|
||||||
EL3WINDOW(5);
|
EL3WINDOW(5);
|
||||||
iowrite16(SetIntrEnb | (ioread16(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
|
iowrite16(SetIntrEnb | (ioread16(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
|
||||||
|
@ -1998,7 +1994,7 @@ vortex_error(struct net_device *dev, int status)
|
||||||
u16 fifo_diag;
|
u16 fifo_diag;
|
||||||
EL3WINDOW(4);
|
EL3WINDOW(4);
|
||||||
fifo_diag = ioread16(ioaddr + Wn4_FIFODiag);
|
fifo_diag = ioread16(ioaddr + Wn4_FIFODiag);
|
||||||
printk(KERN_ERR "%s: Host error, FIFO diagnostic register %4.4x.\n",
|
pr_err("%s: Host error, FIFO diagnostic register %4.4x.\n",
|
||||||
dev->name, fifo_diag);
|
dev->name, fifo_diag);
|
||||||
/* Adapter failure requires Tx/Rx reset and reinit. */
|
/* Adapter failure requires Tx/Rx reset and reinit. */
|
||||||
if (vp->full_bus_master_tx) {
|
if (vp->full_bus_master_tx) {
|
||||||
|
@ -2006,7 +2002,7 @@ vortex_error(struct net_device *dev, int status)
|
||||||
/* 0x80000000 PCI master abort. */
|
/* 0x80000000 PCI master abort. */
|
||||||
/* 0x40000000 PCI target abort. */
|
/* 0x40000000 PCI target abort. */
|
||||||
if (vortex_debug)
|
if (vortex_debug)
|
||||||
printk(KERN_ERR "%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status);
|
pr_err("%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status);
|
||||||
|
|
||||||
/* In this case, blow the card away */
|
/* In this case, blow the card away */
|
||||||
/* Must not enter D3 or we can't legally issue the reset! */
|
/* Must not enter D3 or we can't legally issue the reset! */
|
||||||
|
@ -2075,7 +2071,7 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
while (--i > 0 && (tx_status = ioread8(ioaddr + TxStatus)) > 0) {
|
while (--i > 0 && (tx_status = ioread8(ioaddr + TxStatus)) > 0) {
|
||||||
if (tx_status & 0x3C) { /* A Tx-disabling error occurred. */
|
if (tx_status & 0x3C) { /* A Tx-disabling error occurred. */
|
||||||
if (vortex_debug > 2)
|
if (vortex_debug > 2)
|
||||||
printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n",
|
pr_debug("%s: Tx error, status %2.2x.\n",
|
||||||
dev->name, tx_status);
|
dev->name, tx_status);
|
||||||
if (tx_status & 0x04) dev->stats.tx_fifo_errors++;
|
if (tx_status & 0x04) dev->stats.tx_fifo_errors++;
|
||||||
if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
|
if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
|
||||||
|
@ -2101,17 +2097,17 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (vortex_debug > 6) {
|
if (vortex_debug > 6) {
|
||||||
printk(KERN_DEBUG "boomerang_start_xmit()\n");
|
pr_debug("boomerang_start_xmit()\n");
|
||||||
printk(KERN_DEBUG "%s: Trying to send a packet, Tx index %d.\n",
|
pr_debug("%s: Trying to send a packet, Tx index %d.\n",
|
||||||
dev->name, vp->cur_tx);
|
dev->name, vp->cur_tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) {
|
if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) {
|
||||||
if (vortex_debug > 0)
|
if (vortex_debug > 0)
|
||||||
printk(KERN_WARNING "%s: BUG! Tx Ring full, refusing to send buffer.\n",
|
pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n",
|
||||||
dev->name);
|
dev->name);
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
return 1;
|
return NETDEV_TX_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
vp->tx_skbuff[entry] = skb;
|
vp->tx_skbuff[entry] = skb;
|
||||||
|
@ -2204,7 +2200,7 @@ vortex_interrupt(int irq, void *dev_id)
|
||||||
status = ioread16(ioaddr + EL3_STATUS);
|
status = ioread16(ioaddr + EL3_STATUS);
|
||||||
|
|
||||||
if (vortex_debug > 6)
|
if (vortex_debug > 6)
|
||||||
printk("vortex_interrupt(). status=0x%4x\n", status);
|
pr_debug("vortex_interrupt(). status=0x%4x\n", status);
|
||||||
|
|
||||||
if ((status & IntLatch) == 0)
|
if ((status & IntLatch) == 0)
|
||||||
goto handler_exit; /* No interrupt: shared IRQs cause this */
|
goto handler_exit; /* No interrupt: shared IRQs cause this */
|
||||||
|
@ -2219,19 +2215,19 @@ vortex_interrupt(int irq, void *dev_id)
|
||||||
goto handler_exit;
|
goto handler_exit;
|
||||||
|
|
||||||
if (vortex_debug > 4)
|
if (vortex_debug > 4)
|
||||||
printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
|
pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n",
|
||||||
dev->name, status, ioread8(ioaddr + Timer));
|
dev->name, status, ioread8(ioaddr + Timer));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (vortex_debug > 5)
|
if (vortex_debug > 5)
|
||||||
printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
|
pr_debug("%s: In interrupt loop, status %4.4x.\n",
|
||||||
dev->name, status);
|
dev->name, status);
|
||||||
if (status & RxComplete)
|
if (status & RxComplete)
|
||||||
vortex_rx(dev);
|
vortex_rx(dev);
|
||||||
|
|
||||||
if (status & TxAvailable) {
|
if (status & TxAvailable) {
|
||||||
if (vortex_debug > 5)
|
if (vortex_debug > 5)
|
||||||
printk(KERN_DEBUG " TX room bit was handled.\n");
|
pr_debug(" TX room bit was handled.\n");
|
||||||
/* There's room in the FIFO for a full-sized packet. */
|
/* There's room in the FIFO for a full-sized packet. */
|
||||||
iowrite16(AckIntr | TxAvailable, ioaddr + EL3_CMD);
|
iowrite16(AckIntr | TxAvailable, ioaddr + EL3_CMD);
|
||||||
netif_wake_queue (dev);
|
netif_wake_queue (dev);
|
||||||
|
@ -2263,8 +2259,8 @@ vortex_interrupt(int irq, void *dev_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (--work_done < 0) {
|
if (--work_done < 0) {
|
||||||
printk(KERN_WARNING "%s: Too much work in interrupt, status "
|
pr_warning("%s: Too much work in interrupt, status %4.4x.\n",
|
||||||
"%4.4x.\n", dev->name, status);
|
dev->name, status);
|
||||||
/* Disable all pending interrupts. */
|
/* Disable all pending interrupts. */
|
||||||
do {
|
do {
|
||||||
vp->deferred |= status;
|
vp->deferred |= status;
|
||||||
|
@ -2281,7 +2277,7 @@ vortex_interrupt(int irq, void *dev_id)
|
||||||
} while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
|
} while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
|
||||||
|
|
||||||
if (vortex_debug > 4)
|
if (vortex_debug > 4)
|
||||||
printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
|
pr_debug("%s: exiting interrupt, status %4.4x.\n",
|
||||||
dev->name, status);
|
dev->name, status);
|
||||||
handler_exit:
|
handler_exit:
|
||||||
spin_unlock(&vp->lock);
|
spin_unlock(&vp->lock);
|
||||||
|
@ -2313,14 +2309,14 @@ boomerang_interrupt(int irq, void *dev_id)
|
||||||
status = ioread16(ioaddr + EL3_STATUS);
|
status = ioread16(ioaddr + EL3_STATUS);
|
||||||
|
|
||||||
if (vortex_debug > 6)
|
if (vortex_debug > 6)
|
||||||
printk(KERN_DEBUG "boomerang_interrupt. status=0x%4x\n", status);
|
pr_debug("boomerang_interrupt. status=0x%4x\n", status);
|
||||||
|
|
||||||
if ((status & IntLatch) == 0)
|
if ((status & IntLatch) == 0)
|
||||||
goto handler_exit; /* No interrupt: shared IRQs can cause this */
|
goto handler_exit; /* No interrupt: shared IRQs can cause this */
|
||||||
|
|
||||||
if (status == 0xffff) { /* h/w no longer present (hotplug)? */
|
if (status == 0xffff) { /* h/w no longer present (hotplug)? */
|
||||||
if (vortex_debug > 1)
|
if (vortex_debug > 1)
|
||||||
printk(KERN_DEBUG "boomerang_interrupt(1): status = 0xffff\n");
|
pr_debug("boomerang_interrupt(1): status = 0xffff\n");
|
||||||
goto handler_exit;
|
goto handler_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2330,16 +2326,16 @@ boomerang_interrupt(int irq, void *dev_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vortex_debug > 4)
|
if (vortex_debug > 4)
|
||||||
printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
|
pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n",
|
||||||
dev->name, status, ioread8(ioaddr + Timer));
|
dev->name, status, ioread8(ioaddr + Timer));
|
||||||
do {
|
do {
|
||||||
if (vortex_debug > 5)
|
if (vortex_debug > 5)
|
||||||
printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
|
pr_debug("%s: In interrupt loop, status %4.4x.\n",
|
||||||
dev->name, status);
|
dev->name, status);
|
||||||
if (status & UpComplete) {
|
if (status & UpComplete) {
|
||||||
iowrite16(AckIntr | UpComplete, ioaddr + EL3_CMD);
|
iowrite16(AckIntr | UpComplete, ioaddr + EL3_CMD);
|
||||||
if (vortex_debug > 5)
|
if (vortex_debug > 5)
|
||||||
printk(KERN_DEBUG "boomerang_interrupt->boomerang_rx\n");
|
pr_debug("boomerang_interrupt->boomerang_rx\n");
|
||||||
boomerang_rx(dev);
|
boomerang_rx(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2374,7 +2370,7 @@ boomerang_interrupt(int irq, void *dev_id)
|
||||||
dev_kfree_skb_irq(skb);
|
dev_kfree_skb_irq(skb);
|
||||||
vp->tx_skbuff[entry] = NULL;
|
vp->tx_skbuff[entry] = NULL;
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_DEBUG "boomerang_interrupt: no skb!\n");
|
pr_debug("boomerang_interrupt: no skb!\n");
|
||||||
}
|
}
|
||||||
/* dev->stats.tx_packets++; Counted below. */
|
/* dev->stats.tx_packets++; Counted below. */
|
||||||
dirty_tx++;
|
dirty_tx++;
|
||||||
|
@ -2382,7 +2378,7 @@ boomerang_interrupt(int irq, void *dev_id)
|
||||||
vp->dirty_tx = dirty_tx;
|
vp->dirty_tx = dirty_tx;
|
||||||
if (vp->cur_tx - dirty_tx <= TX_RING_SIZE - 1) {
|
if (vp->cur_tx - dirty_tx <= TX_RING_SIZE - 1) {
|
||||||
if (vortex_debug > 6)
|
if (vortex_debug > 6)
|
||||||
printk(KERN_DEBUG "boomerang_interrupt: wake queue\n");
|
pr_debug("boomerang_interrupt: wake queue\n");
|
||||||
netif_wake_queue (dev);
|
netif_wake_queue (dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2392,8 +2388,8 @@ boomerang_interrupt(int irq, void *dev_id)
|
||||||
vortex_error(dev, status);
|
vortex_error(dev, status);
|
||||||
|
|
||||||
if (--work_done < 0) {
|
if (--work_done < 0) {
|
||||||
printk(KERN_WARNING "%s: Too much work in interrupt, status "
|
pr_warning("%s: Too much work in interrupt, status %4.4x.\n",
|
||||||
"%4.4x.\n", dev->name, status);
|
dev->name, status);
|
||||||
/* Disable all pending interrupts. */
|
/* Disable all pending interrupts. */
|
||||||
do {
|
do {
|
||||||
vp->deferred |= status;
|
vp->deferred |= status;
|
||||||
|
@ -2413,7 +2409,7 @@ boomerang_interrupt(int irq, void *dev_id)
|
||||||
} while ((status = ioread16(ioaddr + EL3_STATUS)) & IntLatch);
|
} while ((status = ioread16(ioaddr + EL3_STATUS)) & IntLatch);
|
||||||
|
|
||||||
if (vortex_debug > 4)
|
if (vortex_debug > 4)
|
||||||
printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
|
pr_debug("%s: exiting interrupt, status %4.4x.\n",
|
||||||
dev->name, status);
|
dev->name, status);
|
||||||
handler_exit:
|
handler_exit:
|
||||||
spin_unlock(&vp->lock);
|
spin_unlock(&vp->lock);
|
||||||
|
@ -2428,13 +2424,13 @@ static int vortex_rx(struct net_device *dev)
|
||||||
short rx_status;
|
short rx_status;
|
||||||
|
|
||||||
if (vortex_debug > 5)
|
if (vortex_debug > 5)
|
||||||
printk(KERN_DEBUG "vortex_rx(): status %4.4x, rx_status %4.4x.\n",
|
pr_debug("vortex_rx(): status %4.4x, rx_status %4.4x.\n",
|
||||||
ioread16(ioaddr+EL3_STATUS), ioread16(ioaddr+RxStatus));
|
ioread16(ioaddr+EL3_STATUS), ioread16(ioaddr+RxStatus));
|
||||||
while ((rx_status = ioread16(ioaddr + RxStatus)) > 0) {
|
while ((rx_status = ioread16(ioaddr + RxStatus)) > 0) {
|
||||||
if (rx_status & 0x4000) { /* Error, update stats. */
|
if (rx_status & 0x4000) { /* Error, update stats. */
|
||||||
unsigned char rx_error = ioread8(ioaddr + RxErrors);
|
unsigned char rx_error = ioread8(ioaddr + RxErrors);
|
||||||
if (vortex_debug > 2)
|
if (vortex_debug > 2)
|
||||||
printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
|
pr_debug(" Rx error: status %2.2x.\n", rx_error);
|
||||||
dev->stats.rx_errors++;
|
dev->stats.rx_errors++;
|
||||||
if (rx_error & 0x01) dev->stats.rx_over_errors++;
|
if (rx_error & 0x01) dev->stats.rx_over_errors++;
|
||||||
if (rx_error & 0x02) dev->stats.rx_length_errors++;
|
if (rx_error & 0x02) dev->stats.rx_length_errors++;
|
||||||
|
@ -2448,7 +2444,7 @@ static int vortex_rx(struct net_device *dev)
|
||||||
|
|
||||||
skb = dev_alloc_skb(pkt_len + 5);
|
skb = dev_alloc_skb(pkt_len + 5);
|
||||||
if (vortex_debug > 4)
|
if (vortex_debug > 4)
|
||||||
printk(KERN_DEBUG "Receiving packet size %d status %4.4x.\n",
|
pr_debug("Receiving packet size %d status %4.4x.\n",
|
||||||
pkt_len, rx_status);
|
pkt_len, rx_status);
|
||||||
if (skb != NULL) {
|
if (skb != NULL) {
|
||||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
||||||
|
@ -2478,8 +2474,8 @@ static int vortex_rx(struct net_device *dev)
|
||||||
break;
|
break;
|
||||||
continue;
|
continue;
|
||||||
} else if (vortex_debug > 0)
|
} else if (vortex_debug > 0)
|
||||||
printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of "
|
pr_notice("%s: No memory to allocate a sk_buff of size %d.\n",
|
||||||
"size %d.\n", dev->name, pkt_len);
|
dev->name, pkt_len);
|
||||||
dev->stats.rx_dropped++;
|
dev->stats.rx_dropped++;
|
||||||
}
|
}
|
||||||
issue_and_wait(dev, RxDiscard);
|
issue_and_wait(dev, RxDiscard);
|
||||||
|
@ -2498,7 +2494,7 @@ boomerang_rx(struct net_device *dev)
|
||||||
int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx;
|
int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx;
|
||||||
|
|
||||||
if (vortex_debug > 5)
|
if (vortex_debug > 5)
|
||||||
printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
|
pr_debug("boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
|
||||||
|
|
||||||
while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){
|
while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){
|
||||||
if (--rx_work_limit < 0)
|
if (--rx_work_limit < 0)
|
||||||
|
@ -2506,7 +2502,7 @@ boomerang_rx(struct net_device *dev)
|
||||||
if (rx_status & RxDError) { /* Error, update stats. */
|
if (rx_status & RxDError) { /* Error, update stats. */
|
||||||
unsigned char rx_error = rx_status >> 16;
|
unsigned char rx_error = rx_status >> 16;
|
||||||
if (vortex_debug > 2)
|
if (vortex_debug > 2)
|
||||||
printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
|
pr_debug(" Rx error: status %2.2x.\n", rx_error);
|
||||||
dev->stats.rx_errors++;
|
dev->stats.rx_errors++;
|
||||||
if (rx_error & 0x01) dev->stats.rx_over_errors++;
|
if (rx_error & 0x01) dev->stats.rx_over_errors++;
|
||||||
if (rx_error & 0x02) dev->stats.rx_length_errors++;
|
if (rx_error & 0x02) dev->stats.rx_length_errors++;
|
||||||
|
@ -2520,7 +2516,7 @@ boomerang_rx(struct net_device *dev)
|
||||||
dma_addr_t dma = le32_to_cpu(vp->rx_ring[entry].addr);
|
dma_addr_t dma = le32_to_cpu(vp->rx_ring[entry].addr);
|
||||||
|
|
||||||
if (vortex_debug > 4)
|
if (vortex_debug > 4)
|
||||||
printk(KERN_DEBUG "Receiving packet size %d status %4.4x.\n",
|
pr_debug("Receiving packet size %d status %4.4x.\n",
|
||||||
pkt_len, rx_status);
|
pkt_len, rx_status);
|
||||||
|
|
||||||
/* Check if the packet is long enough to just accept without
|
/* Check if the packet is long enough to just accept without
|
||||||
|
@ -2566,7 +2562,7 @@ boomerang_rx(struct net_device *dev)
|
||||||
if (skb == NULL) {
|
if (skb == NULL) {
|
||||||
static unsigned long last_jif;
|
static unsigned long last_jif;
|
||||||
if (time_after(jiffies, last_jif + 10 * HZ)) {
|
if (time_after(jiffies, last_jif + 10 * HZ)) {
|
||||||
printk(KERN_WARNING "%s: memory shortage\n", dev->name);
|
pr_warning("%s: memory shortage\n", dev->name);
|
||||||
last_jif = jiffies;
|
last_jif = jiffies;
|
||||||
}
|
}
|
||||||
if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE)
|
if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE)
|
||||||
|
@ -2598,7 +2594,7 @@ rx_oom_timer(unsigned long arg)
|
||||||
if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE) /* This test is redundant, but makes me feel good */
|
if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE) /* This test is redundant, but makes me feel good */
|
||||||
boomerang_rx(dev);
|
boomerang_rx(dev);
|
||||||
if (vortex_debug > 1) {
|
if (vortex_debug > 1) {
|
||||||
printk(KERN_DEBUG "%s: rx_oom_timer %s\n", dev->name,
|
pr_debug("%s: rx_oom_timer %s\n", dev->name,
|
||||||
((vp->cur_rx - vp->dirty_rx) != RX_RING_SIZE) ? "succeeded" : "retrying");
|
((vp->cur_rx - vp->dirty_rx) != RX_RING_SIZE) ? "succeeded" : "retrying");
|
||||||
}
|
}
|
||||||
spin_unlock_irq(&vp->lock);
|
spin_unlock_irq(&vp->lock);
|
||||||
|
@ -2655,9 +2651,9 @@ vortex_close(struct net_device *dev)
|
||||||
vortex_down(dev, 1);
|
vortex_down(dev, 1);
|
||||||
|
|
||||||
if (vortex_debug > 1) {
|
if (vortex_debug > 1) {
|
||||||
printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
|
pr_debug("%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
|
||||||
dev->name, ioread16(ioaddr + EL3_STATUS), ioread8(ioaddr + TxStatus));
|
dev->name, ioread16(ioaddr + EL3_STATUS), ioread8(ioaddr + TxStatus));
|
||||||
printk(KERN_DEBUG "%s: vortex close stats: rx_nocopy %d rx_copy %d"
|
pr_debug("%s: vortex close stats: rx_nocopy %d rx_copy %d"
|
||||||
" tx_queued %d Rx pre-checksummed %d.\n",
|
" tx_queued %d Rx pre-checksummed %d.\n",
|
||||||
dev->name, vp->rx_nocopy, vp->rx_copy, vp->queued_packet, vp->rx_csumhits);
|
dev->name, vp->rx_nocopy, vp->rx_copy, vp->queued_packet, vp->rx_csumhits);
|
||||||
}
|
}
|
||||||
|
@ -2666,8 +2662,7 @@ vortex_close(struct net_device *dev)
|
||||||
if (vp->rx_csumhits &&
|
if (vp->rx_csumhits &&
|
||||||
(vp->drv_flags & HAS_HWCKSM) == 0 &&
|
(vp->drv_flags & HAS_HWCKSM) == 0 &&
|
||||||
(vp->card_idx >= MAX_UNITS || hw_checksums[vp->card_idx] == -1)) {
|
(vp->card_idx >= MAX_UNITS || hw_checksums[vp->card_idx] == -1)) {
|
||||||
printk(KERN_WARNING "%s supports hardware checksums, and we're "
|
pr_warning("%s supports hardware checksums, and we're not using them!\n", dev->name);
|
||||||
"not using them!\n", dev->name);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2717,16 +2712,16 @@ dump_tx_ring(struct net_device *dev)
|
||||||
int i;
|
int i;
|
||||||
int stalled = ioread32(ioaddr + PktStatus) & 0x04; /* Possible racy. But it's only debug stuff */
|
int stalled = ioread32(ioaddr + PktStatus) & 0x04; /* Possible racy. But it's only debug stuff */
|
||||||
|
|
||||||
printk(KERN_ERR " Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
|
pr_err(" Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
|
||||||
vp->full_bus_master_tx,
|
vp->full_bus_master_tx,
|
||||||
vp->dirty_tx, vp->dirty_tx % TX_RING_SIZE,
|
vp->dirty_tx, vp->dirty_tx % TX_RING_SIZE,
|
||||||
vp->cur_tx, vp->cur_tx % TX_RING_SIZE);
|
vp->cur_tx, vp->cur_tx % TX_RING_SIZE);
|
||||||
printk(KERN_ERR " Transmit list %8.8x vs. %p.\n",
|
pr_err(" Transmit list %8.8x vs. %p.\n",
|
||||||
ioread32(ioaddr + DownListPtr),
|
ioread32(ioaddr + DownListPtr),
|
||||||
&vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]);
|
&vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]);
|
||||||
issue_and_wait(dev, DownStall);
|
issue_and_wait(dev, DownStall);
|
||||||
for (i = 0; i < TX_RING_SIZE; i++) {
|
for (i = 0; i < TX_RING_SIZE; i++) {
|
||||||
printk(KERN_ERR " %d: @%p length %8.8x status %8.8x\n", i,
|
pr_err(" %d: @%p length %8.8x status %8.8x\n", i,
|
||||||
&vp->tx_ring[i],
|
&vp->tx_ring[i],
|
||||||
#if DO_ZEROCOPY
|
#if DO_ZEROCOPY
|
||||||
le32_to_cpu(vp->tx_ring[i].frag[0].length),
|
le32_to_cpu(vp->tx_ring[i].frag[0].length),
|
||||||
|
@ -2970,7 +2965,7 @@ static void set_rx_mode(struct net_device *dev)
|
||||||
|
|
||||||
if (dev->flags & IFF_PROMISC) {
|
if (dev->flags & IFF_PROMISC) {
|
||||||
if (vortex_debug > 3)
|
if (vortex_debug > 3)
|
||||||
printk(KERN_NOTICE "%s: Setting promiscuous mode.\n", dev->name);
|
pr_notice("%s: Setting promiscuous mode.\n", dev->name);
|
||||||
new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast|RxProm;
|
new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast|RxProm;
|
||||||
} else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
|
} else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
|
||||||
new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast;
|
new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast;
|
||||||
|
@ -3145,8 +3140,7 @@ static void acpi_set_WOL(struct net_device *dev)
|
||||||
iowrite16(RxEnable, ioaddr + EL3_CMD);
|
iowrite16(RxEnable, ioaddr + EL3_CMD);
|
||||||
|
|
||||||
if (pci_enable_wake(VORTEX_PCI(vp), PCI_D3hot, 1)) {
|
if (pci_enable_wake(VORTEX_PCI(vp), PCI_D3hot, 1)) {
|
||||||
printk(KERN_INFO "%s: WOL not supported.\n",
|
pr_info("%s: WOL not supported.\n", pci_name(VORTEX_PCI(vp)));
|
||||||
pci_name(VORTEX_PCI(vp)));
|
|
||||||
|
|
||||||
vp->enable_wol = 0;
|
vp->enable_wol = 0;
|
||||||
return;
|
return;
|
||||||
|
@ -3164,7 +3158,7 @@ static void __devexit vortex_remove_one(struct pci_dev *pdev)
|
||||||
struct vortex_private *vp;
|
struct vortex_private *vp;
|
||||||
|
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
printk("vortex_remove_one called for Compaq device!\n");
|
pr_err("vortex_remove_one called for Compaq device!\n");
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -541,7 +541,7 @@ int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (!TX_BUFFS_AVAIL)
|
if (!TX_BUFFS_AVAIL)
|
||||||
return -1;
|
return NETDEV_TX_LOCKED;
|
||||||
|
|
||||||
netif_stop_queue (dev);
|
netif_stop_queue (dev);
|
||||||
|
|
||||||
|
|
|
@ -471,8 +471,7 @@ static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail,
|
||||||
u32 status, u32 len)
|
u32 status, u32 len)
|
||||||
{
|
{
|
||||||
if (netif_msg_rx_err (cp))
|
if (netif_msg_rx_err (cp))
|
||||||
printk (KERN_DEBUG
|
pr_debug("%s: rx err, slot %d status 0x%x len %d\n",
|
||||||
"%s: rx err, slot %d status 0x%x len %d\n",
|
|
||||||
cp->dev->name, rx_tail, status, len);
|
cp->dev->name, rx_tail, status, len);
|
||||||
cp->dev->stats.rx_errors++;
|
cp->dev->stats.rx_errors++;
|
||||||
if (status & RxErrFrame)
|
if (status & RxErrFrame)
|
||||||
|
@ -547,7 +546,7 @@ static int cp_rx_poll(struct napi_struct *napi, int budget)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netif_msg_rx_status(cp))
|
if (netif_msg_rx_status(cp))
|
||||||
printk(KERN_DEBUG "%s: rx slot %d status 0x%x len %d\n",
|
pr_debug("%s: rx slot %d status 0x%x len %d\n",
|
||||||
dev->name, rx_tail, status, len);
|
dev->name, rx_tail, status, len);
|
||||||
|
|
||||||
buflen = cp->rx_buf_sz + NET_IP_ALIGN;
|
buflen = cp->rx_buf_sz + NET_IP_ALIGN;
|
||||||
|
@ -626,7 +625,7 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
|
|
||||||
if (netif_msg_intr(cp))
|
if (netif_msg_intr(cp))
|
||||||
printk(KERN_DEBUG "%s: intr, status %04x cmd %02x cpcmd %04x\n",
|
pr_debug("%s: intr, status %04x cmd %02x cpcmd %04x\n",
|
||||||
dev->name, status, cpr8(Cmd), cpr16(CpCmd));
|
dev->name, status, cpr8(Cmd), cpr16(CpCmd));
|
||||||
|
|
||||||
cpw16(IntrStatus, status & ~cp_rx_intr_mask);
|
cpw16(IntrStatus, status & ~cp_rx_intr_mask);
|
||||||
|
@ -658,7 +657,7 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
|
||||||
|
|
||||||
pci_read_config_word(cp->pdev, PCI_STATUS, &pci_status);
|
pci_read_config_word(cp->pdev, PCI_STATUS, &pci_status);
|
||||||
pci_write_config_word(cp->pdev, PCI_STATUS, pci_status);
|
pci_write_config_word(cp->pdev, PCI_STATUS, pci_status);
|
||||||
printk(KERN_ERR "%s: PCI bus error, status=%04x, PCI status=%04x\n",
|
pr_err("%s: PCI bus error, status=%04x, PCI status=%04x\n",
|
||||||
dev->name, status, pci_status);
|
dev->name, status, pci_status);
|
||||||
|
|
||||||
/* TODO: reset hardware */
|
/* TODO: reset hardware */
|
||||||
|
@ -705,7 +704,7 @@ static void cp_tx (struct cp_private *cp)
|
||||||
if (status & LastFrag) {
|
if (status & LastFrag) {
|
||||||
if (status & (TxError | TxFIFOUnder)) {
|
if (status & (TxError | TxFIFOUnder)) {
|
||||||
if (netif_msg_tx_err(cp))
|
if (netif_msg_tx_err(cp))
|
||||||
printk(KERN_DEBUG "%s: tx err, status 0x%x\n",
|
pr_debug("%s: tx err, status 0x%x\n",
|
||||||
cp->dev->name, status);
|
cp->dev->name, status);
|
||||||
cp->dev->stats.tx_errors++;
|
cp->dev->stats.tx_errors++;
|
||||||
if (status & TxOWC)
|
if (status & TxOWC)
|
||||||
|
@ -722,7 +721,7 @@ static void cp_tx (struct cp_private *cp)
|
||||||
cp->dev->stats.tx_packets++;
|
cp->dev->stats.tx_packets++;
|
||||||
cp->dev->stats.tx_bytes += skb->len;
|
cp->dev->stats.tx_bytes += skb->len;
|
||||||
if (netif_msg_tx_done(cp))
|
if (netif_msg_tx_done(cp))
|
||||||
printk(KERN_DEBUG "%s: tx done, slot %d\n", cp->dev->name, tx_tail);
|
pr_debug("%s: tx done, slot %d\n", cp->dev->name, tx_tail);
|
||||||
}
|
}
|
||||||
dev_kfree_skb_irq(skb);
|
dev_kfree_skb_irq(skb);
|
||||||
}
|
}
|
||||||
|
@ -755,9 +754,9 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
||||||
if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) {
|
if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) {
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
spin_unlock_irqrestore(&cp->lock, intr_flags);
|
spin_unlock_irqrestore(&cp->lock, intr_flags);
|
||||||
printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
|
pr_err(PFX "%s: BUG! Tx Ring full when queue awake!\n",
|
||||||
dev->name);
|
dev->name);
|
||||||
return 1;
|
return NETDEV_TX_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CP_VLAN_TAG_USED
|
#if CP_VLAN_TAG_USED
|
||||||
|
@ -882,7 +881,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
||||||
}
|
}
|
||||||
cp->tx_head = entry;
|
cp->tx_head = entry;
|
||||||
if (netif_msg_tx_queued(cp))
|
if (netif_msg_tx_queued(cp))
|
||||||
printk(KERN_DEBUG "%s: tx queued, slot %d, skblen %d\n",
|
pr_debug("%s: tx queued, slot %d, skblen %d\n",
|
||||||
dev->name, entry, skb->len);
|
dev->name, entry, skb->len);
|
||||||
if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1))
|
if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1))
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
|
@ -996,7 +995,7 @@ static void cp_reset_hw (struct cp_private *cp)
|
||||||
schedule_timeout_uninterruptible(10);
|
schedule_timeout_uninterruptible(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(KERN_ERR "%s: hardware reset timeout\n", cp->dev->name);
|
pr_err("%s: hardware reset timeout\n", cp->dev->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cp_start_hw (struct cp_private *cp)
|
static inline void cp_start_hw (struct cp_private *cp)
|
||||||
|
@ -1166,7 +1165,7 @@ static int cp_open (struct net_device *dev)
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (netif_msg_ifup(cp))
|
if (netif_msg_ifup(cp))
|
||||||
printk(KERN_DEBUG "%s: enabling interface\n", dev->name);
|
pr_debug("%s: enabling interface\n", dev->name);
|
||||||
|
|
||||||
rc = cp_alloc_rings(cp);
|
rc = cp_alloc_rings(cp);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -1201,7 +1200,7 @@ static int cp_close (struct net_device *dev)
|
||||||
napi_disable(&cp->napi);
|
napi_disable(&cp->napi);
|
||||||
|
|
||||||
if (netif_msg_ifdown(cp))
|
if (netif_msg_ifdown(cp))
|
||||||
printk(KERN_DEBUG "%s: disabling interface\n", dev->name);
|
pr_debug("%s: disabling interface\n", dev->name);
|
||||||
|
|
||||||
spin_lock_irqsave(&cp->lock, flags);
|
spin_lock_irqsave(&cp->lock, flags);
|
||||||
|
|
||||||
|
@ -1224,7 +1223,7 @@ static void cp_tx_timeout(struct net_device *dev)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
printk(KERN_WARNING "%s: Transmit timeout, status %2x %4x %4x %4x\n",
|
pr_warning("%s: Transmit timeout, status %2x %4x %4x %4x\n",
|
||||||
dev->name, cpr8(Cmd), cpr16(CpCmd),
|
dev->name, cpr8(Cmd), cpr16(CpCmd),
|
||||||
cpr16(IntrStatus), cpr16(IntrMask));
|
cpr16(IntrStatus), cpr16(IntrMask));
|
||||||
|
|
||||||
|
@ -1873,7 +1872,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
#ifndef MODULE
|
#ifndef MODULE
|
||||||
static int version_printed;
|
static int version_printed;
|
||||||
if (version_printed++ == 0)
|
if (version_printed++ == 0)
|
||||||
printk("%s", version);
|
pr_info("%s", version);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
|
if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
|
||||||
|
@ -1995,8 +1994,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err_out_iomap;
|
goto err_out_iomap;
|
||||||
|
|
||||||
printk (KERN_INFO "%s: RTL-8139C+ at 0x%lx, "
|
pr_info("%s: RTL-8139C+ at 0x%lx, %pM, IRQ %d\n",
|
||||||
"%pM, IRQ %d\n",
|
|
||||||
dev->name,
|
dev->name,
|
||||||
dev->base_addr,
|
dev->base_addr,
|
||||||
dev->dev_addr,
|
dev->dev_addr,
|
||||||
|
@ -2113,7 +2111,7 @@ static struct pci_driver cp_driver = {
|
||||||
static int __init cp_init (void)
|
static int __init cp_init (void)
|
||||||
{
|
{
|
||||||
#ifdef MODULE
|
#ifdef MODULE
|
||||||
printk("%s", version);
|
pr_info("%s", version);
|
||||||
#endif
|
#endif
|
||||||
return pci_register_driver(&cp_driver);
|
return pci_register_driver(&cp_driver);
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,19 +126,12 @@
|
||||||
#undef RTL8139_NDEBUG
|
#undef RTL8139_NDEBUG
|
||||||
|
|
||||||
|
|
||||||
#if RTL8139_DEBUG
|
|
||||||
/* note: prints function name for you */
|
|
||||||
# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
|
|
||||||
#else
|
|
||||||
# define DPRINTK(fmt, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef RTL8139_NDEBUG
|
#ifdef RTL8139_NDEBUG
|
||||||
# define assert(expr) do {} while (0)
|
# define assert(expr) do {} while (0)
|
||||||
#else
|
#else
|
||||||
# define assert(expr) \
|
# define assert(expr) \
|
||||||
if(unlikely(!(expr))) { \
|
if(unlikely(!(expr))) { \
|
||||||
printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \
|
pr_err("Assertion failed! %s,%s,%s,line=%d\n", \
|
||||||
#expr, __FILE__, __func__, __LINE__); \
|
#expr, __FILE__, __func__, __LINE__); \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -784,8 +777,8 @@ static __devinit struct net_device * rtl8139_init_board (struct pci_dev *pdev)
|
||||||
|
|
||||||
/* set this immediately, we need to know before
|
/* set this immediately, we need to know before
|
||||||
* we talk to the chip directly */
|
* we talk to the chip directly */
|
||||||
DPRINTK("PIO region size == 0x%02X\n", pio_len);
|
pr_debug("PIO region size == 0x%02lX\n", pio_len);
|
||||||
DPRINTK("MMIO region size == 0x%02lX\n", mmio_len);
|
pr_debug("MMIO region size == 0x%02lX\n", mmio_len);
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
if (use_io) {
|
if (use_io) {
|
||||||
|
@ -865,19 +858,17 @@ static __devinit struct net_device * rtl8139_init_board (struct pci_dev *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if unknown chip, assume array element #0, original RTL-8139 in this case */
|
/* if unknown chip, assume array element #0, original RTL-8139 in this case */
|
||||||
dev_printk (KERN_DEBUG, &pdev->dev,
|
dev_dbg(&pdev->dev, "unknown chip version, assuming RTL-8139\n");
|
||||||
"unknown chip version, assuming RTL-8139\n");
|
dev_dbg(&pdev->dev, "TxConfig = 0x%lx\n", RTL_R32 (TxConfig));
|
||||||
dev_printk (KERN_DEBUG, &pdev->dev,
|
|
||||||
"TxConfig = 0x%lx\n", RTL_R32 (TxConfig));
|
|
||||||
tp->chipset = 0;
|
tp->chipset = 0;
|
||||||
|
|
||||||
match:
|
match:
|
||||||
DPRINTK ("chipset id (%d) == index %d, '%s'\n",
|
pr_debug("chipset id (%d) == index %d, '%s'\n",
|
||||||
version, i, rtl_chip_info[i].name);
|
version, i, rtl_chip_info[i].name);
|
||||||
|
|
||||||
if (tp->chipset >= CH_8139B) {
|
if (tp->chipset >= CH_8139B) {
|
||||||
u8 new_tmp8 = tmp8 = RTL_R8 (Config1);
|
u8 new_tmp8 = tmp8 = RTL_R8 (Config1);
|
||||||
DPRINTK("PCI PM wakeup\n");
|
pr_debug("PCI PM wakeup\n");
|
||||||
if ((rtl_chip_info[tp->chipset].flags & HasLWake) &&
|
if ((rtl_chip_info[tp->chipset].flags & HasLWake) &&
|
||||||
(tmp8 & LWAKE))
|
(tmp8 & LWAKE))
|
||||||
new_tmp8 &= ~LWAKE;
|
new_tmp8 &= ~LWAKE;
|
||||||
|
@ -896,7 +887,7 @@ static __devinit struct net_device * rtl8139_init_board (struct pci_dev *pdev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DPRINTK("Old chip wakeup\n");
|
pr_debug("Old chip wakeup\n");
|
||||||
tmp8 = RTL_R8 (Config1);
|
tmp8 = RTL_R8 (Config1);
|
||||||
tmp8 &= ~(SLEEP | PWRDN);
|
tmp8 &= ~(SLEEP | PWRDN);
|
||||||
RTL_W8 (Config1, tmp8);
|
RTL_W8 (Config1, tmp8);
|
||||||
|
@ -949,7 +940,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
||||||
{
|
{
|
||||||
static int printed_version;
|
static int printed_version;
|
||||||
if (!printed_version++)
|
if (!printed_version++)
|
||||||
printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
|
pr_info(RTL8139_DRIVER_NAME "\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -965,7 +956,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
||||||
pdev->device == PCI_DEVICE_ID_REALTEK_8139 &&
|
pdev->device == PCI_DEVICE_ID_REALTEK_8139 &&
|
||||||
pdev->subsystem_vendor == PCI_VENDOR_ID_ATHEROS &&
|
pdev->subsystem_vendor == PCI_VENDOR_ID_ATHEROS &&
|
||||||
pdev->subsystem_device == PCI_DEVICE_ID_REALTEK_8139) {
|
pdev->subsystem_device == PCI_DEVICE_ID_REALTEK_8139) {
|
||||||
printk(KERN_INFO "8139too: OQO Model 2 detected. Forcing PIO\n");
|
pr_info("8139too: OQO Model 2 detected. Forcing PIO\n");
|
||||||
use_io = 1;
|
use_io = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1018,21 +1009,20 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
||||||
tp->mii.reg_num_mask = 0x1f;
|
tp->mii.reg_num_mask = 0x1f;
|
||||||
|
|
||||||
/* dev is fully set up and ready to use now */
|
/* dev is fully set up and ready to use now */
|
||||||
DPRINTK("about to register device named %s (%p)...\n", dev->name, dev);
|
pr_debug("about to register device named %s (%p)...\n", dev->name, dev);
|
||||||
i = register_netdev (dev);
|
i = register_netdev (dev);
|
||||||
if (i) goto err_out;
|
if (i) goto err_out;
|
||||||
|
|
||||||
pci_set_drvdata (pdev, dev);
|
pci_set_drvdata (pdev, dev);
|
||||||
|
|
||||||
printk (KERN_INFO "%s: %s at 0x%lx, "
|
pr_info("%s: %s at 0x%lx, %pM, IRQ %d\n",
|
||||||
"%pM, IRQ %d\n",
|
|
||||||
dev->name,
|
dev->name,
|
||||||
board_info[ent->driver_data].name,
|
board_info[ent->driver_data].name,
|
||||||
dev->base_addr,
|
dev->base_addr,
|
||||||
dev->dev_addr,
|
dev->dev_addr,
|
||||||
dev->irq);
|
dev->irq);
|
||||||
|
|
||||||
printk (KERN_DEBUG "%s: Identified 8139 chip type '%s'\n",
|
pr_debug("%s: Identified 8139 chip type '%s'\n",
|
||||||
dev->name, rtl_chip_info[tp->chipset].name);
|
dev->name, rtl_chip_info[tp->chipset].name);
|
||||||
|
|
||||||
/* Find the connected MII xcvrs.
|
/* Find the connected MII xcvrs.
|
||||||
|
@ -1046,14 +1036,12 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
||||||
if (mii_status != 0xffff && mii_status != 0x0000) {
|
if (mii_status != 0xffff && mii_status != 0x0000) {
|
||||||
u16 advertising = mdio_read(dev, phy, 4);
|
u16 advertising = mdio_read(dev, phy, 4);
|
||||||
tp->phys[phy_idx++] = phy;
|
tp->phys[phy_idx++] = phy;
|
||||||
printk(KERN_INFO "%s: MII transceiver %d status 0x%4.4x "
|
pr_info("%s: MII transceiver %d status 0x%4.4x advertising %4.4x.\n",
|
||||||
"advertising %4.4x.\n",
|
|
||||||
dev->name, phy, mii_status, advertising);
|
dev->name, phy, mii_status, advertising);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (phy_idx == 0) {
|
if (phy_idx == 0) {
|
||||||
printk(KERN_INFO "%s: No MII transceivers found! Assuming SYM "
|
pr_info("%s: No MII transceivers found! Assuming SYM transceiver.\n",
|
||||||
"transceiver.\n",
|
|
||||||
dev->name);
|
dev->name);
|
||||||
tp->phys[0] = 32;
|
tp->phys[0] = 32;
|
||||||
}
|
}
|
||||||
|
@ -1073,13 +1061,13 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
||||||
if (board_idx < MAX_UNITS && full_duplex[board_idx] > 0)
|
if (board_idx < MAX_UNITS && full_duplex[board_idx] > 0)
|
||||||
tp->mii.full_duplex = full_duplex[board_idx];
|
tp->mii.full_duplex = full_duplex[board_idx];
|
||||||
if (tp->mii.full_duplex) {
|
if (tp->mii.full_duplex) {
|
||||||
printk(KERN_INFO "%s: Media type forced to Full Duplex.\n", dev->name);
|
pr_info("%s: Media type forced to Full Duplex.\n", dev->name);
|
||||||
/* Changing the MII-advertised media because might prevent
|
/* Changing the MII-advertised media because might prevent
|
||||||
re-connection. */
|
re-connection. */
|
||||||
tp->mii.force_media = 1;
|
tp->mii.force_media = 1;
|
||||||
}
|
}
|
||||||
if (tp->default_port) {
|
if (tp->default_port) {
|
||||||
printk(KERN_INFO " Forcing %dMbps %s-duplex operation.\n",
|
pr_info(" Forcing %dMbps %s-duplex operation.\n",
|
||||||
(option & 0x20 ? 100 : 10),
|
(option & 0x20 ? 100 : 10),
|
||||||
(option & 0x10 ? "full" : "half"));
|
(option & 0x10 ? "full" : "half"));
|
||||||
mdio_write(dev, tp->phys[0], 0,
|
mdio_write(dev, tp->phys[0], 0,
|
||||||
|
@ -1342,7 +1330,7 @@ static int rtl8139_open (struct net_device *dev)
|
||||||
netif_start_queue (dev);
|
netif_start_queue (dev);
|
||||||
|
|
||||||
if (netif_msg_ifup(tp))
|
if (netif_msg_ifup(tp))
|
||||||
printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#llx IRQ %d"
|
pr_debug("%s: rtl8139_open() ioaddr %#llx IRQ %d"
|
||||||
" GP Pins %2.2x %s-duplex.\n", dev->name,
|
" GP Pins %2.2x %s-duplex.\n", dev->name,
|
||||||
(unsigned long long)pci_resource_start (tp->pci_dev, 1),
|
(unsigned long long)pci_resource_start (tp->pci_dev, 1),
|
||||||
dev->irq, RTL_R8 (MediaStatus),
|
dev->irq, RTL_R8 (MediaStatus),
|
||||||
|
@ -1404,7 +1392,7 @@ static void rtl8139_hw_start (struct net_device *dev)
|
||||||
RTL_W8 (Config3, RTL_R8 (Config3) & ~Cfg3_Magic);
|
RTL_W8 (Config3, RTL_R8 (Config3) & ~Cfg3_Magic);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTK("init buffer addresses\n");
|
pr_debug("init buffer addresses\n");
|
||||||
|
|
||||||
/* Lock Config[01234] and BMCR register writes */
|
/* Lock Config[01234] and BMCR register writes */
|
||||||
RTL_W8 (Cfg9346, Cfg9346_Lock);
|
RTL_W8 (Cfg9346, Cfg9346_Lock);
|
||||||
|
@ -1566,14 +1554,13 @@ static inline void rtl8139_thread_iter (struct net_device *dev,
|
||||||
tp->mii.full_duplex = duplex;
|
tp->mii.full_duplex = duplex;
|
||||||
|
|
||||||
if (mii_lpa) {
|
if (mii_lpa) {
|
||||||
printk (KERN_INFO
|
pr_info("%s: Setting %s-duplex based on MII #%d link"
|
||||||
"%s: Setting %s-duplex based on MII #%d link"
|
|
||||||
" partner ability of %4.4x.\n",
|
" partner ability of %4.4x.\n",
|
||||||
dev->name,
|
dev->name,
|
||||||
tp->mii.full_duplex ? "full" : "half",
|
tp->mii.full_duplex ? "full" : "half",
|
||||||
tp->phys[0], mii_lpa);
|
tp->phys[0], mii_lpa);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_INFO"%s: media is unconnected, link down, or incompatible connection\n",
|
pr_info("%s: media is unconnected, link down, or incompatible connection\n",
|
||||||
dev->name);
|
dev->name);
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -1588,11 +1575,11 @@ static inline void rtl8139_thread_iter (struct net_device *dev,
|
||||||
|
|
||||||
rtl8139_tune_twister (dev, tp);
|
rtl8139_tune_twister (dev, tp);
|
||||||
|
|
||||||
DPRINTK ("%s: Media selection tick, Link partner %4.4x.\n",
|
pr_debug("%s: Media selection tick, Link partner %4.4x.\n",
|
||||||
dev->name, RTL_R16 (NWayLPAR));
|
dev->name, RTL_R16 (NWayLPAR));
|
||||||
DPRINTK ("%s: Other registers are IntMask %4.4x IntStatus %4.4x\n",
|
pr_debug("%s: Other registers are IntMask %4.4x IntStatus %4.4x\n",
|
||||||
dev->name, RTL_R16 (IntrMask), RTL_R16 (IntrStatus));
|
dev->name, RTL_R16 (IntrMask), RTL_R16 (IntrStatus));
|
||||||
DPRINTK ("%s: Chip config %2.2x %2.2x.\n",
|
pr_debug("%s: Chip config %2.2x %2.2x.\n",
|
||||||
dev->name, RTL_R8 (Config0),
|
dev->name, RTL_R8 (Config0),
|
||||||
RTL_R8 (Config1));
|
RTL_R8 (Config1));
|
||||||
}
|
}
|
||||||
|
@ -1652,14 +1639,14 @@ static void rtl8139_tx_timeout_task (struct work_struct *work)
|
||||||
int i;
|
int i;
|
||||||
u8 tmp8;
|
u8 tmp8;
|
||||||
|
|
||||||
printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x "
|
pr_debug("%s: Transmit timeout, status %2.2x %4.4x %4.4x media %2.2x.\n",
|
||||||
"media %2.2x.\n", dev->name, RTL_R8 (ChipCmd),
|
dev->name, RTL_R8 (ChipCmd),
|
||||||
RTL_R16(IntrStatus), RTL_R16(IntrMask), RTL_R8(MediaStatus));
|
RTL_R16(IntrStatus), RTL_R16(IntrMask), RTL_R8(MediaStatus));
|
||||||
/* Emit info to figure out what went wrong. */
|
/* Emit info to figure out what went wrong. */
|
||||||
printk (KERN_DEBUG "%s: Tx queue start entry %ld dirty entry %ld.\n",
|
pr_debug("%s: Tx queue start entry %ld dirty entry %ld.\n",
|
||||||
dev->name, tp->cur_tx, tp->dirty_tx);
|
dev->name, tp->cur_tx, tp->dirty_tx);
|
||||||
for (i = 0; i < NUM_TX_DESC; i++)
|
for (i = 0; i < NUM_TX_DESC; i++)
|
||||||
printk (KERN_DEBUG "%s: Tx descriptor %d is %8.8lx.%s\n",
|
pr_debug("%s: Tx descriptor %d is %8.8lx.%s\n",
|
||||||
dev->name, i, RTL_R32 (TxStatus0 + (i * 4)),
|
dev->name, i, RTL_R32 (TxStatus0 + (i * 4)),
|
||||||
i == tp->dirty_tx % NUM_TX_DESC ?
|
i == tp->dirty_tx % NUM_TX_DESC ?
|
||||||
" (queue head)" : "");
|
" (queue head)" : "");
|
||||||
|
@ -1741,7 +1728,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
||||||
spin_unlock_irqrestore(&tp->lock, flags);
|
spin_unlock_irqrestore(&tp->lock, flags);
|
||||||
|
|
||||||
if (netif_msg_tx_queued(tp))
|
if (netif_msg_tx_queued(tp))
|
||||||
printk (KERN_DEBUG "%s: Queued Tx packet size %u to slot %d.\n",
|
pr_debug("%s: Queued Tx packet size %u to slot %d.\n",
|
||||||
dev->name, len, entry);
|
dev->name, len, entry);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1772,7 +1759,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
|
||||||
if (txstatus & (TxOutOfWindow | TxAborted)) {
|
if (txstatus & (TxOutOfWindow | TxAborted)) {
|
||||||
/* There was an major error, log it. */
|
/* There was an major error, log it. */
|
||||||
if (netif_msg_tx_err(tp))
|
if (netif_msg_tx_err(tp))
|
||||||
printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
|
pr_debug("%s: Transmit error, Tx status %8.8x.\n",
|
||||||
dev->name, txstatus);
|
dev->name, txstatus);
|
||||||
dev->stats.tx_errors++;
|
dev->stats.tx_errors++;
|
||||||
if (txstatus & TxAborted) {
|
if (txstatus & TxAborted) {
|
||||||
|
@ -1803,7 +1790,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
|
||||||
|
|
||||||
#ifndef RTL8139_NDEBUG
|
#ifndef RTL8139_NDEBUG
|
||||||
if (tp->cur_tx - dirty_tx > NUM_TX_DESC) {
|
if (tp->cur_tx - dirty_tx > NUM_TX_DESC) {
|
||||||
printk (KERN_ERR "%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
|
pr_err("%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
|
||||||
dev->name, dirty_tx, tp->cur_tx);
|
dev->name, dirty_tx, tp->cur_tx);
|
||||||
dirty_tx += NUM_TX_DESC;
|
dirty_tx += NUM_TX_DESC;
|
||||||
}
|
}
|
||||||
|
@ -1828,12 +1815,12 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (netif_msg_rx_err (tp))
|
if (netif_msg_rx_err (tp))
|
||||||
printk(KERN_DEBUG "%s: Ethernet frame had errors, status %8.8x.\n",
|
pr_debug("%s: Ethernet frame had errors, status %8.8x.\n",
|
||||||
dev->name, rx_status);
|
dev->name, rx_status);
|
||||||
dev->stats.rx_errors++;
|
dev->stats.rx_errors++;
|
||||||
if (!(rx_status & RxStatusOK)) {
|
if (!(rx_status & RxStatusOK)) {
|
||||||
if (rx_status & RxTooLong) {
|
if (rx_status & RxTooLong) {
|
||||||
DPRINTK ("%s: Oversized Ethernet frame, status %4.4x!\n",
|
pr_debug("%s: Oversized Ethernet frame, status %4.4x!\n",
|
||||||
dev->name, rx_status);
|
dev->name, rx_status);
|
||||||
/* A.C.: The chip hangs here. */
|
/* A.C.: The chip hangs here. */
|
||||||
}
|
}
|
||||||
|
@ -1866,7 +1853,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (tmp_work <= 0)
|
if (tmp_work <= 0)
|
||||||
printk (KERN_WARNING PFX "rx stop wait too long\n");
|
pr_warning(PFX "rx stop wait too long\n");
|
||||||
/* restart receive */
|
/* restart receive */
|
||||||
tmp_work = 200;
|
tmp_work = 200;
|
||||||
while (--tmp_work > 0) {
|
while (--tmp_work > 0) {
|
||||||
|
@ -1877,7 +1864,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (tmp_work <= 0)
|
if (tmp_work <= 0)
|
||||||
printk (KERN_WARNING PFX "tx/rx enable wait too long\n");
|
pr_warning(PFX "tx/rx enable wait too long\n");
|
||||||
|
|
||||||
/* and reinitialize all rx related registers */
|
/* and reinitialize all rx related registers */
|
||||||
RTL_W8_F (Cfg9346, Cfg9346_Unlock);
|
RTL_W8_F (Cfg9346, Cfg9346_Unlock);
|
||||||
|
@ -1888,7 +1875,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
|
||||||
RTL_W32 (RxConfig, tp->rx_config);
|
RTL_W32 (RxConfig, tp->rx_config);
|
||||||
tp->cur_rx = 0;
|
tp->cur_rx = 0;
|
||||||
|
|
||||||
DPRINTK("init buffer addresses\n");
|
pr_debug("init buffer addresses\n");
|
||||||
|
|
||||||
/* Lock Config[01234] and BMCR register writes */
|
/* Lock Config[01234] and BMCR register writes */
|
||||||
RTL_W8 (Cfg9346, Cfg9346_Lock);
|
RTL_W8 (Cfg9346, Cfg9346_Lock);
|
||||||
|
@ -1942,7 +1929,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
|
||||||
unsigned int cur_rx = tp->cur_rx;
|
unsigned int cur_rx = tp->cur_rx;
|
||||||
unsigned int rx_size = 0;
|
unsigned int rx_size = 0;
|
||||||
|
|
||||||
DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
|
pr_debug("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
|
||||||
" free to %4.4x, Cmd %2.2x.\n", dev->name, (u16)cur_rx,
|
" free to %4.4x, Cmd %2.2x.\n", dev->name, (u16)cur_rx,
|
||||||
RTL_R16 (RxBufAddr),
|
RTL_R16 (RxBufAddr),
|
||||||
RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
|
RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
|
||||||
|
@ -1962,17 +1949,17 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
|
||||||
pkt_size = rx_size - 4;
|
pkt_size = rx_size - 4;
|
||||||
|
|
||||||
if (netif_msg_rx_status(tp))
|
if (netif_msg_rx_status(tp))
|
||||||
printk(KERN_DEBUG "%s: rtl8139_rx() status %4.4x, size %4.4x,"
|
pr_debug("%s: rtl8139_rx() status %4.4x, size %4.4x,"
|
||||||
" cur %4.4x.\n", dev->name, rx_status,
|
" cur %4.4x.\n", dev->name, rx_status,
|
||||||
rx_size, cur_rx);
|
rx_size, cur_rx);
|
||||||
#if RTL8139_DEBUG > 2
|
#if RTL8139_DEBUG > 2
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
DPRINTK ("%s: Frame contents ", dev->name);
|
pr_debug("%s: Frame contents ", dev->name);
|
||||||
for (i = 0; i < 70; i++)
|
for (i = 0; i < 70; i++)
|
||||||
printk (" %2.2x",
|
pr_cont(" %2.2x",
|
||||||
rx_ring[ring_offset + i]);
|
rx_ring[ring_offset + i]);
|
||||||
printk (".\n");
|
pr_cont(".\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1984,12 +1971,12 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
|
||||||
if (!tp->fifo_copy_timeout)
|
if (!tp->fifo_copy_timeout)
|
||||||
tp->fifo_copy_timeout = jiffies + 2;
|
tp->fifo_copy_timeout = jiffies + 2;
|
||||||
else if (time_after(jiffies, tp->fifo_copy_timeout)) {
|
else if (time_after(jiffies, tp->fifo_copy_timeout)) {
|
||||||
DPRINTK ("%s: hung FIFO. Reset.", dev->name);
|
pr_debug("%s: hung FIFO. Reset.", dev->name);
|
||||||
rx_size = 0;
|
rx_size = 0;
|
||||||
goto no_early_rx;
|
goto no_early_rx;
|
||||||
}
|
}
|
||||||
if (netif_msg_intr(tp)) {
|
if (netif_msg_intr(tp)) {
|
||||||
printk(KERN_DEBUG "%s: fifo copy in progress.",
|
pr_debug("%s: fifo copy in progress.",
|
||||||
dev->name);
|
dev->name);
|
||||||
}
|
}
|
||||||
tp->xstats.early_rx++;
|
tp->xstats.early_rx++;
|
||||||
|
@ -2033,8 +2020,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
|
||||||
netif_receive_skb (skb);
|
netif_receive_skb (skb);
|
||||||
} else {
|
} else {
|
||||||
if (net_ratelimit())
|
if (net_ratelimit())
|
||||||
printk (KERN_WARNING
|
pr_warning("%s: Memory squeeze, dropping packet.\n",
|
||||||
"%s: Memory squeeze, dropping packet.\n",
|
|
||||||
dev->name);
|
dev->name);
|
||||||
dev->stats.rx_dropped++;
|
dev->stats.rx_dropped++;
|
||||||
}
|
}
|
||||||
|
@ -2049,12 +2035,10 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
|
||||||
if (unlikely(!received || rx_size == 0xfff0))
|
if (unlikely(!received || rx_size == 0xfff0))
|
||||||
rtl8139_isr_ack(tp);
|
rtl8139_isr_ack(tp);
|
||||||
|
|
||||||
#if RTL8139_DEBUG > 1
|
pr_debug("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
|
||||||
DPRINTK ("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
|
|
||||||
" free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
|
" free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
|
||||||
RTL_R16 (RxBufAddr),
|
RTL_R16 (RxBufAddr),
|
||||||
RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
|
RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
|
||||||
#endif
|
|
||||||
|
|
||||||
tp->cur_rx = cur_rx;
|
tp->cur_rx = cur_rx;
|
||||||
|
|
||||||
|
@ -2075,7 +2059,7 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
|
||||||
void __iomem *ioaddr,
|
void __iomem *ioaddr,
|
||||||
int status, int link_changed)
|
int status, int link_changed)
|
||||||
{
|
{
|
||||||
DPRINTK ("%s: Abnormal interrupt, status %8.8x.\n",
|
pr_debug("%s: Abnormal interrupt, status %8.8x.\n",
|
||||||
dev->name, status);
|
dev->name, status);
|
||||||
|
|
||||||
assert (dev != NULL);
|
assert (dev != NULL);
|
||||||
|
@ -2104,7 +2088,7 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
|
||||||
pci_read_config_word (tp->pci_dev, PCI_STATUS, &pci_cmd_status);
|
pci_read_config_word (tp->pci_dev, PCI_STATUS, &pci_cmd_status);
|
||||||
pci_write_config_word (tp->pci_dev, PCI_STATUS, pci_cmd_status);
|
pci_write_config_word (tp->pci_dev, PCI_STATUS, pci_cmd_status);
|
||||||
|
|
||||||
printk (KERN_ERR "%s: PCI Bus error %4.4x.\n",
|
pr_err("%s: PCI Bus error %4.4x.\n",
|
||||||
dev->name, pci_cmd_status);
|
dev->name, pci_cmd_status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2198,7 +2182,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
|
||||||
out:
|
out:
|
||||||
spin_unlock (&tp->lock);
|
spin_unlock (&tp->lock);
|
||||||
|
|
||||||
DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
|
pr_debug("%s: exiting interrupt, intr_status=%#4.4x.\n",
|
||||||
dev->name, RTL_R16 (IntrStatus));
|
dev->name, RTL_R16 (IntrStatus));
|
||||||
return IRQ_RETVAL(handled);
|
return IRQ_RETVAL(handled);
|
||||||
}
|
}
|
||||||
|
@ -2249,7 +2233,7 @@ static int rtl8139_close (struct net_device *dev)
|
||||||
napi_disable(&tp->napi);
|
napi_disable(&tp->napi);
|
||||||
|
|
||||||
if (netif_msg_ifdown(tp))
|
if (netif_msg_ifdown(tp))
|
||||||
printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
|
pr_debug("%s: Shutting down ethercard, status was 0x%4.4x.\n",
|
||||||
dev->name, RTL_R16 (IntrStatus));
|
dev->name, RTL_R16 (IntrStatus));
|
||||||
|
|
||||||
spin_lock_irqsave (&tp->lock, flags);
|
spin_lock_irqsave (&tp->lock, flags);
|
||||||
|
@ -2292,11 +2276,11 @@ static int rtl8139_close (struct net_device *dev)
|
||||||
other threads or interrupts aren't messing with the 8139. */
|
other threads or interrupts aren't messing with the 8139. */
|
||||||
static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *np = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
void __iomem *ioaddr = np->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
|
|
||||||
spin_lock_irq(&np->lock);
|
spin_lock_irq(&tp->lock);
|
||||||
if (rtl_chip_info[np->chipset].flags & HasLWake) {
|
if (rtl_chip_info[tp->chipset].flags & HasLWake) {
|
||||||
u8 cfg3 = RTL_R8 (Config3);
|
u8 cfg3 = RTL_R8 (Config3);
|
||||||
u8 cfg5 = RTL_R8 (Config5);
|
u8 cfg5 = RTL_R8 (Config5);
|
||||||
|
|
||||||
|
@ -2317,7 +2301,7 @@ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
||||||
if (cfg5 & Cfg5_BWF)
|
if (cfg5 & Cfg5_BWF)
|
||||||
wol->wolopts |= WAKE_BCAST;
|
wol->wolopts |= WAKE_BCAST;
|
||||||
}
|
}
|
||||||
spin_unlock_irq(&np->lock);
|
spin_unlock_irq(&tp->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2326,19 +2310,19 @@ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
||||||
aren't messing with the 8139. */
|
aren't messing with the 8139. */
|
||||||
static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *np = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
void __iomem *ioaddr = np->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
u32 support;
|
u32 support;
|
||||||
u8 cfg3, cfg5;
|
u8 cfg3, cfg5;
|
||||||
|
|
||||||
support = ((rtl_chip_info[np->chipset].flags & HasLWake)
|
support = ((rtl_chip_info[tp->chipset].flags & HasLWake)
|
||||||
? (WAKE_PHY | WAKE_MAGIC
|
? (WAKE_PHY | WAKE_MAGIC
|
||||||
| WAKE_UCAST | WAKE_MCAST | WAKE_BCAST)
|
| WAKE_UCAST | WAKE_MCAST | WAKE_BCAST)
|
||||||
: 0);
|
: 0);
|
||||||
if (wol->wolopts & ~support)
|
if (wol->wolopts & ~support)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
spin_lock_irq(&np->lock);
|
spin_lock_irq(&tp->lock);
|
||||||
cfg3 = RTL_R8 (Config3) & ~(Cfg3_LinkUp | Cfg3_Magic);
|
cfg3 = RTL_R8 (Config3) & ~(Cfg3_LinkUp | Cfg3_Magic);
|
||||||
if (wol->wolopts & WAKE_PHY)
|
if (wol->wolopts & WAKE_PHY)
|
||||||
cfg3 |= Cfg3_LinkUp;
|
cfg3 |= Cfg3_LinkUp;
|
||||||
|
@ -2359,87 +2343,87 @@ static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
||||||
if (wol->wolopts & WAKE_BCAST)
|
if (wol->wolopts & WAKE_BCAST)
|
||||||
cfg5 |= Cfg5_BWF;
|
cfg5 |= Cfg5_BWF;
|
||||||
RTL_W8 (Config5, cfg5); /* need not unlock via Cfg9346 */
|
RTL_W8 (Config5, cfg5); /* need not unlock via Cfg9346 */
|
||||||
spin_unlock_irq(&np->lock);
|
spin_unlock_irq(&tp->lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
|
static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *np = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
strcpy(info->driver, DRV_NAME);
|
strcpy(info->driver, DRV_NAME);
|
||||||
strcpy(info->version, DRV_VERSION);
|
strcpy(info->version, DRV_VERSION);
|
||||||
strcpy(info->bus_info, pci_name(np->pci_dev));
|
strcpy(info->bus_info, pci_name(tp->pci_dev));
|
||||||
info->regdump_len = np->regs_len;
|
info->regdump_len = tp->regs_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtl8139_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
static int rtl8139_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *np = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
spin_lock_irq(&np->lock);
|
spin_lock_irq(&tp->lock);
|
||||||
mii_ethtool_gset(&np->mii, cmd);
|
mii_ethtool_gset(&tp->mii, cmd);
|
||||||
spin_unlock_irq(&np->lock);
|
spin_unlock_irq(&tp->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtl8139_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
static int rtl8139_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *np = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
int rc;
|
int rc;
|
||||||
spin_lock_irq(&np->lock);
|
spin_lock_irq(&tp->lock);
|
||||||
rc = mii_ethtool_sset(&np->mii, cmd);
|
rc = mii_ethtool_sset(&tp->mii, cmd);
|
||||||
spin_unlock_irq(&np->lock);
|
spin_unlock_irq(&tp->lock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtl8139_nway_reset(struct net_device *dev)
|
static int rtl8139_nway_reset(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *np = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
return mii_nway_restart(&np->mii);
|
return mii_nway_restart(&tp->mii);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 rtl8139_get_link(struct net_device *dev)
|
static u32 rtl8139_get_link(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *np = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
return mii_link_ok(&np->mii);
|
return mii_link_ok(&tp->mii);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 rtl8139_get_msglevel(struct net_device *dev)
|
static u32 rtl8139_get_msglevel(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *np = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
return np->msg_enable;
|
return tp->msg_enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
|
static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *np = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
np->msg_enable = datum;
|
tp->msg_enable = datum;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtl8139_get_regs_len(struct net_device *dev)
|
static int rtl8139_get_regs_len(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *np;
|
struct rtl8139_private *tp;
|
||||||
/* TODO: we are too slack to do reg dumping for pio, for now */
|
/* TODO: we are too slack to do reg dumping for pio, for now */
|
||||||
if (use_io)
|
if (use_io)
|
||||||
return 0;
|
return 0;
|
||||||
np = netdev_priv(dev);
|
tp = netdev_priv(dev);
|
||||||
return np->regs_len;
|
return tp->regs_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
|
static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *np;
|
struct rtl8139_private *tp;
|
||||||
|
|
||||||
/* TODO: we are too slack to do reg dumping for pio, for now */
|
/* TODO: we are too slack to do reg dumping for pio, for now */
|
||||||
if (use_io)
|
if (use_io)
|
||||||
return;
|
return;
|
||||||
np = netdev_priv(dev);
|
tp = netdev_priv(dev);
|
||||||
|
|
||||||
regs->version = RTL_REGS_VER;
|
regs->version = RTL_REGS_VER;
|
||||||
|
|
||||||
spin_lock_irq(&np->lock);
|
spin_lock_irq(&tp->lock);
|
||||||
memcpy_fromio(regbuf, np->mmio_addr, regs->len);
|
memcpy_fromio(regbuf, tp->mmio_addr, regs->len);
|
||||||
spin_unlock_irq(&np->lock);
|
spin_unlock_irq(&tp->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtl8139_get_sset_count(struct net_device *dev, int sset)
|
static int rtl8139_get_sset_count(struct net_device *dev, int sset)
|
||||||
|
@ -2454,12 +2438,12 @@ static int rtl8139_get_sset_count(struct net_device *dev, int sset)
|
||||||
|
|
||||||
static void rtl8139_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data)
|
static void rtl8139_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *np = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
|
|
||||||
data[0] = np->xstats.early_rx;
|
data[0] = tp->xstats.early_rx;
|
||||||
data[1] = np->xstats.tx_buf_mapped;
|
data[1] = tp->xstats.tx_buf_mapped;
|
||||||
data[2] = np->xstats.tx_timeouts;
|
data[2] = tp->xstats.tx_timeouts;
|
||||||
data[3] = np->xstats.rx_lost_in_ring;
|
data[3] = tp->xstats.rx_lost_in_ring;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtl8139_get_strings(struct net_device *dev, u32 stringset, u8 *data)
|
static void rtl8139_get_strings(struct net_device *dev, u32 stringset, u8 *data)
|
||||||
|
@ -2486,15 +2470,15 @@ static const struct ethtool_ops rtl8139_ethtool_ops = {
|
||||||
|
|
||||||
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *np = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!netif_running(dev))
|
if (!netif_running(dev))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
spin_lock_irq(&np->lock);
|
spin_lock_irq(&tp->lock);
|
||||||
rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
|
rc = generic_mii_ioctl(&tp->mii, if_mii(rq), cmd, NULL);
|
||||||
spin_unlock_irq(&np->lock);
|
spin_unlock_irq(&tp->lock);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -2527,7 +2511,7 @@ static void __set_rx_mode (struct net_device *dev)
|
||||||
int i, rx_mode;
|
int i, rx_mode;
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
|
||||||
DPRINTK ("%s: rtl8139_set_rx_mode(%4.4x) done -- Rx config %8.8lx.\n",
|
pr_debug("%s: rtl8139_set_rx_mode(%4.4x) done -- Rx config %8.8lx.\n",
|
||||||
dev->name, dev->flags, RTL_R32 (RxConfig));
|
dev->name, dev->flags, RTL_R32 (RxConfig));
|
||||||
|
|
||||||
/* Note: do not reorder, GCC is clever about common statements. */
|
/* Note: do not reorder, GCC is clever about common statements. */
|
||||||
|
@ -2643,7 +2627,7 @@ static int __init rtl8139_init_module (void)
|
||||||
* even if no 8139 board is found.
|
* even if no 8139 board is found.
|
||||||
*/
|
*/
|
||||||
#ifdef MODULE
|
#ifdef MODULE
|
||||||
printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
|
pr_info(RTL8139_DRIVER_NAME "\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return pci_register_driver(&rtl8139_pci_driver);
|
return pci_register_driver(&rtl8139_pci_driver);
|
||||||
|
|
|
@ -122,13 +122,13 @@ static char version[] __initdata =
|
||||||
#define ISCP_BUSY 0x00010000
|
#define ISCP_BUSY 0x00010000
|
||||||
#define MACH_IS_APRICOT 0
|
#define MACH_IS_APRICOT 0
|
||||||
#else
|
#else
|
||||||
#define WSWAPrfd(x) ((struct i596_rfd *)(x))
|
#define WSWAPrfd(x) ((struct i596_rfd *)((long)x))
|
||||||
#define WSWAPrbd(x) ((struct i596_rbd *)(x))
|
#define WSWAPrbd(x) ((struct i596_rbd *)((long)x))
|
||||||
#define WSWAPiscp(x) ((struct i596_iscp *)(x))
|
#define WSWAPiscp(x) ((struct i596_iscp *)((long)x))
|
||||||
#define WSWAPscb(x) ((struct i596_scb *)(x))
|
#define WSWAPscb(x) ((struct i596_scb *)((long)x))
|
||||||
#define WSWAPcmd(x) ((struct i596_cmd *)(x))
|
#define WSWAPcmd(x) ((struct i596_cmd *)((long)x))
|
||||||
#define WSWAPtbd(x) ((struct i596_tbd *)(x))
|
#define WSWAPtbd(x) ((struct i596_tbd *)((long)x))
|
||||||
#define WSWAPchar(x) ((char *)(x))
|
#define WSWAPchar(x) ((char *)((long)x))
|
||||||
#define ISCP_BUSY 0x0001
|
#define ISCP_BUSY 0x0001
|
||||||
#define MACH_IS_APRICOT 1
|
#define MACH_IS_APRICOT 1
|
||||||
#endif
|
#endif
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue