mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-28 17:41:50 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: "Lots of bug fixes here: 1) Out of bounds access in __bpf_skc_lookup, from Lorenz Bauer. 2) Fix rate reporting in cfg80211_calculate_bitrate_he(), from John Crispin. 3) Use after free in psock backlog workqueue, from John Fastabend. 4) Fix source port matching in fdb peer flow rule of mlx5, from Raed Salem. 5) Use atomic_inc_not_zero() in fl6_sock_lookup(), from Eric Dumazet. 6) Network header needs to be set for packet redirect in nfp, from John Hurley. 7) Fix udp zerocopy refcnt, from Willem de Bruijn. 8) Don't assume linear buffers in vxlan and geneve error handlers, from Stefano Brivio. 9) Fix TOS matching in mlxsw, from Jiri Pirko. 10) More SCTP cookie memory leak fixes, from Neil Horman. 11) Fix VLAN filtering in rtl8366, from Linus Walluij. 12) Various TCP SACK payload size and fragmentation memory limit fixes from Eric Dumazet. 13) Use after free in pneigh_get_next(), also from Eric Dumazet. 14) LAPB control block leak fix from Jeremy Sowden" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (145 commits) lapb: fixed leak of control-blocks. tipc: purge deferredq list for each grp member in tipc_group_delete ax25: fix inconsistent lock state in ax25_destroy_timer neigh: fix use-after-free read in pneigh_get_next tcp: fix compile error if !CONFIG_SYSCTL hv_sock: Suppress bogus "may be used uninitialized" warnings be2net: Fix number of Rx queues used for flow hashing net: handle 802.1P vlan 0 packets properly tcp: enforce tcp_min_snd_mss in tcp_mtu_probing() tcp: add tcp_min_snd_mss sysctl tcp: tcp_fragment() should apply sane memory limits tcp: limit payload size of sacked skbs Revert "net: phylink: set the autoneg state in phylink_phy_change" bpf: fix nested bpf tracepoints with per-cpu data bpf: Fix out of bounds memory access in bpf_sk_storage vsock/virtio: set SOCK_DONE on peer shutdown net: dsa: rtl8366: Fix up VLAN filtering net: phylink: set the autoneg state in phylink_phy_change net: add high_order_alloc_disable sysctl/static key tcp: add tcp_tx_skb_cache sysctl ...
This commit is contained in:
commit
da0f382029
161 changed files with 2140 additions and 540 deletions
|
@ -29,7 +29,7 @@ Contact: Bjørn Mork <bjorn@mork.no>
|
||||||
Description:
|
Description:
|
||||||
Unsigned integer.
|
Unsigned integer.
|
||||||
|
|
||||||
Write a number ranging from 1 to 127 to add a qmap mux
|
Write a number ranging from 1 to 254 to add a qmap mux
|
||||||
based network device, supported by recent Qualcomm based
|
based network device, supported by recent Qualcomm based
|
||||||
modems.
|
modems.
|
||||||
|
|
||||||
|
@ -46,5 +46,5 @@ Contact: Bjørn Mork <bjorn@mork.no>
|
||||||
Description:
|
Description:
|
||||||
Unsigned integer.
|
Unsigned integer.
|
||||||
|
|
||||||
Write a number ranging from 1 to 127 to delete a previously
|
Write a number ranging from 1 to 254 to delete a previously
|
||||||
created qmap mux based network device.
|
created qmap mux based network device.
|
||||||
|
|
|
@ -4,6 +4,7 @@ Required properties:
|
||||||
- compatible: Should be one of the following:
|
- compatible: Should be one of the following:
|
||||||
- "microchip,mcp2510" for MCP2510.
|
- "microchip,mcp2510" for MCP2510.
|
||||||
- "microchip,mcp2515" for MCP2515.
|
- "microchip,mcp2515" for MCP2515.
|
||||||
|
- "microchip,mcp25625" for MCP25625.
|
||||||
- reg: SPI chip select.
|
- reg: SPI chip select.
|
||||||
- clocks: The clock feeding the CAN controller.
|
- clocks: The clock feeding the CAN controller.
|
||||||
- interrupts: Should contain IRQ line for the CAN controller.
|
- interrupts: Should contain IRQ line for the CAN controller.
|
||||||
|
|
|
@ -255,6 +255,14 @@ tcp_base_mss - INTEGER
|
||||||
Path MTU discovery (MTU probing). If MTU probing is enabled,
|
Path MTU discovery (MTU probing). If MTU probing is enabled,
|
||||||
this is the initial MSS used by the connection.
|
this is the initial MSS used by the connection.
|
||||||
|
|
||||||
|
tcp_min_snd_mss - INTEGER
|
||||||
|
TCP SYN and SYNACK messages usually advertise an ADVMSS option,
|
||||||
|
as described in RFC 1122 and RFC 6691.
|
||||||
|
If this ADVMSS option is smaller than tcp_min_snd_mss,
|
||||||
|
it is silently capped to tcp_min_snd_mss.
|
||||||
|
|
||||||
|
Default : 48 (at least 8 bytes of payload per segment)
|
||||||
|
|
||||||
tcp_congestion_control - STRING
|
tcp_congestion_control - STRING
|
||||||
Set the congestion control algorithm to be used for new
|
Set the congestion control algorithm to be used for new
|
||||||
connections. The algorithm "reno" is always available, but
|
connections. The algorithm "reno" is always available, but
|
||||||
|
@ -772,6 +780,14 @@ tcp_challenge_ack_limit - INTEGER
|
||||||
in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks)
|
in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks)
|
||||||
Default: 100
|
Default: 100
|
||||||
|
|
||||||
|
tcp_rx_skb_cache - BOOLEAN
|
||||||
|
Controls a per TCP socket cache of one skb, that might help
|
||||||
|
performance of some workloads. This might be dangerous
|
||||||
|
on systems with a lot of TCP sockets, since it increases
|
||||||
|
memory usage.
|
||||||
|
|
||||||
|
Default: 0 (disabled)
|
||||||
|
|
||||||
UDP variables:
|
UDP variables:
|
||||||
|
|
||||||
udp_l3mdev_accept - BOOLEAN
|
udp_l3mdev_accept - BOOLEAN
|
||||||
|
|
|
@ -389,7 +389,7 @@ Multipath RDS (mprds)
|
||||||
a common (to all paths) part, and a per-path struct rds_conn_path. All
|
a common (to all paths) part, and a per-path struct rds_conn_path. All
|
||||||
I/O workqs and reconnect threads are driven from the rds_conn_path.
|
I/O workqs and reconnect threads are driven from the rds_conn_path.
|
||||||
Transports such as TCP that are multipath capable may then set up a
|
Transports such as TCP that are multipath capable may then set up a
|
||||||
TPC socket per rds_conn_path, and this is managed by the transport via
|
TCP socket per rds_conn_path, and this is managed by the transport via
|
||||||
the transport privatee cp_transport_data pointer.
|
the transport privatee cp_transport_data pointer.
|
||||||
|
|
||||||
Transports announce themselves as multipath capable by setting the
|
Transports announce themselves as multipath capable by setting the
|
||||||
|
|
|
@ -338,6 +338,7 @@
|
||||||
#define PPC_INST_MADDLD 0x10000033
|
#define PPC_INST_MADDLD 0x10000033
|
||||||
#define PPC_INST_DIVWU 0x7c000396
|
#define PPC_INST_DIVWU 0x7c000396
|
||||||
#define PPC_INST_DIVD 0x7c0003d2
|
#define PPC_INST_DIVD 0x7c0003d2
|
||||||
|
#define PPC_INST_DIVDU 0x7c000392
|
||||||
#define PPC_INST_RLWINM 0x54000000
|
#define PPC_INST_RLWINM 0x54000000
|
||||||
#define PPC_INST_RLWINM_DOT 0x54000001
|
#define PPC_INST_RLWINM_DOT 0x54000001
|
||||||
#define PPC_INST_RLWIMI 0x50000000
|
#define PPC_INST_RLWIMI 0x50000000
|
||||||
|
|
|
@ -112,7 +112,7 @@
|
||||||
___PPC_RA(a) | IMM_L(i))
|
___PPC_RA(a) | IMM_L(i))
|
||||||
#define PPC_DIVWU(d, a, b) EMIT(PPC_INST_DIVWU | ___PPC_RT(d) | \
|
#define PPC_DIVWU(d, a, b) EMIT(PPC_INST_DIVWU | ___PPC_RT(d) | \
|
||||||
___PPC_RA(a) | ___PPC_RB(b))
|
___PPC_RA(a) | ___PPC_RB(b))
|
||||||
#define PPC_DIVD(d, a, b) EMIT(PPC_INST_DIVD | ___PPC_RT(d) | \
|
#define PPC_DIVDU(d, a, b) EMIT(PPC_INST_DIVDU | ___PPC_RT(d) | \
|
||||||
___PPC_RA(a) | ___PPC_RB(b))
|
___PPC_RA(a) | ___PPC_RB(b))
|
||||||
#define PPC_AND(d, a, b) EMIT(PPC_INST_AND | ___PPC_RA(d) | \
|
#define PPC_AND(d, a, b) EMIT(PPC_INST_AND | ___PPC_RA(d) | \
|
||||||
___PPC_RS(a) | ___PPC_RB(b))
|
___PPC_RS(a) | ___PPC_RB(b))
|
||||||
|
|
|
@ -395,12 +395,12 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
|
||||||
case BPF_ALU64 | BPF_DIV | BPF_X: /* dst /= src */
|
case BPF_ALU64 | BPF_DIV | BPF_X: /* dst /= src */
|
||||||
case BPF_ALU64 | BPF_MOD | BPF_X: /* dst %= src */
|
case BPF_ALU64 | BPF_MOD | BPF_X: /* dst %= src */
|
||||||
if (BPF_OP(code) == BPF_MOD) {
|
if (BPF_OP(code) == BPF_MOD) {
|
||||||
PPC_DIVD(b2p[TMP_REG_1], dst_reg, src_reg);
|
PPC_DIVDU(b2p[TMP_REG_1], dst_reg, src_reg);
|
||||||
PPC_MULD(b2p[TMP_REG_1], src_reg,
|
PPC_MULD(b2p[TMP_REG_1], src_reg,
|
||||||
b2p[TMP_REG_1]);
|
b2p[TMP_REG_1]);
|
||||||
PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]);
|
PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]);
|
||||||
} else
|
} else
|
||||||
PPC_DIVD(dst_reg, dst_reg, src_reg);
|
PPC_DIVDU(dst_reg, dst_reg, src_reg);
|
||||||
break;
|
break;
|
||||||
case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */
|
case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */
|
||||||
case BPF_ALU | BPF_DIV | BPF_K: /* (u32) dst /= (u32) imm */
|
case BPF_ALU | BPF_DIV | BPF_K: /* (u32) dst /= (u32) imm */
|
||||||
|
@ -428,7 +428,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
|
||||||
break;
|
break;
|
||||||
case BPF_ALU64:
|
case BPF_ALU64:
|
||||||
if (BPF_OP(code) == BPF_MOD) {
|
if (BPF_OP(code) == BPF_MOD) {
|
||||||
PPC_DIVD(b2p[TMP_REG_2], dst_reg,
|
PPC_DIVDU(b2p[TMP_REG_2], dst_reg,
|
||||||
b2p[TMP_REG_1]);
|
b2p[TMP_REG_1]);
|
||||||
PPC_MULD(b2p[TMP_REG_1],
|
PPC_MULD(b2p[TMP_REG_1],
|
||||||
b2p[TMP_REG_1],
|
b2p[TMP_REG_1],
|
||||||
|
@ -436,7 +436,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
|
||||||
PPC_SUB(dst_reg, dst_reg,
|
PPC_SUB(dst_reg, dst_reg,
|
||||||
b2p[TMP_REG_1]);
|
b2p[TMP_REG_1]);
|
||||||
} else
|
} else
|
||||||
PPC_DIVD(dst_reg, dst_reg,
|
PPC_DIVDU(dst_reg, dst_reg,
|
||||||
b2p[TMP_REG_1]);
|
b2p[TMP_REG_1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -751,22 +751,32 @@ static int emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
|
||||||
case BPF_ALU | BPF_ADD | BPF_X:
|
case BPF_ALU | BPF_ADD | BPF_X:
|
||||||
case BPF_ALU64 | BPF_ADD | BPF_X:
|
case BPF_ALU64 | BPF_ADD | BPF_X:
|
||||||
emit(is64 ? rv_add(rd, rd, rs) : rv_addw(rd, rd, rs), ctx);
|
emit(is64 ? rv_add(rd, rd, rs) : rv_addw(rd, rd, rs), ctx);
|
||||||
|
if (!is64)
|
||||||
|
emit_zext_32(rd, ctx);
|
||||||
break;
|
break;
|
||||||
case BPF_ALU | BPF_SUB | BPF_X:
|
case BPF_ALU | BPF_SUB | BPF_X:
|
||||||
case BPF_ALU64 | BPF_SUB | BPF_X:
|
case BPF_ALU64 | BPF_SUB | BPF_X:
|
||||||
emit(is64 ? rv_sub(rd, rd, rs) : rv_subw(rd, rd, rs), ctx);
|
emit(is64 ? rv_sub(rd, rd, rs) : rv_subw(rd, rd, rs), ctx);
|
||||||
|
if (!is64)
|
||||||
|
emit_zext_32(rd, ctx);
|
||||||
break;
|
break;
|
||||||
case BPF_ALU | BPF_AND | BPF_X:
|
case BPF_ALU | BPF_AND | BPF_X:
|
||||||
case BPF_ALU64 | BPF_AND | BPF_X:
|
case BPF_ALU64 | BPF_AND | BPF_X:
|
||||||
emit(rv_and(rd, rd, rs), ctx);
|
emit(rv_and(rd, rd, rs), ctx);
|
||||||
|
if (!is64)
|
||||||
|
emit_zext_32(rd, ctx);
|
||||||
break;
|
break;
|
||||||
case BPF_ALU | BPF_OR | BPF_X:
|
case BPF_ALU | BPF_OR | BPF_X:
|
||||||
case BPF_ALU64 | BPF_OR | BPF_X:
|
case BPF_ALU64 | BPF_OR | BPF_X:
|
||||||
emit(rv_or(rd, rd, rs), ctx);
|
emit(rv_or(rd, rd, rs), ctx);
|
||||||
|
if (!is64)
|
||||||
|
emit_zext_32(rd, ctx);
|
||||||
break;
|
break;
|
||||||
case BPF_ALU | BPF_XOR | BPF_X:
|
case BPF_ALU | BPF_XOR | BPF_X:
|
||||||
case BPF_ALU64 | BPF_XOR | BPF_X:
|
case BPF_ALU64 | BPF_XOR | BPF_X:
|
||||||
emit(rv_xor(rd, rd, rs), ctx);
|
emit(rv_xor(rd, rd, rs), ctx);
|
||||||
|
if (!is64)
|
||||||
|
emit_zext_32(rd, ctx);
|
||||||
break;
|
break;
|
||||||
case BPF_ALU | BPF_MUL | BPF_X:
|
case BPF_ALU | BPF_MUL | BPF_X:
|
||||||
case BPF_ALU64 | BPF_MUL | BPF_X:
|
case BPF_ALU64 | BPF_MUL | BPF_X:
|
||||||
|
@ -789,14 +799,20 @@ static int emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
|
||||||
case BPF_ALU | BPF_LSH | BPF_X:
|
case BPF_ALU | BPF_LSH | BPF_X:
|
||||||
case BPF_ALU64 | BPF_LSH | BPF_X:
|
case BPF_ALU64 | BPF_LSH | BPF_X:
|
||||||
emit(is64 ? rv_sll(rd, rd, rs) : rv_sllw(rd, rd, rs), ctx);
|
emit(is64 ? rv_sll(rd, rd, rs) : rv_sllw(rd, rd, rs), ctx);
|
||||||
|
if (!is64)
|
||||||
|
emit_zext_32(rd, ctx);
|
||||||
break;
|
break;
|
||||||
case BPF_ALU | BPF_RSH | BPF_X:
|
case BPF_ALU | BPF_RSH | BPF_X:
|
||||||
case BPF_ALU64 | BPF_RSH | BPF_X:
|
case BPF_ALU64 | BPF_RSH | BPF_X:
|
||||||
emit(is64 ? rv_srl(rd, rd, rs) : rv_srlw(rd, rd, rs), ctx);
|
emit(is64 ? rv_srl(rd, rd, rs) : rv_srlw(rd, rd, rs), ctx);
|
||||||
|
if (!is64)
|
||||||
|
emit_zext_32(rd, ctx);
|
||||||
break;
|
break;
|
||||||
case BPF_ALU | BPF_ARSH | BPF_X:
|
case BPF_ALU | BPF_ARSH | BPF_X:
|
||||||
case BPF_ALU64 | BPF_ARSH | BPF_X:
|
case BPF_ALU64 | BPF_ARSH | BPF_X:
|
||||||
emit(is64 ? rv_sra(rd, rd, rs) : rv_sraw(rd, rd, rs), ctx);
|
emit(is64 ? rv_sra(rd, rd, rs) : rv_sraw(rd, rd, rs), ctx);
|
||||||
|
if (!is64)
|
||||||
|
emit_zext_32(rd, ctx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* dst = -dst */
|
/* dst = -dst */
|
||||||
|
@ -804,6 +820,8 @@ static int emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
|
||||||
case BPF_ALU64 | BPF_NEG:
|
case BPF_ALU64 | BPF_NEG:
|
||||||
emit(is64 ? rv_sub(rd, RV_REG_ZERO, rd) :
|
emit(is64 ? rv_sub(rd, RV_REG_ZERO, rd) :
|
||||||
rv_subw(rd, RV_REG_ZERO, rd), ctx);
|
rv_subw(rd, RV_REG_ZERO, rd), ctx);
|
||||||
|
if (!is64)
|
||||||
|
emit_zext_32(rd, ctx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* dst = BSWAP##imm(dst) */
|
/* dst = BSWAP##imm(dst) */
|
||||||
|
@ -958,14 +976,20 @@ out_be:
|
||||||
case BPF_ALU | BPF_LSH | BPF_K:
|
case BPF_ALU | BPF_LSH | BPF_K:
|
||||||
case BPF_ALU64 | BPF_LSH | BPF_K:
|
case BPF_ALU64 | BPF_LSH | BPF_K:
|
||||||
emit(is64 ? rv_slli(rd, rd, imm) : rv_slliw(rd, rd, imm), ctx);
|
emit(is64 ? rv_slli(rd, rd, imm) : rv_slliw(rd, rd, imm), ctx);
|
||||||
|
if (!is64)
|
||||||
|
emit_zext_32(rd, ctx);
|
||||||
break;
|
break;
|
||||||
case BPF_ALU | BPF_RSH | BPF_K:
|
case BPF_ALU | BPF_RSH | BPF_K:
|
||||||
case BPF_ALU64 | BPF_RSH | BPF_K:
|
case BPF_ALU64 | BPF_RSH | BPF_K:
|
||||||
emit(is64 ? rv_srli(rd, rd, imm) : rv_srliw(rd, rd, imm), ctx);
|
emit(is64 ? rv_srli(rd, rd, imm) : rv_srliw(rd, rd, imm), ctx);
|
||||||
|
if (!is64)
|
||||||
|
emit_zext_32(rd, ctx);
|
||||||
break;
|
break;
|
||||||
case BPF_ALU | BPF_ARSH | BPF_K:
|
case BPF_ALU | BPF_ARSH | BPF_K:
|
||||||
case BPF_ALU64 | BPF_ARSH | BPF_K:
|
case BPF_ALU64 | BPF_ARSH | BPF_K:
|
||||||
emit(is64 ? rv_srai(rd, rd, imm) : rv_sraiw(rd, rd, imm), ctx);
|
emit(is64 ? rv_srai(rd, rd, imm) : rv_sraiw(rd, rd, imm), ctx);
|
||||||
|
if (!is64)
|
||||||
|
emit_zext_32(rd, ctx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* JUMP off */
|
/* JUMP off */
|
||||||
|
|
|
@ -186,9 +186,7 @@ struct jit_context {
|
||||||
#define BPF_MAX_INSN_SIZE 128
|
#define BPF_MAX_INSN_SIZE 128
|
||||||
#define BPF_INSN_SAFETY 64
|
#define BPF_INSN_SAFETY 64
|
||||||
|
|
||||||
#define AUX_STACK_SPACE 40 /* Space for RBX, R13, R14, R15, tailcnt */
|
#define PROLOGUE_SIZE 20
|
||||||
|
|
||||||
#define PROLOGUE_SIZE 37
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Emit x86-64 prologue code for BPF program and check its size.
|
* Emit x86-64 prologue code for BPF program and check its size.
|
||||||
|
@ -199,44 +197,19 @@ static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf)
|
||||||
u8 *prog = *pprog;
|
u8 *prog = *pprog;
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
||||||
/* push rbp */
|
EMIT1(0x55); /* push rbp */
|
||||||
EMIT1(0x55);
|
EMIT3(0x48, 0x89, 0xE5); /* mov rbp, rsp */
|
||||||
|
/* sub rsp, rounded_stack_depth */
|
||||||
/* mov rbp,rsp */
|
EMIT3_off32(0x48, 0x81, 0xEC, round_up(stack_depth, 8));
|
||||||
EMIT3(0x48, 0x89, 0xE5);
|
EMIT1(0x53); /* push rbx */
|
||||||
|
EMIT2(0x41, 0x55); /* push r13 */
|
||||||
/* sub rsp, rounded_stack_depth + AUX_STACK_SPACE */
|
EMIT2(0x41, 0x56); /* push r14 */
|
||||||
EMIT3_off32(0x48, 0x81, 0xEC,
|
EMIT2(0x41, 0x57); /* push r15 */
|
||||||
round_up(stack_depth, 8) + AUX_STACK_SPACE);
|
|
||||||
|
|
||||||
/* sub rbp, AUX_STACK_SPACE */
|
|
||||||
EMIT4(0x48, 0x83, 0xED, AUX_STACK_SPACE);
|
|
||||||
|
|
||||||
/* mov qword ptr [rbp+0],rbx */
|
|
||||||
EMIT4(0x48, 0x89, 0x5D, 0);
|
|
||||||
/* mov qword ptr [rbp+8],r13 */
|
|
||||||
EMIT4(0x4C, 0x89, 0x6D, 8);
|
|
||||||
/* mov qword ptr [rbp+16],r14 */
|
|
||||||
EMIT4(0x4C, 0x89, 0x75, 16);
|
|
||||||
/* mov qword ptr [rbp+24],r15 */
|
|
||||||
EMIT4(0x4C, 0x89, 0x7D, 24);
|
|
||||||
|
|
||||||
if (!ebpf_from_cbpf) {
|
if (!ebpf_from_cbpf) {
|
||||||
/*
|
/* zero init tail_call_cnt */
|
||||||
* Clear the tail call counter (tail_call_cnt): for eBPF tail
|
EMIT2(0x6a, 0x00);
|
||||||
* calls we need to reset the counter to 0. It's done in two
|
|
||||||
* instructions, resetting RAX register to 0, and moving it
|
|
||||||
* to the counter location.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* xor eax, eax */
|
|
||||||
EMIT2(0x31, 0xc0);
|
|
||||||
/* mov qword ptr [rbp+32], rax */
|
|
||||||
EMIT4(0x48, 0x89, 0x45, 32);
|
|
||||||
|
|
||||||
BUILD_BUG_ON(cnt != PROLOGUE_SIZE);
|
BUILD_BUG_ON(cnt != PROLOGUE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
*pprog = prog;
|
*pprog = prog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,13 +254,13 @@ static void emit_bpf_tail_call(u8 **pprog)
|
||||||
* if (tail_call_cnt > MAX_TAIL_CALL_CNT)
|
* if (tail_call_cnt > MAX_TAIL_CALL_CNT)
|
||||||
* goto out;
|
* goto out;
|
||||||
*/
|
*/
|
||||||
EMIT2_off32(0x8B, 0x85, 36); /* mov eax, dword ptr [rbp + 36] */
|
EMIT2_off32(0x8B, 0x85, -36 - MAX_BPF_STACK); /* mov eax, dword ptr [rbp - 548] */
|
||||||
EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT); /* cmp eax, MAX_TAIL_CALL_CNT */
|
EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT); /* cmp eax, MAX_TAIL_CALL_CNT */
|
||||||
#define OFFSET2 (30 + RETPOLINE_RAX_BPF_JIT_SIZE)
|
#define OFFSET2 (30 + RETPOLINE_RAX_BPF_JIT_SIZE)
|
||||||
EMIT2(X86_JA, OFFSET2); /* ja out */
|
EMIT2(X86_JA, OFFSET2); /* ja out */
|
||||||
label2 = cnt;
|
label2 = cnt;
|
||||||
EMIT3(0x83, 0xC0, 0x01); /* add eax, 1 */
|
EMIT3(0x83, 0xC0, 0x01); /* add eax, 1 */
|
||||||
EMIT2_off32(0x89, 0x85, 36); /* mov dword ptr [rbp + 36], eax */
|
EMIT2_off32(0x89, 0x85, -36 - MAX_BPF_STACK); /* mov dword ptr [rbp -548], eax */
|
||||||
|
|
||||||
/* prog = array->ptrs[index]; */
|
/* prog = array->ptrs[index]; */
|
||||||
EMIT4_off32(0x48, 0x8B, 0x84, 0xD6, /* mov rax, [rsi + rdx * 8 + offsetof(...)] */
|
EMIT4_off32(0x48, 0x8B, 0x84, 0xD6, /* mov rax, [rsi + rdx * 8 + offsetof(...)] */
|
||||||
|
@ -1036,17 +1009,12 @@ emit_jmp:
|
||||||
seen_exit = true;
|
seen_exit = true;
|
||||||
/* Update cleanup_addr */
|
/* Update cleanup_addr */
|
||||||
ctx->cleanup_addr = proglen;
|
ctx->cleanup_addr = proglen;
|
||||||
/* mov rbx, qword ptr [rbp+0] */
|
if (!bpf_prog_was_classic(bpf_prog))
|
||||||
EMIT4(0x48, 0x8B, 0x5D, 0);
|
EMIT1(0x5B); /* get rid of tail_call_cnt */
|
||||||
/* mov r13, qword ptr [rbp+8] */
|
EMIT2(0x41, 0x5F); /* pop r15 */
|
||||||
EMIT4(0x4C, 0x8B, 0x6D, 8);
|
EMIT2(0x41, 0x5E); /* pop r14 */
|
||||||
/* mov r14, qword ptr [rbp+16] */
|
EMIT2(0x41, 0x5D); /* pop r13 */
|
||||||
EMIT4(0x4C, 0x8B, 0x75, 16);
|
EMIT1(0x5B); /* pop rbx */
|
||||||
/* mov r15, qword ptr [rbp+24] */
|
|
||||||
EMIT4(0x4C, 0x8B, 0x7D, 24);
|
|
||||||
|
|
||||||
/* add rbp, AUX_STACK_SPACE */
|
|
||||||
EMIT4(0x48, 0x83, 0xC5, AUX_STACK_SPACE);
|
|
||||||
EMIT1(0xC9); /* leave */
|
EMIT1(0xC9); /* leave */
|
||||||
EMIT1(0xC3); /* ret */
|
EMIT1(0xC3); /* ret */
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -166,7 +166,7 @@
|
||||||
#define FLEXCAN_MB_CNT_LENGTH(x) (((x) & 0xf) << 16)
|
#define FLEXCAN_MB_CNT_LENGTH(x) (((x) & 0xf) << 16)
|
||||||
#define FLEXCAN_MB_CNT_TIMESTAMP(x) ((x) & 0xffff)
|
#define FLEXCAN_MB_CNT_TIMESTAMP(x) ((x) & 0xffff)
|
||||||
|
|
||||||
#define FLEXCAN_TIMEOUT_US (50)
|
#define FLEXCAN_TIMEOUT_US (250)
|
||||||
|
|
||||||
/* FLEXCAN hardware feature flags
|
/* FLEXCAN hardware feature flags
|
||||||
*
|
*
|
||||||
|
@ -1583,9 +1583,6 @@ static int flexcan_probe(struct platform_device *pdev)
|
||||||
dev_dbg(&pdev->dev, "failed to setup stop-mode\n");
|
dev_dbg(&pdev->dev, "failed to setup stop-mode\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n",
|
|
||||||
priv->regs, dev->irq);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
failed_register:
|
failed_register:
|
||||||
|
|
|
@ -822,6 +822,27 @@ static int m_can_poll(struct napi_struct *napi, int quota)
|
||||||
if (!irqstatus)
|
if (!irqstatus)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
/* Errata workaround for issue "Needless activation of MRAF irq"
|
||||||
|
* During frame reception while the MCAN is in Error Passive state
|
||||||
|
* and the Receive Error Counter has the value MCAN_ECR.REC = 127,
|
||||||
|
* it may happen that MCAN_IR.MRAF is set although there was no
|
||||||
|
* Message RAM access failure.
|
||||||
|
* If MCAN_IR.MRAF is enabled, an interrupt to the Host CPU is generated
|
||||||
|
* The Message RAM Access Failure interrupt routine needs to check
|
||||||
|
* whether MCAN_ECR.RP = ’1’ and MCAN_ECR.REC = 127.
|
||||||
|
* In this case, reset MCAN_IR.MRAF. No further action is required.
|
||||||
|
*/
|
||||||
|
if ((priv->version <= 31) && (irqstatus & IR_MRAF) &&
|
||||||
|
(m_can_read(priv, M_CAN_ECR) & ECR_RP)) {
|
||||||
|
struct can_berr_counter bec;
|
||||||
|
|
||||||
|
__m_can_get_berr_counter(dev, &bec);
|
||||||
|
if (bec.rxerr == 127) {
|
||||||
|
m_can_write(priv, M_CAN_IR, IR_MRAF);
|
||||||
|
irqstatus &= ~IR_MRAF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
psr = m_can_read(priv, M_CAN_PSR);
|
psr = m_can_read(priv, M_CAN_PSR);
|
||||||
if (irqstatus & IR_ERR_STATE)
|
if (irqstatus & IR_ERR_STATE)
|
||||||
work_done += m_can_handle_state_errors(dev, psr);
|
work_done += m_can_handle_state_errors(dev, psr);
|
||||||
|
|
|
@ -9,9 +9,10 @@ config CAN_HI311X
|
||||||
Driver for the Holt HI311x SPI CAN controllers.
|
Driver for the Holt HI311x SPI CAN controllers.
|
||||||
|
|
||||||
config CAN_MCP251X
|
config CAN_MCP251X
|
||||||
tristate "Microchip MCP251x SPI CAN controllers"
|
tristate "Microchip MCP251x and MCP25625 SPI CAN controllers"
|
||||||
depends on HAS_DMA
|
depends on HAS_DMA
|
||||||
---help---
|
---help---
|
||||||
Driver for the Microchip MCP251x SPI CAN controllers.
|
Driver for the Microchip MCP251x and MCP25625 SPI CAN
|
||||||
|
controllers.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* CAN bus driver for Microchip 251x CAN Controller with SPI Interface
|
* CAN bus driver for Microchip 251x/25625 CAN Controller with SPI Interface
|
||||||
*
|
*
|
||||||
* MCP2510 support and bug fixes by Christian Pellegrin
|
* MCP2510 support and bug fixes by Christian Pellegrin
|
||||||
* <chripell@evolware.org>
|
* <chripell@evolware.org>
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
* static struct spi_board_info spi_board_info[] = {
|
* static struct spi_board_info spi_board_info[] = {
|
||||||
* {
|
* {
|
||||||
* .modalias = "mcp2510",
|
* .modalias = "mcp2510",
|
||||||
* // or "mcp2515" depending on your controller
|
* // "mcp2515" or "mcp25625" depending on your controller
|
||||||
* .platform_data = &mcp251x_info,
|
* .platform_data = &mcp251x_info,
|
||||||
* .irq = IRQ_EINT13,
|
* .irq = IRQ_EINT13,
|
||||||
* .max_speed_hz = 2*1000*1000,
|
* .max_speed_hz = 2*1000*1000,
|
||||||
|
@ -224,6 +224,7 @@ static const struct can_bittiming_const mcp251x_bittiming_const = {
|
||||||
enum mcp251x_model {
|
enum mcp251x_model {
|
||||||
CAN_MCP251X_MCP2510 = 0x2510,
|
CAN_MCP251X_MCP2510 = 0x2510,
|
||||||
CAN_MCP251X_MCP2515 = 0x2515,
|
CAN_MCP251X_MCP2515 = 0x2515,
|
||||||
|
CAN_MCP251X_MCP25625 = 0x25625,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mcp251x_priv {
|
struct mcp251x_priv {
|
||||||
|
@ -266,7 +267,6 @@ static inline int mcp251x_is_##_model(struct spi_device *spi) \
|
||||||
}
|
}
|
||||||
|
|
||||||
MCP251X_IS(2510);
|
MCP251X_IS(2510);
|
||||||
MCP251X_IS(2515);
|
|
||||||
|
|
||||||
static void mcp251x_clean(struct net_device *net)
|
static void mcp251x_clean(struct net_device *net)
|
||||||
{
|
{
|
||||||
|
@ -806,9 +806,8 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
|
||||||
/* receive buffer 0 */
|
/* receive buffer 0 */
|
||||||
if (intf & CANINTF_RX0IF) {
|
if (intf & CANINTF_RX0IF) {
|
||||||
mcp251x_hw_rx(spi, 0);
|
mcp251x_hw_rx(spi, 0);
|
||||||
/*
|
/* Free one buffer ASAP
|
||||||
* Free one buffer ASAP
|
* (The MCP2515/25625 does this automatically.)
|
||||||
* (The MCP2515 does this automatically.)
|
|
||||||
*/
|
*/
|
||||||
if (mcp251x_is_2510(spi))
|
if (mcp251x_is_2510(spi))
|
||||||
mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00);
|
mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00);
|
||||||
|
@ -817,7 +816,7 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
|
||||||
/* receive buffer 1 */
|
/* receive buffer 1 */
|
||||||
if (intf & CANINTF_RX1IF) {
|
if (intf & CANINTF_RX1IF) {
|
||||||
mcp251x_hw_rx(spi, 1);
|
mcp251x_hw_rx(spi, 1);
|
||||||
/* the MCP2515 does this automatically */
|
/* The MCP2515/25625 does this automatically. */
|
||||||
if (mcp251x_is_2510(spi))
|
if (mcp251x_is_2510(spi))
|
||||||
clear_intf |= CANINTF_RX1IF;
|
clear_intf |= CANINTF_RX1IF;
|
||||||
}
|
}
|
||||||
|
@ -992,6 +991,10 @@ static const struct of_device_id mcp251x_of_match[] = {
|
||||||
.compatible = "microchip,mcp2515",
|
.compatible = "microchip,mcp2515",
|
||||||
.data = (void *)CAN_MCP251X_MCP2515,
|
.data = (void *)CAN_MCP251X_MCP2515,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.compatible = "microchip,mcp25625",
|
||||||
|
.data = (void *)CAN_MCP251X_MCP25625,
|
||||||
|
},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, mcp251x_of_match);
|
MODULE_DEVICE_TABLE(of, mcp251x_of_match);
|
||||||
|
@ -1005,6 +1008,10 @@ static const struct spi_device_id mcp251x_id_table[] = {
|
||||||
.name = "mcp2515",
|
.name = "mcp2515",
|
||||||
.driver_data = (kernel_ulong_t)CAN_MCP251X_MCP2515,
|
.driver_data = (kernel_ulong_t)CAN_MCP251X_MCP2515,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "mcp25625",
|
||||||
|
.driver_data = (kernel_ulong_t)CAN_MCP251X_MCP25625,
|
||||||
|
},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(spi, mcp251x_id_table);
|
MODULE_DEVICE_TABLE(spi, mcp251x_id_table);
|
||||||
|
@ -1245,5 +1252,5 @@ module_spi_driver(mcp251x_can_driver);
|
||||||
|
|
||||||
MODULE_AUTHOR("Chris Elston <celston@katalix.com>, "
|
MODULE_AUTHOR("Chris Elston <celston@katalix.com>, "
|
||||||
"Christian Pellegrin <chripell@evolware.org>");
|
"Christian Pellegrin <chripell@evolware.org>");
|
||||||
MODULE_DESCRIPTION("Microchip 251x CAN driver");
|
MODULE_DESCRIPTION("Microchip 251x/25625 CAN driver");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
|
|
|
@ -102,12 +102,6 @@ config CAN_PEAK_USB
|
||||||
|
|
||||||
(see also http://www.peak-system.com).
|
(see also http://www.peak-system.com).
|
||||||
|
|
||||||
config CAN_MCBA_USB
|
|
||||||
tristate "Microchip CAN BUS Analyzer interface"
|
|
||||||
---help---
|
|
||||||
This driver supports the CAN BUS Analyzer interface
|
|
||||||
from Microchip (http://www.microchip.com/development-tools/).
|
|
||||||
|
|
||||||
config CAN_UCAN
|
config CAN_UCAN
|
||||||
tristate "Theobroma Systems UCAN interface"
|
tristate "Theobroma Systems UCAN interface"
|
||||||
---help---
|
---help---
|
||||||
|
|
|
@ -1435,7 +1435,7 @@ static const struct xcan_devtype_data xcan_canfd_data = {
|
||||||
XCAN_FLAG_RXMNF |
|
XCAN_FLAG_RXMNF |
|
||||||
XCAN_FLAG_TX_MAILBOXES |
|
XCAN_FLAG_TX_MAILBOXES |
|
||||||
XCAN_FLAG_RX_FIFO_MULTI,
|
XCAN_FLAG_RX_FIFO_MULTI,
|
||||||
.bittiming_const = &xcan_bittiming_const,
|
.bittiming_const = &xcan_bittiming_const_canfd,
|
||||||
.btr_ts2_shift = XCAN_BTR_TS2_SHIFT_CANFD,
|
.btr_ts2_shift = XCAN_BTR_TS2_SHIFT_CANFD,
|
||||||
.btr_sjw_shift = XCAN_BTR_SJW_SHIFT_CANFD,
|
.btr_sjw_shift = XCAN_BTR_SJW_SHIFT_CANFD,
|
||||||
.bus_clk_name = "s_axi_aclk",
|
.bus_clk_name = "s_axi_aclk",
|
||||||
|
|
|
@ -9,8 +9,8 @@ obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
|
||||||
obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
|
obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
|
||||||
obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
|
obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
|
||||||
obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o
|
obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o
|
||||||
obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek.o
|
obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o
|
||||||
realtek-objs := realtek-smi.o rtl8366.o rtl8366rb.o
|
realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o
|
||||||
obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
|
obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
|
||||||
obj-$(CONFIG_NET_DSA_SMSC_LAN9303_I2C) += lan9303_i2c.o
|
obj-$(CONFIG_NET_DSA_SMSC_LAN9303_I2C) += lan9303_i2c.o
|
||||||
obj-$(CONFIG_NET_DSA_SMSC_LAN9303_MDIO) += lan9303_mdio.o
|
obj-$(CONFIG_NET_DSA_SMSC_LAN9303_MDIO) += lan9303_mdio.o
|
||||||
|
|
|
@ -83,6 +83,9 @@ static void ksz_mib_read_work(struct work_struct *work)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < dev->mib_port_cnt; i++) {
|
for (i = 0; i < dev->mib_port_cnt; i++) {
|
||||||
|
if (dsa_is_unused_port(dev->ds, i))
|
||||||
|
continue;
|
||||||
|
|
||||||
p = &dev->ports[i];
|
p = &dev->ports[i];
|
||||||
mib = &p->mib;
|
mib = &p->mib;
|
||||||
mutex_lock(&mib->cnt_mutex);
|
mutex_lock(&mib->cnt_mutex);
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/if_bridge.h>
|
#include <linux/if_bridge.h>
|
||||||
|
|
||||||
#include "realtek-smi.h"
|
#include "realtek-smi-core.h"
|
||||||
|
|
||||||
#define REALTEK_SMI_ACK_RETRY_COUNT 5
|
#define REALTEK_SMI_ACK_RETRY_COUNT 5
|
||||||
#define REALTEK_SMI_HW_STOP_DELAY 25 /* msecs */
|
#define REALTEK_SMI_HW_STOP_DELAY 25 /* msecs */
|
|
@ -11,7 +11,7 @@
|
||||||
#include <linux/if_bridge.h>
|
#include <linux/if_bridge.h>
|
||||||
#include <net/dsa.h>
|
#include <net/dsa.h>
|
||||||
|
|
||||||
#include "realtek-smi.h"
|
#include "realtek-smi-core.h"
|
||||||
|
|
||||||
int rtl8366_mc_is_used(struct realtek_smi *smi, int mc_index, int *used)
|
int rtl8366_mc_is_used(struct realtek_smi *smi, int mc_index, int *used)
|
||||||
{
|
{
|
||||||
|
@ -307,7 +307,8 @@ int rtl8366_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering)
|
||||||
struct rtl8366_vlan_4k vlan4k;
|
struct rtl8366_vlan_4k vlan4k;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!smi->ops->is_vlan_valid(smi, port))
|
/* Use VLAN nr port + 1 since VLAN0 is not valid */
|
||||||
|
if (!smi->ops->is_vlan_valid(smi, port + 1))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
dev_info(smi->dev, "%s filtering on port %d\n",
|
dev_info(smi->dev, "%s filtering on port %d\n",
|
||||||
|
@ -318,12 +319,12 @@ int rtl8366_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering)
|
||||||
* The hardware support filter ID (FID) 0..7, I have no clue how to
|
* The hardware support filter ID (FID) 0..7, I have no clue how to
|
||||||
* support this in the driver when the callback only says on/off.
|
* support this in the driver when the callback only says on/off.
|
||||||
*/
|
*/
|
||||||
ret = smi->ops->get_vlan_4k(smi, port, &vlan4k);
|
ret = smi->ops->get_vlan_4k(smi, port + 1, &vlan4k);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Just set the filter to FID 1 for now then */
|
/* Just set the filter to FID 1 for now then */
|
||||||
ret = rtl8366_set_vlan(smi, port,
|
ret = rtl8366_set_vlan(smi, port + 1,
|
||||||
vlan4k.member,
|
vlan4k.member,
|
||||||
vlan4k.untag,
|
vlan4k.untag,
|
||||||
1);
|
1);
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include <linux/of_irq.h>
|
#include <linux/of_irq.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
|
|
||||||
#include "realtek-smi.h"
|
#include "realtek-smi-core.h"
|
||||||
|
|
||||||
#define RTL8366RB_PORT_NUM_CPU 5
|
#define RTL8366RB_PORT_NUM_CPU 5
|
||||||
#define RTL8366RB_NUM_PORTS 6
|
#define RTL8366RB_NUM_PORTS 6
|
||||||
|
|
|
@ -50,7 +50,7 @@ config XSURF100
|
||||||
tristate "Amiga XSurf 100 AX88796/NE2000 clone support"
|
tristate "Amiga XSurf 100 AX88796/NE2000 clone support"
|
||||||
depends on ZORRO
|
depends on ZORRO
|
||||||
select AX88796
|
select AX88796
|
||||||
select ASIX_PHY
|
select AX88796B_PHY
|
||||||
help
|
help
|
||||||
This driver is for the Individual Computers X-Surf 100 Ethernet
|
This driver is for the Individual Computers X-Surf 100 Ethernet
|
||||||
card (based on the Asix AX88796 chip). If you have such a card,
|
card (based on the Asix AX88796 chip). If you have such a card,
|
||||||
|
|
|
@ -1101,7 +1101,7 @@ static int be_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
|
||||||
cmd->data = be_get_rss_hash_opts(adapter, cmd->flow_type);
|
cmd->data = be_get_rss_hash_opts(adapter, cmd->flow_type);
|
||||||
break;
|
break;
|
||||||
case ETHTOOL_GRXRINGS:
|
case ETHTOOL_GRXRINGS:
|
||||||
cmd->data = adapter->num_rx_qs - 1;
|
cmd->data = adapter->num_rx_qs;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -428,7 +428,8 @@ static int reset_rx_pools(struct ibmvnic_adapter *adapter)
|
||||||
if (rx_pool->buff_size != be64_to_cpu(size_array[i])) {
|
if (rx_pool->buff_size != be64_to_cpu(size_array[i])) {
|
||||||
free_long_term_buff(adapter, &rx_pool->long_term_buff);
|
free_long_term_buff(adapter, &rx_pool->long_term_buff);
|
||||||
rx_pool->buff_size = be64_to_cpu(size_array[i]);
|
rx_pool->buff_size = be64_to_cpu(size_array[i]);
|
||||||
alloc_long_term_buff(adapter, &rx_pool->long_term_buff,
|
rc = alloc_long_term_buff(adapter,
|
||||||
|
&rx_pool->long_term_buff,
|
||||||
rx_pool->size *
|
rx_pool->size *
|
||||||
rx_pool->buff_size);
|
rx_pool->buff_size);
|
||||||
} else {
|
} else {
|
||||||
|
@ -696,7 +697,7 @@ static int init_tx_pools(struct net_device *netdev)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_one_tx_pool(netdev, &adapter->tso_pool[i],
|
rc = init_one_tx_pool(netdev, &adapter->tso_pool[i],
|
||||||
IBMVNIC_TSO_BUFS,
|
IBMVNIC_TSO_BUFS,
|
||||||
IBMVNIC_TSO_BUF_SZ);
|
IBMVNIC_TSO_BUF_SZ);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@ -1745,7 +1746,8 @@ static int do_reset(struct ibmvnic_adapter *adapter,
|
||||||
|
|
||||||
ibmvnic_cleanup(netdev);
|
ibmvnic_cleanup(netdev);
|
||||||
|
|
||||||
if (adapter->reset_reason != VNIC_RESET_MOBILITY &&
|
if (reset_state == VNIC_OPEN &&
|
||||||
|
adapter->reset_reason != VNIC_RESET_MOBILITY &&
|
||||||
adapter->reset_reason != VNIC_RESET_FAILOVER) {
|
adapter->reset_reason != VNIC_RESET_FAILOVER) {
|
||||||
rc = __ibmvnic_close(netdev);
|
rc = __ibmvnic_close(netdev);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -1844,6 +1846,9 @@ static int do_reset(struct ibmvnic_adapter *adapter,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* refresh device's multicast list */
|
||||||
|
ibmvnic_set_multi(netdev);
|
||||||
|
|
||||||
/* kick napi */
|
/* kick napi */
|
||||||
for (i = 0; i < adapter->req_rx_queues; i++)
|
for (i = 0; i < adapter->req_rx_queues; i++)
|
||||||
napi_schedule(&adapter->napi[i]);
|
napi_schedule(&adapter->napi[i]);
|
||||||
|
|
|
@ -1905,8 +1905,7 @@ static int mvpp2_prs_ip6_init(struct mvpp2 *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find tcam entry with matched pair <vid,port> */
|
/* Find tcam entry with matched pair <vid,port> */
|
||||||
static int mvpp2_prs_vid_range_find(struct mvpp2 *priv, int pmap, u16 vid,
|
static int mvpp2_prs_vid_range_find(struct mvpp2_port *port, u16 vid, u16 mask)
|
||||||
u16 mask)
|
|
||||||
{
|
{
|
||||||
unsigned char byte[2], enable[2];
|
unsigned char byte[2], enable[2];
|
||||||
struct mvpp2_prs_entry pe;
|
struct mvpp2_prs_entry pe;
|
||||||
|
@ -1914,13 +1913,13 @@ static int mvpp2_prs_vid_range_find(struct mvpp2 *priv, int pmap, u16 vid,
|
||||||
int tid;
|
int tid;
|
||||||
|
|
||||||
/* Go through the all entries with MVPP2_PRS_LU_VID */
|
/* Go through the all entries with MVPP2_PRS_LU_VID */
|
||||||
for (tid = MVPP2_PE_VID_FILT_RANGE_START;
|
for (tid = MVPP2_PRS_VID_PORT_FIRST(port->id);
|
||||||
tid <= MVPP2_PE_VID_FILT_RANGE_END; tid++) {
|
tid <= MVPP2_PRS_VID_PORT_LAST(port->id); tid++) {
|
||||||
if (!priv->prs_shadow[tid].valid ||
|
if (!port->priv->prs_shadow[tid].valid ||
|
||||||
priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VID)
|
port->priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VID)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mvpp2_prs_init_from_hw(priv, &pe, tid);
|
mvpp2_prs_init_from_hw(port->priv, &pe, tid);
|
||||||
|
|
||||||
mvpp2_prs_tcam_data_byte_get(&pe, 2, &byte[0], &enable[0]);
|
mvpp2_prs_tcam_data_byte_get(&pe, 2, &byte[0], &enable[0]);
|
||||||
mvpp2_prs_tcam_data_byte_get(&pe, 3, &byte[1], &enable[1]);
|
mvpp2_prs_tcam_data_byte_get(&pe, 3, &byte[1], &enable[1]);
|
||||||
|
@ -1950,7 +1949,7 @@ int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
|
||||||
memset(&pe, 0, sizeof(pe));
|
memset(&pe, 0, sizeof(pe));
|
||||||
|
|
||||||
/* Scan TCAM and see if entry with this <vid,port> already exist */
|
/* Scan TCAM and see if entry with this <vid,port> already exist */
|
||||||
tid = mvpp2_prs_vid_range_find(priv, (1 << port->id), vid, mask);
|
tid = mvpp2_prs_vid_range_find(port, vid, mask);
|
||||||
|
|
||||||
reg_val = mvpp2_read(priv, MVPP2_MH_REG(port->id));
|
reg_val = mvpp2_read(priv, MVPP2_MH_REG(port->id));
|
||||||
if (reg_val & MVPP2_DSA_EXTENDED)
|
if (reg_val & MVPP2_DSA_EXTENDED)
|
||||||
|
@ -2008,7 +2007,7 @@ void mvpp2_prs_vid_entry_remove(struct mvpp2_port *port, u16 vid)
|
||||||
int tid;
|
int tid;
|
||||||
|
|
||||||
/* Scan TCAM and see if entry with this <vid,port> already exist */
|
/* Scan TCAM and see if entry with this <vid,port> already exist */
|
||||||
tid = mvpp2_prs_vid_range_find(priv, (1 << port->id), vid, 0xfff);
|
tid = mvpp2_prs_vid_range_find(port, vid, 0xfff);
|
||||||
|
|
||||||
/* No such entry */
|
/* No such entry */
|
||||||
if (tid < 0)
|
if (tid < 0)
|
||||||
|
@ -2026,8 +2025,10 @@ void mvpp2_prs_vid_remove_all(struct mvpp2_port *port)
|
||||||
|
|
||||||
for (tid = MVPP2_PRS_VID_PORT_FIRST(port->id);
|
for (tid = MVPP2_PRS_VID_PORT_FIRST(port->id);
|
||||||
tid <= MVPP2_PRS_VID_PORT_LAST(port->id); tid++) {
|
tid <= MVPP2_PRS_VID_PORT_LAST(port->id); tid++) {
|
||||||
if (priv->prs_shadow[tid].valid)
|
if (priv->prs_shadow[tid].valid) {
|
||||||
mvpp2_prs_vid_entry_remove(port, tid);
|
mvpp2_prs_hw_inv(priv, tid);
|
||||||
|
priv->prs_shadow[tid].valid = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -441,6 +441,10 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
|
||||||
case MLX5_CMD_OP_CREATE_GENERAL_OBJECT:
|
case MLX5_CMD_OP_CREATE_GENERAL_OBJECT:
|
||||||
case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT:
|
case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT:
|
||||||
case MLX5_CMD_OP_QUERY_GENERAL_OBJECT:
|
case MLX5_CMD_OP_QUERY_GENERAL_OBJECT:
|
||||||
|
case MLX5_CMD_OP_CREATE_UCTX:
|
||||||
|
case MLX5_CMD_OP_DESTROY_UCTX:
|
||||||
|
case MLX5_CMD_OP_CREATE_UMEM:
|
||||||
|
case MLX5_CMD_OP_DESTROY_UMEM:
|
||||||
case MLX5_CMD_OP_ALLOC_MEMIC:
|
case MLX5_CMD_OP_ALLOC_MEMIC:
|
||||||
*status = MLX5_DRIVER_STATUS_ABORTED;
|
*status = MLX5_DRIVER_STATUS_ABORTED;
|
||||||
*synd = MLX5_DRIVER_SYND;
|
*synd = MLX5_DRIVER_SYND;
|
||||||
|
@ -629,6 +633,10 @@ const char *mlx5_command_str(int command)
|
||||||
MLX5_COMMAND_STR_CASE(ALLOC_MEMIC);
|
MLX5_COMMAND_STR_CASE(ALLOC_MEMIC);
|
||||||
MLX5_COMMAND_STR_CASE(DEALLOC_MEMIC);
|
MLX5_COMMAND_STR_CASE(DEALLOC_MEMIC);
|
||||||
MLX5_COMMAND_STR_CASE(QUERY_HOST_PARAMS);
|
MLX5_COMMAND_STR_CASE(QUERY_HOST_PARAMS);
|
||||||
|
MLX5_COMMAND_STR_CASE(CREATE_UCTX);
|
||||||
|
MLX5_COMMAND_STR_CASE(DESTROY_UCTX);
|
||||||
|
MLX5_COMMAND_STR_CASE(CREATE_UMEM);
|
||||||
|
MLX5_COMMAND_STR_CASE(DESTROY_UMEM);
|
||||||
default: return "unknown command opcode";
|
default: return "unknown command opcode";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,11 +248,32 @@ void mlx5_unregister_interface(struct mlx5_interface *intf)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mlx5_unregister_interface);
|
EXPORT_SYMBOL(mlx5_unregister_interface);
|
||||||
|
|
||||||
|
/* Must be called with intf_mutex held */
|
||||||
|
static bool mlx5_has_added_dev_by_protocol(struct mlx5_core_dev *mdev, int protocol)
|
||||||
|
{
|
||||||
|
struct mlx5_device_context *dev_ctx;
|
||||||
|
struct mlx5_interface *intf;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
list_for_each_entry(intf, &intf_list, list) {
|
||||||
|
if (intf->protocol == protocol) {
|
||||||
|
dev_ctx = mlx5_get_device(intf, &mdev->priv);
|
||||||
|
if (dev_ctx && test_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state))
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
void mlx5_reload_interface(struct mlx5_core_dev *mdev, int protocol)
|
void mlx5_reload_interface(struct mlx5_core_dev *mdev, int protocol)
|
||||||
{
|
{
|
||||||
mutex_lock(&mlx5_intf_mutex);
|
mutex_lock(&mlx5_intf_mutex);
|
||||||
|
if (mlx5_has_added_dev_by_protocol(mdev, protocol)) {
|
||||||
mlx5_remove_dev_by_protocol(mdev, protocol);
|
mlx5_remove_dev_by_protocol(mdev, protocol);
|
||||||
mlx5_add_dev_by_protocol(mdev, protocol);
|
mlx5_add_dev_by_protocol(mdev, protocol);
|
||||||
|
}
|
||||||
mutex_unlock(&mlx5_intf_mutex);
|
mutex_unlock(&mlx5_intf_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -385,6 +385,7 @@ struct mlx5e_txqsq {
|
||||||
/* control path */
|
/* control path */
|
||||||
struct mlx5_wq_ctrl wq_ctrl;
|
struct mlx5_wq_ctrl wq_ctrl;
|
||||||
struct mlx5e_channel *channel;
|
struct mlx5e_channel *channel;
|
||||||
|
int ch_ix;
|
||||||
int txq_ix;
|
int txq_ix;
|
||||||
u32 rate_limit;
|
u32 rate_limit;
|
||||||
struct work_struct recover_work;
|
struct work_struct recover_work;
|
||||||
|
@ -1112,6 +1113,7 @@ void mlx5e_del_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti)
|
||||||
netdev_features_t mlx5e_features_check(struct sk_buff *skb,
|
netdev_features_t mlx5e_features_check(struct sk_buff *skb,
|
||||||
struct net_device *netdev,
|
struct net_device *netdev,
|
||||||
netdev_features_t features);
|
netdev_features_t features);
|
||||||
|
int mlx5e_set_features(struct net_device *netdev, netdev_features_t features);
|
||||||
#ifdef CONFIG_MLX5_ESWITCH
|
#ifdef CONFIG_MLX5_ESWITCH
|
||||||
int mlx5e_set_vf_mac(struct net_device *dev, int vf, u8 *mac);
|
int mlx5e_set_vf_mac(struct net_device *dev, int vf, u8 *mac);
|
||||||
int mlx5e_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate, int max_tx_rate);
|
int mlx5e_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate, int max_tx_rate);
|
||||||
|
|
|
@ -11,24 +11,25 @@ static int get_route_and_out_devs(struct mlx5e_priv *priv,
|
||||||
struct net_device **route_dev,
|
struct net_device **route_dev,
|
||||||
struct net_device **out_dev)
|
struct net_device **out_dev)
|
||||||
{
|
{
|
||||||
|
struct net_device *uplink_dev, *uplink_upper, *real_dev;
|
||||||
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
|
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
|
||||||
struct net_device *uplink_dev, *uplink_upper;
|
|
||||||
bool dst_is_lag_dev;
|
bool dst_is_lag_dev;
|
||||||
|
|
||||||
|
real_dev = is_vlan_dev(dev) ? vlan_dev_real_dev(dev) : dev;
|
||||||
uplink_dev = mlx5_eswitch_uplink_get_proto_dev(esw, REP_ETH);
|
uplink_dev = mlx5_eswitch_uplink_get_proto_dev(esw, REP_ETH);
|
||||||
uplink_upper = netdev_master_upper_dev_get(uplink_dev);
|
uplink_upper = netdev_master_upper_dev_get(uplink_dev);
|
||||||
dst_is_lag_dev = (uplink_upper &&
|
dst_is_lag_dev = (uplink_upper &&
|
||||||
netif_is_lag_master(uplink_upper) &&
|
netif_is_lag_master(uplink_upper) &&
|
||||||
dev == uplink_upper &&
|
real_dev == uplink_upper &&
|
||||||
mlx5_lag_is_sriov(priv->mdev));
|
mlx5_lag_is_sriov(priv->mdev));
|
||||||
|
|
||||||
/* if the egress device isn't on the same HW e-switch or
|
/* if the egress device isn't on the same HW e-switch or
|
||||||
* it's a LAG device, use the uplink
|
* it's a LAG device, use the uplink
|
||||||
*/
|
*/
|
||||||
if (!netdev_port_same_parent_id(priv->netdev, dev) ||
|
if (!netdev_port_same_parent_id(priv->netdev, real_dev) ||
|
||||||
dst_is_lag_dev) {
|
dst_is_lag_dev) {
|
||||||
*route_dev = uplink_dev;
|
*route_dev = dev;
|
||||||
*out_dev = *route_dev;
|
*out_dev = uplink_dev;
|
||||||
} else {
|
} else {
|
||||||
*route_dev = dev;
|
*route_dev = dev;
|
||||||
if (is_vlan_dev(*route_dev))
|
if (is_vlan_dev(*route_dev))
|
||||||
|
|
|
@ -1082,6 +1082,7 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
|
||||||
sq->clock = &mdev->clock;
|
sq->clock = &mdev->clock;
|
||||||
sq->mkey_be = c->mkey_be;
|
sq->mkey_be = c->mkey_be;
|
||||||
sq->channel = c;
|
sq->channel = c;
|
||||||
|
sq->ch_ix = c->ix;
|
||||||
sq->txq_ix = txq_ix;
|
sq->txq_ix = txq_ix;
|
||||||
sq->uar_map = mdev->mlx5e_res.bfreg.map;
|
sq->uar_map = mdev->mlx5e_res.bfreg.map;
|
||||||
sq->min_inline_mode = params->tx_min_inline_mode;
|
sq->min_inline_mode = params->tx_min_inline_mode;
|
||||||
|
@ -3635,8 +3636,7 @@ static int mlx5e_handle_feature(struct net_device *netdev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mlx5e_set_features(struct net_device *netdev,
|
int mlx5e_set_features(struct net_device *netdev, netdev_features_t features)
|
||||||
netdev_features_t features)
|
|
||||||
{
|
{
|
||||||
netdev_features_t oper_features = netdev->features;
|
netdev_features_t oper_features = netdev->features;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -5108,6 +5108,11 @@ static void mlx5e_detach(struct mlx5_core_dev *mdev, void *vpriv)
|
||||||
struct mlx5e_priv *priv = vpriv;
|
struct mlx5e_priv *priv = vpriv;
|
||||||
struct net_device *netdev = priv->netdev;
|
struct net_device *netdev = priv->netdev;
|
||||||
|
|
||||||
|
#ifdef CONFIG_MLX5_ESWITCH
|
||||||
|
if (MLX5_ESWITCH_MANAGER(mdev) && vpriv == mdev)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!netif_device_present(netdev))
|
if (!netif_device_present(netdev))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -1351,6 +1351,7 @@ static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
|
||||||
.ndo_get_vf_stats = mlx5e_get_vf_stats,
|
.ndo_get_vf_stats = mlx5e_get_vf_stats,
|
||||||
.ndo_set_vf_vlan = mlx5e_uplink_rep_set_vf_vlan,
|
.ndo_set_vf_vlan = mlx5e_uplink_rep_set_vf_vlan,
|
||||||
.ndo_get_port_parent_id = mlx5e_rep_get_port_parent_id,
|
.ndo_get_port_parent_id = mlx5e_rep_get_port_parent_id,
|
||||||
|
.ndo_set_features = mlx5e_set_features,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool mlx5e_eswitch_rep(struct net_device *netdev)
|
bool mlx5e_eswitch_rep(struct net_device *netdev)
|
||||||
|
@ -1425,10 +1426,9 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev)
|
||||||
|
|
||||||
netdev->watchdog_timeo = 15 * HZ;
|
netdev->watchdog_timeo = 15 * HZ;
|
||||||
|
|
||||||
|
netdev->features |= NETIF_F_NETNS_LOCAL;
|
||||||
|
|
||||||
netdev->features |= NETIF_F_HW_TC | NETIF_F_NETNS_LOCAL;
|
|
||||||
netdev->hw_features |= NETIF_F_HW_TC;
|
netdev->hw_features |= NETIF_F_HW_TC;
|
||||||
|
|
||||||
netdev->hw_features |= NETIF_F_SG;
|
netdev->hw_features |= NETIF_F_SG;
|
||||||
netdev->hw_features |= NETIF_F_IP_CSUM;
|
netdev->hw_features |= NETIF_F_IP_CSUM;
|
||||||
netdev->hw_features |= NETIF_F_IPV6_CSUM;
|
netdev->hw_features |= NETIF_F_IPV6_CSUM;
|
||||||
|
@ -1437,7 +1437,9 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev)
|
||||||
netdev->hw_features |= NETIF_F_TSO6;
|
netdev->hw_features |= NETIF_F_TSO6;
|
||||||
netdev->hw_features |= NETIF_F_RXCSUM;
|
netdev->hw_features |= NETIF_F_RXCSUM;
|
||||||
|
|
||||||
if (rep->vport != MLX5_VPORT_UPLINK)
|
if (rep->vport == MLX5_VPORT_UPLINK)
|
||||||
|
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
|
||||||
|
else
|
||||||
netdev->features |= NETIF_F_VLAN_CHALLENGED;
|
netdev->features |= NETIF_F_VLAN_CHALLENGED;
|
||||||
|
|
||||||
netdev->features |= netdev->hw_features;
|
netdev->features |= netdev->hw_features;
|
||||||
|
|
|
@ -2812,9 +2812,6 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
|
||||||
if (!flow_action_has_entries(flow_action))
|
if (!flow_action_has_entries(flow_action))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
attr->in_rep = rpriv->rep;
|
|
||||||
attr->in_mdev = priv->mdev;
|
|
||||||
|
|
||||||
flow_action_for_each(i, act, flow_action) {
|
flow_action_for_each(i, act, flow_action) {
|
||||||
switch (act->id) {
|
switch (act->id) {
|
||||||
case FLOW_ACTION_DROP:
|
case FLOW_ACTION_DROP:
|
||||||
|
|
|
@ -113,13 +113,13 @@ static inline int mlx5e_get_dscp_up(struct mlx5e_priv *priv, struct sk_buff *skb
|
||||||
u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
|
u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
|
||||||
struct net_device *sb_dev)
|
struct net_device *sb_dev)
|
||||||
{
|
{
|
||||||
int channel_ix = netdev_pick_tx(dev, skb, NULL);
|
int txq_ix = netdev_pick_tx(dev, skb, NULL);
|
||||||
struct mlx5e_priv *priv = netdev_priv(dev);
|
struct mlx5e_priv *priv = netdev_priv(dev);
|
||||||
u16 num_channels;
|
u16 num_channels;
|
||||||
int up = 0;
|
int up = 0;
|
||||||
|
|
||||||
if (!netdev_get_num_tc(dev))
|
if (!netdev_get_num_tc(dev))
|
||||||
return channel_ix;
|
return txq_ix;
|
||||||
|
|
||||||
#ifdef CONFIG_MLX5_CORE_EN_DCB
|
#ifdef CONFIG_MLX5_CORE_EN_DCB
|
||||||
if (priv->dcbx_dp.trust_state == MLX5_QPTS_TRUST_DSCP)
|
if (priv->dcbx_dp.trust_state == MLX5_QPTS_TRUST_DSCP)
|
||||||
|
@ -129,14 +129,14 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
|
||||||
if (skb_vlan_tag_present(skb))
|
if (skb_vlan_tag_present(skb))
|
||||||
up = skb_vlan_tag_get_prio(skb);
|
up = skb_vlan_tag_get_prio(skb);
|
||||||
|
|
||||||
/* channel_ix can be larger than num_channels since
|
/* txq_ix can be larger than num_channels since
|
||||||
* dev->num_real_tx_queues = num_channels * num_tc
|
* dev->num_real_tx_queues = num_channels * num_tc
|
||||||
*/
|
*/
|
||||||
num_channels = priv->channels.params.num_channels;
|
num_channels = priv->channels.params.num_channels;
|
||||||
if (channel_ix >= num_channels)
|
if (txq_ix >= num_channels)
|
||||||
channel_ix = reciprocal_scale(channel_ix, num_channels);
|
txq_ix = priv->txq2sq[txq_ix]->ch_ix;
|
||||||
|
|
||||||
return priv->channel_tc2txq[channel_ix][up];
|
return priv->channel_tc2txq[txq_ix][up];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int mlx5e_skb_l2_header_offset(struct sk_buff *skb)
|
static inline int mlx5e_skb_l2_header_offset(struct sk_buff *skb)
|
||||||
|
|
|
@ -997,7 +997,7 @@ static inline void mlxsw_reg_spaft_pack(char *payload, u8 local_port,
|
||||||
MLXSW_REG_ZERO(spaft, payload);
|
MLXSW_REG_ZERO(spaft, payload);
|
||||||
mlxsw_reg_spaft_local_port_set(payload, local_port);
|
mlxsw_reg_spaft_local_port_set(payload, local_port);
|
||||||
mlxsw_reg_spaft_allow_untagged_set(payload, allow_untagged);
|
mlxsw_reg_spaft_allow_untagged_set(payload, allow_untagged);
|
||||||
mlxsw_reg_spaft_allow_prio_tagged_set(payload, true);
|
mlxsw_reg_spaft_allow_prio_tagged_set(payload, allow_untagged);
|
||||||
mlxsw_reg_spaft_allow_tagged_set(payload, true);
|
mlxsw_reg_spaft_allow_tagged_set(payload, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4280,13 +4280,16 @@ static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MLXSW_SP_LAG_SEED_INIT 0xcafecafe
|
||||||
|
|
||||||
static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
|
static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
|
||||||
{
|
{
|
||||||
char slcr_pl[MLXSW_REG_SLCR_LEN];
|
char slcr_pl[MLXSW_REG_SLCR_LEN];
|
||||||
u32 seed;
|
u32 seed;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
seed = jhash(mlxsw_sp->base_mac, sizeof(mlxsw_sp->base_mac), 0);
|
seed = jhash(mlxsw_sp->base_mac, sizeof(mlxsw_sp->base_mac),
|
||||||
|
MLXSW_SP_LAG_SEED_INIT);
|
||||||
mlxsw_reg_slcr_pack(slcr_pl, MLXSW_REG_SLCR_LAG_HASH_SMAC |
|
mlxsw_reg_slcr_pack(slcr_pl, MLXSW_REG_SLCR_LAG_HASH_SMAC |
|
||||||
MLXSW_REG_SLCR_LAG_HASH_DMAC |
|
MLXSW_REG_SLCR_LAG_HASH_DMAC |
|
||||||
MLXSW_REG_SLCR_LAG_HASH_ETHERTYPE |
|
MLXSW_REG_SLCR_LAG_HASH_ETHERTYPE |
|
||||||
|
|
|
@ -437,8 +437,8 @@ static const struct mlxsw_sp_sb_pr mlxsw_sp1_sb_prs[] = {
|
||||||
MLXSW_SP1_SB_PR_CPU_SIZE, true, false),
|
MLXSW_SP1_SB_PR_CPU_SIZE, true, false),
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MLXSW_SP2_SB_PR_INGRESS_SIZE 40960000
|
#define MLXSW_SP2_SB_PR_INGRESS_SIZE 38128752
|
||||||
#define MLXSW_SP2_SB_PR_EGRESS_SIZE 40960000
|
#define MLXSW_SP2_SB_PR_EGRESS_SIZE 38128752
|
||||||
#define MLXSW_SP2_SB_PR_CPU_SIZE (256 * 1000)
|
#define MLXSW_SP2_SB_PR_CPU_SIZE (256 * 1000)
|
||||||
|
|
||||||
/* Order according to mlxsw_sp2_sb_pool_dess */
|
/* Order according to mlxsw_sp2_sb_pool_dess */
|
||||||
|
|
|
@ -247,8 +247,8 @@ static int mlxsw_sp_flower_parse_ip(struct mlxsw_sp *mlxsw_sp,
|
||||||
match.mask->tos & 0x3);
|
match.mask->tos & 0x3);
|
||||||
|
|
||||||
mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_IP_DSCP,
|
mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_IP_DSCP,
|
||||||
match.key->tos >> 6,
|
match.key->tos >> 2,
|
||||||
match.mask->tos >> 6);
|
match.mask->tos >> 2);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2363,7 +2363,7 @@ static void mlxsw_sp_router_probe_unresolved_nexthops(struct work_struct *work)
|
||||||
static void
|
static void
|
||||||
mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp,
|
mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp,
|
||||||
struct mlxsw_sp_neigh_entry *neigh_entry,
|
struct mlxsw_sp_neigh_entry *neigh_entry,
|
||||||
bool removing);
|
bool removing, bool dead);
|
||||||
|
|
||||||
static enum mlxsw_reg_rauht_op mlxsw_sp_rauht_op(bool adding)
|
static enum mlxsw_reg_rauht_op mlxsw_sp_rauht_op(bool adding)
|
||||||
{
|
{
|
||||||
|
@ -2507,7 +2507,8 @@ static void mlxsw_sp_router_neigh_event_work(struct work_struct *work)
|
||||||
|
|
||||||
memcpy(neigh_entry->ha, ha, ETH_ALEN);
|
memcpy(neigh_entry->ha, ha, ETH_ALEN);
|
||||||
mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, entry_connected);
|
mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, entry_connected);
|
||||||
mlxsw_sp_nexthop_neigh_update(mlxsw_sp, neigh_entry, !entry_connected);
|
mlxsw_sp_nexthop_neigh_update(mlxsw_sp, neigh_entry, !entry_connected,
|
||||||
|
dead);
|
||||||
|
|
||||||
if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list))
|
if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list))
|
||||||
mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry);
|
mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry);
|
||||||
|
@ -3472,13 +3473,79 @@ static void __mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp_nexthop *nh,
|
||||||
nh->update = 1;
|
nh->update = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
|
||||||
|
struct mlxsw_sp_neigh_entry *neigh_entry)
|
||||||
|
{
|
||||||
|
struct neighbour *n, *old_n = neigh_entry->key.n;
|
||||||
|
struct mlxsw_sp_nexthop *nh;
|
||||||
|
bool entry_connected;
|
||||||
|
u8 nud_state, dead;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
nh = list_first_entry(&neigh_entry->nexthop_list,
|
||||||
|
struct mlxsw_sp_nexthop, neigh_list_node);
|
||||||
|
|
||||||
|
n = neigh_lookup(nh->nh_grp->neigh_tbl, &nh->gw_addr, nh->rif->dev);
|
||||||
|
if (!n) {
|
||||||
|
n = neigh_create(nh->nh_grp->neigh_tbl, &nh->gw_addr,
|
||||||
|
nh->rif->dev);
|
||||||
|
if (IS_ERR(n))
|
||||||
|
return PTR_ERR(n);
|
||||||
|
neigh_event_send(n, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
mlxsw_sp_neigh_entry_remove(mlxsw_sp, neigh_entry);
|
||||||
|
neigh_entry->key.n = n;
|
||||||
|
err = mlxsw_sp_neigh_entry_insert(mlxsw_sp, neigh_entry);
|
||||||
|
if (err)
|
||||||
|
goto err_neigh_entry_insert;
|
||||||
|
|
||||||
|
read_lock_bh(&n->lock);
|
||||||
|
nud_state = n->nud_state;
|
||||||
|
dead = n->dead;
|
||||||
|
read_unlock_bh(&n->lock);
|
||||||
|
entry_connected = nud_state & NUD_VALID && !dead;
|
||||||
|
|
||||||
|
list_for_each_entry(nh, &neigh_entry->nexthop_list,
|
||||||
|
neigh_list_node) {
|
||||||
|
neigh_release(old_n);
|
||||||
|
neigh_clone(n);
|
||||||
|
__mlxsw_sp_nexthop_neigh_update(nh, !entry_connected);
|
||||||
|
mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp);
|
||||||
|
}
|
||||||
|
|
||||||
|
neigh_release(n);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_neigh_entry_insert:
|
||||||
|
neigh_entry->key.n = old_n;
|
||||||
|
mlxsw_sp_neigh_entry_insert(mlxsw_sp, neigh_entry);
|
||||||
|
neigh_release(n);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp,
|
mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp,
|
||||||
struct mlxsw_sp_neigh_entry *neigh_entry,
|
struct mlxsw_sp_neigh_entry *neigh_entry,
|
||||||
bool removing)
|
bool removing, bool dead)
|
||||||
{
|
{
|
||||||
struct mlxsw_sp_nexthop *nh;
|
struct mlxsw_sp_nexthop *nh;
|
||||||
|
|
||||||
|
if (list_empty(&neigh_entry->nexthop_list))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (dead) {
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = mlxsw_sp_nexthop_dead_neigh_replace(mlxsw_sp,
|
||||||
|
neigh_entry);
|
||||||
|
if (err)
|
||||||
|
dev_err(mlxsw_sp->bus_info->dev, "Failed to replace dead neigh\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
list_for_each_entry(nh, &neigh_entry->nexthop_list,
|
list_for_each_entry(nh, &neigh_entry->nexthop_list,
|
||||||
neigh_list_node) {
|
neigh_list_node) {
|
||||||
__mlxsw_sp_nexthop_neigh_update(nh, removing);
|
__mlxsw_sp_nexthop_neigh_update(nh, removing);
|
||||||
|
|
|
@ -1867,6 +1867,7 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
|
||||||
napi_gro_receive(&rx_ring->r_vec->napi, skb);
|
napi_gro_receive(&rx_ring->r_vec->napi, skb);
|
||||||
} else {
|
} else {
|
||||||
skb->dev = netdev;
|
skb->dev = netdev;
|
||||||
|
skb_reset_network_header(skb);
|
||||||
__skb_push(skb, ETH_HLEN);
|
__skb_push(skb, ETH_HLEN);
|
||||||
dev_queue_xmit(skb);
|
dev_queue_xmit(skb);
|
||||||
}
|
}
|
||||||
|
|
|
@ -395,7 +395,7 @@ static int geneve_udp_encap_err_lookup(struct sock *sk, struct sk_buff *skb)
|
||||||
u8 zero_vni[3] = { 0 };
|
u8 zero_vni[3] = { 0 };
|
||||||
u8 *vni = zero_vni;
|
u8 *vni = zero_vni;
|
||||||
|
|
||||||
if (skb->len < GENEVE_BASE_HLEN)
|
if (!pskb_may_pull(skb, skb_transport_offset(skb) + GENEVE_BASE_HLEN))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
geneveh = geneve_hdr(skb);
|
geneveh = geneve_hdr(skb);
|
||||||
|
|
|
@ -2407,7 +2407,7 @@ static struct hv_driver netvsc_drv = {
|
||||||
.probe = netvsc_probe,
|
.probe = netvsc_probe,
|
||||||
.remove = netvsc_remove,
|
.remove = netvsc_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
.probe_type = PROBE_FORCE_SYNCHRONOUS,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -254,7 +254,7 @@ config AQUANTIA_PHY
|
||||||
---help---
|
---help---
|
||||||
Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
|
Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
|
||||||
|
|
||||||
config ASIX_PHY
|
config AX88796B_PHY
|
||||||
tristate "Asix PHYs"
|
tristate "Asix PHYs"
|
||||||
help
|
help
|
||||||
Currently supports the Asix Electronics PHY found in the X-Surf 100
|
Currently supports the Asix Electronics PHY found in the X-Surf 100
|
||||||
|
|
|
@ -52,7 +52,7 @@ ifdef CONFIG_HWMON
|
||||||
aquantia-objs += aquantia_hwmon.o
|
aquantia-objs += aquantia_hwmon.o
|
||||||
endif
|
endif
|
||||||
obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
|
obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
|
||||||
obj-$(CONFIG_ASIX_PHY) += asix.o
|
obj-$(CONFIG_AX88796B_PHY) += ax88796b.o
|
||||||
obj-$(CONFIG_AT803X_PHY) += at803x.o
|
obj-$(CONFIG_AT803X_PHY) += at803x.o
|
||||||
obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o
|
obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o
|
||||||
obj-$(CONFIG_BCM7XXX_PHY) += bcm7xxx.o
|
obj-$(CONFIG_BCM7XXX_PHY) += bcm7xxx.o
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <linux/usb/cdc.h>
|
#include <linux/usb/cdc.h>
|
||||||
#include <linux/usb/usbnet.h>
|
#include <linux/usb/usbnet.h>
|
||||||
#include <linux/usb/cdc-wdm.h>
|
#include <linux/usb/cdc-wdm.h>
|
||||||
|
#include <linux/u64_stats_sync.h>
|
||||||
|
|
||||||
/* This driver supports wwan (3G/LTE/?) devices using a vendor
|
/* This driver supports wwan (3G/LTE/?) devices using a vendor
|
||||||
* specific management protocol called Qualcomm MSM Interface (QMI) -
|
* specific management protocol called Qualcomm MSM Interface (QMI) -
|
||||||
|
@ -75,6 +76,7 @@ struct qmimux_hdr {
|
||||||
struct qmimux_priv {
|
struct qmimux_priv {
|
||||||
struct net_device *real_dev;
|
struct net_device *real_dev;
|
||||||
u8 mux_id;
|
u8 mux_id;
|
||||||
|
struct pcpu_sw_netstats __percpu *stats64;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int qmimux_open(struct net_device *dev)
|
static int qmimux_open(struct net_device *dev)
|
||||||
|
@ -101,19 +103,65 @@ static netdev_tx_t qmimux_start_xmit(struct sk_buff *skb, struct net_device *dev
|
||||||
struct qmimux_priv *priv = netdev_priv(dev);
|
struct qmimux_priv *priv = netdev_priv(dev);
|
||||||
unsigned int len = skb->len;
|
unsigned int len = skb->len;
|
||||||
struct qmimux_hdr *hdr;
|
struct qmimux_hdr *hdr;
|
||||||
|
netdev_tx_t ret;
|
||||||
|
|
||||||
hdr = skb_push(skb, sizeof(struct qmimux_hdr));
|
hdr = skb_push(skb, sizeof(struct qmimux_hdr));
|
||||||
hdr->pad = 0;
|
hdr->pad = 0;
|
||||||
hdr->mux_id = priv->mux_id;
|
hdr->mux_id = priv->mux_id;
|
||||||
hdr->pkt_len = cpu_to_be16(len);
|
hdr->pkt_len = cpu_to_be16(len);
|
||||||
skb->dev = priv->real_dev;
|
skb->dev = priv->real_dev;
|
||||||
return dev_queue_xmit(skb);
|
ret = dev_queue_xmit(skb);
|
||||||
|
|
||||||
|
if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
|
||||||
|
struct pcpu_sw_netstats *stats64 = this_cpu_ptr(priv->stats64);
|
||||||
|
|
||||||
|
u64_stats_update_begin(&stats64->syncp);
|
||||||
|
stats64->tx_packets++;
|
||||||
|
stats64->tx_bytes += len;
|
||||||
|
u64_stats_update_end(&stats64->syncp);
|
||||||
|
} else {
|
||||||
|
dev->stats.tx_dropped++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qmimux_get_stats64(struct net_device *net,
|
||||||
|
struct rtnl_link_stats64 *stats)
|
||||||
|
{
|
||||||
|
struct qmimux_priv *priv = netdev_priv(net);
|
||||||
|
unsigned int start;
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
netdev_stats_to_stats64(stats, &net->stats);
|
||||||
|
|
||||||
|
for_each_possible_cpu(cpu) {
|
||||||
|
struct pcpu_sw_netstats *stats64;
|
||||||
|
u64 rx_packets, rx_bytes;
|
||||||
|
u64 tx_packets, tx_bytes;
|
||||||
|
|
||||||
|
stats64 = per_cpu_ptr(priv->stats64, cpu);
|
||||||
|
|
||||||
|
do {
|
||||||
|
start = u64_stats_fetch_begin_irq(&stats64->syncp);
|
||||||
|
rx_packets = stats64->rx_packets;
|
||||||
|
rx_bytes = stats64->rx_bytes;
|
||||||
|
tx_packets = stats64->tx_packets;
|
||||||
|
tx_bytes = stats64->tx_bytes;
|
||||||
|
} while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
|
||||||
|
|
||||||
|
stats->rx_packets += rx_packets;
|
||||||
|
stats->rx_bytes += rx_bytes;
|
||||||
|
stats->tx_packets += tx_packets;
|
||||||
|
stats->tx_bytes += tx_bytes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct net_device_ops qmimux_netdev_ops = {
|
static const struct net_device_ops qmimux_netdev_ops = {
|
||||||
.ndo_open = qmimux_open,
|
.ndo_open = qmimux_open,
|
||||||
.ndo_stop = qmimux_stop,
|
.ndo_stop = qmimux_stop,
|
||||||
.ndo_start_xmit = qmimux_start_xmit,
|
.ndo_start_xmit = qmimux_start_xmit,
|
||||||
|
.ndo_get_stats64 = qmimux_get_stats64,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void qmimux_setup(struct net_device *dev)
|
static void qmimux_setup(struct net_device *dev)
|
||||||
|
@ -153,7 +201,7 @@ static bool qmimux_has_slaves(struct usbnet *dev)
|
||||||
|
|
||||||
static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
|
static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
unsigned int len, offset = 0;
|
unsigned int len, offset = 0, pad_len, pkt_len;
|
||||||
struct qmimux_hdr *hdr;
|
struct qmimux_hdr *hdr;
|
||||||
struct net_device *net;
|
struct net_device *net;
|
||||||
struct sk_buff *skbn;
|
struct sk_buff *skbn;
|
||||||
|
@ -171,10 +219,16 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
|
||||||
if (hdr->pad & 0x80)
|
if (hdr->pad & 0x80)
|
||||||
goto skip;
|
goto skip;
|
||||||
|
|
||||||
|
/* extract padding length and check for valid length info */
|
||||||
|
pad_len = hdr->pad & 0x3f;
|
||||||
|
if (len == 0 || pad_len >= len)
|
||||||
|
goto skip;
|
||||||
|
pkt_len = len - pad_len;
|
||||||
|
|
||||||
net = qmimux_find_dev(dev, hdr->mux_id);
|
net = qmimux_find_dev(dev, hdr->mux_id);
|
||||||
if (!net)
|
if (!net)
|
||||||
goto skip;
|
goto skip;
|
||||||
skbn = netdev_alloc_skb(net, len);
|
skbn = netdev_alloc_skb(net, pkt_len);
|
||||||
if (!skbn)
|
if (!skbn)
|
||||||
return 0;
|
return 0;
|
||||||
skbn->dev = net;
|
skbn->dev = net;
|
||||||
|
@ -191,9 +245,20 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
skb_put_data(skbn, skb->data + offset + qmimux_hdr_sz, len);
|
skb_put_data(skbn, skb->data + offset + qmimux_hdr_sz, pkt_len);
|
||||||
if (netif_rx(skbn) != NET_RX_SUCCESS)
|
if (netif_rx(skbn) != NET_RX_SUCCESS) {
|
||||||
|
net->stats.rx_errors++;
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
struct pcpu_sw_netstats *stats64;
|
||||||
|
struct qmimux_priv *priv = netdev_priv(net);
|
||||||
|
|
||||||
|
stats64 = this_cpu_ptr(priv->stats64);
|
||||||
|
u64_stats_update_begin(&stats64->syncp);
|
||||||
|
stats64->rx_packets++;
|
||||||
|
stats64->rx_bytes += pkt_len;
|
||||||
|
u64_stats_update_end(&stats64->syncp);
|
||||||
|
}
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
offset += len + qmimux_hdr_sz;
|
offset += len + qmimux_hdr_sz;
|
||||||
|
@ -217,6 +282,12 @@ static int qmimux_register_device(struct net_device *real_dev, u8 mux_id)
|
||||||
priv->mux_id = mux_id;
|
priv->mux_id = mux_id;
|
||||||
priv->real_dev = real_dev;
|
priv->real_dev = real_dev;
|
||||||
|
|
||||||
|
priv->stats64 = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
|
||||||
|
if (!priv->stats64) {
|
||||||
|
err = -ENOBUFS;
|
||||||
|
goto out_free_newdev;
|
||||||
|
}
|
||||||
|
|
||||||
err = register_netdevice(new_dev);
|
err = register_netdevice(new_dev);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto out_free_newdev;
|
goto out_free_newdev;
|
||||||
|
@ -241,13 +312,15 @@ out_free_newdev:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qmimux_unregister_device(struct net_device *dev)
|
static void qmimux_unregister_device(struct net_device *dev,
|
||||||
|
struct list_head *head)
|
||||||
{
|
{
|
||||||
struct qmimux_priv *priv = netdev_priv(dev);
|
struct qmimux_priv *priv = netdev_priv(dev);
|
||||||
struct net_device *real_dev = priv->real_dev;
|
struct net_device *real_dev = priv->real_dev;
|
||||||
|
|
||||||
|
free_percpu(priv->stats64);
|
||||||
netdev_upper_dev_unlink(real_dev, dev);
|
netdev_upper_dev_unlink(real_dev, dev);
|
||||||
unregister_netdevice(dev);
|
unregister_netdevice_queue(dev, head);
|
||||||
|
|
||||||
/* Get rid of the reference to real_dev */
|
/* Get rid of the reference to real_dev */
|
||||||
dev_put(real_dev);
|
dev_put(real_dev);
|
||||||
|
@ -356,8 +429,8 @@ static ssize_t add_mux_store(struct device *d, struct device_attribute *attr, c
|
||||||
if (kstrtou8(buf, 0, &mux_id))
|
if (kstrtou8(buf, 0, &mux_id))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* mux_id [1 - 0x7f] range empirically found */
|
/* mux_id [1 - 254] for compatibility with ip(8) and the rmnet driver */
|
||||||
if (mux_id < 1 || mux_id > 0x7f)
|
if (mux_id < 1 || mux_id > 254)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!rtnl_trylock())
|
if (!rtnl_trylock())
|
||||||
|
@ -418,7 +491,7 @@ static ssize_t del_mux_store(struct device *d, struct device_attribute *attr, c
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
qmimux_unregister_device(del_dev);
|
qmimux_unregister_device(del_dev, NULL);
|
||||||
|
|
||||||
if (!qmimux_has_slaves(dev))
|
if (!qmimux_has_slaves(dev))
|
||||||
info->flags &= ~QMI_WWAN_FLAG_MUX;
|
info->flags &= ~QMI_WWAN_FLAG_MUX;
|
||||||
|
@ -1428,6 +1501,7 @@ static void qmi_wwan_disconnect(struct usb_interface *intf)
|
||||||
struct qmi_wwan_state *info;
|
struct qmi_wwan_state *info;
|
||||||
struct list_head *iter;
|
struct list_head *iter;
|
||||||
struct net_device *ldev;
|
struct net_device *ldev;
|
||||||
|
LIST_HEAD(list);
|
||||||
|
|
||||||
/* called twice if separate control and data intf */
|
/* called twice if separate control and data intf */
|
||||||
if (!dev)
|
if (!dev)
|
||||||
|
@ -1440,8 +1514,9 @@ static void qmi_wwan_disconnect(struct usb_interface *intf)
|
||||||
}
|
}
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
netdev_for_each_upper_dev_rcu(dev->net, ldev, iter)
|
netdev_for_each_upper_dev_rcu(dev->net, ldev, iter)
|
||||||
qmimux_unregister_device(ldev);
|
qmimux_unregister_device(ldev, &list);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
unregister_netdevice_many(&list);
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
info->flags &= ~QMI_WWAN_FLAG_MUX;
|
info->flags &= ~QMI_WWAN_FLAG_MUX;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1766,7 +1766,7 @@ static int vxlan_err_lookup(struct sock *sk, struct sk_buff *skb)
|
||||||
struct vxlanhdr *hdr;
|
struct vxlanhdr *hdr;
|
||||||
__be32 vni;
|
__be32 vni;
|
||||||
|
|
||||||
if (skb->len < VXLAN_HLEN)
|
if (!pskb_may_pull(skb, skb_transport_offset(skb) + VXLAN_HLEN))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
hdr = vxlan_hdr(skb);
|
hdr = vxlan_hdr(skb);
|
||||||
|
|
|
@ -2747,3 +2747,42 @@ void iwl_fw_dbg_periodic_trig_handler(struct timer_list *t)
|
||||||
jiffies + msecs_to_jiffies(collect_interval));
|
jiffies + msecs_to_jiffies(collect_interval));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FSEQ_REG(x) { .addr = (x), .str = #x, }
|
||||||
|
|
||||||
|
void iwl_fw_error_print_fseq_regs(struct iwl_fw_runtime *fwrt)
|
||||||
|
{
|
||||||
|
struct iwl_trans *trans = fwrt->trans;
|
||||||
|
unsigned long flags;
|
||||||
|
int i;
|
||||||
|
struct {
|
||||||
|
u32 addr;
|
||||||
|
const char *str;
|
||||||
|
} fseq_regs[] = {
|
||||||
|
FSEQ_REG(FSEQ_ERROR_CODE),
|
||||||
|
FSEQ_REG(FSEQ_TOP_INIT_VERSION),
|
||||||
|
FSEQ_REG(FSEQ_CNVIO_INIT_VERSION),
|
||||||
|
FSEQ_REG(FSEQ_OTP_VERSION),
|
||||||
|
FSEQ_REG(FSEQ_TOP_CONTENT_VERSION),
|
||||||
|
FSEQ_REG(FSEQ_ALIVE_TOKEN),
|
||||||
|
FSEQ_REG(FSEQ_CNVI_ID),
|
||||||
|
FSEQ_REG(FSEQ_CNVR_ID),
|
||||||
|
FSEQ_REG(CNVI_AUX_MISC_CHIP),
|
||||||
|
FSEQ_REG(CNVR_AUX_MISC_CHIP),
|
||||||
|
FSEQ_REG(CNVR_SCU_SD_REGS_SD_REG_DIG_DCDC_VTRIM),
|
||||||
|
FSEQ_REG(CNVR_SCU_SD_REGS_SD_REG_ACTIVE_VDIG_MIRROR),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!iwl_trans_grab_nic_access(trans, &flags))
|
||||||
|
return;
|
||||||
|
|
||||||
|
IWL_ERR(fwrt, "Fseq Registers:\n");
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(fseq_regs); i++)
|
||||||
|
IWL_ERR(fwrt, "0x%08X | %s\n",
|
||||||
|
iwl_read_prph_no_grab(trans, fseq_regs[i].addr),
|
||||||
|
fseq_regs[i].str);
|
||||||
|
|
||||||
|
iwl_trans_release_nic_access(trans, &flags);
|
||||||
|
}
|
||||||
|
IWL_EXPORT_SYMBOL(iwl_fw_error_print_fseq_regs);
|
||||||
|
|
|
@ -471,4 +471,6 @@ static inline void iwl_fw_error_collect(struct iwl_fw_runtime *fwrt)
|
||||||
}
|
}
|
||||||
|
|
||||||
void iwl_fw_dbg_periodic_trig_handler(struct timer_list *t);
|
void iwl_fw_dbg_periodic_trig_handler(struct timer_list *t);
|
||||||
|
|
||||||
|
void iwl_fw_error_print_fseq_regs(struct iwl_fw_runtime *fwrt);
|
||||||
#endif /* __iwl_fw_dbg_h__ */
|
#endif /* __iwl_fw_dbg_h__ */
|
||||||
|
|
|
@ -1597,7 +1597,6 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
||||||
goto free;
|
goto free;
|
||||||
|
|
||||||
out_free_fw:
|
out_free_fw:
|
||||||
iwl_dealloc_ucode(drv);
|
|
||||||
release_firmware(ucode_raw);
|
release_firmware(ucode_raw);
|
||||||
out_unbind:
|
out_unbind:
|
||||||
complete(&drv->request_firmware_complete);
|
complete(&drv->request_firmware_complete);
|
||||||
|
|
|
@ -395,7 +395,11 @@ enum {
|
||||||
WFPM_AUX_CTL_AUX_IF_MAC_OWNER_MSK = 0x80000000,
|
WFPM_AUX_CTL_AUX_IF_MAC_OWNER_MSK = 0x80000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AUX_MISC_REG 0xA200B0
|
#define CNVI_AUX_MISC_CHIP 0xA200B0
|
||||||
|
#define CNVR_AUX_MISC_CHIP 0xA2B800
|
||||||
|
#define CNVR_SCU_SD_REGS_SD_REG_DIG_DCDC_VTRIM 0xA29890
|
||||||
|
#define CNVR_SCU_SD_REGS_SD_REG_ACTIVE_VDIG_MIRROR 0xA29938
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
HW_STEP_LOCATION_BITS = 24,
|
HW_STEP_LOCATION_BITS = 24,
|
||||||
};
|
};
|
||||||
|
@ -408,7 +412,12 @@ enum aux_misc_master1_en {
|
||||||
#define AUX_MISC_MASTER1_SMPHR_STATUS 0xA20800
|
#define AUX_MISC_MASTER1_SMPHR_STATUS 0xA20800
|
||||||
#define RSA_ENABLE 0xA24B08
|
#define RSA_ENABLE 0xA24B08
|
||||||
#define PREG_AUX_BUS_WPROT_0 0xA04CC0
|
#define PREG_AUX_BUS_WPROT_0 0xA04CC0
|
||||||
#define PREG_PRPH_WPROT_0 0xA04CE0
|
|
||||||
|
/* device family 9000 WPROT register */
|
||||||
|
#define PREG_PRPH_WPROT_9000 0xA04CE0
|
||||||
|
/* device family 22000 WPROT register */
|
||||||
|
#define PREG_PRPH_WPROT_22000 0xA04D00
|
||||||
|
|
||||||
#define SB_CPU_1_STATUS 0xA01E30
|
#define SB_CPU_1_STATUS 0xA01E30
|
||||||
#define SB_CPU_2_STATUS 0xA01E34
|
#define SB_CPU_2_STATUS 0xA01E34
|
||||||
#define UMAG_SB_CPU_1_STATUS 0xA038C0
|
#define UMAG_SB_CPU_1_STATUS 0xA038C0
|
||||||
|
@ -442,4 +451,13 @@ enum {
|
||||||
|
|
||||||
#define UREG_DOORBELL_TO_ISR6 0xA05C04
|
#define UREG_DOORBELL_TO_ISR6 0xA05C04
|
||||||
#define UREG_DOORBELL_TO_ISR6_NMI_BIT BIT(0)
|
#define UREG_DOORBELL_TO_ISR6_NMI_BIT BIT(0)
|
||||||
|
|
||||||
|
#define FSEQ_ERROR_CODE 0xA340C8
|
||||||
|
#define FSEQ_TOP_INIT_VERSION 0xA34038
|
||||||
|
#define FSEQ_CNVIO_INIT_VERSION 0xA3403C
|
||||||
|
#define FSEQ_OTP_VERSION 0xA340FC
|
||||||
|
#define FSEQ_TOP_CONTENT_VERSION 0xA340F4
|
||||||
|
#define FSEQ_ALIVE_TOKEN 0xA340F0
|
||||||
|
#define FSEQ_CNVI_ID 0xA3408C
|
||||||
|
#define FSEQ_CNVR_ID 0xA34090
|
||||||
#endif /* __iwl_prph_h__ */
|
#endif /* __iwl_prph_h__ */
|
||||||
|
|
|
@ -1972,26 +1972,6 @@ out:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
|
||||||
const struct fw_img *img = &mvm->fw->img[IWL_UCODE_WOWLAN];
|
|
||||||
u32 len = img->sec[IWL_UCODE_SECTION_DATA].len;
|
|
||||||
u32 offs = img->sec[IWL_UCODE_SECTION_DATA].offset;
|
|
||||||
|
|
||||||
if (!mvm->store_d3_resume_sram)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!mvm->d3_resume_sram) {
|
|
||||||
mvm->d3_resume_sram = kzalloc(len, GFP_KERNEL);
|
|
||||||
if (!mvm->d3_resume_sram)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
iwl_trans_read_mem_bytes(mvm->trans, offs, mvm->d3_resume_sram, len);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
|
static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
|
||||||
struct ieee80211_vif *vif)
|
struct ieee80211_vif *vif)
|
||||||
{
|
{
|
||||||
|
@ -2054,8 +2034,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
|
||||||
}
|
}
|
||||||
|
|
||||||
iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
|
iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
|
||||||
/* query SRAM first in case we want event logging */
|
|
||||||
iwl_mvm_read_d3_sram(mvm);
|
|
||||||
|
|
||||||
if (iwl_mvm_check_rt_status(mvm, vif)) {
|
if (iwl_mvm_check_rt_status(mvm, vif)) {
|
||||||
set_bit(STATUS_FW_ERROR, &mvm->trans->status);
|
set_bit(STATUS_FW_ERROR, &mvm->trans->status);
|
||||||
|
|
|
@ -1557,59 +1557,6 @@ static ssize_t iwl_dbgfs_bcast_filters_macs_write(struct iwl_mvm *mvm,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
|
||||||
static ssize_t iwl_dbgfs_d3_sram_write(struct iwl_mvm *mvm, char *buf,
|
|
||||||
size_t count, loff_t *ppos)
|
|
||||||
{
|
|
||||||
int store;
|
|
||||||
|
|
||||||
if (sscanf(buf, "%d", &store) != 1)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
mvm->store_d3_resume_sram = store;
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
|
|
||||||
size_t count, loff_t *ppos)
|
|
||||||
{
|
|
||||||
struct iwl_mvm *mvm = file->private_data;
|
|
||||||
const struct fw_img *img;
|
|
||||||
int ofs, len, pos = 0;
|
|
||||||
size_t bufsz, ret;
|
|
||||||
char *buf;
|
|
||||||
u8 *ptr = mvm->d3_resume_sram;
|
|
||||||
|
|
||||||
img = &mvm->fw->img[IWL_UCODE_WOWLAN];
|
|
||||||
len = img->sec[IWL_UCODE_SECTION_DATA].len;
|
|
||||||
|
|
||||||
bufsz = len * 4 + 256;
|
|
||||||
buf = kzalloc(bufsz, GFP_KERNEL);
|
|
||||||
if (!buf)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
pos += scnprintf(buf, bufsz, "D3 SRAM capture: %sabled\n",
|
|
||||||
mvm->store_d3_resume_sram ? "en" : "dis");
|
|
||||||
|
|
||||||
if (ptr) {
|
|
||||||
for (ofs = 0; ofs < len; ofs += 16) {
|
|
||||||
pos += scnprintf(buf + pos, bufsz - pos,
|
|
||||||
"0x%.4x %16ph\n", ofs, ptr + ofs);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pos += scnprintf(buf + pos, bufsz - pos,
|
|
||||||
"(no data captured)\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
|
||||||
|
|
||||||
kfree(buf);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PRINT_MVM_REF(ref) do { \
|
#define PRINT_MVM_REF(ref) do { \
|
||||||
if (mvm->refs[ref]) \
|
if (mvm->refs[ref]) \
|
||||||
pos += scnprintf(buf + pos, bufsz - pos, \
|
pos += scnprintf(buf + pos, bufsz - pos, \
|
||||||
|
@ -1940,9 +1887,6 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256);
|
||||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256);
|
MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
|
||||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8);
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile);
|
MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile);
|
||||||
#endif
|
#endif
|
||||||
|
@ -2159,7 +2103,6 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, 0600);
|
|
||||||
MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, 0400);
|
MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, 0400);
|
||||||
debugfs_create_bool("d3_wake_sysassert", 0600, mvm->debugfs_dir,
|
debugfs_create_bool("d3_wake_sysassert", 0600, mvm->debugfs_dir,
|
||||||
&mvm->d3_wake_sysassert);
|
&mvm->d3_wake_sysassert);
|
||||||
|
|
|
@ -311,6 +311,8 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
|
||||||
int ret;
|
int ret;
|
||||||
enum iwl_ucode_type old_type = mvm->fwrt.cur_fw_img;
|
enum iwl_ucode_type old_type = mvm->fwrt.cur_fw_img;
|
||||||
static const u16 alive_cmd[] = { MVM_ALIVE };
|
static const u16 alive_cmd[] = { MVM_ALIVE };
|
||||||
|
bool run_in_rfkill =
|
||||||
|
ucode_type == IWL_UCODE_INIT || iwl_mvm_has_unified_ucode(mvm);
|
||||||
|
|
||||||
if (ucode_type == IWL_UCODE_REGULAR &&
|
if (ucode_type == IWL_UCODE_REGULAR &&
|
||||||
iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) &&
|
iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) &&
|
||||||
|
@ -328,7 +330,12 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
|
||||||
alive_cmd, ARRAY_SIZE(alive_cmd),
|
alive_cmd, ARRAY_SIZE(alive_cmd),
|
||||||
iwl_alive_fn, &alive_data);
|
iwl_alive_fn, &alive_data);
|
||||||
|
|
||||||
ret = iwl_trans_start_fw(mvm->trans, fw, ucode_type == IWL_UCODE_INIT);
|
/*
|
||||||
|
* We want to load the INIT firmware even in RFKILL
|
||||||
|
* For the unified firmware case, the ucode_type is not
|
||||||
|
* INIT, but we still need to run it.
|
||||||
|
*/
|
||||||
|
ret = iwl_trans_start_fw(mvm->trans, fw, run_in_rfkill);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
iwl_fw_set_current_image(&mvm->fwrt, old_type);
|
iwl_fw_set_current_image(&mvm->fwrt, old_type);
|
||||||
iwl_remove_notification(&mvm->notif_wait, &alive_wait);
|
iwl_remove_notification(&mvm->notif_wait, &alive_wait);
|
||||||
|
@ -433,7 +440,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
||||||
* commands
|
* commands
|
||||||
*/
|
*/
|
||||||
ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(SYSTEM_GROUP,
|
ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(SYSTEM_GROUP,
|
||||||
INIT_EXTENDED_CFG_CMD), 0,
|
INIT_EXTENDED_CFG_CMD),
|
||||||
|
CMD_SEND_IN_RFKILL,
|
||||||
sizeof(init_cfg), &init_cfg);
|
sizeof(init_cfg), &init_cfg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
IWL_ERR(mvm, "Failed to run init config command: %d\n",
|
IWL_ERR(mvm, "Failed to run init config command: %d\n",
|
||||||
|
@ -457,7 +465,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(REGULATORY_AND_NVM_GROUP,
|
ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(REGULATORY_AND_NVM_GROUP,
|
||||||
NVM_ACCESS_COMPLETE), 0,
|
NVM_ACCESS_COMPLETE),
|
||||||
|
CMD_SEND_IN_RFKILL,
|
||||||
sizeof(nvm_complete), &nvm_complete);
|
sizeof(nvm_complete), &nvm_complete);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
IWL_ERR(mvm, "Failed to run complete NVM access: %d\n",
|
IWL_ERR(mvm, "Failed to run complete NVM access: %d\n",
|
||||||
|
@ -482,6 +491,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mvm->rfkill_safe_init_done = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -526,7 +537,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
||||||
|
|
||||||
lockdep_assert_held(&mvm->mutex);
|
lockdep_assert_held(&mvm->mutex);
|
||||||
|
|
||||||
if (WARN_ON_ONCE(mvm->calibrating))
|
if (WARN_ON_ONCE(mvm->rfkill_safe_init_done))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
iwl_init_notification_wait(&mvm->notif_wait,
|
iwl_init_notification_wait(&mvm->notif_wait,
|
||||||
|
@ -576,7 +587,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
||||||
goto remove_notif;
|
goto remove_notif;
|
||||||
}
|
}
|
||||||
|
|
||||||
mvm->calibrating = true;
|
mvm->rfkill_safe_init_done = true;
|
||||||
|
|
||||||
/* Send TX valid antennas before triggering calibrations */
|
/* Send TX valid antennas before triggering calibrations */
|
||||||
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
|
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
|
||||||
|
@ -612,7 +623,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
||||||
remove_notif:
|
remove_notif:
|
||||||
iwl_remove_notification(&mvm->notif_wait, &calib_wait);
|
iwl_remove_notification(&mvm->notif_wait, &calib_wait);
|
||||||
out:
|
out:
|
||||||
mvm->calibrating = false;
|
mvm->rfkill_safe_init_done = false;
|
||||||
if (iwlmvm_mod_params.init_dbg && !mvm->nvm_data) {
|
if (iwlmvm_mod_params.init_dbg && !mvm->nvm_data) {
|
||||||
/* we want to debug INIT and we have no NVM - fake */
|
/* we want to debug INIT and we have no NVM - fake */
|
||||||
mvm->nvm_data = kzalloc(sizeof(struct iwl_nvm_data) +
|
mvm->nvm_data = kzalloc(sizeof(struct iwl_nvm_data) +
|
||||||
|
|
|
@ -1209,7 +1209,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
|
||||||
|
|
||||||
mvm->scan_status = 0;
|
mvm->scan_status = 0;
|
||||||
mvm->ps_disabled = false;
|
mvm->ps_disabled = false;
|
||||||
mvm->calibrating = false;
|
mvm->rfkill_safe_init_done = false;
|
||||||
|
|
||||||
/* just in case one was running */
|
/* just in case one was running */
|
||||||
iwl_mvm_cleanup_roc_te(mvm);
|
iwl_mvm_cleanup_roc_te(mvm);
|
||||||
|
|
|
@ -880,7 +880,7 @@ struct iwl_mvm {
|
||||||
struct iwl_mvm_vif *bf_allowed_vif;
|
struct iwl_mvm_vif *bf_allowed_vif;
|
||||||
|
|
||||||
bool hw_registered;
|
bool hw_registered;
|
||||||
bool calibrating;
|
bool rfkill_safe_init_done;
|
||||||
bool support_umac_log;
|
bool support_umac_log;
|
||||||
|
|
||||||
u32 ampdu_ref;
|
u32 ampdu_ref;
|
||||||
|
@ -1039,8 +1039,6 @@ struct iwl_mvm {
|
||||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||||
bool d3_wake_sysassert;
|
bool d3_wake_sysassert;
|
||||||
bool d3_test_active;
|
bool d3_test_active;
|
||||||
bool store_d3_resume_sram;
|
|
||||||
void *d3_resume_sram;
|
|
||||||
u32 d3_test_pme_ptr;
|
u32 d3_test_pme_ptr;
|
||||||
struct ieee80211_vif *keep_vif;
|
struct ieee80211_vif *keep_vif;
|
||||||
u32 last_netdetect_scans; /* no. of scans in the last net-detect wake */
|
u32 last_netdetect_scans; /* no. of scans in the last net-detect wake */
|
||||||
|
|
|
@ -918,9 +918,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
|
||||||
kfree(mvm->error_recovery_buf);
|
kfree(mvm->error_recovery_buf);
|
||||||
mvm->error_recovery_buf = NULL;
|
mvm->error_recovery_buf = NULL;
|
||||||
|
|
||||||
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS)
|
|
||||||
kfree(mvm->d3_resume_sram);
|
|
||||||
#endif
|
|
||||||
iwl_trans_op_mode_leave(mvm->trans);
|
iwl_trans_op_mode_leave(mvm->trans);
|
||||||
|
|
||||||
iwl_phy_db_free(mvm->phy_db);
|
iwl_phy_db_free(mvm->phy_db);
|
||||||
|
@ -1212,7 +1209,8 @@ void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state)
|
||||||
static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
|
static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
|
||||||
{
|
{
|
||||||
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
|
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
|
||||||
bool calibrating = READ_ONCE(mvm->calibrating);
|
bool rfkill_safe_init_done = READ_ONCE(mvm->rfkill_safe_init_done);
|
||||||
|
bool unified = iwl_mvm_has_unified_ucode(mvm);
|
||||||
|
|
||||||
if (state)
|
if (state)
|
||||||
set_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
|
set_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
|
||||||
|
@ -1221,15 +1219,23 @@ static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
|
||||||
|
|
||||||
iwl_mvm_set_rfkill_state(mvm);
|
iwl_mvm_set_rfkill_state(mvm);
|
||||||
|
|
||||||
/* iwl_run_init_mvm_ucode is waiting for results, abort it */
|
/* iwl_run_init_mvm_ucode is waiting for results, abort it. */
|
||||||
if (calibrating)
|
if (rfkill_safe_init_done)
|
||||||
iwl_abort_notification_waits(&mvm->notif_wait);
|
iwl_abort_notification_waits(&mvm->notif_wait);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't ask the transport to stop the firmware. We'll do it
|
||||||
|
* after cfg80211 takes us down.
|
||||||
|
*/
|
||||||
|
if (unified)
|
||||||
|
return false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stop the device if we run OPERATIONAL firmware or if we are in the
|
* Stop the device if we run OPERATIONAL firmware or if we are in the
|
||||||
* middle of the calibrations.
|
* middle of the calibrations.
|
||||||
*/
|
*/
|
||||||
return state && (mvm->fwrt.cur_fw_img != IWL_UCODE_INIT || calibrating);
|
return state && (mvm->fwrt.cur_fw_img != IWL_UCODE_INIT ||
|
||||||
|
rfkill_safe_init_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
|
static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
|
||||||
|
|
|
@ -441,7 +441,8 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||||
*/
|
*/
|
||||||
sta->max_amsdu_len = max_amsdu_len;
|
sta->max_amsdu_len = max_amsdu_len;
|
||||||
|
|
||||||
ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cfg_cmd), &cfg_cmd);
|
ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, CMD_ASYNC, sizeof(cfg_cmd),
|
||||||
|
&cfg_cmd);
|
||||||
if (ret)
|
if (ret)
|
||||||
IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret);
|
IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret);
|
||||||
}
|
}
|
||||||
|
|
|
@ -596,6 +596,8 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
|
||||||
iwl_mvm_dump_lmac_error_log(mvm, 1);
|
iwl_mvm_dump_lmac_error_log(mvm, 1);
|
||||||
|
|
||||||
iwl_mvm_dump_umac_error_log(mvm);
|
iwl_mvm_dump_umac_error_log(mvm);
|
||||||
|
|
||||||
|
iwl_fw_error_print_fseq_regs(&mvm->fwrt);
|
||||||
}
|
}
|
||||||
|
|
||||||
int iwl_mvm_reconfig_scd(struct iwl_mvm *mvm, int queue, int fifo, int sta_id,
|
int iwl_mvm_reconfig_scd(struct iwl_mvm *mvm, int queue, int fifo, int sta_id,
|
||||||
|
|
|
@ -928,7 +928,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
|
||||||
MSIX_HW_INT_CAUSES_REG_RF_KILL);
|
MSIX_HW_INT_CAUSES_REG_RF_KILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trans->cfg->device_family == IWL_DEVICE_FAMILY_9000) {
|
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_9000) {
|
||||||
/*
|
/*
|
||||||
* On 9000-series devices this bit isn't enabled by default, so
|
* On 9000-series devices this bit isn't enabled by default, so
|
||||||
* when we power down the device we need set the bit to allow it
|
* when we power down the device we need set the bit to allow it
|
||||||
|
|
|
@ -1698,10 +1698,40 @@ static int iwl_pcie_init_msix_handler(struct pci_dev *pdev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int iwl_trans_pcie_clear_persistence_bit(struct iwl_trans *trans)
|
||||||
|
{
|
||||||
|
u32 hpm, wprot;
|
||||||
|
|
||||||
|
switch (trans->cfg->device_family) {
|
||||||
|
case IWL_DEVICE_FAMILY_9000:
|
||||||
|
wprot = PREG_PRPH_WPROT_9000;
|
||||||
|
break;
|
||||||
|
case IWL_DEVICE_FAMILY_22000:
|
||||||
|
wprot = PREG_PRPH_WPROT_22000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hpm = iwl_read_umac_prph_no_grab(trans, HPM_DEBUG);
|
||||||
|
if (hpm != 0xa5a5a5a0 && (hpm & PERSISTENCE_BIT)) {
|
||||||
|
u32 wprot_val = iwl_read_umac_prph_no_grab(trans, wprot);
|
||||||
|
|
||||||
|
if (wprot_val & PREG_WFPM_ACCESS) {
|
||||||
|
IWL_ERR(trans,
|
||||||
|
"Error, can not clear persistence bit\n");
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
iwl_write_umac_prph_no_grab(trans, HPM_DEBUG,
|
||||||
|
hpm & ~PERSISTENCE_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
|
static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
|
||||||
{
|
{
|
||||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||||
u32 hpm;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
lockdep_assert_held(&trans_pcie->mutex);
|
lockdep_assert_held(&trans_pcie->mutex);
|
||||||
|
@ -1712,19 +1742,9 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
hpm = iwl_read_umac_prph_no_grab(trans, HPM_DEBUG);
|
err = iwl_trans_pcie_clear_persistence_bit(trans);
|
||||||
if (hpm != 0xa5a5a5a0 && (hpm & PERSISTENCE_BIT)) {
|
if (err)
|
||||||
int wfpm_val = iwl_read_umac_prph_no_grab(trans,
|
return err;
|
||||||
PREG_PRPH_WPROT_0);
|
|
||||||
|
|
||||||
if (wfpm_val & PREG_WFPM_ACCESS) {
|
|
||||||
IWL_ERR(trans,
|
|
||||||
"Error, can not clear persistence bit\n");
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
iwl_write_umac_prph_no_grab(trans, HPM_DEBUG,
|
|
||||||
hpm & ~PERSISTENCE_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
iwl_trans_pcie_sw_reset(trans);
|
iwl_trans_pcie_sw_reset(trans);
|
||||||
|
|
||||||
|
@ -3526,7 +3546,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
|
||||||
hw_step |= ENABLE_WFPM;
|
hw_step |= ENABLE_WFPM;
|
||||||
iwl_write_umac_prph_no_grab(trans, WFPM_CTRL_REG,
|
iwl_write_umac_prph_no_grab(trans, WFPM_CTRL_REG,
|
||||||
hw_step);
|
hw_step);
|
||||||
hw_step = iwl_read_prph_no_grab(trans, AUX_MISC_REG);
|
hw_step = iwl_read_prph_no_grab(trans,
|
||||||
|
CNVI_AUX_MISC_CHIP);
|
||||||
hw_step = (hw_step >> HW_STEP_LOCATION_BITS) & 0xF;
|
hw_step = (hw_step >> HW_STEP_LOCATION_BITS) & 0xF;
|
||||||
if (hw_step == 0x3)
|
if (hw_step == 0x3)
|
||||||
trans->hw_rev = (trans->hw_rev & 0xFFFFFFF3) |
|
trans->hw_rev = (trans->hw_rev & 0xFFFFFFF3) |
|
||||||
|
@ -3577,7 +3598,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
|
||||||
}
|
}
|
||||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
|
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
|
||||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
|
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
|
||||||
(trans->cfg != &iwl_ax200_cfg_cc ||
|
((trans->cfg != &iwl_ax200_cfg_cc &&
|
||||||
|
trans->cfg != &killer1650x_2ax_cfg &&
|
||||||
|
trans->cfg != &killer1650w_2ax_cfg) ||
|
||||||
trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) {
|
trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) {
|
||||||
u32 hw_status;
|
u32 hw_status;
|
||||||
|
|
||||||
|
|
|
@ -3851,6 +3851,7 @@ static int __init init_mac80211_hwsim(void)
|
||||||
break;
|
break;
|
||||||
case HWSIM_REGTEST_STRICT_ALL:
|
case HWSIM_REGTEST_STRICT_ALL:
|
||||||
param.reg_strict = true;
|
param.reg_strict = true;
|
||||||
|
/* fall through */
|
||||||
case HWSIM_REGTEST_DRIVER_REG_ALL:
|
case HWSIM_REGTEST_DRIVER_REG_ALL:
|
||||||
param.reg_alpha2 = hwsim_alpha2s[0];
|
param.reg_alpha2 = hwsim_alpha2s[0];
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -329,6 +329,8 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
|
||||||
struct ieee80211_vendor_ie *vendorhdr;
|
struct ieee80211_vendor_ie *vendorhdr;
|
||||||
u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0;
|
u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0;
|
||||||
int left_len, parsed_len = 0;
|
int left_len, parsed_len = 0;
|
||||||
|
unsigned int token_len;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
if (!info->tail || !info->tail_len)
|
if (!info->tail || !info->tail_len)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -344,6 +346,12 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
|
||||||
*/
|
*/
|
||||||
while (left_len > sizeof(struct ieee_types_header)) {
|
while (left_len > sizeof(struct ieee_types_header)) {
|
||||||
hdr = (void *)(info->tail + parsed_len);
|
hdr = (void *)(info->tail + parsed_len);
|
||||||
|
token_len = hdr->len + sizeof(struct ieee_types_header);
|
||||||
|
if (token_len > left_len) {
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
switch (hdr->element_id) {
|
switch (hdr->element_id) {
|
||||||
case WLAN_EID_SSID:
|
case WLAN_EID_SSID:
|
||||||
case WLAN_EID_SUPP_RATES:
|
case WLAN_EID_SUPP_RATES:
|
||||||
|
@ -361,17 +369,20 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
|
||||||
if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
|
if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
|
||||||
WLAN_OUI_TYPE_MICROSOFT_WMM,
|
WLAN_OUI_TYPE_MICROSOFT_WMM,
|
||||||
(const u8 *)hdr,
|
(const u8 *)hdr,
|
||||||
hdr->len + sizeof(struct ieee_types_header)))
|
token_len))
|
||||||
break;
|
break;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
memcpy(gen_ie->ie_buffer + ie_len, hdr,
|
if (ie_len + token_len > IEEE_MAX_IE_SIZE) {
|
||||||
hdr->len + sizeof(struct ieee_types_header));
|
err = -EINVAL;
|
||||||
ie_len += hdr->len + sizeof(struct ieee_types_header);
|
goto out;
|
||||||
|
}
|
||||||
|
memcpy(gen_ie->ie_buffer + ie_len, hdr, token_len);
|
||||||
|
ie_len += token_len;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
left_len -= hdr->len + sizeof(struct ieee_types_header);
|
left_len -= token_len;
|
||||||
parsed_len += hdr->len + sizeof(struct ieee_types_header);
|
parsed_len += token_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse only WPA vendor IE from tail, WMM IE is configured by
|
/* parse only WPA vendor IE from tail, WMM IE is configured by
|
||||||
|
@ -381,15 +392,17 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
|
||||||
WLAN_OUI_TYPE_MICROSOFT_WPA,
|
WLAN_OUI_TYPE_MICROSOFT_WPA,
|
||||||
info->tail, info->tail_len);
|
info->tail, info->tail_len);
|
||||||
if (vendorhdr) {
|
if (vendorhdr) {
|
||||||
memcpy(gen_ie->ie_buffer + ie_len, vendorhdr,
|
token_len = vendorhdr->len + sizeof(struct ieee_types_header);
|
||||||
vendorhdr->len + sizeof(struct ieee_types_header));
|
if (ie_len + token_len > IEEE_MAX_IE_SIZE) {
|
||||||
ie_len += vendorhdr->len + sizeof(struct ieee_types_header);
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
memcpy(gen_ie->ie_buffer + ie_len, vendorhdr, token_len);
|
||||||
|
ie_len += token_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ie_len) {
|
if (!ie_len)
|
||||||
kfree(gen_ie);
|
goto out;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
gen_ie->ie_index = cpu_to_le16(gen_idx);
|
gen_ie->ie_index = cpu_to_le16(gen_idx);
|
||||||
gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON |
|
gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON |
|
||||||
|
@ -399,13 +412,15 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
|
||||||
|
|
||||||
if (mwifiex_update_uap_custom_ie(priv, gen_ie, &gen_idx, NULL, NULL,
|
if (mwifiex_update_uap_custom_ie(priv, gen_ie, &gen_idx, NULL, NULL,
|
||||||
NULL, NULL)) {
|
NULL, NULL)) {
|
||||||
kfree(gen_ie);
|
err = -EINVAL;
|
||||||
return -1;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->gen_idx = gen_idx;
|
priv->gen_idx = gen_idx;
|
||||||
|
|
||||||
|
out:
|
||||||
kfree(gen_ie);
|
kfree(gen_ie);
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function parses different IEs-head & tail IEs, beacon IEs,
|
/* This function parses different IEs-head & tail IEs, beacon IEs,
|
||||||
|
|
|
@ -1247,6 +1247,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
|
||||||
}
|
}
|
||||||
switch (element_id) {
|
switch (element_id) {
|
||||||
case WLAN_EID_SSID:
|
case WLAN_EID_SSID:
|
||||||
|
if (element_len > IEEE80211_MAX_SSID_LEN)
|
||||||
|
return -EINVAL;
|
||||||
bss_entry->ssid.ssid_len = element_len;
|
bss_entry->ssid.ssid_len = element_len;
|
||||||
memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
|
memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
|
||||||
element_len);
|
element_len);
|
||||||
|
@ -1256,6 +1258,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WLAN_EID_SUPP_RATES:
|
case WLAN_EID_SUPP_RATES:
|
||||||
|
if (element_len > MWIFIEX_SUPPORTED_RATES)
|
||||||
|
return -EINVAL;
|
||||||
memcpy(bss_entry->data_rates, current_ptr + 2,
|
memcpy(bss_entry->data_rates, current_ptr + 2,
|
||||||
element_len);
|
element_len);
|
||||||
memcpy(bss_entry->supported_rates, current_ptr + 2,
|
memcpy(bss_entry->supported_rates, current_ptr + 2,
|
||||||
|
@ -1265,6 +1269,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WLAN_EID_FH_PARAMS:
|
case WLAN_EID_FH_PARAMS:
|
||||||
|
if (element_len + 2 < sizeof(*fh_param_set))
|
||||||
|
return -EINVAL;
|
||||||
fh_param_set =
|
fh_param_set =
|
||||||
(struct ieee_types_fh_param_set *) current_ptr;
|
(struct ieee_types_fh_param_set *) current_ptr;
|
||||||
memcpy(&bss_entry->phy_param_set.fh_param_set,
|
memcpy(&bss_entry->phy_param_set.fh_param_set,
|
||||||
|
@ -1273,6 +1279,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WLAN_EID_DS_PARAMS:
|
case WLAN_EID_DS_PARAMS:
|
||||||
|
if (element_len + 2 < sizeof(*ds_param_set))
|
||||||
|
return -EINVAL;
|
||||||
ds_param_set =
|
ds_param_set =
|
||||||
(struct ieee_types_ds_param_set *) current_ptr;
|
(struct ieee_types_ds_param_set *) current_ptr;
|
||||||
|
|
||||||
|
@ -1284,6 +1292,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WLAN_EID_CF_PARAMS:
|
case WLAN_EID_CF_PARAMS:
|
||||||
|
if (element_len + 2 < sizeof(*cf_param_set))
|
||||||
|
return -EINVAL;
|
||||||
cf_param_set =
|
cf_param_set =
|
||||||
(struct ieee_types_cf_param_set *) current_ptr;
|
(struct ieee_types_cf_param_set *) current_ptr;
|
||||||
memcpy(&bss_entry->ss_param_set.cf_param_set,
|
memcpy(&bss_entry->ss_param_set.cf_param_set,
|
||||||
|
@ -1292,6 +1302,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WLAN_EID_IBSS_PARAMS:
|
case WLAN_EID_IBSS_PARAMS:
|
||||||
|
if (element_len + 2 < sizeof(*ibss_param_set))
|
||||||
|
return -EINVAL;
|
||||||
ibss_param_set =
|
ibss_param_set =
|
||||||
(struct ieee_types_ibss_param_set *)
|
(struct ieee_types_ibss_param_set *)
|
||||||
current_ptr;
|
current_ptr;
|
||||||
|
@ -1301,10 +1313,14 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WLAN_EID_ERP_INFO:
|
case WLAN_EID_ERP_INFO:
|
||||||
|
if (!element_len)
|
||||||
|
return -EINVAL;
|
||||||
bss_entry->erp_flags = *(current_ptr + 2);
|
bss_entry->erp_flags = *(current_ptr + 2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WLAN_EID_PWR_CONSTRAINT:
|
case WLAN_EID_PWR_CONSTRAINT:
|
||||||
|
if (!element_len)
|
||||||
|
return -EINVAL;
|
||||||
bss_entry->local_constraint = *(current_ptr + 2);
|
bss_entry->local_constraint = *(current_ptr + 2);
|
||||||
bss_entry->sensed_11h = true;
|
bss_entry->sensed_11h = true;
|
||||||
break;
|
break;
|
||||||
|
@ -1345,6 +1361,9 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WLAN_EID_VENDOR_SPECIFIC:
|
case WLAN_EID_VENDOR_SPECIFIC:
|
||||||
|
if (element_len + 2 < sizeof(vendor_ie->vend_hdr))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
vendor_ie = (struct ieee_types_vendor_specific *)
|
vendor_ie = (struct ieee_types_vendor_specific *)
|
||||||
current_ptr;
|
current_ptr;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
#include "reg.h"
|
#include "reg.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev *rtwdev, struct sk_buff *skb)
|
static void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev *rtwdev,
|
||||||
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct rtw_c2h_cmd *c2h;
|
struct rtw_c2h_cmd *c2h;
|
||||||
u8 sub_cmd_id;
|
u8 sub_cmd_id;
|
||||||
|
@ -47,7 +48,8 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev, u8 *h2c)
|
static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev,
|
||||||
|
u8 *h2c)
|
||||||
{
|
{
|
||||||
u8 box;
|
u8 box;
|
||||||
u8 box_state;
|
u8 box_state;
|
||||||
|
|
|
@ -162,7 +162,8 @@ static void rtw_watch_dog_work(struct work_struct *work)
|
||||||
rtwdev->stats.tx_cnt = 0;
|
rtwdev->stats.tx_cnt = 0;
|
||||||
rtwdev->stats.rx_cnt = 0;
|
rtwdev->stats.rx_cnt = 0;
|
||||||
|
|
||||||
rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data);
|
/* use atomic version to avoid taking local->iflist_mtx mutex */
|
||||||
|
rtw_iterate_vifs_atomic(rtwdev, rtw_vif_watch_dog_iter, &data);
|
||||||
|
|
||||||
/* fw supports only one station associated to enter lps, if there are
|
/* fw supports only one station associated to enter lps, if there are
|
||||||
* more than two stations associated to the AP, then we can not enter
|
* more than two stations associated to the AP, then we can not enter
|
||||||
|
|
|
@ -144,10 +144,10 @@ static void rtw_phy_stat_rssi_iter(void *data, struct ieee80211_sta *sta)
|
||||||
struct rtw_phy_stat_iter_data *iter_data = data;
|
struct rtw_phy_stat_iter_data *iter_data = data;
|
||||||
struct rtw_dev *rtwdev = iter_data->rtwdev;
|
struct rtw_dev *rtwdev = iter_data->rtwdev;
|
||||||
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
|
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
|
||||||
u8 rssi, rssi_level;
|
u8 rssi;
|
||||||
|
|
||||||
rssi = ewma_rssi_read(&si->avg_rssi);
|
rssi = ewma_rssi_read(&si->avg_rssi);
|
||||||
rssi_level = rtw_phy_get_rssi_level(si->rssi_level, rssi);
|
si->rssi_level = rtw_phy_get_rssi_level(si->rssi_level, rssi);
|
||||||
|
|
||||||
rtw_fw_send_rssi_info(rtwdev, si);
|
rtw_fw_send_rssi_info(rtwdev, si);
|
||||||
|
|
||||||
|
@ -423,6 +423,11 @@ static u64 rtw_phy_db_2_linear(u8 power_db)
|
||||||
u8 i, j;
|
u8 i, j;
|
||||||
u64 linear;
|
u64 linear;
|
||||||
|
|
||||||
|
if (power_db > 96)
|
||||||
|
power_db = 96;
|
||||||
|
else if (power_db < 1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
/* 1dB ~ 96dB */
|
/* 1dB ~ 96dB */
|
||||||
i = (power_db - 1) >> 3;
|
i = (power_db - 1) >> 3;
|
||||||
j = (power_db - 1) - (i << 3);
|
j = (power_db - 1) - (i << 3);
|
||||||
|
@ -848,12 +853,13 @@ u8 rtw_vht_2s_rates[] = {
|
||||||
DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
|
DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
|
||||||
DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9
|
DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9
|
||||||
};
|
};
|
||||||
u8 rtw_cck_size = ARRAY_SIZE(rtw_cck_rates);
|
|
||||||
u8 rtw_ofdm_size = ARRAY_SIZE(rtw_ofdm_rates);
|
static u8 rtw_cck_size = ARRAY_SIZE(rtw_cck_rates);
|
||||||
u8 rtw_ht_1s_size = ARRAY_SIZE(rtw_ht_1s_rates);
|
static u8 rtw_ofdm_size = ARRAY_SIZE(rtw_ofdm_rates);
|
||||||
u8 rtw_ht_2s_size = ARRAY_SIZE(rtw_ht_2s_rates);
|
static u8 rtw_ht_1s_size = ARRAY_SIZE(rtw_ht_1s_rates);
|
||||||
u8 rtw_vht_1s_size = ARRAY_SIZE(rtw_vht_1s_rates);
|
static u8 rtw_ht_2s_size = ARRAY_SIZE(rtw_ht_2s_rates);
|
||||||
u8 rtw_vht_2s_size = ARRAY_SIZE(rtw_vht_2s_rates);
|
static u8 rtw_vht_1s_size = ARRAY_SIZE(rtw_vht_1s_rates);
|
||||||
|
static u8 rtw_vht_2s_size = ARRAY_SIZE(rtw_vht_2s_rates);
|
||||||
u8 *rtw_rate_section[RTW_RATE_SECTION_MAX] = {
|
u8 *rtw_rate_section[RTW_RATE_SECTION_MAX] = {
|
||||||
rtw_cck_rates, rtw_ofdm_rates,
|
rtw_cck_rates, rtw_ofdm_rates,
|
||||||
rtw_ht_1s_rates, rtw_ht_2s_rates,
|
rtw_ht_1s_rates, rtw_ht_2s_rates,
|
||||||
|
|
|
@ -929,11 +929,15 @@ static int rsi_sdio_ta_reset(struct rsi_hw *adapter)
|
||||||
u32 addr;
|
u32 addr;
|
||||||
u8 *data;
|
u8 *data;
|
||||||
|
|
||||||
|
data = kzalloc(RSI_9116_REG_SIZE, GFP_KERNEL);
|
||||||
|
if (!data)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
status = rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR);
|
status = rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
rsi_dbg(ERR_ZONE,
|
rsi_dbg(ERR_ZONE,
|
||||||
"Unable to set ms word to common reg\n");
|
"Unable to set ms word to common reg\n");
|
||||||
return status;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
rsi_dbg(INIT_ZONE, "%s: Bring TA out of reset\n", __func__);
|
rsi_dbg(INIT_ZONE, "%s: Bring TA out of reset\n", __func__);
|
||||||
|
@ -944,7 +948,7 @@ static int rsi_sdio_ta_reset(struct rsi_hw *adapter)
|
||||||
RSI_9116_REG_SIZE);
|
RSI_9116_REG_SIZE);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
rsi_dbg(ERR_ZONE, "Unable to hold TA threads\n");
|
rsi_dbg(ERR_ZONE, "Unable to hold TA threads\n");
|
||||||
return status;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
put_unaligned_le32(TA_SOFT_RST_CLR, data);
|
put_unaligned_le32(TA_SOFT_RST_CLR, data);
|
||||||
|
@ -954,7 +958,7 @@ static int rsi_sdio_ta_reset(struct rsi_hw *adapter)
|
||||||
RSI_9116_REG_SIZE);
|
RSI_9116_REG_SIZE);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
rsi_dbg(ERR_ZONE, "Unable to get TA out of reset\n");
|
rsi_dbg(ERR_ZONE, "Unable to get TA out of reset\n");
|
||||||
return status;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
put_unaligned_le32(TA_PC_ZERO, data);
|
put_unaligned_le32(TA_PC_ZERO, data);
|
||||||
|
@ -964,7 +968,8 @@ static int rsi_sdio_ta_reset(struct rsi_hw *adapter)
|
||||||
RSI_9116_REG_SIZE);
|
RSI_9116_REG_SIZE);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
rsi_dbg(ERR_ZONE, "Unable to Reset TA PC value\n");
|
rsi_dbg(ERR_ZONE, "Unable to Reset TA PC value\n");
|
||||||
return -EINVAL;
|
status = -EINVAL;
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
put_unaligned_le32(TA_RELEASE_THREAD_VALUE, data);
|
put_unaligned_le32(TA_RELEASE_THREAD_VALUE, data);
|
||||||
|
@ -974,17 +979,19 @@ static int rsi_sdio_ta_reset(struct rsi_hw *adapter)
|
||||||
RSI_9116_REG_SIZE);
|
RSI_9116_REG_SIZE);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
rsi_dbg(ERR_ZONE, "Unable to release TA threads\n");
|
rsi_dbg(ERR_ZONE, "Unable to release TA threads\n");
|
||||||
return status;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = rsi_sdio_master_access_msword(adapter, MISC_CFG_BASE_ADDR);
|
status = rsi_sdio_master_access_msword(adapter, MISC_CFG_BASE_ADDR);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
rsi_dbg(ERR_ZONE, "Unable to set ms word to common reg\n");
|
rsi_dbg(ERR_ZONE, "Unable to set ms word to common reg\n");
|
||||||
return status;
|
goto err;
|
||||||
}
|
}
|
||||||
rsi_dbg(INIT_ZONE, "***** TA Reset done *****\n");
|
rsi_dbg(INIT_ZONE, "***** TA Reset done *****\n");
|
||||||
|
|
||||||
return 0;
|
err:
|
||||||
|
kfree(data);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct rsi_host_intf_ops sdio_host_intf_ops = {
|
static struct rsi_host_intf_ops sdio_host_intf_ops = {
|
||||||
|
|
|
@ -238,6 +238,12 @@ int bpf_percpu_cgroup_storage_update(struct bpf_map *map, void *key,
|
||||||
#define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, t_ctx) \
|
#define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, t_ctx) \
|
||||||
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_UDP6_SENDMSG, t_ctx)
|
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_UDP6_SENDMSG, t_ctx)
|
||||||
|
|
||||||
|
#define BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, uaddr) \
|
||||||
|
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_UDP4_RECVMSG, NULL)
|
||||||
|
|
||||||
|
#define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr) \
|
||||||
|
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_UDP6_RECVMSG, NULL)
|
||||||
|
|
||||||
#define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) \
|
#define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) \
|
||||||
({ \
|
({ \
|
||||||
int __ret = 0; \
|
int __ret = 0; \
|
||||||
|
@ -339,6 +345,8 @@ static inline int bpf_percpu_cgroup_storage_update(struct bpf_map *map,
|
||||||
#define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr) ({ 0; })
|
#define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr) ({ 0; })
|
||||||
#define BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, uaddr, t_ctx) ({ 0; })
|
#define BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, uaddr, t_ctx) ({ 0; })
|
||||||
#define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, t_ctx) ({ 0; })
|
#define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, t_ctx) ({ 0; })
|
||||||
|
#define BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, uaddr) ({ 0; })
|
||||||
|
#define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr) ({ 0; })
|
||||||
#define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; })
|
#define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; })
|
||||||
#define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type,major,minor,access) ({ 0; })
|
#define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type,major,minor,access) ({ 0; })
|
||||||
#define BPF_CGROUP_RUN_PROG_SYSCTL(head,table,write,buf,count,pos,nbuf) ({ 0; })
|
#define BPF_CGROUP_RUN_PROG_SYSCTL(head,table,write,buf,count,pos,nbuf) ({ 0; })
|
||||||
|
|
|
@ -600,7 +600,6 @@ void bpf_map_area_free(void *base);
|
||||||
void bpf_map_init_from_attr(struct bpf_map *map, union bpf_attr *attr);
|
void bpf_map_init_from_attr(struct bpf_map *map, union bpf_attr *attr);
|
||||||
|
|
||||||
extern int sysctl_unprivileged_bpf_disabled;
|
extern int sysctl_unprivileged_bpf_disabled;
|
||||||
extern int sysctl_bpf_stats_enabled;
|
|
||||||
|
|
||||||
int bpf_map_new_fd(struct bpf_map *map, int flags);
|
int bpf_map_new_fd(struct bpf_map *map, int flags);
|
||||||
int bpf_prog_new_fd(struct bpf_prog *prog);
|
int bpf_prog_new_fd(struct bpf_prog *prog);
|
||||||
|
|
|
@ -123,11 +123,20 @@ int mac_link_state(struct net_device *ndev,
|
||||||
* @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND.
|
* @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND.
|
||||||
* @state: a pointer to a &struct phylink_link_state.
|
* @state: a pointer to a &struct phylink_link_state.
|
||||||
*
|
*
|
||||||
|
* Note - not all members of @state are valid. In particular,
|
||||||
|
* @state->lp_advertising, @state->link, @state->an_complete are never
|
||||||
|
* guaranteed to be correct, and so any mac_config() implementation must
|
||||||
|
* never reference these fields.
|
||||||
|
*
|
||||||
* The action performed depends on the currently selected mode:
|
* The action performed depends on the currently selected mode:
|
||||||
*
|
*
|
||||||
* %MLO_AN_FIXED, %MLO_AN_PHY:
|
* %MLO_AN_FIXED, %MLO_AN_PHY:
|
||||||
* Configure the specified @state->speed, @state->duplex and
|
* Configure the specified @state->speed, @state->duplex and
|
||||||
* @state->pause (%MLO_PAUSE_TX / %MLO_PAUSE_RX) mode.
|
* @state->pause (%MLO_PAUSE_TX / %MLO_PAUSE_RX) modes over a link
|
||||||
|
* specified by @state->interface. @state->advertising may be used,
|
||||||
|
* but is not required. Other members of @state must be ignored.
|
||||||
|
*
|
||||||
|
* Valid state members: interface, speed, duplex, pause, advertising.
|
||||||
*
|
*
|
||||||
* %MLO_AN_INBAND:
|
* %MLO_AN_INBAND:
|
||||||
* place the link in an inband negotiation mode (such as 802.3z
|
* place the link in an inband negotiation mode (such as 802.3z
|
||||||
|
@ -150,6 +159,8 @@ int mac_link_state(struct net_device *ndev,
|
||||||
* responsible for reading the configuration word and configuring
|
* responsible for reading the configuration word and configuring
|
||||||
* itself accordingly.
|
* itself accordingly.
|
||||||
*
|
*
|
||||||
|
* Valid state members: interface, an_enabled, pause, advertising.
|
||||||
|
*
|
||||||
* Implementations are expected to update the MAC to reflect the
|
* Implementations are expected to update the MAC to reflect the
|
||||||
* requested settings - i.o.w., if nothing has changed between two
|
* requested settings - i.o.w., if nothing has changed between two
|
||||||
* calls, no action is expected. If only flow control settings have
|
* calls, no action is expected. If only flow control settings have
|
||||||
|
|
|
@ -351,6 +351,8 @@ static inline void sk_psock_update_proto(struct sock *sk,
|
||||||
static inline void sk_psock_restore_proto(struct sock *sk,
|
static inline void sk_psock_restore_proto(struct sock *sk,
|
||||||
struct sk_psock *psock)
|
struct sk_psock *psock)
|
||||||
{
|
{
|
||||||
|
sk->sk_write_space = psock->saved_write_space;
|
||||||
|
|
||||||
if (psock->sk_proto) {
|
if (psock->sk_proto) {
|
||||||
sk->sk_prot = psock->sk_proto;
|
sk->sk_prot = psock->sk_proto;
|
||||||
psock->sk_proto = NULL;
|
psock->sk_proto = NULL;
|
||||||
|
|
|
@ -63,6 +63,9 @@ extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int,
|
||||||
void __user *, size_t *, loff_t *);
|
void __user *, size_t *, loff_t *);
|
||||||
extern int proc_do_large_bitmap(struct ctl_table *, int,
|
extern int proc_do_large_bitmap(struct ctl_table *, int,
|
||||||
void __user *, size_t *, loff_t *);
|
void __user *, size_t *, loff_t *);
|
||||||
|
extern int proc_do_static_key(struct ctl_table *table, int write,
|
||||||
|
void __user *buffer, size_t *lenp,
|
||||||
|
loff_t *ppos);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register a set of sysctl names by calling register_sysctl_table
|
* Register a set of sysctl names by calling register_sysctl_table
|
||||||
|
|
|
@ -484,4 +484,8 @@ static inline u16 tcp_mss_clamp(const struct tcp_sock *tp, u16 mss)
|
||||||
|
|
||||||
return (user_mss && user_mss < mss) ? user_mss : mss;
|
return (user_mss && user_mss < mss) ? user_mss : mss;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from, int pcount,
|
||||||
|
int shiftlen);
|
||||||
|
|
||||||
#endif /* _LINUX_TCP_H */
|
#endif /* _LINUX_TCP_H */
|
||||||
|
|
|
@ -309,6 +309,22 @@ static inline struct inet6_dev *__in6_dev_get(const struct net_device *dev)
|
||||||
return rcu_dereference_rtnl(dev->ip6_ptr);
|
return rcu_dereference_rtnl(dev->ip6_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __in6_dev_stats_get - get inet6_dev pointer for stats
|
||||||
|
* @dev: network device
|
||||||
|
* @skb: skb for original incoming interface if neeeded
|
||||||
|
*
|
||||||
|
* Caller must hold rcu_read_lock or RTNL, because this function
|
||||||
|
* does not take a reference on the inet6_dev.
|
||||||
|
*/
|
||||||
|
static inline struct inet6_dev *__in6_dev_stats_get(const struct net_device *dev,
|
||||||
|
const struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
if (netif_is_l3_master(dev))
|
||||||
|
dev = dev_get_by_index_rcu(dev_net(dev), inet6_iif(skb));
|
||||||
|
return __in6_dev_get(dev);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __in6_dev_get_safely - get inet6_dev pointer from netdevice
|
* __in6_dev_get_safely - get inet6_dev pointer from netdevice
|
||||||
* @dev: network device
|
* @dev: network device
|
||||||
|
|
|
@ -3839,7 +3839,8 @@ struct cfg80211_ops {
|
||||||
* on wiphy_new(), but can be changed by the driver if it has a good
|
* on wiphy_new(), but can be changed by the driver if it has a good
|
||||||
* reason to override the default
|
* reason to override the default
|
||||||
* @WIPHY_FLAG_4ADDR_AP: supports 4addr mode even on AP (with a single station
|
* @WIPHY_FLAG_4ADDR_AP: supports 4addr mode even on AP (with a single station
|
||||||
* on a VLAN interface)
|
* on a VLAN interface). This flag also serves an extra purpose of
|
||||||
|
* supporting 4ADDR AP mode on devices which do not support AP/VLAN iftype.
|
||||||
* @WIPHY_FLAG_4ADDR_STATION: supports 4addr mode even as a station
|
* @WIPHY_FLAG_4ADDR_STATION: supports 4addr mode even as a station
|
||||||
* @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the
|
* @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the
|
||||||
* control port protocol ethertype. The device also honours the
|
* control port protocol ethertype. The device also honours the
|
||||||
|
|
|
@ -46,6 +46,7 @@ struct flow_dissector_key_tags {
|
||||||
|
|
||||||
struct flow_dissector_key_vlan {
|
struct flow_dissector_key_vlan {
|
||||||
u16 vlan_id:12,
|
u16 vlan_id:12,
|
||||||
|
vlan_dei:1,
|
||||||
vlan_priority:3;
|
vlan_priority:3;
|
||||||
__be16 vlan_tpid;
|
__be16 vlan_tpid;
|
||||||
};
|
};
|
||||||
|
|
|
@ -117,6 +117,7 @@ struct netns_ipv4 {
|
||||||
#endif
|
#endif
|
||||||
int sysctl_tcp_mtu_probing;
|
int sysctl_tcp_mtu_probing;
|
||||||
int sysctl_tcp_base_mss;
|
int sysctl_tcp_base_mss;
|
||||||
|
int sysctl_tcp_min_snd_mss;
|
||||||
int sysctl_tcp_probe_threshold;
|
int sysctl_tcp_probe_threshold;
|
||||||
u32 sysctl_tcp_probe_interval;
|
u32 sysctl_tcp_probe_interval;
|
||||||
|
|
||||||
|
|
|
@ -1463,12 +1463,14 @@ static inline void sk_mem_uncharge(struct sock *sk, int size)
|
||||||
__sk_mem_reclaim(sk, 1 << 20);
|
__sk_mem_reclaim(sk, 1 << 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECLARE_STATIC_KEY_FALSE(tcp_tx_skb_cache_key);
|
||||||
static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb)
|
static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
|
sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
|
||||||
sk->sk_wmem_queued -= skb->truesize;
|
sk->sk_wmem_queued -= skb->truesize;
|
||||||
sk_mem_uncharge(sk, skb->truesize);
|
sk_mem_uncharge(sk, skb->truesize);
|
||||||
if (!sk->sk_tx_skb_cache && !skb_cloned(skb)) {
|
if (static_branch_unlikely(&tcp_tx_skb_cache_key) &&
|
||||||
|
!sk->sk_tx_skb_cache && !skb_cloned(skb)) {
|
||||||
skb_zcopy_clear(skb, true);
|
skb_zcopy_clear(skb, true);
|
||||||
sk->sk_tx_skb_cache = skb;
|
sk->sk_tx_skb_cache = skb;
|
||||||
return;
|
return;
|
||||||
|
@ -2433,13 +2435,11 @@ static inline void skb_setup_tx_timestamp(struct sk_buff *skb, __u16 tsflags)
|
||||||
* This routine must be called with interrupts disabled or with the socket
|
* This routine must be called with interrupts disabled or with the socket
|
||||||
* locked so that the sk_buff queue operation is ok.
|
* locked so that the sk_buff queue operation is ok.
|
||||||
*/
|
*/
|
||||||
|
DECLARE_STATIC_KEY_FALSE(tcp_rx_skb_cache_key);
|
||||||
static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb)
|
static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
__skb_unlink(skb, &sk->sk_receive_queue);
|
__skb_unlink(skb, &sk->sk_receive_queue);
|
||||||
if (
|
if (static_branch_unlikely(&tcp_rx_skb_cache_key) &&
|
||||||
#ifdef CONFIG_RPS
|
|
||||||
!static_branch_unlikely(&rps_needed) &&
|
|
||||||
#endif
|
|
||||||
!sk->sk_rx_skb_cache) {
|
!sk->sk_rx_skb_cache) {
|
||||||
sk->sk_rx_skb_cache = skb;
|
sk->sk_rx_skb_cache = skb;
|
||||||
skb_orphan(skb);
|
skb_orphan(skb);
|
||||||
|
@ -2534,6 +2534,8 @@ extern int sysctl_optmem_max;
|
||||||
extern __u32 sysctl_wmem_default;
|
extern __u32 sysctl_wmem_default;
|
||||||
extern __u32 sysctl_rmem_default;
|
extern __u32 sysctl_rmem_default;
|
||||||
|
|
||||||
|
DECLARE_STATIC_KEY_FALSE(net_high_order_alloc_disable_key);
|
||||||
|
|
||||||
static inline int sk_get_wmem0(const struct sock *sk, const struct proto *proto)
|
static inline int sk_get_wmem0(const struct sock *sk, const struct proto *proto)
|
||||||
{
|
{
|
||||||
/* Does this proto have per netns sysctl_wmem ? */
|
/* Does this proto have per netns sysctl_wmem ? */
|
||||||
|
|
|
@ -51,6 +51,8 @@ void tcp_time_wait(struct sock *sk, int state, int timeo);
|
||||||
|
|
||||||
#define MAX_TCP_HEADER (128 + MAX_HEADER)
|
#define MAX_TCP_HEADER (128 + MAX_HEADER)
|
||||||
#define MAX_TCP_OPTION_SPACE 40
|
#define MAX_TCP_OPTION_SPACE 40
|
||||||
|
#define TCP_MIN_SND_MSS 48
|
||||||
|
#define TCP_MIN_GSO_SIZE (TCP_MIN_SND_MSS - MAX_TCP_OPTION_SPACE)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Never offer a window over 32767 without using window scaling. Some
|
* Never offer a window over 32767 without using window scaling. Some
|
||||||
|
|
|
@ -192,6 +192,8 @@ enum bpf_attach_type {
|
||||||
BPF_LIRC_MODE2,
|
BPF_LIRC_MODE2,
|
||||||
BPF_FLOW_DISSECTOR,
|
BPF_FLOW_DISSECTOR,
|
||||||
BPF_CGROUP_SYSCTL,
|
BPF_CGROUP_SYSCTL,
|
||||||
|
BPF_CGROUP_UDP4_RECVMSG,
|
||||||
|
BPF_CGROUP_UDP6_RECVMSG,
|
||||||
__MAX_BPF_ATTACH_TYPE
|
__MAX_BPF_ATTACH_TYPE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3376,8 +3378,8 @@ struct bpf_raw_tracepoint_args {
|
||||||
/* DIRECT: Skip the FIB rules and go to FIB table associated with device
|
/* DIRECT: Skip the FIB rules and go to FIB table associated with device
|
||||||
* OUTPUT: Do lookup from egress perspective; default is ingress
|
* OUTPUT: Do lookup from egress perspective; default is ingress
|
||||||
*/
|
*/
|
||||||
#define BPF_FIB_LOOKUP_DIRECT BIT(0)
|
#define BPF_FIB_LOOKUP_DIRECT (1U << 0)
|
||||||
#define BPF_FIB_LOOKUP_OUTPUT BIT(1)
|
#define BPF_FIB_LOOKUP_OUTPUT (1U << 1)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
BPF_FIB_LKUP_RET_SUCCESS, /* lookup successful */
|
BPF_FIB_LKUP_RET_SUCCESS, /* lookup successful */
|
||||||
|
|
|
@ -283,6 +283,7 @@ enum
|
||||||
LINUX_MIB_TCPACKCOMPRESSED, /* TCPAckCompressed */
|
LINUX_MIB_TCPACKCOMPRESSED, /* TCPAckCompressed */
|
||||||
LINUX_MIB_TCPZEROWINDOWDROP, /* TCPZeroWindowDrop */
|
LINUX_MIB_TCPZEROWINDOWDROP, /* TCPZeroWindowDrop */
|
||||||
LINUX_MIB_TCPRCVQDROP, /* TCPRcvQDrop */
|
LINUX_MIB_TCPRCVQDROP, /* TCPRcvQDrop */
|
||||||
|
LINUX_MIB_TCPWQUEUETOOBIG, /* TCPWqueueTooBig */
|
||||||
__LINUX_MIB_MAX
|
__LINUX_MIB_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2097,7 +2097,6 @@ int __weak skb_copy_bits(const struct sk_buff *skb, int offset, void *to,
|
||||||
|
|
||||||
DEFINE_STATIC_KEY_FALSE(bpf_stats_enabled_key);
|
DEFINE_STATIC_KEY_FALSE(bpf_stats_enabled_key);
|
||||||
EXPORT_SYMBOL(bpf_stats_enabled_key);
|
EXPORT_SYMBOL(bpf_stats_enabled_key);
|
||||||
int sysctl_bpf_stats_enabled __read_mostly;
|
|
||||||
|
|
||||||
/* All definitions of tracepoints related to BPF. */
|
/* All definitions of tracepoints related to BPF. */
|
||||||
#define CREATE_TRACE_POINTS
|
#define CREATE_TRACE_POINTS
|
||||||
|
|
|
@ -178,6 +178,7 @@ static void dev_map_free(struct bpf_map *map)
|
||||||
if (!dev)
|
if (!dev)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
free_percpu(dev->bulkq);
|
||||||
dev_put(dev->dev);
|
dev_put(dev->dev);
|
||||||
kfree(dev);
|
kfree(dev);
|
||||||
}
|
}
|
||||||
|
@ -273,6 +274,7 @@ void __dev_map_flush(struct bpf_map *map)
|
||||||
unsigned long *bitmap = this_cpu_ptr(dtab->flush_needed);
|
unsigned long *bitmap = this_cpu_ptr(dtab->flush_needed);
|
||||||
u32 bit;
|
u32 bit;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
for_each_set_bit(bit, bitmap, map->max_entries) {
|
for_each_set_bit(bit, bitmap, map->max_entries) {
|
||||||
struct bpf_dtab_netdev *dev = READ_ONCE(dtab->netdev_map[bit]);
|
struct bpf_dtab_netdev *dev = READ_ONCE(dtab->netdev_map[bit]);
|
||||||
struct xdp_bulk_queue *bq;
|
struct xdp_bulk_queue *bq;
|
||||||
|
@ -283,11 +285,12 @@ void __dev_map_flush(struct bpf_map *map)
|
||||||
if (unlikely(!dev))
|
if (unlikely(!dev))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
__clear_bit(bit, bitmap);
|
|
||||||
|
|
||||||
bq = this_cpu_ptr(dev->bulkq);
|
bq = this_cpu_ptr(dev->bulkq);
|
||||||
bq_xmit_all(dev, bq, XDP_XMIT_FLUSH, true);
|
bq_xmit_all(dev, bq, XDP_XMIT_FLUSH, true);
|
||||||
|
|
||||||
|
__clear_bit(bit, bitmap);
|
||||||
}
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* rcu_read_lock (from syscall and BPF contexts) ensures that if a delete and/or
|
/* rcu_read_lock (from syscall and BPF contexts) ensures that if a delete and/or
|
||||||
|
@ -380,6 +383,7 @@ static void dev_map_flush_old(struct bpf_dtab_netdev *dev)
|
||||||
|
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
for_each_online_cpu(cpu) {
|
for_each_online_cpu(cpu) {
|
||||||
bitmap = per_cpu_ptr(dev->dtab->flush_needed, cpu);
|
bitmap = per_cpu_ptr(dev->dtab->flush_needed, cpu);
|
||||||
__clear_bit(dev->bit, bitmap);
|
__clear_bit(dev->bit, bitmap);
|
||||||
|
@ -387,6 +391,7 @@ static void dev_map_flush_old(struct bpf_dtab_netdev *dev)
|
||||||
bq = per_cpu_ptr(dev->bulkq, cpu);
|
bq = per_cpu_ptr(dev->bulkq, cpu);
|
||||||
bq_xmit_all(dev, bq, XDP_XMIT_FLUSH, false);
|
bq_xmit_all(dev, bq, XDP_XMIT_FLUSH, false);
|
||||||
}
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -716,9 +716,14 @@ find_leftmost:
|
||||||
* have exact two children, so this function will never return NULL.
|
* have exact two children, so this function will never return NULL.
|
||||||
*/
|
*/
|
||||||
for (node = search_root; node;) {
|
for (node = search_root; node;) {
|
||||||
if (!(node->flags & LPM_TREE_NODE_FLAG_IM))
|
if (node->flags & LPM_TREE_NODE_FLAG_IM) {
|
||||||
|
node = rcu_dereference(node->child[0]);
|
||||||
|
} else {
|
||||||
next_node = node;
|
next_node = node;
|
||||||
node = rcu_dereference(node->child[0]);
|
node = rcu_dereference(node->child[0]);
|
||||||
|
if (!node)
|
||||||
|
node = rcu_dereference(next_node->child[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
do_copy:
|
do_copy:
|
||||||
next_key->prefixlen = next_node->prefixlen;
|
next_key->prefixlen = next_node->prefixlen;
|
||||||
|
|
|
@ -1573,6 +1573,8 @@ bpf_prog_load_check_attach_type(enum bpf_prog_type prog_type,
|
||||||
case BPF_CGROUP_INET6_CONNECT:
|
case BPF_CGROUP_INET6_CONNECT:
|
||||||
case BPF_CGROUP_UDP4_SENDMSG:
|
case BPF_CGROUP_UDP4_SENDMSG:
|
||||||
case BPF_CGROUP_UDP6_SENDMSG:
|
case BPF_CGROUP_UDP6_SENDMSG:
|
||||||
|
case BPF_CGROUP_UDP4_RECVMSG:
|
||||||
|
case BPF_CGROUP_UDP6_RECVMSG:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1867,6 +1869,8 @@ static int bpf_prog_attach(const union bpf_attr *attr)
|
||||||
case BPF_CGROUP_INET6_CONNECT:
|
case BPF_CGROUP_INET6_CONNECT:
|
||||||
case BPF_CGROUP_UDP4_SENDMSG:
|
case BPF_CGROUP_UDP4_SENDMSG:
|
||||||
case BPF_CGROUP_UDP6_SENDMSG:
|
case BPF_CGROUP_UDP6_SENDMSG:
|
||||||
|
case BPF_CGROUP_UDP4_RECVMSG:
|
||||||
|
case BPF_CGROUP_UDP6_RECVMSG:
|
||||||
ptype = BPF_PROG_TYPE_CGROUP_SOCK_ADDR;
|
ptype = BPF_PROG_TYPE_CGROUP_SOCK_ADDR;
|
||||||
break;
|
break;
|
||||||
case BPF_CGROUP_SOCK_OPS:
|
case BPF_CGROUP_SOCK_OPS:
|
||||||
|
@ -1952,6 +1956,8 @@ static int bpf_prog_detach(const union bpf_attr *attr)
|
||||||
case BPF_CGROUP_INET6_CONNECT:
|
case BPF_CGROUP_INET6_CONNECT:
|
||||||
case BPF_CGROUP_UDP4_SENDMSG:
|
case BPF_CGROUP_UDP4_SENDMSG:
|
||||||
case BPF_CGROUP_UDP6_SENDMSG:
|
case BPF_CGROUP_UDP6_SENDMSG:
|
||||||
|
case BPF_CGROUP_UDP4_RECVMSG:
|
||||||
|
case BPF_CGROUP_UDP6_RECVMSG:
|
||||||
ptype = BPF_PROG_TYPE_CGROUP_SOCK_ADDR;
|
ptype = BPF_PROG_TYPE_CGROUP_SOCK_ADDR;
|
||||||
break;
|
break;
|
||||||
case BPF_CGROUP_SOCK_OPS:
|
case BPF_CGROUP_SOCK_OPS:
|
||||||
|
@ -2003,6 +2009,8 @@ static int bpf_prog_query(const union bpf_attr *attr,
|
||||||
case BPF_CGROUP_INET6_CONNECT:
|
case BPF_CGROUP_INET6_CONNECT:
|
||||||
case BPF_CGROUP_UDP4_SENDMSG:
|
case BPF_CGROUP_UDP4_SENDMSG:
|
||||||
case BPF_CGROUP_UDP6_SENDMSG:
|
case BPF_CGROUP_UDP6_SENDMSG:
|
||||||
|
case BPF_CGROUP_UDP4_RECVMSG:
|
||||||
|
case BPF_CGROUP_UDP6_RECVMSG:
|
||||||
case BPF_CGROUP_SOCK_OPS:
|
case BPF_CGROUP_SOCK_OPS:
|
||||||
case BPF_CGROUP_DEVICE:
|
case BPF_CGROUP_DEVICE:
|
||||||
case BPF_CGROUP_SYSCTL:
|
case BPF_CGROUP_SYSCTL:
|
||||||
|
|
|
@ -5353,9 +5353,12 @@ static int check_return_code(struct bpf_verifier_env *env)
|
||||||
struct tnum range = tnum_range(0, 1);
|
struct tnum range = tnum_range(0, 1);
|
||||||
|
|
||||||
switch (env->prog->type) {
|
switch (env->prog->type) {
|
||||||
|
case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
|
||||||
|
if (env->prog->expected_attach_type == BPF_CGROUP_UDP4_RECVMSG ||
|
||||||
|
env->prog->expected_attach_type == BPF_CGROUP_UDP6_RECVMSG)
|
||||||
|
range = tnum_range(1, 1);
|
||||||
case BPF_PROG_TYPE_CGROUP_SKB:
|
case BPF_PROG_TYPE_CGROUP_SKB:
|
||||||
case BPF_PROG_TYPE_CGROUP_SOCK:
|
case BPF_PROG_TYPE_CGROUP_SOCK:
|
||||||
case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
|
|
||||||
case BPF_PROG_TYPE_SOCK_OPS:
|
case BPF_PROG_TYPE_SOCK_OPS:
|
||||||
case BPF_PROG_TYPE_CGROUP_DEVICE:
|
case BPF_PROG_TYPE_CGROUP_DEVICE:
|
||||||
case BPF_PROG_TYPE_CGROUP_SYSCTL:
|
case BPF_PROG_TYPE_CGROUP_SYSCTL:
|
||||||
|
@ -5372,16 +5375,17 @@ static int check_return_code(struct bpf_verifier_env *env)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tnum_in(range, reg->var_off)) {
|
if (!tnum_in(range, reg->var_off)) {
|
||||||
verbose(env, "At program exit the register R0 ");
|
|
||||||
if (!tnum_is_unknown(reg->var_off)) {
|
|
||||||
char tn_buf[48];
|
char tn_buf[48];
|
||||||
|
|
||||||
|
verbose(env, "At program exit the register R0 ");
|
||||||
|
if (!tnum_is_unknown(reg->var_off)) {
|
||||||
tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
|
tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
|
||||||
verbose(env, "has value %s", tn_buf);
|
verbose(env, "has value %s", tn_buf);
|
||||||
} else {
|
} else {
|
||||||
verbose(env, "has unknown scalar value");
|
verbose(env, "has unknown scalar value");
|
||||||
}
|
}
|
||||||
verbose(env, " should have been 0 or 1\n");
|
tnum_strn(tn_buf, sizeof(tn_buf), range);
|
||||||
|
verbose(env, " should have been in %s\n", tn_buf);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -230,11 +230,6 @@ static int proc_dostring_coredump(struct ctl_table *table, int write,
|
||||||
#endif
|
#endif
|
||||||
static int proc_dopipe_max_size(struct ctl_table *table, int write,
|
static int proc_dopipe_max_size(struct ctl_table *table, int write,
|
||||||
void __user *buffer, size_t *lenp, loff_t *ppos);
|
void __user *buffer, size_t *lenp, loff_t *ppos);
|
||||||
#ifdef CONFIG_BPF_SYSCALL
|
|
||||||
static int proc_dointvec_minmax_bpf_stats(struct ctl_table *table, int write,
|
|
||||||
void __user *buffer, size_t *lenp,
|
|
||||||
loff_t *ppos);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_MAGIC_SYSRQ
|
#ifdef CONFIG_MAGIC_SYSRQ
|
||||||
/* Note: sysrq code uses its own private copy */
|
/* Note: sysrq code uses its own private copy */
|
||||||
|
@ -1253,12 +1248,10 @@ static struct ctl_table kern_table[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.procname = "bpf_stats_enabled",
|
.procname = "bpf_stats_enabled",
|
||||||
.data = &sysctl_bpf_stats_enabled,
|
.data = &bpf_stats_enabled_key.key,
|
||||||
.maxlen = sizeof(sysctl_bpf_stats_enabled),
|
.maxlen = sizeof(bpf_stats_enabled_key),
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = proc_dointvec_minmax_bpf_stats,
|
.proc_handler = proc_do_static_key,
|
||||||
.extra1 = &zero,
|
|
||||||
.extra2 = &one,
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_TREE_RCU) || defined(CONFIG_PREEMPT_RCU)
|
#if defined(CONFIG_TREE_RCU) || defined(CONFIG_PREEMPT_RCU)
|
||||||
|
@ -3374,26 +3367,35 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
|
||||||
|
|
||||||
#endif /* CONFIG_PROC_SYSCTL */
|
#endif /* CONFIG_PROC_SYSCTL */
|
||||||
|
|
||||||
#if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_SYSCTL)
|
#if defined(CONFIG_SYSCTL)
|
||||||
static int proc_dointvec_minmax_bpf_stats(struct ctl_table *table, int write,
|
int proc_do_static_key(struct ctl_table *table, int write,
|
||||||
void __user *buffer, size_t *lenp,
|
void __user *buffer, size_t *lenp,
|
||||||
loff_t *ppos)
|
loff_t *ppos)
|
||||||
{
|
{
|
||||||
int ret, bpf_stats = *(int *)table->data;
|
struct static_key *key = (struct static_key *)table->data;
|
||||||
struct ctl_table tmp = *table;
|
static DEFINE_MUTEX(static_key_mutex);
|
||||||
|
int val, ret;
|
||||||
|
struct ctl_table tmp = {
|
||||||
|
.data = &val,
|
||||||
|
.maxlen = sizeof(val),
|
||||||
|
.mode = table->mode,
|
||||||
|
.extra1 = &zero,
|
||||||
|
.extra2 = &one,
|
||||||
|
};
|
||||||
|
|
||||||
if (write && !capable(CAP_SYS_ADMIN))
|
if (write && !capable(CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
tmp.data = &bpf_stats;
|
mutex_lock(&static_key_mutex);
|
||||||
|
val = static_key_enabled(key);
|
||||||
ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
|
ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
|
||||||
if (write && !ret) {
|
if (write && !ret) {
|
||||||
*(int *)table->data = bpf_stats;
|
if (val)
|
||||||
if (bpf_stats)
|
static_key_enable(key);
|
||||||
static_branch_enable(&bpf_stats_enabled_key);
|
|
||||||
else
|
else
|
||||||
static_branch_disable(&bpf_stats_enabled_key);
|
static_key_disable(key);
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&static_key_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -410,8 +410,6 @@ static const struct bpf_func_proto bpf_perf_event_read_value_proto = {
|
||||||
.arg4_type = ARG_CONST_SIZE,
|
.arg4_type = ARG_CONST_SIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static DEFINE_PER_CPU(struct perf_sample_data, bpf_trace_sd);
|
|
||||||
|
|
||||||
static __always_inline u64
|
static __always_inline u64
|
||||||
__bpf_perf_event_output(struct pt_regs *regs, struct bpf_map *map,
|
__bpf_perf_event_output(struct pt_regs *regs, struct bpf_map *map,
|
||||||
u64 flags, struct perf_sample_data *sd)
|
u64 flags, struct perf_sample_data *sd)
|
||||||
|
@ -442,24 +440,50 @@ __bpf_perf_event_output(struct pt_regs *regs, struct bpf_map *map,
|
||||||
return perf_event_output(event, sd, regs);
|
return perf_event_output(event, sd, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Support executing tracepoints in normal, irq, and nmi context that each call
|
||||||
|
* bpf_perf_event_output
|
||||||
|
*/
|
||||||
|
struct bpf_trace_sample_data {
|
||||||
|
struct perf_sample_data sds[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
static DEFINE_PER_CPU(struct bpf_trace_sample_data, bpf_trace_sds);
|
||||||
|
static DEFINE_PER_CPU(int, bpf_trace_nest_level);
|
||||||
BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map,
|
BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map,
|
||||||
u64, flags, void *, data, u64, size)
|
u64, flags, void *, data, u64, size)
|
||||||
{
|
{
|
||||||
struct perf_sample_data *sd = this_cpu_ptr(&bpf_trace_sd);
|
struct bpf_trace_sample_data *sds = this_cpu_ptr(&bpf_trace_sds);
|
||||||
|
int nest_level = this_cpu_inc_return(bpf_trace_nest_level);
|
||||||
struct perf_raw_record raw = {
|
struct perf_raw_record raw = {
|
||||||
.frag = {
|
.frag = {
|
||||||
.size = size,
|
.size = size,
|
||||||
.data = data,
|
.data = data,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
struct perf_sample_data *sd;
|
||||||
|
int err;
|
||||||
|
|
||||||
if (unlikely(flags & ~(BPF_F_INDEX_MASK)))
|
if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(sds->sds))) {
|
||||||
return -EINVAL;
|
err = -EBUSY;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
sd = &sds->sds[nest_level - 1];
|
||||||
|
|
||||||
|
if (unlikely(flags & ~(BPF_F_INDEX_MASK))) {
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
perf_sample_data_init(sd, 0, 0);
|
perf_sample_data_init(sd, 0, 0);
|
||||||
sd->raw = &raw;
|
sd->raw = &raw;
|
||||||
|
|
||||||
return __bpf_perf_event_output(regs, map, flags, sd);
|
err = __bpf_perf_event_output(regs, map, flags, sd);
|
||||||
|
|
||||||
|
out:
|
||||||
|
this_cpu_dec(bpf_trace_nest_level);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct bpf_func_proto bpf_perf_event_output_proto = {
|
static const struct bpf_func_proto bpf_perf_event_output_proto = {
|
||||||
|
@ -822,16 +846,48 @@ pe_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
|
||||||
/*
|
/*
|
||||||
* bpf_raw_tp_regs are separate from bpf_pt_regs used from skb/xdp
|
* bpf_raw_tp_regs are separate from bpf_pt_regs used from skb/xdp
|
||||||
* to avoid potential recursive reuse issue when/if tracepoints are added
|
* to avoid potential recursive reuse issue when/if tracepoints are added
|
||||||
* inside bpf_*_event_output, bpf_get_stackid and/or bpf_get_stack
|
* inside bpf_*_event_output, bpf_get_stackid and/or bpf_get_stack.
|
||||||
|
*
|
||||||
|
* Since raw tracepoints run despite bpf_prog_active, support concurrent usage
|
||||||
|
* in normal, irq, and nmi context.
|
||||||
*/
|
*/
|
||||||
static DEFINE_PER_CPU(struct pt_regs, bpf_raw_tp_regs);
|
struct bpf_raw_tp_regs {
|
||||||
|
struct pt_regs regs[3];
|
||||||
|
};
|
||||||
|
static DEFINE_PER_CPU(struct bpf_raw_tp_regs, bpf_raw_tp_regs);
|
||||||
|
static DEFINE_PER_CPU(int, bpf_raw_tp_nest_level);
|
||||||
|
static struct pt_regs *get_bpf_raw_tp_regs(void)
|
||||||
|
{
|
||||||
|
struct bpf_raw_tp_regs *tp_regs = this_cpu_ptr(&bpf_raw_tp_regs);
|
||||||
|
int nest_level = this_cpu_inc_return(bpf_raw_tp_nest_level);
|
||||||
|
|
||||||
|
if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(tp_regs->regs))) {
|
||||||
|
this_cpu_dec(bpf_raw_tp_nest_level);
|
||||||
|
return ERR_PTR(-EBUSY);
|
||||||
|
}
|
||||||
|
|
||||||
|
return &tp_regs->regs[nest_level - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_bpf_raw_tp_regs(void)
|
||||||
|
{
|
||||||
|
this_cpu_dec(bpf_raw_tp_nest_level);
|
||||||
|
}
|
||||||
|
|
||||||
BPF_CALL_5(bpf_perf_event_output_raw_tp, struct bpf_raw_tracepoint_args *, args,
|
BPF_CALL_5(bpf_perf_event_output_raw_tp, struct bpf_raw_tracepoint_args *, args,
|
||||||
struct bpf_map *, map, u64, flags, void *, data, u64, size)
|
struct bpf_map *, map, u64, flags, void *, data, u64, size)
|
||||||
{
|
{
|
||||||
struct pt_regs *regs = this_cpu_ptr(&bpf_raw_tp_regs);
|
struct pt_regs *regs = get_bpf_raw_tp_regs();
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (IS_ERR(regs))
|
||||||
|
return PTR_ERR(regs);
|
||||||
|
|
||||||
perf_fetch_caller_regs(regs);
|
perf_fetch_caller_regs(regs);
|
||||||
return ____bpf_perf_event_output(regs, map, flags, data, size);
|
ret = ____bpf_perf_event_output(regs, map, flags, data, size);
|
||||||
|
|
||||||
|
put_bpf_raw_tp_regs();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct bpf_func_proto bpf_perf_event_output_proto_raw_tp = {
|
static const struct bpf_func_proto bpf_perf_event_output_proto_raw_tp = {
|
||||||
|
@ -848,12 +904,18 @@ static const struct bpf_func_proto bpf_perf_event_output_proto_raw_tp = {
|
||||||
BPF_CALL_3(bpf_get_stackid_raw_tp, struct bpf_raw_tracepoint_args *, args,
|
BPF_CALL_3(bpf_get_stackid_raw_tp, struct bpf_raw_tracepoint_args *, args,
|
||||||
struct bpf_map *, map, u64, flags)
|
struct bpf_map *, map, u64, flags)
|
||||||
{
|
{
|
||||||
struct pt_regs *regs = this_cpu_ptr(&bpf_raw_tp_regs);
|
struct pt_regs *regs = get_bpf_raw_tp_regs();
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (IS_ERR(regs))
|
||||||
|
return PTR_ERR(regs);
|
||||||
|
|
||||||
perf_fetch_caller_regs(regs);
|
perf_fetch_caller_regs(regs);
|
||||||
/* similar to bpf_perf_event_output_tp, but pt_regs fetched differently */
|
/* similar to bpf_perf_event_output_tp, but pt_regs fetched differently */
|
||||||
return bpf_get_stackid((unsigned long) regs, (unsigned long) map,
|
ret = bpf_get_stackid((unsigned long) regs, (unsigned long) map,
|
||||||
flags, 0, 0);
|
flags, 0, 0);
|
||||||
|
put_bpf_raw_tp_regs();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct bpf_func_proto bpf_get_stackid_proto_raw_tp = {
|
static const struct bpf_func_proto bpf_get_stackid_proto_raw_tp = {
|
||||||
|
@ -868,11 +930,17 @@ static const struct bpf_func_proto bpf_get_stackid_proto_raw_tp = {
|
||||||
BPF_CALL_4(bpf_get_stack_raw_tp, struct bpf_raw_tracepoint_args *, args,
|
BPF_CALL_4(bpf_get_stack_raw_tp, struct bpf_raw_tracepoint_args *, args,
|
||||||
void *, buf, u32, size, u64, flags)
|
void *, buf, u32, size, u64, flags)
|
||||||
{
|
{
|
||||||
struct pt_regs *regs = this_cpu_ptr(&bpf_raw_tp_regs);
|
struct pt_regs *regs = get_bpf_raw_tp_regs();
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (IS_ERR(regs))
|
||||||
|
return PTR_ERR(regs);
|
||||||
|
|
||||||
perf_fetch_caller_regs(regs);
|
perf_fetch_caller_regs(regs);
|
||||||
return bpf_get_stack((unsigned long) regs, (unsigned long) buf,
|
ret = bpf_get_stack((unsigned long) regs, (unsigned long) buf,
|
||||||
(unsigned long) size, flags, 0);
|
(unsigned long) size, flags, 0);
|
||||||
|
put_bpf_raw_tp_regs();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct bpf_func_proto bpf_get_stack_proto_raw_tp = {
|
static const struct bpf_func_proto bpf_get_stack_proto_raw_tp = {
|
||||||
|
|
|
@ -426,9 +426,11 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ax25->sk != NULL) {
|
if (ax25->sk != NULL) {
|
||||||
|
local_bh_disable();
|
||||||
bh_lock_sock(ax25->sk);
|
bh_lock_sock(ax25->sk);
|
||||||
sock_reset_flag(ax25->sk, SOCK_ZAPPED);
|
sock_reset_flag(ax25->sk, SOCK_ZAPPED);
|
||||||
bh_unlock_sock(ax25->sk);
|
bh_unlock_sock(ax25->sk);
|
||||||
|
local_bh_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
put:
|
put:
|
||||||
|
|
|
@ -99,6 +99,7 @@ EXPORT_SYMBOL(can_ioctl);
|
||||||
static void can_sock_destruct(struct sock *sk)
|
static void can_sock_destruct(struct sock *sk)
|
||||||
{
|
{
|
||||||
skb_queue_purge(&sk->sk_receive_queue);
|
skb_queue_purge(&sk->sk_receive_queue);
|
||||||
|
skb_queue_purge(&sk->sk_error_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct can_proto *can_get_proto(int protocol)
|
static const struct can_proto *can_get_proto(int protocol)
|
||||||
|
@ -952,6 +953,8 @@ static struct pernet_operations can_pernet_ops __read_mostly = {
|
||||||
|
|
||||||
static __init int can_init(void)
|
static __init int can_init(void)
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
/* check for correct padding to be able to use the structs similarly */
|
/* check for correct padding to be able to use the structs similarly */
|
||||||
BUILD_BUG_ON(offsetof(struct can_frame, can_dlc) !=
|
BUILD_BUG_ON(offsetof(struct can_frame, can_dlc) !=
|
||||||
offsetof(struct canfd_frame, len) ||
|
offsetof(struct canfd_frame, len) ||
|
||||||
|
@ -965,15 +968,31 @@ static __init int can_init(void)
|
||||||
if (!rcv_cache)
|
if (!rcv_cache)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
register_pernet_subsys(&can_pernet_ops);
|
err = register_pernet_subsys(&can_pernet_ops);
|
||||||
|
if (err)
|
||||||
|
goto out_pernet;
|
||||||
|
|
||||||
/* protocol register */
|
/* protocol register */
|
||||||
sock_register(&can_family_ops);
|
err = sock_register(&can_family_ops);
|
||||||
register_netdevice_notifier(&can_netdev_notifier);
|
if (err)
|
||||||
|
goto out_sock;
|
||||||
|
err = register_netdevice_notifier(&can_netdev_notifier);
|
||||||
|
if (err)
|
||||||
|
goto out_notifier;
|
||||||
|
|
||||||
dev_add_pack(&can_packet);
|
dev_add_pack(&can_packet);
|
||||||
dev_add_pack(&canfd_packet);
|
dev_add_pack(&canfd_packet);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
out_notifier:
|
||||||
|
sock_unregister(PF_CAN);
|
||||||
|
out_sock:
|
||||||
|
unregister_pernet_subsys(&can_pernet_ops);
|
||||||
|
out_pernet:
|
||||||
|
kmem_cache_destroy(rcv_cache);
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __exit void can_exit(void)
|
static __exit void can_exit(void)
|
||||||
|
|
|
@ -633,7 +633,8 @@ static struct bpf_map *bpf_sk_storage_map_alloc(union bpf_attr *attr)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
bpf_map_init_from_attr(&smap->map, attr);
|
bpf_map_init_from_attr(&smap->map, attr);
|
||||||
|
|
||||||
smap->bucket_log = ilog2(roundup_pow_of_two(num_possible_cpus()));
|
/* Use at least 2 buckets, select_bucket() is undefined behavior with 1 bucket */
|
||||||
|
smap->bucket_log = max_t(u32, 1, ilog2(roundup_pow_of_two(num_possible_cpus())));
|
||||||
nbuckets = 1U << smap->bucket_log;
|
nbuckets = 1U << smap->bucket_log;
|
||||||
smap->buckets = kvcalloc(sizeof(*smap->buckets), nbuckets,
|
smap->buckets = kvcalloc(sizeof(*smap->buckets), nbuckets,
|
||||||
GFP_USER | __GFP_NOWARN);
|
GFP_USER | __GFP_NOWARN);
|
||||||
|
|
|
@ -4923,8 +4923,36 @@ skip_classify:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(skb_vlan_tag_present(skb))) {
|
if (unlikely(skb_vlan_tag_present(skb))) {
|
||||||
if (skb_vlan_tag_get_id(skb))
|
check_vlan_id:
|
||||||
|
if (skb_vlan_tag_get_id(skb)) {
|
||||||
|
/* Vlan id is non 0 and vlan_do_receive() above couldn't
|
||||||
|
* find vlan device.
|
||||||
|
*/
|
||||||
skb->pkt_type = PACKET_OTHERHOST;
|
skb->pkt_type = PACKET_OTHERHOST;
|
||||||
|
} else if (skb->protocol == cpu_to_be16(ETH_P_8021Q) ||
|
||||||
|
skb->protocol == cpu_to_be16(ETH_P_8021AD)) {
|
||||||
|
/* Outer header is 802.1P with vlan 0, inner header is
|
||||||
|
* 802.1Q or 802.1AD and vlan_do_receive() above could
|
||||||
|
* not find vlan dev for vlan id 0.
|
||||||
|
*/
|
||||||
|
__vlan_hwaccel_clear_tag(skb);
|
||||||
|
skb = skb_vlan_untag(skb);
|
||||||
|
if (unlikely(!skb))
|
||||||
|
goto out;
|
||||||
|
if (vlan_do_receive(&skb))
|
||||||
|
/* After stripping off 802.1P header with vlan 0
|
||||||
|
* vlan dev is found for inner header.
|
||||||
|
*/
|
||||||
|
goto another_round;
|
||||||
|
else if (unlikely(!skb))
|
||||||
|
goto out;
|
||||||
|
else
|
||||||
|
/* We have stripped outer 802.1P vlan 0 header.
|
||||||
|
* But could not find vlan dev.
|
||||||
|
* check again for vlan id to set OTHERHOST.
|
||||||
|
*/
|
||||||
|
goto check_vlan_id;
|
||||||
|
}
|
||||||
/* Note: we might in the future use prio bits
|
/* Note: we might in the future use prio bits
|
||||||
* and set skb->priority like in vlan_do_receive()
|
* and set skb->priority like in vlan_do_receive()
|
||||||
* For the time being, just ignore Priority Code Point
|
* For the time being, just ignore Priority Code Point
|
||||||
|
|
|
@ -3020,6 +3020,11 @@ ethtool_rx_flow_rule_create(const struct ethtool_rx_flow_spec_input *input)
|
||||||
match->mask.vlan.vlan_id =
|
match->mask.vlan.vlan_id =
|
||||||
ntohs(ext_m_spec->vlan_tci) & 0x0fff;
|
ntohs(ext_m_spec->vlan_tci) & 0x0fff;
|
||||||
|
|
||||||
|
match->key.vlan.vlan_dei =
|
||||||
|
!!(ext_h_spec->vlan_tci & htons(0x1000));
|
||||||
|
match->mask.vlan.vlan_dei =
|
||||||
|
!!(ext_m_spec->vlan_tci & htons(0x1000));
|
||||||
|
|
||||||
match->key.vlan.vlan_priority =
|
match->key.vlan.vlan_priority =
|
||||||
(ntohs(ext_h_spec->vlan_tci) & 0xe000) >> 13;
|
(ntohs(ext_h_spec->vlan_tci) & 0xe000) >> 13;
|
||||||
match->mask.vlan.vlan_priority =
|
match->mask.vlan.vlan_priority =
|
||||||
|
|
|
@ -5300,7 +5300,13 @@ __bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
|
||||||
struct net *net;
|
struct net *net;
|
||||||
int sdif;
|
int sdif;
|
||||||
|
|
||||||
family = len == sizeof(tuple->ipv4) ? AF_INET : AF_INET6;
|
if (len == sizeof(tuple->ipv4))
|
||||||
|
family = AF_INET;
|
||||||
|
else if (len == sizeof(tuple->ipv6))
|
||||||
|
family = AF_INET6;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (unlikely(family == AF_UNSPEC || flags ||
|
if (unlikely(family == AF_UNSPEC || flags ||
|
||||||
!((s32)netns_id < 0 || netns_id <= S32_MAX)))
|
!((s32)netns_id < 0 || netns_id <= S32_MAX)))
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -5333,8 +5339,14 @@ __bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
|
||||||
struct sock *sk = __bpf_skc_lookup(skb, tuple, len, caller_net,
|
struct sock *sk = __bpf_skc_lookup(skb, tuple, len, caller_net,
|
||||||
ifindex, proto, netns_id, flags);
|
ifindex, proto, netns_id, flags);
|
||||||
|
|
||||||
if (sk)
|
if (sk) {
|
||||||
sk = sk_to_full_sk(sk);
|
sk = sk_to_full_sk(sk);
|
||||||
|
if (!sk_fullsock(sk)) {
|
||||||
|
if (!sock_flag(sk, SOCK_RCU_FREE))
|
||||||
|
sock_gen_put(sk);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return sk;
|
return sk;
|
||||||
}
|
}
|
||||||
|
@ -5365,8 +5377,14 @@ bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
|
||||||
struct sock *sk = bpf_skc_lookup(skb, tuple, len, proto, netns_id,
|
struct sock *sk = bpf_skc_lookup(skb, tuple, len, proto, netns_id,
|
||||||
flags);
|
flags);
|
||||||
|
|
||||||
if (sk)
|
if (sk) {
|
||||||
sk = sk_to_full_sk(sk);
|
sk = sk_to_full_sk(sk);
|
||||||
|
if (!sk_fullsock(sk)) {
|
||||||
|
if (!sock_flag(sk, SOCK_RCU_FREE))
|
||||||
|
sock_gen_put(sk);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return sk;
|
return sk;
|
||||||
}
|
}
|
||||||
|
@ -6726,6 +6744,7 @@ static bool sock_addr_is_valid_access(int off, int size,
|
||||||
case BPF_CGROUP_INET4_BIND:
|
case BPF_CGROUP_INET4_BIND:
|
||||||
case BPF_CGROUP_INET4_CONNECT:
|
case BPF_CGROUP_INET4_CONNECT:
|
||||||
case BPF_CGROUP_UDP4_SENDMSG:
|
case BPF_CGROUP_UDP4_SENDMSG:
|
||||||
|
case BPF_CGROUP_UDP4_RECVMSG:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -6736,6 +6755,7 @@ static bool sock_addr_is_valid_access(int off, int size,
|
||||||
case BPF_CGROUP_INET6_BIND:
|
case BPF_CGROUP_INET6_BIND:
|
||||||
case BPF_CGROUP_INET6_CONNECT:
|
case BPF_CGROUP_INET6_CONNECT:
|
||||||
case BPF_CGROUP_UDP6_SENDMSG:
|
case BPF_CGROUP_UDP6_SENDMSG:
|
||||||
|
case BPF_CGROUP_UDP6_RECVMSG:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -3203,6 +3203,7 @@ static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags)
|
void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags)
|
||||||
|
__acquires(tbl->lock)
|
||||||
__acquires(rcu_bh)
|
__acquires(rcu_bh)
|
||||||
{
|
{
|
||||||
struct neigh_seq_state *state = seq->private;
|
struct neigh_seq_state *state = seq->private;
|
||||||
|
@ -3213,6 +3214,7 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl
|
||||||
|
|
||||||
rcu_read_lock_bh();
|
rcu_read_lock_bh();
|
||||||
state->nht = rcu_dereference_bh(tbl->nht);
|
state->nht = rcu_dereference_bh(tbl->nht);
|
||||||
|
read_lock(&tbl->lock);
|
||||||
|
|
||||||
return *pos ? neigh_get_idx_any(seq, pos) : SEQ_START_TOKEN;
|
return *pos ? neigh_get_idx_any(seq, pos) : SEQ_START_TOKEN;
|
||||||
}
|
}
|
||||||
|
@ -3246,8 +3248,13 @@ out:
|
||||||
EXPORT_SYMBOL(neigh_seq_next);
|
EXPORT_SYMBOL(neigh_seq_next);
|
||||||
|
|
||||||
void neigh_seq_stop(struct seq_file *seq, void *v)
|
void neigh_seq_stop(struct seq_file *seq, void *v)
|
||||||
|
__releases(tbl->lock)
|
||||||
__releases(rcu_bh)
|
__releases(rcu_bh)
|
||||||
{
|
{
|
||||||
|
struct neigh_seq_state *state = seq->private;
|
||||||
|
struct neigh_table *tbl = state->tbl;
|
||||||
|
|
||||||
|
read_unlock(&tbl->lock);
|
||||||
rcu_read_unlock_bh();
|
rcu_read_unlock_bh();
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(neigh_seq_stop);
|
EXPORT_SYMBOL(neigh_seq_stop);
|
||||||
|
|
|
@ -2337,6 +2337,7 @@ do_frag_list:
|
||||||
kv.iov_base = skb->data + offset;
|
kv.iov_base = skb->data + offset;
|
||||||
kv.iov_len = slen;
|
kv.iov_len = slen;
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
|
msg.msg_flags = MSG_DONTWAIT;
|
||||||
|
|
||||||
ret = kernel_sendmsg_locked(sk, &msg, &kv, 1, slen);
|
ret = kernel_sendmsg_locked(sk, &msg, &kv, 1, slen);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
|
|
|
@ -1850,6 +1850,9 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
RCU_INIT_POINTER(newsk->sk_reuseport_cb, NULL);
|
RCU_INIT_POINTER(newsk->sk_reuseport_cb, NULL);
|
||||||
|
#ifdef CONFIG_BPF_SYSCALL
|
||||||
|
RCU_INIT_POINTER(newsk->sk_bpf_storage, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
newsk->sk_err = 0;
|
newsk->sk_err = 0;
|
||||||
newsk->sk_err_soft = 0;
|
newsk->sk_err_soft = 0;
|
||||||
|
@ -2320,6 +2323,7 @@ static void sk_leave_memory_pressure(struct sock *sk)
|
||||||
|
|
||||||
/* On 32bit arches, an skb frag is limited to 2^15 */
|
/* On 32bit arches, an skb frag is limited to 2^15 */
|
||||||
#define SKB_FRAG_PAGE_ORDER get_order(32768)
|
#define SKB_FRAG_PAGE_ORDER get_order(32768)
|
||||||
|
DEFINE_STATIC_KEY_FALSE(net_high_order_alloc_disable_key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* skb_page_frag_refill - check that a page_frag contains enough room
|
* skb_page_frag_refill - check that a page_frag contains enough room
|
||||||
|
@ -2344,7 +2348,8 @@ bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t gfp)
|
||||||
}
|
}
|
||||||
|
|
||||||
pfrag->offset = 0;
|
pfrag->offset = 0;
|
||||||
if (SKB_FRAG_PAGE_ORDER) {
|
if (SKB_FRAG_PAGE_ORDER &&
|
||||||
|
!static_branch_unlikely(&net_high_order_alloc_disable_key)) {
|
||||||
/* Avoid direct reclaim but allow kswapd to wake */
|
/* Avoid direct reclaim but allow kswapd to wake */
|
||||||
pfrag->page = alloc_pages((gfp & ~__GFP_DIRECT_RECLAIM) |
|
pfrag->page = alloc_pages((gfp & ~__GFP_DIRECT_RECLAIM) |
|
||||||
__GFP_COMP | __GFP_NOWARN |
|
__GFP_COMP | __GFP_NOWARN |
|
||||||
|
|
|
@ -562,6 +562,13 @@ static struct ctl_table net_core_table[] = {
|
||||||
.extra1 = &zero,
|
.extra1 = &zero,
|
||||||
.extra2 = &two,
|
.extra2 = &two,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.procname = "high_order_alloc_disable",
|
||||||
|
.data = &net_high_order_alloc_disable_key.key,
|
||||||
|
.maxlen = sizeof(net_high_order_alloc_disable_key),
|
||||||
|
.mode = 0644,
|
||||||
|
.proc_handler = proc_do_static_key,
|
||||||
|
},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -964,7 +964,7 @@ static int fib_check_nh_v4_gw(struct net *net, struct fib_nh *nh, u32 table,
|
||||||
{
|
{
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
struct fib_result res;
|
struct fib_result res;
|
||||||
int err;
|
int err = 0;
|
||||||
|
|
||||||
if (nh->fib_nh_flags & RTNH_F_ONLINK) {
|
if (nh->fib_nh_flags & RTNH_F_ONLINK) {
|
||||||
unsigned int addr_type;
|
unsigned int addr_type;
|
||||||
|
|
|
@ -918,7 +918,7 @@ static int __ip_append_data(struct sock *sk,
|
||||||
uarg = sock_zerocopy_realloc(sk, length, skb_zcopy(skb));
|
uarg = sock_zerocopy_realloc(sk, length, skb_zcopy(skb));
|
||||||
if (!uarg)
|
if (!uarg)
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
extra_uref = !skb; /* only extra ref if !MSG_MORE */
|
extra_uref = !skb_zcopy(skb); /* only ref on new uarg */
|
||||||
if (rt->dst.dev->features & NETIF_F_SG &&
|
if (rt->dst.dev->features & NETIF_F_SG &&
|
||||||
csummode == CHECKSUM_PARTIAL) {
|
csummode == CHECKSUM_PARTIAL) {
|
||||||
paged = true;
|
paged = true;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue