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: (42 commits)
  net: Fix routing tables with id > 255 for legacy software
  sky2: Hold RTNL while calling dev_close()
  s2io iomem annotations
  atl1: fix suspend regression
  qeth: start dev queue after tx drop error
  qeth: Prepare-function to call s390dbf was wrong
  qeth: reduce number of kernel messages
  qeth: Use ccw_device_get_id().
  qeth: layer 3 Oops in ip event handler
  virtio: use callback on empty in virtio_net
  virtio: virtio_net free transmit skbs in a timer
  virtio: Fix typo in virtio_net_hdr comments
  virtio_net: Fix skb->csum_start computation
  ehea: set mac address fix
  sfc: Recover from RX queue flush failure
  add missing lance_* exports
  ixgbe: fix typo
  forcedeth: msi interrupts
  ipsec: pfkey should ignore events when no listeners
  pppoe: Unshare skb before anything else
  ...
This commit is contained in:
Linus Torvalds 2008-06-11 08:39:51 -07:00
commit f7f866eed0
47 changed files with 361 additions and 366 deletions

View file

@ -506,6 +506,7 @@ int lance_open (struct net_device *dev)
return res;
}
EXPORT_SYMBOL_GPL(lance_open);
int lance_close (struct net_device *dev)
{
@ -521,6 +522,7 @@ int lance_close (struct net_device *dev)
return 0;
}
EXPORT_SYMBOL_GPL(lance_close);
void lance_tx_timeout(struct net_device *dev)
{
@ -529,7 +531,7 @@ void lance_tx_timeout(struct net_device *dev)
dev->trans_start = jiffies;
netif_wake_queue (dev);
}
EXPORT_SYMBOL_GPL(lance_tx_timeout);
int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
{
@ -586,6 +588,7 @@ int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
return 0;
}
EXPORT_SYMBOL_GPL(lance_start_xmit);
/* taken from the depca driver via a2065.c */
static void lance_load_multicast (struct net_device *dev)
@ -654,6 +657,7 @@ void lance_set_multicast (struct net_device *dev)
if (!stopped)
netif_start_queue (dev);
}
EXPORT_SYMBOL_GPL(lance_set_multicast);
#ifdef CONFIG_NET_POLL_CONTROLLER
void lance_poll(struct net_device *dev)

View file

@ -636,22 +636,6 @@ static s32 atl1_phy_leave_power_saving(struct atl1_hw *hw)
return atl1_write_phy_reg(hw, 30, 0);
}
/*
* Force the PHY into power saving mode using vendor magic.
*/
#ifdef CONFIG_PM
static void atl1_phy_enter_power_saving(struct atl1_hw *hw)
{
atl1_write_phy_reg(hw, MII_DBG_ADDR, 0);
atl1_write_phy_reg(hw, MII_DBG_DATA, 0x124E);
atl1_write_phy_reg(hw, MII_DBG_ADDR, 2);
atl1_write_phy_reg(hw, MII_DBG_DATA, 0x3000);
atl1_write_phy_reg(hw, MII_DBG_ADDR, 3);
atl1_write_phy_reg(hw, MII_DBG_DATA, 0);
}
#endif
/*
* Resets the PHY and make all config validate
* hw - Struct containing variables accessed by shared code
@ -2860,7 +2844,6 @@ disable_wol:
ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
atl1_phy_enter_power_saving(hw);
hw->phy_configured = false;
pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
exit:

View file

@ -1766,16 +1766,20 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
mutex_lock(&ehea_bcmc_regs.lock);
/* Deregister old MAC in pHYP */
ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
if (ret)
goto out_upregs;
if (port->state == EHEA_PORT_UP) {
ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
if (ret)
goto out_upregs;
}
port->mac_addr = cb0->port_mac_addr << 16;
/* Register new MAC in pHYP */
ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
if (ret)
goto out_upregs;
if (port->state == EHEA_PORT_UP) {
ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
if (ret)
goto out_upregs;
}
ret = 0;

View file

