summaryrefslogtreecommitdiffstats
path: root/drivers/net/cxgb3/cxgb3_main.c
diff options
context:
space:
mode:
authorAnton Vorontsov <cbouatmailru@gmail.com>2008-07-30 00:05:23 +0200
committerAnton Vorontsov <cbouatmailru@gmail.com>2008-07-30 00:05:23 +0200
commit9fec6060d9e48ed7db0dac0e16d0f0f0e615b7f6 (patch)
tree74b41f31a08f6500ff3dfcf64ba21e2d9a8e87e5 /drivers/net/cxgb3/cxgb3_main.c
parentpower_supply: Sharp SL-6000 (tosa) batteries support (diff)
parentLinux 2.6.27-rc1 (diff)
downloadlinux-9fec6060d9e48ed7db0dac0e16d0f0f0e615b7f6.tar.xz
linux-9fec6060d9e48ed7db0dac0e16d0f0f0e615b7f6.zip
Merge branch 'master' of /home/cbou/linux-2.6
Conflicts: drivers/power/Kconfig drivers/power/Makefile
Diffstat (limited to 'drivers/net/cxgb3/cxgb3_main.c')
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c63
1 files changed, 43 insertions, 20 deletions
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 05e5f59e87fa..5447f3e60f07 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -421,6 +421,13 @@ static void init_napi(struct adapter *adap)
netif_napi_add(qs->netdev, &qs->napi, qs->napi.poll,
64);
}
+
+ /*
+ * netif_napi_add() can be called only once per napi_struct because it
+ * adds each new napi_struct to a list. Be careful not to call it a
+ * second time, e.g., during EEH recovery, by making a note of it.
+ */
+ adap->flags |= NAPI_INIT;
}
/*
@@ -896,7 +903,8 @@ static int cxgb_up(struct adapter *adap)
goto out;
setup_rss(adap);
- init_napi(adap);
+ if (!(adap->flags & NAPI_INIT))
+ init_napi(adap);
adap->flags |= FULL_INIT_DONE;
}
@@ -999,7 +1007,7 @@ static int offload_open(struct net_device *dev)
return 0;
if (!adap_up && (err = cxgb_up(adapter)) < 0)
- return err;
+ goto out;
t3_tp_set_offload_mode(adapter, 1);
tdev->lldev = adapter->port[0];
@@ -1061,10 +1069,8 @@ static int cxgb_open(struct net_device *dev)
int other_ports = adapter->open_device_map & PORT_MASK;
int err;
- if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) {
- quiesce_rx(adapter);
+ if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0)
return err;
- }
set_bit(pi->port_id, &adapter->open_device_map);
if (is_offload(adapter) && !ofld_disable) {
@@ -1206,6 +1212,9 @@ static char stats_strings[][ETH_GSTRING_LEN] = {
"VLANinsertions ",
"TxCsumOffload ",
"RxCsumGood ",
+ "LroAggregated ",
+ "LroFlushed ",
+ "LroNoDesc ",
"RxDrops ",
"CheckTXEnToggled ",
@@ -1334,6 +1343,9 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_VLANINS);
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TX_CSUM);
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD);
+ *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_AGGR);
+ *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_FLUSHED);
+ *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_NO_DESC);
*data++ = s->rx_cong_drops;
*data++ = s->num_toggled;
@@ -1552,6 +1564,13 @@ static int set_rx_csum(struct net_device *dev, u32 data)
struct port_info *p = netdev_priv(dev);
p->rx_csum_offload = data;
+ if (!data) {
+ struct adapter *adap = p->adapter;
+ int i;
+
+ for (i = p->first_qset; i < p->first_qset + p->nqsets; i++)
+ adap->sge.qs[i].lro_enabled = 0;
+ }
return 0;
}
@@ -1824,6 +1843,11 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
}
}
}
+ if (t.lro >= 0) {
+ struct sge_qset *qs = &adapter->sge.qs[t.qset_idx];
+ q->lro = t.lro;
+ qs->lro_enabled = t.lro;
+ }
break;
}
case CHELSIO_GET_QSET_PARAMS:{
@@ -1843,6 +1867,7 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
t.fl_size[0] = q->fl_size;
t.fl_size[1] = q->jumbo_size;
t.polling = q->polling;
+ t.lro = q->lro;
t.intr_lat = q->coalesce_usecs;
t.cong_thres = q->cong_thres;
@@ -1894,11 +1919,11 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
u8 *fw_data;
struct ch_mem_range t;
- if (!capable(CAP_NET_ADMIN))
+ if (!capable(CAP_SYS_RAWIO))
return -EPERM;
if (copy_from_user(&t, useraddr, sizeof(t)))
return -EFAULT;
-
+ /* Check t.len sanity ? */
fw_data = kmalloc(t.len, GFP_KERNEL);
if (!fw_data)
return -ENOMEM;
@@ -2424,14 +2449,11 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev,
test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
offload_close(&adapter->tdev);
- /* Free sge resources */
- t3_free_sge_resources(adapter);
-
adapter->flags &= ~FULL_INIT_DONE;
pci_disable_device(pdev);
- /* Request a slot slot reset. */
+ /* Request a slot reset. */
return PCI_ERS_RESULT_NEED_RESET;
}
@@ -2448,13 +2470,20 @@ static pci_ers_result_t t3_io_slot_reset(struct pci_dev *pdev)
if (pci_enable_device(pdev)) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset.\n");
- return PCI_ERS_RESULT_DISCONNECT;
+ goto err;
}
pci_set_master(pdev);
+ pci_restore_state(pdev);
+
+ /* Free sge resources */
+ t3_free_sge_resources(adapter);
- t3_prep_adapter(adapter, adapter->params.info, 1);
+ if (t3_replay_prep_adapter(adapter))
+ goto err;
return PCI_ERS_RESULT_RECOVERED;
+err:
+ return PCI_ERS_RESULT_DISCONNECT;
}
/**
@@ -2483,13 +2512,6 @@ static void t3_io_resume(struct pci_dev *pdev)
netif_device_attach(netdev);
}
}
-
- if (is_offload(adapter)) {
- __set_bit(OFFLOAD_DEVMAP_BIT, &adapter->registered_device_map);
- if (offload_open(adapter->port[0]))
- printk(KERN_WARNING
- "Could not bring back offload capabilities\n");
- }
}
static struct pci_error_handlers t3_err_handler = {
@@ -2608,6 +2630,7 @@ static int __devinit init_one(struct pci_dev *pdev,
}
pci_set_master(pdev);
+ pci_save_state(pdev);
mmio_start = pci_resource_start(pdev, 0);
mmio_len = pci_resource_len(pdev, 0);