Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Transfer padding was wrong for full-speed USB in ASIX driver, fix from Ingo van Lil. 2) Propagate the negative packet offset fix into the PowerPC BPF JIT. From Jan Seiffert. 3) dl2k driver's private ioctls were letting unprivileged tasks make MII writes and other ugly bits like that. Fix from Jeff Mahoney. 4) Fix TX VLAN and RX packet drops in ucc_geth, from Joakim Tjernlund. 5) OOPS and network namespace fixes in IPVS from Hans Schillstrom and Julian Anastasov. 6) Fix races and sleeping in locked context bugs in drop_monitor, from Neil Horman. 7) Fix link status indication in smsc95xx driver, from Paolo Pisati. 8) Fix bridge netfilter OOPS, from Peter Huang. 9) L2TP sendmsg can return on error conditions with the socket lock held, oops. Fix from Sasha Levin. 10) udp_diag should return meaningful values for socket memory usage, from Shan Wei. 11) Eric Dumazet is so awesome he gets his own section: Socket memory cgroup code (I never should have applied those patches, grumble...) made erroneous changes to sk_sockets_allocated_read_positive(). It was changed to use percpu_counter_sum_positive (which requires BH disabling) instead of percpu_counter_read_positive (which does not). Revert back to avoid crashes and lockdep warnings. Adjust the default tcp_adv_win_scale and tcp_rmem[2] values to fix throughput regressions. This is necessary as a result of our more precise skb->truesize tracking. Fix SKB leak in netem packet scheduler. 12) New device IDs for various bluetooth devices, from Manoj Iyer, AceLan Kao, and Steven Harms. 13) Fix command completion race in ipw2200, from Stanislav Yakovlev. 14) Fix rtlwifi oops on unload, from Larry Finger. 15) Fix hard_mtu when adjusting hard_header_len in smsc95xx driver. From Stephane Fillod. 16) ehea driver registers it's IRQ before all the necessary state is setup, resulting in crashes. Fix from Thadeu Lima de Souza Cascardo. 17) Fix PHY connection failures in davinci_emac driver, from Anatolij Gustschin. 18) Missing break; in switch statement in bluetooth's hci_cmd_complete_evt(). Fix from Szymon Janc. 19) Fix queue programming in iwlwifi, from Johannes Berg. 20) Interrupt throttling defaults not being actually programmed into the hardware, fix from Jeff Kirsher and Ying Cai. 21) TLAN driver SKB encoding in descriptor busted on 64-bit, fix from Benjamin Poirier. 22) Fix blind status block RX producer pointer deref in TG3 driver, from Matt Carlson. 23) Promisc and multicast are busted on ehea, fixes from Thadeu Lima de Souza Cascardo. 24) Fix crashes in 6lowpan, from Alexander Smirnov. 25) tcp_complete_cwr() needs to be careful to not rewind the CWND to ssthresh if ssthresh has the "infinite" value. Fix from Yuchung Cheng. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (81 commits) sungem: Fix WakeOnLan tcp: change tcp_adv_win_scale and tcp_rmem[2] net: l2tp: unlock socket lock before returning from l2tp_ip_sendmsg drop_monitor: prevent init path from scheduling on the wrong cpu usbnet: fix failure handling in usbnet_probe usbnet: fix leak of transfer buffer of dev->interrupt ucc_geth: Add 16 bytes to max TX frame for VLANs net: ucc_geth, increase no. of HW RX descriptors netem: fix possible skb leak sky2: fix receive length error in mixed non-VLAN/VLAN traffic sky2: propogate rx hash when packet is copied net: fix two typos in skbuff.h cxgb3: Don't call cxgb_vlan_mode until q locks are initialized ixgbe: fix calling skb_put on nonlinear skb assertion bug ixgbe: Fix a memory leak in IEEE DCB igbvf: fix the bug when initializing the igbvf smsc75xx: enable mac to detect speed/duplex from phy smsc75xx: declare smsc75xx's MII as GMII capable smsc75xx: fix phy interrupt acknowledge smsc75xx: fix phy init reset loop ...
This commit is contained in:
Коммит
c42f1d4b52
|
@ -147,7 +147,7 @@ tcp_adv_win_scale - INTEGER
|
|||
(if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale),
|
||||
if it is <= 0.
|
||||
Possible values are [-31, 31], inclusive.
|
||||
Default: 2
|
||||
Default: 1
|
||||
|
||||
tcp_allowed_congestion_control - STRING
|
||||
Show/set the congestion control choices available to non-privileged
|
||||
|
@ -410,7 +410,7 @@ tcp_rmem - vector of 3 INTEGERs: min, default, max
|
|||
net.core.rmem_max. Calling setsockopt() with SO_RCVBUF disables
|
||||
automatic tuning of that socket's receive buffer size, in which
|
||||
case this value is ignored.
|
||||
Default: between 87380B and 4MB, depending on RAM size.
|
||||
Default: between 87380B and 6MB, depending on RAM size.
|
||||
|
||||
tcp_sack - BOOLEAN
|
||||
Enable select acknowledgments (SACKS).
|
||||
|
|
|
@ -5892,11 +5892,11 @@ F: Documentation/scsi/st.txt
|
|||
F: drivers/scsi/st*
|
||||
|
||||
SCTP PROTOCOL
|
||||
M: Vlad Yasevich <vladislav.yasevich@hp.com>
|
||||
M: Vlad Yasevich <vyasevich@gmail.com>
|
||||
M: Sridhar Samudrala <sri@us.ibm.com>
|
||||
L: linux-sctp@vger.kernel.org
|
||||
W: http://lksctp.sourceforge.net
|
||||
S: Supported
|
||||
S: Maintained
|
||||
F: Documentation/networking/sctp.txt
|
||||
F: include/linux/sctp.h
|
||||
F: include/net/sctp/
|
||||
|
|
|
@ -48,7 +48,13 @@
|
|||
/*
|
||||
* Assembly helpers from arch/powerpc/net/bpf_jit.S:
|
||||
*/
|
||||
extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[];
|
||||
#define DECLARE_LOAD_FUNC(func) \
|
||||
extern u8 func[], func##_negative_offset[], func##_positive_offset[]
|
||||
|
||||
DECLARE_LOAD_FUNC(sk_load_word);
|
||||
DECLARE_LOAD_FUNC(sk_load_half);
|
||||
DECLARE_LOAD_FUNC(sk_load_byte);
|
||||
DECLARE_LOAD_FUNC(sk_load_byte_msh);
|
||||
|
||||
#define FUNCTION_DESCR_SIZE 24
|
||||
|
||||
|
|
|
@ -31,14 +31,13 @@
|
|||
* then branch directly to slow_path_XXX if required. (In fact, could
|
||||
* load a spare GPR with the address of slow_path_generic and pass size
|
||||
* as an argument, making the call site a mtlr, li and bllr.)
|
||||
*
|
||||
* Technically, the "is addr < 0" check is unnecessary & slowing down
|
||||
* the ABS path, as it's statically checked on generation.
|
||||
*/
|
||||
.globl sk_load_word
|
||||
sk_load_word:
|
||||
cmpdi r_addr, 0
|
||||
blt bpf_error
|
||||
blt bpf_slow_path_word_neg
|
||||
.globl sk_load_word_positive_offset
|
||||
sk_load_word_positive_offset:
|
||||
/* Are we accessing past headlen? */
|
||||
subi r_scratch1, r_HL, 4
|
||||
cmpd r_scratch1, r_addr
|
||||
|
@ -51,7 +50,9 @@ sk_load_word:
|
|||
.globl sk_load_half
|
||||
sk_load_half:
|
||||
cmpdi r_addr, 0
|
||||
blt bpf_error
|
||||
blt bpf_slow_path_half_neg
|
||||
.globl sk_load_half_positive_offset
|
||||
sk_load_half_positive_offset:
|
||||
subi r_scratch1, r_HL, 2
|
||||
cmpd r_scratch1, r_addr
|
||||
blt bpf_slow_path_half
|
||||
|
@ -61,7 +62,9 @@ sk_load_half:
|
|||
.globl sk_load_byte
|
||||
sk_load_byte:
|
||||
cmpdi r_addr, 0
|
||||
blt bpf_error
|
||||
blt bpf_slow_path_byte_neg
|
||||
.globl sk_load_byte_positive_offset
|
||||
sk_load_byte_positive_offset:
|
||||
cmpd r_HL, r_addr
|
||||
ble bpf_slow_path_byte
|
||||
lbzx r_A, r_D, r_addr
|
||||
|
@ -69,22 +72,20 @@ sk_load_byte:
|
|||
|
||||
/*
|
||||
* BPF_S_LDX_B_MSH: ldxb 4*([offset]&0xf)
|
||||
* r_addr is the offset value, already known positive
|
||||
* r_addr is the offset value
|
||||
*/
|
||||
.globl sk_load_byte_msh
|
||||
sk_load_byte_msh:
|
||||
cmpdi r_addr, 0
|
||||
blt bpf_slow_path_byte_msh_neg
|
||||
.globl sk_load_byte_msh_positive_offset
|
||||
sk_load_byte_msh_positive_offset:
|
||||
cmpd r_HL, r_addr
|
||||
ble bpf_slow_path_byte_msh
|
||||
lbzx r_X, r_D, r_addr
|
||||
rlwinm r_X, r_X, 2, 32-4-2, 31-2
|
||||
blr
|
||||
|
||||
bpf_error:
|
||||
/* Entered with cr0 = lt */
|
||||
li r3, 0
|
||||
/* Generated code will 'blt epilogue', returning 0. */
|
||||
blr
|
||||
|
||||
/* Call out to skb_copy_bits:
|
||||
* We'll need to back up our volatile regs first; we have
|
||||
* local variable space at r1+(BPF_PPC_STACK_BASIC).
|
||||
|
@ -136,3 +137,84 @@ bpf_slow_path_byte_msh:
|
|||
lbz r_X, BPF_PPC_STACK_BASIC+(2*8)(r1)
|
||||
rlwinm r_X, r_X, 2, 32-4-2, 31-2
|
||||
blr
|
||||
|
||||
/* Call out to bpf_internal_load_pointer_neg_helper:
|
||||
* We'll need to back up our volatile regs first; we have
|
||||
* local variable space at r1+(BPF_PPC_STACK_BASIC).
|
||||
* Allocate a new stack frame here to remain ABI-compliant in
|
||||
* stashing LR.
|
||||
*/
|
||||
#define sk_negative_common(SIZE) \
|
||||
mflr r0; \
|
||||
std r0, 16(r1); \
|
||||
/* R3 goes in parameter space of caller's frame */ \
|
||||
std r_skb, (BPF_PPC_STACKFRAME+48)(r1); \
|
||||
std r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \
|
||||
std r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \
|
||||
stdu r1, -BPF_PPC_SLOWPATH_FRAME(r1); \
|
||||
/* R3 = r_skb, as passed */ \
|
||||
mr r4, r_addr; \
|
||||
li r5, SIZE; \
|
||||
bl bpf_internal_load_pointer_neg_helper; \
|
||||
/* R3 != 0 on success */ \
|
||||
addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \
|
||||
ld r0, 16(r1); \
|
||||
ld r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \
|
||||
ld r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \
|
||||
mtlr r0; \
|
||||
cmpldi r3, 0; \
|
||||
beq bpf_error_slow; /* cr0 = EQ */ \
|
||||
mr r_addr, r3; \
|
||||
ld r_skb, (BPF_PPC_STACKFRAME+48)(r1); \
|
||||
/* Great success! */
|
||||
|
||||
bpf_slow_path_word_neg:
|
||||
lis r_scratch1,-32 /* SKF_LL_OFF */
|
||||
cmpd r_addr, r_scratch1 /* addr < SKF_* */
|
||||
blt bpf_error /* cr0 = LT */
|
||||
.globl sk_load_word_negative_offset
|
||||
sk_load_word_negative_offset:
|
||||
sk_negative_common(4)
|
||||
lwz r_A, 0(r_addr)
|
||||
blr
|
||||
|
||||
bpf_slow_path_half_neg:
|
||||
lis r_scratch1,-32 /* SKF_LL_OFF */
|
||||
cmpd r_addr, r_scratch1 /* addr < SKF_* */
|
||||
blt bpf_error /* cr0 = LT */
|
||||
.globl sk_load_half_negative_offset
|
||||
sk_load_half_negative_offset:
|
||||
sk_negative_common(2)
|
||||
lhz r_A, 0(r_addr)
|
||||
blr
|
||||
|
||||
bpf_slow_path_byte_neg:
|
||||
lis r_scratch1,-32 /* SKF_LL_OFF */
|
||||
cmpd r_addr, r_scratch1 /* addr < SKF_* */
|
||||
blt bpf_error /* cr0 = LT */
|
||||
.globl sk_load_byte_negative_offset
|
||||
sk_load_byte_negative_offset:
|
||||
sk_negative_common(1)
|
||||
lbz r_A, 0(r_addr)
|
||||
blr
|
||||
|
||||
bpf_slow_path_byte_msh_neg:
|
||||
lis r_scratch1,-32 /* SKF_LL_OFF */
|
||||
cmpd r_addr, r_scratch1 /* addr < SKF_* */
|
||||
blt bpf_error /* cr0 = LT */
|
||||
.globl sk_load_byte_msh_negative_offset
|
||||
sk_load_byte_msh_negative_offset:
|
||||
sk_negative_common(1)
|
||||
lbz r_X, 0(r_addr)
|
||||
rlwinm r_X, r_X, 2, 32-4-2, 31-2
|
||||
blr
|
||||
|
||||
bpf_error_slow:
|
||||
/* fabricate a cr0 = lt */
|
||||
li r_scratch1, -1
|
||||
cmpdi r_scratch1, 0
|
||||
bpf_error:
|
||||
/* Entered with cr0 = lt */
|
||||
li r3, 0
|
||||
/* Generated code will 'blt epilogue', returning 0. */
|
||||
blr
|
||||
|
|
|
@ -127,6 +127,9 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
|
|||
PPC_BLR();
|
||||
}
|
||||
|
||||
#define CHOOSE_LOAD_FUNC(K, func) \
|
||||
((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
|
||||
|
||||
/* Assemble the body code between the prologue & epilogue. */
|
||||
static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
|
||||
struct codegen_context *ctx,
|
||||
|
@ -391,21 +394,16 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
|
|||
|
||||
/*** Absolute loads from packet header/data ***/
|
||||
case BPF_S_LD_W_ABS:
|
||||
func = sk_load_word;
|
||||
func = CHOOSE_LOAD_FUNC(K, sk_load_word);
|
||||
goto common_load;
|
||||
case BPF_S_LD_H_ABS:
|
||||
func = sk_load_half;
|
||||
func = CHOOSE_LOAD_FUNC(K, sk_load_half);
|
||||
goto common_load;
|
||||
case BPF_S_LD_B_ABS:
|
||||
func = sk_load_byte;
|
||||
func = CHOOSE_LOAD_FUNC(K, sk_load_byte);
|
||||
common_load:
|
||||
/*
|
||||
* Load from [K]. Reference with the (negative)
|
||||
* SKF_NET_OFF/SKF_LL_OFF offsets is unsupported.
|
||||
*/
|
||||
/* Load from [K]. */
|
||||
ctx->seen |= SEEN_DATAREF;
|
||||
if ((int)K < 0)
|
||||
return -ENOTSUPP;
|
||||
PPC_LI64(r_scratch1, func);
|
||||
PPC_MTLR(r_scratch1);
|
||||
PPC_LI32(r_addr, K);
|
||||
|
@ -429,7 +427,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
|
|||
common_load_ind:
|
||||
/*
|
||||
* Load from [X + K]. Negative offsets are tested for
|
||||
* in the helper functions, and result in a 'ret 0'.
|
||||
* in the helper functions.
|
||||
*/
|
||||
ctx->seen |= SEEN_DATAREF | SEEN_XREG;
|
||||
PPC_LI64(r_scratch1, func);
|
||||
|
@ -443,13 +441,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
|
|||
break;
|
||||
|
||||
case BPF_S_LDX_B_MSH:
|
||||
/*
|
||||
* x86 version drops packet (RET 0) when K<0, whereas
|
||||
* interpreter does allow K<0 (__load_pointer, special
|
||||
* ancillary data). common_load returns ENOTSUPP if K<0,
|
||||
* so we fall back to interpreter & filter works.
|
||||
*/
|
||||
func = sk_load_byte_msh;
|
||||
func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh);
|
||||
goto common_load;
|
||||
break;
|
||||
|
||||
|
|
|
@ -75,6 +75,8 @@ static struct usb_device_id ath3k_table[] = {
|
|||
{ USB_DEVICE(0x0CF3, 0x311D) },
|
||||
{ USB_DEVICE(0x13d3, 0x3375) },
|
||||
{ USB_DEVICE(0x04CA, 0x3005) },
|
||||
{ USB_DEVICE(0x13d3, 0x3362) },
|
||||
{ USB_DEVICE(0x0CF3, 0xE004) },
|
||||
|
||||
/* Atheros AR5BBU12 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xE02C) },
|
||||
|
@ -94,6 +96,8 @@ static struct usb_device_id ath3k_blist_tbl[] = {
|
|||
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
|
||||
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
|
|
@ -101,12 +101,16 @@ static struct usb_device_id btusb_table[] = {
|
|||
{ USB_DEVICE(0x0c10, 0x0000) },
|
||||
|
||||
/* Broadcom BCM20702A0 */
|
||||
{ USB_DEVICE(0x0489, 0xe042) },
|
||||
{ USB_DEVICE(0x0a5c, 0x21e3) },
|
||||
{ USB_DEVICE(0x0a5c, 0x21e6) },
|
||||
{ USB_DEVICE(0x0a5c, 0x21e8) },
|
||||
{ USB_DEVICE(0x0a5c, 0x21f3) },
|
||||
{ USB_DEVICE(0x413c, 0x8197) },
|
||||
|
||||
/* Foxconn - Hon Hai */
|
||||
{ USB_DEVICE(0x0489, 0xe033) },
|
||||
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
|
@ -133,6 +137,8 @@ static struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
|
||||
|
||||
/* Atheros AR5BBU12 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
|
||||
|
|
|
@ -879,8 +879,13 @@ static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
|
|||
if (sblk->status & SD_STATUS_LINK_CHG)
|
||||
work_exists = 1;
|
||||
}
|
||||
/* check for RX/TX work to do */
|
||||
if (sblk->idx[0].tx_consumer != tnapi->tx_cons ||
|
||||
|
||||
/* check for TX work to do */
|
||||
if (sblk->idx[0].tx_consumer != tnapi->tx_cons)
|
||||
work_exists = 1;
|
||||
|
||||
/* check for RX work to do */
|
||||
if (tnapi->rx_rcb_prod_idx &&
|
||||
*(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)
|
||||
work_exists = 1;
|
||||
|
||||
|
@ -6124,6 +6129,9 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
|
|||
return work_done;
|
||||
}
|
||||
|
||||
if (!tnapi->rx_rcb_prod_idx)
|
||||
return work_done;
|
||||
|
||||
/* run RX thread, within the bounds set by NAPI.
|
||||
* All RX "locking" is done by ensuring outside
|
||||
* code synchronizes with tg3->napi.poll()
|
||||
|
@ -7567,6 +7575,12 @@ static int tg3_alloc_consistent(struct tg3 *tp)
|
|||
*/
|
||||
switch (i) {
|
||||
default:
|
||||
if (tg3_flag(tp, ENABLE_RSS)) {
|
||||
tnapi->rx_rcb_prod_idx = NULL;
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
case 1:
|
||||
tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer;
|
||||
break;
|
||||
case 2:
|
||||
|
|
|
@ -1149,6 +1149,48 @@ release_tpsram:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* t3_synchronize_rx - wait for current Rx processing on a port to complete
|
||||
* @adap: the adapter
|
||||
* @p: the port
|
||||
*
|
||||
* Ensures that current Rx processing on any of the queues associated with
|
||||
* the given port completes before returning. We do this by acquiring and
|
||||
* releasing the locks of the response queues associated with the port.
|
||||
*/
|
||||
static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) {
|
||||
struct sge_rspq *q = &adap->sge.qs[i].rspq;
|
||||
|
||||
spin_lock_irq(&q->lock);
|
||||
spin_unlock_irq(&q->lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features)
|
||||
{
|
||||
struct port_info *pi = netdev_priv(dev);
|
||||
struct adapter *adapter = pi->adapter;
|
||||
|
||||
if (adapter->params.rev > 0) {
|
||||
t3_set_vlan_accel(adapter, 1 << pi->port_id,
|
||||
features & NETIF_F_HW_VLAN_RX);
|
||||
} else {
|
||||
/* single control for all ports */
|
||||
unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX;
|
||||
|
||||
for_each_port(adapter, i)
|
||||
have_vlans |=
|
||||
adapter->port[i]->features & NETIF_F_HW_VLAN_RX;
|
||||
|
||||
t3_set_vlan_accel(adapter, 1, have_vlans);
|
||||
}
|
||||
t3_synchronize_rx(adapter, pi);
|
||||
}
|
||||
|
||||
/**
|
||||
* cxgb_up - enable the adapter
|
||||
* @adapter: adapter being enabled
|
||||
|
@ -1161,7 +1203,7 @@ release_tpsram:
|
|||
*/
|
||||
static int cxgb_up(struct adapter *adap)
|
||||
{
|
||||
int err;
|
||||
int i, err;
|
||||
|
||||
if (!(adap->flags & FULL_INIT_DONE)) {
|
||||
err = t3_check_fw_version(adap);
|
||||
|
@ -1198,6 +1240,9 @@ static int cxgb_up(struct adapter *adap)
|
|||
if (err)
|
||||
goto out;
|
||||
|
||||
for_each_port(adap, i)
|
||||
cxgb_vlan_mode(adap->port[i], adap->port[i]->features);
|
||||
|
||||
setup_rss(adap);
|
||||
if (!(adap->flags & NAPI_INIT))
|
||||
init_napi(adap);
|
||||
|
@ -2508,48 +2553,6 @@ static int cxgb_set_mac_addr(struct net_device *dev, void *p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* t3_synchronize_rx - wait for current Rx processing on a port to complete
|
||||
* @adap: the adapter
|
||||
* @p: the port
|
||||
*
|
||||
* Ensures that current Rx processing on any of the queues associated with
|
||||
* the given port completes before returning. We do this by acquiring and
|
||||
* releasing the locks of the response queues associated with the port.
|
||||
*/
|
||||
static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) {
|
||||
struct sge_rspq *q = &adap->sge.qs[i].rspq;
|
||||
|
||||
spin_lock_irq(&q->lock);
|
||||
spin_unlock_irq(&q->lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features)
|
||||
{
|
||||
struct port_info *pi = netdev_priv(dev);
|
||||
struct adapter *adapter = pi->adapter;
|
||||
|
||||
if (adapter->params.rev > 0) {
|
||||
t3_set_vlan_accel(adapter, 1 << pi->port_id,
|
||||
features & NETIF_F_HW_VLAN_RX);
|
||||
} else {
|
||||
/* single control for all ports */
|
||||
unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX;
|
||||
|
||||
for_each_port(adapter, i)
|
||||
have_vlans |=
|
||||
adapter->port[i]->features & NETIF_F_HW_VLAN_RX;
|
||||
|
||||
t3_set_vlan_accel(adapter, 1, have_vlans);
|
||||
}
|
||||
t3_synchronize_rx(adapter, pi);
|
||||
}
|
||||
|
||||
static netdev_features_t cxgb_fix_features(struct net_device *dev,
|
||||
netdev_features_t features)
|
||||
{
|
||||
|
@ -3353,9 +3356,6 @@ static int __devinit init_one(struct pci_dev *pdev,
|
|||
err = sysfs_create_group(&adapter->port[0]->dev.kobj,
|
||||
&cxgb3_attr_group);
|
||||
|
||||
for_each_port(adapter, i)
|
||||
cxgb_vlan_mode(adapter->port[i], adapter->port[i]->features);
|
||||
|
||||
print_port_info(adapter, ai);
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -1259,55 +1259,21 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
|
|||
{
|
||||
int phy_addr;
|
||||
struct netdev_private *np = netdev_priv(dev);
|
||||
struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru;
|
||||
|
||||
struct netdev_desc *desc;
|
||||
int i;
|
||||
struct mii_ioctl_data *miidata = if_mii(rq);
|
||||
|
||||
phy_addr = np->phy_addr;
|
||||
switch (cmd) {
|
||||
case SIOCDEVPRIVATE:
|
||||
case SIOCGMIIPHY:
|
||||
miidata->phy_id = phy_addr;
|
||||
break;
|
||||
|
||||
case SIOCDEVPRIVATE + 1:
|
||||
miidata->out_value = mii_read (dev, phy_addr, miidata->reg_num);
|
||||
case SIOCGMIIREG:
|
||||
miidata->val_out = mii_read (dev, phy_addr, miidata->reg_num);
|
||||
break;
|
||||
case SIOCDEVPRIVATE + 2:
|
||||
mii_write (dev, phy_addr, miidata->reg_num, miidata->in_value);
|
||||
case SIOCSMIIREG:
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
mii_write (dev, phy_addr, miidata->reg_num, miidata->val_in);
|
||||
break;
|
||||
case SIOCDEVPRIVATE + 3:
|
||||
break;
|
||||
case SIOCDEVPRIVATE + 4:
|
||||
break;
|
||||
case SIOCDEVPRIVATE + 5:
|
||||
netif_stop_queue (dev);
|
||||
break;
|
||||
case SIOCDEVPRIVATE + 6:
|
||||
netif_wake_queue (dev);
|
||||
break;
|
||||
case SIOCDEVPRIVATE + 7:
|
||||
printk
|
||||
("tx_full=%x cur_tx=%lx old_tx=%lx cur_rx=%lx old_rx=%lx\n",
|
||||
netif_queue_stopped(dev), np->cur_tx, np->old_tx, np->cur_rx,
|
||||
np->old_rx);
|
||||
break;
|
||||
case SIOCDEVPRIVATE + 8:
|
||||
printk("TX ring:\n");
|
||||
for (i = 0; i < TX_RING_SIZE; i++) {
|
||||
desc = &np->tx_ring[i];
|
||||
printk
|
||||
("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x",
|
||||
i,
|
||||
(u32) (np->tx_ring_dma + i * sizeof (*desc)),
|
||||
(u32)le64_to_cpu(desc->next_desc),
|
||||
(u32)le64_to_cpu(desc->status),
|
||||
(u32)(le64_to_cpu(desc->fraginfo) >> 32),
|
||||
(u32)le64_to_cpu(desc->fraginfo));
|
||||
printk ("\n");
|
||||
}
|
||||
printk ("\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
|
|
@ -365,13 +365,6 @@ struct ioctl_data {
|
|||
char *data;
|
||||
};
|
||||
|
||||
struct mii_data {
|
||||
__u16 reserved;
|
||||
__u16 reg_num;
|
||||
__u16 in_value;
|
||||
__u16 out_value;
|
||||
};
|
||||
|
||||
/* The Rx and Tx buffer descriptors. */
|
||||
struct netdev_desc {
|
||||
__le64 next_desc;
|
||||
|
|
|
@ -116,10 +116,10 @@ static struct ucc_geth_info ugeth_primary_info = {
|
|||
.maxGroupAddrInHash = 4,
|
||||
.maxIndAddrInHash = 4,
|
||||
.prel = 7,
|
||||
.maxFrameLength = 1518,
|
||||
.maxFrameLength = 1518+16, /* Add extra bytes for VLANs etc. */
|
||||
.minFrameLength = 64,
|
||||
.maxD1Length = 1520,
|
||||
.maxD2Length = 1520,
|
||||
.maxD1Length = 1520+16, /* Add extra bytes for VLANs etc. */
|
||||
.maxD2Length = 1520+16, /* Add extra bytes for VLANs etc. */
|
||||
.vlantype = 0x8100,
|
||||
.ecamptr = ((uint32_t) NULL),
|
||||
.eventRegMask = UCCE_OTHER,
|
||||
|
|
|
@ -877,7 +877,7 @@ struct ucc_geth_hardware_statistics {
|
|||
|
||||
/* Driver definitions */
|
||||
#define TX_BD_RING_LEN 0x10
|
||||
#define RX_BD_RING_LEN 0x10
|
||||
#define RX_BD_RING_LEN 0x20
|
||||
|
||||
#define TX_RING_MOD_MASK(size) (size-1)
|
||||
#define RX_RING_MOD_MASK(size) (size-1)
|
||||
|
|
|
@ -290,16 +290,18 @@ static void ehea_update_bcmc_registrations(void)
|
|||
|
||||
arr[i].adh = adapter->handle;
|
||||
arr[i].port_id = port->logical_port_id;
|
||||
arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
|
||||
EHEA_BCMC_MULTICAST |
|
||||
arr[i].reg_type = EHEA_BCMC_MULTICAST |
|
||||
EHEA_BCMC_UNTAGGED;
|
||||
if (mc_entry->macaddr == 0)
|
||||
arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL;
|
||||
arr[i++].macaddr = mc_entry->macaddr;
|
||||
|
||||
arr[i].adh = adapter->handle;
|
||||
arr[i].port_id = port->logical_port_id;
|
||||
arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
|
||||
EHEA_BCMC_MULTICAST |
|
||||
arr[i].reg_type = EHEA_BCMC_MULTICAST |
|
||||
EHEA_BCMC_VLANID_ALL;
|
||||
if (mc_entry->macaddr == 0)
|
||||
arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL;
|
||||
arr[i++].macaddr = mc_entry->macaddr;
|
||||
num_registrations -= 2;
|
||||
}
|
||||
|
@ -1838,8 +1840,9 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr,
|
|||
u64 hret;
|
||||
u8 reg_type;
|
||||
|
||||
reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST
|
||||
| EHEA_BCMC_UNTAGGED;
|
||||
reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_UNTAGGED;
|
||||
if (mc_mac_addr == 0)
|
||||
reg_type |= EHEA_BCMC_SCOPE_ALL;
|
||||
|
||||
hret = ehea_h_reg_dereg_bcmc(port->adapter->handle,
|
||||
port->logical_port_id,
|
||||
|
@ -1847,8 +1850,9 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr,
|
|||
if (hret)
|
||||
goto out;
|
||||
|
||||
reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST
|
||||
| EHEA_BCMC_VLANID_ALL;
|
||||
reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_VLANID_ALL;
|
||||
if (mc_mac_addr == 0)
|
||||
reg_type |= EHEA_BCMC_SCOPE_ALL;
|
||||
|
||||
hret = ehea_h_reg_dereg_bcmc(port->adapter->handle,
|
||||
port->logical_port_id,
|
||||
|
@ -1898,7 +1902,7 @@ static void ehea_allmulti(struct net_device *dev, int enable)
|
|||
netdev_err(dev,
|
||||
"failed enabling IFF_ALLMULTI\n");
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
if (!enable) {
|
||||
/* Disable ALLMULTI */
|
||||
hret = ehea_multicast_reg_helper(port, 0, H_DEREG_BCMC);
|
||||
|
@ -1908,6 +1912,7 @@ static void ehea_allmulti(struct net_device *dev, int enable)
|
|||
netdev_err(dev,
|
||||
"failed disabling IFF_ALLMULTI\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr)
|
||||
|
@ -1941,11 +1946,7 @@ static void ehea_set_multicast_list(struct net_device *dev)
|
|||
struct netdev_hw_addr *ha;
|
||||
int ret;
|
||||
|
||||
if (port->promisc) {
|
||||
ehea_promiscuous(dev, 1);
|
||||
return;
|
||||
}
|
||||
ehea_promiscuous(dev, 0);
|
||||
ehea_promiscuous(dev, !!(dev->flags & IFF_PROMISC));
|
||||
|
||||
if (dev->flags & IFF_ALLMULTI) {
|
||||
ehea_allmulti(dev, 1);
|
||||
|
@ -2463,6 +2464,7 @@ static int ehea_down(struct net_device *dev)
|
|||
return 0;
|
||||
|
||||
ehea_drop_multicast_list(dev);
|
||||
ehea_allmulti(dev, 0);
|
||||
ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
|
||||
|
||||
ehea_free_interrupts(dev);
|
||||
|
@ -3261,6 +3263,7 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,
|
|||
struct ehea_adapter *adapter;
|
||||
const u64 *adapter_handle;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (!dev || !dev->dev.of_node) {
|
||||
pr_err("Invalid ibmebus device probed\n");
|
||||
|
@ -3314,17 +3317,9 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,
|
|||
tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet,
|
||||
(unsigned long)adapter);
|
||||
|
||||
ret = ibmebus_request_irq(adapter->neq->attr.ist1,
|
||||
ehea_interrupt_neq, IRQF_DISABLED,
|
||||
"ehea_neq", adapter);
|
||||
if (ret) {
|
||||
dev_err(&dev->dev, "requesting NEQ IRQ failed\n");
|
||||
goto out_kill_eq;
|
||||
}
|
||||
|
||||
ret = ehea_create_device_sysfs(dev);
|
||||
if (ret)
|
||||
goto out_free_irq;
|
||||
goto out_kill_eq;
|
||||
|
||||
ret = ehea_setup_ports(adapter);
|
||||
if (ret) {
|
||||
|
@ -3332,15 +3327,28 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,
|
|||
goto out_rem_dev_sysfs;
|
||||
}
|
||||
|
||||
ret = ibmebus_request_irq(adapter->neq->attr.ist1,
|
||||
ehea_interrupt_neq, IRQF_DISABLED,
|
||||
"ehea_neq", adapter);
|
||||
if (ret) {
|
||||
dev_err(&dev->dev, "requesting NEQ IRQ failed\n");
|
||||
goto out_shutdown_ports;
|
||||
}
|
||||
|
||||
|
||||
ret = 0;
|
||||
goto out;
|
||||
|
||||
out_shutdown_ports:
|
||||
for (i = 0; i < EHEA_MAX_PORTS; i++)
|
||||
if (adapter->port[i]) {
|
||||
ehea_shutdown_single_port(adapter->port[i]);
|
||||
adapter->port[i] = NULL;
|
||||
}
|
||||
|
||||
out_rem_dev_sysfs:
|
||||
ehea_remove_device_sysfs(dev);
|
||||
|
||||
out_free_irq:
|
||||
ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
|
||||
|
||||
out_kill_eq:
|
||||
ehea_destroy_eq(adapter->neq);
|
||||
|
||||
|
|
|
@ -450,7 +450,7 @@ u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num,
|
|||
void *cb_addr);
|
||||
|
||||
#define H_REGBCMC_PN EHEA_BMASK_IBM(48, 63)
|
||||
#define H_REGBCMC_REGTYPE EHEA_BMASK_IBM(61, 63)
|
||||
#define H_REGBCMC_REGTYPE EHEA_BMASK_IBM(60, 63)
|
||||
#define H_REGBCMC_MACADDR EHEA_BMASK_IBM(16, 63)
|
||||
#define H_REGBCMC_VLANID EHEA_BMASK_IBM(52, 63)
|
||||
|
||||
|
|
|
@ -3799,7 +3799,7 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
|
|||
/* fire an unusual interrupt on the test handler */
|
||||
ew32(ICS, E1000_ICS_RXSEQ);
|
||||
e1e_flush();
|
||||
msleep(50);
|
||||
msleep(100);
|
||||
|
||||
e1000_irq_disable(adapter);
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
|
|||
/*
|
||||
* Interrupt Throttle Rate (interrupts/sec)
|
||||
*
|
||||
* Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative)
|
||||
* Valid Range: 100-100000 or one of: 0=off, 1=dynamic, 3=dynamic conservative
|
||||
*/
|
||||
E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
|
||||
#define DEFAULT_ITR 3
|
||||
|
@ -344,54 +344,61 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
|
|||
|
||||
if (num_InterruptThrottleRate > bd) {
|
||||
adapter->itr = InterruptThrottleRate[bd];
|
||||
|
||||
/*
|
||||
* Make sure a message is printed for non-special
|
||||
* values. And in case of an invalid option, display
|
||||
* warning, use default and got through itr/itr_setting
|
||||
* adjustment logic below
|
||||
*/
|
||||
if ((adapter->itr > 4) &&
|
||||
e1000_validate_option(&adapter->itr, &opt, adapter))
|
||||
adapter->itr = opt.def;
|
||||
} else {
|
||||
/*
|
||||
* If no option specified, use default value and go
|
||||
* through the logic below to adjust itr/itr_setting
|
||||
*/
|
||||
adapter->itr = opt.def;
|
||||
|
||||
/*
|
||||
* Make sure a message is printed for non-special
|
||||
* default values
|
||||
*/
|
||||
if (adapter->itr > 40)
|
||||
e_info("%s set to default %d\n", opt.name,
|
||||
adapter->itr);
|
||||
}
|
||||
|
||||
adapter->itr_setting = adapter->itr;
|
||||
switch (adapter->itr) {
|
||||
case 0:
|
||||
e_info("%s turned off\n", opt.name);
|
||||
break;
|
||||
case 1:
|
||||
e_info("%s set to dynamic mode\n", opt.name);
|
||||
adapter->itr_setting = adapter->itr;
|
||||
adapter->itr = 20000;
|
||||
break;
|
||||
case 3:
|
||||
e_info("%s set to dynamic conservative mode\n",
|
||||
opt.name);
|
||||
adapter->itr_setting = adapter->itr;
|
||||
adapter->itr = 20000;
|
||||
break;
|
||||
case 4:
|
||||
e_info("%s set to simplified (2000-8000 ints) "
|
||||
"mode\n", opt.name);
|
||||
adapter->itr_setting = 4;
|
||||
e_info("%s set to simplified (2000-8000 ints) mode\n",
|
||||
opt.name);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Save the setting, because the dynamic bits
|
||||
* change itr.
|
||||
*/
|
||||
if (e1000_validate_option(&adapter->itr, &opt,
|
||||
adapter) &&
|
||||
(adapter->itr == 3)) {
|
||||
/*
|
||||
* In case of invalid user value,
|
||||
* default to conservative mode.
|
||||
*/
|
||||
adapter->itr_setting = adapter->itr;
|
||||
adapter->itr = 20000;
|
||||
} else {
|
||||
/*
|
||||
*
|
||||
* Clear the lower two bits because
|
||||
* they are used as control.
|
||||
*/
|
||||
adapter->itr_setting =
|
||||
adapter->itr & ~3;
|
||||
}
|
||||
adapter->itr_setting &= ~3;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
adapter->itr_setting = opt.def;
|
||||
adapter->itr = 20000;
|
||||
}
|
||||
}
|
||||
{ /* Interrupt Mode */
|
||||
static struct e1000_option opt = {
|
||||
|
|
|
@ -2731,14 +2731,14 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,
|
|||
netdev->addr_len);
|
||||
}
|
||||
|
||||
if (!is_valid_ether_addr(netdev->perm_addr)) {
|
||||
if (!is_valid_ether_addr(netdev->dev_addr)) {
|
||||
dev_err(&pdev->dev, "Invalid MAC Address: %pM\n",
|
||||
netdev->dev_addr);
|
||||
err = -EIO;
|
||||
goto err_hw_init;
|
||||
}
|
||||
|
||||
memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
|
||||
memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
|
||||
|
||||
setup_timer(&adapter->watchdog_timer, &igbvf_watchdog,
|
||||
(unsigned long) adapter);
|
||||
|
|
|
@ -437,6 +437,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
|
|||
*/
|
||||
if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) &&
|
||||
(fctl & FC_FC_END_SEQ)) {
|
||||
skb_linearize(skb);
|
||||
crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc));
|
||||
crc->fcoe_eof = FC_EOF_T;
|
||||
}
|
||||
|
|
|
@ -4873,10 +4873,6 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
|
|||
}
|
||||
|
||||
ixgbe_clear_interrupt_scheme(adapter);
|
||||
#ifdef CONFIG_DCB
|
||||
kfree(adapter->ixgbe_ieee_pfc);
|
||||
kfree(adapter->ixgbe_ieee_ets);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
retval = pci_save_state(pdev);
|
||||
|
@ -7224,6 +7220,11 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
|
|||
|
||||
ixgbe_release_hw_control(adapter);
|
||||
|
||||
#ifdef CONFIG_DCB
|
||||
kfree(adapter->ixgbe_ieee_pfc);
|
||||
kfree(adapter->ixgbe_ieee_ets);
|
||||
|
||||
#endif
|
||||
iounmap(adapter->hw.hw_addr);
|
||||
pci_release_selected_regions(pdev, pci_select_bars(pdev,
|
||||
IORESOURCE_MEM));
|
||||
|
|
|
@ -2494,8 +2494,13 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2,
|
|||
skb_copy_from_linear_data(re->skb, skb->data, length);
|
||||
skb->ip_summed = re->skb->ip_summed;
|
||||
skb->csum = re->skb->csum;
|
||||
skb->rxhash = re->skb->rxhash;
|
||||
skb->vlan_tci = re->skb->vlan_tci;
|
||||
|
||||
pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,
|
||||
length, PCI_DMA_FROMDEVICE);
|
||||
re->skb->vlan_tci = 0;
|
||||
re->skb->rxhash = 0;
|
||||
re->skb->ip_summed = CHECKSUM_NONE;
|
||||
skb_put(skb, length);
|
||||
}
|
||||
|
@ -2580,9 +2585,6 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
|
|||
struct sk_buff *skb = NULL;
|
||||
u16 count = (status & GMR_FS_LEN) >> 16;
|
||||
|
||||
if (status & GMR_FS_VLAN)
|
||||
count -= VLAN_HLEN; /* Account for vlan tag */
|
||||
|
||||
netif_printk(sky2, rx_status, KERN_DEBUG, dev,
|
||||
"rx slot %u status 0x%x len %d\n",
|
||||
sky2->rx_next, status, length);
|
||||
|
@ -2590,6 +2592,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
|
|||
sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
|
||||
prefetch(sky2->rx_ring + sky2->rx_next);
|
||||
|
||||
if (vlan_tx_tag_present(re->skb))
|
||||
count -= VLAN_HLEN; /* Account for vlan tag */
|
||||
|
||||
/* This chip has hardware problems that generates bogus status.
|
||||
* So do only marginal checking and expect higher level protocols
|
||||
* to handle crap frames.
|
||||
|
@ -2647,11 +2652,8 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
|
|||
}
|
||||
|
||||
static inline void sky2_skb_rx(const struct sky2_port *sky2,
|
||||
u32 status, struct sk_buff *skb)
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
if (status & GMR_FS_VLAN)
|
||||
__vlan_hwaccel_put_tag(skb, be16_to_cpu(sky2->rx_tag));
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_NONE)
|
||||
netif_receive_skb(skb);
|
||||
else
|
||||
|
@ -2705,6 +2707,14 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status)
|
|||
}
|
||||
}
|
||||
|
||||
static void sky2_rx_tag(struct sky2_port *sky2, u16 length)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = sky2->rx_ring[sky2->rx_next].skb;
|
||||
__vlan_hwaccel_put_tag(skb, be16_to_cpu(length));
|
||||
}
|
||||
|
||||
static void sky2_rx_hash(struct sky2_port *sky2, u32 status)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
@ -2763,8 +2773,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
|
|||
}
|
||||
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
|
||||
sky2_skb_rx(sky2, status, skb);
|
||||
sky2_skb_rx(sky2, skb);
|
||||
|
||||
/* Stop after net poll weight */
|
||||
if (++work_done >= to_do)
|
||||
|
@ -2772,11 +2781,11 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
|
|||
break;
|
||||
|
||||
case OP_RXVLAN:
|
||||
sky2->rx_tag = length;
|
||||
sky2_rx_tag(sky2, length);
|
||||
break;
|
||||
|
||||
case OP_RXCHKSVLAN:
|
||||
sky2->rx_tag = length;
|
||||
sky2_rx_tag(sky2, length);
|
||||
/* fall through */
|
||||
case OP_RXCHKS:
|
||||
if (likely(dev->features & NETIF_F_RXCSUM))
|
||||
|
|
|
@ -2241,7 +2241,6 @@ struct sky2_port {
|
|||
u16 rx_pending;
|
||||
u16 rx_data_size;
|
||||
u16 rx_nfrags;
|
||||
u16 rx_tag;
|
||||
|
||||
struct {
|
||||
unsigned long last;
|
||||
|
|
|
@ -2339,7 +2339,7 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
|
|||
netif_device_detach(dev);
|
||||
|
||||
/* Switch off chip, remember WOL setting */
|
||||
gp->asleep_wol = gp->wake_on_lan;
|
||||
gp->asleep_wol = !!gp->wake_on_lan;
|
||||
gem_do_stop(dev, gp->asleep_wol);
|
||||
|
||||
/* Unlock the network stack */
|
||||
|
|
|
@ -1511,7 +1511,7 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd)
|
|||
|
||||
static int match_first_device(struct device *dev, void *data)
|
||||
{
|
||||
return 1;
|
||||
return !strncmp(dev_name(dev), "davinci_mdio", 12);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -228,7 +228,7 @@ tlan_get_skb(const struct tlan_list *tag)
|
|||
unsigned long addr;
|
||||
|
||||
addr = tag->buffer[9].address;
|
||||
addr |= (tag->buffer[8].address << 16) << 16;
|
||||
addr |= ((unsigned long) tag->buffer[8].address << 16) << 16;
|
||||
return (struct sk_buff *) addr;
|
||||
}
|
||||
|
||||
|
|
|
@ -355,7 +355,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
|
|||
u32 packet_len;
|
||||
u32 padbytes = 0xffff0000;
|
||||
|
||||
padlen = ((skb->len + 4) % 512) ? 0 : 4;
|
||||
padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4;
|
||||
|
||||
if ((!skb_cloned(skb)) &&
|
||||
((headroom + tailroom) >= (4 + padlen))) {
|
||||
|
@ -377,7 +377,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
|
|||
cpu_to_le32s(&packet_len);
|
||||
skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len));
|
||||
|
||||
if ((skb->len % 512) == 0) {
|
||||
if (padlen) {
|
||||
cpu_to_le32s(&padbytes);
|
||||
memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes));
|
||||
skb_put(skb, sizeof(padbytes));
|
||||
|
|
|
@ -98,7 +98,7 @@ static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index,
|
|||
|
||||
if (unlikely(ret < 0))
|
||||
netdev_warn(dev->net,
|
||||
"Failed to read register index 0x%08x", index);
|
||||
"Failed to read reg index 0x%08x: %d", index, ret);
|
||||
|
||||
le32_to_cpus(buf);
|
||||
*data = *buf;
|
||||
|
@ -128,7 +128,7 @@ static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index,
|
|||
|
||||
if (unlikely(ret < 0))
|
||||
netdev_warn(dev->net,
|
||||
"Failed to write register index 0x%08x", index);
|
||||
"Failed to write reg index 0x%08x: %d", index, ret);
|
||||
|
||||
kfree(buf);
|
||||
|
||||
|
@ -171,7 +171,7 @@ static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx)
|
|||
idx &= dev->mii.reg_num_mask;
|
||||
addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
|
||||
| ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
|
||||
| MII_ACCESS_READ;
|
||||
| MII_ACCESS_READ | MII_ACCESS_BUSY;
|
||||
ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
|
||||
check_warn_goto_done(ret, "Error writing MII_ACCESS");
|
||||
|
||||
|
@ -210,7 +210,7 @@ static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx,
|
|||
idx &= dev->mii.reg_num_mask;
|
||||
addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
|
||||
| ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
|
||||
| MII_ACCESS_WRITE;
|
||||
| MII_ACCESS_WRITE | MII_ACCESS_BUSY;
|
||||
ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
|
||||
check_warn_goto_done(ret, "Error writing MII_ACCESS");
|
||||
|
||||
|
@ -508,9 +508,10 @@ static int smsc75xx_link_reset(struct usbnet *dev)
|
|||
u16 lcladv, rmtadv;
|
||||
int ret;
|
||||
|
||||
/* clear interrupt status */
|
||||
/* read and write to clear phy interrupt status */
|
||||
ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);
|
||||
check_warn_return(ret, "Error reading PHY_INT_SRC");
|
||||
smsc75xx_mdio_write(dev->net, mii->phy_id, PHY_INT_SRC, 0xffff);
|
||||
|
||||
ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
|
||||
check_warn_return(ret, "Error writing INT_STS");
|
||||
|
@ -643,7 +644,7 @@ static int smsc75xx_set_mac_address(struct usbnet *dev)
|
|||
|
||||
static int smsc75xx_phy_initialize(struct usbnet *dev)
|
||||
{
|
||||
int bmcr, timeout = 0;
|
||||
int bmcr, ret, timeout = 0;
|
||||
|
||||
/* Initialize MII structure */
|
||||
dev->mii.dev = dev->net;
|
||||
|
@ -651,6 +652,7 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)
|
|||
dev->mii.mdio_write = smsc75xx_mdio_write;
|
||||
dev->mii.phy_id_mask = 0x1f;
|
||||
dev->mii.reg_num_mask = 0x1f;
|
||||
dev->mii.supports_gmii = 1;
|
||||
dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID;
|
||||
|
||||
/* reset phy and wait for reset to complete */
|
||||
|
@ -661,7 +663,7 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)
|
|||
bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
|
||||
check_warn_return(bmcr, "Error reading MII_BMCR");
|
||||
timeout++;
|
||||
} while ((bmcr & MII_BMCR) && (timeout < 100));
|
||||
} while ((bmcr & BMCR_RESET) && (timeout < 100));
|
||||
|
||||
if (timeout >= 100) {
|
||||
netdev_warn(dev->net, "timeout on PHY Reset");
|
||||
|
@ -671,10 +673,13 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)
|
|||
smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
|
||||
ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
|
||||
ADVERTISE_PAUSE_ASYM);
|
||||
smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000,
|
||||
ADVERTISE_1000FULL);
|
||||
|
||||
/* read to clear */
|
||||
smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
|
||||
check_warn_return(bmcr, "Error reading PHY_INT_SRC");
|
||||
/* read and write to clear phy interrupt status */
|
||||
ret = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
|
||||
check_warn_return(ret, "Error reading PHY_INT_SRC");
|
||||
smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_SRC, 0xffff);
|
||||
|
||||
smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK,
|
||||
PHY_INT_MASK_DEFAULT);
|
||||
|
@ -946,6 +951,14 @@ static int smsc75xx_reset(struct usbnet *dev)
|
|||
ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf);
|
||||
check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret);
|
||||
|
||||
/* allow mac to detect speed and duplex from phy */
|
||||
ret = smsc75xx_read_reg(dev, MAC_CR, &buf);
|
||||
check_warn_return(ret, "Failed to read MAC_CR: %d", ret);
|
||||
|
||||
buf |= (MAC_CR_ADD | MAC_CR_ASD);
|
||||
ret = smsc75xx_write_reg(dev, MAC_CR, buf);
|
||||
check_warn_return(ret, "Failed to write MAC_CR: %d", ret);
|
||||
|
||||
ret = smsc75xx_read_reg(dev, MAC_TX, &buf);
|
||||
check_warn_return(ret, "Failed to read MAC_TX: %d", ret);
|
||||
|
||||
|
@ -1212,7 +1225,7 @@ static const struct driver_info smsc75xx_info = {
|
|||
.rx_fixup = smsc75xx_rx_fixup,
|
||||
.tx_fixup = smsc75xx_tx_fixup,
|
||||
.status = smsc75xx_status,
|
||||
.flags = FLAG_ETHER | FLAG_SEND_ZLP,
|
||||
.flags = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR,
|
||||
};
|
||||
|
||||
static const struct usb_device_id products[] = {
|
||||
|
|
|
@ -1017,6 +1017,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
|
|||
dev->net->ethtool_ops = &smsc95xx_ethtool_ops;
|
||||
dev->net->flags |= IFF_MULTICAST;
|
||||
dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM;
|
||||
dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1191,7 +1192,7 @@ static const struct driver_info smsc95xx_info = {
|
|||
.rx_fixup = smsc95xx_rx_fixup,
|
||||
.tx_fixup = smsc95xx_tx_fixup,
|
||||
.status = smsc95xx_status,
|
||||
.flags = FLAG_ETHER | FLAG_SEND_ZLP,
|
||||
.flags = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR,
|
||||
};
|
||||
|
||||
static const struct usb_device_id products[] = {
|
||||
|
|
|
@ -210,6 +210,7 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf)
|
|||
} else {
|
||||
usb_fill_int_urb(dev->interrupt, dev->udev, pipe,
|
||||
buf, maxp, intr_complete, dev, period);
|
||||
dev->interrupt->transfer_flags |= URB_FREE_BUFFER;
|
||||
dev_dbg(&intf->dev,
|
||||
"status ep%din, %d bytes period %d\n",
|
||||
usb_pipeendpoint(pipe), maxp, period);
|
||||
|
@ -1443,7 +1444,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
|
|||
|
||||
status = register_netdev (net);
|
||||
if (status)
|
||||
goto out3;
|
||||
goto out4;
|
||||
netif_info(dev, probe, dev->net,
|
||||
"register '%s' at usb-%s-%s, %s, %pM\n",
|
||||
udev->dev.driver->name,
|
||||
|
@ -1461,6 +1462,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
|
|||
|
||||
return 0;
|
||||
|
||||
out4:
|
||||
usb_free_urb(dev->interrupt);
|
||||
out3:
|
||||
if (info->unbind)
|
||||
info->unbind (dev, udev);
|
||||
|
|
|
@ -220,6 +220,7 @@ static int ath_ahb_remove(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
ath5k_deinit_ah(ah);
|
||||
iounmap(ah->iobase);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
ieee80211_free_hw(hw);
|
||||
|
||||
|
|
|
@ -869,7 +869,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
|
|||
ar5008_hw_set_channel_regs(ah, chan);
|
||||
ar5008_hw_init_chain_masks(ah);
|
||||
ath9k_olc_init(ah);
|
||||
ath9k_hw_apply_txpower(ah, chan);
|
||||
ath9k_hw_apply_txpower(ah, chan, false);
|
||||
|
||||
/* Write analog registers */
|
||||
if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
|
||||
|
|
|
@ -54,7 +54,7 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)
|
|||
|
||||
if (val) {
|
||||
ah->paprd_table_write_done = true;
|
||||
ath9k_hw_apply_txpower(ah, chan);
|
||||
ath9k_hw_apply_txpower(ah, chan, false);
|
||||
}
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
|
||||
|
|
|
@ -694,7 +694,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
|
|||
ar9003_hw_override_ini(ah);
|
||||
ar9003_hw_set_channel_regs(ah, chan);
|
||||
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
|
||||
ath9k_hw_apply_txpower(ah, chan);
|
||||
ath9k_hw_apply_txpower(ah, chan, false);
|
||||
|
||||
if (AR_SREV_9462(ah)) {
|
||||
if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0,
|
||||
|
|
|
@ -824,6 +824,8 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
|
|||
regulatory->max_power_level = ratesArray[i];
|
||||
}
|
||||
|
||||
ath9k_hw_update_regulatory_maxpower(ah);
|
||||
|
||||
if (test)
|
||||
return;
|
||||
|
||||
|
|
|
@ -1454,7 +1454,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
|
|||
return false;
|
||||
}
|
||||
ath9k_hw_set_clockrate(ah);
|
||||
ath9k_hw_apply_txpower(ah, chan);
|
||||
ath9k_hw_apply_txpower(ah, chan, false);
|
||||
ath9k_hw_rfbus_done(ah);
|
||||
|
||||
if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
|
||||
|
@ -2652,7 +2652,8 @@ static int get_antenna_gain(struct ath_hw *ah, struct ath9k_channel *chan)
|
|||
return ah->eep_ops->get_eeprom(ah, gain_param);
|
||||
}
|
||||
|
||||
void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
bool test)
|
||||
{
|
||||
struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
|
||||
struct ieee80211_channel *channel;
|
||||
|
@ -2673,7 +2674,7 @@ void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan)
|
|||
|
||||
ah->eep_ops->set_txpower(ah, chan,
|
||||
ath9k_regd_get_ctl(reg, chan),
|
||||
ant_reduction, new_pwr, false);
|
||||
ant_reduction, new_pwr, test);
|
||||
}
|
||||
|
||||
void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
|
||||
|
@ -2686,7 +2687,7 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
|
|||
if (test)
|
||||
channel->max_power = MAX_RATE_POWER / 2;
|
||||
|
||||
ath9k_hw_apply_txpower(ah, chan);
|
||||
ath9k_hw_apply_txpower(ah, chan, test);
|
||||
|
||||
if (test)
|
||||
channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2);
|
||||
|
|
|
@ -985,7 +985,8 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
|
|||
/* PHY */
|
||||
void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
|
||||
u32 *coef_mantissa, u32 *coef_exponent);
|
||||
void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
bool test);
|
||||
|
||||
/*
|
||||
* Code Specific to AR5008, AR9001 or AR9002,
|
||||
|
|
|
@ -4827,7 +4827,13 @@ static int b43_op_start(struct ieee80211_hw *hw)
|
|||
out_mutex_unlock:
|
||||
mutex_unlock(&wl->mutex);
|
||||
|
||||
/* reload configuration */
|
||||
/*
|
||||
* Configuration may have been overwritten during initialization.
|
||||
* Reload the configuration, but only if initialization was
|
||||
* successful. Reloading the configuration after a failed init
|
||||
* may hang the system.
|
||||
*/
|
||||
if (!err)
|
||||
b43_op_config(hw, ~0);
|
||||
|
||||
return err;
|
||||
|
|
|
@ -108,9 +108,15 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
|
|||
sdio_release_host(sdfunc);
|
||||
}
|
||||
} else if (regaddr == SDIO_CCCR_ABORT) {
|
||||
sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func),
|
||||
GFP_KERNEL);
|
||||
if (!sdfunc)
|
||||
return -ENOMEM;
|
||||
sdfunc->num = 0;
|
||||
sdio_claim_host(sdfunc);
|
||||
sdio_writeb(sdfunc, *byte, regaddr, &err_ret);
|
||||
sdio_release_host(sdfunc);
|
||||
kfree(sdfunc);
|
||||
} else if (regaddr < 0xF0) {
|
||||
brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr);
|
||||
err_ret = -EPERM;
|
||||
|
@ -486,7 +492,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
|
|||
kfree(bus_if);
|
||||
return -ENOMEM;
|
||||
}
|
||||
sdiodev->func[0] = func->card->sdio_func[0];
|
||||
sdiodev->func[0] = func;
|
||||
sdiodev->func[1] = func;
|
||||
sdiodev->bus_if = bus_if;
|
||||
bus_if->bus_priv.sdio = sdiodev;
|
||||
|
|
|
@ -574,6 +574,8 @@ struct brcmf_sdio {
|
|||
|
||||
struct task_struct *dpc_tsk;
|
||||
struct completion dpc_wait;
|
||||
struct list_head dpc_tsklst;
|
||||
spinlock_t dpc_tl_lock;
|
||||
|
||||
struct semaphore sdsem;
|
||||
|
||||
|
@ -2594,29 +2596,58 @@ clkwait:
|
|||
return resched;
|
||||
}
|
||||
|
||||
static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus)
|
||||
{
|
||||
struct list_head *new_hd;
|
||||
unsigned long flags;
|
||||
|
||||
if (in_interrupt())
|
||||
new_hd = kzalloc(sizeof(struct list_head), GFP_ATOMIC);
|
||||
else
|
||||
new_hd = kzalloc(sizeof(struct list_head), GFP_KERNEL);
|
||||
if (new_hd == NULL)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&bus->dpc_tl_lock, flags);
|
||||
list_add_tail(new_hd, &bus->dpc_tsklst);
|
||||
spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
|
||||
}
|
||||
|
||||
static int brcmf_sdbrcm_dpc_thread(void *data)
|
||||
{
|
||||
struct brcmf_sdio *bus = (struct brcmf_sdio *) data;
|
||||
struct list_head *cur_hd, *tmp_hd;
|
||||
unsigned long flags;
|
||||
|
||||
allow_signal(SIGTERM);
|
||||
/* Run until signal received */
|
||||
while (1) {
|
||||
if (kthread_should_stop())
|
||||
break;
|
||||
if (!wait_for_completion_interruptible(&bus->dpc_wait)) {
|
||||
/* Call bus dpc unless it indicated down
|
||||
(then clean stop) */
|
||||
if (bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN) {
|
||||
if (brcmf_sdbrcm_dpc(bus))
|
||||
complete(&bus->dpc_wait);
|
||||
} else {
|
||||
|
||||
if (list_empty(&bus->dpc_tsklst))
|
||||
if (wait_for_completion_interruptible(&bus->dpc_wait))
|
||||
break;
|
||||
|
||||
spin_lock_irqsave(&bus->dpc_tl_lock, flags);
|
||||
list_for_each_safe(cur_hd, tmp_hd, &bus->dpc_tsklst) {
|
||||
spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
|
||||
|
||||
if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {
|
||||
/* after stopping the bus, exit thread */
|
||||
brcmf_sdbrcm_bus_stop(bus->sdiodev->dev);
|
||||
bus->dpc_tsk = NULL;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
break;
|
||||
|
||||
if (brcmf_sdbrcm_dpc(bus))
|
||||
brcmf_sdbrcm_adddpctsk(bus);
|
||||
|
||||
spin_lock_irqsave(&bus->dpc_tl_lock, flags);
|
||||
list_del(cur_hd);
|
||||
kfree(cur_hd);
|
||||
}
|
||||
spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -2669,9 +2700,11 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
|
|||
/* Schedule DPC if needed to send queued packet(s) */
|
||||
if (!bus->dpc_sched) {
|
||||
bus->dpc_sched = true;
|
||||
if (bus->dpc_tsk)
|
||||
if (bus->dpc_tsk) {
|
||||
brcmf_sdbrcm_adddpctsk(bus);
|
||||
complete(&bus->dpc_wait);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -3514,8 +3547,10 @@ void brcmf_sdbrcm_isr(void *arg)
|
|||
brcmf_dbg(ERROR, "isr w/o interrupt configured!\n");
|
||||
|
||||
bus->dpc_sched = true;
|
||||
if (bus->dpc_tsk)
|
||||
if (bus->dpc_tsk) {
|
||||
brcmf_sdbrcm_adddpctsk(bus);
|
||||
complete(&bus->dpc_wait);
|
||||
}
|
||||
}
|
||||
|
||||
static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
|
||||
|
@ -3559,10 +3594,12 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
|
|||
bus->ipend = true;
|
||||
|
||||
bus->dpc_sched = true;
|
||||
if (bus->dpc_tsk)
|
||||
if (bus->dpc_tsk) {
|
||||
brcmf_sdbrcm_adddpctsk(bus);
|
||||
complete(&bus->dpc_wait);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update interrupt tracking */
|
||||
bus->lastintrs = bus->intrcount;
|
||||
|
@ -3897,6 +3934,8 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
|
|||
}
|
||||
/* Initialize DPC thread */
|
||||
init_completion(&bus->dpc_wait);
|
||||
INIT_LIST_HEAD(&bus->dpc_tsklst);
|
||||
spin_lock_init(&bus->dpc_tl_lock);
|
||||
bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread,
|
||||
bus, "brcmf_dpc");
|
||||
if (IS_ERR(bus->dpc_tsk)) {
|
||||
|
|
|
@ -847,8 +847,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
|
|||
*/
|
||||
if (!(txs->status & TX_STATUS_AMPDU)
|
||||
&& (txs->status & TX_STATUS_INTERMEDIATE)) {
|
||||
wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n",
|
||||
__func__);
|
||||
BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -2191,6 +2191,7 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
|
|||
{
|
||||
int rc = 0;
|
||||
unsigned long flags;
|
||||
unsigned long now, end;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
if (priv->status & STATUS_HCMD_ACTIVE) {
|
||||
|
@ -2232,10 +2233,20 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
|
|||
}
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
now = jiffies;
|
||||
end = now + HOST_COMPLETE_TIMEOUT;
|
||||
again:
|
||||
rc = wait_event_interruptible_timeout(priv->wait_command_queue,
|
||||
!(priv->
|
||||
status & STATUS_HCMD_ACTIVE),
|
||||
HOST_COMPLETE_TIMEOUT);
|
||||
end - now);
|
||||
if (rc < 0) {
|
||||
now = jiffies;
|
||||
if (time_before(now, end))
|
||||
goto again;
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
if (priv->status & STATUS_HCMD_ACTIVE) {
|
||||
|
|
|
@ -46,8 +46,8 @@
|
|||
#include "iwl-prph.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL1000_UCODE_API_MAX 6
|
||||
#define IWL100_UCODE_API_MAX 6
|
||||
#define IWL1000_UCODE_API_MAX 5
|
||||
#define IWL100_UCODE_API_MAX 5
|
||||
|
||||
/* Oldest version we won't warn about */
|
||||
#define IWL1000_UCODE_API_OK 5
|
||||
|
@ -226,5 +226,5 @@ const struct iwl_cfg iwl100_bg_cfg = {
|
|||
IWL_DEVICE_100,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_OK));
|
||||
MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_OK));
|
||||
|
|
|
@ -51,10 +51,10 @@
|
|||
#define IWL135_UCODE_API_MAX 6
|
||||
|
||||
/* Oldest version we won't warn about */
|
||||
#define IWL2030_UCODE_API_OK 5
|
||||
#define IWL2000_UCODE_API_OK 5
|
||||
#define IWL105_UCODE_API_OK 5
|
||||
#define IWL135_UCODE_API_OK 5
|
||||
#define IWL2030_UCODE_API_OK 6
|
||||
#define IWL2000_UCODE_API_OK 6
|
||||
#define IWL105_UCODE_API_OK 6
|
||||
#define IWL135_UCODE_API_OK 6
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL2030_UCODE_API_MIN 5
|
||||
|
@ -328,7 +328,7 @@ const struct iwl_cfg iwl135_bgn_cfg = {
|
|||
.ht_params = &iwl2000_ht_params,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_OK));
|
||||
MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_OK));
|
||||
MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_OK));
|
||||
MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_OK));
|
||||
|
|
|
@ -51,6 +51,10 @@
|
|||
#define IWL5000_UCODE_API_MAX 5
|
||||
#define IWL5150_UCODE_API_MAX 2
|
||||
|
||||
/* Oldest version we won't warn about */
|
||||
#define IWL5000_UCODE_API_OK 5
|
||||
#define IWL5150_UCODE_API_OK 2
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL5000_UCODE_API_MIN 1
|
||||
#define IWL5150_UCODE_API_MIN 1
|
||||
|
@ -326,6 +330,7 @@ static const struct iwl_ht_params iwl5000_ht_params = {
|
|||
#define IWL_DEVICE_5000 \
|
||||
.fw_name_pre = IWL5000_FW_PRE, \
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX, \
|
||||
.ucode_api_ok = IWL5000_UCODE_API_OK, \
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN, \
|
||||
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
|
||||
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
|
||||
|
@ -371,6 +376,7 @@ const struct iwl_cfg iwl5350_agn_cfg = {
|
|||
.name = "Intel(R) WiMAX/WiFi Link 5350 AGN",
|
||||
.fw_name_pre = IWL5000_FW_PRE,
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_ok = IWL5000_UCODE_API_OK,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
.max_inst_size = IWLAGN_RTC_INST_SIZE,
|
||||
.max_data_size = IWLAGN_RTC_DATA_SIZE,
|
||||
|
@ -386,6 +392,7 @@ const struct iwl_cfg iwl5350_agn_cfg = {
|
|||
#define IWL_DEVICE_5150 \
|
||||
.fw_name_pre = IWL5150_FW_PRE, \
|
||||
.ucode_api_max = IWL5150_UCODE_API_MAX, \
|
||||
.ucode_api_ok = IWL5150_UCODE_API_OK, \
|
||||
.ucode_api_min = IWL5150_UCODE_API_MIN, \
|
||||
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
|
||||
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
|
||||
|
@ -409,5 +416,5 @@ const struct iwl_cfg iwl5150_abg_cfg = {
|
|||
IWL_DEVICE_5150,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_OK));
|
||||
MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_OK));
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
/* Oldest version we won't warn about */
|
||||
#define IWL6000_UCODE_API_OK 4
|
||||
#define IWL6000G2_UCODE_API_OK 5
|
||||
#define IWL6050_UCODE_API_OK 5
|
||||
#define IWL6000G2B_UCODE_API_OK 6
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL6000_UCODE_API_MIN 4
|
||||
|
@ -388,7 +390,7 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = {
|
|||
#define IWL_DEVICE_6030 \
|
||||
.fw_name_pre = IWL6030_FW_PRE, \
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX, \
|
||||
.ucode_api_ok = IWL6000G2_UCODE_API_OK, \
|
||||
.ucode_api_ok = IWL6000G2B_UCODE_API_OK, \
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN, \
|
||||
.max_inst_size = IWL60_RTC_INST_SIZE, \
|
||||
.max_data_size = IWL60_RTC_DATA_SIZE, \
|
||||
|
@ -557,6 +559,6 @@ const struct iwl_cfg iwl6000_3agn_cfg = {
|
|||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_OK));
|
||||
MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_OK));
|
||||
MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_OK));
|
||||
MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_OK));
|
||||
|
|
|
@ -863,7 +863,6 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
|
|||
|
||||
void iwlagn_prepare_restart(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_rxon_context *ctx;
|
||||
bool bt_full_concurrent;
|
||||
u8 bt_ci_compliance;
|
||||
u8 bt_load;
|
||||
|
@ -872,8 +871,6 @@ void iwlagn_prepare_restart(struct iwl_priv *priv)
|
|||
|
||||
lockdep_assert_held(&priv->mutex);
|
||||
|
||||
for_each_context(priv, ctx)
|
||||
ctx->vif = NULL;
|
||||
priv->is_open = 0;
|
||||
|
||||
/*
|
||||
|
|
|
@ -104,15 +104,29 @@
|
|||
* (see struct iwl_tfd_frame). These 16 pointer registers are offset by 0x04
|
||||
* bytes from one another. Each TFD circular buffer in DRAM must be 256-byte
|
||||
* aligned (address bits 0-7 must be 0).
|
||||
* Later devices have 20 (5000 series) or 30 (higher) queues, but the registers
|
||||
* for them are in different places.
|
||||
*
|
||||
* Bit fields in each pointer register:
|
||||
* 27-0: TFD CB physical base address [35:8], must be 256-byte aligned
|
||||
*/
|
||||
#define FH_MEM_CBBC_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0x9D0)
|
||||
#define FH_MEM_CBBC_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xA10)
|
||||
#define FH_MEM_CBBC_0_15_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0x9D0)
|
||||
#define FH_MEM_CBBC_0_15_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xA10)
|
||||
#define FH_MEM_CBBC_16_19_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xBF0)
|
||||
#define FH_MEM_CBBC_16_19_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xC00)
|
||||
#define FH_MEM_CBBC_20_31_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xB20)
|
||||
#define FH_MEM_CBBC_20_31_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xB80)
|
||||
|
||||
/* Find TFD CB base pointer for given queue (range 0-15). */
|
||||
#define FH_MEM_CBBC_QUEUE(x) (FH_MEM_CBBC_LOWER_BOUND + (x) * 0x4)
|
||||
/* Find TFD CB base pointer for given queue */
|
||||
static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl)
|
||||
{
|
||||
if (chnl < 16)
|
||||
return FH_MEM_CBBC_0_15_LOWER_BOUND + 4 * chnl;
|
||||
if (chnl < 20)
|
||||
return FH_MEM_CBBC_16_19_LOWER_BOUND + 4 * (chnl - 16);
|
||||
WARN_ON_ONCE(chnl >= 32);
|
||||
return FH_MEM_CBBC_20_31_LOWER_BOUND + 4 * (chnl - 20);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -1244,6 +1244,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
|
|||
struct iwl_rxon_context *tmp, *ctx = NULL;
|
||||
int err;
|
||||
enum nl80211_iftype viftype = ieee80211_vif_type_p2p(vif);
|
||||
bool reset = false;
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
|
||||
viftype, vif->addr);
|
||||
|
@ -1265,6 +1266,13 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
|
|||
tmp->interface_modes | tmp->exclusive_interface_modes;
|
||||
|
||||
if (tmp->vif) {
|
||||
/* On reset we need to add the same interface again */
|
||||
if (tmp->vif == vif) {
|
||||
reset = true;
|
||||
ctx = tmp;
|
||||
break;
|
||||
}
|
||||
|
||||
/* check if this busy context is exclusive */
|
||||
if (tmp->exclusive_interface_modes &
|
||||
BIT(tmp->vif->type)) {
|
||||
|
@ -1291,7 +1299,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
|
|||
ctx->vif = vif;
|
||||
|
||||
err = iwl_setup_interface(priv, ctx);
|
||||
if (!err)
|
||||
if (!err || reset)
|
||||
goto out;
|
||||
|
||||
ctx->vif = NULL;
|
||||
|
|
|
@ -223,12 +223,33 @@
|
|||
#define SCD_AIT (SCD_BASE + 0x0c)
|
||||
#define SCD_TXFACT (SCD_BASE + 0x10)
|
||||
#define SCD_ACTIVE (SCD_BASE + 0x14)
|
||||
#define SCD_QUEUE_WRPTR(x) (SCD_BASE + 0x18 + (x) * 4)
|
||||
#define SCD_QUEUE_RDPTR(x) (SCD_BASE + 0x68 + (x) * 4)
|
||||
#define SCD_QUEUECHAIN_SEL (SCD_BASE + 0xe8)
|
||||
#define SCD_AGGR_SEL (SCD_BASE + 0x248)
|
||||
#define SCD_INTERRUPT_MASK (SCD_BASE + 0x108)
|
||||
#define SCD_QUEUE_STATUS_BITS(x) (SCD_BASE + 0x10c + (x) * 4)
|
||||
|
||||
static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl)
|
||||
{
|
||||
if (chnl < 20)
|
||||
return SCD_BASE + 0x18 + chnl * 4;
|
||||
WARN_ON_ONCE(chnl >= 32);
|
||||
return SCD_BASE + 0x284 + (chnl - 20) * 4;
|
||||
}
|
||||
|
||||
static inline unsigned int SCD_QUEUE_RDPTR(unsigned int chnl)
|
||||
{
|
||||
if (chnl < 20)
|
||||
return SCD_BASE + 0x68 + chnl * 4;
|
||||
WARN_ON_ONCE(chnl >= 32);
|
||||
return SCD_BASE + 0x2B4 + (chnl - 20) * 4;
|
||||
}
|
||||
|
||||
static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl)
|
||||
{
|
||||
if (chnl < 20)
|
||||
return SCD_BASE + 0x10c + chnl * 4;
|
||||
WARN_ON_ONCE(chnl >= 32);
|
||||
return SCD_BASE + 0x384 + (chnl - 20) * 4;
|
||||
}
|
||||
|
||||
/*********************** END TX SCHEDULER *************************************/
|
||||
|
||||
|
|
|
@ -1941,6 +1941,7 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
|
|||
rtl_deinit_deferred_work(hw);
|
||||
rtlpriv->intf_ops->adapter_stop(hw);
|
||||
}
|
||||
rtlpriv->cfg->ops->disable_interrupt(hw);
|
||||
|
||||
/*deinit rfkill */
|
||||
rtl_deinit_rfkill(hw);
|
||||
|
|
|
@ -479,6 +479,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
|
|||
cancel_work_sync(&wl->irq_work);
|
||||
cancel_work_sync(&wl->tx_work);
|
||||
cancel_work_sync(&wl->filter_work);
|
||||
cancel_delayed_work_sync(&wl->elp_work);
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
|
||||
|
|
|
@ -315,8 +315,8 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)
|
|||
|
||||
if (wl->irq)
|
||||
free_irq(wl->irq, wl);
|
||||
kfree(wl_sdio);
|
||||
wl1251_free_hw(wl);
|
||||
kfree(wl_sdio);
|
||||
|
||||
sdio_claim_host(func);
|
||||
sdio_release_irq(func);
|
||||
|
|
|
@ -1672,7 +1672,8 @@ static void qeth_configure_blkt_default(struct qeth_card *card, char *prcd)
|
|||
{
|
||||
QETH_DBF_TEXT(SETUP, 2, "cfgblkt");
|
||||
|
||||
if (prcd[74] == 0xF0 && prcd[75] == 0xF0 && prcd[76] == 0xF5) {
|
||||
if (prcd[74] == 0xF0 && prcd[75] == 0xF0 &&
|
||||
(prcd[76] == 0xF5 || prcd[76] == 0xF6)) {
|
||||
card->info.blkt.time_total = 250;
|
||||
card->info.blkt.inter_packet = 5;
|
||||
card->info.blkt.inter_packet_jumbo = 15;
|
||||
|
@ -4540,6 +4541,7 @@ static void qeth_determine_capabilities(struct qeth_card *card)
|
|||
goto out_offline;
|
||||
}
|
||||
qeth_configure_unitaddr(card, prcd);
|
||||
if (ddev_offline)
|
||||
qeth_configure_blkt_default(card, prcd);
|
||||
kfree(prcd);
|
||||
|
||||
|
|
|
@ -104,9 +104,18 @@ struct bridge_skb_cb {
|
|||
} daddr;
|
||||
};
|
||||
|
||||
static inline void br_drop_fake_rtable(struct sk_buff *skb)
|
||||
{
|
||||
struct dst_entry *dst = skb_dst(skb);
|
||||
|
||||
if (dst && (dst->flags & DST_FAKE_RTABLE))
|
||||
skb_dst_drop(skb);
|
||||
}
|
||||
|
||||
#else
|
||||
#define nf_bridge_maybe_copy_header(skb) (0)
|
||||
#define nf_bridge_pad(skb) (0)
|
||||
#define br_drop_fake_rtable(skb) do { } while (0)
|
||||
#endif /* CONFIG_BRIDGE_NETFILTER */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
|
|
@ -1020,7 +1020,7 @@ static inline void skb_queue_splice(const struct sk_buff_head *list,
|
|||
}
|
||||
|
||||
/**
|
||||
* skb_queue_splice - join two skb lists and reinitialise the emptied list
|
||||
* skb_queue_splice_init - join two skb lists and reinitialise the emptied list
|
||||
* @list: the new list to add
|
||||
* @head: the place to add it in the first list
|
||||
*
|
||||
|
@ -1051,7 +1051,7 @@ static inline void skb_queue_splice_tail(const struct sk_buff_head *list,
|
|||
}
|
||||
|
||||
/**
|
||||
* skb_queue_splice_tail - join two skb lists and reinitialise the emptied list
|
||||
* skb_queue_splice_tail_init - join two skb lists and reinitialise the emptied list
|
||||
* @list: the new list to add
|
||||
* @head: the place to add it in the first list
|
||||
*
|
||||
|
|
|
@ -314,6 +314,7 @@ struct hci_conn {
|
|||
|
||||
__u8 remote_cap;
|
||||
__u8 remote_auth;
|
||||
bool flush_key;
|
||||
|
||||
unsigned int sent;
|
||||
|
||||
|
@ -980,7 +981,7 @@ int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
|
|||
int mgmt_connectable(struct hci_dev *hdev, u8 connectable);
|
||||
int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status);
|
||||
int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
|
||||
u8 persistent);
|
||||
bool persistent);
|
||||
int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
|
||||
u8 addr_type, u32 flags, u8 *name, u8 name_len,
|
||||
u8 *dev_class);
|
||||
|
|
|
@ -59,6 +59,7 @@ struct dst_entry {
|
|||
#define DST_NOCACHE 0x0010
|
||||
#define DST_NOCOUNT 0x0020
|
||||
#define DST_NOPEER 0x0040
|
||||
#define DST_FAKE_RTABLE 0x0080
|
||||
|
||||
short error;
|
||||
short obsolete;
|
||||
|
|
|
@ -393,7 +393,7 @@ struct ip_vs_protocol {
|
|||
|
||||
void (*exit)(struct ip_vs_protocol *pp);
|
||||
|
||||
void (*init_netns)(struct net *net, struct ip_vs_proto_data *pd);
|
||||
int (*init_netns)(struct net *net, struct ip_vs_proto_data *pd);
|
||||
|
||||
void (*exit_netns)(struct net *net, struct ip_vs_proto_data *pd);
|
||||
|
||||
|
@ -1203,6 +1203,8 @@ ip_vs_lookup_real_service(struct net *net, int af, __u16 protocol,
|
|||
|
||||
extern int ip_vs_use_count_inc(void);
|
||||
extern void ip_vs_use_count_dec(void);
|
||||
extern int ip_vs_register_nl_ioctl(void);
|
||||
extern void ip_vs_unregister_nl_ioctl(void);
|
||||
extern int ip_vs_control_init(void);
|
||||
extern void ip_vs_control_cleanup(void);
|
||||
extern struct ip_vs_dest *
|
||||
|
|
|
@ -1129,9 +1129,9 @@ sk_sockets_allocated_read_positive(struct sock *sk)
|
|||
struct proto *prot = sk->sk_prot;
|
||||
|
||||
if (mem_cgroup_sockets_enabled && sk->sk_cgrp)
|
||||
return percpu_counter_sum_positive(sk->sk_cgrp->sockets_allocated);
|
||||
return percpu_counter_read_positive(sk->sk_cgrp->sockets_allocated);
|
||||
|
||||
return percpu_counter_sum_positive(prot->sockets_allocated);
|
||||
return percpu_counter_read_positive(prot->sockets_allocated);
|
||||
}
|
||||
|
||||
static inline int
|
||||
|
|
|
@ -1215,40 +1215,40 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
|
||||
static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
|
||||
u8 key_type, u8 old_key_type)
|
||||
{
|
||||
/* Legacy key */
|
||||
if (key_type < 0x03)
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
/* Debug keys are insecure so don't store them persistently */
|
||||
if (key_type == HCI_LK_DEBUG_COMBINATION)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
/* Changed combination key and there's no previous one */
|
||||
if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
/* Security mode 3 case */
|
||||
if (!conn)
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
/* Neither local nor remote side had no-bonding as requirement */
|
||||
if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
/* Local side had dedicated bonding as requirement */
|
||||
if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
/* Remote side had dedicated bonding as requirement */
|
||||
if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
/* If none of the above criteria match, then don't store the key
|
||||
* persistently */
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
|
||||
|
@ -1285,7 +1285,8 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
|
|||
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
|
||||
{
|
||||
struct link_key *key, *old_key;
|
||||
u8 old_key_type, persistent;
|
||||
u8 old_key_type;
|
||||
bool persistent;
|
||||
|
||||
old_key = hci_find_link_key(hdev, bdaddr);
|
||||
if (old_key) {
|
||||
|
@ -1328,10 +1329,8 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
|
|||
|
||||
mgmt_new_link_key(hdev, key, persistent);
|
||||
|
||||
if (!persistent) {
|
||||
list_del(&key->list);
|
||||
kfree(key);
|
||||
}
|
||||
if (conn)
|
||||
conn->flush_key = !persistent;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1901,6 +1901,8 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
|
|||
}
|
||||
|
||||
if (ev->status == 0) {
|
||||
if (conn->type == ACL_LINK && conn->flush_key)
|
||||
hci_remove_link_key(hdev, &conn->dst);
|
||||
hci_proto_disconn_cfm(conn, ev->reason);
|
||||
hci_conn_del(conn);
|
||||
}
|
||||
|
@ -2311,6 +2313,7 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
|
|||
|
||||
case HCI_OP_USER_PASSKEY_NEG_REPLY:
|
||||
hci_cc_user_passkey_neg_reply(hdev, skb);
|
||||
break;
|
||||
|
||||
case HCI_OP_LE_SET_SCAN_PARAM:
|
||||
hci_cc_le_set_scan_param(hdev, skb);
|
||||
|
|
|
@ -2884,7 +2884,7 @@ int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, u8 persistent)
|
||||
int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, bool persistent)
|
||||
{
|
||||
struct mgmt_ev_new_link_key ev;
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ int br_dev_queue_push_xmit(struct sk_buff *skb)
|
|||
kfree_skb(skb);
|
||||
} else {
|
||||
skb_push(skb, ETH_HLEN);
|
||||
br_drop_fake_rtable(skb);
|
||||
dev_queue_xmit(skb);
|
||||
}
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ void br_netfilter_rtable_init(struct net_bridge *br)
|
|||
rt->dst.dev = br->dev;
|
||||
rt->dst.path = &rt->dst;
|
||||
dst_init_metrics(&rt->dst, br_dst_default_metrics, true);
|
||||
rt->dst.flags = DST_NOXFRM | DST_NOPEER;
|
||||
rt->dst.flags = DST_NOXFRM | DST_NOPEER | DST_FAKE_RTABLE;
|
||||
rt->dst.ops = &fake_dst_ops;
|
||||
}
|
||||
|
||||
|
@ -694,11 +694,7 @@ static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff *skb,
|
|||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
struct rtable *rt = skb_rtable(skb);
|
||||
|
||||
if (rt && rt == bridge_parent_rtable(in))
|
||||
skb_dst_drop(skb);
|
||||
|
||||
br_drop_fake_rtable(skb);
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,13 +42,14 @@ static void send_dm_alert(struct work_struct *unused);
|
|||
* netlink alerts
|
||||
*/
|
||||
static int trace_state = TRACE_OFF;
|
||||
static DEFINE_SPINLOCK(trace_state_lock);
|
||||
static DEFINE_MUTEX(trace_state_mutex);
|
||||
|
||||
struct per_cpu_dm_data {
|
||||
struct work_struct dm_alert_work;
|
||||
struct sk_buff *skb;
|
||||
struct sk_buff __rcu *skb;
|
||||
atomic_t dm_hit_count;
|
||||
struct timer_list send_timer;
|
||||
int cpu;
|
||||
};
|
||||
|
||||
struct dm_hw_stat_delta {
|
||||
|
@ -79,29 +80,53 @@ static void reset_per_cpu_data(struct per_cpu_dm_data *data)
|
|||
size_t al;
|
||||
struct net_dm_alert_msg *msg;
|
||||
struct nlattr *nla;
|
||||
struct sk_buff *skb;
|
||||
struct sk_buff *oskb = rcu_dereference_protected(data->skb, 1);
|
||||
|
||||
al = sizeof(struct net_dm_alert_msg);
|
||||
al += dm_hit_limit * sizeof(struct net_dm_drop_point);
|
||||
al += sizeof(struct nlattr);
|
||||
|
||||
data->skb = genlmsg_new(al, GFP_KERNEL);
|
||||
genlmsg_put(data->skb, 0, 0, &net_drop_monitor_family,
|
||||
skb = genlmsg_new(al, GFP_KERNEL);
|
||||
|
||||
if (skb) {
|
||||
genlmsg_put(skb, 0, 0, &net_drop_monitor_family,
|
||||
0, NET_DM_CMD_ALERT);
|
||||
nla = nla_reserve(data->skb, NLA_UNSPEC, sizeof(struct net_dm_alert_msg));
|
||||
nla = nla_reserve(skb, NLA_UNSPEC,
|
||||
sizeof(struct net_dm_alert_msg));
|
||||
msg = nla_data(nla);
|
||||
memset(msg, 0, al);
|
||||
} else
|
||||
schedule_work_on(data->cpu, &data->dm_alert_work);
|
||||
|
||||
/*
|
||||
* Don't need to lock this, since we are guaranteed to only
|
||||
* run this on a single cpu at a time.
|
||||
* Note also that we only update data->skb if the old and new skb
|
||||
* pointers don't match. This ensures that we don't continually call
|
||||
* synchornize_rcu if we repeatedly fail to alloc a new netlink message.
|
||||
*/
|
||||
if (skb != oskb) {
|
||||
rcu_assign_pointer(data->skb, skb);
|
||||
|
||||
synchronize_rcu();
|
||||
|
||||
atomic_set(&data->dm_hit_count, dm_hit_limit);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void send_dm_alert(struct work_struct *unused)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data);
|
||||
struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data);
|
||||
|
||||
WARN_ON_ONCE(data->cpu != smp_processor_id());
|
||||
|
||||
/*
|
||||
* Grab the skb we're about to send
|
||||
*/
|
||||
skb = data->skb;
|
||||
skb = rcu_dereference_protected(data->skb, 1);
|
||||
|
||||
/*
|
||||
* Replace it with a new one
|
||||
|
@ -111,8 +136,10 @@ static void send_dm_alert(struct work_struct *unused)
|
|||
/*
|
||||
* Ship it!
|
||||
*/
|
||||
if (skb)
|
||||
genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL);
|
||||
|
||||
put_cpu_var(dm_cpu_data);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -123,9 +150,11 @@ static void send_dm_alert(struct work_struct *unused)
|
|||
*/
|
||||
static void sched_send_work(unsigned long unused)
|
||||
{
|
||||
struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data);
|
||||
struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data);
|
||||
|
||||
schedule_work(&data->dm_alert_work);
|
||||
schedule_work_on(smp_processor_id(), &data->dm_alert_work);
|
||||
|
||||
put_cpu_var(dm_cpu_data);
|
||||
}
|
||||
|
||||
static void trace_drop_common(struct sk_buff *skb, void *location)
|
||||
|
@ -134,9 +163,16 @@ static void trace_drop_common(struct sk_buff *skb, void *location)
|
|||
struct nlmsghdr *nlh;
|
||||
struct nlattr *nla;
|
||||
int i;
|
||||
struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data);
|
||||
struct sk_buff *dskb;
|
||||
struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data);
|
||||
|
||||
|
||||
rcu_read_lock();
|
||||
dskb = rcu_dereference(data->skb);
|
||||
|
||||
if (!dskb)
|
||||
goto out;
|
||||
|
||||
if (!atomic_add_unless(&data->dm_hit_count, -1, 0)) {
|
||||
/*
|
||||
* we're already at zero, discard this hit
|
||||
|
@ -144,7 +180,7 @@ static void trace_drop_common(struct sk_buff *skb, void *location)
|
|||
goto out;
|
||||
}
|
||||
|
||||
nlh = (struct nlmsghdr *)data->skb->data;
|
||||
nlh = (struct nlmsghdr *)dskb->data;
|
||||
nla = genlmsg_data(nlmsg_data(nlh));
|
||||
msg = nla_data(nla);
|
||||
for (i = 0; i < msg->entries; i++) {
|
||||
|
@ -158,7 +194,7 @@ static void trace_drop_common(struct sk_buff *skb, void *location)
|
|||
/*
|
||||
* We need to create a new entry
|
||||
*/
|
||||
__nla_reserve_nohdr(data->skb, sizeof(struct net_dm_drop_point));
|
||||
__nla_reserve_nohdr(dskb, sizeof(struct net_dm_drop_point));
|
||||
nla->nla_len += NLA_ALIGN(sizeof(struct net_dm_drop_point));
|
||||
memcpy(msg->points[msg->entries].pc, &location, sizeof(void *));
|
||||
msg->points[msg->entries].count = 1;
|
||||
|
@ -170,6 +206,8 @@ static void trace_drop_common(struct sk_buff *skb, void *location)
|
|||
}
|
||||
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
put_cpu_var(dm_cpu_data);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -214,7 +252,7 @@ static int set_all_monitor_traces(int state)
|
|||
struct dm_hw_stat_delta *new_stat = NULL;
|
||||
struct dm_hw_stat_delta *temp;
|
||||
|
||||
spin_lock(&trace_state_lock);
|
||||
mutex_lock(&trace_state_mutex);
|
||||
|
||||
if (state == trace_state) {
|
||||
rc = -EAGAIN;
|
||||
|
@ -253,7 +291,7 @@ static int set_all_monitor_traces(int state)
|
|||
rc = -EINPROGRESS;
|
||||
|
||||
out_unlock:
|
||||
spin_unlock(&trace_state_lock);
|
||||
mutex_unlock(&trace_state_mutex);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -296,12 +334,12 @@ static int dropmon_net_event(struct notifier_block *ev_block,
|
|||
|
||||
new_stat->dev = dev;
|
||||
new_stat->last_rx = jiffies;
|
||||
spin_lock(&trace_state_lock);
|
||||
mutex_lock(&trace_state_mutex);
|
||||
list_add_rcu(&new_stat->list, &hw_stats_list);
|
||||
spin_unlock(&trace_state_lock);
|
||||
mutex_unlock(&trace_state_mutex);
|
||||
break;
|
||||
case NETDEV_UNREGISTER:
|
||||
spin_lock(&trace_state_lock);
|
||||
mutex_lock(&trace_state_mutex);
|
||||
list_for_each_entry_safe(new_stat, tmp, &hw_stats_list, list) {
|
||||
if (new_stat->dev == dev) {
|
||||
new_stat->dev = NULL;
|
||||
|
@ -312,7 +350,7 @@ static int dropmon_net_event(struct notifier_block *ev_block,
|
|||
}
|
||||
}
|
||||
}
|
||||
spin_unlock(&trace_state_lock);
|
||||
mutex_unlock(&trace_state_mutex);
|
||||
break;
|
||||
}
|
||||
out:
|
||||
|
@ -368,13 +406,15 @@ static int __init init_net_drop_monitor(void)
|
|||
|
||||
for_each_present_cpu(cpu) {
|
||||
data = &per_cpu(dm_cpu_data, cpu);
|
||||
reset_per_cpu_data(data);
|
||||
data->cpu = cpu;
|
||||
INIT_WORK(&data->dm_alert_work, send_dm_alert);
|
||||
init_timer(&data->send_timer);
|
||||
data->send_timer.data = cpu;
|
||||
data->send_timer.function = sched_send_work;
|
||||
reset_per_cpu_data(data);
|
||||
}
|
||||
|
||||
|
||||
goto out;
|
||||
|
||||
out_unreg:
|
||||
|
|
|
@ -1044,6 +1044,24 @@ static void lowpan_dev_free(struct net_device *dev)
|
|||
free_netdev(dev);
|
||||
}
|
||||
|
||||
static struct wpan_phy *lowpan_get_phy(const struct net_device *dev)
|
||||
{
|
||||
struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
|
||||
return ieee802154_mlme_ops(real_dev)->get_phy(real_dev);
|
||||
}
|
||||
|
||||
static u16 lowpan_get_pan_id(const struct net_device *dev)
|
||||
{
|
||||
struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
|
||||
return ieee802154_mlme_ops(real_dev)->get_pan_id(real_dev);
|
||||
}
|
||||
|
||||
static u16 lowpan_get_short_addr(const struct net_device *dev)
|
||||
{
|
||||
struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
|
||||
return ieee802154_mlme_ops(real_dev)->get_short_addr(real_dev);
|
||||
}
|
||||
|
||||
static struct header_ops lowpan_header_ops = {
|
||||
.create = lowpan_header_create,
|
||||
};
|
||||
|
@ -1053,6 +1071,12 @@ static const struct net_device_ops lowpan_netdev_ops = {
|
|||
.ndo_set_mac_address = eth_mac_addr,
|
||||
};
|
||||
|
||||
static struct ieee802154_mlme_ops lowpan_mlme = {
|
||||
.get_pan_id = lowpan_get_pan_id,
|
||||
.get_phy = lowpan_get_phy,
|
||||
.get_short_addr = lowpan_get_short_addr,
|
||||
};
|
||||
|
||||
static void lowpan_setup(struct net_device *dev)
|
||||
{
|
||||
pr_debug("(%s)\n", __func__);
|
||||
|
@ -1070,6 +1094,7 @@ static void lowpan_setup(struct net_device *dev)
|
|||
|
||||
dev->netdev_ops = &lowpan_netdev_ops;
|
||||
dev->header_ops = &lowpan_header_ops;
|
||||
dev->ml_priv = &lowpan_mlme;
|
||||
dev->destructor = lowpan_dev_free;
|
||||
}
|
||||
|
||||
|
@ -1143,6 +1168,8 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev,
|
|||
list_add_tail(&entry->list, &lowpan_devices);
|
||||
mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx);
|
||||
|
||||
spin_lock_init(&flist_lock);
|
||||
|
||||
register_netdevice(dev);
|
||||
|
||||
return 0;
|
||||
|
@ -1152,11 +1179,20 @@ static void lowpan_dellink(struct net_device *dev, struct list_head *head)
|
|||
{
|
||||
struct lowpan_dev_info *lowpan_dev = lowpan_dev_info(dev);
|
||||
struct net_device *real_dev = lowpan_dev->real_dev;
|
||||
struct lowpan_dev_record *entry;
|
||||
struct lowpan_dev_record *tmp;
|
||||
struct lowpan_dev_record *entry, *tmp;
|
||||
struct lowpan_fragment *frame, *tframe;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
spin_lock(&flist_lock);
|
||||
list_for_each_entry_safe(frame, tframe, &lowpan_fragments, list) {
|
||||
del_timer(&frame->timer);
|
||||
list_del(&frame->list);
|
||||
dev_kfree_skb(frame->skb);
|
||||
kfree(frame);
|
||||
}
|
||||
spin_unlock(&flist_lock);
|
||||
|
||||
mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx);
|
||||
list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) {
|
||||
if (entry->ldev == dev) {
|
||||
|
|
|
@ -141,7 +141,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
|
|||
goto rtattr_failure;
|
||||
|
||||
if (icsk == NULL) {
|
||||
r->idiag_rqueue = r->idiag_wqueue = 0;
|
||||
handler->idiag_get_info(sk, r, NULL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -3243,7 +3243,7 @@ void __init tcp_init(void)
|
|||
{
|
||||
struct sk_buff *skb = NULL;
|
||||
unsigned long limit;
|
||||
int max_share, cnt;
|
||||
int max_rshare, max_wshare, cnt;
|
||||
unsigned int i;
|
||||
unsigned long jiffy = jiffies;
|
||||
|
||||
|
@ -3303,15 +3303,16 @@ void __init tcp_init(void)
|
|||
tcp_init_mem(&init_net);
|
||||
/* Set per-socket limits to no more than 1/128 the pressure threshold */
|
||||
limit = nr_free_buffer_pages() << (PAGE_SHIFT - 7);
|
||||
max_share = min(4UL*1024*1024, limit);
|
||||
max_wshare = min(4UL*1024*1024, limit);
|
||||
max_rshare = min(6UL*1024*1024, limit);
|
||||
|
||||
sysctl_tcp_wmem[0] = SK_MEM_QUANTUM;
|
||||
sysctl_tcp_wmem[1] = 16*1024;
|
||||
sysctl_tcp_wmem[2] = max(64*1024, max_share);
|
||||
sysctl_tcp_wmem[2] = max(64*1024, max_wshare);
|
||||
|
||||
sysctl_tcp_rmem[0] = SK_MEM_QUANTUM;
|
||||
sysctl_tcp_rmem[1] = 87380;
|
||||
sysctl_tcp_rmem[2] = max(87380, max_share);
|
||||
sysctl_tcp_rmem[2] = max(87380, max_rshare);
|
||||
|
||||
pr_info("Hash tables configured (established %u bind %u)\n",
|
||||
tcp_hashinfo.ehash_mask + 1, tcp_hashinfo.bhash_size);
|
||||
|
|
|
@ -85,7 +85,7 @@ int sysctl_tcp_ecn __read_mostly = 2;
|
|||
EXPORT_SYMBOL(sysctl_tcp_ecn);
|
||||
int sysctl_tcp_dsack __read_mostly = 1;
|
||||
int sysctl_tcp_app_win __read_mostly = 31;
|
||||
int sysctl_tcp_adv_win_scale __read_mostly = 2;
|
||||
int sysctl_tcp_adv_win_scale __read_mostly = 1;
|
||||
EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);
|
||||
|
||||
int sysctl_tcp_stdurg __read_mostly;
|
||||
|
@ -495,7 +495,7 @@ static inline void tcp_rcv_rtt_measure(struct tcp_sock *tp)
|
|||
goto new_measure;
|
||||
if (before(tp->rcv_nxt, tp->rcv_rtt_est.seq))
|
||||
return;
|
||||
tcp_rcv_rtt_update(tp, jiffies - tp->rcv_rtt_est.time, 1);
|
||||
tcp_rcv_rtt_update(tp, tcp_time_stamp - tp->rcv_rtt_est.time, 1);
|
||||
|
||||
new_measure:
|
||||
tp->rcv_rtt_est.seq = tp->rcv_nxt + tp->rcv_wnd;
|
||||
|
@ -2868,12 +2868,15 @@ static inline void tcp_complete_cwr(struct sock *sk)
|
|||
|
||||
/* Do not moderate cwnd if it's already undone in cwr or recovery. */
|
||||
if (tp->undo_marker) {
|
||||
if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR)
|
||||
if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR) {
|
||||
tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
|
||||
else /* PRR */
|
||||
tp->snd_cwnd_stamp = tcp_time_stamp;
|
||||
} else if (tp->snd_ssthresh < TCP_INFINITE_SSTHRESH) {
|
||||
/* PRR algorithm. */
|
||||
tp->snd_cwnd = tp->snd_ssthresh;
|
||||
tp->snd_cwnd_stamp = tcp_time_stamp;
|
||||
}
|
||||
}
|
||||
tcp_ca_event(sk, CA_EVENT_COMPLETE_CWR);
|
||||
}
|
||||
|
||||
|
|
|
@ -146,9 +146,17 @@ static int udp_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh,
|
|||
return udp_dump_one(&udp_table, in_skb, nlh, req);
|
||||
}
|
||||
|
||||
static void udp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
|
||||
void *info)
|
||||
{
|
||||
r->idiag_rqueue = sk_rmem_alloc_get(sk);
|
||||
r->idiag_wqueue = sk_wmem_alloc_get(sk);
|
||||
}
|
||||
|
||||
static const struct inet_diag_handler udp_diag_handler = {
|
||||
.dump = udp_diag_dump,
|
||||
.dump_one = udp_diag_dump_one,
|
||||
.idiag_get_info = udp_diag_get_info,
|
||||
.idiag_type = IPPROTO_UDP,
|
||||
};
|
||||
|
||||
|
@ -167,6 +175,7 @@ static int udplite_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *
|
|||
static const struct inet_diag_handler udplite_diag_handler = {
|
||||
.dump = udplite_diag_dump,
|
||||
.dump_one = udplite_diag_dump_one,
|
||||
.idiag_get_info = udp_diag_get_info,
|
||||
.idiag_type = IPPROTO_UDPLITE,
|
||||
};
|
||||
|
||||
|
|
|
@ -442,8 +442,9 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
|
|||
|
||||
daddr = lip->l2tp_addr.s_addr;
|
||||
} else {
|
||||
rc = -EDESTADDRREQ;
|
||||
if (sk->sk_state != TCP_ESTABLISHED)
|
||||
return -EDESTADDRREQ;
|
||||
goto out;
|
||||
|
||||
daddr = inet->inet_daddr;
|
||||
connected = 1;
|
||||
|
|
|
@ -1210,7 +1210,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
|
|||
struct sk_buff *skb);
|
||||
void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211_mgd_teardown(struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata);
|
||||
|
||||
/* IBSS code */
|
||||
void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
|
||||
|
|
|
@ -486,6 +486,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
|
|||
/* free all potentially still buffered bcast frames */
|
||||
local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps_bc_buf);
|
||||
skb_queue_purge(&sdata->u.ap.ps_bc_buf);
|
||||
} else if (sdata->vif.type == NL80211_IFTYPE_STATION) {
|
||||
ieee80211_mgd_stop(sdata);
|
||||
}
|
||||
|
||||
if (going_down)
|
||||
|
@ -644,8 +646,6 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
|
|||
|
||||
if (ieee80211_vif_is_mesh(&sdata->vif))
|
||||
mesh_rmc_free(sdata);
|
||||
else if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
||||
ieee80211_mgd_teardown(sdata);
|
||||
|
||||
flushed = sta_info_flush(local, sdata);
|
||||
WARN_ON(flushed);
|
||||
|
|
|
@ -3497,7 +3497,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ieee80211_mgd_teardown(struct ieee80211_sub_if_data *sdata)
|
||||
void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
|
||||
|
|
|
@ -1158,7 +1158,8 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
|
|||
tx->sta = rcu_dereference(sdata->u.vlan.sta);
|
||||
if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr)
|
||||
return TX_DROP;
|
||||
} else if (info->flags & IEEE80211_TX_CTL_INJECTED) {
|
||||
} else if (info->flags & IEEE80211_TX_CTL_INJECTED ||
|
||||
tx->sdata->control_port_protocol == tx->skb->protocol) {
|
||||
tx->sta = sta_info_get_bss(sdata, hdr->addr1);
|
||||
}
|
||||
if (!tx->sta)
|
||||
|
|
|
@ -1924,6 +1924,7 @@ protocol_fail:
|
|||
control_fail:
|
||||
ip_vs_estimator_net_cleanup(net);
|
||||
estimator_fail:
|
||||
net->ipvs = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -1936,6 +1937,7 @@ static void __net_exit __ip_vs_cleanup(struct net *net)
|
|||
ip_vs_control_net_cleanup(net);
|
||||
ip_vs_estimator_net_cleanup(net);
|
||||
IP_VS_DBG(2, "ipvs netns %d released\n", net_ipvs(net)->gen);
|
||||
net->ipvs = NULL;
|
||||
}
|
||||
|
||||
static void __net_exit __ip_vs_dev_cleanup(struct net *net)
|
||||
|
@ -1993,10 +1995,18 @@ static int __init ip_vs_init(void)
|
|||
goto cleanup_dev;
|
||||
}
|
||||
|
||||
ret = ip_vs_register_nl_ioctl();
|
||||
if (ret < 0) {
|
||||
pr_err("can't register netlink/ioctl.\n");
|
||||
goto cleanup_hooks;
|
||||
}
|
||||
|
||||
pr_info("ipvs loaded.\n");
|
||||
|
||||
return ret;
|
||||
|
||||
cleanup_hooks:
|
||||
nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
|
||||
cleanup_dev:
|
||||
unregister_pernet_device(&ipvs_core_dev_ops);
|
||||
cleanup_sub:
|
||||
|
@ -2012,6 +2022,7 @@ exit:
|
|||
|
||||
static void __exit ip_vs_cleanup(void)
|
||||
{
|
||||
ip_vs_unregister_nl_ioctl();
|
||||
nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
|
||||
unregister_pernet_device(&ipvs_core_dev_ops);
|
||||
unregister_pernet_subsys(&ipvs_core_ops); /* free ip_vs struct */
|
||||
|
|
|
@ -3680,7 +3680,7 @@ int __net_init ip_vs_control_net_init_sysctl(struct net *net)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net)
|
||||
void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net)
|
||||
{
|
||||
struct netns_ipvs *ipvs = net_ipvs(net);
|
||||
|
||||
|
@ -3692,7 +3692,7 @@ void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net)
|
|||
#else
|
||||
|
||||
int __net_init ip_vs_control_net_init_sysctl(struct net *net) { return 0; }
|
||||
void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net) { }
|
||||
void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net) { }
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -3750,21 +3750,10 @@ void __net_exit ip_vs_control_net_cleanup(struct net *net)
|
|||
free_percpu(ipvs->tot_stats.cpustats);
|
||||
}
|
||||
|
||||
int __init ip_vs_control_init(void)
|
||||
int __init ip_vs_register_nl_ioctl(void)
|
||||
{
|
||||
int idx;
|
||||
int ret;
|
||||
|
||||
EnterFunction(2);
|
||||
|
||||
/* Initialize svc_table, ip_vs_svc_fwm_table, rs_table */
|
||||
for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
|
||||
INIT_LIST_HEAD(&ip_vs_svc_table[idx]);
|
||||
INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]);
|
||||
}
|
||||
|
||||
smp_wmb(); /* Do we really need it now ? */
|
||||
|
||||
ret = nf_register_sockopt(&ip_vs_sockopts);
|
||||
if (ret) {
|
||||
pr_err("cannot register sockopt.\n");
|
||||
|
@ -3776,28 +3765,47 @@ int __init ip_vs_control_init(void)
|
|||
pr_err("cannot register Generic Netlink interface.\n");
|
||||
goto err_genl;
|
||||
}
|
||||
|
||||
ret = register_netdevice_notifier(&ip_vs_dst_notifier);
|
||||
if (ret < 0)
|
||||
goto err_notf;
|
||||
|
||||
LeaveFunction(2);
|
||||
return 0;
|
||||
|
||||
err_notf:
|
||||
ip_vs_genl_unregister();
|
||||
err_genl:
|
||||
nf_unregister_sockopt(&ip_vs_sockopts);
|
||||
err_sock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ip_vs_unregister_nl_ioctl(void)
|
||||
{
|
||||
ip_vs_genl_unregister();
|
||||
nf_unregister_sockopt(&ip_vs_sockopts);
|
||||
}
|
||||
|
||||
int __init ip_vs_control_init(void)
|
||||
{
|
||||
int idx;
|
||||
int ret;
|
||||
|
||||
EnterFunction(2);
|
||||
|
||||
/* Initialize svc_table, ip_vs_svc_fwm_table, rs_table */
|
||||
for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
|
||||
INIT_LIST_HEAD(&ip_vs_svc_table[idx]);
|
||||
INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]);
|
||||
}
|
||||
|
||||
smp_wmb(); /* Do we really need it now ? */
|
||||
|
||||
ret = register_netdevice_notifier(&ip_vs_dst_notifier);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
LeaveFunction(2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ip_vs_control_cleanup(void)
|
||||
{
|
||||
EnterFunction(2);
|
||||
unregister_netdevice_notifier(&ip_vs_dst_notifier);
|
||||
ip_vs_genl_unregister();
|
||||
nf_unregister_sockopt(&ip_vs_sockopts);
|
||||
LeaveFunction(2);
|
||||
}
|
||||
|
|
|
@ -439,6 +439,8 @@ static int __net_init __ip_vs_ftp_init(struct net *net)
|
|||
struct ip_vs_app *app;
|
||||
struct netns_ipvs *ipvs = net_ipvs(net);
|
||||
|
||||
if (!ipvs)
|
||||
return -ENOENT;
|
||||
app = kmemdup(&ip_vs_ftp, sizeof(struct ip_vs_app), GFP_KERNEL);
|
||||
if (!app)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -551,6 +551,9 @@ static int __net_init __ip_vs_lblc_init(struct net *net)
|
|||
{
|
||||
struct netns_ipvs *ipvs = net_ipvs(net);
|
||||
|
||||
if (!ipvs)
|
||||
return -ENOENT;
|
||||
|
||||
if (!net_eq(net, &init_net)) {
|
||||
ipvs->lblc_ctl_table = kmemdup(vs_vars_table,
|
||||
sizeof(vs_vars_table),
|
||||
|
|
|
@ -745,6 +745,9 @@ static int __net_init __ip_vs_lblcr_init(struct net *net)
|
|||
{
|
||||
struct netns_ipvs *ipvs = net_ipvs(net);
|
||||
|
||||
if (!ipvs)
|
||||
return -ENOENT;
|
||||
|
||||
if (!net_eq(net, &init_net)) {
|
||||
ipvs->lblcr_ctl_table = kmemdup(vs_vars_table,
|
||||
sizeof(vs_vars_table),
|
||||
|
|
|
@ -59,9 +59,6 @@ static int __used __init register_ip_vs_protocol(struct ip_vs_protocol *pp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IP_VS_PROTO_TCP) || defined(CONFIG_IP_VS_PROTO_UDP) || \
|
||||
defined(CONFIG_IP_VS_PROTO_SCTP) || defined(CONFIG_IP_VS_PROTO_AH) || \
|
||||
defined(CONFIG_IP_VS_PROTO_ESP)
|
||||
/*
|
||||
* register an ipvs protocols netns related data
|
||||
*/
|
||||
|
@ -81,12 +78,18 @@ register_ip_vs_proto_netns(struct net *net, struct ip_vs_protocol *pp)
|
|||
ipvs->proto_data_table[hash] = pd;
|
||||
atomic_set(&pd->appcnt, 0); /* Init app counter */
|
||||
|
||||
if (pp->init_netns != NULL)
|
||||
pp->init_netns(net, pd);
|
||||
if (pp->init_netns != NULL) {
|
||||
int ret = pp->init_netns(net, pd);
|
||||
if (ret) {
|
||||
/* unlink an free proto data */
|
||||
ipvs->proto_data_table[hash] = pd->next;
|
||||
kfree(pd);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* unregister an ipvs protocol
|
||||
|
@ -316,22 +319,35 @@ ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp,
|
|||
*/
|
||||
int __net_init ip_vs_protocol_net_init(struct net *net)
|
||||
{
|
||||
int i, ret;
|
||||
static struct ip_vs_protocol *protos[] = {
|
||||
#ifdef CONFIG_IP_VS_PROTO_TCP
|
||||
register_ip_vs_proto_netns(net, &ip_vs_protocol_tcp);
|
||||
&ip_vs_protocol_tcp,
|
||||
#endif
|
||||
#ifdef CONFIG_IP_VS_PROTO_UDP
|
||||
register_ip_vs_proto_netns(net, &ip_vs_protocol_udp);
|
||||
&ip_vs_protocol_udp,
|
||||
#endif
|
||||
#ifdef CONFIG_IP_VS_PROTO_SCTP
|
||||
register_ip_vs_proto_netns(net, &ip_vs_protocol_sctp);
|
||||
&ip_vs_protocol_sctp,
|
||||
#endif
|
||||
#ifdef CONFIG_IP_VS_PROTO_AH
|
||||
register_ip_vs_proto_netns(net, &ip_vs_protocol_ah);
|
||||
&ip_vs_protocol_ah,
|
||||
#endif
|
||||
#ifdef CONFIG_IP_VS_PROTO_ESP
|
||||
register_ip_vs_proto_netns(net, &ip_vs_protocol_esp);
|
||||
&ip_vs_protocol_esp,
|
||||
#endif
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(protos); i++) {
|
||||
ret = register_ip_vs_proto_netns(net, protos[i]);
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
ip_vs_protocol_net_cleanup(net);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __net_exit ip_vs_protocol_net_cleanup(struct net *net)
|
||||
|
|
|
@ -1090,7 +1090,7 @@ out:
|
|||
* timeouts is netns related now.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
|
||||
static int __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
|
||||
{
|
||||
struct netns_ipvs *ipvs = net_ipvs(net);
|
||||
|
||||
|
@ -1098,6 +1098,9 @@ static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
|
|||
spin_lock_init(&ipvs->sctp_app_lock);
|
||||
pd->timeout_table = ip_vs_create_timeout_table((int *)sctp_timeouts,
|
||||
sizeof(sctp_timeouts));
|
||||
if (!pd->timeout_table)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __ip_vs_sctp_exit(struct net *net, struct ip_vs_proto_data *pd)
|
||||
|
|
|
@ -677,7 +677,7 @@ void ip_vs_tcp_conn_listen(struct net *net, struct ip_vs_conn *cp)
|
|||
* timeouts is netns related now.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
static void __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd)
|
||||
static int __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd)
|
||||
{
|
||||
struct netns_ipvs *ipvs = net_ipvs(net);
|
||||
|
||||
|
@ -685,7 +685,10 @@ static void __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd)
|
|||
spin_lock_init(&ipvs->tcp_app_lock);
|
||||
pd->timeout_table = ip_vs_create_timeout_table((int *)tcp_timeouts,
|
||||
sizeof(tcp_timeouts));
|
||||
if (!pd->timeout_table)
|
||||
return -ENOMEM;
|
||||
pd->tcp_state_table = tcp_states;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __ip_vs_tcp_exit(struct net *net, struct ip_vs_proto_data *pd)
|
||||
|
|
|
@ -467,7 +467,7 @@ udp_state_transition(struct ip_vs_conn *cp, int direction,
|
|||
cp->timeout = pd->timeout_table[IP_VS_UDP_S_NORMAL];
|
||||
}
|
||||
|
||||
static void __udp_init(struct net *net, struct ip_vs_proto_data *pd)
|
||||
static int __udp_init(struct net *net, struct ip_vs_proto_data *pd)
|
||||
{
|
||||
struct netns_ipvs *ipvs = net_ipvs(net);
|
||||
|
||||
|
@ -475,6 +475,9 @@ static void __udp_init(struct net *net, struct ip_vs_proto_data *pd)
|
|||
spin_lock_init(&ipvs->udp_app_lock);
|
||||
pd->timeout_table = ip_vs_create_timeout_table((int *)udp_timeouts,
|
||||
sizeof(udp_timeouts));
|
||||
if (!pd->timeout_table)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __udp_exit(struct net *net, struct ip_vs_proto_data *pd)
|
||||
|
|
|
@ -227,7 +227,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
|
||||
if (info->timeout) {
|
||||
if (info->timeout[0]) {
|
||||
typeof(nf_ct_timeout_find_get_hook) timeout_find_get;
|
||||
struct nf_conn_timeout *timeout_ext;
|
||||
|
||||
|
|
|
@ -408,10 +408,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
|||
if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) {
|
||||
if (!(skb = skb_unshare(skb, GFP_ATOMIC)) ||
|
||||
(skb->ip_summed == CHECKSUM_PARTIAL &&
|
||||
skb_checksum_help(skb))) {
|
||||
sch->qstats.drops++;
|
||||
return NET_XMIT_DROP;
|
||||
}
|
||||
skb_checksum_help(skb)))
|
||||
return qdisc_drop(skb, sch);
|
||||
|
||||
skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче