1
0
Fork 0

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next

This merge resolves conflicts with 75aec9df3a ("bridge: Remove
br_nf_push_frag_xmit_sk") as part of Eric Biederman's effort to improve
netns support in the network stack that reached upstream via David's
net-next tree.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

Conflicts:
	net/bridge/br_netfilter_hooks.c
hifive-unleashed-5.1
Pablo Neira Ayuso 2015-10-17 14:11:08 +02:00
commit f0a0a978b6
620 changed files with 23810 additions and 7286 deletions

View File

@ -0,0 +1,23 @@
* Broadcom iProc MDIO bus controller
Required properties:
- compatible: should be "brcm,iproc-mdio"
- reg: address and length of the register set for the MDIO interface
- #size-cells: must be 1
- #address-cells: must be 0
Child nodes of this MDIO bus controller node are standard Ethernet PHY device
nodes as described in Documentation/devicetree/bindings/net/phy.txt
Example:
mdio@18002000 {
compatible = "brcm,iproc-mdio";
reg = <0x18002000 0x8>;
#size-cells = <1>;
#address-cells = <0>;
enet-gphy@0 {
reg = <0>;
};
};

View File

@ -57,6 +57,10 @@ Properties:
"rgmii-id", as all other connection types are detected by hardware.
- fsl,magic-packet : If present, indicates that the hardware supports
waking up via magic packet.
- fsl,wake-on-filer : If present, indicates that the hardware supports
waking up by Filer General Purpose Interrupt (FGPI) asserted on the
Rx int line. This is an advanced power management capability allowing
certain packet types (user) defined by filer rules to wake up the system.
- bd-stash : If present, indicates that the hardware supports stashing
buffer descriptors in the L2.
- rx-stash-len : Denotes the number of bytes of a received buffer to stash

View File

@ -0,0 +1,20 @@
* MRF24J40 IEEE 802.15.4 *
Required properties:
- compatible: should be "microchip,mrf24j40", "microchip,mrf24j40ma",
or "microchip,mrf24j40mc" depends on your transceiver
board
- spi-max-frequency: maximal bus speed, should be set something under or equal
10000000
- reg: the chipselect index
- interrupts: the interrupt generated by the device.
Example:
mrf24j40ma@0 {
compatible = "microchip,mrf24j40ma";
spi-max-frequency = <8500000>;
reg = <0>;
interrupts = <19 8>;
interrupt-parent = <&gpio3>;
};

View File

@ -90,7 +90,304 @@ or to specify the output device using cmsg and IP_PKTINFO.
Limitations
-----------
VRF device currently only works for IPv4. Support for IPv6 is under development.
Index of original ingress interface is not available via cmsg. Will address
soon.
################################################################################
Using iproute2 for VRFs
=======================
VRF devices do *not* have to start with 'vrf-'. That is a convention used here
for emphasis of the device type, similar to use of 'br' in bridge names.
1. Create a VRF
To instantiate a VRF device and associate it with a table:
$ ip link add dev NAME type vrf table ID
Remember to add the ip rules as well:
$ ip ru add oif NAME table 10
$ ip ru add iif NAME table 10
$ ip -6 ru add oif NAME table 10
$ ip -6 ru add iif NAME table 10
Without the rules route lookups are not directed to the table.
For example:
$ ip link add dev vrf-blue type vrf table 10
$ ip ru add pref 200 oif vrf-blue table 10
$ ip ru add pref 200 iif vrf-blue table 10
$ ip -6 ru add pref 200 oif vrf-blue table 10
$ ip -6 ru add pref 200 iif vrf-blue table 10
2. List VRFs
To list VRFs that have been created:
$ ip [-d] link show type vrf
NOTE: The -d option is needed to show the table id
For example:
$ ip -d link show type vrf
11: vrf-mgmt: <NOARP,MASTER,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 72:b3:ba:91:e2:24 brd ff:ff:ff:ff:ff:ff promiscuity 0
vrf table 1 addrgenmode eui64
12: vrf-red: <NOARP,MASTER,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether b6:6f:6e:f6:da:73 brd ff:ff:ff:ff:ff:ff promiscuity 0
vrf table 10 addrgenmode eui64
13: vrf-blue: <NOARP,MASTER,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 36:62:e8:7d:bb:8c brd ff:ff:ff:ff:ff:ff promiscuity 0
vrf table 66 addrgenmode eui64
14: vrf-green: <NOARP,MASTER,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether e6:28:b8:63:70:bb brd ff:ff:ff:ff:ff:ff promiscuity 0
vrf table 81 addrgenmode eui64
Or in brief output:
$ ip -br link show type vrf
vrf-mgmt UP 72:b3:ba:91:e2:24 <NOARP,MASTER,UP,LOWER_UP>
vrf-red UP b6:6f:6e:f6:da:73 <NOARP,MASTER,UP,LOWER_UP>
vrf-blue UP 36:62:e8:7d:bb:8c <NOARP,MASTER,UP,LOWER_UP>
vrf-green UP e6:28:b8:63:70:bb <NOARP,MASTER,UP,LOWER_UP>
3. Assign a Network Interface to a VRF
Network interfaces are assigned to a VRF by enslaving the netdevice to a
VRF device:
$ ip link set dev NAME master VRF-NAME
On enslavement connected and local routes are automatically moved to the
table associated with the VRF device.
For example:
$ ip link set dev eth0 master vrf-mgmt
4. Show Devices Assigned to a VRF
To show devices that have been assigned to a specific VRF add the master
option to the ip command:
$ ip link show master VRF-NAME
For example:
$ ip link show master vrf-red
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master vrf-red state UP mode DEFAULT group default qlen 1000
link/ether 02:00:00:00:02:02 brd ff:ff:ff:ff:ff:ff
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master vrf-red state UP mode DEFAULT group default qlen 1000
link/ether 02:00:00:00:02:03 brd ff:ff:ff:ff:ff:ff
7: eth5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master vrf-red state DOWN mode DEFAULT group default qlen 1000
link/ether 02:00:00:00:02:06 brd ff:ff:ff:ff:ff:ff
Or using the brief output:
$ ip -br link show master vrf-red
eth1 UP 02:00:00:00:02:02 <BROADCAST,MULTICAST,UP,LOWER_UP>
eth2 UP 02:00:00:00:02:03 <BROADCAST,MULTICAST,UP,LOWER_UP>
eth5 DOWN 02:00:00:00:02:06 <BROADCAST,MULTICAST>
5. Show Neighbor Entries for a VRF
To list neighbor entries associated with devices enslaved to a VRF device
add the master option to the ip command:
$ ip [-6] neigh show master VRF-NAME
For example:
$ ip neigh show master vrf-red
10.2.1.254 dev eth1 lladdr a6:d9:c7:4f:06:23 REACHABLE
10.2.2.254 dev eth2 lladdr 5e:54:01:6a:ee:80 REACHABLE
$ ip -6 neigh show master vrf-red
2002:1::64 dev eth1 lladdr a6:d9:c7:4f:06:23 REACHABLE
6. Show Addresses for a VRF
To show addresses for interfaces associated with a VRF add the master
option to the ip command:
$ ip addr show master VRF-NAME
For example:
$ ip addr show master vrf-red
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master vrf-red state UP group default qlen 1000
link/ether 02:00:00:00:02:02 brd ff:ff:ff:ff:ff:ff
inet 10.2.1.2/24 brd 10.2.1.255 scope global eth1
valid_lft forever preferred_lft forever
inet6 2002:1::2/120 scope global
valid_lft forever preferred_lft forever
inet6 fe80::ff:fe00:202/64 scope link
valid_lft forever preferred_lft forever
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master vrf-red state UP group default qlen 1000
link/ether 02:00:00:00:02:03 brd ff:ff:ff:ff:ff:ff
inet 10.2.2.2/24 brd 10.2.2.255 scope global eth2
valid_lft forever preferred_lft forever
inet6 2002:2::2/120 scope global
valid_lft forever preferred_lft forever
inet6 fe80::ff:fe00:203/64 scope link
valid_lft forever preferred_lft forever
7: eth5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master vrf-red state DOWN group default qlen 1000
link/ether 02:00:00:00:02:06 brd ff:ff:ff:ff:ff:ff
Or in brief format:
$ ip -br addr show master vrf-red
eth1 UP 10.2.1.2/24 2002:1::2/120 fe80::ff:fe00:202/64
eth2 UP 10.2.2.2/24 2002:2::2/120 fe80::ff:fe00:203/64
eth5 DOWN
7. Show Routes for a VRF
To show routes for a VRF use the ip command to display the table associated
with the VRF device:
$ ip [-6] route show table ID
For example:
$ ip route show table vrf-red
prohibit default
broadcast 10.2.1.0 dev eth1 proto kernel scope link src 10.2.1.2
10.2.1.0/24 dev eth1 proto kernel scope link src 10.2.1.2
local 10.2.1.2 dev eth1 proto kernel scope host src 10.2.1.2
broadcast 10.2.1.255 dev eth1 proto kernel scope link src 10.2.1.2
broadcast 10.2.2.0 dev eth2 proto kernel scope link src 10.2.2.2
10.2.2.0/24 dev eth2 proto kernel scope link src 10.2.2.2
local 10.2.2.2 dev eth2 proto kernel scope host src 10.2.2.2
broadcast 10.2.2.255 dev eth2 proto kernel scope link src 10.2.2.2
$ ip -6 route show table vrf-red
local 2002:1:: dev lo proto none metric 0 pref medium
local 2002:1::2 dev lo proto none metric 0 pref medium
2002:1::/120 dev eth1 proto kernel metric 256 pref medium
local 2002:2:: dev lo proto none metric 0 pref medium
local 2002:2::2 dev lo proto none metric 0 pref medium
2002:2::/120 dev eth2 proto kernel metric 256 pref medium
local fe80:: dev lo proto none metric 0 pref medium
local fe80:: dev lo proto none metric 0 pref medium
local fe80::ff:fe00:202 dev lo proto none metric 0 pref medium
local fe80::ff:fe00:203 dev lo proto none metric 0 pref medium
fe80::/64 dev eth1 proto kernel metric 256 pref medium
fe80::/64 dev eth2 proto kernel metric 256 pref medium
ff00::/8 dev vrf-red metric 256 pref medium
ff00::/8 dev eth1 metric 256 pref medium
ff00::/8 dev eth2 metric 256 pref medium
8. Route Lookup for a VRF
A test route lookup can be done for a VRF by adding the oif option to ip:
$ ip [-6] route get oif VRF-NAME ADDRESS
For example:
$ ip route get 10.2.1.40 oif vrf-red
10.2.1.40 dev eth1 table vrf-red src 10.2.1.2
cache
$ ip -6 route get 2002:1::32 oif vrf-red
2002:1::32 from :: dev eth1 table vrf-red proto kernel src 2002:1::2 metric 256 pref medium
9. Removing Network Interface from a VRF
Network interfaces are removed from a VRF by breaking the enslavement to
the VRF device:
$ ip link set dev NAME nomaster
Connected routes are moved back to the default table and local entries are
moved to the local table.
For example:
$ ip link set dev eth0 nomaster
--------------------------------------------------------------------------------
Commands used in this example:
cat >> /etc/iproute2/rt_tables <<EOF
1 vrf-mgmt
10 vrf-red
66 vrf-blue
81 vrf-green
EOF
function vrf_create
{
VRF=$1
TBID=$2
# create VRF device
ip link add vrf-${VRF} type vrf table ${TBID}
# add rules that direct lookups to vrf table
ip ru add pref 200 oif vrf-${VRF} table ${TBID}
ip ru add pref 200 iif vrf-${VRF} table ${TBID}
ip -6 ru add pref 200 oif vrf-${VRF} table ${TBID}
ip -6 ru add pref 200 iif vrf-${VRF} table ${TBID}
if [ "${VRF}" != "mgmt" ]; then
ip route add table ${TBID} prohibit default
fi
ip link set dev vrf-${VRF} up
ip link set dev vrf-${VRF} state up
}
vrf_create mgmt 1
ip link set dev eth0 master vrf-mgmt
vrf_create red 10
ip link set dev eth1 master vrf-red
ip link set dev eth2 master vrf-red
ip link set dev eth5 master vrf-red
vrf_create blue 66
ip link set dev eth3 master vrf-blue
vrf_create green 81
ip link set dev eth4 master vrf-green
Interface addresses from /etc/network/interfaces:
auto eth0
iface eth0 inet static
address 10.0.0.2
netmask 255.255.255.0
gateway 10.0.0.254
iface eth0 inet6 static
address 2000:1::2
netmask 120
auto eth1
iface eth1 inet static
address 10.2.1.2
netmask 255.255.255.0
iface eth1 inet6 static
address 2002:1::2
netmask 120
auto eth2
iface eth2 inet static
address 10.2.2.2
netmask 255.255.255.0
iface eth2 inet6 static
address 2002:2::2
netmask 120
auto eth3
iface eth3 inet static
address 10.2.3.2
netmask 255.255.255.0
iface eth3 inet6 static
address 2002:3::2
netmask 120
auto eth4
iface eth4 inet static
address 10.2.4.2
netmask 255.255.255.0
iface eth4 inet6 static
address 2002:4::2
netmask 120

View File

@ -5546,7 +5546,7 @@ F: drivers/net/wireless/iwlegacy/
INTEL WIRELESS WIFI LINK (iwlwifi)
M: Johannes Berg <johannes.berg@intel.com>
M: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
M: Intel Linux Wireless <ilw@linux.intel.com>
M: Intel Linux Wireless <linuxwifi@intel.com>
L: linux-wireless@vger.kernel.org
W: http://intellinuxwireless.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi.git
@ -6978,6 +6978,7 @@ M: Alan Ott <alan@signal11.us>
L: linux-wpan@vger.kernel.org
S: Maintained
F: drivers/net/ieee802154/mrf24j40.c
F: Documentation/devicetree/bindings/net/ieee802154/mrf24j40.txt
MSI LAPTOP SUPPORT
M: "Lee, Chun-Yi" <jlee@suse.com>

View File

@ -125,7 +125,7 @@ static u64 jit_get_skb_w(struct sk_buff *skb, int offset)
}
/*
* Wrapper that handles both OABI and EABI and assures Thumb2 interworking
* Wrappers which handle both OABI and EABI and assures Thumb2 interworking
* (where the assembly routines like __aeabi_uidiv could cause problems).
*/
static u32 jit_udiv(u32 dividend, u32 divisor)
@ -133,6 +133,11 @@ static u32 jit_udiv(u32 dividend, u32 divisor)
return dividend / divisor;
}
static u32 jit_mod(u32 dividend, u32 divisor)
{
return dividend % divisor;
}
static inline void _emit(int cond, u32 inst, struct jit_ctx *ctx)
{
inst |= (cond << 28);
@ -471,11 +476,17 @@ static inline void emit_blx_r(u8 tgt_reg, struct jit_ctx *ctx)
#endif
}
static inline void emit_udiv(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx)
static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx,
int bpf_op)
{
#if __LINUX_ARM_ARCH__ == 7
if (elf_hwcap & HWCAP_IDIVA) {
emit(ARM_UDIV(rd, rm, rn), ctx);
if (bpf_op == BPF_DIV)
emit(ARM_UDIV(rd, rm, rn), ctx);
else {
emit(ARM_UDIV(ARM_R3, rm, rn), ctx);
emit(ARM_MLS(rd, rn, ARM_R3, rm), ctx);
}
return;
}
#endif
@ -496,7 +507,8 @@ static inline void emit_udiv(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx)
emit(ARM_MOV_R(ARM_R0, rm), ctx);
ctx->seen |= SEEN_CALL;
emit_mov_i(ARM_R3, (u32)jit_udiv, ctx);
emit_mov_i(ARM_R3, bpf_op == BPF_DIV ? (u32)jit_udiv : (u32)jit_mod,
ctx);
emit_blx_r(ARM_R3, ctx);
if (rd != ARM_R0)
@ -697,13 +709,27 @@ load_ind:
if (k == 1)
break;
emit_mov_i(r_scratch, k, ctx);
emit_udiv(r_A, r_A, r_scratch, ctx);
emit_udivmod(r_A, r_A, r_scratch, ctx, BPF_DIV);
break;
case BPF_ALU | BPF_DIV | BPF_X:
update_on_xread(ctx);
emit(ARM_CMP_I(r_X, 0), ctx);
emit_err_ret(ARM_COND_EQ, ctx);
emit_udiv(r_A, r_A, r_X, ctx);
emit_udivmod(r_A, r_A, r_X, ctx, BPF_DIV);
break;
case BPF_ALU | BPF_MOD | BPF_K:
if (k == 1) {
emit_mov_i(r_A, 0, ctx);
break;
}
emit_mov_i(r_scratch, k, ctx);
emit_udivmod(r_A, r_A, r_scratch, ctx, BPF_MOD);
break;
case BPF_ALU | BPF_MOD | BPF_X:
update_on_xread(ctx);
emit(ARM_CMP_I(r_X, 0), ctx);
emit_err_ret(ARM_COND_EQ, ctx);
emit_udivmod(r_A, r_A, r_X, ctx, BPF_MOD);
break;
case BPF_ALU | BPF_OR | BPF_K:
/* A |= K */

View File

@ -115,6 +115,8 @@
#define ARM_INST_UMULL 0x00800090
#define ARM_INST_MLS 0x00600090
/*
* Use a suitable undefined instruction to use for ARM/Thumb2 faulting.
* We need to be careful not to conflict with those used by other modules
@ -210,4 +212,7 @@
#define ARM_UMULL(rd_lo, rd_hi, rn, rm) (ARM_INST_UMULL | (rd_hi) << 16 \
| (rd_lo) << 12 | (rm) << 8 | rn)
#define ARM_MLS(rd, rn, rm, ra) (ARM_INST_MLS | (rd) << 16 | (rn) | (rm) << 8 \
| (ra) << 12)
#endif /* PFILTER_OPCODES_ARM_H */

View File

@ -224,10 +224,12 @@
/include/ "pq3-etsec2-0.dtsi"
enet0: enet0_grp2: ethernet@b0000 {
fsl,wake-on-filer;
};
/include/ "pq3-etsec2-1.dtsi"
enet1: enet1_grp2: ethernet@b1000 {
fsl,wake-on-filer;
};
global-utilities@e0000 {

View File

@ -112,7 +112,8 @@ static void ia_enque_head_rtn_q (IARTN_Q *que, IARTN_Q * data)
static int ia_enque_rtn_q (IARTN_Q *que, struct desc_tbl_t data) {
IARTN_Q *entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
if (!entry) return -1;
if (!entry)
return -ENOMEM;
entry->data = data;
entry->next = NULL;
if (que->next == NULL)
@ -1175,7 +1176,7 @@ static int rx_pkt(struct atm_dev *dev)
if (!(skb = atm_alloc_charge(vcc, len, GFP_ATOMIC))) {
if (vcc->vci < 32)
printk("Drop control packets\n");
goto out_free_desc;
goto out_free_desc;
}
skb_put(skb,len);
// pwang_test

View File

@ -98,6 +98,8 @@ struct regmap {
int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
int (*reg_write)(void *context, unsigned int reg, unsigned int val);
int (*reg_update_bits)(void *context, unsigned int reg,
unsigned int mask, unsigned int val);
bool defer_caching;

View File

@ -619,6 +619,7 @@ struct regmap *__regmap_init(struct device *dev,
goto skip_format_initialization;
} else {
map->reg_read = _regmap_bus_read;
map->reg_update_bits = bus->reg_update_bits;
}
reg_endian = regmap_get_reg_endian(bus, config);
@ -2509,20 +2510,26 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
int ret;
unsigned int tmp, orig;
ret = _regmap_read(map, reg, &orig);
if (ret != 0)
return ret;
if (change)
*change = false;
tmp = orig & ~mask;
tmp |= val & mask;
if (force_write || (tmp != orig)) {
ret = _regmap_write(map, reg, tmp);
if (change)
if (regmap_volatile(map, reg) && map->reg_update_bits) {
ret = map->reg_update_bits(map->bus_context, reg, mask, val);
if (ret == 0 && change)
*change = true;
} else {
if (change)
*change = false;
ret = _regmap_read(map, reg, &orig);
if (ret != 0)
return ret;
tmp = orig & ~mask;
tmp |= val & mask;
if (force_write || (tmp != orig)) {
ret = _regmap_write(map, reg, tmp);
if (ret == 0 && change)
*change = true;
}
}
return ret;

View File

@ -436,13 +436,8 @@ int bcma_bus_register(struct bcma_bus *bus)
}
dev = bcma_bus_get_host_dev(bus);
/* TODO: remove check for IS_BUILTIN(CONFIG_BCMA) check when
* of_default_bus_match_table is exported or in some other way
* accessible. This is just a temporary workaround.
*/
if (IS_BUILTIN(CONFIG_BCMA) && dev) {
of_platform_populate(dev->of_node, of_default_bus_match_table,
NULL, dev);
if (dev) {
of_platform_default_populate(dev->of_node, NULL, dev);
}
/* Cores providing flash access go before SPROM init */

View File

@ -4,6 +4,7 @@ menu "Bluetooth device drivers"
config BT_INTEL
tristate
select REGMAP
config BT_BCM
tristate
@ -183,6 +184,7 @@ config BT_HCIBCM203X
config BT_HCIBPA10X
tristate "HCI BPA10x USB driver"
depends on USB
select BT_HCIUART_H4
help
Bluetooth HCI BPA10x USB driver.
This driver provides support for the Digianswer BPA 100/105 Bluetooth
@ -275,7 +277,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/8787/8797/8887/8897.
Marvell Bluetooth devices, such as 8688/8787/8797/8887/8897/8997.
Say Y here to compile Marvell Bluetooth driver
into the kernel or say M to compile it as module.
@ -289,7 +291,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 SD8688/SD8787/SD8797/SD8887/SD8897
devices with SDIO interface. Currently SD8688/SD8787/SD8797/SD8887/SD8897/SD8997
chipsets are supported.
Say Y here to compile support for Marvell BT-over-SDIO driver

View File

@ -422,17 +422,12 @@ static int bfusb_open(struct hci_dev *hdev)
BT_DBG("hdev %p bfusb %p", hdev, data);
if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
return 0;
write_lock_irqsave(&data->lock, flags);
err = bfusb_rx_submit(data, NULL);
if (!err) {
for (i = 1; i < BFUSB_MAX_BULK_RX; i++)
bfusb_rx_submit(data, NULL);
} else {
clear_bit(HCI_RUNNING, &hdev->flags);
}
write_unlock_irqrestore(&data->lock, flags);
@ -458,9 +453,6 @@ static int bfusb_close(struct hci_dev *hdev)
BT_DBG("hdev %p bfusb %p", hdev, data);
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
write_lock_irqsave(&data->lock, flags);
write_unlock_irqrestore(&data->lock, flags);
@ -479,9 +471,6 @@ static int bfusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
hdev->stat.cmd_tx++;

View File

@ -390,7 +390,7 @@ static void bluecard_receive(struct bluecard_info *info,
for (i = 0; i < len; i++) {
/* Allocate packet */
if (info->rx_skb == NULL) {
if (!info->rx_skb) {
info->rx_state = RECV_WAIT_PACKET_TYPE;
info->rx_count = 0;
info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
@ -628,9 +628,6 @@ static int bluecard_hci_open(struct hci_dev *hdev)
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
if (test_and_set_bit(HCI_RUNNING, &(hdev->flags)))
return 0;
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) {
unsigned int iobase = info->p_dev->resource[0]->start;
@ -646,9 +643,6 @@ static int bluecard_hci_close(struct hci_dev *hdev)
{
struct bluecard_info *info = hci_get_drvdata(hdev);
if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
return 0;
bluecard_hci_flush(hdev);
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) {

View File

@ -35,7 +35,9 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#define VERSION "0.10"
#include "hci_uart.h"
#define VERSION "0.11"
static const struct usb_device_id bpa10x_table[] = {
/* Tektronix BPA 100/105 (Digianswer) */
@ -56,112 +58,6 @@ struct bpa10x_data {
struct sk_buff *rx_skb[2];
};
#define HCI_VENDOR_HDR_SIZE 5
struct hci_vendor_hdr {
__u8 type;
__le16 snum;
__le16 dlen;
} __packed;
static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
{
struct bpa10x_data *data = hci_get_drvdata(hdev);
BT_DBG("%s queue %d buffer %p count %d", hdev->name,
queue, buf, count);
if (queue < 0 || queue > 1)
return -EILSEQ;
hdev->stat.byte_rx += count;
while (count) {
struct sk_buff *skb = data->rx_skb[queue];
struct { __u8 type; int expect; } *scb;
int type, len = 0;
if (!skb) {
/* Start of the frame */
type = *((__u8 *) buf);
count--; buf++;
switch (type) {
case HCI_EVENT_PKT:
if (count >= HCI_EVENT_HDR_SIZE) {
struct hci_event_hdr *h = buf;
len = HCI_EVENT_HDR_SIZE + h->plen;
} else
return -EILSEQ;
break;
case HCI_ACLDATA_PKT:
if (count >= HCI_ACL_HDR_SIZE) {
struct hci_acl_hdr *h = buf;
len = HCI_ACL_HDR_SIZE +
__le16_to_cpu(h->dlen);
} else
return -EILSEQ;
break;
case HCI_SCODATA_PKT:
if (count >= HCI_SCO_HDR_SIZE) {
struct hci_sco_hdr *h = buf;
len = HCI_SCO_HDR_SIZE + h->dlen;
} else
return -EILSEQ;
break;
case HCI_VENDOR_PKT:
if (count >= HCI_VENDOR_HDR_SIZE) {
struct hci_vendor_hdr *h = buf;
len = HCI_VENDOR_HDR_SIZE +
__le16_to_cpu(h->dlen);
} else
return -EILSEQ;
break;
}
skb = bt_skb_alloc(len, GFP_ATOMIC);
if (!skb) {
BT_ERR("%s no memory for packet", hdev->name);
return -ENOMEM;
}
data->rx_skb[queue] = skb;
scb = (void *) skb->cb;
scb->type = type;
scb->expect = len;
} else {
/* Continuation */
scb = (void *) skb->cb;
len = scb->expect;
}
len = min(len, count);
memcpy(skb_put(skb, len), buf, len);
scb->expect -= len;
if (scb->expect == 0) {
/* Complete frame */
data->rx_skb[queue] = NULL;
bt_cb(skb)->pkt_type = scb->type;
hci_recv_frame(hdev, skb);
}
count -= len; buf += len;
}
return 0;
}
static void bpa10x_tx_complete(struct urb *urb)
{
struct sk_buff *skb = urb->context;
@ -184,6 +80,22 @@ done:
kfree_skb(skb);
}
#define HCI_VENDOR_HDR_SIZE 5
#define HCI_RECV_VENDOR \
.type = HCI_VENDOR_PKT, \
.hlen = HCI_VENDOR_HDR_SIZE, \
.loff = 3, \
.lsize = 2, \
.maxlen = HCI_MAX_FRAME_SIZE
static const struct h4_recv_pkt bpa10x_recv_pkts[] = {
{ H4_RECV_ACL, .recv = hci_recv_frame },
{ H4_RECV_SCO, .recv = hci_recv_frame },
{ H4_RECV_EVENT, .recv = hci_recv_frame },
{ HCI_RECV_VENDOR, .recv = hci_recv_diag },
};
static void bpa10x_rx_complete(struct urb *urb)
{
struct hci_dev *hdev = urb->context;
@ -197,11 +109,17 @@ static void bpa10x_rx_complete(struct urb *urb)
return;
if (urb->status == 0) {
if (bpa10x_recv(hdev, usb_pipebulk(urb->pipe),
bool idx = usb_pipebulk(urb->pipe);
data->rx_skb[idx] = h4_recv_buf(hdev, data->rx_skb[idx],
urb->transfer_buffer,
urb->actual_length) < 0) {
urb->actual_length,
bpa10x_recv_pkts,
ARRAY_SIZE(bpa10x_recv_pkts));
if (IS_ERR(data->rx_skb[idx])) {
BT_ERR("%s corrupted event packet", hdev->name);
hdev->stat.err_rx++;
data->rx_skb[idx] = NULL;
}
}
@ -304,9 +222,6 @@ static int bpa10x_open(struct hci_dev *hdev)
BT_DBG("%s", hdev->name);
if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
return 0;
err = bpa10x_submit_intr_urb(hdev);
if (err < 0)
goto error;
@ -320,8 +235,6 @@ static int bpa10x_open(struct hci_dev *hdev)
error:
usb_kill_anchored_urbs(&data->rx_anchor);
clear_bit(HCI_RUNNING, &hdev->flags);
return err;
}
@ -331,9 +244,6 @@ static int bpa10x_close(struct hci_dev *hdev)
BT_DBG("%s", hdev->name);
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
usb_kill_anchored_urbs(&data->rx_anchor);
return 0;
@ -350,6 +260,24 @@ static int bpa10x_flush(struct hci_dev *hdev)
return 0;
}
static int bpa10x_setup(struct hci_dev *hdev)
{
const u8 req[] = { 0x07 };
struct sk_buff *skb;
BT_DBG("%s", hdev->name);
/* Read revision string */
skb = __hci_cmd_sync(hdev, 0xfc0e, sizeof(req), req, HCI_INIT_TIMEOUT);
if (IS_ERR(skb))
return PTR_ERR(skb);
BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1));
kfree_skb(skb);
return 0;
}
static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
struct bpa10x_data *data = hci_get_drvdata(hdev);
@ -360,9 +288,6 @@ static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s", hdev->name);
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
skb->dev = (void *) hdev;
urb = usb_alloc_urb(0, GFP_ATOMIC);
@ -431,6 +356,25 @@ static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
return 0;
}
static int bpa10x_set_diag(struct hci_dev *hdev, bool enable)
{
const u8 req[] = { 0x00, enable };
struct sk_buff *skb;
BT_DBG("%s", hdev->name);
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -ENETDOWN;
/* Enable sniffer operation */
skb = __hci_cmd_sync(hdev, 0xfc0e, sizeof(req), req, HCI_INIT_TIMEOUT);
if (IS_ERR(skb))
return PTR_ERR(skb);
kfree_skb(skb);
return 0;
}
static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct bpa10x_data *data;
@ -465,7 +409,9 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
hdev->open = bpa10x_open;
hdev->close = bpa10x_close;
hdev->flush = bpa10x_flush;
hdev->setup = bpa10x_setup;
hdev->send = bpa10x_send_frame;
hdev->set_diag = bpa10x_set_diag;
set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);

View File

@ -233,7 +233,7 @@ static void bt3c_receive(struct bt3c_info *info)
info->hdev->stat.byte_rx++;
/* Allocate packet */
if (info->rx_skb == NULL) {
if (!info->rx_skb) {
info->rx_state = RECV_WAIT_PACKET_TYPE;
info->rx_count = 0;
info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
@ -270,7 +270,6 @@ static void bt3c_receive(struct bt3c_info *info)
/* Unknown packet */
BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
info->hdev->stat.err_rx++;
clear_bit(HCI_RUNNING, &(info->hdev->flags));
kfree_skb(info->rx_skb);
info->rx_skb = NULL;
@ -395,17 +394,12 @@ static int bt3c_hci_flush(struct hci_dev *hdev)
static int bt3c_hci_open(struct hci_dev *hdev)
{
set_bit(HCI_RUNNING, &(hdev->flags));
return 0;
}
static int bt3c_hci_close(struct hci_dev *hdev)
{
if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
return 0;
bt3c_hci_flush(hdev);
return 0;

View File

@ -181,6 +181,27 @@ static int btbcm_reset(struct hci_dev *hdev)
return 0;
}
static struct sk_buff *btbcm_read_local_name(struct hci_dev *hdev)
{
struct sk_buff *skb;
skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL,
HCI_INIT_TIMEOUT);
if (IS_ERR(skb)) {
BT_ERR("%s: BCM: Reading local name failed (%ld)",
hdev->name, PTR_ERR(skb));
return skb;
}
if (skb->len != sizeof(struct hci_rp_read_local_name)) {
BT_ERR("%s: BCM: Local name length mismatch", hdev->name);
kfree_skb(skb);
return ERR_PTR(-EIO);
}
return skb;
}
static struct sk_buff *btbcm_read_local_version(struct hci_dev *hdev)
{
struct sk_buff *skb;
@ -393,6 +414,14 @@ int btbcm_setup_patchram(struct hci_dev *hdev)
BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
kfree_skb(skb);
/* Read Local Name */
skb = btbcm_read_local_name(hdev);
if (IS_ERR(skb))
return PTR_ERR(skb);
BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1));
kfree_skb(skb);
switch ((rev & 0xf000) >> 12) {
case 0:
case 3:
@ -464,6 +493,14 @@ int btbcm_setup_patchram(struct hci_dev *hdev)
hw_name ? : "BCM", (subver & 0x7000) >> 13,
(subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
/* Read Local Name */
skb = btbcm_read_local_name(hdev);
if (IS_ERR(skb))
return PTR_ERR(skb);
BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1));
kfree_skb(skb);
btbcm_check_bdaddr(hdev);
set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
@ -475,12 +512,25 @@ EXPORT_SYMBOL_GPL(btbcm_setup_patchram);
int btbcm_setup_apple(struct hci_dev *hdev)
{
struct sk_buff *skb;
int err;
/* Reset */
err = btbcm_reset(hdev);
if (err)
return err;
/* Read Verbose Config Version Info */
skb = btbcm_read_verbose_config(hdev);
if (!IS_ERR(skb)) {
BT_INFO("%s: BCM: chip id %u build %4.4u", hdev->name, skb->data[1],
get_unaligned_le16(skb->data + 5));
BT_INFO("%s: BCM: chip id %u build %4.4u", hdev->name,
skb->data[1], get_unaligned_le16(skb->data + 5));
kfree_skb(skb);
}
/* Read Local Name */
skb = btbcm_read_local_name(hdev);
if (!IS_ERR(skb)) {
BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1));
kfree_skb(skb);
}

View File

@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/regmap.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@ -215,6 +216,201 @@ int btintel_load_ddc_config(struct hci_dev *hdev, const char *ddc_name)
}
EXPORT_SYMBOL_GPL(btintel_load_ddc_config);
/* ------- REGMAP IBT SUPPORT ------- */
#define IBT_REG_MODE_8BIT 0x00
#define IBT_REG_MODE_16BIT 0x01
#define IBT_REG_MODE_32BIT 0x02
struct regmap_ibt_context {
struct hci_dev *hdev;
__u16 op_write;
__u16 op_read;
};
struct ibt_cp_reg_access {
__le32 addr;
__u8 mode;
__u8 len;
__u8 data[0];
} __packed;
struct ibt_rp_reg_access {
__u8 status;
__le32 addr;
__u8 data[0];
} __packed;
static int regmap_ibt_read(void *context, const void *addr, size_t reg_size,
void *val, size_t val_size)
{
struct regmap_ibt_context *ctx = context;
struct ibt_cp_reg_access cp;
struct ibt_rp_reg_access *rp;
struct sk_buff *skb;
int err = 0;
if (reg_size != sizeof(__le32))
return -EINVAL;
switch (val_size) {
case 1:
cp.mode = IBT_REG_MODE_8BIT;
break;
case 2:
cp.mode = IBT_REG_MODE_16BIT;
break;
case 4:
cp.mode = IBT_REG_MODE_32BIT;
break;
default:
return -EINVAL;
}
/* regmap provides a little-endian formatted addr */
cp.addr = *(__le32 *)addr;
cp.len = val_size;
bt_dev_dbg(ctx->hdev, "Register (0x%x) read", le32_to_cpu(cp.addr));
skb = hci_cmd_sync(ctx->hdev, ctx->op_read, sizeof(cp), &cp,
HCI_CMD_TIMEOUT);
if (IS_ERR(skb)) {
err = PTR_ERR(skb);
bt_dev_err(ctx->hdev, "regmap: Register (0x%x) read error (%d)",
le32_to_cpu(cp.addr), err);
return err;
}
if (skb->len != sizeof(*rp) + val_size) {
bt_dev_err(ctx->hdev, "regmap: Register (0x%x) read error, bad len",
le32_to_cpu(cp.addr));
err = -EINVAL;
goto done;
}
rp = (struct ibt_rp_reg_access *)skb->data;
if (rp->addr != cp.addr) {
bt_dev_err(ctx->hdev, "regmap: Register (0x%x) read error, bad addr",
le32_to_cpu(rp->addr));
err = -EINVAL;
goto done;
}
memcpy(val, rp->data, val_size);
done:
kfree_skb(skb);
return err;
}
static int regmap_ibt_gather_write(void *context,
const void *addr, size_t reg_size,
const void *val, size_t val_size)
{
struct regmap_ibt_context *ctx = context;
struct ibt_cp_reg_access *cp;
struct sk_buff *skb;
int plen = sizeof(*cp) + val_size;
u8 mode;
int err = 0;
if (reg_size != sizeof(__le32))
return -EINVAL;
switch (val_size) {
case 1:
mode = IBT_REG_MODE_8BIT;
break;
case 2:
mode = IBT_REG_MODE_16BIT;
break;
case 4:
mode = IBT_REG_MODE_32BIT;
break;
default:
return -EINVAL;
}
cp = kmalloc(plen, GFP_KERNEL);
if (!cp)
return -ENOMEM;
/* regmap provides a little-endian formatted addr/value */
cp->addr = *(__le32 *)addr;
cp->mode = mode;
cp->len = val_size;
memcpy(&cp->data, val, val_size);
bt_dev_dbg(ctx->hdev, "Register (0x%x) write", le32_to_cpu(cp->addr));
skb = hci_cmd_sync(ctx->hdev, ctx->op_write, plen, cp, HCI_CMD_TIMEOUT);
if (IS_ERR(skb)) {
err = PTR_ERR(skb);
bt_dev_err(ctx->hdev, "regmap: Register (0x%x) write error (%d)",
le32_to_cpu(cp->addr), err);
goto done;
}
kfree_skb(skb);
done:
kfree(cp);
return err;
}
static int regmap_ibt_write(void *context, const void *data, size_t count)
{
/* data contains register+value, since we only support 32bit addr,
* minimum data size is 4 bytes.
*/
if (WARN_ONCE(count < 4, "Invalid register access"))
return -EINVAL;
return regmap_ibt_gather_write(context, data, 4, data + 4, count - 4);
}
static void regmap_ibt_free_context(void *context)
{
kfree(context);
}
static struct regmap_bus regmap_ibt = {
.read = regmap_ibt_read,
.write = regmap_ibt_write,
.gather_write = regmap_ibt_gather_write,
.free_context = regmap_ibt_free_context,
.reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
.val_format_endian_default = REGMAP_ENDIAN_LITTLE,
};
/* Config is the same for all register regions */
static const struct regmap_config regmap_ibt_cfg = {
.name = "btintel_regmap",
.reg_bits = 32,
.val_bits = 32,
};
struct regmap *btintel_regmap_init(struct hci_dev *hdev, u16 opcode_read,
u16 opcode_write)
{
struct regmap_ibt_context *ctx;
bt_dev_info(hdev, "regmap: Init R%x-W%x region", opcode_read,
opcode_write);
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return ERR_PTR(-ENOMEM);
ctx->op_read = opcode_read;
ctx->op_write = opcode_write;
ctx->hdev = hdev;
return regmap_init(&hdev->dev, &regmap_ibt, ctx, &regmap_ibt_cfg);
}
EXPORT_SYMBOL_GPL(btintel_regmap_init);
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth support for Intel devices ver " VERSION);
MODULE_VERSION(VERSION);

View File

@ -80,6 +80,9 @@ int btintel_secure_send(struct hci_dev *hdev, u8 fragment_type, u32 plen,
const void *param);
int btintel_load_ddc_config(struct hci_dev *hdev, const char *ddc_name);
struct regmap *btintel_regmap_init(struct hci_dev *hdev, u16 opcode_read,
u16 opcode_write);
#else
static inline int btintel_check_bdaddr(struct hci_dev *hdev)
@ -113,4 +116,10 @@ static inline int btintel_load_ddc_config(struct hci_dev *hdev,
return -EOPNOTSUPP;
}
static inline struct regmap *btintel_regmap_init(struct hci_dev *hdev,
u16 opcode_read,
u16 opcode_write)
{
return ERR_PTR(-EINVAL);
}
#endif

View File

@ -184,7 +184,7 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode,
}
skb = bt_skb_alloc(HCI_COMMAND_HDR_SIZE + len, GFP_ATOMIC);
if (skb == NULL) {
if (!skb) {
BT_ERR("No free skb");
return -ENOMEM;
}
@ -436,13 +436,6 @@ static int btmrvl_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len);
if (!test_bit(HCI_RUNNING, &hdev->flags)) {
BT_ERR("Failed testing HCI_RUNING, flags=%lx", hdev->flags);
print_hex_dump_bytes("data: ", DUMP_PREFIX_OFFSET,
skb->data, skb->len);
return -EBUSY;
}
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
hdev->stat.cmd_tx++;
@ -477,9 +470,6 @@ static int btmrvl_close(struct hci_dev *hdev)
{
struct btmrvl_private *priv = hci_get_drvdata(hdev);
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
skb_queue_purge(&priv->adapter->tx_queue);
return 0;
@ -487,8 +477,6 @@ static int btmrvl_close(struct hci_dev *hdev)
static int btmrvl_open(struct hci_dev *hdev)
{
set_bit(HCI_RUNNING, &hdev->flags);
return 0;
}

View File

@ -146,6 +146,29 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_8897 = {
.fw_dump_end = 0xea,
};
static const struct btmrvl_sdio_card_reg btmrvl_reg_8997 = {
.cfg = 0x00,
.host_int_mask = 0x08,
.host_intstatus = 0x0c,
.card_status = 0x5c,
.sq_read_base_addr_a0 = 0xf8,
.sq_read_base_addr_a1 = 0xf9,
.card_revision = 0xc8,
.card_fw_status0 = 0xe8,
.card_fw_status1 = 0xe9,
.card_rx_len = 0xea,
.card_rx_unit = 0xeb,
.io_port_0 = 0xe4,
.io_port_1 = 0xe5,
.io_port_2 = 0xe6,
.int_read_to_clear = true,
.host_int_rsr = 0x04,
.card_misc_cfg = 0xD8,
.fw_dump_ctrl = 0xf0,
.fw_dump_start = 0xf1,
.fw_dump_end = 0xf8,
};
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
.helper = "mrvl/sd8688_helper.bin",
.firmware = "mrvl/sd8688.bin",
@ -191,25 +214,37 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
.supports_fw_dump = true,
};
static const struct btmrvl_sdio_device btmrvl_sdio_sd8997 = {
.helper = NULL,
.firmware = "mrvl/sd8997_uapsta.bin",
.reg = &btmrvl_reg_8997,
.support_pscan_win_report = true,
.sd_blksz_fw_dl = 256,
.supports_fw_dump = true,
};
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_sd8688 },
.driver_data = (unsigned long)&btmrvl_sdio_sd8688 },
/* Marvell SD8787 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A),
.driver_data = (unsigned long) &btmrvl_sdio_sd8787 },
.driver_data = (unsigned long)&btmrvl_sdio_sd8787 },
/* Marvell SD8787 Bluetooth AMP device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911B),
.driver_data = (unsigned long) &btmrvl_sdio_sd8787 },
.driver_data = (unsigned long)&btmrvl_sdio_sd8787 },
/* Marvell SD8797 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A),
.driver_data = (unsigned long) &btmrvl_sdio_sd8797 },
.driver_data = (unsigned long)&btmrvl_sdio_sd8797 },
/* Marvell SD8887 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9136),
.driver_data = (unsigned long)&btmrvl_sdio_sd8887 },
/* Marvell SD8897 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912E),
.driver_data = (unsigned long) &btmrvl_sdio_sd8897 },
.driver_data = (unsigned long)&btmrvl_sdio_sd8897 },
/* Marvell SD8997 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9142),
.driver_data = (unsigned long)&btmrvl_sdio_sd8997 },
{ } /* Terminating entry */
};
@ -619,7 +654,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
/* Allocate buffer */
skb = bt_skb_alloc(num_blocks * blksz + BTSDIO_DMA_ALIGN, GFP_ATOMIC);
if (skb == NULL) {
if (!skb) {
BT_ERR("No free skb");
ret = -ENOMEM;
goto exit;
@ -1278,6 +1313,12 @@ static void btmrvl_sdio_dump_firmware(struct btmrvl_private *priv)
if (memory_size == 0) {
BT_INFO("Firmware dump finished!");
sdio_writeb(card->func, FW_DUMP_READ_DONE,
card->reg->fw_dump_ctrl, &ret);
if (ret) {
BT_ERR("SDIO Write MEMDUMP_FINISH ERR");
goto done;
}
break;
}
@ -1616,3 +1657,4 @@ MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8887_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8997_uapsta.bin");

View File

@ -194,21 +194,15 @@ static int btsdio_open(struct hci_dev *hdev)
BT_DBG("%s", hdev->name);
if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
return 0;
sdio_claim_host(data->func);
err = sdio_enable_func(data->func);
if (err < 0) {
clear_bit(HCI_RUNNING, &hdev->flags);
if (err < 0)
goto release;
}
err = sdio_claim_irq(data->func, btsdio_interrupt);
if (err < 0) {
sdio_disable_func(data->func);
clear_bit(HCI_RUNNING, &hdev->flags);
goto release;
}
@ -229,9 +223,6 @@ static int btsdio_close(struct hci_dev *hdev)
BT_DBG("%s", hdev->name);
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
sdio_claim_host(data->func);
sdio_writeb(data->func, 0x00, REG_EN_INTRD, NULL);
@ -261,9 +252,6 @@ static int btsdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s", hdev->name);
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
hdev->stat.cmd_tx++;

View File

@ -38,7 +38,7 @@
#include <linux/serial.h>
#include <linux/serial_reg.h>
#include <linux/bitops.h>
#include <asm/io.h>
#include <linux/io.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h>
@ -188,7 +188,7 @@ static void btuart_receive(struct btuart_info *info)
info->hdev->stat.byte_rx++;
/* Allocate packet */
if (info->rx_skb == NULL) {
if (!info->rx_skb) {
info->rx_state = RECV_WAIT_PACKET_TYPE;
info->rx_count = 0;
info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
@ -223,7 +223,6 @@ static void btuart_receive(struct btuart_info *info)
/* Unknown packet */
BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
info->hdev->stat.err_rx++;
clear_bit(HCI_RUNNING, &(info->hdev->flags));
kfree_skb(info->rx_skb);
info->rx_skb = NULL;
@ -409,17 +408,12 @@ static int btuart_hci_flush(struct hci_dev *hdev)
static int btuart_hci_open(struct hci_dev *hdev)
{
set_bit(HCI_RUNNING, &(hdev->flags));
return 0;
}
static int btuart_hci_close(struct hci_dev *hdev)
{
if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
return 0;
btuart_hci_flush(hdev);
return 0;

View File

@ -940,9 +940,6 @@ static int btusb_open(struct hci_dev *hdev)
data->intf->needs_remote_wakeup = 1;
if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
goto done;
if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
goto done;
@ -965,7 +962,6 @@ done:
failed:
clear_bit(BTUSB_INTR_RUNNING, &data->flags);
clear_bit(HCI_RUNNING, &hdev->flags);
usb_autopm_put_interface(data->intf);
return err;
}
@ -984,9 +980,6 @@ static int btusb_close(struct hci_dev *hdev)
BT_DBG("%s", hdev->name);
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
cancel_work_sync(&data->work);
cancel_work_sync(&data->waker);
@ -1156,9 +1149,6 @@ static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s", hdev->name);
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
urb = alloc_ctrl_urb(hdev, skb);
@ -1843,9 +1833,6 @@ static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s", hdev->name);
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
if (test_bit(BTUSB_BOOTLOADER, &data->flags)) {

View File

@ -155,9 +155,6 @@ static int ti_st_open(struct hci_dev *hdev)
BT_DBG("%s %p", hdev->name, hdev);
if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
/* provide contexts for callbacks from ST */
hst = hci_get_drvdata(hdev);
@ -181,7 +178,6 @@ static int ti_st_open(struct hci_dev *hdev)
goto done;
if (err != -EINPROGRESS) {
clear_bit(HCI_RUNNING, &hdev->flags);
BT_ERR("st_register failed %d", err);
return err;
}
@ -195,7 +191,6 @@ static int ti_st_open(struct hci_dev *hdev)
(&hst->wait_reg_completion,
msecs_to_jiffies(BT_REGISTER_TIMEOUT));
if (!timeleft) {
clear_bit(HCI_RUNNING, &hdev->flags);
BT_ERR("Timeout(%d sec),didn't get reg "
"completion signal from ST",
BT_REGISTER_TIMEOUT / 1000);
@ -205,7 +200,6 @@ static int ti_st_open(struct hci_dev *hdev)
/* Is ST registration callback
* called with ERROR status? */
if (hst->reg_status != 0) {
clear_bit(HCI_RUNNING, &hdev->flags);
BT_ERR("ST registration completed with invalid "
"status %d", hst->reg_status);
return -EAGAIN;
@ -215,7 +209,6 @@ done:
hst->st_write = ti_st_proto[i].write;
if (!hst->st_write) {
BT_ERR("undefined ST write function");
clear_bit(HCI_RUNNING, &hdev->flags);
for (i = 0; i < MAX_BT_CHNL_IDS; i++) {
/* Undo registration with ST */
err = st_unregister(&ti_st_proto[i]);
@ -236,9 +229,6 @@ static int ti_st_close(struct hci_dev *hdev)
int err, i;
struct ti_st *hst = hci_get_drvdata(hdev);
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
for (i = MAX_BT_CHNL_IDS-1; i >= 0; i--) {
err = st_unregister(&ti_st_proto[i]);
if (err)
@ -256,9 +246,6 @@ static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
struct ti_st *hst;
long len;
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
hst = hci_get_drvdata(hdev);
/* Prepend skb with frame type */

View File

@ -357,8 +357,6 @@ static irqreturn_t dtl1_interrupt(int irq, void *dev_inst)
static int dtl1_hci_open(struct hci_dev *hdev)
{
set_bit(HCI_RUNNING, &(hdev->flags));
return 0;
}
@ -376,9 +374,6 @@ static int dtl1_hci_flush(struct hci_dev *hdev)
static int dtl1_hci_close(struct hci_dev *hdev)
{
if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
return 0;
dtl1_hci_flush(hdev);
return 0;

View File

@ -32,6 +32,8 @@
#include <linux/gpio/consumer.h>
#include <linux/tty.h>
#include <linux/interrupt.h>
#include <linux/dmi.h>
#include <linux/pm_runtime.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@ -39,6 +41,11 @@
#include "btbcm.h"
#include "hci_uart.h"
#define BCM_LM_DIAG_PKT 0x07
#define BCM_LM_DIAG_SIZE 63
#define BCM_AUTOSUSPEND_DELAY 5000 /* default autosleep delay */
struct bcm_device {
struct list_head list;
@ -55,7 +62,7 @@ struct bcm_device {
int irq;
u8 irq_polarity;
#ifdef CONFIG_PM_SLEEP
#ifdef CONFIG_PM
struct hci_uart *hu;
bool is_suspended; /* suspend/resume flag */
#endif
@ -152,13 +159,17 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered)
return 0;
}
#ifdef CONFIG_PM_SLEEP
#ifdef CONFIG_PM
static irqreturn_t bcm_host_wake(int irq, void *data)
{
struct bcm_device *bdev = data;
bt_dev_dbg(bdev, "Host wake IRQ");
pm_runtime_get(&bdev->pdev->dev);
pm_runtime_mark_last_busy(&bdev->pdev->dev);
pm_runtime_put_autosuspend(&bdev->pdev->dev);
return IRQ_HANDLED;
}
@ -182,6 +193,12 @@ static int bcm_request_irq(struct bcm_data *bcm)
goto unlock;
device_init_wakeup(&bdev->pdev->dev, true);
pm_runtime_set_autosuspend_delay(&bdev->pdev->dev,
BCM_AUTOSUSPEND_DELAY);
pm_runtime_use_autosuspend(&bdev->pdev->dev);
pm_runtime_set_active(&bdev->pdev->dev);
pm_runtime_enable(&bdev->pdev->dev);
}
unlock:
@ -197,7 +214,7 @@ static const struct bcm_set_sleep_mode default_sleep_params = {
.bt_wake_active = 1, /* BT_WAKE active mode: 1 = high, 0 = low */
.host_wake_active = 0, /* HOST_WAKE active mode: 1 = high, 0 = low */
.allow_host_sleep = 1, /* Allow host sleep in SCO flag */
.combine_modes = 0, /* Combine sleep and LPM flag */
.combine_modes = 1, /* Combine sleep and LPM flag */
.tristate_control = 0, /* Allow tri-state control of UART tx flag */
/* Irrelevant USB flags */
.usb_auto_sleep = 0,
@ -232,6 +249,29 @@ static inline int bcm_request_irq(struct bcm_data *bcm) { return 0; }
static inline int bcm_setup_sleep(struct hci_uart *hu) { return 0; }
#endif
static int bcm_set_diag(struct hci_dev *hdev, bool enable)
{
struct hci_uart *hu = hci_get_drvdata(hdev);
struct bcm_data *bcm = hu->priv;
struct sk_buff *skb;
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -ENETDOWN;
skb = bt_skb_alloc(3, GFP_KERNEL);
if (IS_ERR(skb))
return PTR_ERR(skb);
*skb_put(skb, 1) = BCM_LM_DIAG_PKT;
*skb_put(skb, 1) = 0xf0;
*skb_put(skb, 1) = enable;
skb_queue_tail(&bcm->txq, skb);
hci_uart_tx_wakeup(hu);
return 0;
}
static int bcm_open(struct hci_uart *hu)
{
struct bcm_data *bcm;
@ -258,7 +298,7 @@ static int bcm_open(struct hci_uart *hu)
if (hu->tty->dev->parent == dev->pdev->dev.parent) {
bcm->dev = dev;
hu->init_speed = dev->init_speed;
#ifdef CONFIG_PM_SLEEP
#ifdef CONFIG_PM
dev->hu = hu;
#endif
bcm_gpio_set_power(bcm->dev, true);
@ -282,7 +322,10 @@ static int bcm_close(struct hci_uart *hu)
mutex_lock(&bcm_device_lock);
if (bcm_device_exists(bdev)) {
bcm_gpio_set_power(bdev, false);
#ifdef CONFIG_PM_SLEEP
#ifdef CONFIG_PM
pm_runtime_disable(&bdev->pdev->dev);
pm_runtime_set_suspended(&bdev->pdev->dev);
if (device_can_wakeup(&bdev->pdev->dev)) {
devm_free_irq(&bdev->pdev->dev, bdev->irq, bdev);
device_init_wakeup(&bdev->pdev->dev, false);
@ -322,6 +365,7 @@ static int bcm_setup(struct hci_uart *hu)
bt_dev_dbg(hu->hdev, "hu %p", hu);
hu->hdev->set_diag = bcm_set_diag;
hu->hdev->set_bdaddr = btbcm_set_bdaddr;
err = btbcm_initialize(hu->hdev, fw_name, sizeof(fw_name));
@ -379,10 +423,18 @@ finalize:
return err;
}
#define BCM_RECV_LM_DIAG \
.type = BCM_LM_DIAG_PKT, \
.hlen = BCM_LM_DIAG_SIZE, \
.loff = 0, \
.lsize = 0, \
.maxlen = BCM_LM_DIAG_SIZE
static const struct h4_recv_pkt bcm_recv_pkts[] = {
{ H4_RECV_ACL, .recv = hci_recv_frame },
{ H4_RECV_SCO, .recv = hci_recv_frame },
{ H4_RECV_EVENT, .recv = hci_recv_frame },
{ H4_RECV_ACL, .recv = hci_recv_frame },
{ H4_RECV_SCO, .recv = hci_recv_frame },
{ H4_RECV_EVENT, .recv = hci_recv_frame },
{ BCM_RECV_LM_DIAG, .recv = hci_recv_diag },
};
static int bcm_recv(struct hci_uart *hu, const void *data, int count)
@ -399,6 +451,15 @@ static int bcm_recv(struct hci_uart *hu, const void *data, int count)
bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err);
bcm->rx_skb = NULL;
return err;
} else if (!bcm->rx_skb) {
/* Delay auto-suspend when receiving completed packet */
mutex_lock(&bcm_device_lock);
if (bcm->dev && bcm_device_exists(bcm->dev)) {
pm_runtime_get(&bcm->dev->pdev->dev);
pm_runtime_mark_last_busy(&bcm->dev->pdev->dev);
pm_runtime_put_autosuspend(&bcm->dev->pdev->dev);
}
mutex_unlock(&bcm_device_lock);
}
return count;
@ -420,10 +481,76 @@ static int bcm_enqueue(struct hci_uart *hu, struct sk_buff *skb)
static struct sk_buff *bcm_dequeue(struct hci_uart *hu)
{
struct bcm_data *bcm = hu->priv;
struct sk_buff *skb = NULL;
struct bcm_device *bdev = NULL;
return skb_dequeue(&bcm->txq);
mutex_lock(&bcm_device_lock);
if (bcm_device_exists(bcm->dev)) {
bdev = bcm->dev;
pm_runtime_get_sync(&bdev->pdev->dev);
/* Shall be resumed here */
}
skb = skb_dequeue(&bcm->txq);
if (bdev) {
pm_runtime_mark_last_busy(&bdev->pdev->dev);
pm_runtime_put_autosuspend(&bdev->pdev->dev);
}
mutex_unlock(&bcm_device_lock);
return skb;
}
#ifdef CONFIG_PM
static int bcm_suspend_device(struct device *dev)
{
struct bcm_device *bdev = platform_get_drvdata(to_platform_device(dev));
bt_dev_dbg(bdev, "");
if (!bdev->is_suspended && bdev->hu) {
hci_uart_set_flow_control(bdev->hu, true);
/* Once this returns, driver suspends BT via GPIO */
bdev->is_suspended = true;
}
/* Suspend the device */
if (bdev->device_wakeup) {
gpiod_set_value(bdev->device_wakeup, false);
bt_dev_dbg(bdev, "suspend, delaying 15 ms");
mdelay(15);
}
return 0;
}
static int bcm_resume_device(struct device *dev)
{
struct bcm_device *bdev = platform_get_drvdata(to_platform_device(dev));
bt_dev_dbg(bdev, "");
if (bdev->device_wakeup) {
gpiod_set_value(bdev->device_wakeup, true);
bt_dev_dbg(bdev, "resume, delaying 15 ms");
mdelay(15);
}
/* When this executes, the device has woken up already */
if (bdev->is_suspended && bdev->hu) {
bdev->is_suspended = false;
hci_uart_set_flow_control(bdev->hu, false);
}
return 0;
}
#endif
#ifdef CONFIG_PM_SLEEP
/* Platform suspend callback */
static int bcm_suspend(struct device *dev)
@ -433,24 +560,17 @@ static int bcm_suspend(struct device *dev)
bt_dev_dbg(bdev, "suspend: is_suspended %d", bdev->is_suspended);
/* bcm_suspend can be called at any time as long as platform device is
* bound, so it should use bcm_device_lock to protect access to hci_uart
* and device_wake-up GPIO.
*/
mutex_lock(&bcm_device_lock);
if (!bdev->hu)
goto unlock;
if (!bdev->is_suspended) {
hci_uart_set_flow_control(bdev->hu, true);
/* Once this callback returns, driver suspends BT via GPIO */
bdev->is_suspended = true;
}
/* Suspend the device */
if (bdev->device_wakeup) {
gpiod_set_value(bdev->device_wakeup, false);
bt_dev_dbg(bdev, "suspend, delaying 15 ms");
mdelay(15);
}
if (pm_runtime_active(dev))
bcm_suspend_device(dev);
if (device_may_wakeup(&bdev->pdev->dev)) {
error = enable_irq_wake(bdev->irq);
@ -471,6 +591,10 @@ static int bcm_resume(struct device *dev)
bt_dev_dbg(bdev, "resume: is_suspended %d", bdev->is_suspended);
/* bcm_resume can be called at any time as long as platform device is
* bound, so it should use bcm_device_lock to protect access to hci_uart
* and device_wake-up GPIO.
*/
mutex_lock(&bcm_device_lock);
if (!bdev->hu)
@ -481,22 +605,15 @@ static int bcm_resume(struct device *dev)
bt_dev_dbg(bdev, "BCM irq: disabled");
}
if (bdev->device_wakeup) {
gpiod_set_value(bdev->device_wakeup, true);
bt_dev_dbg(bdev, "resume, delaying 15 ms");
mdelay(15);
}
/* When this callback executes, the device has woken up already */
if (bdev->is_suspended) {
bdev->is_suspended = false;
hci_uart_set_flow_control(bdev->hu, false);
}
bcm_resume_device(dev);
unlock:
mutex_unlock(&bcm_device_lock);
pm_runtime_disable(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
return 0;
}
#endif
@ -513,6 +630,22 @@ static const struct acpi_gpio_mapping acpi_bcm_default_gpios[] = {
};
#ifdef CONFIG_ACPI
static u8 acpi_active_low = ACPI_ACTIVE_LOW;
/* IRQ polarity of some chipsets are not defined correctly in ACPI table. */
static const struct dmi_system_id bcm_wrong_irq_dmi_table[] = {
{
.ident = "Asus T100TA",
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR,
"ASUSTeK COMPUTER INC."),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
},
.driver_data = &acpi_active_low,
},
{ }
};
static int bcm_resource(struct acpi_resource *ares, void *data)
{
struct bcm_device *dev = data;
@ -549,15 +682,10 @@ static int bcm_resource(struct acpi_resource *ares, void *data)
static int bcm_acpi_probe(struct bcm_device *dev)
{
struct platform_device *pdev = dev->pdev;
const struct acpi_device_id *id;
struct acpi_device *adev;
LIST_HEAD(resources);
const struct dmi_system_id *dmi_id;
int ret;
id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
if (!id)
return -ENODEV;
/* Retrieve GPIO data */
dev->name = dev_name(&pdev->dev);
ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(&pdev->dev),
@ -602,11 +730,18 @@ static int bcm_acpi_probe(struct bcm_device *dev)
}
/* Retrieve UART ACPI info */
adev = ACPI_COMPANION(&dev->pdev->dev);
if (!adev)
return 0;
ret = acpi_dev_get_resources(ACPI_COMPANION(&dev->pdev->dev),
&resources, bcm_resource, dev);
if (ret < 0)
return ret;
acpi_dev_free_resource_list(&resources);
acpi_dev_get_resources(adev, &resources, bcm_resource, dev);
dmi_id = dmi_first_match(bcm_wrong_irq_dmi_table);
if (dmi_id) {
bt_dev_warn(dev, "%s: Overwriting IRQ polarity to active low",
dmi_id->ident);
dev->irq_polarity = *(u8 *)dmi_id->driver_data;
}
return 0;
}
@ -620,7 +755,6 @@ static int bcm_acpi_probe(struct bcm_device *dev)
static int bcm_probe(struct platform_device *pdev)
{
struct bcm_device *dev;
struct acpi_device_id *pdata = pdev->dev.platform_data;
int ret;
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
@ -629,15 +763,9 @@ static int bcm_probe(struct platform_device *pdev)
dev->pdev = pdev;
if (ACPI_HANDLE(&pdev->dev)) {
ret = bcm_acpi_probe(dev);
if (ret)
return ret;
} else if (pdata) {
dev->name = pdata->id;
} else {
return -ENODEV;
}
ret = bcm_acpi_probe(dev);
if (ret)
return ret;
platform_set_drvdata(pdev, dev);
@ -693,7 +821,10 @@ MODULE_DEVICE_TABLE(acpi, bcm_acpi_match);
#endif
/* Platform suspend and resume callbacks */
static SIMPLE_DEV_PM_OPS(bcm_pm_ops, bcm_suspend, bcm_resume);
static const struct dev_pm_ops bcm_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(bcm_suspend, bcm_resume)
SET_RUNTIME_PM_OPS(bcm_suspend_device, bcm_resume_device, NULL)
};
static struct platform_driver bcm_driver = {
.probe = bcm_probe,

View File

@ -266,3 +266,4 @@ struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb,
return skb;
}
EXPORT_SYMBOL_GPL(h4_recv_buf);

View File

@ -128,7 +128,7 @@ static void h5_timed_event(unsigned long arg)
{
const unsigned char sync_req[] = { 0x01, 0x7e };
unsigned char conf_req[] = { 0x03, 0xfc, 0x01 };
struct hci_uart *hu = (struct hci_uart *) arg;
struct hci_uart *hu = (struct hci_uart *)arg;
struct h5 *h5 = hu->priv;
struct sk_buff *skb;
unsigned long flags;
@ -210,7 +210,7 @@ static int h5_open(struct hci_uart *hu)
init_timer(&h5->timer);
h5->timer.function = h5_timed_event;
h5->timer.data = (unsigned long) hu;
h5->timer.data = (unsigned long)hu;
h5->tx_win = H5_TX_WIN_MAX;
@ -453,7 +453,7 @@ static int h5_rx_pkt_start(struct hci_uart *hu, unsigned char c)
return -ENOMEM;
}
h5->rx_skb->dev = (void *) hu->hdev;
h5->rx_skb->dev = (void *)hu->hdev;
return 0;
}
@ -696,7 +696,7 @@ static struct sk_buff *h5_dequeue(struct hci_uart *hu)
}
skb = skb_dequeue(&h5->unrel);
if (skb != NULL) {
if (skb) {
nskb = h5_prepare_pkt(hu, bt_cb(skb)->pkt_type,
skb->data, skb->len);
if (nskb) {
@ -714,7 +714,7 @@ static struct sk_buff *h5_dequeue(struct hci_uart *hu)
goto unlock;
skb = skb_dequeue(&h5->rel);
if (skb != NULL) {
if (skb) {
nskb = h5_prepare_pkt(hu, bt_cb(skb)->pkt_type,
skb->data, skb->len);
if (nskb) {

View File

@ -1165,22 +1165,6 @@ static const struct acpi_device_id intel_acpi_match[] = {
{ },
};
MODULE_DEVICE_TABLE(acpi, intel_acpi_match);
static int intel_acpi_probe(struct intel_device *idev)
{
const struct acpi_device_id *id;
id = acpi_match_device(intel_acpi_match, &idev->pdev->dev);
if (!id)
return -ENODEV;
return 0;
}
#else
static int intel_acpi_probe(struct intel_device *idev)
{
return -ENODEV;
}
#endif
#ifdef CONFIG_PM
@ -1248,14 +1232,6 @@ static int intel_probe(struct platform_device *pdev)
idev->pdev = pdev;
if (ACPI_HANDLE(&pdev->dev)) {
int err = intel_acpi_probe(idev);
if (err)
return err;
} else {
return -ENODEV;
}
idev->reset = devm_gpiod_get_optional(&pdev->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(idev->reset)) {

View File

@ -208,9 +208,6 @@ static int hci_uart_open(struct hci_dev *hdev)
BT_DBG("%s %p", hdev->name, hdev);
/* Nothing to do for UART driver */
set_bit(HCI_RUNNING, &hdev->flags);
return 0;
}
@ -241,9 +238,6 @@ static int hci_uart_close(struct hci_dev *hdev)
{
BT_DBG("hdev %p", hdev);
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
hci_uart_flush(hdev);
hdev->flush = NULL;
return 0;
@ -254,9 +248,6 @@ static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_uart *hu = hci_get_drvdata(hdev);
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
hu->proto->enqueue(hu, skb);
@ -470,8 +461,6 @@ static int hci_uart_tty_open(struct tty_struct *tty)
INIT_WORK(&hu->init_ready, hci_uart_init_work);
INIT_WORK(&hu->write_work, hci_uart_write_work);
spin_lock_init(&hu->rx_lock);
/* Flush any pending characters in the driver and line discipline. */
/* FIXME: why is this needed. Note don't use ldisc_ref here as the
@ -569,14 +558,14 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data,
if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
return;
spin_lock(&hu->rx_lock);
/* It does not need a lock here as it is already protected by a mutex in
* tty caller
*/
hu->proto->recv(hu, data, count);
if (hu->hdev)
hu->hdev->stat.byte_rx += count;
spin_unlock(&hu->rx_lock);
tty_unthrottle(tty);
}

View File

@ -347,7 +347,7 @@ static void hci_ibs_wake_retrans_timeout(unsigned long arg)
struct hci_uart *hu = (struct hci_uart *)arg;
struct qca_data *qca = hu->priv;
unsigned long flags, retrans_delay;
unsigned long retransmit = 0;
bool retransmit = false;
BT_DBG("hu %p wake retransmit timeout in %d state",
hu, qca->tx_ibs_state);
@ -358,7 +358,7 @@ static void hci_ibs_wake_retrans_timeout(unsigned long arg)
switch (qca->tx_ibs_state) {
case HCI_IBS_TX_WAKING:
/* No WAKE_ACK, retransmit WAKE */
retransmit = 1;
retransmit = true;
if (send_hci_ibs_cmd(HCI_IBS_WAKE_IND, hu) < 0) {
BT_ERR("Failed to acknowledge device wake up");
break;

View File

@ -85,7 +85,6 @@ struct hci_uart {
struct sk_buff *tx_skb;
unsigned long tx_state;
spinlock_t rx_lock;
unsigned int init_speed;
unsigned int oper_speed;

View File

@ -55,8 +55,6 @@ struct vhci_data {
static int vhci_open_dev(struct hci_dev *hdev)
{
set_bit(HCI_RUNNING, &hdev->flags);
return 0;
}
@ -64,9 +62,6 @@ static int vhci_close_dev(struct hci_dev *hdev)
{
struct vhci_data *data = hci_get_drvdata(hdev);
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
skb_queue_purge(&data->readq);
return 0;
@ -85,9 +80,6 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
struct vhci_data *data = hci_get_drvdata(hdev);
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
skb_queue_tail(&data->readq, skb);

View File

@ -1325,9 +1325,6 @@ static void nes_netdev_get_drvinfo(struct net_device *netdev,
"%u.%u", nesadapter->firmware_version >> 16,
nesadapter->firmware_version & 0x000000ff);
strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version));
drvinfo->testinfo_len = 0;
drvinfo->eedump_len = 0;
drvinfo->regdump_len = 0;
}

View File

@ -235,7 +235,7 @@ void dsp_pipeline_destroy(struct dsp_pipeline *pipeline)
int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg)
{
int len, incomplete = 0, found = 0;
int incomplete = 0, found = 0;
char *dup, *tok, *name, *args;
struct dsp_element_entry *entry, *n;
struct dsp_pipeline_entry *pipeline_entry;
@ -247,17 +247,9 @@ int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg)
if (!list_empty(&pipeline->list))
_dsp_pipeline_destroy(pipeline);
if (!cfg)
return 0;
len = strlen(cfg);
if (!len)
return 0;
dup = kmalloc(len + 1, GFP_ATOMIC);
dup = kstrdup(cfg, GFP_ATOMIC);
if (!dup)
return 0;
strcpy(dup, cfg);
while ((tok = strsep(&dup, "|"))) {
if (!strlen(tok))
continue;

View File

@ -298,8 +298,10 @@ config NLMON
config NET_VRF
tristate "Virtual Routing and Forwarding (Lite)"
depends on IP_MULTIPLE_TABLES && IPV6_MULTIPLE_TABLES
depends on IP_MULTIPLE_TABLES
depends on NET_L3_MASTER_DEV
depends on IPV6 || IPV6=n
depends on IPV6_MULTIPLE_TABLES || IPV6=n
---help---
This option enables the support for mapping interfaces into VRF's. The
support enables VRF devices.

View File

@ -1071,7 +1071,7 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
NETIF_F_HIGHDMA | NETIF_F_LRO)
#define BOND_ENC_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | NETIF_F_RXCSUM |\
NETIF_F_TSO)
NETIF_F_ALL_TSO)
static void bond_compute_features(struct bonding *bond)
{

View File

@ -8,15 +8,6 @@
* Public License ("GPL") version 2 as distributed in the 'COPYING'
* file from the main directory of the linux kernel source.
*
*
* Your platform definition file should specify something like:
*
* static struct at91_can_data ek_can_data = {
* transceiver_switch = sam9263ek_transceiver_switch,
* };
*
* at91_add_device_can(&ek_can_data);
*
*/
#include <linux/clk.h>
@ -33,7 +24,6 @@
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/platform_data/atmel.h>
#include <linux/can/dev.h>
#include <linux/can/error.h>
@ -324,15 +314,6 @@ static inline u32 at91_can_id_to_reg_mid(canid_t can_id)
return reg_mid;
}
/*
* Swtich transceiver on or off
*/
static void at91_transceiver_switch(const struct at91_priv *priv, int on)
{
if (priv->pdata && priv->pdata->transceiver_switch)
priv->pdata->transceiver_switch(on);
}
static void at91_setup_mailboxes(struct net_device *dev)
{
struct at91_priv *priv = netdev_priv(dev);
@ -416,7 +397,6 @@ static void at91_chip_start(struct net_device *dev)
at91_set_bittiming(dev);
at91_setup_mailboxes(dev);
at91_transceiver_switch(priv, 1);
/* enable chip */
if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
@ -444,7 +424,6 @@ static void at91_chip_stop(struct net_device *dev, enum can_state state)
reg_mr = at91_read(priv, AT91_MR);
at91_write(priv, AT91_MR, reg_mr & ~AT91_MR_CANEN);
at91_transceiver_switch(priv, 0);
priv->can.state = state;
}

View File

@ -601,7 +601,7 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
stats->tx_errors++;
if (likely(skb)) {
cf->can_id |= CAN_ERR_LOSTARB;
cf->data[0] = (alc & 0x1f) >> 8;
cf->data[0] = (alc >> 8) & 0x1f;
}
}
@ -854,4 +854,4 @@ module_platform_driver(sun4i_can_driver);
MODULE_AUTHOR("Peter Chen <xingkongcp@gmail.com>");
MODULE_AUTHOR("Gerhard Bertelsmann <info@gerhard-bertelsmann.de>");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION(DRV_NAME "CAN driver for Allwinner SoCs (A10/A20)");
MODULE_DESCRIPTION("CAN driver for Allwinner SoCs (A10/A20)");

View File

@ -125,7 +125,6 @@ struct dsa_switch_driver mv88e6123_61_65_switch_driver = {
.set_addr = mv88e6xxx_set_addr_indirect,
.phy_read = mv88e6xxx_phy_read,
.phy_write = mv88e6xxx_phy_write,
.poll_link = mv88e6xxx_poll_link,
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
.get_sset_count = mv88e6xxx_get_sset_count,

View File

@ -178,7 +178,6 @@ struct dsa_switch_driver mv88e6131_switch_driver = {
.set_addr = mv88e6xxx_set_addr_direct,
.phy_read = mv88e6131_phy_read,
.phy_write = mv88e6131_phy_write,
.poll_link = mv88e6xxx_poll_link,
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
.get_sset_count = mv88e6xxx_get_sset_count,

View File

@ -104,7 +104,6 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
.set_addr = mv88e6xxx_set_addr_indirect,
.phy_read = mv88e6xxx_phy_read_indirect,
.phy_write = mv88e6xxx_phy_write_indirect,
.poll_link = mv88e6xxx_poll_link,
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
.get_sset_count = mv88e6xxx_get_sset_count,
@ -114,14 +113,13 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
#endif
.get_regs_len = mv88e6xxx_get_regs_len,
.get_regs = mv88e6xxx_get_regs,
.port_join_bridge = mv88e6xxx_join_bridge,
.port_leave_bridge = mv88e6xxx_leave_bridge,
.port_stp_update = mv88e6xxx_port_stp_update,
.port_pvid_get = mv88e6xxx_port_pvid_get,
.port_pvid_set = mv88e6xxx_port_pvid_set,
.port_vlan_add = mv88e6xxx_port_vlan_add,
.port_vlan_del = mv88e6xxx_port_vlan_del,
.vlan_getnext = mv88e6xxx_vlan_getnext,
.port_fdb_prepare = mv88e6xxx_port_fdb_prepare,
.port_fdb_add = mv88e6xxx_port_fdb_add,
.port_fdb_del = mv88e6xxx_port_fdb_del,
.port_fdb_getnext = mv88e6xxx_port_fdb_getnext,

View File

@ -324,7 +324,6 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
.set_addr = mv88e6xxx_set_addr_indirect,
.phy_read = mv88e6xxx_phy_read_indirect,
.phy_write = mv88e6xxx_phy_write_indirect,
.poll_link = mv88e6xxx_poll_link,
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
.get_sset_count = mv88e6xxx_get_sset_count,
@ -341,14 +340,13 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
.set_eeprom = mv88e6352_set_eeprom,
.get_regs_len = mv88e6xxx_get_regs_len,
.get_regs = mv88e6xxx_get_regs,
.port_join_bridge = mv88e6xxx_join_bridge,
.port_leave_bridge = mv88e6xxx_leave_bridge,
.port_stp_update = mv88e6xxx_port_stp_update,
.port_pvid_get = mv88e6xxx_port_pvid_get,
.port_pvid_set = mv88e6xxx_port_pvid_set,
.port_vlan_add = mv88e6xxx_port_vlan_add,
.port_vlan_del = mv88e6xxx_port_vlan_del,
.vlan_getnext = mv88e6xxx_vlan_getnext,
.port_fdb_prepare = mv88e6xxx_port_fdb_prepare,
.port_fdb_add = mv88e6xxx_port_fdb_add,
.port_fdb_del = mv88e6xxx_port_fdb_del,
.port_fdb_getnext = mv88e6xxx_port_fdb_getnext,

View File

@ -23,6 +23,7 @@
#include <linux/phy.h>
#include <linux/seq_file.h>
#include <net/dsa.h>
#include <net/switchdev.h>
#include "mv88e6xxx.h"
/* MDIO bus access can be nested in the case of PHYs connected to the
@ -388,73 +389,6 @@ int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
}
#endif
void mv88e6xxx_poll_link(struct dsa_switch *ds)
{
int i;
for (i = 0; i < DSA_MAX_PORTS; i++) {
struct net_device *dev;
int uninitialized_var(port_status);
int pcs_ctrl;
int link;
int speed;
int duplex;
int fc;
dev = ds->ports[i];
if (dev == NULL)
continue;
pcs_ctrl = mv88e6xxx_reg_read(ds, REG_PORT(i), PORT_PCS_CTRL);
if (pcs_ctrl < 0 || pcs_ctrl & PORT_PCS_CTRL_FORCE_LINK)
continue;
link = 0;
if (dev->flags & IFF_UP) {
port_status = mv88e6xxx_reg_read(ds, REG_PORT(i),
PORT_STATUS);
if (port_status < 0)
continue;
link = !!(port_status & PORT_STATUS_LINK);
}
if (!link) {
if (netif_carrier_ok(dev)) {
netdev_info(dev, "link down\n");
netif_carrier_off(dev);
}
continue;
}
switch (port_status & PORT_STATUS_SPEED_MASK) {
case PORT_STATUS_SPEED_10:
speed = 10;
break;
case PORT_STATUS_SPEED_100:
speed = 100;
break;
case PORT_STATUS_SPEED_1000:
speed = 1000;
break;
default:
speed = -1;
break;
}
duplex = (port_status & PORT_STATUS_DUPLEX) ? 1 : 0;
fc = (port_status & PORT_STATUS_PAUSE_EN) ? 1 : 0;
if (!netif_carrier_ok(dev)) {
netdev_info(dev,
"link up, %d Mb/s, %s duplex, flow control %sabled\n",
speed,
duplex ? "full" : "half",
fc ? "en" : "dis");
netif_carrier_on(dev);
}
}
}
static bool mv88e6xxx_6065_family(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@ -1112,11 +1046,6 @@ static int _mv88e6xxx_atu_flush(struct dsa_switch *ds, u16 fid, bool static_too)
return _mv88e6xxx_atu_flush_move(ds, &entry, static_too);
}
static int _mv88e6xxx_flush_fid(struct dsa_switch *ds, int fid)
{
return _mv88e6xxx_atu_flush(ds, fid, false);
}
static int _mv88e6xxx_atu_move(struct dsa_switch *ds, u16 fid, int from_port,
int to_port, bool static_too)
{
@ -1178,132 +1107,23 @@ abort:
return ret;
}
/* Must be called with smi lock held */
static int _mv88e6xxx_update_port_config(struct dsa_switch *ds, int port)
static int _mv88e6xxx_port_vlan_map_set(struct dsa_switch *ds, int port,
u16 output_ports)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
u8 fid = ps->fid[port];
u16 reg = fid << 12;
const u16 mask = (1 << ps->num_ports) - 1;
int reg;
if (dsa_is_cpu_port(ds, port))
reg |= ds->phys_port_mask;
else
reg |= (ps->bridge_mask[fid] |
(1 << dsa_upstream_port(ds))) & ~(1 << port);
reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_BASE_VLAN);
if (reg < 0)
return reg;
reg &= ~mask;
reg |= output_ports & mask;
return _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_BASE_VLAN, reg);
}
/* Must be called with smi lock held */
static int _mv88e6xxx_update_bridge_config(struct dsa_switch *ds, int fid)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int port;
u32 mask;
int ret;
mask = ds->phys_port_mask;
while (mask) {
port = __ffs(mask);
mask &= ~(1 << port);
if (ps->fid[port] != fid)
continue;
ret = _mv88e6xxx_update_port_config(ds, port);
if (ret)
return ret;
}
return _mv88e6xxx_flush_fid(ds, fid);
}
/* Bridge handling functions */
int mv88e6xxx_join_bridge(struct dsa_switch *ds, int port, u32 br_port_mask)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret = 0;
u32 nmask;
int fid;
/* If the bridge group is not empty, join that group.
* Otherwise create a new group.
*/
fid = ps->fid[port];
nmask = br_port_mask & ~(1 << port);
if (nmask)
fid = ps->fid[__ffs(nmask)];
nmask = ps->bridge_mask[fid] | (1 << port);
if (nmask != br_port_mask) {
netdev_err(ds->ports[port],
"join: Bridge port mask mismatch fid=%d mask=0x%x expected 0x%x\n",
fid, br_port_mask, nmask);
return -EINVAL;
}
mutex_lock(&ps->smi_mutex);
ps->bridge_mask[fid] = br_port_mask;
if (fid != ps->fid[port]) {
clear_bit(ps->fid[port], ps->fid_bitmap);
ps->fid[port] = fid;
ret = _mv88e6xxx_update_bridge_config(ds, fid);
}
mutex_unlock(&ps->smi_mutex);
return ret;
}
int mv88e6xxx_leave_bridge(struct dsa_switch *ds, int port, u32 br_port_mask)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
u8 fid, newfid;
int ret;
fid = ps->fid[port];
if (ps->bridge_mask[fid] != br_port_mask) {
netdev_err(ds->ports[port],
"leave: Bridge port mask mismatch fid=%d mask=0x%x expected 0x%x\n",
fid, br_port_mask, ps->bridge_mask[fid]);
return -EINVAL;
}
/* If the port was the last port of a bridge, we are done.
* Otherwise assign a new fid to the port, and fix up
* the bridge configuration.
*/
if (br_port_mask == (1 << port))
return 0;
mutex_lock(&ps->smi_mutex);
newfid = find_next_zero_bit(ps->fid_bitmap, VLAN_N_VID, 1);
if (unlikely(newfid > ps->num_ports)) {
netdev_err(ds->ports[port], "all first %d FIDs are used\n",
ps->num_ports);
ret = -ENOSPC;
goto unlock;
}
ps->fid[port] = newfid;
set_bit(newfid, ps->fid_bitmap);
ps->bridge_mask[fid] &= ~(1 << port);
ps->bridge_mask[newfid] = 1 << port;
ret = _mv88e6xxx_update_bridge_config(ds, fid);
if (!ret)
ret = _mv88e6xxx_update_bridge_config(ds, newfid);
unlock:
mutex_unlock(&ps->smi_mutex);
return ret;
}
int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@ -1613,6 +1433,7 @@ static int _mv88e6xxx_vlan_init(struct dsa_switch *ds, u16 vid,
struct mv88e6xxx_vtu_stu_entry vlan = {
.valid = true,
.vid = vid,
.fid = vid, /* We use one FID per VLAN */
};
int i;
@ -1646,22 +1467,10 @@ static int _mv88e6xxx_vlan_init(struct dsa_switch *ds, u16 vid,
return err;
}
/* Non-bridged ports and bridge groups use FIDs from 1 to
* num_ports; VLANs use FIDs from num_ports+1 to 4095.
*/
vlan.fid = find_next_zero_bit(ps->fid_bitmap, VLAN_N_VID,
ps->num_ports + 1);
if (unlikely(vlan.fid == VLAN_N_VID)) {
pr_err("no more FID available for VLAN %d\n", vid);
return -ENOSPC;
}
/* Clear all MAC addresses from the new database */
err = _mv88e6xxx_atu_flush(ds, vlan.fid, true);
if (err)
return err;
set_bit(vlan.fid, ps->fid_bitmap);
}
*entry = vlan;
@ -1701,7 +1510,6 @@ int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
struct mv88e6xxx_vtu_stu_entry vlan;
bool keep = false;
int i, err;
mutex_lock(&ps->smi_mutex);
@ -1719,28 +1527,22 @@ int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
vlan.data[port] = GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
/* keep the VLAN unless all ports are excluded */
vlan.valid = false;
for (i = 0; i < ps->num_ports; ++i) {
if (dsa_is_cpu_port(ds, i))
continue;
if (vlan.data[i] != GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER) {
keep = true;
vlan.valid = true;
break;
}
}
vlan.valid = keep;
err = _mv88e6xxx_vtu_loadpurge(ds, &vlan);
if (err)
goto unlock;
err = _mv88e6xxx_atu_remove(ds, vlan.fid, port, false);
if (err)
goto unlock;
if (!keep)
clear_bit(vlan.fid, ps->fid_bitmap);
unlock:
mutex_unlock(&ps->smi_mutex);
@ -1867,37 +1669,13 @@ static int _mv88e6xxx_atu_load(struct dsa_switch *ds,
return _mv88e6xxx_atu_cmd(ds, GLOBAL_ATU_OP_LOAD_DB);
}
static int _mv88e6xxx_port_vid_to_fid(struct dsa_switch *ds, int port, u16 vid)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
struct mv88e6xxx_vtu_stu_entry vlan;
int err;
if (vid == 0)
return ps->fid[port];
err = _mv88e6xxx_port_vtu_getnext(ds, port, vid - 1, &vlan);
if (err)
return err;
if (vlan.vid == vid)
return vlan.fid;
return -ENOENT;
}
static int _mv88e6xxx_port_fdb_load(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid,
u8 state)
{
struct mv88e6xxx_atu_entry entry = { 0 };
int ret;
ret = _mv88e6xxx_port_vid_to_fid(ds, port, vid);
if (ret < 0)
return ret;
entry.fid = ret;
entry.fid = vid; /* We use one FID per VLAN */
entry.state = state;
ether_addr_copy(entry.mac, addr);
if (state != GLOBAL_ATU_DATA_STATE_UNUSED) {
@ -1908,30 +1686,45 @@ static int _mv88e6xxx_port_fdb_load(struct dsa_switch *ds, int port,
return _mv88e6xxx_atu_load(ds, &entry);
}
int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid)
int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_fdb *fdb,
struct switchdev_trans *trans)
{
int state = is_multicast_ether_addr(addr) ?
/* We don't use per-port FDB */
if (fdb->vid == 0)
return -EOPNOTSUPP;
/* We don't need any dynamic resource from the kernel (yet),
* so skip the prepare phase.
*/
return 0;
}
int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_fdb *fdb,
struct switchdev_trans *trans)
{
int state = is_multicast_ether_addr(fdb->addr) ?
GLOBAL_ATU_DATA_STATE_MC_STATIC :
GLOBAL_ATU_DATA_STATE_UC_STATIC;
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
mutex_lock(&ps->smi_mutex);
ret = _mv88e6xxx_port_fdb_load(ds, port, addr, vid, state);
ret = _mv88e6xxx_port_fdb_load(ds, port, fdb->addr, fdb->vid, state);
mutex_unlock(&ps->smi_mutex);
return ret;
}
int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid)
const struct switchdev_obj_port_fdb *fdb)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
mutex_lock(&ps->smi_mutex);
ret = _mv88e6xxx_port_fdb_load(ds, port, addr, vid,
ret = _mv88e6xxx_port_fdb_load(ds, port, fdb->addr, fdb->vid,
GLOBAL_ATU_DATA_STATE_UNUSED);
mutex_unlock(&ps->smi_mutex);
@ -1998,16 +1791,11 @@ int mv88e6xxx_port_fdb_getnext(struct dsa_switch *ds, int port,
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
struct mv88e6xxx_atu_entry next;
u16 fid;
u16 fid = *vid; /* We use one FID per VLAN */
int ret;
mutex_lock(&ps->smi_mutex);
ret = _mv88e6xxx_port_vid_to_fid(ds, port, *vid);
if (ret < 0)
goto unlock;
fid = ret;
do {
if (is_broadcast_ether_addr(addr)) {
struct mv88e6xxx_vtu_stu_entry vtu;
@ -2058,7 +1846,7 @@ static void mv88e6xxx_bridge_work(struct work_struct *work)
static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret, fid;
int ret;
u16 reg;
mutex_lock(&ps->smi_mutex);
@ -2184,7 +1972,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
reg |= PORT_CONTROL_2_FORWARD_UNKNOWN;
}
reg |= PORT_CONTROL_2_8021Q_FALLBACK;
reg |= PORT_CONTROL_2_8021Q_SECURE;
if (reg) {
ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
@ -2277,19 +2065,11 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
if (ret)
goto abort;
/* Port based VLAN map: give each port its own address
* database, allow the CPU port to talk to each of the 'real'
* ports, and allow each of the 'real' ports to only talk to
* the upstream port.
/* Port based VLAN map: do not give each port its own address
* database, and allow every port to egress frames on all other ports.
*/
fid = port + 1;
ps->fid[port] = fid;
set_bit(fid, ps->fid_bitmap);
if (!dsa_is_cpu_port(ds, port))
ps->bridge_mask[fid] = 1 << port;
ret = _mv88e6xxx_update_port_config(ds, port);
reg = BIT(ps->num_ports) - 1; /* all ports */
ret = _mv88e6xxx_port_vlan_map_set(ds, port, reg & ~port);
if (ret)
goto abort;

View File

@ -402,12 +402,6 @@ struct mv88e6xxx_priv_state {
int id; /* switch product id */
int num_ports; /* number of switch ports */
/* hw bridging */
DECLARE_BITMAP(fid_bitmap, VLAN_N_VID); /* FIDs 1 to 4095 available */
u16 fid[DSA_MAX_PORTS]; /* per (non-bridged) port FID */
u16 bridge_mask[DSA_MAX_PORTS]; /* br groups (indexed by FID) */
unsigned long port_state_update_mask;
u8 port_state[DSA_MAX_PORTS];
@ -442,7 +436,6 @@ void mv88e6xxx_ppu_state_init(struct dsa_switch *ds);
int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum);
int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
int regnum, u16 val);
void mv88e6xxx_poll_link(struct dsa_switch *ds);
void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data);
void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
uint64_t *data);
@ -465,8 +458,6 @@ int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum,
int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
struct phy_device *phydev, struct ethtool_eee *e);
int mv88e6xxx_join_bridge(struct dsa_switch *ds, int port, u32 br_port_mask);
int mv88e6xxx_leave_bridge(struct dsa_switch *ds, int port, u32 br_port_mask);
int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state);
int mv88e6xxx_port_pvid_get(struct dsa_switch *ds, int port, u16 *vid);
int mv88e6xxx_port_pvid_set(struct dsa_switch *ds, int port, u16 vid);
@ -475,10 +466,14 @@ int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, u16 vid,
int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid);
int mv88e6xxx_vlan_getnext(struct dsa_switch *ds, u16 *vid,
unsigned long *ports, unsigned long *untagged);
int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_fdb *fdb,
struct switchdev_trans *trans);
int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid);
const struct switchdev_obj_port_fdb *fdb,
struct switchdev_trans *trans);
int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid);
const struct switchdev_obj_port_fdb *fdb);
int mv88e6xxx_port_fdb_getnext(struct dsa_switch *ds, int port,
unsigned char *addr, u16 *vid, bool *is_static);
int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg);

View File

@ -1141,8 +1141,6 @@ static void greth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *in
strlcpy(info->version, "revision: 1.0", sizeof(info->version));
strlcpy(info->bus_info, greth->dev->bus->name, sizeof(info->bus_info));
strlcpy(info->fw_version, "N/A", sizeof(info->fw_version));
info->eedump_len = 0;
info->regdump_len = sizeof(struct greth_regs);
}
static void greth_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)

View File

@ -714,7 +714,6 @@ au1000_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
strlcpy(info->version, DRV_VERSION, sizeof(info->version));
snprintf(info->bus_info, sizeof(info->bus_info), "%s %d", DRV_NAME,
aup->mac_id);
info->regdump_len = 0;
}
static void au1000_set_msglevel(struct net_device *dev, u32 value)

View File

@ -1940,84 +1940,31 @@ static void xgbe_config_mtl_mode(struct xgbe_prv_data *pdata)
static unsigned int xgbe_calculate_per_queue_fifo(unsigned int fifo_size,
unsigned int queue_count)
{
unsigned int q_fifo_size = 0;
enum xgbe_mtl_fifo_size p_fifo = XGMAC_MTL_FIFO_SIZE_256;
unsigned int q_fifo_size;
unsigned int p_fifo;
/* Calculate Tx/Rx fifo share per queue */
switch (fifo_size) {
case 0:
q_fifo_size = XGBE_FIFO_SIZE_B(128);
break;
case 1:
q_fifo_size = XGBE_FIFO_SIZE_B(256);
break;
case 2:
q_fifo_size = XGBE_FIFO_SIZE_B(512);
break;
case 3:
q_fifo_size = XGBE_FIFO_SIZE_KB(1);
break;
case 4:
q_fifo_size = XGBE_FIFO_SIZE_KB(2);
break;
case 5:
q_fifo_size = XGBE_FIFO_SIZE_KB(4);
break;
case 6:
q_fifo_size = XGBE_FIFO_SIZE_KB(8);
break;
case 7:
q_fifo_size = XGBE_FIFO_SIZE_KB(16);
break;
case 8:
q_fifo_size = XGBE_FIFO_SIZE_KB(32);
break;
case 9:
q_fifo_size = XGBE_FIFO_SIZE_KB(64);
break;
case 10:
q_fifo_size = XGBE_FIFO_SIZE_KB(128);
break;
case 11:
q_fifo_size = XGBE_FIFO_SIZE_KB(256);
break;
}
/* Calculate the configured fifo size */
q_fifo_size = 1 << (fifo_size + 7);
/* The configured value is not the actual amount of fifo RAM */
/* The configured value may not be the actual amount of fifo RAM */
q_fifo_size = min_t(unsigned int, XGBE_FIFO_MAX, q_fifo_size);
q_fifo_size = q_fifo_size / queue_count;
/* Set the queue fifo size programmable value */
if (q_fifo_size >= XGBE_FIFO_SIZE_KB(256))
p_fifo = XGMAC_MTL_FIFO_SIZE_256K;
else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(128))
p_fifo = XGMAC_MTL_FIFO_SIZE_128K;
else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(64))
p_fifo = XGMAC_MTL_FIFO_SIZE_64K;
else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(32))
p_fifo = XGMAC_MTL_FIFO_SIZE_32K;
else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(16))
p_fifo = XGMAC_MTL_FIFO_SIZE_16K;
else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(8))
p_fifo = XGMAC_MTL_FIFO_SIZE_8K;
else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(4))
p_fifo = XGMAC_MTL_FIFO_SIZE_4K;
else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(2))
p_fifo = XGMAC_MTL_FIFO_SIZE_2K;
else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(1))
p_fifo = XGMAC_MTL_FIFO_SIZE_1K;
else if (q_fifo_size >= XGBE_FIFO_SIZE_B(512))
p_fifo = XGMAC_MTL_FIFO_SIZE_512;
else if (q_fifo_size >= XGBE_FIFO_SIZE_B(256))
p_fifo = XGMAC_MTL_FIFO_SIZE_256;
/* Each increment in the queue fifo size represents 256 bytes of
* fifo, with 0 representing 256 bytes. Distribute the fifo equally
* between the queues.
*/
p_fifo = q_fifo_size / 256;
if (p_fifo)
p_fifo--;
return p_fifo;
}
static void xgbe_config_tx_fifo_size(struct xgbe_prv_data *pdata)
{
enum xgbe_mtl_fifo_size fifo_size;
unsigned int fifo_size;
unsigned int i;
fifo_size = xgbe_calculate_per_queue_fifo(pdata->hw_feat.tx_fifo_size,
@ -2033,7 +1980,7 @@ static void xgbe_config_tx_fifo_size(struct xgbe_prv_data *pdata)
static void xgbe_config_rx_fifo_size(struct xgbe_prv_data *pdata)
{
enum xgbe_mtl_fifo_size fifo_size;
unsigned int fifo_size;
unsigned int i;
fifo_size = xgbe_calculate_per_queue_fifo(pdata->hw_feat.rx_fifo_size,
@ -2224,7 +2171,7 @@ static u64 xgbe_mmc_read(struct xgbe_prv_data *pdata, unsigned int reg_lo)
default:
read_hi = false;
};
}
val = XGMAC_IOREAD(pdata, reg_lo);

View File

@ -360,6 +360,9 @@ static irqreturn_t xgbe_isr(int irq, void *data)
}
}
if (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, RBU))
pdata->ext_stats.rx_buffer_unavailable++;
/* Restart the device on a Fatal Bus Error */
if (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, FBE))
schedule_work(&pdata->restart_work);
@ -384,7 +387,8 @@ static irqreturn_t xgbe_isr(int irq, void *data)
/* Read Tx Timestamp to clear interrupt */
pdata->tx_tstamp =
hw_if->get_tx_tstamp(pdata);
schedule_work(&pdata->tx_tstamp_work);
queue_work(pdata->dev_workqueue,
&pdata->tx_tstamp_work);
}
}
}
@ -450,7 +454,7 @@ static void xgbe_service_timer(unsigned long data)
{
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;
schedule_work(&pdata->service_work);
queue_work(pdata->dev_workqueue, &pdata->service_work);
mod_timer(&pdata->service_timer, jiffies + HZ);
}
@ -891,7 +895,7 @@ static int xgbe_start(struct xgbe_prv_data *pdata)
netif_tx_start_all_queues(netdev);
xgbe_start_timers(pdata);
schedule_work(&pdata->service_work);
queue_work(pdata->dev_workqueue, &pdata->service_work);
DBGPR("<--xgbe_start\n");

