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
Check: IRQF_SAMPLE_RANDOM
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
When: January 2011
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
----------
@ -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,
vpn, etc ... (anything with ethernet-style layer 2).
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
of a neighbor originator's interface which
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
-> "SEC mac" - secondary mac address of source
(requires preceding PRIMARY)
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
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
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
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
will enable debug messages for when routes or HNAs change.
will enable debug messages for when routes or TTs change.
BATCTL

View File

@ -1,7 +1,7 @@
Linux Ethernet Bonding Driver HOWTO
Latest update: 23 September 2009
Latest update: 27 April 2011
Initial release : Thomas Davis <tadavis at lbl.gov>
Corrections, HA extensions : 2000/10/03-15 :
@ -585,25 +585,23 @@ mode
chosen.
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
Specifies the number of unsolicited IPv6 Neighbor Advertisements
to be issued after a failover event. One unsolicited NA is issued
immediately after the failover.
Specify the number of peer notifications (gratuitous ARPs and
unsolicited IPv6 Neighbor Advertisements) to be issued after a
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
affects only the active-backup mode. This option was added for
bonding version 3.4.0.
The valid range is 0 - 255; the default value is 1. These options
affect only the active-backup mode. These options were added for
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

View File

@ -93,6 +93,19 @@ Additional Configurations
REQUIREMENTS: MSI-X support is required for Multiqueue. If MSI-X is not
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
=======

View File

@ -32,6 +32,17 @@ Table : Subdirectories in /proc/sys/net
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
------------

View File

@ -1232,13 +1232,6 @@ W: http://wireless.kernel.org/en/users/Drivers/ath9k
S: Supported
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
M: Christian Lamparter <chunkeey@googlemail.com>
L: linux-wireless@vger.kernel.org
@ -3363,6 +3356,12 @@ F: Documentation/wimax/README.i2400m
F: drivers/net/wimax/i2400m/
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)
M: Wey-Yi Guy <wey-yi.w.guy@intel.com>
M: Intel Linux Wireless <ilw@linux.intel.com>
@ -4385,6 +4384,7 @@ S: Maintained
F: net/ipv4/
F: net/ipv6/
F: include/net/ip*
F: arch/x86/net/*
NETWORKING [LABELED] (NetLabel, CIPSO, Labeled IPsec, SECMARK)
M: Paul Moore <paul.moore@hp.com>
@ -5832,6 +5832,13 @@ S: Maintained
F: drivers/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
M: Mattia Dongili <malattia@linux.it>
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)
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 };
int speed = 100; /* default 100Mbps */
int err;
if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
return speed;
err = dev->ethtool_ops->get_settings(dev, &cmd);
if (err < 0)
return speed;
speed = cmd.speed == SPEED_100 ? 100 : 10;
return speed;
struct ethtool_cmd cmd;
if (dev_ethtool_get_settings(dev, &cmd))
return 100; /* default 100Mbps */
return ethtool_cmd_speed(&cmd);
}
static int tx4939_netdev_event(struct notifier_block *this,
unsigned long event,
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))
bit = TX4939_PCFG_SPEED1;
if (bit) {
int speed = tx4939_get_eth_speed(dev);
if (speed == 100)
if (tx4939_get_eth_speed(dev) == 100)
txx9_set64(&tx4939_ccfgptr->pcfg, bit);
else
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(clock_adjtime)
SYSCALL_SPU(syncfs)
COMPAT_SYS_SPU(sendmmsg)

View File

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

View File

@ -404,8 +404,9 @@
#define __NR_open_by_handle_at 333
#define __NR_clock_adjtime 334
#define __NR_syncfs 335
#define __NR_sendmmsg 336
#define NR_syscalls 336
#define NR_syscalls 337
#ifdef __32bit_syscall_numbers__
/* 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
/*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
/*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
.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
.word sys_syncfs
.word sys_syncfs, compat_sys_sendmmsg
#endif /* CONFIG_COMPAT */
@ -162,4 +162,4 @@ sys_call_table:
/*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
/*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-y += platform/
obj-y += net/

View File

@ -72,6 +72,7 @@ config X86
select GENERIC_IRQ_SHOW
select IRQ_FORCED_THREADING
select USE_GENERIC_SMP_HELPERS if SMP
select HAVE_BPF_JIT if (X86_64 && NET)
config INSTRUCTION_DECODER
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_clock_adjtime
.quad sys_syncfs
.quad compat_sys_sendmmsg /* 345 */
ia32_syscall_end:

View File

@ -350,10 +350,11 @@
#define __NR_open_by_handle_at 342
#define __NR_clock_adjtime 343
#define __NR_syncfs 344
#define __NR_sendmmsg 345
#ifdef __KERNEL__
#define NR_syscalls 345
#define NR_syscalls 346
#define __ARCH_WANT_IPC_PARSE_VERSION
#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)
#define __NR_syncfs 306
__SYSCALL(__NR_syncfs, sys_syncfs)
#define __NR_sendmmsg 307
__SYSCALL(__NR_sendmmsg, sys_sendmmsg)
#ifndef __NO_STUBS
#define __ARCH_WANT_OLD_READDIR

View File

@ -344,3 +344,4 @@ ENTRY(sys_call_table)
.long sys_open_by_handle_at
.long sys_clock_adjtime
.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/bcma/Kconfig"
source "drivers/mfd/Kconfig"
source "drivers/regulator/Kconfig"

View File

@ -110,6 +110,7 @@ obj-$(CONFIG_HID) += hid/
obj-$(CONFIG_PPC_PS3) += ps3/
obj-$(CONFIG_OF) += of/
obj-$(CONFIG_SSB) += ssb/
obj-$(CONFIG_BCMA) += bcma/
obj-$(CONFIG_VHOST_NET) += vhost/
obj-$(CONFIG_VLYNQ) += vlynq/
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)
{
struct eni_dev *eni_dev;
DPRINTK(">bug_int\n");
eni_dev = ENI_DEV(dev);
if (reason & MID_DMA_ERR_ACK)
printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - DMA "
"error\n",dev->number);
@ -1900,7 +1897,6 @@ static void eni_close(struct atm_vcc *vcc)
static int eni_open(struct atm_vcc *vcc)
{
struct eni_dev *eni_dev;
struct eni_vcc *eni_vcc;
int error;
short vpi = vcc->vpi;
@ -1910,7 +1906,6 @@ static int eni_open(struct atm_vcc *vcc)
EVENT("eni_open\n",0,0);
if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))
vcc->dev_data = NULL;
eni_dev = ENI_DEV(vcc->dev);
if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
set_bit(ATM_VF_ADDR,&vcc->flags);
if (vcc->qos.aal != ATM_AAL0 && vcc->qos.aal != ATM_AAL5)

