]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/net/s2io.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[net-next-2.6.git] / drivers / net / s2io.c
index 1d37f0c310ca4bd91d715129f24a11356ad41fa1..d0af924ddd67208ac5a794b0d58997f0d42062cf 100644 (file)
@@ -38,7 +38,7 @@
  * Tx descriptors that can be associated with each corresponding FIFO.
  * intr_type: This defines the type of interrupt. The values can be 0(INTA),
  *     2(MSI_X). Default value is '2(MSI_X)'
- * lro_enable: Specifies whether to enable Large Receive Offload (LRO) or not.
+ * lro: Specifies whether to enable Large Receive Offload (LRO) or not.
  *     Possible values '1' for enable '0' for disable. Default is '0'
  * lro_max_pkts: This parameter defines maximum number of packets can be
  *     aggregated as a single large packet
@@ -90,7 +90,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.26.25"
+#define DRV_VERSION "2.0.26.26"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -496,7 +496,7 @@ S2IO_PARM_INT(rxsync_frequency, 3);
 /* Interrupt type. Values can be 0(INTA), 2(MSI_X) */
 S2IO_PARM_INT(intr_type, 2);
 /* Large receive offload feature */
-static unsigned int lro_enable;
+static unsigned int lro_enable = 1;
 module_param_named(lro, lro_enable, uint, 0);
 
 /* Max pkts to be aggregated by LRO at one time. If not specified,
@@ -795,7 +795,6 @@ static int init_shared_mem(struct s2io_nic *nic)
                ring->rx_curr_put_info.ring_len = rx_cfg->num_rxd - 1;
                ring->nic = nic;
                ring->ring_no = i;
-               ring->lro = lro_enable;
 
                blk_cnt = rx_cfg->num_rxd / (rxd_count[nic->rxd_mode] + 1);
                /*  Allocating all the Rx blocks */
@@ -6707,6 +6706,7 @@ static u32 s2io_ethtool_op_get_tso(struct net_device *dev)
 {
        return (dev->features & NETIF_F_TSO) != 0;
 }
+
 static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data)
 {
        if (data)
@@ -6717,6 +6717,42 @@ static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data)
        return 0;
 }
 
+static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
+{
+       struct s2io_nic *sp = netdev_priv(dev);
+       int rc = 0;
+       int changed = 0;
+
+       if (data & ~ETH_FLAG_LRO)
+               return -EINVAL;
+
+       if (data & ETH_FLAG_LRO) {
+               if (lro_enable) {
+                       if (!(dev->features & NETIF_F_LRO)) {
+                               dev->features |= NETIF_F_LRO;
+                               changed = 1;
+                       }
+               } else
+                       rc = -EINVAL;
+       } else if (dev->features & NETIF_F_LRO) {
+               dev->features &= ~NETIF_F_LRO;
+               changed = 1;
+       }
+
+       if (changed && netif_running(dev)) {
+               s2io_stop_all_tx_queue(sp);
+               s2io_card_down(sp);
+               sp->lro = !!(dev->features & NETIF_F_LRO);
+               rc = s2io_card_up(sp);
+               if (rc)
+                       s2io_reset(sp);
+               else
+                       s2io_start_all_tx_queue(sp);
+       }
+
+       return rc;
+}
+
 static const struct ethtool_ops netdev_ethtool_ops = {
        .get_settings = s2io_ethtool_gset,
        .set_settings = s2io_ethtool_sset,
@@ -6733,6 +6769,8 @@ static const struct ethtool_ops netdev_ethtool_ops = {
        .get_rx_csum = s2io_ethtool_get_rx_csum,
        .set_rx_csum = s2io_ethtool_set_rx_csum,
        .set_tx_csum = s2io_ethtool_op_set_tx_csum,
+       .set_flags = s2io_ethtool_set_flags,
+       .get_flags = ethtool_op_get_flags,
        .set_sg = ethtool_op_set_sg,
        .get_tso = s2io_ethtool_op_get_tso,
        .set_tso = s2io_ethtool_op_set_tso,
@@ -7261,6 +7299,7 @@ static int s2io_card_up(struct s2io_nic *sp)
                struct ring_info *ring = &mac_control->rings[i];
 
                ring->mtu = dev->mtu;
+               ring->lro = sp->lro;
                ret = fill_rx_buffers(sp, ring, 1);
                if (ret) {
                        DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
@@ -8001,7 +8040,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        dev->netdev_ops = &s2io_netdev_ops;
        SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-
+       if (lro_enable)
+               dev->features |= NETIF_F_LRO;
        dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
        if (sp->high_dma_flag == true)
                dev->features |= NETIF_F_HIGHDMA;