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: (1446 commits)
  macvlan: fix panic if lowerdev in a bond
  tg3: Add braces around 5906 workaround.
  tg3: Fix NETIF_F_LOOPBACK error
  macvlan: remove one synchronize_rcu() call
  networking: NET_CLS_ROUTE4 depends on INET
  irda: Fix error propagation in ircomm_lmp_connect_response()
  irda: Kill set but unused variable 'bytes' in irlan_check_command_param()
  irda: Kill set but unused variable 'clen' in ircomm_connect_indication()
  rxrpc: Fix set but unused variable 'usage' in rxrpc_get_transport()
  be2net: Kill set but unused variable 'req' in lancer_fw_download()
  irda: Kill set but unused vars 'saddr' and 'daddr' in irlan_provider_connect_indication()
  atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined.
  rxrpc: Fix set but unused variable 'usage' in rxrpc_get_peer().
  rxrpc: Kill set but unused variable 'local' in rxrpc_UDP_error_handler()
  rxrpc: Kill set but unused variable 'sp' in rxrpc_process_connection()
  rxrpc: Kill set but unused variable 'sp' in rxrpc_rotate_tx_window()
  pkt_sched: Kill set but unused variable 'protocol' in tc_classify()
  isdn: capi: Use pr_debug() instead of ifdefs.
  tg3: Update version to 3.119
  tg3: Apply rx_discards fix to 5719/5720
  ...

Fix up trivial conflicts in arch/x86/Kconfig and net/mac80211/agg-tx.c
as per Davem.
This commit is contained in:
Linus Torvalds 2011-05-20 13:43:21 -07:00
commit 06f4e926d2
1198 changed files with 127024 additions and 79786 deletions

View File

@ -0,0 +1,31 @@
What: /sys/bus/bcma/devices/.../manuf
Date: May 2011
KernelVersion: 2.6.40
Contact: Rafał Miłecki <zajec5@gmail.com>
Description:
Each BCMA core has it's manufacturer id. See
include/linux/bcma/bcma.h for possible values.
What: /sys/bus/bcma/devices/.../id
Date: May 2011
KernelVersion: 2.6.40
Contact: Rafał Miłecki <zajec5@gmail.com>
Description:
There are a few types of BCMA cores, they can be identified by
id field.
What: /sys/bus/bcma/devices/.../rev
Date: May 2011
KernelVersion: 2.6.40
Contact: Rafał Miłecki <zajec5@gmail.com>
Description:
BCMA cores of the same type can still slightly differ depending
on their revision. Use it for detailed programming.
What: /sys/bus/bcma/devices/.../class
Date: May 2011
KernelVersion: 2.6.40
Contact: Rafał Miłecki <zajec5@gmail.com>
Description:
Each BCMA core is identified by few fields, including class it
belongs to. See include/linux/bcma/bcma.h for possible values.

View File

@ -35,17 +35,6 @@ Who: Luis R. Rodriguez <lrodriguez@atheros.com>
--------------------------- ---------------------------
What: AR9170USB
When: 2.6.40
Why: This driver is deprecated and the firmware is no longer
maintained. The replacement driver "carl9170" has been
around for a while, so the devices are still supported.
Who: Christian Lamparter <chunkeey@googlemail.com>
---------------------------
What: IRQF_SAMPLE_RANDOM What: IRQF_SAMPLE_RANDOM
Check: IRQF_SAMPLE_RANDOM Check: IRQF_SAMPLE_RANDOM
When: July 2009 When: July 2009
@ -405,16 +394,6 @@ Who: anybody or Florian Mickler <florian@mickler.org>
---------------------------- ----------------------------
What: capifs
When: February 2011
Files: drivers/isdn/capi/capifs.*
Why: udev fully replaces this special file system that only contains CAPI
NCCI TTY device nodes. User space (pppdcapiplugin) works without
noticing the difference.
Who: Jan Kiszka <jan.kiszka@web.de>
----------------------------
What: KVM paravirt mmu host support What: KVM paravirt mmu host support
When: January 2011 When: January 2011
Why: The paravirt mmu host support is slower than non-paravirt mmu, both Why: The paravirt mmu host support is slower than non-paravirt mmu, both

View File

@ -1,4 +1,4 @@
[state: 27-01-2011] [state: 17-04-2011]
BATMAN-ADV BATMAN-ADV
---------- ----------
@ -19,6 +19,7 @@ duce the overhead to a minimum. It does not depend on any (other)
network driver, and can be used on wifi as well as ethernet lan, network driver, and can be used on wifi as well as ethernet lan,
vpn, etc ... (anything with ethernet-style layer 2). vpn, etc ... (anything with ethernet-style layer 2).
CONFIGURATION CONFIGURATION
------------- -------------
@ -160,13 +161,13 @@ face. Each entry can/has to have the following values:
-> "TQ mac value" - src mac's link quality towards mac address -> "TQ mac value" - src mac's link quality towards mac address
of a neighbor originator's interface which of a neighbor originator's interface which
is being used for routing is being used for routing
-> "HNA mac" - HNA announced by source mac -> "TT mac" - TT announced by source mac
-> "PRIMARY" - this is a primary interface -> "PRIMARY" - this is a primary interface
-> "SEC mac" - secondary mac address of source -> "SEC mac" - secondary mac address of source
(requires preceding PRIMARY) (requires preceding PRIMARY)
The TQ value has a range from 4 to 255 with 255 being the best. The TQ value has a range from 4 to 255 with 255 being the best.
The HNA entries are showing which hosts are connected to the mesh The TT entries are showing which hosts are connected to the mesh
via bat0 or being bridged into the mesh network. The PRIMARY/SEC via bat0 or being bridged into the mesh network. The PRIMARY/SEC
values are only applied on primary interfaces values are only applied on primary interfaces
@ -199,7 +200,7 @@ abled during run time. Following log_levels are defined:
0 - All debug output disabled 0 - All debug output disabled
1 - Enable messages related to routing / flooding / broadcasting 1 - Enable messages related to routing / flooding / broadcasting
2 - Enable route or hna added / changed / deleted 2 - Enable route or tt entry added / changed / deleted
3 - Enable all messages 3 - Enable all messages
The debug output can be changed at runtime using the file The debug output can be changed at runtime using the file
@ -207,7 +208,7 @@ The debug output can be changed at runtime using the file
# echo 2 > /sys/class/net/bat0/mesh/log_level # echo 2 > /sys/class/net/bat0/mesh/log_level
will enable debug messages for when routes or HNAs change. will enable debug messages for when routes or TTs change.
BATCTL BATCTL

View File

@ -1,7 +1,7 @@
Linux Ethernet Bonding Driver HOWTO Linux Ethernet Bonding Driver HOWTO
Latest update: 23 September 2009 Latest update: 27 April 2011
Initial release : Thomas Davis <tadavis at lbl.gov> Initial release : Thomas Davis <tadavis at lbl.gov>
Corrections, HA extensions : 2000/10/03-15 : Corrections, HA extensions : 2000/10/03-15 :
@ -585,25 +585,23 @@ mode
chosen. chosen.
num_grat_arp num_grat_arp
Specifies the number of gratuitous ARPs to be issued after a
failover event. One gratuitous ARP is issued immediately after
the failover, subsequent ARPs are sent at a rate of one per link
monitor interval (arp_interval or miimon, whichever is active).
The valid range is 0 - 255; the default value is 1. This option
affects only the active-backup mode. This option was added for
bonding version 3.3.0.
num_unsol_na num_unsol_na
Specifies the number of unsolicited IPv6 Neighbor Advertisements Specify the number of peer notifications (gratuitous ARPs and
to be issued after a failover event. One unsolicited NA is issued unsolicited IPv6 Neighbor Advertisements) to be issued after a
immediately after the failover. failover event. As soon as the link is up on the new slave
(possibly immediately) a peer notification is sent on the
bonding device and each VLAN sub-device. This is repeated at
each link monitor interval (arp_interval or miimon, whichever
is active) if the number is greater than 1.
The valid range is 0 - 255; the default value is 1. This option The valid range is 0 - 255; the default value is 1. These options
affects only the active-backup mode. This option was added for affect only the active-backup mode. These options were added for
bonding version 3.4.0. bonding versions 3.3.0 and 3.4.0 respectively.
From Linux 2.6.40 and bonding version 3.7.1, these notifications
are generated by the ipv4 and ipv6 code and the numbers of
repetitions cannot be set independently.
primary primary

View File

@ -93,6 +93,19 @@ Additional Configurations
REQUIREMENTS: MSI-X support is required for Multiqueue. If MSI-X is not REQUIREMENTS: MSI-X support is required for Multiqueue. If MSI-X is not
found, the system will fallback to MSI or to Legacy interrupts. found, the system will fallback to MSI or to Legacy interrupts.
MAC and VLAN anti-spoofing feature
----------------------------------
When a malicious driver attempts to send a spoofed packet, it is dropped by
the hardware and not transmitted. An interrupt is sent to the PF driver
notifying it of the spoof attempt.
When a spoofed packet is detected the PF driver will send the following
message to the system log (displayed by the "dmesg" command):
Spoof event(s) detected on VF(n)
Where n=the VF that attempted to do the spoofing.
Support Support
======= =======

View File

@ -32,6 +32,17 @@ Table : Subdirectories in /proc/sys/net
1. /proc/sys/net/core - Network core options 1. /proc/sys/net/core - Network core options
------------------------------------------------------- -------------------------------------------------------
bpf_jit_enable
--------------
This enables Berkeley Packet Filter Just in Time compiler.
Currently supported on x86_64 architecture, bpf_jit provides a framework
to speed packet filtering, the one used by tcpdump/libpcap for example.
Values :
0 - disable the JIT (default value)
1 - enable the JIT
2 - enable the JIT and ask the compiler to emit traces on kernel log.
rmem_default rmem_default
------------ ------------

View File