View File

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

View File

@ -1261,14 +1261,13 @@ idt77252_rx_raw(struct idt77252_dev *card)
PCI_DMA_FROMDEVICE);
while (head != tail) {
unsigned int vpi, vci, pti;
unsigned int vpi, vci;
u32 header;
header = le32_to_cpu(*(u32 *) &queue->data[0]);
vpi = (header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_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
if (debug & DBG_RAW_CELL) {
@ -2709,53 +2708,10 @@ idt77252_proc_read(struct atm_dev *dev, loff_t * pos, char *page)
static void
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

View File

@ -613,7 +613,6 @@ static int ia_que_tx (IADEV *iadev) {
struct sk_buff *skb;
int num_desc;
struct atm_vcc *vcc;
struct ia_vcc *iavcc;
num_desc = ia_avail_descs(iadev);
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);
break;
}
iavcc = INPH_IA_VCC(vcc);
if (ia_pkt_tx (vcc, skb)) {
skb_queue_head(&iadev->tx_backlog, skb);
}
@ -823,8 +821,6 @@ static void IaFrontEndIntr(IADEV *iadev) {
volatile IA_SUNI *suni;
volatile ia_mb25_t *mb25;
volatile suni_pm7345_t *suni_pm7345;
u32 intr_status;
u_int frmr_intr;
if(iadev->phy_type & FE_25MBIT_PHY) {
mb25 = (ia_mb25_t*)iadev->phy;
@ -832,18 +828,18 @@ static void IaFrontEndIntr(IADEV *iadev) {
} else if (iadev->phy_type & FE_DS3_PHY) {
suni_pm7345 = (suni_pm7345_t *)iadev->phy;
/* clear FRMR interrupts */
frmr_intr = suni_pm7345->suni_ds3_frm_intr_stat;
(void) suni_pm7345->suni_ds3_frm_intr_stat;
iadev->carrier_detect =
Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV));
} else if (iadev->phy_type & FE_E3_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 =
Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat&SUNI_E3_LOS));
}
else {
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));
}
if (iadev->carrier_detect)
@ -2660,7 +2656,6 @@ static void ia_close(struct atm_vcc *vcc)
static int ia_open(struct atm_vcc *vcc)
{
IADEV *iadev;
struct ia_vcc *ia_vcc;
int error;
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");)
vcc->dev_data = NULL;
}
iadev = INPH_IA_DEV(vcc->dev);
if (vcc->vci != ATM_VPI_UNSPEC && vcc->vpi != ATM_VCI_UNSPEC)
{
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)
{
IADEV *iadev;
struct ia_vcc *iavcc;
unsigned long flags;
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)

View File

@ -527,7 +527,6 @@ static int flash_upgrade(struct solos_card *card, int chip)
{
const struct firmware *fw;
const char *fw_name;
uint32_t data32 = 0;
int blocksize = 0;
int numblocks = 0;
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");
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 */
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.
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
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.
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.
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*/
{ USB_DEVICE(0x0CF3, 0x3002) },
{ USB_DEVICE(0x13d3, 0x3304) },
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03F0, 0x311D) },
@ -138,9 +139,6 @@ static int ath3k_load_firmware(struct usb_device *udev,
count -= size;
}
kfree(send_buf);
return 0;
error:
kfree(send_buf);
return err;

View File

@ -49,15 +49,59 @@
static u8 user_rmmod;
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 = {
.helper = "sd8688_helper.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[] = {
/* Marvell SD8688 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105),
.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 */
};
@ -69,7 +113,7 @@ static int btmrvl_sdio_get_rx_unit(struct btmrvl_sdio_card *card)
u8 reg;
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)
card->rx_unit = reg;
@ -83,11 +127,11 @@ static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat)
*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)
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)
return -EIO;
@ -101,7 +145,7 @@ static int btmrvl_sdio_read_rx_len(struct btmrvl_sdio_card *card, u16 *dat)
u8 reg;
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)
*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;
sdio_writeb(card->func, mask, HOST_INT_MASK_REG, &ret);
sdio_writeb(card->func, mask, card->reg->host_int_mask, &ret);
if (ret) {
BT_ERR("Unable to enable the host interrupt!");
ret = -EIO;
@ -128,13 +172,13 @@ static int btmrvl_sdio_disable_host_int_mask(struct btmrvl_sdio_card *card,
u8 host_int_mask;
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)
return -EIO;
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) {
BT_ERR("Unable to disable the host interrupt!");
return -EIO;
@ -150,7 +194,7 @@ static int btmrvl_sdio_poll_card_status(struct btmrvl_sdio_card *card, u8 bits)
int ret;
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)
goto failed;
if ((status & bits) == bits)
@ -299,7 +343,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
u8 base0, base1;
void *tmpfwbuf = NULL;
u8 *fwbuf;
u16 len;
u16 len, blksz_dl = card->sd_blksz_fw_dl;
int txlen = 0, tx_blocks = 0, count = 0;
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++) {
base0 = sdio_readb(card->func,
SQ_READ_BASE_ADDRESS_A0_REG, &ret);
card->reg->sq_read_base_addr_a0, &ret);
if (ret) {
BT_ERR("BASE0 register read failed:"
" base0 = 0x%04X(%d)."
@ -355,7 +399,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
goto done;
}
base1 = sdio_readb(card->func,
SQ_READ_BASE_ADDRESS_A1_REG, &ret);
card->reg->sq_read_base_addr_a1, &ret);
if (ret) {
BT_ERR("BASE1 register read failed:"
" 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)
txlen = firmwarelen - offset;
tx_blocks =
(txlen + SDIO_BLOCK_SIZE - 1) / SDIO_BLOCK_SIZE;
tx_blocks = (txlen + blksz_dl - 1) / blksz_dl;
memcpy(fwbuf, &firmware[offset], txlen);
}
ret = sdio_writesb(card->func, card->ioport, fwbuf,
tx_blocks * SDIO_BLOCK_SIZE);
tx_blocks * blksz_dl);
if (ret < 0) {
BT_ERR("FW download, writesb(%d) failed @%d",
count, offset);
sdio_writeb(card->func, HOST_CMD53_FIN, CONFIG_REG,
&ret);
sdio_writeb(card->func, HOST_CMD53_FIN,
card->reg->cfg, &ret);
if (ret)
BT_ERR("writeb failed (CFG)");
}
@ -597,7 +640,7 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func)
priv = card->priv;
ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret);
ireg = sdio_readb(card->func, card->reg->host_intstatus, &ret);
if (ret) {
BT_ERR("sdio_readb: read int status register failed");
return;
@ -613,7 +656,7 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func)
sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS |
UP_LD_HOST_INT_STATUS),
HOST_INTSTATUS_REG, &ret);
card->reg->host_intstatus, &ret);
if (ret) {
BT_ERR("sdio_writeb: clear int status register failed");
return;
@ -664,7 +707,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
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) {
ret = -EIO;
goto release_irq;
@ -672,7 +715,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
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) {
ret = -EIO;
goto release_irq;
@ -680,7 +723,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
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) {
ret = -EIO;
goto release_irq;
@ -815,6 +858,8 @@ exit:
static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card)
{
int ret = 0;
u8 fws0;
int pollnum = MAX_POLL_TRIES;
if (!card || !card->func) {
BT_ERR("card or function is NULL!");
@ -827,20 +872,36 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card)
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) {
BT_ERR("Failed to download helper!");
BT_ERR("Failed to read FW downloading status!");
ret = -EIO;
goto done;
}
if (fws0) {
BT_DBG("BT not the winner (%#x). Skip FW downloading", fws0);
if (btmrvl_sdio_download_fw_w_helper(card)) {
BT_ERR("Failed to download firmware!");
ret = -EIO;
goto done;
/* Give other function more time to download the firmware */
pollnum *= 10;
} else {
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!");
ret = -ETIMEDOUT;
goto done;
@ -864,7 +925,7 @@ static int btmrvl_sdio_wakeup_fw(struct btmrvl_private *priv)
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);
@ -893,8 +954,10 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
if (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->reg = data->reg;
card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
}
if (btmrvl_sdio_register_dev(card) < 0) {
@ -1011,3 +1074,4 @@ MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE("sd8688_helper.bin");
MODULE_FIRMWARE("sd8688.bin");
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");

View File

@ -47,44 +47,46 @@
/* Max retry number of CMD53 write */
#define MAX_WRITE_IOMEM_RETRY 2
/* Host Control Registers */
#define IO_PORT_0_REG 0x00
#define IO_PORT_1_REG 0x01
#define IO_PORT_2_REG 0x02
/* register bitmasks */
#define HOST_POWER_UP BIT(1)
#define HOST_CMD53_FIN BIT(2)
#define CONFIG_REG 0x03
#define HOST_POWER_UP BIT(1)
#define HOST_CMD53_FIN BIT(2)
#define HIM_DISABLE 0xff
#define HIM_ENABLE (BIT(0) | BIT(1))
#define HOST_INT_MASK_REG 0x04
#define HIM_DISABLE 0xff
#define HIM_ENABLE (BIT(0) | BIT(1))
#define UP_LD_HOST_INT_STATUS BIT(0)
#define DN_LD_HOST_INT_STATUS BIT(1)
#define HOST_INTSTATUS_REG 0x05
#define UP_LD_HOST_INT_STATUS BIT(0)
#define DN_LD_HOST_INT_STATUS BIT(1)
#define DN_LD_CARD_RDY BIT(0)
#define CARD_IO_READY BIT(3)
/* Card Control Registers */
#define SQ_READ_BASE_ADDRESS_A0_REG 0x10
#define SQ_READ_BASE_ADDRESS_A1_REG 0x11
#define FIRMWARE_READY 0xfedc
#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 sdio_func *func;
u32 ioport;
const char *helper;
const char *firmware;
const struct btmrvl_sdio_card_reg *reg;
u16 sd_blksz_fw_dl;
u8 rx_unit;
struct btmrvl_private *priv;
};
@ -92,6 +94,8 @@ struct btmrvl_sdio_card {
struct btmrvl_sdio_device {
const char *helper;
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 */
{ USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
/* Atheros AR9285 Malbec with sflash firmware */
{ 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 */
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");
return ret;
}
return count;
}

View File

@ -151,8 +151,13 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len)
/* Recv data */
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");
return ret;
}
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)
{
int ret;
struct hci_uart *hu = (void *)tty->disc_data;
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;
spin_lock(&hu->rx_lock);
hu->proto->recv(hu, (void *) data, count);
hu->hdev->stat.byte_rx += count;
ret = hu->proto->recv(hu, (void *) data, count);
if (ret > 0)
hu->hdev->stat.byte_rx += count;
spin_unlock(&hu->rx_lock);
tty_unthrottle(tty);

View File

@ -393,16 +393,6 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
priv = netdev_priv(dev);
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);
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;
struct rtable *rt;
struct neighbour *neigh;
struct flowi4 fl4;
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)) {
ret = PTR_ERR(rt);
goto out;
}
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) {
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)
{
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,
tos, 0);
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)
{
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,
tos, 0);
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 &
(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) {
if (nesvnic->rx_checksum_disabled == 0) {
if (nesvnic->netdev->features & NETIF_F_RXCSUM)
rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
}
} else
nes_debug(NES_DBG_CQ, "%s: unsuccessfully checksummed TCP or UDP packet."
" 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 &
(NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | 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;
/* nes_debug(NES_DBG_CQ, "%s: Reporting successfully checksummed IPv4 packet.\n",
nesvnic->netdev->name); */

View File

@ -1245,7 +1245,6 @@ struct nes_vnic {
u8 next_qp_nic_index;
u8 of_device_registered;
u8 rdma_enabled;
u8 rx_checksum_disabled;
u32 lro_max_aggr;
struct net_lro_mgr lro_mgr;
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)
/**
* 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
@ -1521,7 +1493,7 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd
et_cmd->maxrxpkt = 511;
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) {
et_cmd->supported = SUPPORTED_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->phy_address = mac_index;
}
et_cmd->speed = SPEED_10000;
ethtool_cmd_speed_set(et_cmd, SPEED_10000);
et_cmd->autoneg = AUTONEG_DISABLE;
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 = {
.get_link = ethtool_op_get_link,
.get_settings = nes_netdev_get_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_sset_count = nes_netdev_get_sset_count,
.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,
.get_pauseparam = nes_netdev_get_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;
memcpy(netdev->perm_addr, netdev->dev_addr, 6);
if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV)) {
netdev->features |= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
netdev->features |= NETIF_F_GSO | NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
} else {
netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
}
netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_IP_CSUM;
if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV))
netdev->hw_features |= NETIF_F_TSO;
netdev->features |= netdev->hw_features;
netdev->hw_features |= NETIF_F_LRO;
nes_debug(NES_DBG_INIT, "nesvnic = %p, reported features = 0x%lX, QPid = %d,"
" nic_index = %d, logical_port = %d, mac_index = %d.\n",

View File

@ -91,7 +91,6 @@ enum {
IPOIB_STOP_REAPER = 7,
IPOIB_FLAG_ADMIN_CM = 9,
IPOIB_FLAG_UMCAST = 10,
IPOIB_FLAG_CSUM = 11,
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);
ipoib_warn(priv, "enabling connected mode "
"will cause multicast packet drops\n");
dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO);
netdev_update_features(dev);
rtnl_unlock();
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")) {
clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
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;
}
netdev_update_features(dev);
dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu));
rtnl_unlock();
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);
}
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,
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 = {
.get_drvinfo = ipoib_get_drvinfo,
.get_rx_csum = ipoib_get_rx_csum,
.set_tso = ipoib_set_tso,
.get_coalesce = ipoib_get_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;
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;
napi_gro_receive(&priv->napi, skb);

View File

@ -171,6 +171,16 @@ static int ipoib_stop(struct net_device *dev)
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)
{
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_stop = ipoib_stop,
.ndo_change_mtu = ipoib_change_mtu,
.ndo_fix_features = ipoib_fix_features,
.ndo_start_xmit = ipoib_start_xmit,
.ndo_tx_timeout = ipoib_timeout,
.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);
if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) {
set_bit(IPOIB_FLAG_CSUM, &priv->flags);
priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
priv->dev->hw_features = NETIF_F_SG |
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;
}
static struct net_device *ipoib_add_port(const char *format,
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
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
tristate "CAPI2.0 capidrv interface support"
depends on ISDN_I4L

View File

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

View File

@ -38,15 +38,10 @@
#include <linux/isdn/capiutil.h>
#include <linux/isdn/capicmd.h>
#include "capifs.h"
MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface");
MODULE_AUTHOR("Carsten Paeth");
MODULE_LICENSE("GPL");
#undef _DEBUG_TTYFUNCS /* call to tty_driver */
#undef _DEBUG_DATAFLOW /* data flow */
/* -------- driver information -------------------------------------- */
static DEFINE_MUTEX(capi_mutex);
@ -85,7 +80,6 @@ struct capiminor {
struct kref kref;
unsigned int minor;
struct dentry *capifs_dentry;
struct capi20_appl *ap;
u32 ncci;
@ -300,17 +294,8 @@ static void capiminor_free(struct capiminor *mp)
static void capincci_alloc_minor(struct capidev *cdev, struct capincci *np)
{
struct capiminor *mp;
dev_t device;
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);
}
if (cdev->userflags & CAPIFLAG_HIGHJACKING)
np->minorp = capiminor_alloc(&cdev->ap, np->ncci);
}
static void capincci_free_minor(struct capincci *np)
@ -319,8 +304,6 @@ static void capincci_free_minor(struct capincci *np)
struct tty_struct *tty;
if (mp) {
capifs_free_ncci(mp->capifs_dentry);
tty = tty_port_tty_get(&mp->port);
if (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);
if (!tty) {
#ifdef _DEBUG_DATAFLOW
printk(KERN_DEBUG "capi: currently no receiver\n");
#endif
pr_debug("capi: currently no receiver\n");
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 defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n");
#endif
pr_debug("capi: ldisc has no receive_buf function\n");
/* fatal error, do not requeue */
goto free_skb;
}
if (mp->ttyinstop) {
#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
printk(KERN_DEBUG "capi: recv tty throttled\n");
#endif
pr_debug("capi: recv tty throttled\n");
goto deref_ldisc;
}
if (tty->receive_room < datalen) {
#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
printk(KERN_DEBUG "capi: no room in tty\n");
#endif
pr_debug("capi: no room in tty\n");
goto deref_ldisc;
}
@ -479,10 +454,8 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
if (errcode == CAPI_NOERROR) {
skb_pull(skb, CAPIMSG_LEN(skb->data));
#ifdef _DEBUG_DATAFLOW
printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
datahandle, skb->len);
#endif
pr_debug("capi: DATA_B3_RESP %u len=%d => ldisc\n",
datahandle, skb->len);
ld->ops->receive_buf(tty, skb->data, NULL, skb->len);
} else {
printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
@ -529,9 +502,7 @@ static void handle_minor_send(struct capiminor *mp)
return;
if (mp->ttyoutstop) {
#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
printk(KERN_DEBUG "capi: send: tty stopped\n");
#endif
pr_debug("capi: send: tty stopped\n");
tty_kref_put(tty);
return;
}
@ -573,10 +544,8 @@ static void handle_minor_send(struct capiminor *mp)
}
errcode = capi20_put_message(mp->ap, skb);
if (errcode == CAPI_NOERROR) {
#ifdef _DEBUG_DATAFLOW
printk(KERN_DEBUG "capi: DATA_B3_REQ %u len=%u\n",
datahandle, len);
#endif
pr_debug("capi: DATA_B3_REQ %u len=%u\n",
datahandle, len);
continue;
}
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) {
datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2);
#ifdef _DEBUG_DATAFLOW
printk(KERN_DEBUG "capi_signal: DATA_B3_IND %u len=%d\n",
datahandle, skb->len-CAPIMSG_LEN(skb->data));
#endif
pr_debug("capi_signal: DATA_B3_IND %u len=%d\n",
datahandle, skb->len-CAPIMSG_LEN(skb->data));
skb_queue_tail(&mp->inqueue, skb);
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) {
datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4);
#ifdef _DEBUG_DATAFLOW
printk(KERN_DEBUG "capi_signal: DATA_B3_CONF %u 0x%x\n",
datahandle,
CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2));
#endif
pr_debug("capi_signal: DATA_B3_CONF %u 0x%x\n",
datahandle,
CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2));
kfree_skb(skb);
capiminor_del_ack(mp, datahandle);
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 sk_buff *skb;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_write(count=%d)\n", count);
#endif
pr_debug("capinc_tty_write(count=%d)\n", count);
spin_lock_bh(&mp->outlock);
skb = mp->outskb;
@ -1133,9 +1096,7 @@ static int capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
struct sk_buff *skb;
int ret = 1;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_put_char(%u)\n", ch);
#endif
pr_debug("capinc_put_char(%u)\n", ch);
spin_lock_bh(&mp->outlock);
skb = mp->outskb;
@ -1174,9 +1135,7 @@ static void capinc_tty_flush_chars(struct tty_struct *tty)
struct capiminor *mp = tty->driver_data;
struct sk_buff *skb;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_flush_chars\n");
#endif
pr_debug("capinc_tty_flush_chars\n");
spin_lock_bh(&mp->outlock);
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 *= CAPI_MAX_BLKSIZE;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_write_room = %d\n", room);
#endif
pr_debug("capinc_tty_write_room = %d\n", room);
return room;
}
@ -1210,12 +1167,10 @@ static int capinc_tty_chars_in_buffer(struct tty_struct *tty)
{
struct capiminor *mp = tty->driver_data;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%d\n",
mp->outbytes, mp->nack,
skb_queue_len(&mp->outqueue),
skb_queue_len(&mp->inqueue));
#endif
pr_debug("capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%d\n",
mp->outbytes, mp->nack,
skb_queue_len(&mp->outqueue),
skb_queue_len(&mp->inqueue));
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)
{
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_set_termios\n");
#endif
pr_debug("capinc_tty_set_termios\n");
}
static void capinc_tty_throttle(struct tty_struct *tty)
{
struct capiminor *mp = tty->driver_data;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_throttle\n");
#endif
pr_debug("capinc_tty_throttle\n");
mp->ttyinstop = 1;
}
@ -1245,9 +1196,7 @@ static void capinc_tty_unthrottle(struct tty_struct *tty)
{
struct capiminor *mp = tty->driver_data;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_unthrottle\n");
#endif
pr_debug("capinc_tty_unthrottle\n");
mp->ttyinstop = 0;
handle_minor_recv(mp);
}
@ -1256,9 +1205,7 @@ static void capinc_tty_stop(struct tty_struct *tty)
{
struct capiminor *mp = tty->driver_data;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_stop\n");
#endif
pr_debug("capinc_tty_stop\n");
mp->ttyoutstop = 1;
}
@ -1266,9 +1213,7 @@ static void capinc_tty_start(struct tty_struct *tty)
{
struct capiminor *mp = tty->driver_data;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_start\n");
#endif
pr_debug("capinc_tty_start\n");
mp->ttyoutstop = 0;
handle_minor_send(mp);
}
@ -1277,39 +1222,29 @@ static void capinc_tty_hangup(struct tty_struct *tty)
{
struct capiminor *mp = tty->driver_data;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_hangup\n");
#endif
pr_debug("capinc_tty_hangup\n");
tty_port_hangup(&mp->port);
}
static int capinc_tty_break_ctl(struct tty_struct *tty, int state)
{
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_break_ctl(%d)\n", state);
#endif
pr_debug("capinc_tty_break_ctl(%d)\n", state);
return 0;
}
static void capinc_tty_flush_buffer(struct tty_struct *tty)
{
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_flush_buffer\n");
#endif
pr_debug("capinc_tty_flush_buffer\n");
}
static void capinc_tty_set_ldisc(struct tty_struct *tty)
{
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_set_ldisc\n");
#endif
pr_debug("capinc_tty_set_ldisc\n");
}
static void capinc_tty_send_xchar(struct tty_struct *tty, char ch)
{
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_send_xchar(%d)\n", ch);
#endif
pr_debug("capinc_tty_send_xchar(%d)\n", ch);
}
static const struct tty_operations capinc_ops = {
@ -1514,10 +1449,8 @@ static int __init capi_init(void)
proc_init();
#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
compileinfo = " (middleware+capifs)";
#elif defined(CONFIG_ISDN_CAPI_MIDDLEWARE)
compileinfo = " (no capifs)";
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
compileinfo = " (middleware)";
#else
compileinfo = " (no middleware)";
#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;
int status;
struct usb_iso_packet_descriptor *ifd;
int offset;
unsigned long flags;
int i;
struct sk_buff *skb;
@ -1225,7 +1224,6 @@ static void write_iso_tasklet(unsigned long data)
* successfully sent
* - all following frames are not sent at all
*/
offset = done->limit; /* default (no error) */
for (i = 0; i < BAS_NUMFRAMES; i++) {
ifd = &urb->iso_frame_desc[i];
if (ifd->status ||
@ -1235,9 +1233,6 @@ static void write_iso_tasklet(unsigned long data)
i, ifd->actual_length,
ifd->length,
get_usb_statmsg(ifd->status));
offset = (ifd->offset +
ifd->actual_length)
% BAS_OUTBUFSIZE;
break;
}
}