@ -3273,6 +3273,20 @@ static void nv_link_irq(struct net_device *dev)
dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name);
}
static void nv_msi_workaround(struct fe_priv *np)
{
/* Need to toggle the msi irq mask within the ethernet device,
* otherwise, future interrupts will not be detected.
*/
if (np->msi_flags & NV_MSI_ENABLED) {
u8 __iomem *base = np->base;
writel(0, base + NvRegMSIIrqMask);
writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask);
}
}
static irqreturn_t nv_nic_irq(int foo, void *data)
{
struct net_device *dev = (struct net_device *) data;
@ -3295,6 +3309,8 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
if (!(events & np->irqmask))
break;
nv_msi_workaround(np);
spin_lock(&np->lock);
nv_tx_done(dev);
spin_unlock(&np->lock);
@ -3410,6 +3426,8 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
if (!(events & np->irqmask))
break;
nv_msi_workaround(np);
spin_lock(&np->lock);
nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
spin_unlock(&np->lock);
@ -3750,6 +3768,8 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data)
if (!(events & NVREG_IRQ_TIMER))
return IRQ_RETVAL(0);
nv_msi_workaround(np);
spin_lock(&np->lock);
np->intr_test = 1;
spin_unlock(&np->lock);

View file

@ -329,6 +329,7 @@ config PXA_FICP
config MCS_FIR
tristate "MosChip MCS7780 IrDA-USB dongle"
depends on IRDA && USB && EXPERIMENTAL
select CRC32
help
Say Y or M here if you want to build support for the MosChip
MCS7780 IrDA-USB bridge device driver.

View file

@ -58,8 +58,8 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw);
static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
{
hw->mac.num_rx_queues = IXGBE_82598_MAX_TX_QUEUES;
hw->mac.num_tx_queues = IXGBE_82598_MAX_RX_QUEUES;
hw->mac.num_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
hw->mac.num_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
hw->mac.num_rx_addrs = IXGBE_82598_RAR_ENTRIES;
/* PHY ops are filled in by default properly for Fiber only */

View file

@ -341,12 +341,6 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb)
struct pppox_sock *relay_po;
if (sk->sk_state & PPPOX_BOUND) {
struct pppoe_hdr *ph = pppoe_hdr(skb);
int len = ntohs(ph->length);
skb_pull_rcsum(skb, sizeof(struct pppoe_hdr));
if (pskb_trim_rcsum(skb, len))
goto abort_kfree;
ppp_input(&po->chan, skb);
} else if (sk->sk_state & PPPOX_RELAY) {
relay_po = get_item_by_addr(&po->pppoe_relay);
@ -357,7 +351,6 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb)
if ((sk_pppox(relay_po)->sk_state & PPPOX_CONNECTED) == 0)
goto abort_put;
skb_pull(skb, sizeof(struct pppoe_hdr));
if (!__pppoe_xmit(sk_pppox(relay_po), skb))
goto abort_put;
} else {
@ -388,6 +381,7 @@ static int pppoe_rcv(struct sk_buff *skb,
{
struct pppoe_hdr *ph;
struct pppox_sock *po;
int len;
if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
goto out;
@ -399,10 +393,21 @@ static int pppoe_rcv(struct sk_buff *skb,
goto drop;
ph = pppoe_hdr(skb);
len = ntohs(ph->length);
skb_pull_rcsum(skb, sizeof(*ph));
if (skb->len < len)
goto drop;
po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
if (po != NULL)
return sk_receive_skb(sk_pppox(po), skb, 0);
if (!po)
goto drop;
if (pskb_trim_rcsum(skb, len))
goto drop;
return sk_receive_skb(sk_pppox(po), skb, 0);
drop:
kfree_skb(skb);
out:
@ -427,12 +432,12 @@ static int pppoe_disc_rcv(struct sk_buff *skb,
if (dev_net(dev) != &init_net)
goto abort;
if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
goto abort;
if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
goto out;
if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
goto abort;
ph = pppoe_hdr(skb);
if (ph->code != PADT_CODE)
goto abort;
@ -937,12 +942,10 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock,
m->msg_namelen = 0;
if (skb) {
struct pppoe_hdr *ph = pppoe_hdr(skb);
const int len = ntohs(ph->length);
error = memcpy_toiovec(m->msg_iov, (unsigned char *) &ph->tag[0], len);
total_len = min(total_len, skb->len);
error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len);
if (error == 0)
error = len;
error = total_len;
}
kfree_skb(skb);

View file

@ -783,14 +783,18 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock,
err = 0;
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
flags & MSG_DONTWAIT, &err);
if (skb) {
err = memcpy_toiovec(msg->msg_iov, (unsigned char *) skb->data,
skb->len);
if (err < 0)
goto do_skb_free;
err = skb->len;
}
do_skb_free:
if (!skb)
goto end;
if (len > skb->len)
len = skb->len;
else if (len < skb->len)
msg->msg_flags |= MSG_TRUNC;
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len);
if (likely(err == 0))
err = len;
kfree_skb(skb);
end:
return err;

View file

@ -733,8 +733,10 @@ void falcon_fini_rx(struct efx_rx_queue *rx_queue)
continue;
break;
}
if (rc)
if (rc) {
EFX_ERR(efx, "failed to flush rx queue %d\n", rx_queue->queue);
efx_schedule_reset(efx, RESET_TYPE_INVISIBLE);
}
/* Remove RX descriptor ring from card */
EFX_ZERO_OWORD(rx_desc_ptr);

View file

@ -4404,7 +4404,9 @@ static int sky2_resume(struct pci_dev *pdev)
if (err) {
printk(KERN_ERR PFX "%s: could not up: %d\n",
dev->name, err);
rtnl_lock();
dev_close(dev);
rtnl_unlock();
goto out;
}
}