View File

@ -179,6 +179,7 @@ static const struct xgbe_stats xgbe_gstring_stats[] = {
XGMAC_MMC_STAT("rx_watchdog_errors", rxwatchdogerror),
XGMAC_MMC_STAT("rx_pause_frames", rxpauseframes),
XGMAC_EXT_STAT("rx_split_header_packets", rx_split_header_packets),
XGMAC_EXT_STAT("rx_buffer_unavailable", rx_buffer_unavailable),
};
#define XGBE_STATS_COUNT ARRAY_SIZE(xgbe_gstring_stats)
@ -187,8 +188,6 @@ static void xgbe_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
{
int i;
DBGPR("-->%s\n", __func__);
switch (stringset) {
case ETH_SS_STATS:
for (i = 0; i < XGBE_STATS_COUNT; i++) {
@ -198,8 +197,6 @@ static void xgbe_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
}
break;
}
DBGPR("<--%s\n", __func__);
}
static void xgbe_get_ethtool_stats(struct net_device *netdev,
@ -209,23 +206,17 @@ static void xgbe_get_ethtool_stats(struct net_device *netdev,
u8 *stat;
int i;
DBGPR("-->%s\n", __func__);
pdata->hw_if.read_mmc_stats(pdata);
for (i = 0; i < XGBE_STATS_COUNT; i++) {
stat = (u8 *)pdata + xgbe_gstring_stats[i].stat_offset;
*data++ = *(u64 *)stat;
}
DBGPR("<--%s\n", __func__);
}
static int xgbe_get_sset_count(struct net_device *netdev, int stringset)
{
int ret;
DBGPR("-->%s\n", __func__);
switch (stringset) {
case ETH_SS_STATS:
ret = XGBE_STATS_COUNT;
@ -235,8 +226,6 @@ static int xgbe_get_sset_count(struct net_device *netdev, int stringset)
ret = -EOPNOTSUPP;
}
DBGPR("<--%s\n", __func__);
return ret;
}
@ -245,13 +234,9 @@ static void xgbe_get_pauseparam(struct net_device *netdev,
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
DBGPR("-->xgbe_get_pauseparam\n");
pause->autoneg = pdata->phy.pause_autoneg;
pause->tx_pause = pdata->phy.tx_pause;
pause->rx_pause = pdata->phy.rx_pause;
DBGPR("<--xgbe_get_pauseparam\n");
}
static int xgbe_set_pauseparam(struct net_device *netdev,
@ -260,13 +245,11 @@ static int xgbe_set_pauseparam(struct net_device *netdev,
struct xgbe_prv_data *pdata = netdev_priv(netdev);
int ret = 0;
DBGPR("-->xgbe_set_pauseparam\n");
DBGPR(" autoneg = %d, tx_pause = %d, rx_pause = %d\n",
pause->autoneg, pause->tx_pause, pause->rx_pause);
if (pause->autoneg && (pdata->phy.autoneg != AUTONEG_ENABLE))
if (pause->autoneg && (pdata->phy.autoneg != AUTONEG_ENABLE)) {
netdev_err(netdev,
"autoneg disabled, pause autoneg not avialable\n");
return -EINVAL;
}
pdata->phy.pause_autoneg = pause->autoneg;
pdata->phy.tx_pause = pause->tx_pause;
@ -286,8 +269,6 @@ static int xgbe_set_pauseparam(struct net_device *netdev,
if (netif_running(netdev))
ret = pdata->phy_if.phy_config_aneg(pdata);
DBGPR("<--xgbe_set_pauseparam\n");
return ret;
}
@ -296,8 +277,6 @@ static int xgbe_get_settings(struct net_device *netdev,
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
DBGPR("-->xgbe_get_settings\n");
cmd->phy_address = pdata->phy.address;
cmd->supported = pdata->phy.supported;
@ -311,8 +290,6 @@ static int xgbe_get_settings(struct net_device *netdev,
cmd->port = PORT_NONE;
cmd->transceiver = XCVR_INTERNAL;
DBGPR("<--xgbe_get_settings\n");
return 0;
}
@ -323,16 +300,20 @@ static int xgbe_set_settings(struct net_device *netdev,
u32 speed;
int ret;
DBGPR("-->xgbe_set_settings\n");
speed = ethtool_cmd_speed(cmd);
if (cmd->phy_address != pdata->phy.address)
if (cmd->phy_address != pdata->phy.address) {
netdev_err(netdev, "invalid phy address %hhu\n",
cmd->phy_address);
return -EINVAL;
}
if ((cmd->autoneg != AUTONEG_ENABLE) &&
(cmd->autoneg != AUTONEG_DISABLE))
(cmd->autoneg != AUTONEG_DISABLE)) {
netdev_err(netdev, "unsupported autoneg %hhu\n",
cmd->autoneg);
return -EINVAL;
}
if (cmd->autoneg == AUTONEG_DISABLE) {
switch (speed) {
@ -341,16 +322,27 @@ static int xgbe_set_settings(struct net_device *netdev,
case SPEED_1000:
break;
default:
netdev_err(netdev, "unsupported speed %u\n", speed);
return -EINVAL;
}
if (cmd->duplex != DUPLEX_FULL)
if (cmd->duplex != DUPLEX_FULL) {
netdev_err(netdev, "unsupported duplex %hhu\n",
cmd->duplex);
return -EINVAL;
}
}
netif_dbg(pdata, link, netdev,
"requested advertisement %#x, phy supported %#x\n",
cmd->advertising, pdata->phy.supported);
cmd->advertising &= pdata->phy.supported;
if ((cmd->autoneg == AUTONEG_ENABLE) && !cmd->advertising)
if ((cmd->autoneg == AUTONEG_ENABLE) && !cmd->advertising) {
netdev_err(netdev,
"unsupported requested advertisement\n");
return -EINVAL;
}
ret = 0;
pdata->phy.autoneg = cmd->autoneg;
@ -366,8 +358,6 @@ static int xgbe_set_settings(struct net_device *netdev,
if (netif_running(netdev))
ret = pdata->phy_if.phy_config_aneg(pdata);
DBGPR("<--xgbe_set_settings\n");
return ret;
}
@ -385,7 +375,20 @@ static void xgbe_get_drvinfo(struct net_device *netdev,
XGMAC_GET_BITS(hw_feat->version, MAC_VR, USERVER),
XGMAC_GET_BITS(hw_feat->version, MAC_VR, DEVID),
XGMAC_GET_BITS(hw_feat->version, MAC_VR, SNPSVER));
drvinfo->n_stats = XGBE_STATS_COUNT;
}
static u32 xgbe_get_msglevel(struct net_device *netdev)
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
return pdata->msg_enable;
}
static void xgbe_set_msglevel(struct net_device *netdev, u32 msglevel)
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
pdata->msg_enable = msglevel;
}
static int xgbe_get_coalesce(struct net_device *netdev,
@ -393,8 +396,6 @@ static int xgbe_get_coalesce(struct net_device *netdev,
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
DBGPR("-->xgbe_get_coalesce\n");
memset(ec, 0, sizeof(struct ethtool_coalesce));
ec->rx_coalesce_usecs = pdata->rx_usecs;
@ -402,8 +403,6 @@ static int xgbe_get_coalesce(struct net_device *netdev,
ec->tx_max_coalesced_frames = pdata->tx_frames;
DBGPR("<--xgbe_get_coalesce\n");
return 0;
}
@ -415,8 +414,6 @@ static int xgbe_set_coalesce(struct net_device *netdev,
unsigned int rx_frames, rx_riwt, rx_usecs;
unsigned int tx_frames;
DBGPR("-->xgbe_set_coalesce\n");
/* Check for not supported parameters */
if ((ec->rx_coalesce_usecs_irq) ||
(ec->rx_max_coalesced_frames_irq) ||
@ -436,8 +433,10 @@ static int xgbe_set_coalesce(struct net_device *netdev,
(ec->rx_max_coalesced_frames_high) ||
(ec->tx_coalesce_usecs_high) ||
(ec->tx_max_coalesced_frames_high) ||
(ec->rate_sample_interval))
(ec->rate_sample_interval)) {
netdev_err(netdev, "unsupported coalescing parameter\n");
return -EOPNOTSUPP;
}
rx_riwt = hw_if->usec_to_riwt(pdata, ec->rx_coalesce_usecs);
rx_usecs = ec->rx_coalesce_usecs;
@ -449,13 +448,13 @@ static int xgbe_set_coalesce(struct net_device *netdev,
/* Check the bounds of values for Rx */
if (rx_riwt > XGMAC_MAX_DMA_RIWT) {
netdev_alert(netdev, "rx-usec is limited to %d usecs\n",
hw_if->riwt_to_usec(pdata, XGMAC_MAX_DMA_RIWT));
netdev_err(netdev, "rx-usec is limited to %d usecs\n",
hw_if->riwt_to_usec(pdata, XGMAC_MAX_DMA_RIWT));
return -EINVAL;
}
if (rx_frames > pdata->rx_desc_count) {
netdev_alert(netdev, "rx-frames is limited to %d frames\n",
pdata->rx_desc_count);
netdev_err(netdev, "rx-frames is limited to %d frames\n",
pdata->rx_desc_count);
return -EINVAL;
}
@ -463,8 +462,8 @@ static int xgbe_set_coalesce(struct net_device *netdev,
/* Check the bounds of values for Tx */
if (tx_frames > pdata->tx_desc_count) {
netdev_alert(netdev, "tx-frames is limited to %d frames\n",
pdata->tx_desc_count);
netdev_err(netdev, "tx-frames is limited to %d frames\n",
pdata->tx_desc_count);
return -EINVAL;
}
@ -476,8 +475,6 @@ static int xgbe_set_coalesce(struct net_device *netdev,
pdata->tx_frames = tx_frames;
hw_if->config_tx_coalesce(pdata);
DBGPR("<--xgbe_set_coalesce\n");
return 0;
}
@ -539,8 +536,10 @@ static int xgbe_set_rxfh(struct net_device *netdev, const u32 *indir,
struct xgbe_hw_if *hw_if = &pdata->hw_if;
unsigned int ret;
if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) {
netdev_err(netdev, "unsupported hash function\n");
return -EOPNOTSUPP;
}
if (indir) {
ret = hw_if->set_rss_lookup_table(pdata, indir);
@ -594,6 +593,8 @@ static const struct ethtool_ops xgbe_ethtool_ops = {
.get_settings = xgbe_get_settings,
.set_settings = xgbe_set_settings,
.get_drvinfo = xgbe_get_drvinfo,
.get_msglevel = xgbe_get_msglevel,
.set_msglevel = xgbe_set_msglevel,
.get_link = ethtool_op_get_link,
.get_coalesce = xgbe_get_coalesce,
.set_coalesce = xgbe_set_coalesce,

View File

@ -371,7 +371,7 @@ static int xgbe_probe(struct platform_device *pdev)
set_bit(XGBE_DOWN, &pdata->dev_state);
/* Check if we should use ACPI or DT */
pdata->use_acpi = (!pdata->adev || acpi_disabled) ? 0 : 1;
pdata->use_acpi = dev->of_node ? 0 : 1;
phy_pdev = xgbe_get_phy_pdev(pdata);
if (!phy_pdev) {

View File

@ -1115,8 +1115,7 @@ static void xgbe_phy_status(struct xgbe_prv_data *pdata)
unsigned int reg, link_aneg;
if (test_bit(XGBE_LINK_ERR, &pdata->dev_state)) {
if (test_and_clear_bit(XGBE_LINK, &pdata->dev_state))
netif_carrier_off(pdata->netdev);
netif_carrier_off(pdata->netdev);
pdata->phy.link = 0;
goto adjust_link;
@ -1142,10 +1141,7 @@ static void xgbe_phy_status(struct xgbe_prv_data *pdata)
if (test_bit(XGBE_LINK_INIT, &pdata->dev_state))
clear_bit(XGBE_LINK_INIT, &pdata->dev_state);
if (!test_bit(XGBE_LINK, &pdata->dev_state)) {
set_bit(XGBE_LINK, &pdata->dev_state);
netif_carrier_on(pdata->netdev);
}
netif_carrier_on(pdata->netdev);
} else {
if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) {
xgbe_check_link_timeout(pdata);
@ -1156,10 +1152,7 @@ static void xgbe_phy_status(struct xgbe_prv_data *pdata)
xgbe_phy_status_aneg(pdata);
if (test_bit(XGBE_LINK, &pdata->dev_state)) {
clear_bit(XGBE_LINK, &pdata->dev_state);
netif_carrier_off(pdata->netdev);
}
netif_carrier_off(pdata->netdev);
}
adjust_link:
@ -1179,8 +1172,7 @@ static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
devm_free_irq(pdata->dev, pdata->an_irq, pdata);
pdata->phy.link = 0;
if (test_and_clear_bit(XGBE_LINK, &pdata->dev_state))
netif_carrier_off(pdata->netdev);
netif_carrier_off(pdata->netdev);
xgbe_phy_adjust_link(pdata);
}

View File

@ -209,8 +209,6 @@
#define XGMAC_IOCTL_CONTEXT 2
#define XGBE_FIFO_MAX 81920
#define XGBE_FIFO_SIZE_B(x) (x)
#define XGBE_FIFO_SIZE_KB(x) (x * 1024)
#define XGBE_TC_MIN_QUANTUM 10
@ -461,7 +459,6 @@ struct xgbe_channel {
enum xgbe_state {
XGBE_DOWN,
XGBE_LINK,
XGBE_LINK_INIT,
XGBE_LINK_ERR,
};
@ -483,20 +480,6 @@ enum xgbe_int_state {
XGMAC_INT_STATE_RESTORE,
};
enum xgbe_mtl_fifo_size {
XGMAC_MTL_FIFO_SIZE_256 = 0x00,
XGMAC_MTL_FIFO_SIZE_512 = 0x01,
XGMAC_MTL_FIFO_SIZE_1K = 0x03,
XGMAC_MTL_FIFO_SIZE_2K = 0x07,
XGMAC_MTL_FIFO_SIZE_4K = 0x0f,
XGMAC_MTL_FIFO_SIZE_8K = 0x1f,
XGMAC_MTL_FIFO_SIZE_16K = 0x3f,
XGMAC_MTL_FIFO_SIZE_32K = 0x7f,
XGMAC_MTL_FIFO_SIZE_64K = 0xff,
XGMAC_MTL_FIFO_SIZE_128K = 0x1ff,
XGMAC_MTL_FIFO_SIZE_256K = 0x3ff,
};
enum xgbe_speed {
XGBE_SPEED_1000 = 0,
XGBE_SPEED_2500,
@ -598,6 +581,7 @@ struct xgbe_mmc_stats {
struct xgbe_ext_stats {
u64 tx_tso_packets;
u64 rx_split_header_packets;
u64 rx_buffer_unavailable;
};
struct xgbe_hw_if {

View File

@ -233,10 +233,6 @@ static void atl1c_get_drvinfo(struct net_device *netdev,
sizeof(drvinfo->version));
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
drvinfo->n_stats = 0;
drvinfo->testinfo_len = 0;
drvinfo->regdump_len = atl1c_get_regs_len(netdev);
drvinfo->eedump_len = atl1c_get_eeprom_len(netdev);
}
static void atl1c_get_wol(struct net_device *netdev,

View File

@ -316,10 +316,6 @@ static void atl1e_get_drvinfo(struct net_device *netdev,
strlcpy(drvinfo->fw_version, "L1e", sizeof(drvinfo->fw_version));
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
drvinfo->n_stats = 0;
drvinfo->testinfo_len = 0;
drvinfo->regdump_len = atl1e_get_regs_len(netdev);
drvinfo->eedump_len = atl1e_get_eeprom_len(netdev);
}
static void atl1e_get_wol(struct net_device *netdev,

View File

@ -3388,7 +3388,6 @@ static void atl1_get_drvinfo(struct net_device *netdev,
sizeof(drvinfo->version));
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
drvinfo->eedump_len = ATL1_EEDUMP_LEN;
}
static void atl1_get_wol(struct net_device *netdev,

View File

@ -2030,10 +2030,6 @@ static void atl2_get_drvinfo(struct net_device *netdev,
strlcpy(drvinfo->fw_version, "L2", sizeof(drvinfo->fw_version));
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
drvinfo->n_stats = 0;
drvinfo->testinfo_len = 0;
drvinfo->regdump_len = atl2_get_regs_len(netdev);
drvinfo->eedump_len = atl2_get_eeprom_len(netdev);
}
static void atl2_get_wol(struct net_device *netdev,

View File

@ -1333,7 +1333,6 @@ static void bcm_enet_get_drvinfo(struct net_device *netdev,
sizeof(drvinfo->version));
strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
strlcpy(drvinfo->bus_info, "bcm63xx", sizeof(drvinfo->bus_info));
drvinfo->n_stats = BCM_ENET_STATS_LEN;
}
static int bcm_enet_get_sset_count(struct net_device *netdev,
@ -2597,7 +2596,6 @@ static void bcm_enetsw_get_drvinfo(struct net_device *netdev,
strncpy(drvinfo->version, bcm_enet_driver_version, 32);
strncpy(drvinfo->fw_version, "N/A", 32);
strncpy(drvinfo->bus_info, "bcm63xx", 32);
drvinfo->n_stats = BCM_ENETSW_STATS_LEN;
}
static void bcm_enetsw_get_ethtool_stats(struct net_device *netdev,

View File

@ -287,7 +287,6 @@ static void bcm_sysport_get_drvinfo(struct net_device *dev,
strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
strlcpy(info->version, "0.1", sizeof(info->version));
strlcpy(info->bus_info, "platform", sizeof(info->bus_info));
info->n_stats = BCM_SYSPORT_STATS_LEN;
}
static u32 bcm_sysport_get_msglvl(struct net_device *dev)

View File

@ -812,6 +812,46 @@ bnx2_alloc_rx_mem(struct bnx2 *bp)
return 0;
}
static void
bnx2_free_stats_blk(struct net_device *dev)
{
struct bnx2 *bp = netdev_priv(dev);
if (bp->status_blk) {
dma_free_coherent(&bp->pdev->dev, bp->status_stats_size,
bp->status_blk,
bp->status_blk_mapping);
bp->status_blk = NULL;
bp->stats_blk = NULL;
}
}
static int
bnx2_alloc_stats_blk(struct net_device *dev)
{
int status_blk_size;
void *status_blk;
struct bnx2 *bp = netdev_priv(dev);
/* Combine status and statistics blocks into one allocation. */
status_blk_size = L1_CACHE_ALIGN(sizeof(struct status_block));
if (bp->flags & BNX2_FLAG_MSIX_CAP)
status_blk_size = L1_CACHE_ALIGN(BNX2_MAX_MSIX_HW_VEC *
BNX2_SBLK_MSIX_ALIGN_SIZE);
bp->status_stats_size = status_blk_size +
sizeof(struct statistics_block);
status_blk = dma_zalloc_coherent(&bp->pdev->dev, bp->status_stats_size,
&bp->status_blk_mapping, GFP_KERNEL);
if (status_blk == NULL)
return -ENOMEM;
bp->status_blk = status_blk;
bp->stats_blk = status_blk + status_blk_size;
bp->stats_blk_mapping = bp->status_blk_mapping + status_blk_size;
return 0;
}
static void
bnx2_free_mem(struct bnx2 *bp)
{
@ -829,37 +869,19 @@ bnx2_free_mem(struct bnx2 *bp)
bp->ctx_blk[i] = NULL;
}
}
if (bnapi->status_blk.msi) {
dma_free_coherent(&bp->pdev->dev, bp->status_stats_size,
bnapi->status_blk.msi,
bp->status_blk_mapping);
if (bnapi->status_blk.msi)
bnapi->status_blk.msi = NULL;
bp->stats_blk = NULL;
}
}
static int
bnx2_alloc_mem(struct bnx2 *bp)
{
int i, status_blk_size, err;
int i, err;
struct bnx2_napi *bnapi;
void *status_blk;
/* Combine status and statistics blocks into one allocation. */
status_blk_size = L1_CACHE_ALIGN(sizeof(struct status_block));
if (bp->flags & BNX2_FLAG_MSIX_CAP)
status_blk_size = L1_CACHE_ALIGN(BNX2_MAX_MSIX_HW_VEC *
BNX2_SBLK_MSIX_ALIGN_SIZE);
bp->status_stats_size = status_blk_size +
sizeof(struct statistics_block);
status_blk = dma_zalloc_coherent(&bp->pdev->dev, bp->status_stats_size,
&bp->status_blk_mapping, GFP_KERNEL);
if (status_blk == NULL)
goto alloc_mem_err;
bnapi = &bp->bnx2_napi[0];
bnapi->status_blk.msi = status_blk;
bnapi->status_blk.msi = bp->status_blk;
bnapi->hw_tx_cons_ptr =
&bnapi->status_blk.msi->status_tx_quick_consumer_index0;
bnapi->hw_rx_cons_ptr =
@ -870,7 +892,7 @@ bnx2_alloc_mem(struct bnx2 *bp)
bnapi = &bp->bnx2_napi[i];
sblk = (status_blk + BNX2_SBLK_MSIX_ALIGN_SIZE * i);
sblk = (bp->status_blk + BNX2_SBLK_MSIX_ALIGN_SIZE * i);
bnapi->status_blk.msix = sblk;
bnapi->hw_tx_cons_ptr =
&sblk->status_tx_quick_consumer_index;
@ -880,10 +902,6 @@ bnx2_alloc_mem(struct bnx2 *bp)
}
}
bp->stats_blk = status_blk + status_blk_size;
bp->stats_blk_mapping = bp->status_blk_mapping + status_blk_size;
if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
bp->ctx_pages = 0x2000 / BNX2_PAGE_SIZE;
if (bp->ctx_pages == 0)
@ -8330,6 +8348,11 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->phy_addr = 1;
/* allocate stats_blk */
rc = bnx2_alloc_stats_blk(dev);
if (rc)
goto err_out_unmap;
/* Disable WOL support if we are running on a SERDES chip. */
if (BNX2_CHIP(bp) == BNX2_CHIP_5709)
bnx2_get_5709_media(bp);
@ -8453,6 +8476,8 @@ err_out_disable:
pci_disable_device(pdev);
err_out:
kfree(bp->temp_stats_blk);
return rc;
}
@ -8586,6 +8611,7 @@ error:
pci_release_regions(pdev);
pci_disable_device(pdev);
err_free:
bnx2_free_stats_blk(dev);
free_netdev(dev);
return rc;
}
@ -8603,6 +8629,7 @@ bnx2_remove_one(struct pci_dev *pdev)
pci_iounmap(bp->pdev, bp->regview);
bnx2_free_stats_blk(dev);
kfree(bp->temp_stats_blk);
if (bp->flags & BNX2_FLAG_AER_ENABLED) {

View File

@ -6928,6 +6928,7 @@ struct bnx2 {
dma_addr_t status_blk_mapping;
void *status_blk;
struct statistics_block *stats_blk;
struct statistics_block *temp_stats_blk;
dma_addr_t stats_blk_mapping;

View File

@ -1090,10 +1090,6 @@ static void bnx2x_get_drvinfo(struct net_device *dev,
bnx2x_fill_fw_str(bp, info->fw_version, sizeof(info->fw_version));
strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info));
info->n_stats = BNX2X_NUM_STATS;
info->testinfo_len = BNX2X_NUM_TESTS(bp);
info->eedump_len = bp->common.flash_size;
info->regdump_len = bnx2x_get_regs_len(dev);
}
static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)

View File

@ -793,7 +793,6 @@ static void bcmgenet_get_drvinfo(struct net_device *dev,
{
strlcpy(info->driver, "bcmgenet", sizeof(info->driver));
strlcpy(info->version, "v2.0", sizeof(info->version));
info->n_stats = BCMGENET_STATS_LEN;
}
static int bcmgenet_get_sset_count(struct net_device *dev, int string_set)

View File

@ -153,7 +153,6 @@ lio_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
strncpy(drvinfo->fw_version, oct->fw_info.liquidio_firmware_version,
ETHTOOL_FWVERS_LEN);
strncpy(drvinfo->bus_info, pci_name(oct->pci_dev), 32);
drvinfo->regdump_len = OCT_ETHTOOL_REGDUMP_LEN;
}
static void

View File

@ -940,6 +940,7 @@ static const char * const devlog_level_strings[] = {
static const char * const devlog_facility_strings[] = {
[FW_DEVLOG_FACILITY_CORE] = "CORE",
[FW_DEVLOG_FACILITY_CF] = "CF",
[FW_DEVLOG_FACILITY_SCHED] = "SCHED",
[FW_DEVLOG_FACILITY_TIMER] = "TIMER",
[FW_DEVLOG_FACILITY_RES] = "RES",
@ -1128,18 +1129,26 @@ static const struct file_operations devlog_fops = {
static int mbox_show(struct seq_file *seq, void *v)
{
static const char * const owner[] = { "none", "FW", "driver",
"unknown" };
"unknown", "<unread>" };
int i;
unsigned int mbox = (uintptr_t)seq->private & 7;
struct adapter *adap = seq->private - mbox;
void __iomem *addr = adap->regs + PF_REG(mbox, CIM_PF_MAILBOX_DATA_A);
unsigned int ctrl_reg = (is_t4(adap->params.chip)
? CIM_PF_MAILBOX_CTRL_A
: CIM_PF_MAILBOX_CTRL_SHADOW_COPY_A);
void __iomem *ctrl = adap->regs + PF_REG(mbox, ctrl_reg);
i = MBOWNER_G(readl(ctrl));
/* For T4 we don't have a shadow copy of the Mailbox Control register.
* And since reading that real register causes a side effect of
* granting ownership, we're best of simply not reading it at all.
*/
if (is_t4(adap->params.chip)) {
i = 4; /* index of "<unread>" */
} else {
unsigned int ctrl_reg = CIM_PF_MAILBOX_CTRL_SHADOW_COPY_A;
void __iomem *ctrl = adap->regs + PF_REG(mbox, ctrl_reg);
i = MBOWNER_G(readl(ctrl));
}
seq_printf(seq, "mailbox owned by %s\n\n", owner[i]);
for (i = 0; i < MBOX_LEN; i += 8)

View File

@ -275,7 +275,7 @@ static void link_report(struct net_device *dev)
else {
static const char *fc[] = { "no", "Rx", "Tx", "Tx/Rx" };
const char *s = "10Mbps";
const char *s;
const struct port_info *p = netdev_priv(dev);
switch (p->link_cfg.speed) {
@ -291,6 +291,10 @@ static void link_report(struct net_device *dev)
case 40000:
s = "40Gbps";
break;
default:
pr_info("%s: unsupported speed: %d\n",
dev->name, p->link_cfg.speed);
return;
}
netdev_info(dev, "link up, %s, full-duplex, %s PAUSE\n", s,
@ -3694,7 +3698,7 @@ static int adap_init0(struct adapter *adap)
t4_get_tp_version(adap, &adap->params.tp_vers);
ret = t4_check_fw_version(adap);
/* If firmware is too old (not supported by driver) force an update. */
if (ret == -EFAULT)
if (ret)
state = DEV_STATE_UNINIT;
if ((adap->flags & MASTER_PF) && state != DEV_STATE_INIT) {
struct fw_info *fw_info;

File diff suppressed because it is too large Load Diff

View File

@ -143,6 +143,7 @@ struct enic {
struct vnic_dev *vdev;
struct timer_list notify_timer;
struct work_struct reset;
struct work_struct tx_hang_reset;
struct work_struct change_mtu_work;
struct msix_entry msix_entry[ENIC_INTR_MAX];
struct enic_msix_entry msix[ENIC_INTR_MAX];

View File

@ -178,13 +178,15 @@ static int enic_wq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc,
return 0;
}
static void enic_log_q_error(struct enic *enic)
static bool enic_log_q_error(struct enic *enic)
{
unsigned int i;
u32 error_status;
bool err = false;
for (i = 0; i < enic->wq_count; i++) {
error_status = vnic_wq_error_status(&enic->wq[i]);
err |= error_status;
if (error_status)
netdev_err(enic->netdev, "WQ[%d] error_status %d\n",
i, error_status);
@ -192,10 +194,13 @@ static void enic_log_q_error(struct enic *enic)
for (i = 0; i < enic->rq_count; i++) {
error_status = vnic_rq_error_status(&enic->rq[i]);
err |= error_status;
if (error_status)
netdev_err(enic->netdev, "RQ[%d] error_status %d\n",
i, error_status);
}
return err;
}
static void enic_msglvl_check(struct enic *enic)
@ -333,10 +338,9 @@ static irqreturn_t enic_isr_msix_err(int irq, void *data)
vnic_intr_return_all_credits(&enic->intr[intr]);
enic_log_q_error(enic);
/* schedule recovery from WQ/RQ error */
schedule_work(&enic->reset);
if (enic_log_q_error(enic))
/* schedule recovery from WQ/RQ error */
schedule_work(&enic->reset);
return IRQ_HANDLED;
}
@ -804,7 +808,7 @@ static void enic_set_rx_mode(struct net_device *netdev)
static void enic_tx_timeout(struct net_device *netdev)
{
struct enic *enic = netdev_priv(netdev);
schedule_work(&enic->reset);
schedule_work(&enic->tx_hang_reset);
}
static int enic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
@ -1924,6 +1928,19 @@ static int enic_dev_open(struct enic *enic)
return err;
}
static int enic_dev_soft_reset(struct enic *enic)
{
int err;
err = enic_dev_wait(enic->vdev, vnic_dev_soft_reset,
vnic_dev_soft_reset_done, 0);
if (err)
netdev_err(enic->netdev, "vNIC soft reset failed, err %d\n",
err);
return err;
}
static int enic_dev_hang_reset(struct enic *enic)
{
int err;
@ -2059,6 +2076,26 @@ static void enic_reset(struct work_struct *work)
rtnl_lock();
spin_lock(&enic->enic_api_lock);
enic_stop(enic->netdev);
enic_dev_soft_reset(enic);
enic_reset_addr_lists(enic);
enic_init_vnic_resources(enic);
enic_set_rss_nic_cfg(enic);
enic_dev_set_ig_vlan_rewrite_mode(enic);
enic_open(enic->netdev);
spin_unlock(&enic->enic_api_lock);
call_netdevice_notifiers(NETDEV_REBOOT, enic->netdev);
rtnl_unlock();
}
static void enic_tx_hang_reset(struct work_struct *work)
{
struct enic *enic = container_of(work, struct enic, tx_hang_reset);
rtnl_lock();
spin_lock(&enic->enic_api_lock);
enic_dev_hang_notify(enic);
enic_stop(enic->netdev);
@ -2583,6 +2620,7 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
enic_set_rx_coal_setting(enic);
INIT_WORK(&enic->reset, enic_reset);
INIT_WORK(&enic->tx_hang_reset, enic_tx_hang_reset);
INIT_WORK(&enic->change_mtu_work, enic_change_mtu_work);
for (i = 0; i < enic->wq_count; i++)

View File

@ -659,14 +659,14 @@ int vnic_dev_open_done(struct vnic_dev *vdev, int *done)
return 0;
}
static int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg)
int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg)
{
u64 a0 = (u32)arg, a1 = 0;
int wait = 1000;
return vnic_dev_cmd(vdev, CMD_SOFT_RESET, &a0, &a1, wait);
}
static int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done)
int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done)
{
u64 a0 = 0, a1 = 0;
int wait = 1000;

View File

@ -155,7 +155,9 @@ int vnic_dev_deinit(struct vnic_dev *vdev);
void vnic_dev_intr_coal_timer_info_default(struct vnic_dev *vdev);
int vnic_dev_intr_coal_timer_info(struct vnic_dev *vdev);
int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg);
int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg);
int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done);
int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done);
void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
enum vnic_dev_intr_mode intr_mode);
enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev);

View File

@ -1597,7 +1597,6 @@ static void de_get_drvinfo (struct net_device *dev,struct ethtool_drvinfo *info)
strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
strlcpy(info->version, DRV_VERSION, sizeof(info->version));
strlcpy(info->bus_info, pci_name(de->pdev), sizeof(info->bus_info));
info->eedump_len = DE_EEPROM_SIZE;
}
static int de_get_regs_len(struct net_device *dev)

View File

@ -234,9 +234,6 @@ static void be_get_drvinfo(struct net_device *netdev,
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
drvinfo->testinfo_len = 0;
drvinfo->regdump_len = 0;
drvinfo->eedump_len = 0;
}
static u32 lancer_cmd_get_file_len(struct be_adapter *adapter, u8 *file_name)

View File

@ -112,9 +112,8 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
unsigned long flags;
u32 val, tempval;
int inc;
struct timespec ts;
struct timespec64 ts;
u64 ns;
u32 remainder;
val = 0;
if (!(fep->hwts_tx_en || fep->hwts_rx_en)) {
@ -163,8 +162,7 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
tempval = readl(fep->hwp + FEC_ATIME);
/* Convert the ptp local counter to 1588 timestamp */
ns = timecounter_cyc2time(&fep->tc, tempval);
ts.tv_sec = div_u64_rem(ns, 1000000000ULL, &remainder);
ts.tv_nsec = remainder;
ts = ns_to_timespec64(ns);
/* The tempval is less than 3 seconds, and so val is less than
* 4 seconds. No overflow for 32bit calculation.

View File

@ -907,6 +907,9 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
if (of_find_property(np, "fsl,magic-packet", NULL))
priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET;
if (of_get_property(np, "fsl,wake-on-filer", NULL))
priv->device_flags |= FSL_GIANFAR_DEV_HAS_WAKE_ON_FILER;
priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
/* In the case of a fixed PHY, the DT node associated
@ -1415,8 +1418,14 @@ static int gfar_probe(struct platform_device *ofdev)
goto register_fail;
}
device_set_wakeup_capable(&dev->dev, priv->device_flags &
FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET)
priv->wol_supported |= GFAR_WOL_MAGIC;
if ((priv->device_flags & FSL_GIANFAR_DEV_HAS_WAKE_ON_FILER) &&
priv->rx_filer_enable)
priv->wol_supported |= GFAR_WOL_FILER_UCAST;
device_set_wakeup_capable(&ofdev->dev, priv->wol_supported);
/* fill out IRQ number and name fields */
for (i = 0; i < priv->num_grps; i++) {
@ -1479,15 +1488,122 @@ static int gfar_remove(struct platform_device *ofdev)
#ifdef CONFIG_PM
static void __gfar_filer_disable(struct gfar_private *priv)
{
struct gfar __iomem *regs = priv->gfargrp[0].regs;
u32 temp;
temp = gfar_read(&regs->rctrl);
temp &= ~(RCTRL_FILREN | RCTRL_PRSDEP_INIT);
gfar_write(&regs->rctrl, temp);
}
static void __gfar_filer_enable(struct gfar_private *priv)
{
struct gfar __iomem *regs = priv->gfargrp[0].regs;
u32 temp;
temp = gfar_read(&regs->rctrl);
temp |= RCTRL_FILREN | RCTRL_PRSDEP_INIT;
gfar_write(&regs->rctrl, temp);
}
/* Filer rules implementing wol capabilities */
static void gfar_filer_config_wol(struct gfar_private *priv)
{
unsigned int i;
u32 rqfcr;
__gfar_filer_disable(priv);
/* clear the filer table, reject any packet by default */
rqfcr = RQFCR_RJE | RQFCR_CMP_MATCH;
for (i = 0; i <= MAX_FILER_IDX; i++)
gfar_write_filer(priv, i, rqfcr, 0);
i = 0;
if (priv->wol_opts & GFAR_WOL_FILER_UCAST) {
/* unicast packet, accept it */
struct net_device *ndev = priv->ndev;
/* get the default rx queue index */
u8 qindex = (u8)priv->gfargrp[0].rx_queue->qindex;
u32 dest_mac_addr = (ndev->dev_addr[0] << 16) |
(ndev->dev_addr[1] << 8) |
ndev->dev_addr[2];
rqfcr = (qindex << 10) | RQFCR_AND |
RQFCR_CMP_EXACT | RQFCR_PID_DAH;
gfar_write_filer(priv, i++, rqfcr, dest_mac_addr);
dest_mac_addr = (ndev->dev_addr[3] << 16) |
(ndev->dev_addr[4] << 8) |
ndev->dev_addr[5];
rqfcr = (qindex << 10) | RQFCR_GPI |
RQFCR_CMP_EXACT | RQFCR_PID_DAL;
gfar_write_filer(priv, i++, rqfcr, dest_mac_addr);
}
__gfar_filer_enable(priv);
}
static void gfar_filer_restore_table(struct gfar_private *priv)
{
u32 rqfcr, rqfpr;
unsigned int i;
__gfar_filer_disable(priv);
for (i = 0; i <= MAX_FILER_IDX; i++) {
rqfcr = priv->ftp_rqfcr[i];
rqfpr = priv->ftp_rqfpr[i];
gfar_write_filer(priv, i, rqfcr, rqfpr);
}
__gfar_filer_enable(priv);
}
/* gfar_start() for Rx only and with the FGPI filer interrupt enabled */
static void gfar_start_wol_filer(struct gfar_private *priv)
{
struct gfar __iomem *regs = priv->gfargrp[0].regs;
u32 tempval;
int i = 0;
/* Enable Rx hw queues */
gfar_write(&regs->rqueue, priv->rqueue);
/* Initialize DMACTRL to have WWR and WOP */
tempval = gfar_read(&regs->dmactrl);
tempval |= DMACTRL_INIT_SETTINGS;
gfar_write(&regs->dmactrl, tempval);
/* Make sure we aren't stopped */
tempval = gfar_read(&regs->dmactrl);
tempval &= ~DMACTRL_GRS;
gfar_write(&regs->dmactrl, tempval);
for (i = 0; i < priv->num_grps; i++) {
regs = priv->gfargrp[i].regs;
/* Clear RHLT, so that the DMA starts polling now */
gfar_write(&regs->rstat, priv->gfargrp[i].rstat);
/* enable the Filer General Purpose Interrupt */
gfar_write(&regs->imask, IMASK_FGPI);
}
/* Enable Rx DMA */
tempval = gfar_read(&regs->maccfg1);
tempval |= MACCFG1_RX_EN;
gfar_write(&regs->maccfg1, tempval);
}
static int gfar_suspend(struct device *dev)
{
struct gfar_private *priv = dev_get_drvdata(dev);
struct net_device *ndev = priv->ndev;
struct gfar __iomem *regs = priv->gfargrp[0].regs;
u32 tempval;
int magic_packet = priv->wol_en &&
(priv->device_flags &
FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
u16 wol = priv->wol_opts;
if (!netif_running(ndev))
return 0;
@ -1499,7 +1615,7 @@ static int gfar_suspend(struct device *dev)
gfar_halt(priv);
if (magic_packet) {
if (wol & GFAR_WOL_MAGIC) {
/* Enable interrupt on Magic Packet */
gfar_write(&regs->imask, IMASK_MAG);
@ -1513,6 +1629,10 @@ static int gfar_suspend(struct device *dev)
tempval |= MACCFG1_RX_EN;
gfar_write(&regs->maccfg1, tempval);
} else if (wol & GFAR_WOL_FILER_UCAST) {
gfar_filer_config_wol(priv);
gfar_start_wol_filer(priv);
} else {
phy_stop(priv->phydev);
}
@ -1526,18 +1646,22 @@ static int gfar_resume(struct device *dev)
struct net_device *ndev = priv->ndev;
struct gfar __iomem *regs = priv->gfargrp[0].regs;
u32 tempval;
int magic_packet = priv->wol_en &&
(priv->device_flags &
FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
u16 wol = priv->wol_opts;
if (!netif_running(ndev))
return 0;
if (magic_packet) {
if (wol & GFAR_WOL_MAGIC) {
/* Disable Magic Packet mode */
tempval = gfar_read(&regs->maccfg2);
tempval &= ~MACCFG2_MPEN;
gfar_write(&regs->maccfg2, tempval);
} else if (wol & GFAR_WOL_FILER_UCAST) {
/* need to stop rx only, tx is already down */
gfar_halt(priv);
gfar_filer_restore_table(priv);
} else {
phy_start(priv->phydev);
}
@ -1998,6 +2122,8 @@ static int register_grp_irqs(struct gfar_priv_grp *grp)
gfar_irq(grp, RX)->irq);
goto rx_irq_fail;
}
enable_irq_wake(gfar_irq(grp, RX)->irq);
} else {
err = request_irq(gfar_irq(grp, TX)->irq, gfar_interrupt, 0,
gfar_irq(grp, TX)->name, grp);
@ -2743,7 +2869,14 @@ irqreturn_t gfar_receive(int irq, void *grp_id)
{
struct gfar_priv_grp *grp = (struct gfar_priv_grp *)grp_id;
unsigned long flags;
u32 imask;
u32 imask, ievent;
ievent = gfar_read(&grp->regs->ievent);
if (unlikely(ievent & IEVENT_FGPI)) {
gfar_write(&grp->regs->ievent, IEVENT_FGPI);
return IRQ_HANDLED;
}
if (likely(napi_schedule_prep(&grp->napi_rx))) {
spin_lock_irqsave(&grp->grplock, flags);

View File

@ -340,6 +340,7 @@ extern const char gfar_driver_version[];
#define IEVENT_MAG 0x00000800
#define IEVENT_GRSC 0x00000100
#define IEVENT_RXF0 0x00000080
#define IEVENT_FGPI 0x00000010
#define IEVENT_FIR 0x00000008
#define IEVENT_FIQ 0x00000004
#define IEVENT_DPE 0x00000002
@ -372,6 +373,7 @@ extern const char gfar_driver_version[];
#define IMASK_MAG 0x00000800
#define IMASK_GRSC 0x00000100
#define IMASK_RXFEN0 0x00000080
#define IMASK_FGPI 0x00000010
#define IMASK_FIR 0x00000008
#define IMASK_FIQ 0x00000004
#define IMASK_DPE 0x00000002
@ -540,6 +542,9 @@ extern const char gfar_driver_version[];
#define GFAR_INT_NAME_MAX (IFNAMSIZ + 6) /* '_g#_xx' */
#define GFAR_WOL_MAGIC 0x00000001
#define GFAR_WOL_FILER_UCAST 0x00000002
struct txbd8
{
union {
@ -917,6 +922,7 @@ struct gfar {
#define FSL_GIANFAR_DEV_HAS_BD_STASHING 0x00000200
#define FSL_GIANFAR_DEV_HAS_BUF_STASHING 0x00000400
#define FSL_GIANFAR_DEV_HAS_TIMER 0x00000800
#define FSL_GIANFAR_DEV_HAS_WAKE_ON_FILER 0x00001000
#if (MAXGROUPS == 2)
#define DEFAULT_MAPPING 0xAA
@ -1161,8 +1167,6 @@ struct gfar_private {
extended_hash:1,
bd_stash_en:1,
rx_filer_enable:1,
/* Wake-on-LAN enabled */
wol_en:1,
/* Enable priorty based Tx scheduling in Hw */
prio_sched_en:1,
/* Flow control flags */
@ -1191,6 +1195,10 @@ struct gfar_private {
u32 __iomem *hash_regs[16];
int hash_width;
/* wake-on-lan settings */
u16 wol_opts;
u16 wol_supported;
/*Filer table*/
unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];

View File

@ -182,8 +182,6 @@ static void gfar_gdrvinfo(struct net_device *dev,
sizeof(drvinfo->version));
strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
strlcpy(drvinfo->bus_info, "N/A", sizeof(drvinfo->bus_info));
drvinfo->regdump_len = 0;
drvinfo->eedump_len = 0;
}
@ -644,28 +642,49 @@ static void gfar_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct gfar_private *priv = netdev_priv(dev);
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) {
wol->supported = WAKE_MAGIC;
wol->wolopts = priv->wol_en ? WAKE_MAGIC : 0;
} else {
wol->supported = wol->wolopts = 0;
}
wol->supported = 0;
wol->wolopts = 0;
if (priv->wol_supported & GFAR_WOL_MAGIC)
wol->supported |= WAKE_MAGIC;
if (priv->wol_supported & GFAR_WOL_FILER_UCAST)
wol->supported |= WAKE_UCAST;
if (priv->wol_opts & GFAR_WOL_MAGIC)
wol->wolopts |= WAKE_MAGIC;
if (priv->wol_opts & GFAR_WOL_FILER_UCAST)
wol->wolopts |= WAKE_UCAST;
}
static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct gfar_private *priv = netdev_priv(dev);
u16 wol_opts = 0;
int err;
if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) &&
wol->wolopts != 0)
if (!priv->wol_supported && wol->wolopts)
return -EINVAL;
if (wol->wolopts & ~WAKE_MAGIC)
if (wol->wolopts & ~(WAKE_MAGIC | WAKE_UCAST))
return -EINVAL;
device_set_wakeup_enable(&dev->dev, wol->wolopts & WAKE_MAGIC);
if (wol->wolopts & WAKE_MAGIC) {
wol_opts |= GFAR_WOL_MAGIC;
} else {
if (wol->wolopts & WAKE_UCAST)
wol_opts |= GFAR_WOL_FILER_UCAST;
}
priv->wol_en = !!device_may_wakeup(&dev->dev);
wol_opts &= priv->wol_supported;
priv->wol_opts = 0;
err = device_set_wakeup_enable(priv->dev, wol_opts);
if (err)
return err;
priv->wol_opts = wol_opts;
return 0;
}

View File

@ -351,8 +351,6 @@ uec_get_drvinfo(struct net_device *netdev,
strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version));
strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
strlcpy(drvinfo->bus_info, "QUICC ENGINE", sizeof(drvinfo->bus_info));
drvinfo->eedump_len = 0;
drvinfo->regdump_len = uec_get_regs_len(netdev);
}
#ifdef CONFIG_PM

View File

@ -24,7 +24,6 @@ config HIX5HD2_GMAC
config HIP04_ETH
tristate "HISILICON P04 Ethernet support"
select PHYLIB
select MARVELL_PHY
select MFD_SYSCON
select HNS_MDIO
@ -33,8 +32,8 @@ config HIP04_ETH
want to use the internal ethernet then you should answer Y to this.
config HNS_MDIO
tristate "Hisilicon HNS MDIO device Support"
select MDIO
tristate
select PHYLIB
---help---
This selects the HNS MDIO support. It is needed by HNS_DSAF to access
the PHY

View File

@ -448,12 +448,12 @@ static ssize_t handles_show(struct device *dev,
s += sprintf(buf + s, "handle %d (eport_id=%u from %s):\n",
i++, h->eport_id, h->dev->name);
for (j = 0; j < h->q_num; j++) {
s += sprintf(buf + s, "\tqueue[%d] on 0x%llx\n",
j, (u64)h->qs[i]->io_base);
#define HANDEL_TX_MSG "\t\ttx_ring on 0x%llx:%u,%u,%u,%u,%u,%llu,%llu\n"
s += sprintf(buf + s, "\tqueue[%d] on %p\n",
j, h->qs[i]->io_base);
#define HANDEL_TX_MSG "\t\ttx_ring on %p:%u,%u,%u,%u,%u,%llu,%llu\n"
s += sprintf(buf + s,
HANDEL_TX_MSG,
(u64)h->qs[i]->tx_ring.io_base,
h->qs[i]->tx_ring.io_base,
h->qs[i]->tx_ring.buf_size,
h->qs[i]->tx_ring.desc_num,
h->qs[i]->tx_ring.max_desc_num_per_pkt,
@ -462,8 +462,8 @@ static ssize_t handles_show(struct device *dev,
h->qs[i]->tx_ring.stats.sw_err_cnt,
h->qs[i]->tx_ring.stats.io_err_cnt);
s += sprintf(buf + s,
"\t\trx_ring on 0x%llx:%u,%u,%llu,%llu,%llu\n",
(u64)h->qs[i]->rx_ring.io_base,
"\t\trx_ring on %p:%u,%u,%llu,%llu,%llu\n",
h->qs[i]->rx_ring.io_base,
h->qs[i]->rx_ring.buf_size,
h->qs[i]->rx_ring.desc_num,
h->qs[i]->rx_ring.stats.sw_err_cnt,

View File

@ -32,6 +32,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/notifier.h>
#include <linux/phy.h>
#include <linux/types.h>
#define HNAE_DRIVER_VERSION "1.3.0"
@ -429,6 +430,7 @@ struct hnae_ae_ops {
void (*set_coalesce_usecs)(struct hnae_handle *handle, u32 timeout);
int (*set_coalesce_frames)(struct hnae_handle *handle,
u32 coalesce_frames);
void (*set_promisc_mode)(struct hnae_handle *handle, u32 en);
int (*get_mac_addr)(struct hnae_handle *handle, void **p);
int (*set_mac_addr)(struct hnae_handle *handle, void *p);
int (*set_mc_addr)(struct hnae_handle *handle, void *addr);

View File

@ -392,6 +392,11 @@ static int hns_ae_set_autoneg(struct hnae_handle *handle, u8 enable)
return hns_mac_set_autoneg(hns_get_mac_cb(handle), enable);
}
static void hns_ae_set_promisc_mode(struct hnae_handle *handle, u32 en)
{
hns_dsaf_set_promisc_mode(hns_ae_get_dsaf_dev(handle->dev), en);
}
static int hns_ae_get_autoneg(struct hnae_handle *handle)
{
u32 auto_neg;
@ -748,6 +753,7 @@ static struct hnae_ae_ops hns_dsaf_ops = {
.get_rx_max_coalesced_frames = hns_ae_get_rx_max_coalesced_frames,
.set_coalesce_usecs = hns_ae_set_coalesce_usecs,
.set_coalesce_frames = hns_ae_set_coalesce_frames,
.set_promisc_mode = hns_ae_set_promisc_mode,
.set_mac_addr = hns_ae_set_mac_address,
.set_mc_addr = hns_ae_set_multicast_one,
.set_mtu = hns_ae_set_mtu,

View File

@ -744,9 +744,11 @@ int hns_mac_get_cfg(struct dsaf_device *dsaf_dev, int mac_idx)
mac_cb->serdes_vaddr = dsaf_dev->sds_base;
if (dsaf_dev->cpld_base &&
mac_idx < DSAF_SERVICE_PORT_NUM_PER_DSAF)
mac_idx < DSAF_SERVICE_PORT_NUM_PER_DSAF) {
mac_cb->cpld_vaddr = dsaf_dev->cpld_base +
mac_cb->mac_id * CPLD_ADDR_PORT_OFFSET;
cpld_led_reset(mac_cb);
}
mac_cb->sfp_prsnt = 0;
mac_cb->txpkt_for_led = 0;
mac_cb->rxpkt_for_led = 0;

View File

@ -217,6 +217,25 @@ hns_dsaf_ppe_qid_cfg(struct dsaf_device *dsaf_dev, u32 qid_cfg)
}
}
static void hns_dsaf_mix_def_qid_cfg(struct dsaf_device *dsaf_dev)
{
u16 max_q_per_vf, max_vfn;
u32 q_id, q_num_per_port;
u32 i;
hns_rcb_get_queue_mode(dsaf_dev->dsaf_mode,
HNS_DSAF_COMM_SERVICE_NW_IDX,
&max_vfn, &max_q_per_vf);
q_num_per_port = max_vfn * max_q_per_vf;
for (i = 0, q_id = 0; i < DSAF_SERVICE_NW_NUM; i++) {
dsaf_set_dev_field(dsaf_dev,
DSAF_MIX_DEF_QID_0_REG + 0x0004 * i,
0xff, 0, q_id);
q_id += q_num_per_port;
}
}
/**
* hns_dsaf_sw_port_type_cfg - cfg sw type
* @dsaf_id: dsa fabric id
@ -592,6 +611,11 @@ static void hns_dsaf_tbl_tcam_data_ucast_pul(
dsaf_write_dev(dsaf_dev, DSAF_TBL_PUL_0_REG, o_tbl_pul);
}
void hns_dsaf_set_promisc_mode(struct dsaf_device *dsaf_dev, u32 en)
{
dsaf_set_dev_bit(dsaf_dev, DSAF_CFG_0_REG, DSAF_CFG_MIX_MODE_S, !!en);
}
/**
* hns_dsaf_tbl_stat_en - tbl
* @dsaf_id: dsa fabric id
@ -920,6 +944,9 @@ static void hns_dsaf_comm_init(struct dsaf_device *dsaf_dev)
/* set 22 queue per tx ppe engine, only used in switch mode */
hns_dsaf_ppe_qid_cfg(dsaf_dev, DSAF_DEFAUTL_QUEUE_NUM_PER_PPE);
/* set promisc def queue id */
hns_dsaf_mix_def_qid_cfg(dsaf_dev);
/* in non switch mode, set all port to access mode */
hns_dsaf_sw_port_type_cfg(dsaf_dev, DSAF_SW_PORT_TYPE_NON_VLAN);

View File

@ -423,5 +423,6 @@ void hns_dsaf_get_strings(int stringset, u8 *data, int port);
void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data);
int hns_dsaf_get_regs_count(void);
void hns_dsaf_set_promisc_mode(struct dsaf_device *dsaf_dev, u32 en);
#endif /* __HNS_DSAF_MAIN_H__ */

View File

@ -575,8 +575,8 @@ int hns_rcb_set_coalesced_frames(struct dsaf_device *dsaf_dev,
*@max_vfn : max vfn number
*@max_q_per_vf:max ring number per vm
*/
static void hns_rcb_get_queue_mode(enum dsaf_mode dsaf_mode, int comm_index,
u16 *max_vfn, u16 *max_q_per_vf)
void hns_rcb_get_queue_mode(enum dsaf_mode dsaf_mode, int comm_index,
u16 *max_vfn, u16 *max_q_per_vf)
{
if (comm_index == HNS_DSAF_COMM_SERVICE_NW_IDX) {
switch (dsaf_mode) {

View File

@ -107,6 +107,8 @@ int hns_rcb_common_init_hw(struct rcb_common_cb *rcb_common);
void hns_rcb_start(struct hnae_queue *q, u32 val);
void hns_rcb_get_cfg(struct rcb_common_cb *rcb_common);
void hns_rcb_common_init_commit_hw(struct rcb_common_cb *rcb_common);
void hns_rcb_get_queue_mode(enum dsaf_mode dsaf_mode, int comm_index,
u16 *max_vfn, u16 *max_q_per_vf);
void hns_rcb_ring_enable_hw(struct hnae_queue *q, u32 val);
void hns_rcb_int_clr_hw(struct hnae_queue *q, u32 flag);

View File

@ -51,9 +51,9 @@ static const struct mac_stats_string g_xgmac_stats_string[] = {
{"xgmac_rx_bad_pkt_from_dsaf", MAC_STATS_FIELD_OFF(rx_bad_from_sw)},
{"xgmac_tx_bad_pkt_64tomax", MAC_STATS_FIELD_OFF(tx_bad_pkts)},
{"xgmac_rx_not_well_pkt", MAC_STATS_FIELD_OFF(rx_fragment_err)},
{"xgmac_rx_good_well_pkt", MAC_STATS_FIELD_OFF(rx_undersize)},
{"xgmac_rx_total_pkt", MAC_STATS_FIELD_OFF(rx_under_min)},
{"xgmac_rx_bad_pkts_minto64", MAC_STATS_FIELD_OFF(rx_fragment_err)},
{"xgmac_rx_good_pkts_minto64", MAC_STATS_FIELD_OFF(rx_undersize)},
{"xgmac_rx_total_pkts_minto64", MAC_STATS_FIELD_OFF(rx_under_min)},
{"xgmac_rx_pkt_64", MAC_STATS_FIELD_OFF(rx_64bytes)},
{"xgmac_rx_pkt_65to127", MAC_STATS_FIELD_OFF(rx_65to127)},
{"xgmac_rx_pkt_128to255", MAC_STATS_FIELD_OFF(rx_128to255)},

View File

@ -1161,6 +1161,21 @@ void hns_set_multicast_list(struct net_device *ndev)
}
}
void hns_nic_set_rx_mode(struct net_device *ndev)
{
struct hns_nic_priv *priv = netdev_priv(ndev);
struct hnae_handle *h = priv->ae_handle;
if (h->dev->ops->set_promisc_mode) {
if (ndev->flags & IFF_PROMISC)
h->dev->ops->set_promisc_mode(h, 1);
else
h->dev->ops->set_promisc_mode(h, 0);
}
hns_set_multicast_list(ndev);
}
struct rtnl_link_stats64 *hns_nic_get_stats64(struct net_device *ndev,
struct rtnl_link_stats64 *stats)
{
@ -1220,7 +1235,7 @@ static const struct net_device_ops hns_nic_netdev_ops = {
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = hns_nic_poll_controller,
#endif
.ndo_set_rx_mode = hns_set_multicast_list,
.ndo_set_rx_mode = hns_nic_set_rx_mode,
};
static void hns_nic_update_link_status(struct net_device *netdev)

View File

@ -682,7 +682,6 @@ static void hns_nic_get_drvinfo(struct net_device *net_dev,
drvinfo->bus_info[ETHTOOL_BUSINFO_LEN - 1] = '\0';
strncpy(drvinfo->fw_version, "N/A", ETHTOOL_FWVERS_LEN);
drvinfo->eedump_len = 0;
}
/**

View File

@ -2204,7 +2204,6 @@ static void emac_ethtool_get_drvinfo(struct net_device *ndev,
strlcpy(info->version, DRV_VERSION, sizeof(info->version));
snprintf(info->bus_info, sizeof(info->bus_info), "PPC 4xx EMAC-%d %s",
dev->cell_index, dev->ofdev->dev.of_node->full_name);
info->regdump_len = emac_ethtool_get_regs_len(ndev);
}
static const struct ethtool_ops emac_ethtool_ops = {

View File

@ -559,8 +559,6 @@ static void e1000_get_drvinfo(struct net_device *netdev,
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
drvinfo->regdump_len = e1000_get_regs_len(netdev);
drvinfo->eedump_len = e1000_get_eeprom_len(netdev);
}
static void e1000_get_ringparam(struct net_device *netdev,

View File

@ -3820,7 +3820,7 @@ static int e1000_clean(struct napi_struct *napi, int budget)
if (work_done < budget) {
if (likely(adapter->itr_setting & 3))
e1000_set_itr(adapter);
napi_complete(napi);
napi_complete_done(napi, work_done);
if (!test_bit(__E1000_DOWN, &adapter->flags))
e1000_irq_enable(adapter);
}

View File

@ -648,8 +648,6 @@ static void e1000_get_drvinfo(struct net_device *netdev,
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
drvinfo->regdump_len = e1000_get_regs_len(netdev);
drvinfo->eedump_len = e1000_get_eeprom_len(netdev);
}
static void e1000_get_ringparam(struct net_device *netdev,

View File

@ -2693,7 +2693,7 @@ static int e1000e_poll(struct napi_struct *napi, int weight)
if (work_done < weight) {
if (adapter->itr_setting & 3)
e1000_set_itr(adapter);
napi_complete(napi);
napi_complete_done(napi, work_done);
if (!test_bit(__E1000_DOWN, &adapter->state)) {
if (adapter->msix_entries)
ew32(IMS, adapter->rx_ring->ims_val);

View File

@ -176,7 +176,7 @@ void fm10k_dbg_q_vector_init(struct fm10k_q_vector *q_vector)
return;
/* Generate a folder for each q_vector */
sprintf(name, "q_vector.%03d", q_vector->v_idx);
snprintf(name, sizeof(name), "q_vector.%03d", q_vector->v_idx);
q_vector->dbg_q_vector = debugfs_create_dir(name, interface->dbg_intfc);
if (!q_vector->dbg_q_vector)
@ -186,7 +186,7 @@ void fm10k_dbg_q_vector_init(struct fm10k_q_vector *q_vector)
for (i = 0; i < q_vector->tx.count; i++) {
struct fm10k_ring *ring = &q_vector->tx.ring[i];
sprintf(name, "tx_ring.%03d", ring->queue_index);
snprintf(name, sizeof(name), "tx_ring.%03d", ring->queue_index);
debugfs_create_file(name, 0600,
q_vector->dbg_q_vector, ring,
@ -197,7 +197,7 @@ void fm10k_dbg_q_vector_init(struct fm10k_q_vector *q_vector)
for (i = 0; i < q_vector->rx.count; i++) {
struct fm10k_ring *ring = &q_vector->rx.ring[i];
sprintf(name, "rx_ring.%03d", ring->queue_index);
snprintf(name, sizeof(name), "rx_ring.%03d", ring->queue_index);
debugfs_create_file(name, 0600,
q_vector->dbg_q_vector, ring,

View File

@ -206,13 +206,13 @@ static void fm10k_get_stat_strings(struct net_device *dev, u8 *data)
}
for (i = 0; i < interface->hw.mac.max_queues; i++) {
sprintf(p, "tx_queue_%u_packets", i);
snprintf(p, ETH_GSTRING_LEN, "tx_queue_%u_packets", i);
p += ETH_GSTRING_LEN;
sprintf(p, "tx_queue_%u_bytes", i);
snprintf(p, ETH_GSTRING_LEN, "tx_queue_%u_bytes", i);
p += ETH_GSTRING_LEN;
sprintf(p, "rx_queue_%u_packets", i);
snprintf(p, ETH_GSTRING_LEN, "rx_queue_%u_packets", i);
p += ETH_GSTRING_LEN;
sprintf(p, "rx_queue_%u_bytes", i);
snprintf(p, ETH_GSTRING_LEN, "rx_queue_%u_bytes", i);
p += ETH_GSTRING_LEN;
}
}
@ -515,10 +515,6 @@ static void fm10k_get_drvinfo(struct net_device *dev,
sizeof(info->version) - 1);
strncpy(info->bus_info, pci_name(interface->pdev),
sizeof(info->bus_info) - 1);
info->n_stats = fm10k_get_sset_count(dev, ETH_SS_STATS);
info->regdump_len = fm10k_get_regs_len(dev);
}
static void fm10k_get_pauseparam(struct net_device *dev,

View File

@ -593,9 +593,9 @@ static void fm10k_receive_skb(struct fm10k_q_vector *q_vector,
napi_gro_receive(&q_vector->napi, skb);
}
static bool fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector,
struct fm10k_ring *rx_ring,
int budget)
static int fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector,
struct fm10k_ring *rx_ring,
int budget)
{
struct sk_buff *skb = rx_ring->skb;
unsigned int total_bytes = 0, total_packets = 0;
@ -662,7 +662,7 @@ static bool fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector,
q_vector->rx.total_packets += total_packets;
q_vector->rx.total_bytes += total_bytes;
return total_packets < budget;
return total_packets;
}
#define VXLAN_HLEN (sizeof(struct udphdr) + 8)
@ -1422,7 +1422,7 @@ static int fm10k_poll(struct napi_struct *napi, int budget)
struct fm10k_q_vector *q_vector =
container_of(napi, struct fm10k_q_vector, napi);
struct fm10k_ring *ring;
int per_ring_budget;
int per_ring_budget, work_done = 0;
bool clean_complete = true;
fm10k_for_each_ring(ring, q_vector->tx)
@ -1436,16 +1436,19 @@ static int fm10k_poll(struct napi_struct *napi, int budget)
else
per_ring_budget = budget;
fm10k_for_each_ring(ring, q_vector->rx)
clean_complete &= fm10k_clean_rx_irq(q_vector, ring,
per_ring_budget);
fm10k_for_each_ring(ring, q_vector->rx) {
int work = fm10k_clean_rx_irq(q_vector, ring, per_ring_budget);
work_done += work;
clean_complete &= !!(work < per_ring_budget);
}
/* If all work not completed, return budget and keep polling */
if (!clean_complete)
return budget;
/* all work done, exit the polling mode */
napi_complete(napi);
napi_complete_done(napi, work_done);
/* re-enable the q_vector */
fm10k_qv_enable(q_vector);
@ -1905,7 +1908,7 @@ static void fm10k_init_reta(struct fm10k_intfc *interface)
u32 reta, base;
/* If the netdev is initialized we have to maintain table if possible */
if (interface->netdev->reg_state) {
if (interface->netdev->reg_state != NETREG_UNINITIALIZED) {
for (i = FM10K_RETA_SIZE; i--;) {
reta = interface->reta[i];
if ((((reta << 24) >> 24) < rss_i) &&

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