View File

@ -390,12 +390,12 @@ static const struct zsau_resp_t {
*/
static int cid_of_response(char *s)
{
unsigned long cid;
int cid;
int rc;
if (s[-1] != ';')
return 0; /* no CID separator */
rc = strict_strtoul(s, 10, &cid);
rc = kstrtoint(s, 10, &cid);
if (rc)
return 0; /* CID not numeric */
if (cid < 1 || cid > 65535)
@ -566,27 +566,19 @@ void gigaset_handle_modem_response(struct cardstate *cs)
case RT_ZCAU:
event->parameter = -1;
if (curarg + 1 < params) {
unsigned long type, value;
u8 type, value;
i = strict_strtoul(argv[curarg++], 16, &type);
j = strict_strtoul(argv[curarg++], 16, &value);
if (i == 0 && type < 256 &&
j == 0 && value < 256)
i = kstrtou8(argv[curarg++], 16, &type);
j = kstrtou8(argv[curarg++], 16, &value);
if (i == 0 && j == 0)
event->parameter = (type << 8) | value;
} else
curarg = params - 1;
break;
case RT_NUMBER:
event->parameter = -1;
if (curarg < params) {
unsigned long res;
int rc;
rc = strict_strtoul(argv[curarg++], 10, &res);
if (rc == 0)
event->parameter = res;
}
if (curarg >= params ||
kstrtoint(argv[curarg++], 10, &event->parameter))
event->parameter = -1;
gig_dbg(DEBUG_EVENT, "parameter==%d", event->parameter);
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) {
diva_os_spin_lock_magic_t old_irql, old_irql1;
dword sec, usec, logical, serial, org_mask;
int id, best_id = 0, free_id = -1;
int id, free_id = -1;
char tmp[128];
diva_dbg_entry_head_t* pmsg = NULL;
int len;
@ -906,7 +906,6 @@ void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) {
and slot is still free - reuse it
*/
free_id = id;
best_id = 1;
break;
}
}

