mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller:
1) Fix hotplug deadlock in hv_netvsc, from Stephen Hemminger.
2) Fix double-free in rmnet driver, from Dan Carpenter.
3) INET connection socket layer can double put request sockets, fix
from Eric Dumazet.
4) Don't match collect metadata-mode tunnels if the device is down,
from Haishuang Yan.
5) Do not perform TSO6/GSO on ipv6 packets with extensions headers in
be2net driver, from Suresh Reddy.
6) Fix scaling error in gen_estimator, from Eric Dumazet.
7) Fix 64-bit statistics deadlock in systemport driver, from Florian
Fainelli.
8) Fix use-after-free in sctp_sock_dump, from Xin Long.
9) Reject invalid BPF_END instructions in verifier, from Edward Cree.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (43 commits)
mlxsw: spectrum_router: Only handle IPv4 and IPv6 events
Documentation: link in networking docs
tcp: fix data delivery rate
bpf/verifier: reject BPF_ALU64|BPF_END
sctp: do not mark sk dumped when inet_sctp_diag_fill returns err
sctp: fix an use-after-free issue in sctp_sock_dump
netvsc: increase default receive buffer size
tcp: update skb->skb_mstamp more carefully
net: ipv4: fix l3slave check for index returned in IP_PKTINFO
net: smsc911x: Quieten netif during suspend
net: systemport: Fix 64-bit stats deadlock
net: vrf: avoid gcc-4.6 warning
qed: remove unnecessary call to memset
tg3: clean up redundant initialization of tnapi
tls: make tls_sw_free_resources static
sctp: potential read out of bounds in sctp_ulpevent_type_enabled()
MAINTAINERS: review Renesas DT bindings as well
net_sched: gen_estimator: fix scaling error in bytes/packets samples
nfp: wait for the NSP resource to appear on boot
nfp: wait for board state before talking to the NSP
...
This commit is contained in:
@@ -45,7 +45,7 @@ in many more places. There's xt_bpf for netfilter, cls_bpf in the kernel
|
||||
qdisc layer, SECCOMP-BPF (SECure COMPuting [1]), and lots of other places
|
||||
such as team driver, PTP code, etc where BPF is being used.
|
||||
|
||||
[1] Documentation/prctl/seccomp_filter.txt
|
||||
[1] Documentation/userspace-api/seccomp_filter.rst
|
||||
|
||||
Original BPF paper:
|
||||
|
||||
|
||||
@@ -11435,6 +11435,8 @@ RENESAS ETHERNET DRIVERS
|
||||
R: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
|
||||
L: netdev@vger.kernel.org
|
||||
L: linux-renesas-soc@vger.kernel.org
|
||||
F: Documentation/devicetree/bindings/net/renesas,*.txt
|
||||
F: Documentation/devicetree/bindings/net/sh_eth.txt
|
||||
F: drivers/net/ethernet/renesas/
|
||||
F: include/linux/sh_eth.h
|
||||
|
||||
|
||||
@@ -4289,7 +4289,7 @@ static int bond_check_params(struct bond_params *params)
|
||||
int bond_mode = BOND_MODE_ROUNDROBIN;
|
||||
int xmit_hashtype = BOND_XMIT_POLICY_LAYER2;
|
||||
int lacp_fast = 0;
|
||||
int tlb_dynamic_lb = 0;
|
||||
int tlb_dynamic_lb;
|
||||
|
||||
/* Convert string parameters. */
|
||||
if (mode) {
|
||||
@@ -4601,16 +4601,13 @@ static int bond_check_params(struct bond_params *params)
|
||||
}
|
||||
ad_user_port_key = valptr->value;
|
||||
|
||||
if ((bond_mode == BOND_MODE_TLB) || (bond_mode == BOND_MODE_ALB)) {
|
||||
bond_opt_initstr(&newval, "default");
|
||||
valptr = bond_opt_parse(bond_opt_get(BOND_OPT_TLB_DYNAMIC_LB),
|
||||
&newval);
|
||||
if (!valptr) {
|
||||
pr_err("Error: No tlb_dynamic_lb default value");
|
||||
return -EINVAL;
|
||||
}
|
||||
tlb_dynamic_lb = valptr->value;
|
||||
bond_opt_initstr(&newval, "default");
|
||||
valptr = bond_opt_parse(bond_opt_get(BOND_OPT_TLB_DYNAMIC_LB), &newval);
|
||||
if (!valptr) {
|
||||
pr_err("Error: No tlb_dynamic_lb default value");
|
||||
return -EINVAL;
|
||||
}
|
||||
tlb_dynamic_lb = valptr->value;
|
||||
|
||||
if (lp_interval == 0) {
|
||||
pr_warn("Warning: ip_interval must be between 1 and %d, so it was reset to %d\n",
|
||||
|
||||
@@ -754,6 +754,9 @@ static int bond_option_mode_set(struct bonding *bond,
|
||||
bond->params.miimon);
|
||||
}
|
||||
|
||||
if (newval->value == BOND_MODE_ALB)
|
||||
bond->params.tlb_dynamic_lb = 1;
|
||||
|
||||
/* don't cache arp_validate between modes */
|
||||
bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
|
||||
bond->params.mode = newval->value;
|
||||
|
||||
@@ -1735,11 +1735,8 @@ static void bcm_sysport_get_stats64(struct net_device *dev,
|
||||
stats->tx_packets += tx_packets;
|
||||
}
|
||||
|
||||
/* lockless update tx_bytes and tx_packets */
|
||||
u64_stats_update_begin(&priv->syncp);
|
||||
stats64->tx_bytes = stats->tx_bytes;
|
||||
stats64->tx_packets = stats->tx_packets;
|
||||
u64_stats_update_end(&priv->syncp);
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_irq(&priv->syncp);
|
||||
|
||||
@@ -11536,11 +11536,11 @@ static int tg3_start(struct tg3 *tp, bool reset_phy, bool test_irq,
|
||||
tg3_napi_enable(tp);
|
||||
|
||||
for (i = 0; i < tp->irq_cnt; i++) {
|
||||
struct tg3_napi *tnapi = &tp->napi[i];
|
||||
err = tg3_request_irq(tp, i);
|
||||
if (err) {
|
||||
for (i--; i >= 0; i--) {
|
||||
tnapi = &tp->napi[i];
|
||||
struct tg3_napi *tnapi = &tp->napi[i];
|
||||
|
||||
free_irq(tnapi->irq_vec, tnapi);
|
||||
}
|
||||
goto out_napi_fini;
|
||||
|
||||
@@ -930,6 +930,14 @@ static inline bool is_ipv4_pkt(struct sk_buff *skb)
|
||||
return skb->protocol == htons(ETH_P_IP) && ip_hdr(skb)->version == 4;
|
||||
}
|
||||
|
||||
static inline bool is_ipv6_ext_hdr(struct sk_buff *skb)
|
||||
{
|
||||
if (ip_hdr(skb)->version == 6)
|
||||
return ipv6_ext_hdr(ipv6_hdr(skb)->nexthdr);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
#define be_error_recovering(adapter) \
|
||||
(adapter->flags & BE_FLAGS_TRY_RECOVERY)
|
||||
|
||||
|
||||
@@ -5089,6 +5089,20 @@ static netdev_features_t be_features_check(struct sk_buff *skb,
|
||||
struct be_adapter *adapter = netdev_priv(dev);
|
||||
u8 l4_hdr = 0;
|
||||
|
||||
if (skb_is_gso(skb)) {
|
||||
/* IPv6 TSO requests with extension hdrs are a problem
|
||||
* to Lancer and BE3 HW. Disable TSO6 feature.
|
||||
*/
|
||||
if (!skyhawk_chip(adapter) && is_ipv6_ext_hdr(skb))
|
||||
features &= ~NETIF_F_TSO6;
|
||||
|
||||
/* Lancer cannot handle the packet with MSS less than 256.
|
||||
* Disable the GSO support in such cases
|
||||
*/
|
||||
if (lancer_chip(adapter) && skb_shinfo(skb)->gso_size < 256)
|
||||
features &= ~NETIF_F_GSO_MASK;
|
||||
}
|
||||
|
||||
/* The code below restricts offload features for some tunneled and
|
||||
* Q-in-Q packets.
|
||||
* Offload features for normal (non tunnel) packets are unchanged.
|
||||
|
||||
@@ -575,15 +575,14 @@ static void mlxsw_sp_span_entry_destroy(struct mlxsw_sp *mlxsw_sp,
|
||||
}
|
||||
|
||||
static struct mlxsw_sp_span_entry *
|
||||
mlxsw_sp_span_entry_find(struct mlxsw_sp_port *port)
|
||||
mlxsw_sp_span_entry_find(struct mlxsw_sp *mlxsw_sp, u8 local_port)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
|
||||
struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
|
||||
|
||||
if (curr->used && curr->local_port == port->local_port)
|
||||
if (curr->used && curr->local_port == local_port)
|
||||
return curr;
|
||||
}
|
||||
return NULL;
|
||||
@@ -594,7 +593,8 @@ static struct mlxsw_sp_span_entry
|
||||
{
|
||||
struct mlxsw_sp_span_entry *span_entry;
|
||||
|
||||
span_entry = mlxsw_sp_span_entry_find(port);
|
||||
span_entry = mlxsw_sp_span_entry_find(port->mlxsw_sp,
|
||||
port->local_port);
|
||||
if (span_entry) {
|
||||
/* Already exists, just take a reference */
|
||||
span_entry->ref_count++;
|
||||
@@ -783,12 +783,13 @@ err_port_bind:
|
||||
}
|
||||
|
||||
static void mlxsw_sp_span_mirror_remove(struct mlxsw_sp_port *from,
|
||||
struct mlxsw_sp_port *to,
|
||||
u8 destination_port,
|
||||
enum mlxsw_sp_span_type type)
|
||||
{
|
||||
struct mlxsw_sp_span_entry *span_entry;
|
||||
|
||||
span_entry = mlxsw_sp_span_entry_find(to);
|
||||
span_entry = mlxsw_sp_span_entry_find(from->mlxsw_sp,
|
||||
destination_port);
|
||||
if (!span_entry) {
|
||||
netdev_err(from->dev, "no span entry found\n");
|
||||
return;
|
||||
@@ -1563,14 +1564,12 @@ static void
|
||||
mlxsw_sp_port_del_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
struct mlxsw_sp_port_mall_mirror_tc_entry *mirror)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
enum mlxsw_sp_span_type span_type;
|
||||
struct mlxsw_sp_port *to_port;
|
||||
|
||||
to_port = mlxsw_sp->ports[mirror->to_local_port];
|
||||
span_type = mirror->ingress ?
|
||||
MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
|
||||
mlxsw_sp_span_mirror_remove(mlxsw_sp_port, to_port, span_type);
|
||||
mlxsw_sp_span_mirror_remove(mlxsw_sp_port, mirror->to_local_port,
|
||||
span_type);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -2545,7 +2544,9 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
#define MLXSW_SP_QSFP_I2C_ADDR 0x50
|
||||
#define MLXSW_SP_I2C_ADDR_LOW 0x50
|
||||
#define MLXSW_SP_I2C_ADDR_HIGH 0x51
|
||||
#define MLXSW_SP_EEPROM_PAGE_LENGTH 256
|
||||
|
||||
static int mlxsw_sp_query_module_eeprom(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
u16 offset, u16 size, void *data,
|
||||
@@ -2554,12 +2555,25 @@ static int mlxsw_sp_query_module_eeprom(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
char eeprom_tmp[MLXSW_SP_REG_MCIA_EEPROM_SIZE];
|
||||
char mcia_pl[MLXSW_REG_MCIA_LEN];
|
||||
u16 i2c_addr;
|
||||
int status;
|
||||
int err;
|
||||
|
||||
size = min_t(u16, size, MLXSW_SP_REG_MCIA_EEPROM_SIZE);
|
||||
|
||||
if (offset < MLXSW_SP_EEPROM_PAGE_LENGTH &&
|
||||
offset + size > MLXSW_SP_EEPROM_PAGE_LENGTH)
|
||||
/* Cross pages read, read until offset 256 in low page */
|
||||
size = MLXSW_SP_EEPROM_PAGE_LENGTH - offset;
|
||||
|
||||
i2c_addr = MLXSW_SP_I2C_ADDR_LOW;
|
||||
if (offset >= MLXSW_SP_EEPROM_PAGE_LENGTH) {
|
||||
i2c_addr = MLXSW_SP_I2C_ADDR_HIGH;
|
||||
offset -= MLXSW_SP_EEPROM_PAGE_LENGTH;
|
||||
}
|
||||
|
||||
mlxsw_reg_mcia_pack(mcia_pl, mlxsw_sp_port->mapping.module,
|
||||
0, 0, offset, size, MLXSW_SP_QSFP_I2C_ADDR);
|
||||
0, 0, offset, size, i2c_addr);
|
||||
|
||||
err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mcia), mcia_pl);
|
||||
if (err)
|
||||
|
||||
@@ -4868,7 +4868,8 @@ static int mlxsw_sp_router_fib_event(struct notifier_block *nb,
|
||||
struct fib_notifier_info *info = ptr;
|
||||
struct mlxsw_sp_router *router;
|
||||
|
||||
if (!net_eq(info->net, &init_net))
|
||||
if (!net_eq(info->net, &init_net) ||
|
||||
(info->family != AF_INET && info->family != AF_INET6))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
fib_work = kzalloc(sizeof(*fib_work), GFP_ATOMIC);
|
||||
|
||||
@@ -44,6 +44,16 @@
|
||||
#include "../nfp_net.h"
|
||||
#include "../nfp_port.h"
|
||||
|
||||
#define NFP_FLOWER_WHITELIST_DISSECTOR \
|
||||
(BIT(FLOW_DISSECTOR_KEY_CONTROL) | \
|
||||
BIT(FLOW_DISSECTOR_KEY_BASIC) | \
|
||||
BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) | \
|
||||
BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) | \
|
||||
BIT(FLOW_DISSECTOR_KEY_PORTS) | \
|
||||
BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) | \
|
||||
BIT(FLOW_DISSECTOR_KEY_VLAN) | \
|
||||
BIT(FLOW_DISSECTOR_KEY_IP))
|
||||
|
||||
static int
|
||||
nfp_flower_xmit_flow(struct net_device *netdev,
|
||||
struct nfp_fl_payload *nfp_flow, u8 mtype)
|
||||
@@ -112,6 +122,9 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
|
||||
u8 key_layer;
|
||||
int key_size;
|
||||
|
||||
if (flow->dissector->used_keys & ~NFP_FLOWER_WHITELIST_DISSECTOR)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (dissector_uses_key(flow->dissector,
|
||||
FLOW_DISSECTOR_KEY_ENC_CONTROL)) {
|
||||
struct flow_dissector_key_control *mask_enc_ctl =
|
||||
|
||||
@@ -74,6 +74,45 @@ static const struct pci_device_id nfp_pci_device_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, nfp_pci_device_ids);
|
||||
|
||||
static bool nfp_board_ready(struct nfp_pf *pf)
|
||||
{
|
||||
const char *cp;
|
||||
long state;
|
||||
int err;
|
||||
|
||||
cp = nfp_hwinfo_lookup(pf->hwinfo, "board.state");
|
||||
if (!cp)
|
||||
return false;
|
||||
|
||||
err = kstrtol(cp, 0, &state);
|
||||
if (err < 0)
|
||||
return false;
|
||||
|
||||
return state == 15;
|
||||
}
|
||||
|
||||
static int nfp_pf_board_state_wait(struct nfp_pf *pf)
|
||||
{
|
||||
const unsigned long wait_until = jiffies + 10 * HZ;
|
||||
|
||||
while (!nfp_board_ready(pf)) {
|
||||
if (time_is_before_eq_jiffies(wait_until)) {
|
||||
nfp_err(pf->cpp, "NFP board initialization timeout\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nfp_info(pf->cpp, "waiting for board initialization\n");
|
||||
if (msleep_interruptible(500))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
/* Refresh cached information */
|
||||
kfree(pf->hwinfo);
|
||||
pf->hwinfo = nfp_hwinfo_read(pf->cpp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nfp_pcie_sriov_read_nfd_limit(struct nfp_pf *pf)
|
||||
{
|
||||
int err;
|
||||
@@ -312,6 +351,10 @@ static int nfp_nsp_init(struct pci_dev *pdev, struct nfp_pf *pf)
|
||||
struct nfp_nsp *nsp;
|
||||
int err;
|
||||
|
||||
err = nfp_resource_wait(pf->cpp, NFP_RESOURCE_NSP, 30);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
nsp = nfp_nsp_open(pf->cpp);
|
||||
if (IS_ERR(nsp)) {
|
||||
err = PTR_ERR(nsp);
|
||||
@@ -425,6 +468,10 @@ static int nfp_pci_probe(struct pci_dev *pdev,
|
||||
nfp_hwinfo_lookup(pf->hwinfo, "assembly.revision"),
|
||||
nfp_hwinfo_lookup(pf->hwinfo, "cpld.version"));
|
||||
|
||||
err = nfp_pf_board_state_wait(pf);
|
||||
if (err)
|
||||
goto err_hwinfo_free;
|
||||
|
||||
err = devlink_register(devlink, &pdev->dev);
|
||||
if (err)
|
||||
goto err_hwinfo_free;
|
||||
|
||||
@@ -64,23 +64,6 @@
|
||||
|
||||
#define NFP_PF_CSR_SLICE_SIZE (32 * 1024)
|
||||
|
||||
static int nfp_is_ready(struct nfp_pf *pf)
|
||||
{
|
||||
const char *cp;
|
||||
long state;
|
||||
int err;
|
||||
|
||||
cp = nfp_hwinfo_lookup(pf->hwinfo, "board.state");
|
||||
if (!cp)
|
||||
return 0;
|
||||
|
||||
err = kstrtol(cp, 0, &state);
|
||||
if (err < 0)
|
||||
return 0;
|
||||
|
||||
return state == 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfp_net_get_mac_addr() - Get the MAC address.
|
||||
* @pf: NFP PF handle
|
||||
@@ -725,12 +708,6 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
|
||||
|
||||
INIT_WORK(&pf->port_refresh_work, nfp_net_refresh_vnics);
|
||||
|
||||
/* Verify that the board has completed initialization */
|
||||
if (!nfp_is_ready(pf)) {
|
||||
nfp_err(pf->cpp, "NFP is not ready for NIC operation.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!pf->rtbl) {
|
||||
nfp_err(pf->cpp, "No %s, giving up.\n",
|
||||
pf->fw_loaded ? "symbol table" : "firmware found");
|
||||
|
||||
@@ -97,6 +97,8 @@ nfp_resource_acquire(struct nfp_cpp *cpp, const char *name);
|
||||
|
||||
void nfp_resource_release(struct nfp_resource *res);
|
||||
|
||||
int nfp_resource_wait(struct nfp_cpp *cpp, const char *name, unsigned int secs);
|
||||
|
||||
u32 nfp_resource_cpp_id(struct nfp_resource *res);
|
||||
|
||||
const char *nfp_resource_name(struct nfp_resource *res);
|
||||
|
||||
@@ -249,6 +249,51 @@ void nfp_resource_release(struct nfp_resource *res)
|
||||
kfree(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* nfp_resource_wait() - Wait for resource to appear
|
||||
* @cpp: NFP CPP handle
|
||||
* @name: Name of the resource
|
||||
* @secs: Number of seconds to wait
|
||||
*
|
||||
* Wait for resource to appear in the resource table, grab and release
|
||||
* its lock. The wait is jiffies-based, don't expect fine granularity.
|
||||
*
|
||||
* Return: 0 on success, errno otherwise.
|
||||
*/
|
||||
int nfp_resource_wait(struct nfp_cpp *cpp, const char *name, unsigned int secs)
|
||||
{
|
||||
unsigned long warn_at = jiffies + NFP_MUTEX_WAIT_FIRST_WARN * HZ;
|
||||
unsigned long err_at = jiffies + secs * HZ;
|
||||
struct nfp_resource *res;
|
||||
|
||||
while (true) {
|
||||
res = nfp_resource_acquire(cpp, name);
|
||||
if (!IS_ERR(res)) {
|
||||
nfp_resource_release(res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (PTR_ERR(res) != -ENOENT) {
|
||||
nfp_err(cpp, "error waiting for resource %s: %ld\n",
|
||||
name, PTR_ERR(res));
|
||||
return PTR_ERR(res);
|
||||
}
|
||||
if (time_is_before_eq_jiffies(err_at)) {
|
||||
nfp_err(cpp, "timeout waiting for resource %s\n", name);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
if (time_is_before_eq_jiffies(warn_at)) {
|
||||
warn_at = jiffies + NFP_MUTEX_WAIT_NEXT_WARN * HZ;
|
||||
nfp_info(cpp, "waiting for NFP resource %s\n", name);
|
||||
}
|
||||
if (msleep_interruptible(10)) {
|
||||
nfp_err(cpp, "wait for resource %s interrupted\n",
|
||||
name);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nfp_resource_cpp_id() - Return the cpp_id of a resource handle
|
||||
* @res: NFP Resource handle
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
||||
@@ -1244,7 +1244,6 @@ int qed_dcbx_get_config_params(struct qed_hwfn *p_hwfn,
|
||||
if (!dcbx_info)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(dcbx_info, 0, sizeof(*dcbx_info));
|
||||
rc = qed_dcbx_query_params(p_hwfn, dcbx_info, QED_DCBX_OPERATIONAL_MIB);
|
||||
if (rc) {
|
||||
kfree(dcbx_info);
|
||||
|
||||
@@ -84,6 +84,10 @@ struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb)
|
||||
if (((int)skb->len - (int)packet_len) < 0)
|
||||
return NULL;
|
||||
|
||||
/* Some hardware can send us empty frames. Catch them */
|
||||
if (ntohs(maph->pkt_len) == 0)
|
||||
return NULL;
|
||||
|
||||
skbn = alloc_skb(packet_len + RMNET_MAP_DEAGGR_SPACING, GFP_ATOMIC);
|
||||
if (!skbn)
|
||||
return NULL;
|
||||
@@ -94,11 +98,5 @@ struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb)
|
||||
memcpy(skbn->data, skb->data, packet_len);
|
||||
skb_pull(skb, packet_len);
|
||||
|
||||
/* Some hardware can send us empty frames. Catch them */
|
||||
if (ntohs(maph->pkt_len) == 0) {
|
||||
kfree_skb(skb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return skbn;
|
||||
}
|
||||
|
||||
@@ -2595,6 +2595,11 @@ static int smsc911x_suspend(struct device *dev)
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
struct smsc911x_data *pdata = netdev_priv(ndev);
|
||||
|
||||
if (netif_running(ndev)) {
|
||||
netif_stop_queue(ndev);
|
||||
netif_device_detach(ndev);
|
||||
}
|
||||
|
||||
/* enable wake on LAN, energy detection and the external PME
|
||||
* signal. */
|
||||
smsc911x_reg_write(pdata, PMT_CTRL,
|
||||
@@ -2628,7 +2633,15 @@ static int smsc911x_resume(struct device *dev)
|
||||
while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to)
|
||||
udelay(1000);
|
||||
|
||||
return (to == 0) ? -EIO : 0;
|
||||
if (to == 0)
|
||||
return -EIO;
|
||||
|
||||
if (netif_running(ndev)) {
|
||||
netif_device_attach(ndev);
|
||||
netif_start_queue(ndev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops smsc911x_pm_ops = {
|
||||
|
||||
@@ -204,6 +204,8 @@ int netvsc_recv_callback(struct net_device *net,
|
||||
const struct ndis_pkt_8021q_info *vlan);
|
||||
void netvsc_channel_cb(void *context);
|
||||
int netvsc_poll(struct napi_struct *napi, int budget);
|
||||
|
||||
void rndis_set_subchannel(struct work_struct *w);
|
||||
bool rndis_filter_opened(const struct netvsc_device *nvdev);
|
||||
int rndis_filter_open(struct netvsc_device *nvdev);
|
||||
int rndis_filter_close(struct netvsc_device *nvdev);
|
||||
@@ -782,6 +784,7 @@ struct netvsc_device {
|
||||
u32 num_chn;
|
||||
|
||||
atomic_t open_chn;
|
||||
struct work_struct subchan_work;
|
||||
wait_queue_head_t subchan_open;
|
||||
|
||||
struct rndis_device *extension;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user