@ -1232,13 +1232,6 @@ W: http://wireless.kernel.org/en/users/Drivers/ath9k
S: Supported S: Supported
F: drivers/net/wireless/ath/ath9k/ F: drivers/net/wireless/ath/ath9k/
ATHEROS AR9170 WIRELESS DRIVER
M: Christian Lamparter <chunkeey@web.de>
L: linux-wireless@vger.kernel.org
W: http://wireless.kernel.org/en/users/Drivers/ar9170
S: Obsolete
F: drivers/net/wireless/ath/ar9170/
CARL9170 LINUX COMMUNITY WIRELESS DRIVER CARL9170 LINUX COMMUNITY WIRELESS DRIVER
M: Christian Lamparter <chunkeey@googlemail.com> M: Christian Lamparter <chunkeey@googlemail.com>
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
@ -3363,6 +3356,12 @@ F: Documentation/wimax/README.i2400m
F: drivers/net/wimax/i2400m/ F: drivers/net/wimax/i2400m/
F: include/linux/wimax/i2400m.h F: include/linux/wimax/i2400m.h
INTEL WIRELESS 3945ABG/BG, 4965AGN (iwlegacy)
M: Stanislaw Gruszka <sgruszka@redhat.com>
L: linux-wireless@vger.kernel.org
S: Supported
F: drivers/net/wireless/iwlegacy/
INTEL WIRELESS WIFI LINK (iwlwifi) INTEL WIRELESS WIFI LINK (iwlwifi)
M: Wey-Yi Guy <wey-yi.w.guy@intel.com> M: Wey-Yi Guy <wey-yi.w.guy@intel.com>
M: Intel Linux Wireless <ilw@linux.intel.com> M: Intel Linux Wireless <ilw@linux.intel.com>
@ -4385,6 +4384,7 @@ S: Maintained
F: net/ipv4/ F: net/ipv4/
F: net/ipv6/ F: net/ipv6/
F: include/net/ip* F: include/net/ip*
F: arch/x86/net/*
NETWORKING [LABELED] (NetLabel, CIPSO, Labeled IPsec, SECMARK) NETWORKING [LABELED] (NetLabel, CIPSO, Labeled IPsec, SECMARK)
M: Paul Moore <paul.moore@hp.com> M: Paul Moore <paul.moore@hp.com>
@ -5832,6 +5832,13 @@ S: Maintained
F: drivers/ssb/ F: drivers/ssb/
F: include/linux/ssb/ F: include/linux/ssb/
BROADCOM SPECIFIC AMBA DRIVER (BCMA)
M: Rafał Miłecki <zajec5@gmail.com>
L: linux-wireless@vger.kernel.org
S: Maintained
F: drivers/bcma/
F: include/linux/bcma/
SONY VAIO CONTROL DEVICE DRIVER SONY VAIO CONTROL DEVICE DRIVER
M: Mattia Dongili <malattia@linux.it> M: Mattia Dongili <malattia@linux.it>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org

View File

@ -318,19 +318,15 @@ void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask)
} }
#if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE) #if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE)
static int tx4939_get_eth_speed(struct net_device *dev) static u32 tx4939_get_eth_speed(struct net_device *dev)
{ {
struct ethtool_cmd cmd = { ETHTOOL_GSET }; struct ethtool_cmd cmd;
int speed = 100; /* default 100Mbps */ if (dev_ethtool_get_settings(dev, &cmd))
int err; return 100; /* default 100Mbps */
if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
return speed; return ethtool_cmd_speed(&cmd);
err = dev->ethtool_ops->get_settings(dev, &cmd);
if (err < 0)
return speed;
speed = cmd.speed == SPEED_100 ? 100 : 10;
return speed;
} }
static int tx4939_netdev_event(struct notifier_block *this, static int tx4939_netdev_event(struct notifier_block *this,
unsigned long event, unsigned long event,
void *ptr) void *ptr)
@ -343,8 +339,7 @@ static int tx4939_netdev_event(struct notifier_block *this,
else if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(1)) else if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(1))
bit = TX4939_PCFG_SPEED1; bit = TX4939_PCFG_SPEED1;
if (bit) { if (bit) {
int speed = tx4939_get_eth_speed(dev); if (tx4939_get_eth_speed(dev) == 100)
if (speed == 100)
txx9_set64(&tx4939_ccfgptr->pcfg, bit); txx9_set64(&tx4939_ccfgptr->pcfg, bit);
else else
txx9_clear64(&tx4939_ccfgptr->pcfg, bit); txx9_clear64(&tx4939_ccfgptr->pcfg, bit);

View File

@ -352,3 +352,4 @@ SYSCALL_SPU(name_to_handle_at)
COMPAT_SYS_SPU(open_by_handle_at) COMPAT_SYS_SPU(open_by_handle_at)
COMPAT_SYS_SPU(clock_adjtime) COMPAT_SYS_SPU(clock_adjtime)
SYSCALL_SPU(syncfs) SYSCALL_SPU(syncfs)
COMPAT_SYS_SPU(sendmmsg)

View File

@ -371,10 +371,11 @@
#define __NR_open_by_handle_at 346 #define __NR_open_by_handle_at 346
#define __NR_clock_adjtime 347 #define __NR_clock_adjtime 347
#define __NR_syncfs 348 #define __NR_syncfs 348
#define __NR_sendmmsg 349
#ifdef __KERNEL__ #ifdef __KERNEL__
#define __NR_syscalls 349 #define __NR_syscalls 350
#define __NR__exit __NR_exit #define __NR__exit __NR_exit
#define NR_syscalls __NR_syscalls #define NR_syscalls __NR_syscalls

View File

@ -404,8 +404,9 @@
#define __NR_open_by_handle_at 333 #define __NR_open_by_handle_at 333
#define __NR_clock_adjtime 334 #define __NR_clock_adjtime 334
#define __NR_syncfs 335 #define __NR_syncfs 335
#define __NR_sendmmsg 336
#define NR_syscalls 336 #define NR_syscalls 337
#ifdef __32bit_syscall_numbers__ #ifdef __32bit_syscall_numbers__
/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,

View File

@ -84,4 +84,4 @@ sys_call_table:
/*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv /*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
/*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
/*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
/*335*/ .long sys_syncfs /*335*/ .long sys_syncfs, sys_sendmmsg

View File

@ -85,7 +85,7 @@ sys_call_table32:
/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv
.word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init
/*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime
.word sys_syncfs .word sys_syncfs, compat_sys_sendmmsg
#endif /* CONFIG_COMPAT */ #endif /* CONFIG_COMPAT */
@ -162,4 +162,4 @@ sys_call_table:
/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
.word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
/*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
.word sys_syncfs .word sys_syncfs, sys_sendmmsg

View File

@ -15,3 +15,4 @@ obj-y += vdso/
obj-$(CONFIG_IA32_EMULATION) += ia32/ obj-$(CONFIG_IA32_EMULATION) += ia32/
obj-y += platform/ obj-y += platform/
obj-y += net/

View File

@ -72,6 +72,7 @@ config X86
select GENERIC_IRQ_SHOW select GENERIC_IRQ_SHOW
select IRQ_FORCED_THREADING select IRQ_FORCED_THREADING
select USE_GENERIC_SMP_HELPERS if SMP select USE_GENERIC_SMP_HELPERS if SMP
select HAVE_BPF_JIT if (X86_64 && NET)
config INSTRUCTION_DECODER config INSTRUCTION_DECODER
def_bool (KPROBES || PERF_EVENTS) def_bool (KPROBES || PERF_EVENTS)

View File

@ -848,4 +848,5 @@ ia32_sys_call_table:
.quad compat_sys_open_by_handle_at .quad compat_sys_open_by_handle_at
.quad compat_sys_clock_adjtime .quad compat_sys_clock_adjtime
.quad sys_syncfs .quad sys_syncfs
.quad compat_sys_sendmmsg /* 345 */
ia32_syscall_end: ia32_syscall_end:

View File

@ -350,10 +350,11 @@
#define __NR_open_by_handle_at 342 #define __NR_open_by_handle_at 342
#define __NR_clock_adjtime 343 #define __NR_clock_adjtime 343
#define __NR_syncfs 344 #define __NR_syncfs 344
#define __NR_sendmmsg 345
#ifdef __KERNEL__ #ifdef __KERNEL__
#define NR_syscalls 345 #define NR_syscalls 346
#define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_READDIR

View File

@ -677,6 +677,8 @@ __SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at)
__SYSCALL(__NR_clock_adjtime, sys_clock_adjtime) __SYSCALL(__NR_clock_adjtime, sys_clock_adjtime)
#define __NR_syncfs 306 #define __NR_syncfs 306
__SYSCALL(__NR_syncfs, sys_syncfs) __SYSCALL(__NR_syncfs, sys_syncfs)
#define __NR_sendmmsg 307
__SYSCALL(__NR_sendmmsg, sys_sendmmsg)
#ifndef __NO_STUBS #ifndef __NO_STUBS
#define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_READDIR

View File

@ -344,3 +344,4 @@ ENTRY(sys_call_table)
.long sys_open_by_handle_at .long sys_open_by_handle_at
.long sys_clock_adjtime .long sys_clock_adjtime
.long sys_syncfs .long sys_syncfs
.long sys_sendmmsg /* 345 */

4
arch/x86/net/Makefile Normal file
View File

@ -0,0 +1,4 @@
#
# Arch-specific network modules
#
obj-$(CONFIG_BPF_JIT) += bpf_jit.o bpf_jit_comp.o

140
arch/x86/net/bpf_jit.S Normal file
View File

@ -0,0 +1,140 @@
/* bpf_jit.S : BPF JIT helper functions
*
* Copyright (C) 2011 Eric Dumazet (eric.dumazet@gmail.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/linkage.h>
#include <asm/dwarf2.h>
/*
* Calling convention :
* rdi : skb pointer
* esi : offset of byte(s) to fetch in skb (can be scratched)
* r8 : copy of skb->data
* r9d : hlen = skb->len - skb->data_len
*/
#define SKBDATA %r8
sk_load_word_ind:
.globl sk_load_word_ind
add %ebx,%esi /* offset += X */
# test %esi,%esi /* if (offset < 0) goto bpf_error; */
js bpf_error
sk_load_word:
.globl sk_load_word
mov %r9d,%eax # hlen
sub %esi,%eax # hlen - offset
cmp $3,%eax
jle bpf_slow_path_word
mov (SKBDATA,%rsi),%eax
bswap %eax /* ntohl() */
ret
sk_load_half_ind:
.globl sk_load_half_ind
add %ebx,%esi /* offset += X */
js bpf_error
sk_load_half:
.globl sk_load_half
mov %r9d,%eax
sub %esi,%eax # hlen - offset
cmp $1,%eax
jle bpf_slow_path_half
movzwl (SKBDATA,%rsi),%eax
rol $8,%ax # ntohs()
ret
sk_load_byte_ind:
.globl sk_load_byte_ind
add %ebx,%esi /* offset += X */
js bpf_error
sk_load_byte:
.globl sk_load_byte
cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte */
jle bpf_slow_path_byte
movzbl (SKBDATA,%rsi),%eax
ret
/**
* sk_load_byte_msh - BPF_S_LDX_B_MSH helper
*
* Implements BPF_S_LDX_B_MSH : ldxb 4*([offset]&0xf)
* Must preserve A accumulator (%eax)
* Inputs : %esi is the offset value, already known positive
*/
ENTRY(sk_load_byte_msh)
CFI_STARTPROC
cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte_msh */
jle bpf_slow_path_byte_msh
movzbl (SKBDATA,%rsi),%ebx
and $15,%bl
shl $2,%bl
ret
CFI_ENDPROC
ENDPROC(sk_load_byte_msh)
bpf_error:
# force a return 0 from jit handler
xor %eax,%eax
mov -8(%rbp),%rbx
leaveq
ret
/* rsi contains offset and can be scratched */
#define bpf_slow_path_common(LEN) \
push %rdi; /* save skb */ \
push %r9; \
push SKBDATA; \
/* rsi already has offset */ \
mov $LEN,%ecx; /* len */ \
lea -12(%rbp),%rdx; \
call skb_copy_bits; \
test %eax,%eax; \
pop SKBDATA; \
pop %r9; \
pop %rdi
bpf_slow_path_word:
bpf_slow_path_common(4)
js bpf_error
mov -12(%rbp),%eax
bswap %eax
ret
bpf_slow_path_half:
bpf_slow_path_common(2)
js bpf_error
mov -12(%rbp),%ax
rol $8,%ax
movzwl %ax,%eax
ret
bpf_slow_path_byte:
bpf_slow_path_common(1)
js bpf_error
movzbl -12(%rbp),%eax
ret
bpf_slow_path_byte_msh:
xchg %eax,%ebx /* dont lose A , X is about to be scratched */
bpf_slow_path_common(1)
js bpf_error
movzbl -12(%rbp),%eax
and $15,%al
shl $2,%al
xchg %eax,%ebx
ret

654
arch/x86/net/bpf_jit_comp.c Normal file
View File

@ -0,0 +1,654 @@
/* bpf_jit_comp.c : BPF JIT compiler
*
* Copyright (C) 2011 Eric Dumazet (eric.dumazet@gmail.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/moduleloader.h>
#include <asm/cacheflush.h>
#include <linux/netdevice.h>
#include <linux/filter.h>
/*
* Conventions :
* EAX : BPF A accumulator
* EBX : BPF X accumulator
* RDI : pointer to skb (first argument given to JIT function)
* RBP : frame pointer (even if CONFIG_FRAME_POINTER=n)
* ECX,EDX,ESI : scratch registers
* r9d : skb->len - skb->data_len (headlen)
* r8 : skb->data
* -8(RBP) : saved RBX value
* -16(RBP)..-80(RBP) : BPF_MEMWORDS values
*/
int bpf_jit_enable __read_mostly;
/*
* assembly code in arch/x86/net/bpf_jit.S
*/
extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[];
extern u8 sk_load_word_ind[], sk_load_half_ind[], sk_load_byte_ind[];
static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
{
if (len == 1)
*ptr = bytes;
else if (len == 2)
*(u16 *)ptr = bytes;
else {
*(u32 *)ptr = bytes;
barrier();
}
return ptr + len;
}
#define EMIT(bytes, len) do { prog = emit_code(prog, bytes, len); } while (0)
#define EMIT1(b1) EMIT(b1, 1)
#define EMIT2(b1, b2) EMIT((b1) + ((b2) << 8), 2)
#define EMIT3(b1, b2, b3) EMIT((b1) + ((b2) << 8) + ((b3) << 16), 3)
#define EMIT4(b1, b2, b3, b4) EMIT((b1) + ((b2) << 8) + ((b3) << 16) + ((b4) << 24), 4)
#define EMIT1_off32(b1, off) do { EMIT1(b1); EMIT(off, 4);} while (0)
#define CLEAR_A() EMIT2(0x31, 0xc0) /* xor %eax,%eax */
#define CLEAR_X() EMIT2(0x31, 0xdb) /* xor %ebx,%ebx */
static inline bool is_imm8(int value)
{
return value <= 127 && value >= -128;
}
static inline bool is_near(int offset)
{
return offset <= 127 && offset >= -128;
}
#define EMIT_JMP(offset) \
do { \
if (offset) { \
if (is_near(offset)) \
EMIT2(0xeb, offset); /* jmp .+off8 */ \
else \
EMIT1_off32(0xe9, offset); /* jmp .+off32 */ \
} \
} while (0)
/* list of x86 cond jumps opcodes (. + s8)
* Add 0x10 (and an extra 0x0f) to generate far jumps (. + s32)
*/
#define X86_JB 0x72
#define X86_JAE 0x73
#define X86_JE 0x74
#define X86_JNE 0x75
#define X86_JBE 0x76
#define X86_JA 0x77
#define EMIT_COND_JMP(op, offset) \
do { \
if (is_near(offset)) \
EMIT2(op, offset); /* jxx .+off8 */ \
else { \
EMIT2(0x0f, op + 0x10); \
EMIT(offset, 4); /* jxx .+off32 */ \
} \
} while (0)
#define COND_SEL(CODE, TOP, FOP) \
case CODE: \
t_op = TOP; \
f_op = FOP; \
goto cond_branch
#define SEEN_DATAREF 1 /* might call external helpers */
#define SEEN_XREG 2 /* ebx is used */
#define SEEN_MEM 4 /* use mem[] for temporary storage */
static inline void bpf_flush_icache(void *start, void *end)
{
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
smp_wmb();
flush_icache_range((unsigned long)start, (unsigned long)end);
set_fs(old_fs);
}
void bpf_jit_compile(struct sk_filter *fp)
{
u8 temp[64];
u8 *prog;
unsigned int proglen, oldproglen = 0;
int ilen, i;
int t_offset, f_offset;
u8 t_op, f_op, seen = 0, pass;
u8 *image = NULL;
u8 *func;
int pc_ret0 = -1; /* bpf index of first RET #0 instruction (if any) */
unsigned int cleanup_addr; /* epilogue code offset */
unsigned int *addrs;
const struct sock_filter *filter = fp->insns;
int flen = fp->len;
if (!bpf_jit_enable)
return;
addrs = kmalloc(flen * sizeof(*addrs), GFP_KERNEL);
if (addrs == NULL)
return;
/* Before first pass, make a rough estimation of addrs[]
* each bpf instruction is translated to less than 64 bytes
*/
for (proglen = 0, i = 0; i < flen; i++) {
proglen += 64;
addrs[i] = proglen;
}
cleanup_addr = proglen; /* epilogue address */
for (pass = 0; pass < 10; pass++) {
/* no prologue/epilogue for trivial filters (RET something) */
proglen = 0;
prog = temp;
if (seen) {
EMIT4(0x55, 0x48, 0x89, 0xe5); /* push %rbp; mov %rsp,%rbp */
EMIT4(0x48, 0x83, 0xec, 96); /* subq $96,%rsp */
/* note : must save %rbx in case bpf_error is hit */
if (seen & (SEEN_XREG | SEEN_DATAREF))
EMIT4(0x48, 0x89, 0x5d, 0xf8); /* mov %rbx, -8(%rbp) */
if (seen & SEEN_XREG)
CLEAR_X(); /* make sure we dont leek kernel memory */
/*
* If this filter needs to access skb data,
* loads r9 and r8 with :
* r9 = skb->len - skb->data_len
* r8 = skb->data
*/
if (seen & SEEN_DATAREF) {
if (offsetof(struct sk_buff, len) <= 127)
/* mov off8(%rdi),%r9d */
EMIT4(0x44, 0x8b, 0x4f, offsetof(struct sk_buff, len));
else {
/* mov off32(%rdi),%r9d */
EMIT3(0x44, 0x8b, 0x8f);
EMIT(offsetof(struct sk_buff, len), 4);
}
if (is_imm8(offsetof(struct sk_buff, data_len)))
/* sub off8(%rdi),%r9d */
EMIT4(0x44, 0x2b, 0x4f, offsetof(struct sk_buff, data_len));
else {
EMIT3(0x44, 0x2b, 0x8f);
EMIT(offsetof(struct sk_buff, data_len), 4);
}
if (is_imm8(offsetof(struct sk_buff, data)))
/* mov off8(%rdi),%r8 */
EMIT4(0x4c, 0x8b, 0x47, offsetof(struct sk_buff, data));
else {
/* mov off32(%rdi),%r8 */
EMIT3(0x4c, 0x8b, 0x87);
EMIT(offsetof(struct sk_buff, data), 4);
}
}
}
switch (filter[0].code) {
case BPF_S_RET_K:
case BPF_S_LD_W_LEN:
case BPF_S_ANC_PROTOCOL:
case BPF_S_ANC_IFINDEX:
case BPF_S_ANC_MARK:
case BPF_S_ANC_RXHASH:
case BPF_S_ANC_CPU:
case BPF_S_ANC_QUEUE:
case BPF_S_LD_W_ABS:
case BPF_S_LD_H_ABS:
case BPF_S_LD_B_ABS:
/* first instruction sets A register (or is RET 'constant') */
break;
default:
/* make sure we dont leak kernel information to user */
CLEAR_A(); /* A = 0 */
}
for (i = 0; i < flen; i++) {
unsigned int K = filter[i].k;
switch (filter[i].code) {
case BPF_S_ALU_ADD_X: /* A += X; */
seen |= SEEN_XREG;
EMIT2(0x01, 0xd8); /* add %ebx,%eax */
break;
case BPF_S_ALU_ADD_K: /* A += K; */
if (!K)
break;
if (is_imm8(K))
EMIT3(0x83, 0xc0, K); /* add imm8,%eax */
else
EMIT1_off32(0x05, K); /* add imm32,%eax */
break;
case BPF_S_ALU_SUB_X: /* A -= X; */
seen |= SEEN_XREG;
EMIT2(0x29, 0xd8); /* sub %ebx,%eax */
break;
case BPF_S_ALU_SUB_K: /* A -= K */
if (!K)
break;
if (is_imm8(K))
EMIT3(0x83, 0xe8, K); /* sub imm8,%eax */
else
EMIT1_off32(0x2d, K); /* sub imm32,%eax */
break;
case BPF_S_ALU_MUL_X: /* A *= X; */
seen |= SEEN_XREG;
EMIT3(0x0f, 0xaf, 0xc3); /* imul %ebx,%eax */
break;
case BPF_S_ALU_MUL_K: /* A *= K */
if (is_imm8(K))
EMIT3(0x6b, 0xc0, K); /* imul imm8,%eax,%eax */
else {
EMIT2(0x69, 0xc0); /* imul imm32,%eax */
EMIT(K, 4);
}
break;
case BPF_S_ALU_DIV_X: /* A /= X; */
seen |= SEEN_XREG;
EMIT2(0x85, 0xdb); /* test %ebx,%ebx */
if (pc_ret0 != -1)
EMIT_COND_JMP(X86_JE, addrs[pc_ret0] - (addrs[i] - 4));
else {
EMIT_COND_JMP(X86_JNE, 2 + 5);
CLEAR_A();
EMIT1_off32(0xe9, cleanup_addr - (addrs[i] - 4)); /* jmp .+off32 */
}
EMIT4(0x31, 0xd2, 0xf7, 0xf3); /* xor %edx,%edx; div %ebx */
break;
case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */
EMIT3(0x48, 0x69, 0xc0); /* imul imm32,%rax,%rax */
EMIT(K, 4);
EMIT4(0x48, 0xc1, 0xe8, 0x20); /* shr $0x20,%rax */
break;
case BPF_S_ALU_AND_X:
seen |= SEEN_XREG;
EMIT2(0x21, 0xd8); /* and %ebx,%eax */
break;
case BPF_S_ALU_AND_K:
if (K >= 0xFFFFFF00) {
EMIT2(0x24, K & 0xFF); /* and imm8,%al */
} else if (K >= 0xFFFF0000) {
EMIT2(0x66, 0x25); /* and imm16,%ax */
EMIT2(K, 2);
} else {
EMIT1_off32(0x25, K); /* and imm32,%eax */
}
break;
case BPF_S_ALU_OR_X:
seen |= SEEN_XREG;
EMIT2(0x09, 0xd8); /* or %ebx,%eax */
break;
case BPF_S_ALU_OR_K:
if (is_imm8(K))
EMIT3(0x83, 0xc8, K); /* or imm8,%eax */
else
EMIT1_off32(0x0d, K); /* or imm32,%eax */
break;
case BPF_S_ALU_LSH_X: /* A <<= X; */
seen |= SEEN_XREG;
EMIT4(0x89, 0xd9, 0xd3, 0xe0); /* mov %ebx,%ecx; shl %cl,%eax */
break;
case BPF_S_ALU_LSH_K:
if (K == 0)
break;
else if (K == 1)
EMIT2(0xd1, 0xe0); /* shl %eax */
else
EMIT3(0xc1, 0xe0, K);
break;
case BPF_S_ALU_RSH_X: /* A >>= X; */
seen |= SEEN_XREG;
EMIT4(0x89, 0xd9, 0xd3, 0xe8); /* mov %ebx,%ecx; shr %cl,%eax */
break;
case BPF_S_ALU_RSH_K: /* A >>= K; */
if (K == 0)
break;
else if (K == 1)
EMIT2(0xd1, 0xe8); /* shr %eax */
else
EMIT3(0xc1, 0xe8, K);
break;
case BPF_S_ALU_NEG:
EMIT2(0xf7, 0xd8); /* neg %eax */
break;
case BPF_S_RET_K:
if (!K) {
if (pc_ret0 == -1)
pc_ret0 = i;
CLEAR_A();
} else {
EMIT1_off32(0xb8, K); /* mov $imm32,%eax */
}
/* fallinto */
case BPF_S_RET_A:
if (seen) {
if (i != flen - 1) {
EMIT_JMP(cleanup_addr - addrs[i]);
break;
}
if (seen & SEEN_XREG)
EMIT4(0x48, 0x8b, 0x5d, 0xf8); /* mov -8(%rbp),%rbx */
EMIT1(0xc9); /* leaveq */
}
EMIT1(0xc3); /* ret */
break;
case BPF_S_MISC_TAX: /* X = A */
seen |= SEEN_XREG;
EMIT2(0x89, 0xc3); /* mov %eax,%ebx */
break;
case BPF_S_MISC_TXA: /* A = X */
seen |= SEEN_XREG;
EMIT2(0x89, 0xd8); /* mov %ebx,%eax */
break;
case BPF_S_LD_IMM: /* A = K */
if (!K)
CLEAR_A();
else
EMIT1_off32(0xb8, K); /* mov $imm32,%eax */
break;
case BPF_S_LDX_IMM: /* X = K */
seen |= SEEN_XREG;
if (!K)
CLEAR_X();
else
EMIT1_off32(0xbb, K); /* mov $imm32,%ebx */
break;
case BPF_S_LD_MEM: /* A = mem[K] : mov off8(%rbp),%eax */
seen |= SEEN_MEM;
EMIT3(0x8b, 0x45, 0xf0 - K*4);
break;
case BPF_S_LDX_MEM: /* X = mem[K] : mov off8(%rbp),%ebx */
seen |= SEEN_XREG | SEEN_MEM;
EMIT3(0x8b, 0x5d, 0xf0 - K*4);
break;
case BPF_S_ST: /* mem[K] = A : mov %eax,off8(%rbp) */
seen |= SEEN_MEM;
EMIT3(0x89, 0x45, 0xf0 - K*4);
break;
case BPF_S_STX: /* mem[K] = X : mov %ebx,off8(%rbp) */
seen |= SEEN_XREG | SEEN_MEM;
EMIT3(0x89, 0x5d, 0xf0 - K*4);
break;
case BPF_S_LD_W_LEN: /* A = skb->len; */
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
if (is_imm8(offsetof(struct sk_buff, len)))
/* mov off8(%rdi),%eax */
EMIT3(0x8b, 0x47, offsetof(struct sk_buff, len));
else {
EMIT2(0x8b, 0x87);
EMIT(offsetof(struct sk_buff, len), 4);
}
break;
case BPF_S_LDX_W_LEN: /* X = skb->len; */
seen |= SEEN_XREG;
if (is_imm8(offsetof(struct sk_buff, len)))
/* mov off8(%rdi),%ebx */
EMIT3(0x8b, 0x5f, offsetof(struct sk_buff, len));
else {
EMIT2(0x8b, 0x9f);
EMIT(offsetof(struct sk_buff, len), 4);
}
break;
case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol); */
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, protocol) != 2);
if (is_imm8(offsetof(struct sk_buff, protocol))) {
/* movzwl off8(%rdi),%eax */
EMIT4(0x0f, 0xb7, 0x47, offsetof(struct sk_buff, protocol));
} else {
EMIT3(0x0f, 0xb7, 0x87); /* movzwl off32(%rdi),%eax */
EMIT(offsetof(struct sk_buff, protocol), 4);
}
EMIT2(0x86, 0xc4); /* ntohs() : xchg %al,%ah */
break;
case BPF_S_ANC_IFINDEX:
if (is_imm8(offsetof(struct sk_buff, dev))) {
/* movq off8(%rdi),%rax */
EMIT4(0x48, 0x8b, 0x47, offsetof(struct sk_buff, dev));
} else {
EMIT3(0x48, 0x8b, 0x87); /* movq off32(%rdi),%rax */
EMIT(offsetof(struct sk_buff, dev), 4);
}
EMIT3(0x48, 0x85, 0xc0); /* test %rax,%rax */
EMIT_COND_JMP(X86_JE, cleanup_addr - (addrs[i] - 6));
BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, ifindex) != 4);
EMIT2(0x8b, 0x80); /* mov off32(%rax),%eax */
EMIT(offsetof(struct net_device, ifindex), 4);
break;
case BPF_S_ANC_MARK:
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
if (is_imm8(offsetof(struct sk_buff, mark))) {
/* mov off8(%rdi),%eax */
EMIT3(0x8b, 0x47, offsetof(struct sk_buff, mark));
} else {
EMIT2(0x8b, 0x87);
EMIT(offsetof(struct sk_buff, mark), 4);
}
break;
case BPF_S_ANC_RXHASH:
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4);
if (is_imm8(offsetof(struct sk_buff, rxhash))) {
/* mov off8(%rdi),%eax */
EMIT3(0x8b, 0x47, offsetof(struct sk_buff, rxhash));
} else {
EMIT2(0x8b, 0x87);
EMIT(offsetof(struct sk_buff, rxhash), 4);
}
break;
case BPF_S_ANC_QUEUE:
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, queue_mapping) != 2);
if (is_imm8(offsetof(struct sk_buff, queue_mapping))) {
/* movzwl off8(%rdi),%eax */
EMIT4(0x0f, 0xb7, 0x47, offsetof(struct sk_buff, queue_mapping));
} else {
EMIT3(0x0f, 0xb7, 0x87); /* movzwl off32(%rdi),%eax */
EMIT(offsetof(struct sk_buff, queue_mapping), 4);
}
break;
case BPF_S_ANC_CPU:
#ifdef CONFIG_SMP
EMIT4(0x65, 0x8b, 0x04, 0x25); /* mov %gs:off32,%eax */
EMIT((u32)(unsigned long)&cpu_number, 4); /* A = smp_processor_id(); */
#else
CLEAR_A();
#endif
break;
case BPF_S_LD_W_ABS:
func = sk_load_word;
common_load: seen |= SEEN_DATAREF;
if ((int)K < 0)
goto out;
t_offset = func - (image + addrs[i]);
EMIT1_off32(0xbe, K); /* mov imm32,%esi */
EMIT1_off32(0xe8, t_offset); /* call */
break;
case BPF_S_LD_H_ABS:
func = sk_load_half;
goto common_load;
case BPF_S_LD_B_ABS:
func = sk_load_byte;
goto common_load;
case BPF_S_LDX_B_MSH:
if ((int)K < 0) {
if (pc_ret0 != -1) {
EMIT_JMP(addrs[pc_ret0] - addrs[i]);
break;
}
CLEAR_A();
EMIT_JMP(cleanup_addr - addrs[i]);
break;
}
seen |= SEEN_DATAREF | SEEN_XREG;
t_offset = sk_load_byte_msh - (image + addrs[i]);
EMIT1_off32(0xbe, K); /* mov imm32,%esi */
EMIT1_off32(0xe8, t_offset); /* call sk_load_byte_msh */
break;
case BPF_S_LD_W_IND:
func = sk_load_word_ind;
common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG;
t_offset = func - (image + addrs[i]);
EMIT1_off32(0xbe, K); /* mov imm32,%esi */
EMIT1_off32(0xe8, t_offset); /* call sk_load_xxx_ind */
break;
case BPF_S_LD_H_IND:
func = sk_load_half_ind;
goto common_load_ind;
case BPF_S_LD_B_IND:
func = sk_load_byte_ind;
goto common_load_ind;
case BPF_S_JMP_JA:
t_offset = addrs[i + K] - addrs[i];
EMIT_JMP(t_offset);
break;
COND_SEL(BPF_S_JMP_JGT_K, X86_JA, X86_JBE);
COND_SEL(BPF_S_JMP_JGE_K, X86_JAE, X86_JB);
COND_SEL(BPF_S_JMP_JEQ_K, X86_JE, X86_JNE);
COND_SEL(BPF_S_JMP_JSET_K,X86_JNE, X86_JE);
COND_SEL(BPF_S_JMP_JGT_X, X86_JA, X86_JBE);
COND_SEL(BPF_S_JMP_JGE_X, X86_JAE, X86_JB);
COND_SEL(BPF_S_JMP_JEQ_X, X86_JE, X86_JNE);
COND_SEL(BPF_S_JMP_JSET_X,X86_JNE, X86_JE);
cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
t_offset = addrs[i + filter[i].jt] - addrs[i];
/* same targets, can avoid doing the test :) */
if (filter[i].jt == filter[i].jf) {
EMIT_JMP(t_offset);
break;
}
switch (filter[i].code) {
case BPF_S_JMP_JGT_X:
case BPF_S_JMP_JGE_X:
case BPF_S_JMP_JEQ_X:
seen |= SEEN_XREG;
EMIT2(0x39, 0xd8); /* cmp %ebx,%eax */
break;
case BPF_S_JMP_JSET_X:
seen |= SEEN_XREG;
EMIT2(0x85, 0xd8); /* test %ebx,%eax */
break;
case BPF_S_JMP_JEQ_K:
if (K == 0) {
EMIT2(0x85, 0xc0); /* test %eax,%eax */
break;
}
case BPF_S_JMP_JGT_K:
case BPF_S_JMP_JGE_K:
if (K <= 127)
EMIT3(0x83, 0xf8, K); /* cmp imm8,%eax */
else
EMIT1_off32(0x3d, K); /* cmp imm32,%eax */
break;
case BPF_S_JMP_JSET_K:
if (K <= 0xFF)
EMIT2(0xa8, K); /* test imm8,%al */
else if (!(K & 0xFFFF00FF))
EMIT3(0xf6, 0xc4, K >> 8); /* test imm8,%ah */
else if (K <= 0xFFFF) {
EMIT2(0x66, 0xa9); /* test imm16,%ax */
EMIT(K, 2);
} else {
EMIT1_off32(0xa9, K); /* test imm32,%eax */
}
break;
}
if (filter[i].jt != 0) {
if (filter[i].jf)
t_offset += is_near(f_offset) ? 2 : 6;
EMIT_COND_JMP(t_op, t_offset);
if (filter[i].jf)
EMIT_JMP(f_offset);
break;
}
EMIT_COND_JMP(f_op, f_offset);
break;
default:
/* hmm, too complex filter, give up with jit compiler */
goto out;
}
ilen = prog - temp;
if (image) {
if (unlikely(proglen + ilen > oldproglen)) {
pr_err("bpb_jit_compile fatal error\n");
kfree(addrs);
module_free(NULL, image);
return;
}
memcpy(image + proglen, temp, ilen);
}
proglen += ilen;
addrs[i] = proglen;
prog = temp;
}
/* last bpf instruction is always a RET :
* use it to give the cleanup instruction(s) addr
*/
cleanup_addr = proglen - 1; /* ret */
if (seen)
cleanup_addr -= 1; /* leaveq */
if (seen & SEEN_XREG)
cleanup_addr -= 4; /* mov -8(%rbp),%rbx */
if (image) {
WARN_ON(proglen != oldproglen);
break;
}
if (proglen == oldproglen) {
image = module_alloc(max_t(unsigned int,
proglen,
sizeof(struct work_struct)));
if (!image)
goto out;
}
oldproglen = proglen;
}
if (bpf_jit_enable > 1)
pr_err("flen=%d proglen=%u pass=%d image=%p\n",
flen, proglen, pass, image);
if (image) {
if (bpf_jit_enable > 1)
print_hex_dump(KERN_ERR, "JIT code: ", DUMP_PREFIX_ADDRESS,
16, 1, image, proglen, false);
bpf_flush_icache(image, image + proglen);
fp->bpf_func = (void *)image;
}
out:
kfree(addrs);
return;
}
static void jit_free_defer(struct work_struct *arg)
{
module_free(NULL, arg);
}
/* run from softirq, we must use a work_struct to call
* module_free() from process context
*/
void bpf_jit_free(struct sk_filter *fp)
{
if (fp->bpf_func != sk_run_filter) {
struct work_struct *work = (struct work_struct *)fp->bpf_func;
INIT_WORK(work, jit_free_defer);
schedule_work(work);
}
}

View File

@ -68,6 +68,8 @@ source "drivers/watchdog/Kconfig"
source "drivers/ssb/Kconfig" source "drivers/ssb/Kconfig"
source "drivers/bcma/Kconfig"
source "drivers/mfd/Kconfig" source "drivers/mfd/Kconfig"
source "drivers/regulator/Kconfig" source "drivers/regulator/Kconfig"

View File

@ -110,6 +110,7 @@ obj-$(CONFIG_HID) += hid/
obj-$(CONFIG_PPC_PS3) += ps3/ obj-$(CONFIG_PPC_PS3) += ps3/
obj-$(CONFIG_OF) += of/ obj-$(CONFIG_OF) += of/
obj-$(CONFIG_SSB) += ssb/ obj-$(CONFIG_SSB) += ssb/
obj-$(CONFIG_BCMA) += bcma/
obj-$(CONFIG_VHOST_NET) += vhost/ obj-$(CONFIG_VHOST_NET) += vhost/
obj-$(CONFIG_VLYNQ) += vlynq/ obj-$(CONFIG_VLYNQ) += vlynq/
obj-$(CONFIG_STAGING) += staging/ obj-$(CONFIG_STAGING) += staging/

View File

@ -1469,10 +1469,7 @@ if (eni_boards) printk(KERN_INFO "loss: %ld\n",ENI_DEV(eni_boards)->lost);
static void bug_int(struct atm_dev *dev,unsigned long reason) static void bug_int(struct atm_dev *dev,unsigned long reason)
{ {
struct eni_dev *eni_dev;
DPRINTK(">bug_int\n"); DPRINTK(">bug_int\n");
eni_dev = ENI_DEV(dev);
if (reason & MID_DMA_ERR_ACK) if (reason & MID_DMA_ERR_ACK)
printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - DMA " printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - DMA "
"error\n",dev->number); "error\n",dev->number);
@ -1900,7 +1897,6 @@ static void eni_close(struct atm_vcc *vcc)
static int eni_open(struct atm_vcc *vcc) static int eni_open(struct atm_vcc *vcc)
{ {
struct eni_dev *eni_dev;
struct eni_vcc *eni_vcc; struct eni_vcc *eni_vcc;
int error; int error;
short vpi = vcc->vpi; short vpi = vcc->vpi;
@ -1910,7 +1906,6 @@ static int eni_open(struct atm_vcc *vcc)
EVENT("eni_open\n",0,0); EVENT("eni_open\n",0,0);
if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))
vcc->dev_data = NULL; vcc->dev_data = NULL;
eni_dev = ENI_DEV(vcc->dev);
if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC) if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
set_bit(ATM_VF_ADDR,&vcc->flags); set_bit(ATM_VF_ADDR,&vcc->flags);
if (vcc->qos.aal != ATM_AAL0 && vcc->qos.aal != ATM_AAL5) if (vcc->qos.aal != ATM_AAL0 && vcc->qos.aal != ATM_AAL5)

View File