View File

@ -1198,7 +1198,6 @@ static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
word ch;
word i;
word Info;
word CIP;
byte LinkLayer;
API_PARSE * ai;
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,LLC,&parms[7]);
add_s(plci,HLC,&parms[8]);
CIP = GET_WORD(parms[0].info);
if (a->Info_Mask[appl->Id-1] & 0x200)
{
/* 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 Id;
dword rId;
word Number = 0;
word i;
word cip;
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) {
/* Response to Get_Supported_Services request */
@ -5894,7 +5891,6 @@ static void sig_ind(PLCI *plci)
break;
case TEL_CTRL:
Number = 0;
ie = multi_fac_parms[0]; /* inspect the facility hook indications */
if(plci->State==ADVANCED_VOICE_SIG && ie[0]){
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)
{
word Info;
word i;
byte result[4];
dbug (1, dprintf ("[%06lx] %s,%d: dtmf_confirmation",
UnMapId (Id), (char *)(FILE_), __LINE__));
Info = GOOD;
result[0] = 2;
PUT_WORD (&result[1], DTMF_SUCCESS);
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)
{
DIVA_CAPI_ADAPTER *a;
word i, internal_command, Info;
word i, internal_command;
dbug (1, dprintf ("[%06lx] %s,%d: mixer_command %02x %04x %04x",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command,
plci->li_cmd));
Info = GOOD;
a = plci->adapter;
internal_command = plci->internal_command;
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",
UnMapId (Id), (char *)(FILE_), __LINE__));
Info = _FACILITY_NOT_SUPPORTED;
break;
}
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)
&& !(plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG));
}
Info = _FACILITY_NOT_SUPPORTED;
break;
}
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",
UnMapId (Id), (char *)(FILE_), __LINE__));
Info = _FACILITY_NOT_SUPPORTED;
break;
}
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)
{
dword d;
DIVA_CAPI_ADAPTER *a;
byte result[12];
dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_coefs_set",
UnMapId (Id), (char *)(FILE_), __LINE__));
a = plci->adapter;
if (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos)
{
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)
{
word Info;
word internal_command;
dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_ack_command %02x %04x",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
Info = GOOD;
internal_command = plci->internal_command;
plci->internal_command = 0;
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)
{
word Info;
word internal_command;
dbug (1, dprintf ("[%06lx] %s,%d: fax_edata_ack_command %02x %04x",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
Info = GOOD;
internal_command = plci->internal_command;
plci->internal_command = 0;
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)
{
word Info;
word internal_command;
dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
Info = GOOD;
internal_command = plci->internal_command;
plci->internal_command = 0;
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",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
Info = _WRONG_STATE;
break;
}
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 *ptr, *ptr1, new_f2;
int total, maxlen, new_z2;
int maxlen, new_z2;
struct zt *zp;
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");
return;
}
total = count;
count -= 3;
ptr = skb_put(bch->rx_skb, count);
@ -968,7 +967,6 @@ static void
ph_state_nt(struct dchannel *dch)
{
struct hfc_pci *hc = dch->hw;
u_char val;
if (dch->debug)
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;
Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
/* 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);
udelay(10);
Write_hfc(hc, HFCPCI_STATES, 4);

View File

@ -118,14 +118,12 @@ static void
ctrl_complete(struct urb *urb)
{
struct hfcsusb *hw = (struct hfcsusb *) urb->context;
struct ctrl_buf *buf;
if (debug & DBG_HFC_CALL_TRACE)
printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
urb->dev = hw->dev;
if (hw->ctrl_cnt) {
buf = &hw->ctrl_buff[hw->ctrl_out_idx];
hw->ctrl_cnt--; /* decrement actual count */
if (++hw->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
hw->ctrl_out_idx = 0; /* pointer wrap */
@ -1726,7 +1724,6 @@ hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel)
static int
setup_hfcsusb(struct hfcsusb *hw)
{
int err;
u_char b;
if (debug & DBG_HFC_CALL_TRACE)
@ -1745,7 +1742,7 @@ setup_hfcsusb(struct hfcsusb *hw)
}
/* 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;

View File

@ -30,8 +30,6 @@ add_arcofi_timer(struct IsdnCardState *cs) {
static void
send_arcofi(struct IsdnCardState *cs) {
u_char val;
add_arcofi_timer(cs);
cs->dc.isac.mon_txp = 0;
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 |= 0xa0;
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->dc.isac.mocr |= 0x10;
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)
{
local_info_t *dev;
int i;
IsdnCard_t icard;
dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
dev = link->priv;
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;
unsigned cval, fcr = 0;
int bits;
/* byte size and parity */
cval = 0x03; bits = 10;
cval = 0x03;
/* Determine divisor based on baud rate */
baud_base = BASE_BAUD;
quot = baud_base / baud;

View File

@ -258,11 +258,9 @@ static void
ctrl_complete(struct urb *urb)
{
hfcusb_data *hfc = (hfcusb_data *) urb->context;
ctrl_buft *buf;
urb->dev = hfc->dev;
if (hfc->ctrl_cnt) {
buf = &hfc->ctrl_buff[hfc->ctrl_out_idx];
hfc->ctrl_cnt--; /* decrement actual count */
if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
hfc->ctrl_out_idx = 0; /* pointer wrap */
@ -1097,7 +1095,7 @@ static int
hfc_usb_init(hfcusb_data * hfc)
{
usb_fifo *fifo;
int i, err;
int i;
u_char b;
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 */
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 */
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 sk_buff *skb = arg;
u_char cda1_cr, cda2_cr;
u_char cda1_cr;
switch (pr) {
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_TSDP11, 0x81); // Timeslot 0 is B1
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
cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x0a);
}

View File

@ -23,10 +23,9 @@
int
JadeVersion(struct IsdnCardState *cs, char *s)
{
int ver,i;
int ver;
int to = 50;
cs->BC_Write_Reg(cs, -1, 0x50, 0x19);
i=0;
while (to) {
udelay(1);
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
dss1up(struct PStack *st, int pr, void *arg)
{
int i, mt, cr, cause, callState;
int i, mt, cr, callState;
char *ptr;
u_char *p;
struct sk_buff *skb = arg;
@ -3034,12 +3034,10 @@ dss1up(struct PStack *st, int pr, void *arg)
return;
}
} else if (mt == MT_STATUS) {
cause = 0;
if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {
ptr++;
if (*ptr++ == 2)
ptr++;
cause = *ptr & 0x7f;
}
callState = 0;
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
ni1up(struct PStack *st, int pr, void *arg)
{
int i, mt, cr, cause, callState;
int i, mt, cr, callState;
char *ptr;
u_char *p;
struct sk_buff *skb = arg;
@ -2986,12 +2986,10 @@ ni1up(struct PStack *st, int pr, void *arg)
return;
}
} else if (mt == MT_STATUS) {
cause = 0;
if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {
ptr++;
if (*ptr++ == 2)
ptr++;
cause = *ptr & 0x7f;
}
callState = 0;
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 list_head list;
int number_of_leds;
struct usb_device *usb_dev;
struct hisax_d_if hisax_d_if;

View File

@ -46,8 +46,6 @@ module_param(debug, int, 0);
#endif
int st5481_debug;
static LIST_HEAD(adapter_list);
/* ======================================================================
* 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.l2l1 = st5481_b_l2l1;
}
list_add(&adapter->list, &adapter_list);
retval = st5481_setup_usb(adapter);
if (retval < 0)
@ -125,6 +122,7 @@ static int probe_st5481(struct usb_interface *intf,
err_usb:
st5481_release_usb(adapter);
err:
kfree(adapter);
return -EIO;
}
@ -142,8 +140,6 @@ static void disconnect_st5481(struct usb_interface *intf)
if (!adapter)
return;
list_del(&adapter->list);
st5481_stop(adapter);
st5481_release_b(&adapter->bcs[1]);
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)
{
local_info_t *dev;
int i;
IsdnCard_t icard;
dev_dbg(&link->dev, "teles_config(0x%p)\n", link);
dev = link->priv;
i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
if (i != 0)

View File

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

View File

@ -399,13 +399,8 @@ isdn_all_eaz(int di, int ch)
#include <linux/isdn/capicmd.h>
static int
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);
isdn_capi_rec_hl_msg(capi_msg *cm)
{
switch(cm->Command) {
case CAPI_FACILITY:
/* 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);
isdn_ctrl c;
int drvidx;
int chidx;
int ret;
int i;
char __user *p;
@ -1340,7 +1334,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
drvidx = isdn_minor2drv(minor);
if (drvidx < 0)
return -ENODEV;
chidx = isdn_minor2chan(minor);
if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING))
return -ENODEV;
return 0;

View File

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

View File

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

View File

@ -1640,7 +1640,7 @@ l2_tei_remove(struct FsmInst *fi, int event, void *arg)
}
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 sk_buff *skb = arg;
@ -1654,7 +1654,7 @@ l2_st14_persistant_da(struct FsmInst *fi, int event, void *arg)
}
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 sk_buff *skb = arg;
@ -1671,7 +1671,7 @@ l2_st5_persistant_da(struct FsmInst *fi, int event, void *arg)
}
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 sk_buff *skb = arg;
@ -1685,7 +1685,7 @@ l2_st6_persistant_da(struct FsmInst *fi, int event, void *arg)
}
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 sk_buff *skb = arg;
@ -1829,14 +1829,14 @@ static struct FsmNode L2FnList[] =
{ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error},
{ST_L2_7, 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_3, EV_L1_DEACTIVATE, l2_st3_tei_remove},
{ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistant_da},
{ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistant_da},
{ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistant_da},
{ST_L2_7, EV_L1_DEACTIVATE, l2_persistant_da},
{ST_L2_8, EV_L1_DEACTIVATE, l2_persistant_da},
{ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistent_da},
{ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistent_da},
{ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistent_da},
{ST_L2_7, EV_L1_DEACTIVATE, l2_persistent_da},
{ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da},
};
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))
return -EFAULT;
if (len != sizeof(char))
return -EINVAL;
switch (optname) {
case 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;
#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 ushort id_read_eeprom(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;
#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 = "TCM5091" }, /* 3Com Etherlink III */
{ .id = "TCM5094" }, /* 3Com Etherlink III (combo) */
@ -478,7 +478,7 @@ static int pnp_registered;
#endif /* CONFIG_PNP */
#ifdef CONFIG_EISA
static struct eisa_device_id el3_eisa_ids[] = {
static const struct eisa_device_id el3_eisa_ids[] __devinitconst = {
{ "TCM5090" },
{ "TCM5091" },
{ "TCM5092" },
@ -508,7 +508,7 @@ static int eisa_registered;
#ifdef CONFIG_MCA
static int el3_mca_probe(struct device *dev);
static short el3_mca_adapter_ids[] __initdata = {
static const short el3_mca_adapter_ids[] __devinitconst = {
0x627c,
0x627d,
0x62db,
@ -517,7 +517,7 @@ static short el3_mca_adapter_ids[] __initdata = {
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 (10baseT)",
"3Com 3c529 EtherLink III (test mode)",
@ -601,7 +601,7 @@ static void el3_common_remove (struct net_device *dev)
}
#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,
* heavily modified by Chris Beauregard
@ -671,7 +671,7 @@ static int __init el3_mca_probe(struct device *device)
#endif /* CONFIG_MCA */
#ifdef CONFIG_EISA
static int __init el3_eisa_probe (struct device *device)
static int __devinit el3_eisa_probe (struct device *device)
{
short i;
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->speed = SPEED_10;
ethtool_cmd_speed_set(ecmd, SPEED_10);
EL3WINDOW(1);
return 0;
}

View File

@ -901,14 +901,14 @@ static const struct dev_pm_ops vortex_pm_ops = {
#endif /* !CONFIG_PM */
#ifdef CONFIG_EISA
static struct eisa_device_id vortex_eisa_ids[] = {
static const struct eisa_device_id vortex_eisa_ids[] __devinitconst = {
{ "TCM5920", CH_3C592 },
{ "TCM5970", CH_3C597 },
{ "" }
};
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;
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;
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) {
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;
}
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);
return (cpr16(CpCmd) & RxChkSum) ? 1 : 0;
}
unsigned long flags;
static int cp_set_rx_csum(struct net_device *dev, u32 data)
{
struct cp_private *cp = netdev_priv(dev);
u16 cmd = cp->cpcmd, newcmd;
if (!((dev->features ^ features) & NETIF_F_RXCSUM))
return 0;
newcmd = cmd;
spin_lock_irqsave(&cp->lock, flags);
if (data)
newcmd |= RxChkSum;
if (features & NETIF_F_RXCSUM)
cp->cpcmd |= RxChkSum;
else
newcmd &= ~RxChkSum;
cp->cpcmd &= ~RxChkSum;
if (newcmd != cmd) {
unsigned long flags;
spin_lock_irqsave(&cp->lock, flags);
cp->cpcmd = newcmd;
cpw16_f(CpCmd, newcmd);
spin_unlock_irqrestore(&cp->lock, flags);
}
cpw16_f(CpCmd, cp->cpcmd);
spin_unlock_irqrestore(&cp->lock, flags);
return 0;
}
@ -1554,11 +1544,6 @@ static const struct ethtool_ops cp_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_msglevel = cp_get_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_wol = cp_get_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_start_xmit = cp_start_xmit,
.ndo_tx_timeout = cp_tx_timeout,
.ndo_set_features = cp_set_features,
#if CP_VLAN_TAG_USED
.ndo_vlan_rx_register = cp_vlan_rx_register,
#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) |
PCIMulRW | RxChkSum | CpRxOn | CpTxOn;
dev->features |= NETIF_F_RXCSUM;
dev->hw_features |= NETIF_F_RXCSUM;
regs = ioremap(pciaddr, CP_REGS_SIZE);
if (!regs) {
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)
dev->features |= NETIF_F_HIGHDMA;
#if 0 /* disabled by default until verified */
dev->features |= NETIF_F_TSO;
#endif
/* disabled by default until verified */
dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
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);
if (link & LNK_1000MB)
ecmd->speed = SPEED_1000;
ethtool_cmd_speed_set(ecmd, SPEED_1000);
else {
link = readl(&regs->FastLnkState);
if (link & LNK_100MB)
ecmd->speed = SPEED_100;
ethtool_cmd_speed_set(ecmd, SPEED_100);
else if (link & LNK_10MB)
ecmd->speed = SPEED_10;
ethtool_cmd_speed_set(ecmd, SPEED_10);
else
ecmd->speed = 0;
ethtool_cmd_speed_set(ecmd, 0);
}
if (link & LNK_FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
@ -2719,9 +2719,9 @@ static int ace_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
link |= LNK_TX_FLOW_CTL_Y;
if (ecmd->autoneg == AUTONEG_ENABLE)
link |= LNK_NEGOTIATE;
if (ecmd->speed != speed) {
if (ethtool_cmd_speed(ecmd) != speed) {
link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB);
switch (speed) {
switch (ethtool_cmd_speed(ecmd)) {
case SPEED_1000:
link |= LNK_1000MB;
break;

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)
{
cmd->supported = etherh_priv(dev)->supported;
cmd->speed = SPEED_10;
ethtool_cmd_speed_set(cmd, SPEED_10);
cmd->duplex = DUPLEX_HALF;
cmd->port = dev->if_port == IF_PORT_10BASET ? PORT_TP : PORT_BNC;
cmd->autoneg = dev->flags & IFF_AUTOMEDIA ? AUTONEG_ENABLE : AUTONEG_DISABLE;
cmd->autoneg = (dev->flags & IFF_AUTOMEDIA ?
AUTONEG_ENABLE : AUTONEG_DISABLE);
return 0;
}

View File

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

View File

@ -50,13 +50,13 @@ static int atl1c_get_settings(struct net_device *netdev,
ecmd->transceiver = XCVR_INTERNAL;
if (adapter->link_speed != SPEED_0) {
ecmd->speed = adapter->link_speed;
ethtool_cmd_speed_set(ecmd, adapter->link_speed);
if (adapter->link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
} else {
ecmd->speed = -1;
ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1;
}
@ -77,7 +77,8 @@ static int atl1c_set_settings(struct net_device *netdev,
if (ecmd->autoneg == AUTONEG_ENABLE) {
autoneg_advertised = ADVERTISED_Autoneg;
} else {
if (ecmd->speed == SPEED_1000) {
u32 speed = ethtool_cmd_speed(ecmd);
if (speed == SPEED_1000) {
if (ecmd->duplex != DUPLEX_FULL) {
if (netif_msg_link(adapter))
dev_warn(&adapter->pdev->dev,
@ -86,7 +87,7 @@ static int atl1c_set_settings(struct net_device *netdev,
return -EINVAL;
}
autoneg_advertised = ADVERTISED_1000baseT_Full;
} else if (ecmd->speed == SPEED_100) {
} else if (speed == SPEED_100) {
if (ecmd->duplex == DUPLEX_FULL)
autoneg_advertised = ADVERTISED_100baseT_Full;
else
@ -113,11 +114,6 @@ static int atl1c_set_settings(struct net_device *netdev,
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)
{
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_eeprom_len = atl1c_get_eeprom_len,
.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)

View File

@ -480,6 +480,15 @@ static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter,
adapter->rx_buffer_len = mtu > 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
* @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;
adapter->hw.max_frame_size = new_mtu;
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);
netdev_update_features(netdev);
atl1c_up(adapter);
clear_bit(__AT_RESETTING, &adapter->flags);
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;
u16 tx_offload_thresh;
u32 txq_ctrl_data;
u32 extra_size = 0; /* Jumbo frame threshold in QWORD unit */
u32 max_pay_load_data;
extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN;
tx_offload_thresh = MAX_TX_OFFLOAD_THRESH;
AT_WRITE_REG(hw, REG_TX_TSO_OFFLOAD_THRESH,
(tx_offload_thresh >> 3) & TX_TSO_OFFLOAD_THRESH_MASK);
@ -2536,6 +2537,7 @@ static int atl1c_suspend(struct device *dev)
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int atl1c_resume(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
@ -2562,6 +2564,7 @@ static int atl1c_resume(struct device *dev)
return 0;
}
#endif
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_multicast_list = atl1c_set_multi,
.ndo_change_mtu = atl1c_change_mtu,
.ndo_fix_features = atl1c_fix_features,
.ndo_do_ioctl = atl1c_ioctl,
.ndo_tx_timeout = atl1c_tx_timeout,
.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);
/* TODO: add when ready */
netdev->features = NETIF_F_SG |
netdev->hw_features = NETIF_F_SG |
NETIF_F_HW_CSUM |
NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
NETIF_F_TSO |
NETIF_F_TSO6;
netdev->features = netdev->hw_features |
NETIF_F_HW_VLAN_RX;
return 0;
}

View File

@ -51,13 +51,13 @@ static int atl1e_get_settings(struct net_device *netdev,
ecmd->transceiver = XCVR_INTERNAL;
if (adapter->link_speed != SPEED_0) {
ecmd->speed = adapter->link_speed;
ethtool_cmd_speed_set(ecmd, adapter->link_speed);
if (adapter->link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
} else {
ecmd->speed = -1;
ethtool_cmd_speed_set(ecmd, -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 = atl1e_get_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)

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

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