Skip to content

Commit

Permalink
Merge branch 'davem-fixes' of master.kernel.org:/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/jgarzik/netdev-2.6
  • Loading branch information
David S. Miller committed Jun 10, 2008
2 parents 709772e + 68c2889 commit 513fd37
Show file tree
Hide file tree
Showing 16 changed files with 151 additions and 189 deletions.
6 changes: 5 additions & 1 deletion drivers/net/7990.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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)
{
Expand All @@ -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)
{
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
17 changes: 0 additions & 17 deletions drivers/net/atlx/atl1.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -2860,7 +2844,6 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
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:
Expand Down
16 changes: 10 additions & 6 deletions drivers/net/ehea/ehea_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
20 changes: 20 additions & 0 deletions drivers/net/forcedeth.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ixgbe/ixgbe_82598.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
10 changes: 6 additions & 4 deletions drivers/net/s2io.c
Original file line number Diff line number Diff line change
Expand Up @@ -2861,7 +2861,8 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget)
struct config_param *config;
struct mac_info *mac_control;
int pkts_processed = 0;
u8 *addr = NULL, val8 = 0;
u8 __iomem *addr = NULL;
u8 val8 = 0;
struct s2io_nic *nic = dev->priv;
struct XENA_dev_config __iomem *bar0 = nic->bar0;
int budget_org = budget;
Expand All @@ -2878,7 +2879,7 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget)
if (pkts_processed < budget_org) {
netif_rx_complete(dev, napi);
/*Re Enable MSI-Rx Vector*/
addr = (u8 *)&bar0->xmsi_mask_reg;
addr = (u8 __iomem *)&bar0->xmsi_mask_reg;
addr += 7 - ring->ring_no;
val8 = (ring->ring_no == 0) ? 0x3f : 0xbf;
writeb(val8, addr);
Expand Down Expand Up @@ -4364,9 +4365,10 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id)
return IRQ_HANDLED;

if (sp->config.napi) {
u8 *addr = NULL, val8 = 0;
u8 __iomem *addr = NULL;
u8 val8 = 0;

addr = (u8 *)&bar0->xmsi_mask_reg;
addr = (u8 __iomem *)&bar0->xmsi_mask_reg;
addr += (7 - ring->ring_no);
val8 = (ring->ring_no == 0) ? 0x7f : 0xff;
writeb(val8, addr);
Expand Down
4 changes: 3 additions & 1 deletion drivers/net/sfc/falcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/sky2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
52 changes: 45 additions & 7 deletions drivers/net/virtio_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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++;

Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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);
}

Expand Down Expand Up @@ -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)) {
Expand All @@ -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");
Expand Down Expand Up @@ -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);
Expand All @@ -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 = {
Expand Down
Loading

0 comments on commit 513fd37

Please sign in to comment.