@ -1801,7 +1801,7 @@ return_host_buffers:
next_rbrq_entry: next_rbrq_entry:
he_dev->rbrq_head = (struct he_rbrq *) he_dev->rbrq_head = (struct he_rbrq *)
((unsigned long) he_dev->rbrq_base | ((unsigned long) he_dev->rbrq_base |
RBRQ_MASK(++he_dev->rbrq_head)); RBRQ_MASK(he_dev->rbrq_head + 1));
} }
read_unlock(&vcc_sklist_lock); read_unlock(&vcc_sklist_lock);
@ -1884,7 +1884,7 @@ next_tbrq_entry:
pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status)); pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
he_dev->tbrq_head = (struct he_tbrq *) he_dev->tbrq_head = (struct he_tbrq *)
((unsigned long) he_dev->tbrq_base | ((unsigned long) he_dev->tbrq_base |
TBRQ_MASK(++he_dev->tbrq_head)); TBRQ_MASK(he_dev->tbrq_head + 1));
} }
if (updated) { if (updated) {

View File

@ -1261,14 +1261,13 @@ idt77252_rx_raw(struct idt77252_dev *card)
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
while (head != tail) { while (head != tail) {
unsigned int vpi, vci, pti; unsigned int vpi, vci;
u32 header; u32 header;
header = le32_to_cpu(*(u32 *) &queue->data[0]); header = le32_to_cpu(*(u32 *) &queue->data[0]);
vpi = (header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT; vpi = (header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT;
vci = (header & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT; vci = (header & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT;
pti = (header & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT;
#ifdef CONFIG_ATM_IDT77252_DEBUG #ifdef CONFIG_ATM_IDT77252_DEBUG
if (debug & DBG_RAW_CELL) { if (debug & DBG_RAW_CELL) {
@ -2709,53 +2708,10 @@ idt77252_proc_read(struct atm_dev *dev, loff_t * pos, char *page)
static void static void
idt77252_collect_stat(struct idt77252_dev *card) idt77252_collect_stat(struct idt77252_dev *card)
{ {
u32 cdc, vpec, icc; (void) readl(SAR_REG_CDC);
(void) readl(SAR_REG_VPEC);
(void) readl(SAR_REG_ICC);
cdc = readl(SAR_REG_CDC);
vpec = readl(SAR_REG_VPEC);
icc = readl(SAR_REG_ICC);
#ifdef NOTDEF
printk("%s:", card->name);
if (cdc & 0x7f0000) {
char *s = "";
printk(" [");
if (cdc & (1 << 22)) {
printk("%sRM ID", s);
s = " | ";
}
if (cdc & (1 << 21)) {
printk("%sCON TAB", s);
s = " | ";
}
if (cdc & (1 << 20)) {
printk("%sNO FB", s);
s = " | ";
}
if (cdc & (1 << 19)) {
printk("%sOAM CRC", s);
s = " | ";
}
if (cdc & (1 << 18)) {
printk("%sRM CRC", s);
s = " | ";
}
if (cdc & (1 << 17)) {
printk("%sRM FIFO", s);
s = " | ";
}
if (cdc & (1 << 16)) {
printk("%sRX FIFO", s);
s = " | ";
}
printk("]");
}
printk(" CDC %04x, VPEC %04x, ICC: %04x\n",
cdc & 0xffff, vpec & 0xffff, icc & 0xffff);
#endif
} }
static irqreturn_t static irqreturn_t

View File

@ -613,7 +613,6 @@ static int ia_que_tx (IADEV *iadev) {
struct sk_buff *skb; struct sk_buff *skb;
int num_desc; int num_desc;
struct atm_vcc *vcc; struct atm_vcc *vcc;
struct ia_vcc *iavcc;
num_desc = ia_avail_descs(iadev); num_desc = ia_avail_descs(iadev);
while (num_desc && (skb = skb_dequeue(&iadev->tx_backlog))) { while (num_desc && (skb = skb_dequeue(&iadev->tx_backlog))) {
@ -627,7 +626,6 @@ static int ia_que_tx (IADEV *iadev) {
printk("Free the SKB on closed vci %d \n", vcc->vci); printk("Free the SKB on closed vci %d \n", vcc->vci);
break; break;
} }
iavcc = INPH_IA_VCC(vcc);
if (ia_pkt_tx (vcc, skb)) { if (ia_pkt_tx (vcc, skb)) {
skb_queue_head(&iadev->tx_backlog, skb); skb_queue_head(&iadev->tx_backlog, skb);
} }
@ -823,8 +821,6 @@ static void IaFrontEndIntr(IADEV *iadev) {
volatile IA_SUNI *suni; volatile IA_SUNI *suni;
volatile ia_mb25_t *mb25; volatile ia_mb25_t *mb25;
volatile suni_pm7345_t *suni_pm7345; volatile suni_pm7345_t *suni_pm7345;
u32 intr_status;
u_int frmr_intr;
if(iadev->phy_type & FE_25MBIT_PHY) { if(iadev->phy_type & FE_25MBIT_PHY) {
mb25 = (ia_mb25_t*)iadev->phy; mb25 = (ia_mb25_t*)iadev->phy;
@ -832,18 +828,18 @@ static void IaFrontEndIntr(IADEV *iadev) {
} else if (iadev->phy_type & FE_DS3_PHY) { } else if (iadev->phy_type & FE_DS3_PHY) {
suni_pm7345 = (suni_pm7345_t *)iadev->phy; suni_pm7345 = (suni_pm7345_t *)iadev->phy;
/* clear FRMR interrupts */ /* clear FRMR interrupts */
frmr_intr = suni_pm7345->suni_ds3_frm_intr_stat; (void) suni_pm7345->suni_ds3_frm_intr_stat;
iadev->carrier_detect = iadev->carrier_detect =
Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV)); Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV));
} else if (iadev->phy_type & FE_E3_PHY ) { } else if (iadev->phy_type & FE_E3_PHY ) {
suni_pm7345 = (suni_pm7345_t *)iadev->phy; suni_pm7345 = (suni_pm7345_t *)iadev->phy;
frmr_intr = suni_pm7345->suni_e3_frm_maint_intr_ind; (void) suni_pm7345->suni_e3_frm_maint_intr_ind;
iadev->carrier_detect = iadev->carrier_detect =
Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat&SUNI_E3_LOS)); Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat&SUNI_E3_LOS));
} }
else { else {
suni = (IA_SUNI *)iadev->phy; suni = (IA_SUNI *)iadev->phy;
intr_status = suni->suni_rsop_status & 0xff; (void) suni->suni_rsop_status;
iadev->carrier_detect = Boolean(!(suni->suni_rsop_status & SUNI_LOSV)); iadev->carrier_detect = Boolean(!(suni->suni_rsop_status & SUNI_LOSV));
} }
if (iadev->carrier_detect) if (iadev->carrier_detect)
@ -2660,7 +2656,6 @@ static void ia_close(struct atm_vcc *vcc)
static int ia_open(struct atm_vcc *vcc) static int ia_open(struct atm_vcc *vcc)
{ {
IADEV *iadev;
struct ia_vcc *ia_vcc; struct ia_vcc *ia_vcc;
int error; int error;
if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))
@ -2668,7 +2663,6 @@ static int ia_open(struct atm_vcc *vcc)
IF_EVENT(printk("ia: not partially allocated resources\n");) IF_EVENT(printk("ia: not partially allocated resources\n");)
vcc->dev_data = NULL; vcc->dev_data = NULL;
} }
iadev = INPH_IA_DEV(vcc->dev);
if (vcc->vci != ATM_VPI_UNSPEC && vcc->vpi != ATM_VCI_UNSPEC) if (vcc->vci != ATM_VPI_UNSPEC && vcc->vpi != ATM_VCI_UNSPEC)
{ {
IF_EVENT(printk("iphase open: unspec part\n");) IF_EVENT(printk("iphase open: unspec part\n");)
@ -3052,11 +3046,9 @@ static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) {
static int ia_send(struct atm_vcc *vcc, struct sk_buff *skb) static int ia_send(struct atm_vcc *vcc, struct sk_buff *skb)
{ {
IADEV *iadev; IADEV *iadev;
struct ia_vcc *iavcc;
unsigned long flags; unsigned long flags;
iadev = INPH_IA_DEV(vcc->dev); iadev = INPH_IA_DEV(vcc->dev);
iavcc = INPH_IA_VCC(vcc);
if ((!skb)||(skb->len>(iadev->tx_buf_sz-sizeof(struct cpcs_trailer)))) if ((!skb)||(skb->len>(iadev->tx_buf_sz-sizeof(struct cpcs_trailer))))
{ {
if (!skb) if (!skb)

View File

@ -527,7 +527,6 @@ static int flash_upgrade(struct solos_card *card, int chip)
{ {
const struct firmware *fw; const struct firmware *fw;
const char *fw_name; const char *fw_name;
uint32_t data32 = 0;
int blocksize = 0; int blocksize = 0;
int numblocks = 0; int numblocks = 0;
int offset; int offset;
@ -576,7 +575,7 @@ static int flash_upgrade(struct solos_card *card, int chip)
dev_info(&card->dev->dev, "Changing FPGA to Update mode\n"); dev_info(&card->dev->dev, "Changing FPGA to Update mode\n");
iowrite32(1, card->config_regs + FPGA_MODE); iowrite32(1, card->config_regs + FPGA_MODE);
data32 = ioread32(card->config_regs + FPGA_MODE); (void) ioread32(card->config_regs + FPGA_MODE);
/* Set mode to Chip Erase */ /* Set mode to Chip Erase */
if(chip == 0 || chip == 2) if(chip == 0 || chip == 2)

33
drivers/bcma/Kconfig Normal file
View File

@ -0,0 +1,33 @@
config BCMA_POSSIBLE
bool
depends on HAS_IOMEM && HAS_DMA
default y
menu "Broadcom specific AMBA"
depends on BCMA_POSSIBLE
config BCMA
tristate "BCMA support"
depends on BCMA_POSSIBLE
help
Bus driver for Broadcom specific Advanced Microcontroller Bus
Architecture.
config BCMA_HOST_PCI_POSSIBLE
bool
depends on BCMA && PCI = y
default y
config BCMA_HOST_PCI
bool "Support for BCMA on PCI-host bus"
depends on BCMA_HOST_PCI_POSSIBLE
config BCMA_DEBUG
bool "BCMA debugging"
depends on BCMA
help
This turns on additional debugging messages.
If unsure, say N
endmenu

7
drivers/bcma/Makefile Normal file
View File

@ -0,0 +1,7 @@
bcma-y += main.o scan.o core.o
bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
bcma-y += driver_pci.o
bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
obj-$(CONFIG_BCMA) += bcma.o
ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG

19
drivers/bcma/README Normal file
View File

@ -0,0 +1,19 @@
Broadcom introduced new bus as replacement for older SSB. It is based on AMBA,
however from programming point of view there is nothing AMBA specific we use.
Standard AMBA drivers are platform specific, have hardcoded addresses and use
AMBA standard fields like CID and PID.
In case of Broadcom's cards every device consists of:
1) Broadcom specific AMBA device. It is put on AMBA bus, but can not be treated
as standard AMBA device. Reading it's CID or PID can cause machine lockup.
2) AMBA standard devices called ports or wrappers. They have CIDs (AMBA_CID)
and PIDs (0x103BB369), but we do not use that info for anything. One of that
devices is used for managing Broadcom specific core.
Addresses of AMBA devices are not hardcoded in driver and have to be read from
EPROM.
In this situation we decided to introduce separated bus. It can contain up to
16 devices identified by Broadcom specific fields: manufacturer, id, revision
and class.

3
drivers/bcma/TODO Normal file
View File

@ -0,0 +1,3 @@
- Interrupts
- Defines for PCI core driver
- Create kernel Documentation (use info from README)

View File

@ -0,0 +1,28 @@
#ifndef LINUX_BCMA_PRIVATE_H_
#define LINUX_BCMA_PRIVATE_H_
#ifndef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#endif
#include <linux/bcma/bcma.h>
#include <linux/delay.h>
#define BCMA_CORE_SIZE 0x1000
struct bcma_bus;
/* main.c */
extern int bcma_bus_register(struct bcma_bus *bus);
extern void bcma_bus_unregister(struct bcma_bus *bus);
/* scan.c */
int bcma_bus_scan(struct bcma_bus *bus);
#ifdef CONFIG_BCMA_HOST_PCI
/* host_pci.c */
extern int __init bcma_host_pci_init(void);
extern void __exit bcma_host_pci_exit(void);
#endif /* CONFIG_BCMA_HOST_PCI */
#endif

51
drivers/bcma/core.c Normal file
View File

@ -0,0 +1,51 @@
/*
* Broadcom specific AMBA
* Core ops
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
#include "bcma_private.h"
#include <linux/bcma/bcma.h>
bool bcma_core_is_enabled(struct bcma_device *core)
{
if ((bcma_aread32(core, BCMA_IOCTL) & (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC))
!= BCMA_IOCTL_CLK)
return false;
if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
return false;
return true;
}
EXPORT_SYMBOL_GPL(bcma_core_is_enabled);
static void bcma_core_disable(struct bcma_device *core, u32 flags)
{
if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
return;
bcma_awrite32(core, BCMA_IOCTL, flags);
bcma_aread32(core, BCMA_IOCTL);
udelay(10);
bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
udelay(1);
}
int bcma_core_enable(struct bcma_device *core, u32 flags)
{
bcma_core_disable(core, flags);
bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags));
bcma_aread32(core, BCMA_IOCTL);
bcma_awrite32(core, BCMA_RESET_CTL, 0);
udelay(1);
bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags));
bcma_aread32(core, BCMA_IOCTL);
udelay(1);
return 0;
}
EXPORT_SYMBOL_GPL(bcma_core_enable);

View File

@ -0,0 +1,89 @@
/*
* Broadcom specific AMBA
* ChipCommon core driver
*
* Copyright 2005, Broadcom Corporation
* Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
#include "bcma_private.h"
#include <linux/bcma/bcma.h>
static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
u32 mask, u32 value)
{
value &= mask;
value |= bcma_cc_read32(cc, offset) & ~mask;
bcma_cc_write32(cc, offset, value);
return value;
}
void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
{
if (cc->core->id.rev >= 11)
cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
if (cc->core->id.rev >= 35)
cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);
if (cc->core->id.rev >= 20) {
bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0);
bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0);
}
if (cc->capabilities & BCMA_CC_CAP_PMU)
bcma_pmu_init(cc);
if (cc->capabilities & BCMA_CC_CAP_PCTL)
pr_err("Power control not implemented!\n");
}
/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
{
/* instant NMI */
bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
}
void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
{
bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value);
}
u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask)
{
return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask;
}
u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
{
return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
}
u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
{
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
}
u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
{
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
}
u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
{
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
}
EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
{
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
}
u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
{
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
}

View File

@ -0,0 +1,134 @@
/*
* Broadcom specific AMBA
* ChipCommon Power Management Unit driver
*
* Copyright 2009, Michael Buesch <mb@bu3sch.de>
* Copyright 2007, Broadcom Corporation
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
#include "bcma_private.h"
#include <linux/bcma/bcma.h>
static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
u32 offset, u32 mask, u32 set)
{
u32 value;
bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
value &= mask;
value |= set;
bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
}
static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
{
struct bcma_bus *bus = cc->core->bus;
switch (bus->chipinfo.id) {
case 0x4313:
case 0x4331:
case 43224:
case 43225:
break;
default:
pr_err("PLL init unknown for device 0x%04X\n",
bus->chipinfo.id);
}
}
static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
{
struct bcma_bus *bus = cc->core->bus;
u32 min_msk = 0, max_msk = 0;
switch (bus->chipinfo.id) {
case 0x4313:
min_msk = 0x200D;
max_msk = 0xFFFF;
break;
case 43224:
break;
default:
pr_err("PMU resource config unknown for device 0x%04X\n",
bus->chipinfo.id);
}
/* Set the resource masks. */
if (min_msk)
bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk);
if (max_msk)
bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk);
}
void bcma_pmu_swreg_init(struct bcma_drv_cc *cc)
{
struct bcma_bus *bus = cc->core->bus;
switch (bus->chipinfo.id) {
case 0x4313:
case 0x4331:
case 43224:
break;
default:
pr_err("PMU switch/regulators init unknown for device "
"0x%04X\n", bus->chipinfo.id);
}
}
void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
{
struct bcma_bus *bus = cc->core->bus;
switch (bus->chipinfo.id) {
case 0x4313:
bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
break;
case 0x4331:
pr_err("Enabling Ext PA lines not implemented\n");
break;
case 43224:
if (bus->chipinfo.rev == 0) {
pr_err("Workarounds for 43224 rev 0 not fully "
"implemented\n");
bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
} else {
bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
}
break;
default:
pr_err("Workarounds unknown for device 0x%04X\n",
bus->chipinfo.id);
}
}
void bcma_pmu_init(struct bcma_drv_cc *cc)
{
u32 pmucap;
pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP);
cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION);
pr_debug("Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev,
pmucap);
if (cc->pmu.rev == 1)
bcma_cc_mask32(cc, BCMA_CC_PMU_CTL,
~BCMA_CC_PMU_CTL_NOILPONW);
else
bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
BCMA_CC_PMU_CTL_NOILPONW);
if (cc->core->id.id == 0x4329 && cc->core->id.rev == 2)
pr_err("Fix for 4329b0 bad LPOM state not implemented!\n");
bcma_pmu_pll_init(cc);
bcma_pmu_resources_init(cc);
bcma_pmu_swreg_init(cc);
bcma_pmu_workarounds(cc);
}

163
drivers/bcma/driver_pci.c Normal file
View File

@ -0,0 +1,163 @@
/*
* Broadcom specific AMBA
* PCI Core
*
* Copyright 2005, Broadcom Corporation
* Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
#include "bcma_private.h"
#include <linux/bcma/bcma.h>
/**************************************************
* R/W ops.
**************************************************/
static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
{
pcicore_write32(pc, 0x130, address);
pcicore_read32(pc, 0x130);
return pcicore_read32(pc, 0x134);
}
#if 0
static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
{
pcicore_write32(pc, 0x130, address);
pcicore_read32(pc, 0x130);
pcicore_write32(pc, 0x134, data);
}
#endif
static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
{
const u16 mdio_control = 0x128;
const u16 mdio_data = 0x12C;
u32 v;
int i;
v = (1 << 30); /* Start of Transaction */
v |= (1 << 28); /* Write Transaction */
v |= (1 << 17); /* Turnaround */
v |= (0x1F << 18);
v |= (phy << 4);
pcicore_write32(pc, mdio_data, v);
udelay(10);
for (i = 0; i < 200; i++) {
v = pcicore_read32(pc, mdio_control);
if (v & 0x100 /* Trans complete */)
break;
msleep(1);
}
}
static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
{
const u16 mdio_control = 0x128;
const u16 mdio_data = 0x12C;
int max_retries = 10;
u16 ret = 0;
u32 v;
int i;
v = 0x80; /* Enable Preamble Sequence */
v |= 0x2; /* MDIO Clock Divisor */
pcicore_write32(pc, mdio_control, v);
if (pc->core->id.rev >= 10) {
max_retries = 200;
bcma_pcie_mdio_set_phy(pc, device);
}
v = (1 << 30); /* Start of Transaction */
v |= (1 << 29); /* Read Transaction */
v |= (1 << 17); /* Turnaround */
if (pc->core->id.rev < 10)
v |= (u32)device << 22;
v |= (u32)address << 18;
pcicore_write32(pc, mdio_data, v);
/* Wait for the device to complete the transaction */
udelay(10);
for (i = 0; i < max_retries; i++) {
v = pcicore_read32(pc, mdio_control);
if (v & 0x100 /* Trans complete */) {
udelay(10);
ret = pcicore_read32(pc, mdio_data);
break;
}
msleep(1);
}
pcicore_write32(pc, mdio_control, 0);
return ret;
}
static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
u8 address, u16 data)
{
const u16 mdio_control = 0x128;
const u16 mdio_data = 0x12C;
int max_retries = 10;
u32 v;
int i;
v = 0x80; /* Enable Preamble Sequence */
v |= 0x2; /* MDIO Clock Divisor */
pcicore_write32(pc, mdio_control, v);
if (pc->core->id.rev >= 10) {
max_retries = 200;
bcma_pcie_mdio_set_phy(pc, device);
}
v = (1 << 30); /* Start of Transaction */
v |= (1 << 28); /* Write Transaction */
v |= (1 << 17); /* Turnaround */
if (pc->core->id.rev < 10)
v |= (u32)device << 22;
v |= (u32)address << 18;
v |= data;
pcicore_write32(pc, mdio_data, v);
/* Wait for the device to complete the transaction */
udelay(10);
for (i = 0; i < max_retries; i++) {
v = pcicore_read32(pc, mdio_control);
if (v & 0x100 /* Trans complete */)
break;
msleep(1);
}
pcicore_write32(pc, mdio_control, 0);
}
/**************************************************
* Workarounds.
**************************************************/
static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
{
return (bcma_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
}
static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
{
const u8 serdes_pll_device = 0x1D;
const u8 serdes_rx_device = 0x1F;
u16 tmp;
bcma_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
bcma_pcicore_polarity_workaround(pc));
tmp = bcma_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
if (tmp & 0x4000)
bcma_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
}
/**************************************************
* Init.
**************************************************/
void bcma_core_pci_init(struct bcma_drv_pci *pc)
{
bcma_pcicore_serdes_workaround(pc);
}

196
drivers/bcma/host_pci.c Normal file
View File

@ -0,0 +1,196 @@
/*
* Broadcom specific AMBA
* PCI Host
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
#include "bcma_private.h"
#include <linux/bcma/bcma.h>
#include <linux/pci.h>
static void bcma_host_pci_switch_core(struct bcma_device *core)
{
pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN,
core->addr);
pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN2,
core->wrap);
core->bus->mapped_core = core;
pr_debug("Switched to core: 0x%X\n", core->id.id);
}
static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
{
if (core->bus->mapped_core != core)
bcma_host_pci_switch_core(core);
return ioread8(core->bus->mmio + offset);
}
static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
{
if (core->bus->mapped_core != core)
bcma_host_pci_switch_core(core);
return ioread16(core->bus->mmio + offset);
}
static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
{
if (core->bus->mapped_core != core)
bcma_host_pci_switch_core(core);
return ioread32(core->bus->mmio + offset);
}
static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
u8 value)
{
if (core->bus->mapped_core != core)
bcma_host_pci_switch_core(core);
iowrite8(value, core->bus->mmio + offset);
}
static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
u16 value)
{
if (core->bus->mapped_core != core)
bcma_host_pci_switch_core(core);
iowrite16(value, core->bus->mmio + offset);
}
static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
u32 value)
{
if (core->bus->mapped_core != core)
bcma_host_pci_switch_core(core);
iowrite32(value, core->bus->mmio + offset);
}
static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
{
if (core->bus->mapped_core != core)
bcma_host_pci_switch_core(core);
return ioread32(core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
}
static void bcma_host_pci_awrite32(struct bcma_device *core, u16 offset,
u32 value)
{
if (core->bus->mapped_core != core)
bcma_host_pci_switch_core(core);
iowrite32(value, core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
}
const struct bcma_host_ops bcma_host_pci_ops = {
.read8 = bcma_host_pci_read8,
.read16 = bcma_host_pci_read16,
.read32 = bcma_host_pci_read32,
.write8 = bcma_host_pci_write8,
.write16 = bcma_host_pci_write16,
.write32 = bcma_host_pci_write32,
.aread32 = bcma_host_pci_aread32,
.awrite32 = bcma_host_pci_awrite32,
};
static int bcma_host_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
struct bcma_bus *bus;
int err = -ENOMEM;
const char *name;
u32 val;
/* Alloc */
bus = kzalloc(sizeof(*bus), GFP_KERNEL);
if (!bus)
goto out;
/* Basic PCI configuration */
err = pci_enable_device(dev);
if (err)
goto err_kfree_bus;
name = dev_name(&dev->dev);
if (dev->driver && dev->driver->name)
name = dev->driver->name;
err = pci_request_regions(dev, name);
if (err)
goto err_pci_disable;
pci_set_master(dev);
/* Disable the RETRY_TIMEOUT register (0x41) to keep
* PCI Tx retries from interfering with C3 CPU state */
pci_read_config_dword(dev, 0x40, &val);
if ((val & 0x0000ff00) != 0)
pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
/* SSB needed additional powering up, do we have any AMBA PCI cards? */
if (!pci_is_pcie(dev))
pr_err("PCI card detected, report problems.\n");
/* Map MMIO */
err = -ENOMEM;
bus->mmio = pci_iomap(dev, 0, ~0UL);
if (!bus->mmio)
goto err_pci_release_regions;
/* Host specific */
bus->host_pci = dev;
bus->hosttype = BCMA_HOSTTYPE_PCI;
bus->ops = &bcma_host_pci_ops;
/* Register */
err = bcma_bus_register(bus);
if (err)
goto err_pci_unmap_mmio;
pci_set_drvdata(dev, bus);
out:
return err;
err_pci_unmap_mmio:
pci_iounmap(dev, bus->mmio);
err_pci_release_regions:
pci_release_regions(dev);
err_pci_disable:
pci_disable_device(dev);
err_kfree_bus:
kfree(bus);
return err;
}
static void bcma_host_pci_remove(struct pci_dev *dev)
{
struct bcma_bus *bus = pci_get_drvdata(dev);
bcma_bus_unregister(bus);
pci_iounmap(dev, bus->mmio);
pci_release_regions(dev);
pci_disable_device(dev);
kfree(bus);
pci_set_drvdata(dev, NULL);
}
static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
static struct pci_driver bcma_pci_bridge_driver = {
.name = "bcma-pci-bridge",
.id_table = bcma_pci_bridge_tbl,
.probe = bcma_host_pci_probe,
.remove = bcma_host_pci_remove,
};
int __init bcma_host_pci_init(void)
{
return pci_register_driver(&bcma_pci_bridge_driver);
}
void __exit bcma_host_pci_exit(void)
{
pci_unregister_driver(&bcma_pci_bridge_driver);
}

247
drivers/bcma/main.c Normal file
View File

@ -0,0 +1,247 @@
/*
* Broadcom specific AMBA
* Bus subsystem
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
#include "bcma_private.h"
#include <linux/bcma/bcma.h>
MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
MODULE_LICENSE("GPL");
static int bcma_bus_match(struct device *dev, struct device_driver *drv);
static int bcma_device_probe(struct device *dev);
static int bcma_device_remove(struct device *dev);
static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct bcma_device *core = container_of(dev, struct bcma_device, dev);
return sprintf(buf, "0x%03X\n", core->id.manuf);
}
static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct bcma_device *core = container_of(dev, struct bcma_device, dev);
return sprintf(buf, "0x%03X\n", core->id.id);
}
static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct bcma_device *core = container_of(dev, struct bcma_device, dev);
return sprintf(buf, "0x%02X\n", core->id.rev);
}
static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct bcma_device *core = container_of(dev, struct bcma_device, dev);
return sprintf(buf, "0x%X\n", core->id.class);
}
static struct device_attribute bcma_device_attrs[] = {
__ATTR_RO(manuf),
__ATTR_RO(id),
__ATTR_RO(rev),
__ATTR_RO(class),
__ATTR_NULL,
};
static struct bus_type bcma_bus_type = {
.name = "bcma",
.match = bcma_bus_match,
.probe = bcma_device_probe,
.remove = bcma_device_remove,
.dev_attrs = bcma_device_attrs,
};
static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
{
struct bcma_device *core;
list_for_each_entry(core, &bus->cores, list) {
if (core->id.id == coreid)
return core;
}
return NULL;
}
static void bcma_release_core_dev(struct device *dev)
{
struct bcma_device *core = container_of(dev, struct bcma_device, dev);
kfree(core);
}
static int bcma_register_cores(struct bcma_bus *bus)
{
struct bcma_device *core;
int err, dev_id = 0;
list_for_each_entry(core, &bus->cores, list) {
/* We support that cores ourself */
switch (core->id.id) {
case BCMA_CORE_CHIPCOMMON:
case BCMA_CORE_PCI:
case BCMA_CORE_PCIE:
continue;
}
core->dev.release = bcma_release_core_dev;
core->dev.bus = &bcma_bus_type;
dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
switch (bus->hosttype) {
case BCMA_HOSTTYPE_PCI:
core->dev.parent = &bus->host_pci->dev;
break;
case BCMA_HOSTTYPE_NONE:
case BCMA_HOSTTYPE_SDIO:
break;
}
err = device_register(&core->dev);
if (err) {
pr_err("Could not register dev for core 0x%03X\n",
core->id.id);
continue;
}
core->dev_registered = true;
dev_id++;
}
return 0;
}
static void bcma_unregister_cores(struct bcma_bus *bus)
{
struct bcma_device *core;
list_for_each_entry(core, &bus->cores, list) {
if (core->dev_registered)
device_unregister(&core->dev);
}
}
int bcma_bus_register(struct bcma_bus *bus)
{
int err;
struct bcma_device *core;
/* Scan for devices (cores) */
err = bcma_bus_scan(bus);
if (err) {
pr_err("Failed to scan: %d\n", err);
return -1;
}
/* Init CC core */
core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
if (core) {
bus->drv_cc.core = core;
bcma_core_chipcommon_init(&bus->drv_cc);
}
/* Init PCIE core */
core = bcma_find_core(bus, BCMA_CORE_PCIE);
if (core) {
bus->drv_pci.core = core;
bcma_core_pci_init(&bus->drv_pci);
}
/* Register found cores */
bcma_register_cores(bus);
pr_info("Bus registered\n");
return 0;
}
EXPORT_SYMBOL_GPL(bcma_bus_register);
void bcma_bus_unregister(struct bcma_bus *bus)
{
bcma_unregister_cores(bus);
}
EXPORT_SYMBOL_GPL(bcma_bus_unregister);
int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
{
drv->drv.name = drv->name;
drv->drv.bus = &bcma_bus_type;
drv->drv.owner = owner;
return driver_register(&drv->drv);
}
EXPORT_SYMBOL_GPL(__bcma_driver_register);
void bcma_driver_unregister(struct bcma_driver *drv)
{
driver_unregister(&drv->drv);
}
EXPORT_SYMBOL_GPL(bcma_driver_unregister);
static int bcma_bus_match(struct device *dev, struct device_driver *drv)
{
struct bcma_device *core = container_of(dev, struct bcma_device, dev);
struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
const struct bcma_device_id *cid = &core->id;
const struct bcma_device_id *did;
for (did = adrv->id_table; did->manuf || did->id || did->rev; did++) {
if ((did->manuf == cid->manuf || did->manuf == BCMA_ANY_MANUF) &&
(did->id == cid->id || did->id == BCMA_ANY_ID) &&
(did->rev == cid->rev || did->rev == BCMA_ANY_REV) &&
(did->class == cid->class || did->class == BCMA_ANY_CLASS))
return 1;
}
return 0;
}
static int bcma_device_probe(struct device *dev)
{
struct bcma_device *core = container_of(dev, struct bcma_device, dev);
struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
drv);
int err = 0;
if (adrv->probe)
err = adrv->probe(core);
return err;
}
static int bcma_device_remove(struct device *dev)
{
struct bcma_device *core = container_of(dev, struct bcma_device, dev);
struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
drv);
if (adrv->remove)
adrv->remove(core);
return 0;
}
static int __init bcma_modinit(void)
{
int err;
err = bus_register(&bcma_bus_type);
if (err)
return err;
#ifdef CONFIG_BCMA_HOST_PCI
err = bcma_host_pci_init();
if (err) {
pr_err("PCI host initialization failed\n");
err = 0;
}
#endif
return err;
}
fs_initcall(bcma_modinit);
static void __exit bcma_modexit(void)
{
#ifdef CONFIG_BCMA_HOST_PCI
bcma_host_pci_exit();
#endif
bus_unregister(&bcma_bus_type);
}
module_exit(bcma_modexit)

