Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: can: add sanity checks fs_enet: restore promiscuous and multicast settings in restart() ibm_newemac: Fixes entry of short packets ibm_newemac: Fixes kernel crashes when speed of cable connected changes pasemi_mac: Access iph->tot_len with correct endianness ehea: Access iph->tot_len with correct endianness ehea: fix race condition ehea: add MODULE_DEVICE_TABLE ehea: fix might sleep problem forcedeth: fix lockdep warning on ethtool -s Add missing skb->dev assignment in Frame Relay RX code bridge: fix use-after-free in br_cleanup_bridges() tcp: fix a size_t < 0 comparison in tcp_read_sock tcp: net/ipv4/tcp.c needs linux/scatterlist.h libertas: support USB persistence on suspend/resume (resend) iwlwifi: drop skb silently for Tx request in monitor mode iwlwifi: fix incorrect 5GHz rates reported in monitor mode
This commit is contained in:
commit
b2798bf0ec
@ -40,7 +40,7 @@
|
|||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
#define DRV_NAME "ehea"
|
#define DRV_NAME "ehea"
|
||||||
#define DRV_VERSION "EHEA_0091"
|
#define DRV_VERSION "EHEA_0092"
|
||||||
|
|
||||||
/* eHEA capability flags */
|
/* eHEA capability flags */
|
||||||
#define DLPAR_PORT_ADD_REM 1
|
#define DLPAR_PORT_ADD_REM 1
|
||||||
@ -452,7 +452,7 @@ struct ehea_bcmc_reg_entry {
|
|||||||
struct ehea_bcmc_reg_array {
|
struct ehea_bcmc_reg_array {
|
||||||
struct ehea_bcmc_reg_entry *arr;
|
struct ehea_bcmc_reg_entry *arr;
|
||||||
int num_entries;
|
int num_entries;
|
||||||
struct mutex lock;
|
spinlock_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define EHEA_PORT_UP 1
|
#define EHEA_PORT_UP 1
|
||||||
@ -478,6 +478,7 @@ struct ehea_port {
|
|||||||
int num_add_tx_qps;
|
int num_add_tx_qps;
|
||||||
int num_mcs;
|
int num_mcs;
|
||||||
int resets;
|
int resets;
|
||||||
|
u64 flags;
|
||||||
u64 mac_addr;
|
u64 mac_addr;
|
||||||
u32 logical_port_id;
|
u32 logical_port_id;
|
||||||
u32 port_speed;
|
u32 port_speed;
|
||||||
@ -501,7 +502,8 @@ struct port_res_cfg {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum ehea_flag_bits {
|
enum ehea_flag_bits {
|
||||||
__EHEA_STOP_XFER
|
__EHEA_STOP_XFER,
|
||||||
|
__EHEA_DISABLE_PORT_RESET
|
||||||
};
|
};
|
||||||
|
|
||||||
void ehea_set_ethtool_ops(struct net_device *netdev);
|
void ehea_set_ethtool_ops(struct net_device *netdev);
|
||||||
|
@ -118,6 +118,7 @@ static struct of_device_id ehea_device_table[] = {
|
|||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, ehea_device_table);
|
||||||
|
|
||||||
static struct of_platform_driver ehea_driver = {
|
static struct of_platform_driver ehea_driver = {
|
||||||
.name = "ehea",
|
.name = "ehea",
|
||||||
@ -137,6 +138,12 @@ void ehea_dump(void *adr, int len, char *msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ehea_schedule_port_reset(struct ehea_port *port)
|
||||||
|
{
|
||||||
|
if (!test_bit(__EHEA_DISABLE_PORT_RESET, &port->flags))
|
||||||
|
schedule_work(&port->reset_task);
|
||||||
|
}
|
||||||
|
|
||||||
static void ehea_update_firmware_handles(void)
|
static void ehea_update_firmware_handles(void)
|
||||||
{
|
{
|
||||||
struct ehea_fw_handle_entry *arr = NULL;
|
struct ehea_fw_handle_entry *arr = NULL;
|
||||||
@ -241,7 +248,7 @@ static void ehea_update_bcmc_registrations(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (num_registrations) {
|
if (num_registrations) {
|
||||||
arr = kzalloc(num_registrations * sizeof(*arr), GFP_KERNEL);
|
arr = kzalloc(num_registrations * sizeof(*arr), GFP_ATOMIC);
|
||||||
if (!arr)
|
if (!arr)
|
||||||
return; /* Keep the existing array */
|
return; /* Keep the existing array */
|
||||||
} else
|
} else
|
||||||
@ -301,7 +308,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev)
|
|||||||
|
|
||||||
memset(stats, 0, sizeof(*stats));
|
memset(stats, 0, sizeof(*stats));
|
||||||
|
|
||||||
cb2 = kzalloc(PAGE_SIZE, GFP_KERNEL);
|
cb2 = kzalloc(PAGE_SIZE, GFP_ATOMIC);
|
||||||
if (!cb2) {
|
if (!cb2) {
|
||||||
ehea_error("no mem for cb2");
|
ehea_error("no mem for cb2");
|
||||||
goto out;
|
goto out;
|
||||||
@ -587,7 +594,7 @@ static int ehea_treat_poll_error(struct ehea_port_res *pr, int rq,
|
|||||||
"Resetting port.", pr->qp->init_attr.qp_nr);
|
"Resetting port.", pr->qp->init_attr.qp_nr);
|
||||||
ehea_dump(cqe, sizeof(*cqe), "CQE");
|
ehea_dump(cqe, sizeof(*cqe), "CQE");
|
||||||
}
|
}
|
||||||
schedule_work(&pr->port->reset_task);
|
ehea_schedule_port_reset(pr->port);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -616,7 +623,7 @@ static int get_skb_hdr(struct sk_buff *skb, void **iphdr,
|
|||||||
*tcph = tcp_hdr(skb);
|
*tcph = tcp_hdr(skb);
|
||||||
|
|
||||||
/* check if ip header and tcp header are complete */
|
/* check if ip header and tcp header are complete */
|
||||||
if (iph->tot_len < ip_len + tcp_hdrlen(skb))
|
if (ntohs(iph->tot_len) < ip_len + tcp_hdrlen(skb))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
*hdr_flags = LRO_IPV4 | LRO_TCP;
|
*hdr_flags = LRO_IPV4 | LRO_TCP;
|
||||||
@ -765,7 +772,7 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota)
|
|||||||
ehea_error("Send Completion Error: Resetting port");
|
ehea_error("Send Completion Error: Resetting port");
|
||||||
if (netif_msg_tx_err(pr->port))
|
if (netif_msg_tx_err(pr->port))
|
||||||
ehea_dump(cqe, sizeof(*cqe), "Send CQE");
|
ehea_dump(cqe, sizeof(*cqe), "Send CQE");
|
||||||
schedule_work(&pr->port->reset_task);
|
ehea_schedule_port_reset(pr->port);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -885,7 +892,7 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param)
|
|||||||
eqe = ehea_poll_eq(port->qp_eq);
|
eqe = ehea_poll_eq(port->qp_eq);
|
||||||
}
|
}
|
||||||
|
|
||||||
schedule_work(&port->reset_task);
|
ehea_schedule_port_reset(port);
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
@ -1763,7 +1770,7 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
|
|||||||
|
|
||||||
memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);
|
memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);
|
||||||
|
|
||||||
mutex_lock(&ehea_bcmc_regs.lock);
|
spin_lock(&ehea_bcmc_regs.lock);
|
||||||
|
|
||||||
/* Deregister old MAC in pHYP */
|
/* Deregister old MAC in pHYP */
|
||||||
if (port->state == EHEA_PORT_UP) {
|
if (port->state == EHEA_PORT_UP) {
|
||||||
@ -1785,7 +1792,7 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
|
|||||||
|
|
||||||
out_upregs:
|
out_upregs:
|
||||||
ehea_update_bcmc_registrations();
|
ehea_update_bcmc_registrations();
|
||||||
mutex_unlock(&ehea_bcmc_regs.lock);
|
spin_unlock(&ehea_bcmc_regs.lock);
|
||||||
out_free:
|
out_free:
|
||||||
kfree(cb0);
|
kfree(cb0);
|
||||||
out:
|
out:
|
||||||
@ -1947,7 +1954,7 @@ static void ehea_set_multicast_list(struct net_device *dev)
|
|||||||
}
|
}
|
||||||
ehea_promiscuous(dev, 0);
|
ehea_promiscuous(dev, 0);
|
||||||
|
|
||||||
mutex_lock(&ehea_bcmc_regs.lock);
|
spin_lock(&ehea_bcmc_regs.lock);
|
||||||
|
|
||||||
if (dev->flags & IFF_ALLMULTI) {
|
if (dev->flags & IFF_ALLMULTI) {
|
||||||
ehea_allmulti(dev, 1);
|
ehea_allmulti(dev, 1);
|
||||||
@ -1978,7 +1985,7 @@ static void ehea_set_multicast_list(struct net_device *dev)
|
|||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
ehea_update_bcmc_registrations();
|
ehea_update_bcmc_registrations();
|
||||||
mutex_unlock(&ehea_bcmc_regs.lock);
|
spin_unlock(&ehea_bcmc_regs.lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2497,7 +2504,7 @@ static int ehea_up(struct net_device *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&ehea_bcmc_regs.lock);
|
spin_lock(&ehea_bcmc_regs.lock);
|
||||||
|
|
||||||
ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
|
ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -2520,7 +2527,7 @@ out:
|
|||||||
ehea_info("Failed starting %s. ret=%i", dev->name, ret);
|
ehea_info("Failed starting %s. ret=%i", dev->name, ret);
|
||||||
|
|
||||||
ehea_update_bcmc_registrations();
|
ehea_update_bcmc_registrations();
|
||||||
mutex_unlock(&ehea_bcmc_regs.lock);
|
spin_unlock(&ehea_bcmc_regs.lock);
|
||||||
|
|
||||||
ehea_update_firmware_handles();
|
ehea_update_firmware_handles();
|
||||||
mutex_unlock(&ehea_fw_handles.lock);
|
mutex_unlock(&ehea_fw_handles.lock);
|
||||||
@ -2575,7 +2582,7 @@ static int ehea_down(struct net_device *dev)
|
|||||||
|
|
||||||
mutex_lock(&ehea_fw_handles.lock);
|
mutex_lock(&ehea_fw_handles.lock);
|
||||||
|
|
||||||
mutex_lock(&ehea_bcmc_regs.lock);
|
spin_lock(&ehea_bcmc_regs.lock);
|
||||||
ehea_drop_multicast_list(dev);
|
ehea_drop_multicast_list(dev);
|
||||||
ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
|
ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
|
||||||
|
|
||||||
@ -2584,7 +2591,7 @@ static int ehea_down(struct net_device *dev)
|
|||||||
port->state = EHEA_PORT_DOWN;
|
port->state = EHEA_PORT_DOWN;
|
||||||
|
|
||||||
ehea_update_bcmc_registrations();
|
ehea_update_bcmc_registrations();
|
||||||
mutex_unlock(&ehea_bcmc_regs.lock);
|
spin_unlock(&ehea_bcmc_regs.lock);
|
||||||
|
|
||||||
ret = ehea_clean_all_portres(port);
|
ret = ehea_clean_all_portres(port);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -2605,13 +2612,14 @@ static int ehea_stop(struct net_device *dev)
|
|||||||
if (netif_msg_ifdown(port))
|
if (netif_msg_ifdown(port))
|
||||||
ehea_info("disabling port %s", dev->name);
|
ehea_info("disabling port %s", dev->name);
|
||||||
|
|
||||||
|
set_bit(__EHEA_DISABLE_PORT_RESET, &port->flags);
|
||||||
cancel_work_sync(&port->reset_task);
|
cancel_work_sync(&port->reset_task);
|
||||||
|
|
||||||
mutex_lock(&port->port_lock);
|
mutex_lock(&port->port_lock);
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
port_napi_disable(port);
|
port_napi_disable(port);
|
||||||
ret = ehea_down(dev);
|
ret = ehea_down(dev);
|
||||||
mutex_unlock(&port->port_lock);
|
mutex_unlock(&port->port_lock);
|
||||||
|
clear_bit(__EHEA_DISABLE_PORT_RESET, &port->flags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2941,7 +2949,7 @@ static void ehea_tx_watchdog(struct net_device *dev)
|
|||||||
|
|
||||||
if (netif_carrier_ok(dev) &&
|
if (netif_carrier_ok(dev) &&
|
||||||
!test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))
|
!test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))
|
||||||
schedule_work(&port->reset_task);
|
ehea_schedule_port_reset(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ehea_sense_adapter_attr(struct ehea_adapter *adapter)
|
int ehea_sense_adapter_attr(struct ehea_adapter *adapter)
|
||||||
@ -3590,7 +3598,7 @@ int __init ehea_module_init(void)
|
|||||||
memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs));
|
memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs));
|
||||||
|
|
||||||
mutex_init(&ehea_fw_handles.lock);
|
mutex_init(&ehea_fw_handles.lock);
|
||||||
mutex_init(&ehea_bcmc_regs.lock);
|
spin_lock_init(&ehea_bcmc_regs.lock);
|
||||||
|
|
||||||
ret = check_module_parm();
|
ret = check_module_parm();
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -4194,12 +4194,23 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
|
|||||||
|
|
||||||
netif_carrier_off(dev);
|
netif_carrier_off(dev);
|
||||||
if (netif_running(dev)) {
|
if (netif_running(dev)) {
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
nv_disable_irq(dev);
|
nv_disable_irq(dev);
|
||||||
netif_tx_lock_bh(dev);
|
netif_tx_lock_bh(dev);
|
||||||
spin_lock(&np->lock);
|
/* with plain spinlock lockdep complains */
|
||||||
|
spin_lock_irqsave(&np->lock, flags);
|
||||||
/* stop engines */
|
/* stop engines */
|
||||||
|
/* FIXME:
|
||||||
|
* this can take some time, and interrupts are disabled
|
||||||
|
* due to spin_lock_irqsave, but let's hope no daemon
|
||||||
|
* is going to change the settings very often...
|
||||||
|
* Worst case:
|
||||||
|
* NV_RXSTOP_DELAY1MAX + NV_TXSTOP_DELAY1MAX
|
||||||
|
* + some minor delays, which is up to a second approximately
|
||||||
|
*/
|
||||||
nv_stop_rxtx(dev);
|
nv_stop_rxtx(dev);
|
||||||
spin_unlock(&np->lock);
|
spin_unlock_irqrestore(&np->lock, flags);
|
||||||
netif_tx_unlock_bh(dev);
|
netif_tx_unlock_bh(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,6 +463,9 @@ static void restart(struct net_device *dev)
|
|||||||
else
|
else
|
||||||
C32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB);
|
C32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB);
|
||||||
|
|
||||||
|
/* Restore multicast and promiscuous settings */
|
||||||
|
set_multicast_list(dev);
|
||||||
|
|
||||||
S32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT);
|
S32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1636,6 +1636,12 @@ static int emac_poll_rx(void *param, int budget)
|
|||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (len < ETH_HLEN) {
|
||||||
|
++dev->estats.rx_dropped_stack;
|
||||||
|
emac_recycle_rx_skb(dev, slot, len);
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
|
||||||
if (len && len < EMAC_RX_COPY_THRESH) {
|
if (len && len < EMAC_RX_COPY_THRESH) {
|
||||||
struct sk_buff *copy_skb =
|
struct sk_buff *copy_skb =
|
||||||
alloc_skb(len + EMAC_RX_SKB_HEADROOM + 2, GFP_ATOMIC);
|
alloc_skb(len + EMAC_RX_SKB_HEADROOM + 2, GFP_ATOMIC);
|
||||||
@ -2719,6 +2725,8 @@ static int __devinit emac_probe(struct of_device *ofdev,
|
|||||||
/* Clean rings */
|
/* Clean rings */
|
||||||
memset(dev->tx_desc, 0, NUM_TX_BUFF * sizeof(struct mal_descriptor));
|
memset(dev->tx_desc, 0, NUM_TX_BUFF * sizeof(struct mal_descriptor));
|
||||||
memset(dev->rx_desc, 0, NUM_RX_BUFF * sizeof(struct mal_descriptor));
|
memset(dev->rx_desc, 0, NUM_RX_BUFF * sizeof(struct mal_descriptor));
|
||||||
|
memset(dev->tx_skb, 0, NUM_TX_BUFF * sizeof(struct sk_buff *));
|
||||||
|
memset(dev->rx_skb, 0, NUM_RX_BUFF * sizeof(struct sk_buff *));
|
||||||
|
|
||||||
/* Attach to ZMII, if needed */
|
/* Attach to ZMII, if needed */
|
||||||
if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII) &&
|
if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII) &&
|
||||||
|
@ -277,7 +277,7 @@ static int get_skb_hdr(struct sk_buff *skb, void **iphdr,
|
|||||||
*tcph = tcp_hdr(skb);
|
*tcph = tcp_hdr(skb);
|
||||||
|
|
||||||
/* check if ip header and tcp header are complete */
|
/* check if ip header and tcp header are complete */
|
||||||
if (iph->tot_len < ip_len + tcp_hdrlen(skb))
|
if (ntohs(iph->tot_len) < ip_len + tcp_hdrlen(skb))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
*hdr_flags = LRO_IPV4 | LRO_TCP;
|
*hdr_flags = LRO_IPV4 | LRO_TCP;
|
||||||
|
@ -1008,6 +1008,7 @@ static int fr_rx(struct sk_buff *skb)
|
|||||||
stats->rx_bytes += skb->len;
|
stats->rx_bytes += skb->len;
|
||||||
if (pvc->state.becn)
|
if (pvc->state.becn)
|
||||||
stats->rx_compressed++;
|
stats->rx_compressed++;
|
||||||
|
skb->dev = dev;
|
||||||
netif_rx(skb);
|
netif_rx(skb);
|
||||||
return NET_RX_SUCCESS;
|
return NET_RX_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
|
@ -588,8 +588,12 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv,
|
|||||||
|
|
||||||
if (rate == -1)
|
if (rate == -1)
|
||||||
iwl3945_rt->rt_rate = 0;
|
iwl3945_rt->rt_rate = 0;
|
||||||
else
|
else {
|
||||||
|
if (stats->band == IEEE80211_BAND_5GHZ)
|
||||||
|
rate += IWL_FIRST_OFDM_RATE;
|
||||||
|
|
||||||
iwl3945_rt->rt_rate = iwl3945_rates[rate].ieee;
|
iwl3945_rt->rt_rate = iwl3945_rates[rate].ieee;
|
||||||
|
}
|
||||||
|
|
||||||
/* antenna number */
|
/* antenna number */
|
||||||
antenna = phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK;
|
antenna = phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK;
|
||||||
|
@ -3528,8 +3528,12 @@ static void iwl4965_add_radiotap(struct iwl_priv *priv,
|
|||||||
|
|
||||||
if (rate == -1)
|
if (rate == -1)
|
||||||
iwl4965_rt->rt_rate = 0;
|
iwl4965_rt->rt_rate = 0;
|
||||||
else
|
else {
|
||||||
|
if (stats->band == IEEE80211_BAND_5GHZ)
|
||||||
|
rate += IWL_FIRST_OFDM_RATE;
|
||||||
|
|
||||||
iwl4965_rt->rt_rate = iwl4965_rates[rate].ieee;
|
iwl4965_rt->rt_rate = iwl4965_rates[rate].ieee;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "antenna number"
|
* "antenna number"
|
||||||
|
@ -6687,7 +6687,8 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
|
|||||||
|
|
||||||
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
|
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
|
||||||
IWL_DEBUG_MAC80211("leave - monitor\n");
|
IWL_DEBUG_MAC80211("leave - monitor\n");
|
||||||
return -1;
|
dev_kfree_skb_any(skb);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
|
IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
|
||||||
|
@ -6237,7 +6237,8 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
|
|||||||
|
|
||||||
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
|
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
|
||||||
IWL_DEBUG_MAC80211("leave - monitor\n");
|
IWL_DEBUG_MAC80211("leave - monitor\n");
|
||||||
return -1;
|
dev_kfree_skb_any(skb);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
|
IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
|
||||||
|
@ -925,6 +925,7 @@ static struct usb_driver if_usb_driver = {
|
|||||||
.id_table = if_usb_table,
|
.id_table = if_usb_table,
|
||||||
.suspend = if_usb_suspend,
|
.suspend = if_usb_suspend,
|
||||||
.resume = if_usb_resume,
|
.resume = if_usb_resume,
|
||||||
|
.reset_resume = if_usb_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init if_usb_init_module(void)
|
static int __init if_usb_init_module(void)
|
||||||
|
@ -442,12 +442,16 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
|
|||||||
|
|
||||||
void __exit br_cleanup_bridges(void)
|
void __exit br_cleanup_bridges(void)
|
||||||
{
|
{
|
||||||
struct net_device *dev, *nxt;
|
struct net_device *dev;
|
||||||
|
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
for_each_netdev_safe(&init_net, dev, nxt)
|
restart:
|
||||||
if (dev->priv_flags & IFF_EBRIDGE)
|
for_each_netdev(&init_net, dev) {
|
||||||
|
if (dev->priv_flags & IFF_EBRIDGE) {
|
||||||
del_br(dev->priv);
|
del_br(dev->priv);
|
||||||
|
goto restart;
|
||||||
|
}
|
||||||
|
}
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -205,12 +205,19 @@ static int can_create(struct net *net, struct socket *sock, int protocol)
|
|||||||
* -ENOBUFS on full driver queue (see net_xmit_errno())
|
* -ENOBUFS on full driver queue (see net_xmit_errno())
|
||||||
* -ENOMEM when local loopback failed at calling skb_clone()
|
* -ENOMEM when local loopback failed at calling skb_clone()
|
||||||
* -EPERM when trying to send on a non-CAN interface
|
* -EPERM when trying to send on a non-CAN interface
|
||||||
|
* -EINVAL when the skb->data does not contain a valid CAN frame
|
||||||
*/
|
*/
|
||||||
int can_send(struct sk_buff *skb, int loop)
|
int can_send(struct sk_buff *skb, int loop)
|
||||||
{
|
{
|
||||||
struct sk_buff *newskb = NULL;
|
struct sk_buff *newskb = NULL;
|
||||||
|
struct can_frame *cf = (struct can_frame *)skb->data;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (skb->len != sizeof(struct can_frame) || cf->can_dlc > 8) {
|
||||||
|
kfree_skb(skb);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (skb->dev->type != ARPHRD_CAN) {
|
if (skb->dev->type != ARPHRD_CAN) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
@ -605,6 +612,7 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
|
|||||||
struct packet_type *pt, struct net_device *orig_dev)
|
struct packet_type *pt, struct net_device *orig_dev)
|
||||||
{
|
{
|
||||||
struct dev_rcv_lists *d;
|
struct dev_rcv_lists *d;
|
||||||
|
struct can_frame *cf = (struct can_frame *)skb->data;
|
||||||
int matches;
|
int matches;
|
||||||
|
|
||||||
if (dev->type != ARPHRD_CAN || dev_net(dev) != &init_net) {
|
if (dev->type != ARPHRD_CAN || dev_net(dev) != &init_net) {
|
||||||
@ -612,6 +620,8 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BUG_ON(skb->len != sizeof(struct can_frame) || cf->can_dlc > 8);
|
||||||
|
|
||||||
/* update statistics */
|
/* update statistics */
|
||||||
can_stats.rx_frames++;
|
can_stats.rx_frames++;
|
||||||
can_stats.rx_frames_delta++;
|
can_stats.rx_frames_delta++;
|
||||||
|
@ -298,7 +298,7 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head,
|
|||||||
|
|
||||||
if (head->nframes) {
|
if (head->nframes) {
|
||||||
/* can_frames starting here */
|
/* can_frames starting here */
|
||||||
firstframe = (struct can_frame *) skb_tail_pointer(skb);
|
firstframe = (struct can_frame *)skb_tail_pointer(skb);
|
||||||
|
|
||||||
memcpy(skb_put(skb, datalen), frames, datalen);
|
memcpy(skb_put(skb, datalen), frames, datalen);
|
||||||
|
|
||||||
@ -826,6 +826,10 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
|
|||||||
for (i = 0; i < msg_head->nframes; i++) {
|
for (i = 0; i < msg_head->nframes; i++) {
|
||||||
err = memcpy_fromiovec((u8 *)&op->frames[i],
|
err = memcpy_fromiovec((u8 *)&op->frames[i],
|
||||||
msg->msg_iov, CFSIZ);
|
msg->msg_iov, CFSIZ);
|
||||||
|
|
||||||
|
if (op->frames[i].can_dlc > 8)
|
||||||
|
err = -EINVAL;
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -858,6 +862,10 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
|
|||||||
for (i = 0; i < msg_head->nframes; i++) {
|
for (i = 0; i < msg_head->nframes; i++) {
|
||||||
err = memcpy_fromiovec((u8 *)&op->frames[i],
|
err = memcpy_fromiovec((u8 *)&op->frames[i],
|
||||||
msg->msg_iov, CFSIZ);
|
msg->msg_iov, CFSIZ);
|
||||||
|
|
||||||
|
if (op->frames[i].can_dlc > 8)
|
||||||
|
err = -EINVAL;
|
||||||
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
if (op->frames != &op->sframe)
|
if (op->frames != &op->sframe)
|
||||||
kfree(op->frames);
|
kfree(op->frames);
|
||||||
@ -1164,9 +1172,12 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk)
|
|||||||
|
|
||||||
skb->dev = dev;
|
skb->dev = dev;
|
||||||
skb->sk = sk;
|
skb->sk = sk;
|
||||||
can_send(skb, 1); /* send with loopback */
|
err = can_send(skb, 1); /* send with loopback */
|
||||||
dev_put(dev);
|
dev_put(dev);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
return CFSIZ + MHSIZ;
|
return CFSIZ + MHSIZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1185,6 +1196,10 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
|
|||||||
if (!bo->bound)
|
if (!bo->bound)
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
|
|
||||||
|
/* check for valid message length from userspace */
|
||||||
|
if (size < MHSIZ || (size - MHSIZ) % CFSIZ)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* check for alternative ifindex for this bcm_op */
|
/* check for alternative ifindex for this bcm_op */
|
||||||
|
|
||||||
if (!ifindex && msg->msg_name) {
|
if (!ifindex && msg->msg_name) {
|
||||||
@ -1259,8 +1274,8 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TX_SEND:
|
case TX_SEND:
|
||||||
/* we need at least one can_frame */
|
/* we need exactly one can_frame behind the msg head */
|
||||||
if (msg_head.nframes < 1)
|
if ((msg_head.nframes != 1) || (size != CFSIZ + MHSIZ))
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
else
|
else
|
||||||
ret = bcm_tx_send(msg, ifindex, sk);
|
ret = bcm_tx_send(msg, ifindex, sk);
|
||||||
|
@ -632,6 +632,9 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
|
|||||||
} else
|
} else
|
||||||
ifindex = ro->ifindex;
|
ifindex = ro->ifindex;
|
||||||
|
|
||||||
|
if (size != sizeof(struct can_frame))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
dev = dev_get_by_index(&init_net, ifindex);
|
dev = dev_get_by_index(&init_net, ifindex);
|
||||||
if (!dev)
|
if (!dev)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
@ -255,6 +255,7 @@
|
|||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/scatterlist.h>
|
||||||
#include <linux/splice.h>
|
#include <linux/splice.h>
|
||||||
#include <linux/net.h>
|
#include <linux/net.h>
|
||||||
#include <linux/socket.h>
|
#include <linux/socket.h>
|
||||||
@ -1208,7 +1209,8 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
|
|||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
|
while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
|
||||||
if (offset < skb->len) {
|
if (offset < skb->len) {
|
||||||
size_t used, len;
|
int used;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
len = skb->len - offset;
|
len = skb->len - offset;
|
||||||
/* Stop reading if we hit a patch of urgent data */
|
/* Stop reading if we hit a patch of urgent data */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user