View file

@ -64,8 +64,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "3.92"
#define DRV_MODULE_RELDATE "May 2, 2008"
#define DRV_MODULE_VERSION "3.92.1"
#define DRV_MODULE_RELDATE "June 9, 2008"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@ -1295,6 +1295,21 @@ static void tg3_frob_aux_power(struct tg3 *tp)
GRC_LCLCTRL_GPIO_OUTPUT0 |
GRC_LCLCTRL_GPIO_OUTPUT1),
100);
} else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) {
/* The 5761 non-e device swaps GPIO 0 and GPIO 2. */
u32 grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 |
GRC_LCLCTRL_GPIO_OE1 |
GRC_LCLCTRL_GPIO_OE2 |
GRC_LCLCTRL_GPIO_OUTPUT0 |
GRC_LCLCTRL_GPIO_OUTPUT1 |
tp->grc_local_ctrl;
tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100);
grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT2;
tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100);
grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT0;
tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100);
} else {
u32 no_gpio2;
u32 grc_local_ctrl = 0;
@ -3168,8 +3183,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
err |= tg3_readphy(tp, MII_BMCR, &bmcr);
if ((tp->link_config.autoneg == AUTONEG_ENABLE) && !force_reset &&
(tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT) &&
tp->link_config.flowctrl == tp->link_config.active_flowctrl) {
(tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT)) {
/* do nothing, just check for link up at the end */
} else if (tp->link_config.autoneg == AUTONEG_ENABLE) {
u32 adv, new_adv;
@ -8599,7 +8613,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
(cmd->speed == SPEED_1000))
return -EINVAL;
else if ((cmd->speed == SPEED_1000) &&
(tp->tg3_flags2 & TG3_FLAG_10_100_ONLY))
(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
return -EINVAL;
tg3_full_lock(tp, 0);
@ -11768,6 +11782,15 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) {
/* Turn off the debug UART. */
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
/* Keep VMain power. */
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE0 |
GRC_LCLCTRL_GPIO_OUTPUT0;
}
/* Force the chip into D0. */
err = tg3_set_power_state(tp, PCI_D0);
if (err) {

View file

@ -44,11 +44,15 @@ struct virtnet_info
/* The skb we couldn't send because buffers were full. */
struct sk_buff *last_xmit_skb;
/* If we need to free in a timer, this is it. */
struct timer_list xmit_free_timer;
/* Number of input buffers, and max we've ever had. */
unsigned int num, max;
/* For cleaning up after transmission. */
struct tasklet_struct tasklet;
bool free_in_tasklet;
/* Receive & send queues. */
struct sk_buff_head recv;
@ -72,7 +76,7 @@ static void skb_xmit_done(struct virtqueue *svq)
/* Suppress further interrupts. */
svq->vq_ops->disable_cb(svq);
/* We were waiting for more output buffers. */
/* We were probably waiting for more output buffers. */
netif_wake_queue(vi->dev);
/* Make sure we re-xmit last_xmit_skb: if there are no more packets
@ -94,9 +98,7 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb,
BUG_ON(len > MAX_PACKET_LEN);
skb_trim(skb, len);
skb->protocol = eth_type_trans(skb, dev);
pr_debug("Receiving skb proto 0x%04x len %i type %i\n",
ntohs(skb->protocol), skb->len, skb->pkt_type);
dev->stats.rx_bytes += skb->len;
dev->stats.rx_packets++;
@ -106,6 +108,10 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb,
goto frame_err;
}
skb->protocol = eth_type_trans(skb, dev);
pr_debug("Receiving skb proto 0x%04x len %i type %i\n",
ntohs(skb->protocol), skb->len, skb->pkt_type);
if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
pr_debug("GSO!\n");
switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
@ -238,9 +244,25 @@ static void free_old_xmit_skbs(struct virtnet_info *vi)
}
}
/* If the virtio transport doesn't always notify us when all in-flight packets
* are consumed, we fall back to using this function on a timer to free them. */
static void xmit_free(unsigned long data)
{
struct virtnet_info *vi = (void *)data;
netif_tx_lock(vi->dev);
free_old_xmit_skbs(vi);
if (!skb_queue_empty(&vi->send))
mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10));
netif_tx_unlock(vi->dev);
}
static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
{
int num;
int num, err;
struct scatterlist sg[2+MAX_SKB_FRAGS];
struct virtio_net_hdr *hdr;
const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
@ -283,7 +305,11 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
vnet_hdr_to_sg(sg, skb);
num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
return vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb);
err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb);
if (!err && !vi->free_in_tasklet)
mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10));
return err;
}
static void xmit_tasklet(unsigned long data)
@ -295,6 +321,8 @@ static void xmit_tasklet(unsigned long data)
vi->svq->vq_ops->kick(vi->svq);
vi->last_xmit_skb = NULL;
}
if (vi->free_in_tasklet)
free_old_xmit_skbs(vi);
netif_tx_unlock_bh(vi->dev);
}
@ -435,6 +463,10 @@ static int virtnet_probe(struct virtio_device *vdev)
vi->vdev = vdev;
vdev->priv = vi;
/* If they give us a callback when all buffers are done, we don't need
* the timer. */
vi->free_in_tasklet = virtio_has_feature(vdev,VIRTIO_F_NOTIFY_ON_EMPTY);
/* We expect two virtqueues, receive then send. */
vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done);
if (IS_ERR(vi->rvq)) {
@ -454,6 +486,9 @@ static int virtnet_probe(struct virtio_device *vdev)
tasklet_init(&vi->tasklet, xmit_tasklet, (unsigned long)vi);
if (!vi->free_in_tasklet)
setup_timer(&vi->xmit_free_timer, xmit_free, (unsigned long)vi);
err = register_netdev(dev);
if (err) {
pr_debug("virtio_net: registering device failed\n");
@ -491,6 +526,9 @@ static void virtnet_remove(struct virtio_device *vdev)
/* Stop all the virtqueues. */
vdev->config->reset(vdev);
if (!vi->free_in_tasklet)
del_timer_sync(&vi->xmit_free_timer);
/* Free our skbs in send and recv queues, if any. */
while ((skb = __skb_dequeue(&vi->recv)) != NULL) {
kfree_skb(skb);
@ -514,7 +552,7 @@ static struct virtio_device_id id_table[] = {
static unsigned int features[] = {
VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
VIRTIO_NET_F_HOST_ECN,
VIRTIO_NET_F_HOST_ECN, VIRTIO_F_NOTIFY_ON_EMPTY,
};
static struct virtio_driver virtio_net = {

View file

@ -1753,6 +1753,8 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
if (priv->workqueue) {
cancel_delayed_work(&priv->request_scan);
cancel_delayed_work(&priv->request_direct_scan);
cancel_delayed_work(&priv->request_passive_scan);
cancel_delayed_work(&priv->scan_event);
}
queue_work(priv->workqueue, &priv->down);
@ -2005,6 +2007,8 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
wake_up_interruptible(&priv->wait_command_queue);
priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
cancel_delayed_work(&priv->request_scan);
cancel_delayed_work(&priv->request_direct_scan);
cancel_delayed_work(&priv->request_passive_scan);
cancel_delayed_work(&priv->scan_event);
schedule_work(&priv->link_down);
queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
@ -4712,6 +4716,12 @@ static void ipw_rx_notification(struct ipw_priv *priv,
priv->status &= ~STATUS_SCAN_FORCED;
#endif /* CONFIG_IPW2200_MONITOR */
/* Do queued direct scans first */
if (priv->status & STATUS_DIRECT_SCAN_PENDING) {
queue_delayed_work(priv->workqueue,
&priv->request_direct_scan, 0);
}
if (!(priv->status & (STATUS_ASSOCIATED |
STATUS_ASSOCIATING |
STATUS_ROAMING |
@ -6267,7 +6277,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
}
}
static int ipw_request_scan_helper(struct ipw_priv *priv, int type)
static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
{
struct ipw_scan_request_ext scan;
int err = 0, scan_type;
@ -6278,22 +6288,31 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type)
mutex_lock(&priv->mutex);
if (direct && (priv->direct_scan_ssid_len == 0)) {
IPW_DEBUG_HC("Direct scan requested but no SSID to scan for\n");
priv->status &= ~STATUS_DIRECT_SCAN_PENDING;
goto done;
}
if (priv->status & STATUS_SCANNING) {
IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n");
priv->status |= STATUS_SCAN_PENDING;
IPW_DEBUG_HC("Concurrent scan requested. Queuing.\n");
priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING :
STATUS_SCAN_PENDING;
goto done;
}
if (!(priv->status & STATUS_SCAN_FORCED) &&
priv->status & STATUS_SCAN_ABORTING) {
IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");
priv->status |= STATUS_SCAN_PENDING;
priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING :
STATUS_SCAN_PENDING;
goto done;
}
if (priv->status & STATUS_RF_KILL_MASK) {
IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n");
priv->status |= STATUS_SCAN_PENDING;
IPW_DEBUG_HC("Queuing scan due to RF Kill activation\n");
priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING :
STATUS_SCAN_PENDING;
goto done;
}
@ -6321,6 +6340,7 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type)
cpu_to_le16(20);
scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);
#ifdef CONFIG_IPW2200_MONITOR
if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
@ -6360,13 +6380,23 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type)
cpu_to_le16(2000);
} else {
#endif /* CONFIG_IPW2200_MONITOR */
/* If we are roaming, then make this a directed scan for the
* current network. Otherwise, ensure that every other scan
* is a fast channel hop scan */
if ((priv->status & STATUS_ROAMING)
|| (!(priv->status & STATUS_ASSOCIATED)
&& (priv->config & CFG_STATIC_ESSID)
&& (le32_to_cpu(scan.full_scan_index) % 2))) {
/* Honor direct scans first, otherwise if we are roaming make
* this a direct scan for the current network. Finally,
* ensure that every other scan is a fast channel hop scan */
if (direct) {
err = ipw_send_ssid(priv, priv->direct_scan_ssid,
priv->direct_scan_ssid_len);
if (err) {
IPW_DEBUG_HC("Attempt to send SSID command "
"failed\n");
goto done;
}
scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
} else if ((priv->status & STATUS_ROAMING)
|| (!(priv->status & STATUS_ASSOCIATED)
&& (priv->config & CFG_STATIC_ESSID)
&& (le32_to_cpu(scan.full_scan_index) % 2))) {
err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
if (err) {
IPW_DEBUG_HC("Attempt to send SSID command "
@ -6391,7 +6421,12 @@ send_request:
}
priv->status |= STATUS_SCANNING;
priv->status &= ~STATUS_SCAN_PENDING;
if (direct) {
priv->status &= ~STATUS_DIRECT_SCAN_PENDING;
priv->direct_scan_ssid_len = 0;
} else
priv->status &= ~STATUS_SCAN_PENDING;
queue_delayed_work(priv->workqueue, &priv->scan_check,
IPW_SCAN_CHECK_WATCHDOG);
done:
@ -6402,15 +6437,22 @@ done:
static void ipw_request_passive_scan(struct work_struct *work)
{
struct ipw_priv *priv =
container_of(work, struct ipw_priv, request_passive_scan);
ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE);
container_of(work, struct ipw_priv, request_passive_scan.work);
ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE, 0);
}
static void ipw_request_scan(struct work_struct *work)
{
struct ipw_priv *priv =
container_of(work, struct ipw_priv, request_scan.work);
ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE);
ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE, 0);
}
static void ipw_request_direct_scan(struct work_struct *work)
{
struct ipw_priv *priv =
container_of(work, struct ipw_priv, request_direct_scan.work);
ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE, 1);
}
static void ipw_bg_abort_scan(struct work_struct *work)
@ -9477,99 +9519,38 @@ static int ipw_wx_get_retry(struct net_device *dev,
return 0;
}
static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid,
int essid_len)
{
struct ipw_scan_request_ext scan;
int err = 0, scan_type;
if (!(priv->status & STATUS_INIT) ||
(priv->status & STATUS_EXIT_PENDING))
return 0;
mutex_lock(&priv->mutex);
if (priv->status & STATUS_RF_KILL_MASK) {
IPW_DEBUG_HC("Aborting scan due to RF kill activation\n");
priv->status |= STATUS_SCAN_PENDING;
goto done;
}
IPW_DEBUG_HC("starting request direct scan!\n");
if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
/* We should not sleep here; otherwise we will block most
* of the system (for instance, we hold rtnl_lock when we
* get here).
*/
err = -EAGAIN;
goto done;
}
memset(&scan, 0, sizeof(scan));
if (priv->config & CFG_SPEED_SCAN)
scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
cpu_to_le16(30);
else
scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
cpu_to_le16(20);
scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
cpu_to_le16(20);
scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);
scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
err = ipw_send_ssid(priv, essid, essid_len);
if (err) {
IPW_DEBUG_HC("Attempt to send SSID command failed\n");
goto done;
}
scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
ipw_add_scan_channels(priv, &scan, scan_type);
err = ipw_send_scan_request_ext(priv, &scan);
if (err) {
IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
goto done;
}
priv->status |= STATUS_SCANNING;
done:
mutex_unlock(&priv->mutex);
return err;
}
static int ipw_wx_set_scan(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
struct iw_scan_req *req = (struct iw_scan_req *)extra;
struct delayed_work *work = NULL;
mutex_lock(&priv->mutex);
priv->user_requested_scan = 1;
mutex_unlock(&priv->mutex);
if (wrqu->data.length == sizeof(struct iw_scan_req)) {
if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
ipw_request_direct_scan(priv, req->essid,
req->essid_len);
return 0;
}
if (req->scan_type == IW_SCAN_TYPE_PASSIVE) {
queue_work(priv->workqueue,
&priv->request_passive_scan);
return 0;
int len = min((int)req->essid_len,
(int)sizeof(priv->direct_scan_ssid));
memcpy(priv->direct_scan_ssid, req->essid, len);
priv->direct_scan_ssid_len = len;
work = &priv->request_direct_scan;
} else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) {
work = &priv->request_passive_scan;
}
} else {
/* Normal active broadcast scan */
work = &priv->request_scan;
}
mutex_unlock(&priv->mutex);
IPW_DEBUG_WX("Start scan\n");
queue_delayed_work(priv->workqueue, &priv->request_scan, 0);
queue_delayed_work(priv->workqueue, work, 0);
return 0;
}
@ -10731,6 +10712,8 @@ static void ipw_link_up(struct ipw_priv *priv)
}
cancel_delayed_work(&priv->request_scan);
cancel_delayed_work(&priv->request_direct_scan);
cancel_delayed_work(&priv->request_passive_scan);
cancel_delayed_work(&priv->scan_event);
ipw_reset_stats(priv);
/* Ensure the rate is updated immediately */
@ -10761,6 +10744,8 @@ static void ipw_link_down(struct ipw_priv *priv)
/* Cancel any queued work ... */
cancel_delayed_work(&priv->request_scan);
cancel_delayed_work(&priv->request_direct_scan);
cancel_delayed_work(&priv->request_passive_scan);
cancel_delayed_work(&priv->adhoc_check);
cancel_delayed_work(&priv->gather_stats);
@ -10800,8 +10785,9 @@ static int __devinit ipw_setup_deferred_work(struct ipw_priv *priv)
INIT_WORK(&priv->up, ipw_bg_up);
INIT_WORK(&priv->down, ipw_bg_down);
INIT_DELAYED_WORK(&priv->request_scan, ipw_request_scan);
INIT_DELAYED_WORK(&priv->request_direct_scan, ipw_request_direct_scan);
INIT_DELAYED_WORK(&priv->request_passive_scan, ipw_request_passive_scan);
INIT_DELAYED_WORK(&priv->scan_event, ipw_scan_event);
INIT_WORK(&priv->request_passive_scan, ipw_request_passive_scan);
INIT_DELAYED_WORK(&priv->gather_stats, ipw_bg_gather_stats);
INIT_WORK(&priv->abort_scan, ipw_bg_abort_scan);
INIT_WORK(&priv->roam, ipw_bg_roam);
@ -11835,6 +11821,8 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
cancel_delayed_work(&priv->adhoc_check);
cancel_delayed_work(&priv->gather_stats);
cancel_delayed_work(&priv->request_scan);
cancel_delayed_work(&priv->request_direct_scan);
cancel_delayed_work(&priv->request_passive_scan);
cancel_delayed_work(&priv->scan_event);
cancel_delayed_work(&priv->rf_kill);
cancel_delayed_work(&priv->scan_check);