360
drivers/bcma/scan.c Normal file
View File

@ -0,0 +1,360 @@
/*
* Broadcom specific AMBA
* Bus scanning
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
#include "scan.h"
#include "bcma_private.h"
#include <linux/bcma/bcma.h>
#include <linux/bcma/bcma_regs.h>
#include <linux/pci.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
struct bcma_device_id_name {
u16 id;
const char *name;
};
struct bcma_device_id_name bcma_device_names[] = {
{ BCMA_CORE_OOB_ROUTER, "OOB Router" },
{ BCMA_CORE_INVALID, "Invalid" },
{ BCMA_CORE_CHIPCOMMON, "ChipCommon" },
{ BCMA_CORE_ILINE20, "ILine 20" },
{ BCMA_CORE_SRAM, "SRAM" },
{ BCMA_CORE_SDRAM, "SDRAM" },
{ BCMA_CORE_PCI, "PCI" },
{ BCMA_CORE_MIPS, "MIPS" },
{ BCMA_CORE_ETHERNET, "Fast Ethernet" },
{ BCMA_CORE_V90, "V90" },
{ BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" },
{ BCMA_CORE_ADSL, "ADSL" },
{ BCMA_CORE_ILINE100, "ILine 100" },
{ BCMA_CORE_IPSEC, "IPSEC" },
{ BCMA_CORE_UTOPIA, "UTOPIA" },
{ BCMA_CORE_PCMCIA, "PCMCIA" },
{ BCMA_CORE_INTERNAL_MEM, "Internal Memory" },
{ BCMA_CORE_MEMC_SDRAM, "MEMC SDRAM" },
{ BCMA_CORE_OFDM, "OFDM" },
{ BCMA_CORE_EXTIF, "EXTIF" },
{ BCMA_CORE_80211, "IEEE 802.11" },
{ BCMA_CORE_PHY_A, "PHY A" },
{ BCMA_CORE_PHY_B, "PHY B" },
{ BCMA_CORE_PHY_G, "PHY G" },
{ BCMA_CORE_MIPS_3302, "MIPS 3302" },
{ BCMA_CORE_USB11_HOST, "USB 1.1 Host" },
{ BCMA_CORE_USB11_DEV, "USB 1.1 Device" },
{ BCMA_CORE_USB20_HOST, "USB 2.0 Host" },
{ BCMA_CORE_USB20_DEV, "USB 2.0 Device" },
{ BCMA_CORE_SDIO_HOST, "SDIO Host" },
{ BCMA_CORE_ROBOSWITCH, "Roboswitch" },
{ BCMA_CORE_PARA_ATA, "PATA" },
{ BCMA_CORE_SATA_XORDMA, "SATA XOR-DMA" },
{ BCMA_CORE_ETHERNET_GBIT, "GBit Ethernet" },
{ BCMA_CORE_PCIE, "PCIe" },
{ BCMA_CORE_PHY_N, "PHY N" },
{ BCMA_CORE_SRAM_CTL, "SRAM Controller" },
{ BCMA_CORE_MINI_MACPHY, "Mini MACPHY" },
{ BCMA_CORE_ARM_1176, "ARM 1176" },
{ BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
{ BCMA_CORE_PHY_LP, "PHY LP" },
{ BCMA_CORE_PMU, "PMU" },
{ BCMA_CORE_PHY_SSN, "PHY SSN" },
{ BCMA_CORE_SDIO_DEV, "SDIO Device" },
{ BCMA_CORE_ARM_CM3, "ARM CM3" },
{ BCMA_CORE_PHY_HT, "PHY HT" },
{ BCMA_CORE_MIPS_74K, "MIPS 74K" },
{ BCMA_CORE_MAC_GBIT, "GBit MAC" },
{ BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" },
{ BCMA_CORE_PCIE_RC, "PCIe Root Complex" },
{ BCMA_CORE_OCP_OCP_BRIDGE, "OCP to OCP Bridge" },
{ BCMA_CORE_SHARED_COMMON, "Common Shared" },
{ BCMA_CORE_OCP_AHB_BRIDGE, "OCP to AHB Bridge" },
{ BCMA_CORE_SPI_HOST, "SPI Host" },
{ BCMA_CORE_I2S, "I2S" },
{ BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" },
{ BCMA_CORE_SHIM, "SHIM" },
{ BCMA_CORE_DEFAULT, "Default" },
};
const char *bcma_device_name(struct bcma_device_id *id)
{
int i;
if (id->manuf == BCMA_MANUF_BCM) {
for (i = 0; i < ARRAY_SIZE(bcma_device_names); i++) {
if (bcma_device_names[i].id == id->id)
return bcma_device_names[i].name;
}
}
return "UNKNOWN";
}
static u32 bcma_scan_read32(struct bcma_bus *bus, u8 current_coreidx,
u16 offset)
{
return readl(bus->mmio + offset);
}
static void bcma_scan_switch_core(struct bcma_bus *bus, u32 addr)
{
if (bus->hosttype == BCMA_HOSTTYPE_PCI)
pci_write_config_dword(bus->host_pci, BCMA_PCI_BAR0_WIN,
addr);
}
static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 **eromptr)
{
u32 ent = readl(*eromptr);
(*eromptr)++;
return ent;
}
static void bcma_erom_push_ent(u32 **eromptr)
{
(*eromptr)--;
}
static s32 bcma_erom_get_ci(struct bcma_bus *bus, u32 **eromptr)
{
u32 ent = bcma_erom_get_ent(bus, eromptr);
if (!(ent & SCAN_ER_VALID))
return -ENOENT;
if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_CI)
return -ENOENT;
return ent;
}
static bool bcma_erom_is_end(struct bcma_bus *bus, u32 **eromptr)
{
u32 ent = bcma_erom_get_ent(bus, eromptr);
bcma_erom_push_ent(eromptr);
return (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID));
}
static bool bcma_erom_is_bridge(struct bcma_bus *bus, u32 **eromptr)
{
u32 ent = bcma_erom_get_ent(bus, eromptr);
bcma_erom_push_ent(eromptr);
return (((ent & SCAN_ER_VALID)) &&
((ent & SCAN_ER_TAGX) == SCAN_ER_TAG_ADDR) &&
((ent & SCAN_ADDR_TYPE) == SCAN_ADDR_TYPE_BRIDGE));
}
static void bcma_erom_skip_component(struct bcma_bus *bus, u32 **eromptr)
{
u32 ent;
while (1) {
ent = bcma_erom_get_ent(bus, eromptr);
if ((ent & SCAN_ER_VALID) &&
((ent & SCAN_ER_TAG) == SCAN_ER_TAG_CI))
break;
if (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID))
break;
}
bcma_erom_push_ent(eromptr);
}
static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 **eromptr)
{
u32 ent = bcma_erom_get_ent(bus, eromptr);
if (!(ent & SCAN_ER_VALID))
return -ENOENT;
if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_MP)
return -ENOENT;
return ent;
}
static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
u32 type, u8 port)
{
u32 addrl, addrh, sizel, sizeh = 0;
u32 size;
u32 ent = bcma_erom_get_ent(bus, eromptr);
if ((!(ent & SCAN_ER_VALID)) ||
((ent & SCAN_ER_TAGX) != SCAN_ER_TAG_ADDR) ||
((ent & SCAN_ADDR_TYPE) != type) ||
(((ent & SCAN_ADDR_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) {
bcma_erom_push_ent(eromptr);
return -EINVAL;
}
addrl = ent & SCAN_ADDR_ADDR;
if (ent & SCAN_ADDR_AG32)
addrh = bcma_erom_get_ent(bus, eromptr);
else
addrh = 0;
if ((ent & SCAN_ADDR_SZ) == SCAN_ADDR_SZ_SZD) {
size = bcma_erom_get_ent(bus, eromptr);
sizel = size & SCAN_SIZE_SZ;
if (size & SCAN_SIZE_SG32)
sizeh = bcma_erom_get_ent(bus, eromptr);
} else
sizel = SCAN_ADDR_SZ_BASE <<
((ent & SCAN_ADDR_SZ) >> SCAN_ADDR_SZ_SHIFT);
return addrl;
}
int bcma_bus_scan(struct bcma_bus *bus)
{
u32 erombase;
u32 __iomem *eromptr, *eromend;
s32 cia, cib;
u8 ports[2], wrappers[2];
s32 tmp;
u8 i, j;
int err;
INIT_LIST_HEAD(&bus->cores);
bus->nr_cores = 0;
bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
eromptr = bus->mmio;
eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
bcma_scan_switch_core(bus, erombase);
while (eromptr < eromend) {
struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
if (!core)
return -ENOMEM;
INIT_LIST_HEAD(&core->list);
core->bus = bus;
/* get CIs */
cia = bcma_erom_get_ci(bus, &eromptr);
if (cia < 0) {
bcma_erom_push_ent(&eromptr);
if (bcma_erom_is_end(bus, &eromptr))
break;
err= -EILSEQ;
goto out;
}
cib = bcma_erom_get_ci(bus, &eromptr);
if (cib < 0) {
err= -EILSEQ;
goto out;
}
/* parse CIs */
core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
if (((core->id.manuf == BCMA_MANUF_ARM) &&
(core->id.id == 0xFFF)) ||
(ports[1] == 0)) {
bcma_erom_skip_component(bus, &eromptr);
continue;
}
/* check if component is a core at all */
if (wrappers[0] + wrappers[1] == 0) {
/* we could save addrl of the router
if (cid == BCMA_CORE_OOB_ROUTER)
*/
bcma_erom_skip_component(bus, &eromptr);
continue;
}
if (bcma_erom_is_bridge(bus, &eromptr)) {
bcma_erom_skip_component(bus, &eromptr);
continue;
}
/* get & parse master ports */
for (i = 0; i < ports[0]; i++) {
u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
if (mst_port_d < 0) {
err= -EILSEQ;
goto out;
}
}
/* get & parse slave ports */
for (i = 0; i < ports[1]; i++) {
for (j = 0; ; j++) {
tmp = bcma_erom_get_addr_desc(bus, &eromptr,
SCAN_ADDR_TYPE_SLAVE, i);
if (tmp < 0) {
/* no more entries for port _i_ */
/* pr_debug("erom: slave port %d "
* "has %d descriptors\n", i, j); */
break;
} else {
if (i == 0 && j == 0)
core->addr = tmp;
}
}
}
/* get & parse master wrappers */
for (i = 0; i < wrappers[0]; i++) {
for (j = 0; ; j++) {
tmp = bcma_erom_get_addr_desc(bus, &eromptr,
SCAN_ADDR_TYPE_MWRAP, i);
if (tmp < 0) {
/* no more entries for port _i_ */
/* pr_debug("erom: master wrapper %d "
* "has %d descriptors\n", i, j); */
break;
} else {
if (i == 0 && j == 0)
core->wrap = tmp;
}
}
}
/* get & parse slave wrappers */
for (i = 0; i < wrappers[1]; i++) {
u8 hack = (ports[1] == 1) ? 0 : 1;
for (j = 0; ; j++) {
tmp = bcma_erom_get_addr_desc(bus, &eromptr,
SCAN_ADDR_TYPE_SWRAP, i + hack);
if (tmp < 0) {
/* no more entries for port _i_ */
/* pr_debug("erom: master wrapper %d "
* has %d descriptors\n", i, j); */
break;
} else {
if (wrappers[0] == 0 && !i && !j)
core->wrap = tmp;
}
}
}
pr_info("Core %d found: %s "
"(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
bus->nr_cores, bcma_device_name(&core->id),
core->id.manuf, core->id.id, core->id.rev,
core->id.class);
core->core_index = bus->nr_cores++;
list_add(&core->list, &bus->cores);
continue;
out:
return err;
}
return 0;
}

56
drivers/bcma/scan.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef BCMA_SCAN_H_
#define BCMA_SCAN_H_
#define BCMA_ADDR_BASE 0x18000000
#define BCMA_WRAP_BASE 0x18100000
#define SCAN_ER_VALID 0x00000001
#define SCAN_ER_TAGX 0x00000006 /* we have to ignore 0x8 bit when checking tag for SCAN_ER_TAG_ADDR */
#define SCAN_ER_TAG 0x0000000E
#define SCAN_ER_TAG_CI 0x00000000
#define SCAN_ER_TAG_MP 0x00000002
#define SCAN_ER_TAG_ADDR 0x00000004
#define SCAN_ER_TAG_END 0x0000000E
#define SCAN_ER_BAD 0xFFFFFFFF
#define SCAN_CIA_CLASS 0x000000F0
#define SCAN_CIA_CLASS_SHIFT 4
#define SCAN_CIA_ID 0x000FFF00
#define SCAN_CIA_ID_SHIFT 8
#define SCAN_CIA_MANUF 0xFFF00000
#define SCAN_CIA_MANUF_SHIFT 20
#define SCAN_CIB_NMP 0x000001F0
#define SCAN_CIB_NMP_SHIFT 4
#define SCAN_CIB_NSP 0x00003E00
#define SCAN_CIB_NSP_SHIFT 9
#define SCAN_CIB_NMW 0x0007C000
#define SCAN_CIB_NMW_SHIFT 14
#define SCAN_CIB_NSW 0x00F80000
#define SCAN_CIB_NSW_SHIFT 17
#define SCAN_CIB_REV 0xFF000000
#define SCAN_CIB_REV_SHIFT 24
#define SCAN_ADDR_AG32 0x00000008
#define SCAN_ADDR_SZ 0x00000030
#define SCAN_ADDR_SZ_SHIFT 4
#define SCAN_ADDR_SZ_4K 0x00000000
#define SCAN_ADDR_SZ_8K 0x00000010
#define SCAN_ADDR_SZ_16K 0x00000020
#define SCAN_ADDR_SZ_SZD 0x00000030
#define SCAN_ADDR_TYPE 0x000000C0
#define SCAN_ADDR_TYPE_SLAVE 0x00000000
#define SCAN_ADDR_TYPE_BRIDGE 0x00000040
#define SCAN_ADDR_TYPE_SWRAP 0x00000080
#define SCAN_ADDR_TYPE_MWRAP 0x000000C0
#define SCAN_ADDR_PORT 0x00000F00
#define SCAN_ADDR_PORT_SHIFT 8
#define SCAN_ADDR_ADDR 0xFFFFF000
#define SCAN_ADDR_SZ_BASE 0x00001000 /* 4KB */
#define SCAN_SIZE_SZ_ALIGN 0x00000FFF
#define SCAN_SIZE_SZ 0xFFFFF000
#define SCAN_SIZE_SG32 0x00000008
#endif /* BCMA_SCAN_H_ */

View File

@ -188,7 +188,7 @@ config BT_MRVL
The core driver to support Marvell Bluetooth devices. The core driver to support Marvell Bluetooth devices.
This driver is required if you want to support This driver is required if you want to support
Marvell Bluetooth devices, such as 8688. Marvell Bluetooth devices, such as 8688/8787.
Say Y here to compile Marvell Bluetooth driver Say Y here to compile Marvell Bluetooth driver
into the kernel or say M to compile it as module. into the kernel or say M to compile it as module.
@ -201,7 +201,7 @@ config BT_MRVL_SDIO
The driver for Marvell Bluetooth chipsets with SDIO interface. The driver for Marvell Bluetooth chipsets with SDIO interface.
This driver is required if you want to use Marvell Bluetooth This driver is required if you want to use Marvell Bluetooth
devices with SDIO interface. Currently only SD8688 chipset is devices with SDIO interface. Currently SD8688/SD8787 chipsets are
supported. supported.
Say Y here to compile support for Marvell BT-over-SDIO driver Say Y here to compile support for Marvell BT-over-SDIO driver

View File

@ -62,6 +62,7 @@ static struct usb_device_id ath3k_table[] = {
/* Atheros AR3011 with sflash firmware*/ /* Atheros AR3011 with sflash firmware*/
{ USB_DEVICE(0x0CF3, 0x3002) }, { USB_DEVICE(0x0CF3, 0x3002) },
{ USB_DEVICE(0x13d3, 0x3304) },
/* Atheros AR9285 Malbec with sflash firmware */ /* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03F0, 0x311D) }, { USB_DEVICE(0x03F0, 0x311D) },
@ -138,9 +139,6 @@ static int ath3k_load_firmware(struct usb_device *udev,
count -= size; count -= size;
} }
kfree(send_buf);
return 0;
error: error:
kfree(send_buf); kfree(send_buf);
return err; return err;

View File

@ -49,15 +49,59 @@
static u8 user_rmmod; static u8 user_rmmod;
static u8 sdio_ireg; static u8 sdio_ireg;
static const struct btmrvl_sdio_card_reg btmrvl_reg_8688 = {
.cfg = 0x03,
.host_int_mask = 0x04,
.host_intstatus = 0x05,
.card_status = 0x20,
.sq_read_base_addr_a0 = 0x10,
.sq_read_base_addr_a1 = 0x11,
.card_fw_status0 = 0x40,
.card_fw_status1 = 0x41,
.card_rx_len = 0x42,
.card_rx_unit = 0x43,
.io_port_0 = 0x00,
.io_port_1 = 0x01,
.io_port_2 = 0x02,
};
static const struct btmrvl_sdio_card_reg btmrvl_reg_8787 = {
.cfg = 0x00,
.host_int_mask = 0x02,
.host_intstatus = 0x03,
.card_status = 0x30,
.sq_read_base_addr_a0 = 0x40,
.sq_read_base_addr_a1 = 0x41,
.card_revision = 0x5c,
.card_fw_status0 = 0x60,
.card_fw_status1 = 0x61,
.card_rx_len = 0x62,
.card_rx_unit = 0x63,
.io_port_0 = 0x78,
.io_port_1 = 0x79,
.io_port_2 = 0x7a,
};
static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = { static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = {
.helper = "sd8688_helper.bin", .helper = "sd8688_helper.bin",
.firmware = "sd8688.bin", .firmware = "sd8688.bin",
.reg = &btmrvl_reg_8688,
.sd_blksz_fw_dl = 64,
};
static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
.helper = NULL,
.firmware = "mrvl/sd8787_uapsta.bin",
.reg = &btmrvl_reg_8787,
.sd_blksz_fw_dl = 256,
}; };
static const struct sdio_device_id btmrvl_sdio_ids[] = { static const struct sdio_device_id btmrvl_sdio_ids[] = {
/* Marvell SD8688 Bluetooth device */ /* Marvell SD8688 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105), { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105),
.driver_data = (unsigned long) &btmrvl_sdio_sd6888 }, .driver_data = (unsigned long) &btmrvl_sdio_sd6888 },
/* Marvell SD8787 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A),
.driver_data = (unsigned long) &btmrvl_sdio_sd8787 },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
@ -69,7 +113,7 @@ static int btmrvl_sdio_get_rx_unit(struct btmrvl_sdio_card *card)
u8 reg; u8 reg;
int ret; int ret;
reg = sdio_readb(card->func, CARD_RX_UNIT_REG, &ret); reg = sdio_readb(card->func, card->reg->card_rx_unit, &ret);
if (!ret) if (!ret)
card->rx_unit = reg; card->rx_unit = reg;
@ -83,11 +127,11 @@ static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat)
*dat = 0; *dat = 0;
fws0 = sdio_readb(card->func, CARD_FW_STATUS0_REG, &ret); fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret);
if (ret) if (ret)
return -EIO; return -EIO;
fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret); fws1 = sdio_readb(card->func, card->reg->card_fw_status1, &ret);
if (ret) if (ret)
return -EIO; return -EIO;
@ -101,7 +145,7 @@ static int btmrvl_sdio_read_rx_len(struct btmrvl_sdio_card *card, u16 *dat)
u8 reg; u8 reg;
int ret; int ret;
reg = sdio_readb(card->func, CARD_RX_LEN_REG, &ret); reg = sdio_readb(card->func, card->reg->card_rx_len, &ret);
if (!ret) if (!ret)
*dat = (u16) reg << card->rx_unit; *dat = (u16) reg << card->rx_unit;
@ -113,7 +157,7 @@ static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card,
{ {
int ret; int ret;
sdio_writeb(card->func, mask, HOST_INT_MASK_REG, &ret); sdio_writeb(card->func, mask, card->reg->host_int_mask, &ret);
if (ret) { if (ret) {
BT_ERR("Unable to enable the host interrupt!"); BT_ERR("Unable to enable the host interrupt!");
ret = -EIO; ret = -EIO;
@ -128,13 +172,13 @@ static int btmrvl_sdio_disable_host_int_mask(struct btmrvl_sdio_card *card,
u8 host_int_mask; u8 host_int_mask;
int ret; int ret;
host_int_mask = sdio_readb(card->func, HOST_INT_MASK_REG, &ret); host_int_mask = sdio_readb(card->func, card->reg->host_int_mask, &ret);
if (ret) if (ret)
return -EIO; return -EIO;
host_int_mask &= ~mask; host_int_mask &= ~mask;
sdio_writeb(card->func, host_int_mask, HOST_INT_MASK_REG, &ret); sdio_writeb(card->func, host_int_mask, card->reg->host_int_mask, &ret);
if (ret < 0) { if (ret < 0) {
BT_ERR("Unable to disable the host interrupt!"); BT_ERR("Unable to disable the host interrupt!");
return -EIO; return -EIO;
@ -150,7 +194,7 @@ static int btmrvl_sdio_poll_card_status(struct btmrvl_sdio_card *card, u8 bits)
int ret; int ret;
for (tries = 0; tries < MAX_POLL_TRIES * 1000; tries++) { for (tries = 0; tries < MAX_POLL_TRIES * 1000; tries++) {
status = sdio_readb(card->func, CARD_STATUS_REG, &ret); status = sdio_readb(card->func, card->reg->card_status, &ret);
if (ret) if (ret)
goto failed; goto failed;
if ((status & bits) == bits) if ((status & bits) == bits)
@ -299,7 +343,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
u8 base0, base1; u8 base0, base1;
void *tmpfwbuf = NULL; void *tmpfwbuf = NULL;
u8 *fwbuf; u8 *fwbuf;
u16 len; u16 len, blksz_dl = card->sd_blksz_fw_dl;
int txlen = 0, tx_blocks = 0, count = 0; int txlen = 0, tx_blocks = 0, count = 0;
ret = request_firmware(&fw_firmware, card->firmware, ret = request_firmware(&fw_firmware, card->firmware,
@ -345,7 +389,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
for (tries = 0; tries < MAX_POLL_TRIES; tries++) { for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
base0 = sdio_readb(card->func, base0 = sdio_readb(card->func,
SQ_READ_BASE_ADDRESS_A0_REG, &ret); card->reg->sq_read_base_addr_a0, &ret);
if (ret) { if (ret) {
BT_ERR("BASE0 register read failed:" BT_ERR("BASE0 register read failed:"
" base0 = 0x%04X(%d)." " base0 = 0x%04X(%d)."
@ -355,7 +399,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
goto done; goto done;
} }
base1 = sdio_readb(card->func, base1 = sdio_readb(card->func,
SQ_READ_BASE_ADDRESS_A1_REG, &ret); card->reg->sq_read_base_addr_a1, &ret);
if (ret) { if (ret) {
BT_ERR("BASE1 register read failed:" BT_ERR("BASE1 register read failed:"
" base1 = 0x%04X(%d)." " base1 = 0x%04X(%d)."
@ -403,20 +447,19 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
if (firmwarelen - offset < txlen) if (firmwarelen - offset < txlen)
txlen = firmwarelen - offset; txlen = firmwarelen - offset;
tx_blocks = tx_blocks = (txlen + blksz_dl - 1) / blksz_dl;
(txlen + SDIO_BLOCK_SIZE - 1) / SDIO_BLOCK_SIZE;
memcpy(fwbuf, &firmware[offset], txlen); memcpy(fwbuf, &firmware[offset], txlen);
} }
ret = sdio_writesb(card->func, card->ioport, fwbuf, ret = sdio_writesb(card->func, card->ioport, fwbuf,
tx_blocks * SDIO_BLOCK_SIZE); tx_blocks * blksz_dl);
if (ret < 0) { if (ret < 0) {
BT_ERR("FW download, writesb(%d) failed @%d", BT_ERR("FW download, writesb(%d) failed @%d",
count, offset); count, offset);
sdio_writeb(card->func, HOST_CMD53_FIN, CONFIG_REG, sdio_writeb(card->func, HOST_CMD53_FIN,
&ret); card->reg->cfg, &ret);
if (ret) if (ret)
BT_ERR("writeb failed (CFG)"); BT_ERR("writeb failed (CFG)");
} }
@ -597,7 +640,7 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func)
priv = card->priv; priv = card->priv;
ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret); ireg = sdio_readb(card->func, card->reg->host_intstatus, &ret);
if (ret) { if (ret) {
BT_ERR("sdio_readb: read int status register failed"); BT_ERR("sdio_readb: read int status register failed");
return; return;
@ -613,7 +656,7 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func)
sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS | sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS |
UP_LD_HOST_INT_STATUS), UP_LD_HOST_INT_STATUS),
HOST_INTSTATUS_REG, &ret); card->reg->host_intstatus, &ret);
if (ret) { if (ret) {
BT_ERR("sdio_writeb: clear int status register failed"); BT_ERR("sdio_writeb: clear int status register failed");
return; return;
@ -664,7 +707,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
goto release_irq; goto release_irq;
} }
reg = sdio_readb(func, IO_PORT_0_REG, &ret); reg = sdio_readb(func, card->reg->io_port_0, &ret);
if (ret < 0) { if (ret < 0) {
ret = -EIO; ret = -EIO;
goto release_irq; goto release_irq;
@ -672,7 +715,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
card->ioport = reg; card->ioport = reg;
reg = sdio_readb(func, IO_PORT_1_REG, &ret); reg = sdio_readb(func, card->reg->io_port_1, &ret);
if (ret < 0) { if (ret < 0) {
ret = -EIO; ret = -EIO;
goto release_irq; goto release_irq;
@ -680,7 +723,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
card->ioport |= (reg << 8); card->ioport |= (reg << 8);
reg = sdio_readb(func, IO_PORT_2_REG, &ret); reg = sdio_readb(func, card->reg->io_port_2, &ret);
if (ret < 0) { if (ret < 0) {
ret = -EIO; ret = -EIO;
goto release_irq; goto release_irq;
@ -815,6 +858,8 @@ exit:
static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card)
{ {
int ret = 0; int ret = 0;
u8 fws0;
int pollnum = MAX_POLL_TRIES;
if (!card || !card->func) { if (!card || !card->func) {
BT_ERR("card or function is NULL!"); BT_ERR("card or function is NULL!");
@ -827,20 +872,36 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card)
goto done; goto done;
} }
ret = btmrvl_sdio_download_helper(card); /* Check if other function driver is downloading the firmware */
fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret);
if (ret) { if (ret) {
BT_ERR("Failed to download helper!"); BT_ERR("Failed to read FW downloading status!");
ret = -EIO; ret = -EIO;
goto done; goto done;
} }
if (fws0) {
BT_DBG("BT not the winner (%#x). Skip FW downloading", fws0);
if (btmrvl_sdio_download_fw_w_helper(card)) { /* Give other function more time to download the firmware */
BT_ERR("Failed to download firmware!"); pollnum *= 10;
ret = -EIO; } else {
goto done; if (card->helper) {
ret = btmrvl_sdio_download_helper(card);
if (ret) {
BT_ERR("Failed to download helper!");
ret = -EIO;
goto done;
}
}
if (btmrvl_sdio_download_fw_w_helper(card)) {
BT_ERR("Failed to download firmware!");
ret = -EIO;
goto done;
}
} }
if (btmrvl_sdio_verify_fw_download(card, MAX_POLL_TRIES)) { if (btmrvl_sdio_verify_fw_download(card, pollnum)) {
BT_ERR("FW failed to be active in time!"); BT_ERR("FW failed to be active in time!");
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
goto done; goto done;
@ -864,7 +925,7 @@ static int btmrvl_sdio_wakeup_fw(struct btmrvl_private *priv)
sdio_claim_host(card->func); sdio_claim_host(card->func);
sdio_writeb(card->func, HOST_POWER_UP, CONFIG_REG, &ret); sdio_writeb(card->func, HOST_POWER_UP, card->reg->cfg, &ret);
sdio_release_host(card->func); sdio_release_host(card->func);
@ -893,8 +954,10 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
if (id->driver_data) { if (id->driver_data) {
struct btmrvl_sdio_device *data = (void *) id->driver_data; struct btmrvl_sdio_device *data = (void *) id->driver_data;
card->helper = data->helper; card->helper = data->helper;
card->firmware = data->firmware; card->firmware = data->firmware;
card->reg = data->reg;
card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
} }
if (btmrvl_sdio_register_dev(card) < 0) { if (btmrvl_sdio_register_dev(card) < 0) {
@ -1011,3 +1074,4 @@ MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE("sd8688_helper.bin"); MODULE_FIRMWARE("sd8688_helper.bin");
MODULE_FIRMWARE("sd8688.bin"); MODULE_FIRMWARE("sd8688.bin");
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");

View File

@ -47,44 +47,46 @@
/* Max retry number of CMD53 write */ /* Max retry number of CMD53 write */
#define MAX_WRITE_IOMEM_RETRY 2 #define MAX_WRITE_IOMEM_RETRY 2
/* Host Control Registers */ /* register bitmasks */
#define IO_PORT_0_REG 0x00 #define HOST_POWER_UP BIT(1)
#define IO_PORT_1_REG 0x01 #define HOST_CMD53_FIN BIT(2)
#define IO_PORT_2_REG 0x02
#define CONFIG_REG 0x03 #define HIM_DISABLE 0xff
#define HOST_POWER_UP BIT(1) #define HIM_ENABLE (BIT(0) | BIT(1))
#define HOST_CMD53_FIN BIT(2)
#define HOST_INT_MASK_REG 0x04 #define UP_LD_HOST_INT_STATUS BIT(0)
#define HIM_DISABLE 0xff #define DN_LD_HOST_INT_STATUS BIT(1)
#define HIM_ENABLE (BIT(0) | BIT(1))
#define HOST_INTSTATUS_REG 0x05 #define DN_LD_CARD_RDY BIT(0)
#define UP_LD_HOST_INT_STATUS BIT(0) #define CARD_IO_READY BIT(3)
#define DN_LD_HOST_INT_STATUS BIT(1)
/* Card Control Registers */ #define FIRMWARE_READY 0xfedc
#define SQ_READ_BASE_ADDRESS_A0_REG 0x10
#define SQ_READ_BASE_ADDRESS_A1_REG 0x11
#define CARD_STATUS_REG 0x20
#define DN_LD_CARD_RDY BIT(0)
#define CARD_IO_READY BIT(3)
#define CARD_FW_STATUS0_REG 0x40
#define CARD_FW_STATUS1_REG 0x41
#define FIRMWARE_READY 0xfedc
#define CARD_RX_LEN_REG 0x42
#define CARD_RX_UNIT_REG 0x43
struct btmrvl_sdio_card_reg {
u8 cfg;
u8 host_int_mask;
u8 host_intstatus;
u8 card_status;
u8 sq_read_base_addr_a0;
u8 sq_read_base_addr_a1;
u8 card_revision;
u8 card_fw_status0;
u8 card_fw_status1;
u8 card_rx_len;
u8 card_rx_unit;
u8 io_port_0;
u8 io_port_1;
u8 io_port_2;
};
struct btmrvl_sdio_card { struct btmrvl_sdio_card {
struct sdio_func *func; struct sdio_func *func;
u32 ioport; u32 ioport;
const char *helper; const char *helper;
const char *firmware; const char *firmware;
const struct btmrvl_sdio_card_reg *reg;
u16 sd_blksz_fw_dl;
u8 rx_unit; u8 rx_unit;
struct btmrvl_private *priv; struct btmrvl_private *priv;
}; };
@ -92,6 +94,8 @@ struct btmrvl_sdio_card {
struct btmrvl_sdio_device { struct btmrvl_sdio_device {
const char *helper; const char *helper;
const char *firmware; const char *firmware;
const struct btmrvl_sdio_card_reg *reg;
u16 sd_blksz_fw_dl;
}; };

View File

@ -104,6 +104,7 @@ static struct usb_device_id blacklist_table[] = {
/* Atheros 3011 with sflash firmware */ /* Atheros 3011 with sflash firmware */
{ USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
/* Atheros AR9285 Malbec with sflash firmware */ /* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },

View File

@ -201,8 +201,13 @@ static struct sk_buff *ath_dequeue(struct hci_uart *hu)
/* Recv data */ /* Recv data */
static int ath_recv(struct hci_uart *hu, void *data, int count) static int ath_recv(struct hci_uart *hu, void *data, int count)
{ {
if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) int ret;
ret = hci_recv_stream_fragment(hu->hdev, data, count);
if (ret < 0) {
BT_ERR("Frame Reassembly Failed"); BT_ERR("Frame Reassembly Failed");
return ret;
}
return count; return count;
} }

View File

@ -151,8 +151,13 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len)
/* Recv data */ /* Recv data */
static int h4_recv(struct hci_uart *hu, void *data, int count) static int h4_recv(struct hci_uart *hu, void *data, int count)
{ {
if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) int ret;
ret = hci_recv_stream_fragment(hu->hdev, data, count);
if (ret < 0) {
BT_ERR("Frame Reassembly Failed"); BT_ERR("Frame Reassembly Failed");
return ret;
}
return count; return count;
} }

View File

@ -359,6 +359,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
*/ */
static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count)
{ {
int ret;
struct hci_uart *hu = (void *)tty->disc_data; struct hci_uart *hu = (void *)tty->disc_data;
if (!hu || tty != hu->tty) if (!hu || tty != hu->tty)
@ -368,8 +369,9 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *f
return; return;
spin_lock(&hu->rx_lock); spin_lock(&hu->rx_lock);
hu->proto->recv(hu, (void *) data, count); ret = hu->proto->recv(hu, (void *) data, count);
hu->hdev->stat.byte_rx += count; if (ret > 0)
hu->hdev->stat.byte_rx += count;
spin_unlock(&hu->rx_lock); spin_unlock(&hu->rx_lock);
tty_unthrottle(tty); tty_unthrottle(tty);

View File

@ -393,16 +393,6 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
priv = netdev_priv(dev); priv = netdev_priv(dev);
priv->phy = phy; priv->phy = phy;
/*
* 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;
}
wpan_phy_set_dev(phy, &pdev->dev); wpan_phy_set_dev(phy, &pdev->dev);
SET_NETDEV_DEV(dev, &phy->dev); SET_NETDEV_DEV(dev, &phy->dev);

View File

@ -185,15 +185,20 @@ static int addr4_resolve(struct sockaddr_in *src_in,
__be32 dst_ip = dst_in->sin_addr.s_addr; __be32 dst_ip = dst_in->sin_addr.s_addr;
struct rtable *rt; struct rtable *rt;
struct neighbour *neigh; struct neighbour *neigh;
struct flowi4 fl4;
int ret; int ret;
rt = ip_route_output(&init_net, dst_ip, src_ip, 0, addr->bound_dev_if); memset(&fl4, 0, sizeof(fl4));
fl4.daddr = dst_ip;
fl4.saddr = src_ip;
fl4.flowi4_oif = addr->bound_dev_if;
rt = ip_route_output_key(&init_net, &fl4);
if (IS_ERR(rt)) { if (IS_ERR(rt)) {
ret = PTR_ERR(rt); ret = PTR_ERR(rt);
goto out; goto out;
} }
src_in->sin_family = AF_INET; src_in->sin_family = AF_INET;
src_in->sin_addr.s_addr = rt->rt_src; src_in->sin_addr.s_addr = fl4.saddr;
if (rt->dst.dev->flags & IFF_LOOPBACK) { if (rt->dst.dev->flags & IFF_LOOPBACK) {
ret = rdma_translate_ip((struct sockaddr *) dst_in, addr); ret = rdma_translate_ip((struct sockaddr *) dst_in, addr);

View File

@ -338,8 +338,9 @@ static struct rtable *find_route(struct t3cdev *dev, __be32 local_ip,
__be16 peer_port, u8 tos) __be16 peer_port, u8 tos)
{ {
struct rtable *rt; struct rtable *rt;
struct flowi4 fl4;
rt = ip_route_output_ports(&init_net, NULL, peer_ip, local_ip, rt = ip_route_output_ports(&init_net, &fl4, NULL, peer_ip, local_ip,
peer_port, local_port, IPPROTO_TCP, peer_port, local_port, IPPROTO_TCP,
tos, 0); tos, 0);
if (IS_ERR(rt)) if (IS_ERR(rt))

View File

@ -315,8 +315,9 @@ static struct rtable *find_route(struct c4iw_dev *dev, __be32 local_ip,
__be16 peer_port, u8 tos) __be16 peer_port, u8 tos)
{ {
struct rtable *rt; struct rtable *rt;
struct flowi4 fl4;
rt = ip_route_output_ports(&init_net, NULL, peer_ip, local_ip, rt = ip_route_output_ports(&init_net, &fl4, NULL, peer_ip, local_ip,
peer_port, local_port, IPPROTO_TCP, peer_port, local_port, IPPROTO_TCP,
tos, 0); tos, 0);
if (IS_ERR(rt)) if (IS_ERR(rt))

View File

@ -2885,9 +2885,8 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
if ((cqe_errv & if ((cqe_errv &
(NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_TCPUDP_CSUM_ERR | (NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_TCPUDP_CSUM_ERR |
NES_NIC_ERRV_BITS_IPH_ERR | NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) { NES_NIC_ERRV_BITS_IPH_ERR | NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) {
if (nesvnic->rx_checksum_disabled == 0) { if (nesvnic->netdev->features & NETIF_F_RXCSUM)
rx_skb->ip_summed = CHECKSUM_UNNECESSARY; rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
}
} else } else
nes_debug(NES_DBG_CQ, "%s: unsuccessfully checksummed TCP or UDP packet." nes_debug(NES_DBG_CQ, "%s: unsuccessfully checksummed TCP or UDP packet."
" errv = 0x%X, pkt_type = 0x%X.\n", " errv = 0x%X, pkt_type = 0x%X.\n",
@ -2897,7 +2896,7 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
if ((cqe_errv & if ((cqe_errv &
(NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_IPH_ERR | (NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_IPH_ERR |
NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) { NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) {
if (nesvnic->rx_checksum_disabled == 0) { if (nesvnic->netdev->features & NETIF_F_RXCSUM) {
rx_skb->ip_summed = CHECKSUM_UNNECESSARY; rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
/* nes_debug(NES_DBG_CQ, "%s: Reporting successfully checksummed IPv4 packet.\n", /* nes_debug(NES_DBG_CQ, "%s: Reporting successfully checksummed IPv4 packet.\n",
nesvnic->netdev->name); */ nesvnic->netdev->name); */

View File

@ -1245,7 +1245,6 @@ struct nes_vnic {
u8 next_qp_nic_index; u8 next_qp_nic_index;
u8 of_device_registered; u8 of_device_registered;
u8 rdma_enabled; u8 rdma_enabled;
u8 rx_checksum_disabled;
u32 lro_max_aggr; u32 lro_max_aggr;
struct net_lro_mgr lro_mgr; struct net_lro_mgr lro_mgr;
struct net_lro_desc lro_desc[NES_MAX_LRO_DESCRIPTORS]; struct net_lro_desc lro_desc[NES_MAX_LRO_DESCRIPTORS];

View File

@ -1093,34 +1093,6 @@ static const char nes_ethtool_stringset[][ETH_GSTRING_LEN] = {
}; };
#define NES_ETHTOOL_STAT_COUNT ARRAY_SIZE(nes_ethtool_stringset) #define NES_ETHTOOL_STAT_COUNT ARRAY_SIZE(nes_ethtool_stringset)
/**
* nes_netdev_get_rx_csum
*/
static u32 nes_netdev_get_rx_csum (struct net_device *netdev)
{
struct nes_vnic *nesvnic = netdev_priv(netdev);
if (nesvnic->rx_checksum_disabled)
return 0;
else
return 1;
}
/**
* nes_netdev_set_rc_csum
*/
static int nes_netdev_set_rx_csum(struct net_device *netdev, u32 enable)
{
struct nes_vnic *nesvnic = netdev_priv(netdev);
if (enable)
nesvnic->rx_checksum_disabled = 0;
else
nesvnic->rx_checksum_disabled = 1;
return 0;
}
/** /**
* nes_netdev_get_sset_count * nes_netdev_get_sset_count
@ -1521,7 +1493,7 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd
et_cmd->maxrxpkt = 511; et_cmd->maxrxpkt = 511;
if (nesadapter->OneG_Mode) { if (nesadapter->OneG_Mode) {
et_cmd->speed = SPEED_1000; ethtool_cmd_speed_set(et_cmd, SPEED_1000);
if (phy_type == NES_PHY_TYPE_PUMA_1G) { if (phy_type == NES_PHY_TYPE_PUMA_1G) {
et_cmd->supported = SUPPORTED_1000baseT_Full; et_cmd->supported = SUPPORTED_1000baseT_Full;
et_cmd->advertising = ADVERTISED_1000baseT_Full; et_cmd->advertising = ADVERTISED_1000baseT_Full;
@ -1560,7 +1532,7 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd
et_cmd->advertising = ADVERTISED_10000baseT_Full; et_cmd->advertising = ADVERTISED_10000baseT_Full;
et_cmd->phy_address = mac_index; et_cmd->phy_address = mac_index;
} }
et_cmd->speed = SPEED_10000; ethtool_cmd_speed_set(et_cmd, SPEED_10000);
et_cmd->autoneg = AUTONEG_DISABLE; et_cmd->autoneg = AUTONEG_DISABLE;
return 0; return 0;
} }
@ -1598,19 +1570,10 @@ static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd
} }
static int nes_netdev_set_flags(struct net_device *netdev, u32 flags)
{
return ethtool_op_set_flags(netdev, flags, ETH_FLAG_LRO);
}
static const struct ethtool_ops nes_ethtool_ops = { static const struct ethtool_ops nes_ethtool_ops = {
.get_link = ethtool_op_get_link, .get_link = ethtool_op_get_link,
.get_settings = nes_netdev_get_settings, .get_settings = nes_netdev_get_settings,
.set_settings = nes_netdev_set_settings, .set_settings = nes_netdev_set_settings,
.get_tx_csum = ethtool_op_get_tx_csum,
.get_rx_csum = nes_netdev_get_rx_csum,
.get_sg = ethtool_op_get_sg,
.get_strings = nes_netdev_get_strings, .get_strings = nes_netdev_get_strings,
.get_sset_count = nes_netdev_get_sset_count, .get_sset_count = nes_netdev_get_sset_count,
.get_ethtool_stats = nes_netdev_get_ethtool_stats, .get_ethtool_stats = nes_netdev_get_ethtool_stats,
@ -1619,13 +1582,6 @@ static const struct ethtool_ops nes_ethtool_ops = {
.set_coalesce = nes_netdev_set_coalesce, .set_coalesce = nes_netdev_set_coalesce,
.get_pauseparam = nes_netdev_get_pauseparam, .get_pauseparam = nes_netdev_get_pauseparam,
.set_pauseparam = nes_netdev_set_pauseparam, .set_pauseparam = nes_netdev_set_pauseparam,
.set_tx_csum = ethtool_op_set_tx_csum,
.set_rx_csum = nes_netdev_set_rx_csum,
.set_sg = ethtool_op_set_sg,
.get_tso = ethtool_op_get_tso,
.set_tso = ethtool_op_set_tso,
.get_flags = ethtool_op_get_flags,
.set_flags = nes_netdev_set_flags,
}; };
@ -1727,12 +1683,11 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
netdev->dev_addr[5] = (u8)u64temp; netdev->dev_addr[5] = (u8)u64temp;
memcpy(netdev->perm_addr, netdev->dev_addr, 6); memcpy(netdev->perm_addr, netdev->dev_addr, 6);
if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV)) { netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_IP_CSUM;
netdev->features |= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM; if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV))
netdev->features |= NETIF_F_GSO | NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM; netdev->hw_features |= NETIF_F_TSO;
} else { netdev->features |= netdev->hw_features;
netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; netdev->hw_features |= NETIF_F_LRO;
}
nes_debug(NES_DBG_INIT, "nesvnic = %p, reported features = 0x%lX, QPid = %d," nes_debug(NES_DBG_INIT, "nesvnic = %p, reported features = 0x%lX, QPid = %d,"
" nic_index = %d, logical_port = %d, mac_index = %d.\n", " nic_index = %d, logical_port = %d, mac_index = %d.\n",

View File

@ -91,7 +91,6 @@ enum {
IPOIB_STOP_REAPER = 7, IPOIB_STOP_REAPER = 7,
IPOIB_FLAG_ADMIN_CM = 9, IPOIB_FLAG_ADMIN_CM = 9,
IPOIB_FLAG_UMCAST = 10, IPOIB_FLAG_UMCAST = 10,
IPOIB_FLAG_CSUM = 11,
IPOIB_MAX_BACKOFF_SECONDS = 16, IPOIB_MAX_BACKOFF_SECONDS = 16,

View File

@ -1463,8 +1463,7 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
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");
netdev_update_features(dev);
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;
@ -1474,13 +1473,7 @@ 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);
netdev_update_features(dev);
if (test_bit(IPOIB_FLAG_CSUM, &priv->flags)) {
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
priv->dev->features |= NETIF_F_GRO;
if (priv->hca_caps & IB_DEVICE_UD_TSO)
dev->features |= NETIF_F_TSO;
}
dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu)); dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu));
rtnl_unlock(); rtnl_unlock();
ipoib_flush_paths(dev); ipoib_flush_paths(dev);

View File

@ -42,32 +42,6 @@ static void ipoib_get_drvinfo(struct net_device *netdev,
strncpy(drvinfo->driver, "ipoib", sizeof(drvinfo->driver) - 1); strncpy(drvinfo->driver, "ipoib", sizeof(drvinfo->driver) - 1);
} }
static u32 ipoib_get_rx_csum(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
return test_bit(IPOIB_FLAG_CSUM, &priv->flags) &&
!test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
}
static int ipoib_set_tso(struct net_device *dev, u32 data)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
if (data) {
if (!test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags) &&
(dev->features & NETIF_F_SG) &&
(priv->hca_caps & IB_DEVICE_UD_TSO)) {
dev->features |= NETIF_F_TSO;
} else {
ipoib_warn(priv, "can't set TSO on\n");
return -EOPNOTSUPP;
}
} else
dev->features &= ~NETIF_F_TSO;
return 0;
}
static int ipoib_get_coalesce(struct net_device *dev, static int ipoib_get_coalesce(struct net_device *dev,
struct ethtool_coalesce *coal) struct ethtool_coalesce *coal)
{ {
@ -108,8 +82,6 @@ static int ipoib_set_coalesce(struct net_device *dev,
static const struct ethtool_ops ipoib_ethtool_ops = { static const struct ethtool_ops ipoib_ethtool_ops = {
.get_drvinfo = ipoib_get_drvinfo, .get_drvinfo = ipoib_get_drvinfo,
.get_rx_csum = ipoib_get_rx_csum,
.set_tso = ipoib_set_tso,
.get_coalesce = ipoib_get_coalesce, .get_coalesce = ipoib_get_coalesce,
.set_coalesce = ipoib_set_coalesce, .set_coalesce = ipoib_set_coalesce,
}; };

View File

@ -292,7 +292,7 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
dev->stats.rx_bytes += skb->len; dev->stats.rx_bytes += skb->len;
skb->dev = dev; skb->dev = dev;
if (test_bit(IPOIB_FLAG_CSUM, &priv->flags) && likely(wc->csum_ok)) if ((dev->features & NETIF_F_RXCSUM) && likely(wc->csum_ok))
skb->ip_summed = CHECKSUM_UNNECESSARY; skb->ip_summed = CHECKSUM_UNNECESSARY;
napi_gro_receive(&priv->napi, skb); napi_gro_receive(&priv->napi, skb);

View File

@ -171,6 +171,16 @@ static int ipoib_stop(struct net_device *dev)
return 0; return 0;
} }
static u32 ipoib_fix_features(struct net_device *dev, u32 features)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
if (test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags))
features &= ~(NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
return features;
}
static int ipoib_change_mtu(struct net_device *dev, int new_mtu) static int ipoib_change_mtu(struct net_device *dev, int new_mtu)
{ {
struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_dev_priv *priv = netdev_priv(dev);
@ -970,6 +980,7 @@ static const struct net_device_ops ipoib_netdev_ops = {
.ndo_open = ipoib_open, .ndo_open = ipoib_open,
.ndo_stop = ipoib_stop, .ndo_stop = ipoib_stop,
.ndo_change_mtu = ipoib_change_mtu, .ndo_change_mtu = ipoib_change_mtu,
.ndo_fix_features = ipoib_fix_features,
.ndo_start_xmit = ipoib_start_xmit, .ndo_start_xmit = ipoib_start_xmit,
.ndo_tx_timeout = ipoib_timeout, .ndo_tx_timeout = ipoib_timeout,
.ndo_set_multicast_list = ipoib_set_mcast_list, .ndo_set_multicast_list = ipoib_set_mcast_list,
@ -1154,19 +1165,18 @@ int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca)
kfree(device_attr); kfree(device_attr);
if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) { if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) {
set_bit(IPOIB_FLAG_CSUM, &priv->flags); priv->dev->hw_features = NETIF_F_SG |
priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
if (priv->hca_caps & IB_DEVICE_UD_TSO)
priv->dev->hw_features |= NETIF_F_TSO;
priv->dev->features |= priv->dev->hw_features;
} }
priv->dev->features |= NETIF_F_GRO;
if (priv->dev->features & NETIF_F_SG && priv->hca_caps & IB_DEVICE_UD_TSO)
priv->dev->features |= NETIF_F_TSO;
return 0; return 0;
} }
static struct net_device *ipoib_add_port(const char *format, static struct net_device *ipoib_add_port(const char *format,
struct ib_device *hca, u8 port) struct ib_device *hca, u8 port)
{ {

View File

@ -33,21 +33,6 @@ config ISDN_CAPI_CAPI20
standardized libcapi20 to access this functionality. You should say standardized libcapi20 to access this functionality. You should say
Y/M here. Y/M here.
config ISDN_CAPI_CAPIFS_BOOL
bool "CAPI2.0 filesystem support (DEPRECATED)"
depends on ISDN_CAPI_MIDDLEWARE && ISDN_CAPI_CAPI20
help
This option provides a special file system, similar to /dev/pts with
device nodes for the special ttys established by using the
middleware extension above.
You no longer need this, udev fully replaces it. This feature is
scheduled for removal.
config ISDN_CAPI_CAPIFS
tristate
depends on ISDN_CAPI_CAPIFS_BOOL
default ISDN_CAPI_CAPI20
config ISDN_CAPI_CAPIDRV config ISDN_CAPI_CAPIDRV
tristate "CAPI2.0 capidrv interface support" tristate "CAPI2.0 capidrv interface support"
depends on ISDN_I4L depends on ISDN_I4L

View File

@ -7,7 +7,6 @@
obj-$(CONFIG_ISDN_CAPI) += kernelcapi.o obj-$(CONFIG_ISDN_CAPI) += kernelcapi.o
obj-$(CONFIG_ISDN_CAPI_CAPI20) += capi.o obj-$(CONFIG_ISDN_CAPI_CAPI20) += capi.o
obj-$(CONFIG_ISDN_CAPI_CAPIDRV) += capidrv.o obj-$(CONFIG_ISDN_CAPI_CAPIDRV) += capidrv.o
obj-$(CONFIG_ISDN_CAPI_CAPIFS) += capifs.o
# Multipart objects. # Multipart objects.

View File

@ -38,15 +38,10 @@
#include <linux/isdn/capiutil.h> #include <linux/isdn/capiutil.h>
#include <linux/isdn/capicmd.h> #include <linux/isdn/capicmd.h>
#include "capifs.h"
MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface"); MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface");
MODULE_AUTHOR("Carsten Paeth"); MODULE_AUTHOR("Carsten Paeth");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#undef _DEBUG_TTYFUNCS /* call to tty_driver */
#undef _DEBUG_DATAFLOW /* data flow */
/* -------- driver information -------------------------------------- */ /* -------- driver information -------------------------------------- */
static DEFINE_MUTEX(capi_mutex); static DEFINE_MUTEX(capi_mutex);
@ -85,7 +80,6 @@ struct capiminor {
struct kref kref; struct kref kref;
unsigned int minor; unsigned int minor;
struct dentry *capifs_dentry;
struct capi20_appl *ap; struct capi20_appl *ap;
u32 ncci; u32 ncci;
@ -300,17 +294,8 @@ static void capiminor_free(struct capiminor *mp)
static void capincci_alloc_minor(struct capidev *cdev, struct capincci *np) static void capincci_alloc_minor(struct capidev *cdev, struct capincci *np)
{ {
struct capiminor *mp; if (cdev->userflags & CAPIFLAG_HIGHJACKING)
dev_t device; np->minorp = capiminor_alloc(&cdev->ap, np->ncci);
if (!(cdev->userflags & CAPIFLAG_HIGHJACKING))
return;
mp = np->minorp = capiminor_alloc(&cdev->ap, np->ncci);
if (mp) {
device = MKDEV(capinc_tty_driver->major, mp->minor);
mp->capifs_dentry = capifs_new_ncci(mp->minor, device);
}
} }
static void capincci_free_minor(struct capincci *np) static void capincci_free_minor(struct capincci *np)
@ -319,8 +304,6 @@ static void capincci_free_minor(struct capincci *np)
struct tty_struct *tty; struct tty_struct *tty;
if (mp) { if (mp) {
capifs_free_ncci(mp->capifs_dentry);
tty = tty_port_tty_get(&mp->port); tty = tty_port_tty_get(&mp->port);
if (tty) { if (tty) {
tty_vhangup(tty); tty_vhangup(tty);
@ -432,9 +415,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
tty = tty_port_tty_get(&mp->port); tty = tty_port_tty_get(&mp->port);
if (!tty) { if (!tty) {
#ifdef _DEBUG_DATAFLOW pr_debug("capi: currently no receiver\n");
printk(KERN_DEBUG "capi: currently no receiver\n");
#endif
return -1; return -1;
} }
@ -447,23 +428,17 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
} }
if (ld->ops->receive_buf == NULL) { if (ld->ops->receive_buf == NULL) {
#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) pr_debug("capi: ldisc has no receive_buf function\n");
printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n");
#endif
/* fatal error, do not requeue */ /* fatal error, do not requeue */
goto free_skb; goto free_skb;
} }
if (mp->ttyinstop) { if (mp->ttyinstop) {
#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) pr_debug("capi: recv tty throttled\n");
printk(KERN_DEBUG "capi: recv tty throttled\n");
#endif
goto deref_ldisc; goto deref_ldisc;
} }
if (tty->receive_room < datalen) { if (tty->receive_room < datalen) {
#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) pr_debug("capi: no room in tty\n");
printk(KERN_DEBUG "capi: no room in tty\n");
#endif
goto deref_ldisc; goto deref_ldisc;
} }
@ -479,10 +454,8 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
if (errcode == CAPI_NOERROR) { if (errcode == CAPI_NOERROR) {
skb_pull(skb, CAPIMSG_LEN(skb->data)); skb_pull(skb, CAPIMSG_LEN(skb->data));
#ifdef _DEBUG_DATAFLOW pr_debug("capi: DATA_B3_RESP %u len=%d => ldisc\n",
printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n", datahandle, skb->len);
datahandle, skb->len);
#endif
ld->ops->receive_buf(tty, skb->data, NULL, skb->len); ld->ops->receive_buf(tty, skb->data, NULL, skb->len);
} else { } else {
printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n", printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
@ -529,9 +502,7 @@ static void handle_minor_send(struct capiminor *mp)
return; return;
if (mp->ttyoutstop) { if (mp->ttyoutstop) {
#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) pr_debug("capi: send: tty stopped\n");
printk(KERN_DEBUG "capi: send: tty stopped\n");
#endif
tty_kref_put(tty); tty_kref_put(tty);
return; return;
} }
@ -573,10 +544,8 @@ static void handle_minor_send(struct capiminor *mp)
} }
errcode = capi20_put_message(mp->ap, skb); errcode = capi20_put_message(mp->ap, skb);
if (errcode == CAPI_NOERROR) { if (errcode == CAPI_NOERROR) {
#ifdef _DEBUG_DATAFLOW pr_debug("capi: DATA_B3_REQ %u len=%u\n",
printk(KERN_DEBUG "capi: DATA_B3_REQ %u len=%u\n", datahandle, len);
datahandle, len);
#endif
continue; continue;
} }
capiminor_del_ack(mp, datahandle); capiminor_del_ack(mp, datahandle);
@ -650,10 +619,8 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
} }
if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) { if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2); datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2);
#ifdef _DEBUG_DATAFLOW pr_debug("capi_signal: DATA_B3_IND %u len=%d\n",
printk(KERN_DEBUG "capi_signal: DATA_B3_IND %u len=%d\n", datahandle, skb->len-CAPIMSG_LEN(skb->data));
datahandle, skb->len-CAPIMSG_LEN(skb->data));
#endif
skb_queue_tail(&mp->inqueue, skb); skb_queue_tail(&mp->inqueue, skb);
handle_minor_recv(mp); handle_minor_recv(mp);
@ -661,11 +628,9 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
} else if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF) { } else if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF) {
datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4); datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4);
#ifdef _DEBUG_DATAFLOW pr_debug("capi_signal: DATA_B3_CONF %u 0x%x\n",
printk(KERN_DEBUG "capi_signal: DATA_B3_CONF %u 0x%x\n", datahandle,
datahandle, CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2));
CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2));
#endif
kfree_skb(skb); kfree_skb(skb);
capiminor_del_ack(mp, datahandle); capiminor_del_ack(mp, datahandle);
tty = tty_port_tty_get(&mp->port); tty = tty_port_tty_get(&mp->port);
@ -1095,9 +1060,7 @@ static int capinc_tty_write(struct tty_struct *tty,
struct capiminor *mp = tty->driver_data; struct capiminor *mp = tty->driver_data;
struct sk_buff *skb; struct sk_buff *skb;
#ifdef _DEBUG_TTYFUNCS pr_debug("capinc_tty_write(count=%d)\n", count);
printk(KERN_DEBUG "capinc_tty_write(count=%d)\n", count);
#endif
spin_lock_bh(&mp->outlock); spin_lock_bh(&mp->outlock);
skb = mp->outskb; skb = mp->outskb;
@ -1133,9 +1096,7 @@ static int capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
struct sk_buff *skb; struct sk_buff *skb;
int ret = 1; int ret = 1;
#ifdef _DEBUG_TTYFUNCS pr_debug("capinc_put_char(%u)\n", ch);
printk(KERN_DEBUG "capinc_put_char(%u)\n", ch);
#endif
spin_lock_bh(&mp->outlock); spin_lock_bh(&mp->outlock);
skb = mp->outskb; skb = mp->outskb;
@ -1174,9 +1135,7 @@ static void capinc_tty_flush_chars(struct tty_struct *tty)
struct capiminor *mp = tty->driver_data; struct capiminor *mp = tty->driver_data;
struct sk_buff *skb; struct sk_buff *skb;
#ifdef _DEBUG_TTYFUNCS pr_debug("capinc_tty_flush_chars\n");
printk(KERN_DEBUG "capinc_tty_flush_chars\n");
#endif
spin_lock_bh(&mp->outlock); spin_lock_bh(&mp->outlock);
skb = mp->outskb; skb = mp->outskb;
@ -1200,9 +1159,7 @@ static int capinc_tty_write_room(struct tty_struct *tty)
room = CAPINC_MAX_SENDQUEUE-skb_queue_len(&mp->outqueue); room = CAPINC_MAX_SENDQUEUE-skb_queue_len(&mp->outqueue);
room *= CAPI_MAX_BLKSIZE; room *= CAPI_MAX_BLKSIZE;
#ifdef _DEBUG_TTYFUNCS pr_debug("capinc_tty_write_room = %d\n", room);
printk(KERN_DEBUG "capinc_tty_write_room = %d\n", room);
#endif
return room; return room;
} }
@ -1210,12 +1167,10 @@ static int capinc_tty_chars_in_buffer(struct tty_struct *tty)
{ {
struct capiminor *mp = tty->driver_data; struct capiminor *mp = tty->driver_data;
#ifdef _DEBUG_TTYFUNCS pr_debug("capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%d\n",
printk(KERN_DEBUG "capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%d\n", mp->outbytes, mp->nack,
mp->outbytes, mp->nack, skb_queue_len(&mp->outqueue),
skb_queue_len(&mp->outqueue), skb_queue_len(&mp->inqueue));
skb_queue_len(&mp->inqueue));
#endif
return mp->outbytes; return mp->outbytes;
} }
@ -1227,17 +1182,13 @@ static int capinc_tty_ioctl(struct tty_struct *tty,
static void capinc_tty_set_termios(struct tty_struct *tty, struct ktermios * old) static void capinc_tty_set_termios(struct tty_struct *tty, struct ktermios * old)
{ {
#ifdef _DEBUG_TTYFUNCS pr_debug("capinc_tty_set_termios\n");
printk(KERN_DEBUG "capinc_tty_set_termios\n");
#endif
} }
static void capinc_tty_throttle(struct tty_struct *tty) static void capinc_tty_throttle(struct tty_struct *tty)
{ {
struct capiminor *mp = tty->driver_data; struct capiminor *mp = tty->driver_data;
#ifdef _DEBUG_TTYFUNCS pr_debug("capinc_tty_throttle\n");
printk(KERN_DEBUG "capinc_tty_throttle\n");
#endif
mp->ttyinstop = 1; mp->ttyinstop = 1;
} }
@ -1245,9 +1196,7 @@ static void capinc_tty_unthrottle(struct tty_struct *tty)
{ {
struct capiminor *mp = tty->driver_data; struct capiminor *mp = tty->driver_data;
#ifdef _DEBUG_TTYFUNCS pr_debug("capinc_tty_unthrottle\n");
printk(KERN_DEBUG "capinc_tty_unthrottle\n");
#endif
mp->ttyinstop = 0; mp->ttyinstop = 0;
handle_minor_recv(mp); handle_minor_recv(mp);
} }
@ -1256,9 +1205,7 @@ static void capinc_tty_stop(struct tty_struct *tty)
{ {
struct capiminor *mp = tty->driver_data; struct capiminor *mp = tty->driver_data;
#ifdef _DEBUG_TTYFUNCS pr_debug("capinc_tty_stop\n");
printk(KERN_DEBUG "capinc_tty_stop\n");
#endif
mp->ttyoutstop = 1; mp->ttyoutstop = 1;
} }
@ -1266,9 +1213,7 @@ static void capinc_tty_start(struct tty_struct *tty)
{ {
struct capiminor *mp = tty->driver_data; struct capiminor *mp = tty->driver_data;
#ifdef _DEBUG_TTYFUNCS pr_debug("capinc_tty_start\n");
printk(KERN_DEBUG "capinc_tty_start\n");
#endif
mp->ttyoutstop = 0; mp->ttyoutstop = 0;
handle_minor_send(mp); handle_minor_send(mp);
} }
@ -1277,39 +1222,29 @@ static void capinc_tty_hangup(struct tty_struct *tty)
{ {
struct capiminor *mp = tty->driver_data; struct capiminor *mp = tty->driver_data;
#ifdef _DEBUG_TTYFUNCS pr_debug("capinc_tty_hangup\n");
printk(KERN_DEBUG "capinc_tty_hangup\n");
#endif
tty_port_hangup(&mp->port); tty_port_hangup(&mp->port);
} }
static int capinc_tty_break_ctl(struct tty_struct *tty, int state) static int capinc_tty_break_ctl(struct tty_struct *tty, int state)
{ {
#ifdef _DEBUG_TTYFUNCS pr_debug("capinc_tty_break_ctl(%d)\n", state);
printk(KERN_DEBUG "capinc_tty_break_ctl(%d)\n", state);
#endif
return 0; return 0;
} }
static void capinc_tty_flush_buffer(struct tty_struct *tty) static void capinc_tty_flush_buffer(struct tty_struct *tty)
{ {
#ifdef _DEBUG_TTYFUNCS pr_debug("capinc_tty_flush_buffer\n");
printk(KERN_DEBUG "capinc_tty_flush_buffer\n");
#endif
} }
static void capinc_tty_set_ldisc(struct tty_struct *tty) static void capinc_tty_set_ldisc(struct tty_struct *tty)
{ {
#ifdef _DEBUG_TTYFUNCS pr_debug("capinc_tty_set_ldisc\n");
printk(KERN_DEBUG "capinc_tty_set_ldisc\n");
#endif
} }
static void capinc_tty_send_xchar(struct tty_struct *tty, char ch) static void capinc_tty_send_xchar(struct tty_struct *tty, char ch)
{ {
#ifdef _DEBUG_TTYFUNCS pr_debug("capinc_tty_send_xchar(%d)\n", ch);
printk(KERN_DEBUG "capinc_tty_send_xchar(%d)\n", ch);
#endif
} }
static const struct tty_operations capinc_ops = { static const struct tty_operations capinc_ops = {
@ -1514,10 +1449,8 @@ static int __init capi_init(void)
proc_init(); proc_init();
#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE) #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
compileinfo = " (middleware+capifs)"; compileinfo = " (middleware)";
#elif defined(CONFIG_ISDN_CAPI_MIDDLEWARE)
compileinfo = " (no capifs)";
#else #else
compileinfo = " (no middleware)"; compileinfo = " (no middleware)";
#endif #endif

View File

@ -1,239 +0,0 @@
/* $Id: capifs.c,v 1.1.2.3 2004/01/16 21:09:26 keil Exp $
*
* Copyright 2000 by Carsten Paeth <calle@calle.de>
*
* Heavily based on devpts filesystem from H. Peter Anvin
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
*/
#include <linux/fs.h>
#include <linux/mount.h>
#include <linux/slab.h>
#include <linux/namei.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/ctype.h>
#include <linux/sched.h> /* current */
#include "capifs.h"
MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem");
MODULE_AUTHOR("Carsten Paeth");
MODULE_LICENSE("GPL");
/* ------------------------------------------------------------------ */
#define CAPIFS_SUPER_MAGIC (('C'<<8)|'N')
static struct vfsmount *capifs_mnt;
static int capifs_mnt_count;
static struct {
int setuid;
int setgid;
uid_t uid;
gid_t gid;
umode_t mode;
} config = {.mode = 0600};
/* ------------------------------------------------------------------ */
static int capifs_remount(struct super_block *s, int *flags, char *data)
{
int setuid = 0;
int setgid = 0;
uid_t uid = 0;
gid_t gid = 0;
umode_t mode = 0600;
char *this_char;
char *new_opt = kstrdup(data, GFP_KERNEL);
this_char = NULL;
while ((this_char = strsep(&data, ",")) != NULL) {
int n;
char dummy;
if (!*this_char)
continue;
if (sscanf(this_char, "uid=%i%c", &n, &dummy) == 1) {
setuid = 1;
uid = n;
} else if (sscanf(this_char, "gid=%i%c", &n, &dummy) == 1) {
setgid = 1;
gid = n;
} else if (sscanf(this_char, "mode=%o%c", &n, &dummy) == 1)
mode = n & ~S_IFMT;
else {
kfree(new_opt);
printk("capifs: called with bogus options\n");
return -EINVAL;
}
}
mutex_lock(&s->s_root->d_inode->i_mutex);
replace_mount_options(s, new_opt);
config.setuid = setuid;
config.setgid = setgid;
config.uid = uid;
config.gid = gid;
config.mode = mode;
mutex_unlock(&s->s_root->d_inode->i_mutex);
return 0;
}
static const struct super_operations capifs_sops =
{
.statfs = simple_statfs,
.remount_fs = capifs_remount,
.show_options = generic_show_options,
};
static int
capifs_fill_super(struct super_block *s, void *data, int silent)
{
struct inode * inode;
s->s_blocksize = 1024;
s->s_blocksize_bits = 10;
s->s_magic = CAPIFS_SUPER_MAGIC;
s->s_op = &capifs_sops;
s->s_time_gran = 1;
inode = new_inode(s);
if (!inode)
goto fail;
inode->i_ino = 1;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
inode->i_nlink = 2;
s->s_root = d_alloc_root(inode);
if (s->s_root)
return 0;
printk("capifs: get root dentry failed\n");
iput(inode);
fail:
return -ENOMEM;
}
static struct dentry *capifs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
return mount_single(fs_type, flags, data, capifs_fill_super);
}
static struct file_system_type capifs_fs_type = {
.owner = THIS_MODULE,
.name = "capifs",
.mount = capifs_mount,
.kill_sb = kill_anon_super,
};
static struct dentry *new_ncci(unsigned int number, dev_t device)
{
struct super_block *s = capifs_mnt->mnt_sb;
struct dentry *root = s->s_root;
struct dentry *dentry;
struct inode *inode;
char name[10];
int namelen;
mutex_lock(&root->d_inode->i_mutex);
namelen = sprintf(name, "%d", number);
dentry = lookup_one_len(name, root, namelen);
if (IS_ERR(dentry)) {
dentry = NULL;
goto unlock_out;
}
if (dentry->d_inode) {
dput(dentry);
dentry = NULL;
goto unlock_out;
}
inode = new_inode(s);
if (!inode) {
dput(dentry);
dentry = NULL;
goto unlock_out;
}
/* config contents is protected by root's i_mutex */
inode->i_uid = config.setuid ? config.uid : current_fsuid();
inode->i_gid = config.setgid ? config.gid : current_fsgid();
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_ino = number + 2;
init_special_inode(inode, S_IFCHR|config.mode, device);
d_instantiate(dentry, inode);
dget(dentry);
unlock_out:
mutex_unlock(&root->d_inode->i_mutex);
return dentry;
}
struct dentry *capifs_new_ncci(unsigned int number, dev_t device)
{
struct dentry *dentry;
if (simple_pin_fs(&capifs_fs_type, &capifs_mnt, &capifs_mnt_count) < 0)
return NULL;
dentry = new_ncci(number, device);
if (!dentry)
simple_release_fs(&capifs_mnt, &capifs_mnt_count);
return dentry;
}
void capifs_free_ncci(struct dentry *dentry)
{
struct dentry *root = capifs_mnt->mnt_sb->s_root;
struct inode *inode;
if (!dentry)
return;
mutex_lock(&root->d_inode->i_mutex);
inode = dentry->d_inode;
if (inode) {
drop_nlink(inode);
d_delete(dentry);
dput(dentry);
}
dput(dentry);
mutex_unlock(&root->d_inode->i_mutex);
simple_release_fs(&capifs_mnt, &capifs_mnt_count);
}
static int __init capifs_init(void)
{
return register_filesystem(&capifs_fs_type);
}
static void __exit capifs_exit(void)
{
unregister_filesystem(&capifs_fs_type);
}
EXPORT_SYMBOL(capifs_new_ncci);
EXPORT_SYMBOL(capifs_free_ncci);
module_init(capifs_init);
module_exit(capifs_exit);

View File

@ -1,28 +0,0 @@
/* $Id: capifs.h,v 1.1.2.2 2004/01/16 21:09:26 keil Exp $
*
* Copyright 2000 by Carsten Paeth <calle@calle.de>
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
*/
#include <linux/dcache.h>
#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
struct dentry *capifs_new_ncci(unsigned int num, dev_t device);
void capifs_free_ncci(struct dentry *dentry);
#else
static inline struct dentry *capifs_new_ncci(unsigned int num, dev_t device)
{
return NULL;
}
static inline void capifs_free_ncci(struct dentry *dentry)
{
}
#endif

View File

@ -1157,7 +1157,6 @@ static void write_iso_tasklet(unsigned long data)
struct urb *urb; struct urb *urb;
int status; int status;
struct usb_iso_packet_descriptor *ifd; struct usb_iso_packet_descriptor *ifd;
int offset;
unsigned long flags; unsigned long flags;
int i; int i;
struct sk_buff *skb; struct sk_buff *skb;
@ -1225,7 +1224,6 @@ static void write_iso_tasklet(unsigned long data)
* successfully sent * successfully sent
* - all following frames are not sent at all * - all following frames are not sent at all
*/ */
offset = done->limit; /* default (no error) */
for (i = 0; i < BAS_NUMFRAMES; i++) { for (i = 0; i < BAS_NUMFRAMES; i++) {
ifd = &urb->iso_frame_desc[i]; ifd = &urb->iso_frame_desc[i];
if (ifd->status || if (ifd->status ||
@ -1235,9 +1233,6 @@ static void write_iso_tasklet(unsigned long data)
i, ifd->actual_length, i, ifd->actual_length,
ifd->length, ifd->length,
get_usb_statmsg(ifd->status)); get_usb_statmsg(ifd->status));
offset = (ifd->offset +
ifd->actual_length)
% BAS_OUTBUFSIZE;
break; break;
} }
} }