View file

@ -1037,6 +1037,7 @@ struct ipw_cmd { /* XXX */
#define STATUS_DISASSOC_PENDING (1<<12)
#define STATUS_STATE_PENDING (1<<13)
#define STATUS_DIRECT_SCAN_PENDING (1<<19)
#define STATUS_SCAN_PENDING (1<<20)
#define STATUS_SCANNING (1<<21)
#define STATUS_SCAN_ABORTING (1<<22)
@ -1292,6 +1293,8 @@ struct ipw_priv {
struct iw_public_data wireless_data;
int user_requested_scan;
u8 direct_scan_ssid[IW_ESSID_MAX_SIZE];
u8 direct_scan_ssid_len;
struct workqueue_struct *workqueue;
@ -1301,8 +1304,9 @@ struct ipw_priv {
struct work_struct system_config;
struct work_struct rx_replenish;
struct delayed_work request_scan;
struct delayed_work request_direct_scan;
struct delayed_work request_passive_scan;
struct delayed_work scan_event;
struct work_struct request_passive_scan;
struct work_struct adapter_restart;
struct delayed_work rf_kill;
struct work_struct up;

View file

@ -229,14 +229,15 @@ static int iwl3945_led_register_led(struct iwl3945_priv *priv,
led->led_dev.brightness_set = iwl3945_led_brightness_set;
led->led_dev.default_trigger = trigger;
led->priv = priv;
led->type = type;
ret = led_classdev_register(device, &led->led_dev);
if (ret) {
IWL_ERROR("Error: failed to register led handler.\n");
return ret;
}
led->priv = priv;
led->type = type;
led->registered = 1;
if (set_led && led->led_on)

View file

@ -1842,6 +1842,9 @@ static void lbs_send_confirmsleep(struct lbs_private *priv)
spin_lock_irqsave(&priv->driver_lock, flags);
/* We don't get a response on the sleep-confirmation */
priv->dnld_sent = DNLD_RES_RECEIVED;
/* If nothing to do, go back to sleep (?) */
if (!__kfifo_len(priv->event_fifo) && !priv->resp_len[priv->resp_idx])
priv->psstate = PS_STATE_SLEEP;
@ -1904,12 +1907,12 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv)
lbs_deb_enter(LBS_DEB_HOST);
spin_lock_irqsave(&priv->driver_lock, flags);
if (priv->dnld_sent) {
allowed = 0;
lbs_deb_host("dnld_sent was set\n");
}
spin_lock_irqsave(&priv->driver_lock, flags);
/* In-progress command? */
if (priv->cur_cmd) {
allowed = 0;

View file

@ -732,8 +732,8 @@ static int lbs_thread(void *data)
lbs_deb_thread("4: currenttxskb %p, dnld_sent %d\n",
priv->currenttxskb, priv->dnld_sent);
spin_lock_irq(&priv->driver_lock);
/* Process any pending command response */
spin_lock_irq(&priv->driver_lock);
resp_idx = priv->resp_idx;
if (priv->resp_len[resp_idx]) {
spin_unlock_irq(&priv->driver_lock);

View file

@ -719,7 +719,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
fc = le16_to_cpu(*((__le16 *) buffer));
is_qos = ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_QOS_DATA);
(fc & IEEE80211_STYPE_QOS_DATA);
is_4addr = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS);
need_padding = is_qos ^ is_4addr;