View File

@ -390,12 +390,12 @@ static const struct zsau_resp_t {
*/ */
static int cid_of_response(char *s) static int cid_of_response(char *s)
{ {
unsigned long cid; int cid;
int rc; int rc;
if (s[-1] != ';') if (s[-1] != ';')
return 0; /* no CID separator */ return 0; /* no CID separator */
rc = strict_strtoul(s, 10, &cid); rc = kstrtoint(s, 10, &cid);
if (rc) if (rc)
return 0; /* CID not numeric */ return 0; /* CID not numeric */
if (cid < 1 || cid > 65535) if (cid < 1 || cid > 65535)
@ -566,27 +566,19 @@ void gigaset_handle_modem_response(struct cardstate *cs)
case RT_ZCAU: case RT_ZCAU:
event->parameter = -1; event->parameter = -1;
if (curarg + 1 < params) { if (curarg + 1 < params) {
unsigned long type, value; u8 type, value;
i = strict_strtoul(argv[curarg++], 16, &type); i = kstrtou8(argv[curarg++], 16, &type);
j = strict_strtoul(argv[curarg++], 16, &value); j = kstrtou8(argv[curarg++], 16, &value);
if (i == 0 && j == 0)
if (i == 0 && type < 256 &&
j == 0 && value < 256)
event->parameter = (type << 8) | value; event->parameter = (type << 8) | value;
} else } else
curarg = params - 1; curarg = params - 1;
break; break;
case RT_NUMBER: case RT_NUMBER:
event->parameter = -1; if (curarg >= params ||
if (curarg < params) { kstrtoint(argv[curarg++], 10, &event->parameter))
unsigned long res; event->parameter = -1;
int rc;
rc = strict_strtoul(argv[curarg++], 10, &res);
if (rc == 0)
event->parameter = res;
}
gig_dbg(DEBUG_EVENT, "parameter==%d", event->parameter); gig_dbg(DEBUG_EVENT, "parameter==%d", event->parameter);
break; break;
} }

View File

@ -861,7 +861,7 @@ static int diva_get_idi_adapter_info (IDI_CALL request, dword* serial, dword* lo
void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) { void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) {
diva_os_spin_lock_magic_t old_irql, old_irql1; diva_os_spin_lock_magic_t old_irql, old_irql1;
dword sec, usec, logical, serial, org_mask; dword sec, usec, logical, serial, org_mask;
int id, best_id = 0, free_id = -1; int id, free_id = -1;
char tmp[128]; char tmp[128];
diva_dbg_entry_head_t* pmsg = NULL; diva_dbg_entry_head_t* pmsg = NULL;
int len; int len;
@ -906,7 +906,6 @@ void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) {
and slot is still free - reuse it and slot is still free - reuse it
*/ */
free_id = id; free_id = id;
best_id = 1;
break; break;
} }
} }

View File

@ -1198,7 +1198,6 @@ static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
word ch; word ch;
word i; word i;
word Info; word Info;
word CIP;
byte LinkLayer; byte LinkLayer;
API_PARSE * ai; API_PARSE * ai;
API_PARSE * bp; API_PARSE * bp;
@ -1340,7 +1339,6 @@ static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
add_s(plci,BC,&parms[6]); add_s(plci,BC,&parms[6]);
add_s(plci,LLC,&parms[7]); add_s(plci,LLC,&parms[7]);
add_s(plci,HLC,&parms[8]); add_s(plci,HLC,&parms[8]);
CIP = GET_WORD(parms[0].info);
if (a->Info_Mask[appl->Id-1] & 0x200) if (a->Info_Mask[appl->Id-1] & 0x200)
{ {
/* early B3 connect (CIP mask bit 9) no release after a disc */ /* early B3 connect (CIP mask bit 9) no release after a disc */
@ -4830,7 +4828,6 @@ static void sig_ind(PLCI *plci)
dword x_Id; dword x_Id;
dword Id; dword Id;
dword rId; dword rId;
word Number = 0;
word i; word i;
word cip; word cip;
dword cip_mask; dword cip_mask;
@ -5106,7 +5103,7 @@ static void sig_ind(PLCI *plci)
} }
} }
if(plci->appl) Number = plci->appl->Number++; if(plci->appl) plci->appl->Number++;
switch(plci->Sig.Ind) { switch(plci->Sig.Ind) {
/* Response to Get_Supported_Services request */ /* Response to Get_Supported_Services request */
@ -5894,7 +5891,6 @@ static void sig_ind(PLCI *plci)
break; break;
case TEL_CTRL: case TEL_CTRL:
Number = 0;
ie = multi_fac_parms[0]; /* inspect the facility hook indications */ ie = multi_fac_parms[0]; /* inspect the facility hook indications */
if(plci->State==ADVANCED_VOICE_SIG && ie[0]){ if(plci->State==ADVANCED_VOICE_SIG && ie[0]){
switch (ie[1]&0x91) { switch (ie[1]&0x91) {
@ -10119,14 +10115,12 @@ static byte dtmf_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
static void dtmf_confirmation (dword Id, PLCI *plci) static void dtmf_confirmation (dword Id, PLCI *plci)
{ {
word Info;
word i; word i;
byte result[4]; byte result[4];
dbug (1, dprintf ("[%06lx] %s,%d: dtmf_confirmation", dbug (1, dprintf ("[%06lx] %s,%d: dtmf_confirmation",
UnMapId (Id), (char *)(FILE_), __LINE__)); UnMapId (Id), (char *)(FILE_), __LINE__));
Info = GOOD;
result[0] = 2; result[0] = 2;
PUT_WORD (&result[1], DTMF_SUCCESS); PUT_WORD (&result[1], DTMF_SUCCESS);
if (plci->dtmf_send_requests != 0) if (plci->dtmf_send_requests != 0)
@ -11520,13 +11514,12 @@ static word mixer_restore_config (dword Id, PLCI *plci, byte Rc)
static void mixer_command (dword Id, PLCI *plci, byte Rc) static void mixer_command (dword Id, PLCI *plci, byte Rc)
{ {
DIVA_CAPI_ADAPTER *a; DIVA_CAPI_ADAPTER *a;
word i, internal_command, Info; word i, internal_command;
dbug (1, dprintf ("[%06lx] %s,%d: mixer_command %02x %04x %04x", dbug (1, dprintf ("[%06lx] %s,%d: mixer_command %02x %04x %04x",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command, UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command,
plci->li_cmd)); plci->li_cmd));
Info = GOOD;
a = plci->adapter; a = plci->adapter;
internal_command = plci->internal_command; internal_command = plci->internal_command;
plci->internal_command = 0; plci->internal_command = 0;
@ -11550,7 +11543,6 @@ static void mixer_command (dword Id, PLCI *plci, byte Rc)
{ {
dbug (1, dprintf ("[%06lx] %s,%d: Load mixer failed", dbug (1, dprintf ("[%06lx] %s,%d: Load mixer failed",
UnMapId (Id), (char *)(FILE_), __LINE__)); UnMapId (Id), (char *)(FILE_), __LINE__));
Info = _FACILITY_NOT_SUPPORTED;
break; break;
} }
if (plci->internal_command) if (plci->internal_command)
@ -11592,7 +11584,6 @@ static void mixer_command (dword Id, PLCI *plci, byte Rc)
} while ((plci->li_plci_b_write_pos != plci->li_plci_b_req_pos) } while ((plci->li_plci_b_write_pos != plci->li_plci_b_req_pos)
&& !(plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG)); && !(plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG));
} }
Info = _FACILITY_NOT_SUPPORTED;
break; break;
} }
if (plci->internal_command) if (plci->internal_command)
@ -11610,7 +11601,6 @@ static void mixer_command (dword Id, PLCI *plci, byte Rc)
{ {
dbug (1, dprintf ("[%06lx] %s,%d: Unload mixer failed", dbug (1, dprintf ("[%06lx] %s,%d: Unload mixer failed",
UnMapId (Id), (char *)(FILE_), __LINE__)); UnMapId (Id), (char *)(FILE_), __LINE__));
Info = _FACILITY_NOT_SUPPORTED;
break; break;
} }
if (plci->internal_command) if (plci->internal_command)
@ -12448,13 +12438,11 @@ static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
static void mixer_indication_coefs_set (dword Id, PLCI *plci) static void mixer_indication_coefs_set (dword Id, PLCI *plci)
{ {
dword d; dword d;
DIVA_CAPI_ADAPTER *a;
byte result[12]; byte result[12];
dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_coefs_set", dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_coefs_set",
UnMapId (Id), (char *)(FILE_), __LINE__)); UnMapId (Id), (char *)(FILE_), __LINE__));
a = plci->adapter;
if (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos) if (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos)
{ {
do do
@ -14111,13 +14099,11 @@ static void select_b_command (dword Id, PLCI *plci, byte Rc)
static void fax_connect_ack_command (dword Id, PLCI *plci, byte Rc) static void fax_connect_ack_command (dword Id, PLCI *plci, byte Rc)
{ {
word Info;
word internal_command; word internal_command;
dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_ack_command %02x %04x", dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_ack_command %02x %04x",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
Info = GOOD;
internal_command = plci->internal_command; internal_command = plci->internal_command;
plci->internal_command = 0; plci->internal_command = 0;
switch (internal_command) switch (internal_command)
@ -14160,13 +14146,11 @@ static void fax_connect_ack_command (dword Id, PLCI *plci, byte Rc)
static void fax_edata_ack_command (dword Id, PLCI *plci, byte Rc) static void fax_edata_ack_command (dword Id, PLCI *plci, byte Rc)
{ {
word Info;
word internal_command; word internal_command;
dbug (1, dprintf ("[%06lx] %s,%d: fax_edata_ack_command %02x %04x", dbug (1, dprintf ("[%06lx] %s,%d: fax_edata_ack_command %02x %04x",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
Info = GOOD;
internal_command = plci->internal_command; internal_command = plci->internal_command;
plci->internal_command = 0; plci->internal_command = 0;
switch (internal_command) switch (internal_command)
@ -14395,13 +14379,11 @@ static void rtp_connect_b3_req_command (dword Id, PLCI *plci, byte Rc)
static void rtp_connect_b3_res_command (dword Id, PLCI *plci, byte Rc) static void rtp_connect_b3_res_command (dword Id, PLCI *plci, byte Rc)
{ {
word Info;
word internal_command; word internal_command;
dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x", dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
Info = GOOD;
internal_command = plci->internal_command; internal_command = plci->internal_command;
plci->internal_command = 0; plci->internal_command = 0;
switch (internal_command) switch (internal_command)
@ -14423,7 +14405,6 @@ static void rtp_connect_b3_res_command (dword Id, PLCI *plci, byte Rc)
{ {
dbug (1, dprintf ("[%06lx] %s,%d: RTP setting connect resp info failed %02x", dbug (1, dprintf ("[%06lx] %s,%d: RTP setting connect resp info failed %02x",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
Info = _WRONG_STATE;
break; break;
} }
if (plci_nl_busy (plci)) if (plci_nl_busy (plci))

View File

@ -405,7 +405,7 @@ hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz,
u_char *bdata, int count) u_char *bdata, int count)
{ {
u_char *ptr, *ptr1, new_f2; u_char *ptr, *ptr1, new_f2;
int total, maxlen, new_z2; int maxlen, new_z2;
struct zt *zp; struct zt *zp;
if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO)) if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO))
@ -431,7 +431,6 @@ hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz,
printk(KERN_WARNING "HFCPCI: receive out of memory\n"); printk(KERN_WARNING "HFCPCI: receive out of memory\n");
return; return;
} }
total = count;
count -= 3; count -= 3;
ptr = skb_put(bch->rx_skb, count); ptr = skb_put(bch->rx_skb, count);
@ -968,7 +967,6 @@ 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",
@ -982,7 +980,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 */
val = Read_hfc(hc, HFCPCI_INT_S1); (void) 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);

View File

@ -118,14 +118,12 @@ static void
ctrl_complete(struct urb *urb) ctrl_complete(struct urb *urb)
{ {
struct hfcsusb *hw = (struct hfcsusb *) urb->context; struct hfcsusb *hw = (struct hfcsusb *) urb->context;
struct ctrl_buf *buf;
if (debug & DBG_HFC_CALL_TRACE) if (debug & DBG_HFC_CALL_TRACE)
printk(KERN_DEBUG "%s: %s\n", hw->name, __func__); printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
urb->dev = hw->dev; urb->dev = hw->dev;
if (hw->ctrl_cnt) { if (hw->ctrl_cnt) {
buf = &hw->ctrl_buff[hw->ctrl_out_idx];
hw->ctrl_cnt--; /* decrement actual count */ hw->ctrl_cnt--; /* decrement actual count */
if (++hw->ctrl_out_idx >= HFC_CTRL_BUFSIZE) if (++hw->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
hw->ctrl_out_idx = 0; /* pointer wrap */ hw->ctrl_out_idx = 0; /* pointer wrap */
@ -1726,7 +1724,6 @@ hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel)
static int static int
setup_hfcsusb(struct hfcsusb *hw) setup_hfcsusb(struct hfcsusb *hw)
{ {
int err;
u_char b; u_char b;
if (debug & DBG_HFC_CALL_TRACE) if (debug & DBG_HFC_CALL_TRACE)
@ -1745,7 +1742,7 @@ setup_hfcsusb(struct hfcsusb *hw)
} }
/* first set the needed config, interface and alternate */ /* first set the needed config, interface and alternate */
err = usb_set_interface(hw->dev, hw->if_used, hw->alt_used); (void) usb_set_interface(hw->dev, hw->if_used, hw->alt_used);
hw->led_state = 0; hw->led_state = 0;

View File

@ -30,8 +30,6 @@ add_arcofi_timer(struct IsdnCardState *cs) {
static void static void
send_arcofi(struct IsdnCardState *cs) { send_arcofi(struct IsdnCardState *cs) {
u_char val;
add_arcofi_timer(cs); add_arcofi_timer(cs);
cs->dc.isac.mon_txp = 0; cs->dc.isac.mon_txp = 0;
cs->dc.isac.mon_txc = cs->dc.isac.arcofi_list->len; cs->dc.isac.mon_txc = cs->dc.isac.arcofi_list->len;
@ -45,7 +43,7 @@ send_arcofi(struct IsdnCardState *cs) {
cs->dc.isac.mocr &= 0x0f; cs->dc.isac.mocr &= 0x0f;
cs->dc.isac.mocr |= 0xa0; cs->dc.isac.mocr |= 0xa0;
cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
val = cs->readisac(cs, ISAC_MOSR); (void) cs->readisac(cs, ISAC_MOSR);
cs->writeisac(cs, ISAC_MOX1, cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]); cs->writeisac(cs, ISAC_MOX1, cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]);
cs->dc.isac.mocr |= 0x10; cs->dc.isac.mocr |= 0x10;
cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);

View File

@ -129,12 +129,10 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
static int __devinit elsa_cs_config(struct pcmcia_device *link) static int __devinit elsa_cs_config(struct pcmcia_device *link)
{ {
local_info_t *dev;
int i; int i;
IsdnCard_t icard; IsdnCard_t icard;
dev_dbg(&link->dev, "elsa_config(0x%p)\n", link); dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
dev = link->priv;
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;

View File

@ -109,11 +109,10 @@ static void change_speed(struct IsdnCardState *cs, int baud)
{ {
int quot = 0, baud_base; int quot = 0, baud_base;
unsigned cval, fcr = 0; unsigned cval, fcr = 0;
int bits;
/* byte size and parity */ /* byte size and parity */
cval = 0x03; bits = 10; cval = 0x03;
/* Determine divisor based on baud rate */ /* Determine divisor based on baud rate */
baud_base = BASE_BAUD; baud_base = BASE_BAUD;
quot = baud_base / baud; quot = baud_base / baud;

View File

@ -258,11 +258,9 @@ static void
ctrl_complete(struct urb *urb) ctrl_complete(struct urb *urb)
{ {
hfcusb_data *hfc = (hfcusb_data *) urb->context; hfcusb_data *hfc = (hfcusb_data *) urb->context;
ctrl_buft *buf;
urb->dev = hfc->dev; urb->dev = hfc->dev;
if (hfc->ctrl_cnt) { if (hfc->ctrl_cnt) {
buf = &hfc->ctrl_buff[hfc->ctrl_out_idx];
hfc->ctrl_cnt--; /* decrement actual count */ hfc->ctrl_cnt--; /* decrement actual count */
if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE) if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
hfc->ctrl_out_idx = 0; /* pointer wrap */ hfc->ctrl_out_idx = 0; /* pointer wrap */
@ -1097,7 +1095,7 @@ static int
hfc_usb_init(hfcusb_data * hfc) hfc_usb_init(hfcusb_data * hfc)
{ {
usb_fifo *fifo; usb_fifo *fifo;
int i, err; int i;
u_char b; u_char b;
struct hisax_b_if *p_b_if[2]; struct hisax_b_if *p_b_if[2];
@ -1112,7 +1110,7 @@ hfc_usb_init(hfcusb_data * hfc)
} }
/* first set the needed config, interface and alternate */ /* first set the needed config, interface and alternate */
err = usb_set_interface(hfc->dev, hfc->if_used, hfc->alt_used); usb_set_interface(hfc->dev, hfc->if_used, hfc->alt_used);
/* do Chip reset */ /* do Chip reset */
write_usb(hfc, HFCUSB_CIRM, 8); write_usb(hfc, HFCUSB_CIRM, 8);

View File

@ -96,7 +96,7 @@ dch_l2l1(struct PStack *st, int pr, void *arg)
{ {
struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
struct sk_buff *skb = arg; struct sk_buff *skb = arg;
u_char cda1_cr, cda2_cr; u_char cda1_cr;
switch (pr) { switch (pr) {
case (PH_DATA |REQUEST): case (PH_DATA |REQUEST):
@ -163,7 +163,7 @@ dch_l2l1(struct PStack *st, int pr, void *arg)
cs->writeisac(cs, IPACX_CDA_TSDP10, 0x80); // Timeslot 0 is B1 cs->writeisac(cs, IPACX_CDA_TSDP10, 0x80); // Timeslot 0 is B1
cs->writeisac(cs, IPACX_CDA_TSDP11, 0x81); // Timeslot 0 is B1 cs->writeisac(cs, IPACX_CDA_TSDP11, 0x81); // Timeslot 0 is B1
cda1_cr = cs->readisac(cs, IPACX_CDA1_CR); cda1_cr = cs->readisac(cs, IPACX_CDA1_CR);
cda2_cr = cs->readisac(cs, IPACX_CDA2_CR); (void) cs->readisac(cs, IPACX_CDA2_CR);
if ((long)arg &1) { // loop B1 if ((long)arg &1) { // loop B1
cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x0a); cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x0a);
} }

View File

@ -23,10 +23,9 @@
int int
JadeVersion(struct IsdnCardState *cs, char *s) JadeVersion(struct IsdnCardState *cs, char *s)
{ {
int ver,i; int ver;
int to = 50; int to = 50;
cs->BC_Write_Reg(cs, -1, 0x50, 0x19); cs->BC_Write_Reg(cs, -1, 0x50, 0x19);
i=0;
while (to) { while (to) {
udelay(1); udelay(1);
ver = cs->BC_Read_Reg(cs, -1, 0x60); ver = cs->BC_Read_Reg(cs, -1, 0x60);

View File

@ -2943,7 +2943,7 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
static void static void
dss1up(struct PStack *st, int pr, void *arg) dss1up(struct PStack *st, int pr, void *arg)
{ {
int i, mt, cr, cause, callState; int i, mt, cr, callState;
char *ptr; char *ptr;
u_char *p; u_char *p;
struct sk_buff *skb = arg; struct sk_buff *skb = arg;
@ -3034,12 +3034,10 @@ dss1up(struct PStack *st, int pr, void *arg)
return; return;
} }
} else if (mt == MT_STATUS) { } else if (mt == MT_STATUS) {
cause = 0;
if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) { if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {
ptr++; ptr++;
if (*ptr++ == 2) if (*ptr++ == 2)
ptr++; ptr++;
cause = *ptr & 0x7f;
} }
callState = 0; callState = 0;
if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) { if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) {

View File

@ -2883,7 +2883,7 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
static void static void
ni1up(struct PStack *st, int pr, void *arg) ni1up(struct PStack *st, int pr, void *arg)
{ {
int i, mt, cr, cause, callState; int i, mt, cr, callState;
char *ptr; char *ptr;
u_char *p; u_char *p;
struct sk_buff *skb = arg; struct sk_buff *skb = arg;
@ -2986,12 +2986,10 @@ ni1up(struct PStack *st, int pr, void *arg)
return; return;
} }
} else if (mt == MT_STATUS) { } else if (mt == MT_STATUS) {
cause = 0;
if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) { if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {
ptr++; ptr++;
if (*ptr++ == 2) if (*ptr++ == 2)
ptr++; ptr++;
cause = *ptr & 0x7f;
} }
callState = 0; callState = 0;
if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) { if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) {

View File

@ -377,7 +377,6 @@ struct st5481_bcs {
}; };
struct st5481_adapter { struct st5481_adapter {
struct list_head list;
int number_of_leds; int number_of_leds;
struct usb_device *usb_dev; struct usb_device *usb_dev;
struct hisax_d_if hisax_d_if; struct hisax_d_if hisax_d_if;

View File

@ -46,8 +46,6 @@ module_param(debug, int, 0);
#endif #endif
int st5481_debug; int st5481_debug;
static LIST_HEAD(adapter_list);
/* ====================================================================== /* ======================================================================
* registration/deregistration with the USB layer * registration/deregistration with the USB layer
*/ */
@ -86,7 +84,6 @@ static int probe_st5481(struct usb_interface *intf,
adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i]; adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i];
adapter->bcs[i].b_if.ifc.l2l1 = st5481_b_l2l1; adapter->bcs[i].b_if.ifc.l2l1 = st5481_b_l2l1;
} }
list_add(&adapter->list, &adapter_list);
retval = st5481_setup_usb(adapter); retval = st5481_setup_usb(adapter);
if (retval < 0) if (retval < 0)
@ -125,6 +122,7 @@ static int probe_st5481(struct usb_interface *intf,
err_usb: err_usb:
st5481_release_usb(adapter); st5481_release_usb(adapter);
err: err:
kfree(adapter);
return -EIO; return -EIO;
} }
@ -142,8 +140,6 @@ static void disconnect_st5481(struct usb_interface *intf)
if (!adapter) if (!adapter)
return; return;
list_del(&adapter->list);
st5481_stop(adapter); st5481_stop(adapter);
st5481_release_b(&adapter->bcs[1]); st5481_release_b(&adapter->bcs[1]);
st5481_release_b(&adapter->bcs[0]); st5481_release_b(&adapter->bcs[0]);

View File

@ -111,12 +111,10 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
static int __devinit teles_cs_config(struct pcmcia_device *link) static int __devinit teles_cs_config(struct pcmcia_device *link)
{ {
local_info_t *dev;
int i; int i;
IsdnCard_t icard; IsdnCard_t icard;
dev_dbg(&link->dev, "teles_config(0x%p)\n", link); dev_dbg(&link->dev, "teles_config(0x%p)\n", link);
dev = link->priv;
i = pcmcia_loop_config(link, teles_cs_configcheck, NULL); i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
if (i != 0) if (i != 0)

View File

@ -155,7 +155,6 @@ put_log_buffer(hysdn_card * card, char *cp)
static ssize_t static ssize_t
hysdn_log_write(struct file *file, const char __user *buf, size_t count, loff_t * off) hysdn_log_write(struct file *file, const char __user *buf, size_t count, loff_t * off)
{ {
unsigned long u = 0;
int rc; int rc;
unsigned char valbuf[128]; unsigned char valbuf[128];
hysdn_card *card = file->private_data; hysdn_card *card = file->private_data;
@ -167,12 +166,10 @@ hysdn_log_write(struct file *file, const char __user *buf, size_t count, loff_t
valbuf[count] = 0; /* terminating 0 */ valbuf[count] = 0; /* terminating 0 */
rc = strict_strtoul(valbuf, 0, &u); rc = kstrtoul(valbuf, 0, &card->debug_flags);
if (rc < 0)
if (rc == 0) { return rc;
card->debug_flags = u; /* remember debug flags */ hysdn_addlog(card, "debug set to 0x%lx", card->debug_flags);
hysdn_addlog(card, "debug set to 0x%lx", card->debug_flags);
}
return (count); return (count);
} /* hysdn_log_write */ } /* hysdn_log_write */

View File

@ -399,13 +399,8 @@ isdn_all_eaz(int di, int ch)
#include <linux/isdn/capicmd.h> #include <linux/isdn/capicmd.h>
static int static int
isdn_capi_rec_hl_msg(capi_msg *cm) { isdn_capi_rec_hl_msg(capi_msg *cm)
{
int di;
int ch;
di = (cm->adr.Controller & 0x7f) -1;
ch = isdn_dc2minor(di, (cm->adr.Controller>>8)& 0x7f);
switch(cm->Command) { switch(cm->Command) {
case CAPI_FACILITY: case CAPI_FACILITY:
/* in the moment only handled in tty */ /* in the moment only handled in tty */
@ -1278,7 +1273,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
uint minor = iminor(file->f_path.dentry->d_inode); uint minor = iminor(file->f_path.dentry->d_inode);
isdn_ctrl c; isdn_ctrl c;
int drvidx; int drvidx;
int chidx;
int ret; int ret;
int i; int i;
char __user *p; char __user *p;
@ -1340,7 +1334,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
drvidx = isdn_minor2drv(minor); drvidx = isdn_minor2drv(minor);
if (drvidx < 0) if (drvidx < 0)
return -ENODEV; return -ENODEV;
chidx = isdn_minor2chan(minor);
if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING)) if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING))
return -ENODEV; return -ENODEV;
return 0; return 0;

View File

@ -1678,7 +1678,6 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
u32 your_seq; u32 your_seq;
__be32 local; __be32 local;
__be32 *addr, *mask; __be32 *addr, *mask;
u16 unused;
if (skb->len < 14) if (skb->len < 14)
return; return;
@ -1722,7 +1721,6 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
lp->cisco_last_slarp_in = jiffies; lp->cisco_last_slarp_in = jiffies;
my_seq = be32_to_cpup((__be32 *)(p + 0)); my_seq = be32_to_cpup((__be32 *)(p + 0));
your_seq = be32_to_cpup((__be32 *)(p + 4)); your_seq = be32_to_cpup((__be32 *)(p + 4));
unused = be16_to_cpup((__be16 *)(p + 8));
p += 10; p += 10;
lp->cisco_yourseq = my_seq; lp->cisco_yourseq = my_seq;
lp->cisco_mineseen = your_seq; lp->cisco_mineseen = your_seq;

View File

@ -998,7 +998,6 @@ isdn_tty_change_speed(modem_info * info)
{ {
uint cflag, uint cflag,
cval, cval,
fcr,
quot; quot;
int i; int i;
@ -1037,7 +1036,6 @@ isdn_tty_change_speed(modem_info * info)
cval |= UART_LCR_PARITY; cval |= UART_LCR_PARITY;
if (!(cflag & PARODD)) if (!(cflag & PARODD))
cval |= UART_LCR_EPAR; cval |= UART_LCR_EPAR;
fcr = 0;
/* CTS flow control flag and modem status interrupts */ /* CTS flow control flag and modem status interrupts */
if (cflag & CRTSCTS) { if (cflag & CRTSCTS) {

View File

@ -1640,7 +1640,7 @@ l2_tei_remove(struct FsmInst *fi, int event, void *arg)
} }
static void static void
l2_st14_persistant_da(struct FsmInst *fi, int event, void *arg) l2_st14_persistent_da(struct FsmInst *fi, int event, void *arg)
{ {
struct layer2 *l2 = fi->userdata; struct layer2 *l2 = fi->userdata;
struct sk_buff *skb = arg; struct sk_buff *skb = arg;
@ -1654,7 +1654,7 @@ l2_st14_persistant_da(struct FsmInst *fi, int event, void *arg)
} }
static void static void
l2_st5_persistant_da(struct FsmInst *fi, int event, void *arg) l2_st5_persistent_da(struct FsmInst *fi, int event, void *arg)
{ {
struct layer2 *l2 = fi->userdata; struct layer2 *l2 = fi->userdata;
struct sk_buff *skb = arg; struct sk_buff *skb = arg;
@ -1671,7 +1671,7 @@ l2_st5_persistant_da(struct FsmInst *fi, int event, void *arg)
} }
static void static void
l2_st6_persistant_da(struct FsmInst *fi, int event, void *arg) l2_st6_persistent_da(struct FsmInst *fi, int event, void *arg)
{ {
struct layer2 *l2 = fi->userdata; struct layer2 *l2 = fi->userdata;
struct sk_buff *skb = arg; struct sk_buff *skb = arg;
@ -1685,7 +1685,7 @@ l2_st6_persistant_da(struct FsmInst *fi, int event, void *arg)
} }
static void static void
l2_persistant_da(struct FsmInst *fi, int event, void *arg) l2_persistent_da(struct FsmInst *fi, int event, void *arg)
{ {
struct layer2 *l2 = fi->userdata; struct layer2 *l2 = fi->userdata;
struct sk_buff *skb = arg; struct sk_buff *skb = arg;
@ -1829,14 +1829,14 @@ static struct FsmNode L2FnList[] =
{ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error}, {ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error},
{ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest}, {ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest},
{ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest}, {ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest},
{ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistant_da}, {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistent_da},
{ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove}, {ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove},
{ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove}, {ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove},
{ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistant_da}, {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistent_da},
{ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistant_da}, {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistent_da},
{ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistant_da}, {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistent_da},
{ST_L2_7, EV_L1_DEACTIVATE, l2_persistant_da}, {ST_L2_7, EV_L1_DEACTIVATE, l2_persistent_da},
{ST_L2_8, EV_L1_DEACTIVATE, l2_persistant_da}, {ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da},
}; };
static int static int

View File

@ -457,6 +457,9 @@ static int data_sock_getsockopt(struct socket *sock, int level, int optname,
if (get_user(len, optlen)) if (get_user(len, optlen))
return -EFAULT; return -EFAULT;
if (len != sizeof(char))
return -EINVAL;
switch (optname) { switch (optname) {
case MISDN_TIME_STAMP: case MISDN_TIME_STAMP:
if (_pms(sk)->cmask & MISDN_TIME_STAMP) if (_pms(sk)->cmask & MISDN_TIME_STAMP)

View File

@ -185,7 +185,7 @@ static int max_interrupt_work = 10;
static int nopnp; static int nopnp;
#endif #endif
static int __devinit el3_common_init(struct net_device *dev); static int el3_common_init(struct net_device *dev);
static void el3_common_remove(struct net_device *dev); static void el3_common_remove(struct net_device *dev);
static ushort id_read_eeprom(int index); static ushort id_read_eeprom(int index);
static ushort read_eeprom(int ioaddr, int index); static ushort read_eeprom(int ioaddr, int index);
@ -395,7 +395,7 @@ static struct isa_driver el3_isa_driver = {
static int isa_registered; static int isa_registered;
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
static struct pnp_device_id el3_pnp_ids[] = { static const struct pnp_device_id el3_pnp_ids[] __devinitconst = {
{ .id = "TCM5090" }, /* 3Com Etherlink III (TP) */ { .id = "TCM5090" }, /* 3Com Etherlink III (TP) */
{ .id = "TCM5091" }, /* 3Com Etherlink III */ { .id = "TCM5091" }, /* 3Com Etherlink III */
{ .id = "TCM5094" }, /* 3Com Etherlink III (combo) */ { .id = "TCM5094" }, /* 3Com Etherlink III (combo) */
@ -478,7 +478,7 @@ static int pnp_registered;
#endif /* CONFIG_PNP */ #endif /* CONFIG_PNP */
#ifdef CONFIG_EISA #ifdef CONFIG_EISA
static struct eisa_device_id el3_eisa_ids[] = { static const struct eisa_device_id el3_eisa_ids[] __devinitconst = {
{ "TCM5090" }, { "TCM5090" },
{ "TCM5091" }, { "TCM5091" },
{ "TCM5092" }, { "TCM5092" },
@ -508,7 +508,7 @@ static int eisa_registered;
#ifdef CONFIG_MCA #ifdef CONFIG_MCA
static int el3_mca_probe(struct device *dev); static int el3_mca_probe(struct device *dev);
static short el3_mca_adapter_ids[] __initdata = { static const short el3_mca_adapter_ids[] __devinitconst = {
0x627c, 0x627c,
0x627d, 0x627d,
0x62db, 0x62db,
@ -517,7 +517,7 @@ static short el3_mca_adapter_ids[] __initdata = {
0x0000 0x0000
}; };
static char *el3_mca_adapter_names[] __initdata = { static const char *const el3_mca_adapter_names[] __devinitconst = {
"3Com 3c529 EtherLink III (10base2)", "3Com 3c529 EtherLink III (10base2)",
"3Com 3c529 EtherLink III (10baseT)", "3Com 3c529 EtherLink III (10baseT)",
"3Com 3c529 EtherLink III (test mode)", "3Com 3c529 EtherLink III (test mode)",
@ -601,7 +601,7 @@ static void el3_common_remove (struct net_device *dev)
} }
#ifdef CONFIG_MCA #ifdef CONFIG_MCA
static int __init el3_mca_probe(struct device *device) static int __devinit el3_mca_probe(struct device *device)
{ {
/* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch,
* heavily modified by Chris Beauregard * heavily modified by Chris Beauregard
@ -671,7 +671,7 @@ static int __init el3_mca_probe(struct device *device)
#endif /* CONFIG_MCA */ #endif /* CONFIG_MCA */
#ifdef CONFIG_EISA #ifdef CONFIG_EISA
static int __init el3_eisa_probe (struct device *device) static int __devinit el3_eisa_probe (struct device *device)
{ {
short i; short i;
int ioaddr, irq, if_port; int ioaddr, irq, if_port;
@ -1207,7 +1207,7 @@ el3_netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->duplex = DUPLEX_FULL; ecmd->duplex = DUPLEX_FULL;
} }
ecmd->speed = SPEED_10; ethtool_cmd_speed_set(ecmd, SPEED_10);
EL3WINDOW(1); EL3WINDOW(1);
return 0; return 0;
} }

View File

@ -901,14 +901,14 @@ static const struct dev_pm_ops vortex_pm_ops = {
#endif /* !CONFIG_PM */ #endif /* !CONFIG_PM */
#ifdef CONFIG_EISA #ifdef CONFIG_EISA
static struct eisa_device_id vortex_eisa_ids[] = { static const struct eisa_device_id vortex_eisa_ids[] __devinitconst = {
{ "TCM5920", CH_3C592 }, { "TCM5920", CH_3C592 },
{ "TCM5970", CH_3C597 }, { "TCM5970", CH_3C597 },
{ "" } { "" }
}; };
MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids); MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids);
static int __init vortex_eisa_probe(struct device *device) static int __devinit vortex_eisa_probe(struct device *device)
{ {
void __iomem *ioaddr; void __iomem *ioaddr;
struct eisa_device *edev; struct eisa_device *edev;

View File

@ -758,8 +758,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
entry = cp->tx_head; entry = cp->tx_head;
eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
if (dev->features & NETIF_F_TSO) mss = skb_shinfo(skb)->gso_size;
mss = skb_shinfo(skb)->gso_size;
if (skb_shinfo(skb)->nr_frags == 0) { if (skb_shinfo(skb)->nr_frags == 0) {
struct cp_desc *txd = &cp->tx_ring[entry]; struct cp_desc *txd = &cp->tx_ring[entry];
@ -1416,32 +1415,23 @@ static void cp_set_msglevel(struct net_device *dev, u32 value)
cp->msg_enable = value; cp->msg_enable = value;
} }
static u32 cp_get_rx_csum(struct net_device *dev) static int cp_set_features(struct net_device *dev, u32 features)
{ {
struct cp_private *cp = netdev_priv(dev); struct cp_private *cp = netdev_priv(dev);
return (cpr16(CpCmd) & RxChkSum) ? 1 : 0; unsigned long flags;
}
static int cp_set_rx_csum(struct net_device *dev, u32 data) if (!((dev->features ^ features) & NETIF_F_RXCSUM))
{ return 0;
struct cp_private *cp = netdev_priv(dev);
u16 cmd = cp->cpcmd, newcmd;
newcmd = cmd; spin_lock_irqsave(&cp->lock, flags);
if (data) if (features & NETIF_F_RXCSUM)
newcmd |= RxChkSum; cp->cpcmd |= RxChkSum;
else else
newcmd &= ~RxChkSum; cp->cpcmd &= ~RxChkSum;
if (newcmd != cmd) { cpw16_f(CpCmd, cp->cpcmd);
unsigned long flags; spin_unlock_irqrestore(&cp->lock, flags);
spin_lock_irqsave(&cp->lock, flags);
cp->cpcmd = newcmd;
cpw16_f(CpCmd, newcmd);
spin_unlock_irqrestore(&cp->lock, flags);
}
return 0; return 0;
} }
@ -1554,11 +1544,6 @@ static const struct ethtool_ops cp_ethtool_ops = {
.get_link = ethtool_op_get_link, .get_link = ethtool_op_get_link,
.get_msglevel = cp_get_msglevel, .get_msglevel = cp_get_msglevel,
.set_msglevel = cp_set_msglevel, .set_msglevel = cp_set_msglevel,
.get_rx_csum = cp_get_rx_csum,
.set_rx_csum = cp_set_rx_csum,
.set_tx_csum = ethtool_op_set_tx_csum, /* local! */
.set_sg = ethtool_op_set_sg,
.set_tso = ethtool_op_set_tso,
.get_regs = cp_get_regs, .get_regs = cp_get_regs,
.get_wol = cp_get_wol, .get_wol = cp_get_wol,
.set_wol = cp_set_wol, .set_wol = cp_set_wol,
@ -1831,6 +1816,7 @@ static const struct net_device_ops cp_netdev_ops = {
.ndo_do_ioctl = cp_ioctl, .ndo_do_ioctl = cp_ioctl,
.ndo_start_xmit = cp_start_xmit, .ndo_start_xmit = cp_start_xmit,
.ndo_tx_timeout = cp_tx_timeout, .ndo_tx_timeout = cp_tx_timeout,
.ndo_set_features = cp_set_features,
#if CP_VLAN_TAG_USED #if CP_VLAN_TAG_USED
.ndo_vlan_rx_register = cp_vlan_rx_register, .ndo_vlan_rx_register = cp_vlan_rx_register,
#endif #endif
@ -1934,6 +1920,9 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
cp->cpcmd = (pci_using_dac ? PCIDAC : 0) | cp->cpcmd = (pci_using_dac ? PCIDAC : 0) |
PCIMulRW | RxChkSum | CpRxOn | CpTxOn; PCIMulRW | RxChkSum | CpRxOn | CpTxOn;
dev->features |= NETIF_F_RXCSUM;
dev->hw_features |= NETIF_F_RXCSUM;
regs = ioremap(pciaddr, CP_REGS_SIZE); regs = ioremap(pciaddr, CP_REGS_SIZE);
if (!regs) { if (!regs) {
rc = -EIO; rc = -EIO;
@ -1966,9 +1955,8 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_using_dac) if (pci_using_dac)
dev->features |= NETIF_F_HIGHDMA; dev->features |= NETIF_F_HIGHDMA;
#if 0 /* disabled by default until verified */ /* disabled by default until verified */
dev->features |= NETIF_F_TSO; dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
#endif
dev->irq = pdev->irq; dev->irq = pdev->irq;

View File

@ -2659,15 +2659,15 @@ static int ace_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
link = readl(&regs->GigLnkState); link = readl(&regs->GigLnkState);
if (link & LNK_1000MB) if (link & LNK_1000MB)
ecmd->speed = SPEED_1000; ethtool_cmd_speed_set(ecmd, SPEED_1000);
else { else {
link = readl(&regs->FastLnkState); link = readl(&regs->FastLnkState);
if (link & LNK_100MB) if (link & LNK_100MB)
ecmd->speed = SPEED_100; ethtool_cmd_speed_set(ecmd, SPEED_100);
else if (link & LNK_10MB) else if (link & LNK_10MB)
ecmd->speed = SPEED_10; ethtool_cmd_speed_set(ecmd, SPEED_10);
else else
ecmd->speed = 0; ethtool_cmd_speed_set(ecmd, 0);
} }
if (link & LNK_FULL_DUPLEX) if (link & LNK_FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL; ecmd->duplex = DUPLEX_FULL;
@ -2719,9 +2719,9 @@ static int ace_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
link |= LNK_TX_FLOW_CTL_Y; link |= LNK_TX_FLOW_CTL_Y;
if (ecmd->autoneg == AUTONEG_ENABLE) if (ecmd->autoneg == AUTONEG_ENABLE)
link |= LNK_NEGOTIATE; link |= LNK_NEGOTIATE;
if (ecmd->speed != speed) { if (ethtool_cmd_speed(ecmd) != speed) {
link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB); link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB);
switch (speed) { switch (ethtool_cmd_speed(ecmd)) {
case SPEED_1000: case SPEED_1000:
link |= LNK_1000MB; link |= LNK_1000MB;
break; break;

View File

@ -591,10 +591,11 @@ static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i
static int etherh_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) static int etherh_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{ {
cmd->supported = etherh_priv(dev)->supported; cmd->supported = etherh_priv(dev)->supported;
cmd->speed = SPEED_10; ethtool_cmd_speed_set(cmd, SPEED_10);
cmd->duplex = DUPLEX_HALF; cmd->duplex = DUPLEX_HALF;
cmd->port = dev->if_port == IF_PORT_10BASET ? PORT_TP : PORT_BNC; cmd->port = dev->if_port == IF_PORT_10BASET ? PORT_TP : PORT_BNC;
cmd->autoneg = dev->flags & IFF_AUTOMEDIA ? AUTONEG_ENABLE : AUTONEG_DISABLE; cmd->autoneg = (dev->flags & IFF_AUTOMEDIA ?
AUTONEG_ENABLE : AUTONEG_DISABLE);
return 0; return 0;
} }

View File

@ -891,15 +891,16 @@ ks8695_wan_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
cmd->advertising |= ADVERTISED_Pause; cmd->advertising |= ADVERTISED_Pause;
cmd->autoneg = AUTONEG_ENABLE; cmd->autoneg = AUTONEG_ENABLE;
cmd->speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10; ethtool_cmd_speed_set(cmd,
(ctrl & WMC_WSS) ? SPEED_100 : SPEED_10);
cmd->duplex = (ctrl & WMC_WDS) ? cmd->duplex = (ctrl & WMC_WDS) ?
DUPLEX_FULL : DUPLEX_HALF; DUPLEX_FULL : DUPLEX_HALF;
} else { } else {
/* auto-negotiation is disabled */ /* auto-negotiation is disabled */
cmd->autoneg = AUTONEG_DISABLE; cmd->autoneg = AUTONEG_DISABLE;
cmd->speed = (ctrl & WMC_WANF100) ? ethtool_cmd_speed_set(cmd, ((ctrl & WMC_WANF100) ?
SPEED_100 : SPEED_10; SPEED_100 : SPEED_10));
cmd->duplex = (ctrl & WMC_WANFF) ? cmd->duplex = (ctrl & WMC_WANFF) ?
DUPLEX_FULL : DUPLEX_HALF; DUPLEX_FULL : DUPLEX_HALF;
} }

View File

@ -50,13 +50,13 @@ static int atl1c_get_settings(struct net_device *netdev,
ecmd->transceiver = XCVR_INTERNAL; ecmd->transceiver = XCVR_INTERNAL;
if (adapter->link_speed != SPEED_0) { if (adapter->link_speed != SPEED_0) {
ecmd->speed = adapter->link_speed; ethtool_cmd_speed_set(ecmd, adapter->link_speed);
if (adapter->link_duplex == FULL_DUPLEX) if (adapter->link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL; ecmd->duplex = DUPLEX_FULL;
else else
ecmd->duplex = DUPLEX_HALF; ecmd->duplex = DUPLEX_HALF;
} else { } else {
ecmd->speed = -1; ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1; ecmd->duplex = -1;
} }
@ -77,7 +77,8 @@ static int atl1c_set_settings(struct net_device *netdev,
if (ecmd->autoneg == AUTONEG_ENABLE) { if (ecmd->autoneg == AUTONEG_ENABLE) {
autoneg_advertised = ADVERTISED_Autoneg; autoneg_advertised = ADVERTISED_Autoneg;
} else { } else {
if (ecmd->speed == SPEED_1000) { u32 speed = ethtool_cmd_speed(ecmd);
if (speed == SPEED_1000) {
if (ecmd->duplex != DUPLEX_FULL) { if (ecmd->duplex != DUPLEX_FULL) {
if (netif_msg_link(adapter)) if (netif_msg_link(adapter))
dev_warn(&adapter->pdev->dev, dev_warn(&adapter->pdev->dev,
@ -86,7 +87,7 @@ static int atl1c_set_settings(struct net_device *netdev,
return -EINVAL; return -EINVAL;
} }
autoneg_advertised = ADVERTISED_1000baseT_Full; autoneg_advertised = ADVERTISED_1000baseT_Full;
} else if (ecmd->speed == SPEED_100) { } else if (speed == SPEED_100) {
if (ecmd->duplex == DUPLEX_FULL) if (ecmd->duplex == DUPLEX_FULL)
autoneg_advertised = ADVERTISED_100baseT_Full; autoneg_advertised = ADVERTISED_100baseT_Full;
else else
@ -113,11 +114,6 @@ static int atl1c_set_settings(struct net_device *netdev,
return 0; return 0;
} }
static u32 atl1c_get_tx_csum(struct net_device *netdev)
{
return (netdev->features & NETIF_F_HW_CSUM) != 0;
}
static u32 atl1c_get_msglevel(struct net_device *netdev) static u32 atl1c_get_msglevel(struct net_device *netdev)
{ {
struct atl1c_adapter *adapter = netdev_priv(netdev); struct atl1c_adapter *adapter = netdev_priv(netdev);
@ -307,9 +303,6 @@ static const struct ethtool_ops atl1c_ethtool_ops = {
.get_link = ethtool_op_get_link, .get_link = ethtool_op_get_link,
.get_eeprom_len = atl1c_get_eeprom_len, .get_eeprom_len = atl1c_get_eeprom_len,
.get_eeprom = atl1c_get_eeprom, .get_eeprom = atl1c_get_eeprom,
.get_tx_csum = atl1c_get_tx_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
}; };
void atl1c_set_ethtool_ops(struct net_device *netdev) void atl1c_set_ethtool_ops(struct net_device *netdev)

View File

@ -480,6 +480,15 @@ static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter,
adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ? adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ?
roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE; roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE;
} }
static u32 atl1c_fix_features(struct net_device *netdev, u32 features)
{
if (netdev->mtu > MAX_TSO_FRAME_SIZE)
features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
return features;
}
/* /*
* atl1c_change_mtu - Change the Maximum Transfer Unit * atl1c_change_mtu - Change the Maximum Transfer Unit
* @netdev: network interface device structure * @netdev: network interface device structure
@ -506,14 +515,8 @@ static int atl1c_change_mtu(struct net_device *netdev, int new_mtu)
netdev->mtu = new_mtu; netdev->mtu = new_mtu;
adapter->hw.max_frame_size = new_mtu; adapter->hw.max_frame_size = new_mtu;
atl1c_set_rxbufsize(adapter, netdev); atl1c_set_rxbufsize(adapter, netdev);
if (new_mtu > MAX_TSO_FRAME_SIZE) {
adapter->netdev->features &= ~NETIF_F_TSO;
adapter->netdev->features &= ~NETIF_F_TSO6;
} else {
adapter->netdev->features |= NETIF_F_TSO;
adapter->netdev->features |= NETIF_F_TSO6;
}
atl1c_down(adapter); atl1c_down(adapter);
netdev_update_features(netdev);
atl1c_up(adapter); atl1c_up(adapter);
clear_bit(__AT_RESETTING, &adapter->flags); clear_bit(__AT_RESETTING, &adapter->flags);
if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) { if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) {
@ -1088,10 +1091,8 @@ static void atl1c_configure_tx(struct atl1c_adapter *adapter)
u32 max_pay_load; u32 max_pay_load;
u16 tx_offload_thresh; u16 tx_offload_thresh;
u32 txq_ctrl_data; u32 txq_ctrl_data;
u32 extra_size = 0; /* Jumbo frame threshold in QWORD unit */
u32 max_pay_load_data; u32 max_pay_load_data;
extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN;
tx_offload_thresh = MAX_TX_OFFLOAD_THRESH; tx_offload_thresh = MAX_TX_OFFLOAD_THRESH;
AT_WRITE_REG(hw, REG_TX_TSO_OFFLOAD_THRESH, AT_WRITE_REG(hw, REG_TX_TSO_OFFLOAD_THRESH,
(tx_offload_thresh >> 3) & TX_TSO_OFFLOAD_THRESH_MASK); (tx_offload_thresh >> 3) & TX_TSO_OFFLOAD_THRESH_MASK);
@ -2536,6 +2537,7 @@ static int atl1c_suspend(struct device *dev)
return 0; return 0;
} }
#ifdef CONFIG_PM_SLEEP
static int atl1c_resume(struct device *dev) static int atl1c_resume(struct device *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
@ -2562,6 +2564,7 @@ static int atl1c_resume(struct device *dev)
return 0; return 0;
} }
#endif
static void atl1c_shutdown(struct pci_dev *pdev) static void atl1c_shutdown(struct pci_dev *pdev)
{ {
@ -2581,6 +2584,7 @@ static const struct net_device_ops atl1c_netdev_ops = {
.ndo_set_mac_address = atl1c_set_mac_addr, .ndo_set_mac_address = atl1c_set_mac_addr,
.ndo_set_multicast_list = atl1c_set_multi, .ndo_set_multicast_list = atl1c_set_multi,
.ndo_change_mtu = atl1c_change_mtu, .ndo_change_mtu = atl1c_change_mtu,
.ndo_fix_features = atl1c_fix_features,
.ndo_do_ioctl = atl1c_ioctl, .ndo_do_ioctl = atl1c_ioctl,
.ndo_tx_timeout = atl1c_tx_timeout, .ndo_tx_timeout = atl1c_tx_timeout,
.ndo_get_stats = atl1c_get_stats, .ndo_get_stats = atl1c_get_stats,
@ -2601,12 +2605,13 @@ static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
atl1c_set_ethtool_ops(netdev); atl1c_set_ethtool_ops(netdev);
/* TODO: add when ready */ /* TODO: add when ready */
netdev->features = NETIF_F_SG | netdev->hw_features = NETIF_F_SG |
NETIF_F_HW_CSUM | NETIF_F_HW_CSUM |
NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
NETIF_F_TSO | NETIF_F_TSO |
NETIF_F_TSO6; NETIF_F_TSO6;
netdev->features = netdev->hw_features |
NETIF_F_HW_VLAN_RX;
return 0; return 0;
} }

View File

@ -51,13 +51,13 @@ static int atl1e_get_settings(struct net_device *netdev,
ecmd->transceiver = XCVR_INTERNAL; ecmd->transceiver = XCVR_INTERNAL;
if (adapter->link_speed != SPEED_0) { if (adapter->link_speed != SPEED_0) {
ecmd->speed = adapter->link_speed; ethtool_cmd_speed_set(ecmd, adapter->link_speed);
if (adapter->link_duplex == FULL_DUPLEX) if (adapter->link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL; ecmd->duplex = DUPLEX_FULL;
else else
ecmd->duplex = DUPLEX_HALF; ecmd->duplex = DUPLEX_HALF;
} else { } else {
ecmd->speed = -1; ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1; ecmd->duplex = -1;
} }
@ -382,9 +382,6 @@ static const struct ethtool_ops atl1e_ethtool_ops = {
.get_eeprom_len = atl1e_get_eeprom_len, .get_eeprom_len = atl1e_get_eeprom_len,
.get_eeprom = atl1e_get_eeprom, .get_eeprom = atl1e_get_eeprom,
.set_eeprom = atl1e_set_eeprom, .set_eeprom = atl1e_set_eeprom,
.set_tx_csum = ethtool_op_set_tx_hw_csum,
.set_sg = ethtool_op_set_sg,
.set_tso = ethtool_op_set_tso,
}; };
void atl1e_set_ethtool_ops(struct net_device *netdev) void atl1e_set_ethtool_ops(struct net_device *netdev)

View File

@ -691,10 +691,8 @@ static void atl1e_cal_ring_size(struct atl1e_adapter *adapter, u32 *ring_size)
static void atl1e_init_ring_resources(struct atl1e_adapter *adapter) static void atl1e_init_ring_resources(struct atl1e_adapter *adapter)
{ {
struct atl1e_tx_ring *tx_ring = NULL;
struct atl1e_rx_ring *rx_ring = NULL; struct atl1e_rx_ring *rx_ring = NULL;
tx_ring = &adapter->tx_ring;
rx_ring = &adapter->rx_ring; rx_ring = &adapter->rx_ring;
rx_ring->real_page_size = adapter->rx_ring.page_size rx_ring->real_page_size = adapter->rx_ring.page_size
@ -1927,11 +1925,7 @@ void atl1e_down(struct atl1e_adapter *adapter)
* reschedule our watchdog timer */ * reschedule our watchdog timer */
set_bit(__AT_DOWN, &adapter->flags); set_bit(__AT_DOWN, &adapter->flags);
#ifdef NETIF_F_LLTX
netif_stop_queue(netdev); netif_stop_queue(netdev);
#else
netif_tx_disable(netdev);
#endif
/* reset MAC to disable all RX/TX */ /* reset MAC to disable all RX/TX */
atl1e_reset_hw(&adapter->hw); atl1e_reset_hw(&adapter->hw);
@ -2223,10 +2217,10 @@ static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
netdev->watchdog_timeo = AT_TX_WATCHDOG; netdev->watchdog_timeo = AT_TX_WATCHDOG;
atl1e_set_ethtool_ops(netdev); atl1e_set_ethtool_ops(netdev);
netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM | netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO |
NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; NETIF_F_HW_VLAN_TX;
netdev->features |= NETIF_F_LLTX; netdev->features = netdev->hw_features |
netdev->features |= NETIF_F_TSO; NETIF_F_HW_VLAN_RX | NETIF_F_LLTX;
return 0; return 0;
} }

Some files were not shown because too many files have changed in this diff Show More