aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/enic
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/enic')
-rw-r--r--drivers/net/enic/cq_desc.h5
-rw-r--r--drivers/net/enic/enic.h2
-rw-r--r--drivers/net/enic/enic_main.c86
-rw-r--r--drivers/net/enic/enic_res.c7
-rw-r--r--drivers/net/enic/enic_res.h4
-rw-r--r--drivers/net/enic/vnic_dev.c70
-rw-r--r--drivers/net/enic/vnic_devcmd.h19
-rw-r--r--drivers/net/enic/vnic_intr.h2
-rw-r--r--drivers/net/enic/vnic_resource.h2
-rw-r--r--drivers/net/enic/vnic_rq.h9
-rw-r--r--drivers/net/enic/vnic_rss.h13
-rw-r--r--drivers/net/enic/vnic_wq.h9
12 files changed, 146 insertions, 82 deletions
diff --git a/drivers/net/enic/cq_desc.h b/drivers/net/enic/cq_desc.h
index c036a8bfd043..1eb289f773bf 100644
--- a/drivers/net/enic/cq_desc.h
+++ b/drivers/net/enic/cq_desc.h
@@ -44,9 +44,10 @@ struct cq_desc {
44 u8 type_color; 44 u8 type_color;
45}; 45};
46 46
47#define CQ_DESC_TYPE_BITS 7 47#define CQ_DESC_TYPE_BITS 4
48#define CQ_DESC_TYPE_MASK ((1 << CQ_DESC_TYPE_BITS) - 1) 48#define CQ_DESC_TYPE_MASK ((1 << CQ_DESC_TYPE_BITS) - 1)
49#define CQ_DESC_COLOR_MASK 1 49#define CQ_DESC_COLOR_MASK 1
50#define CQ_DESC_COLOR_SHIFT 7
50#define CQ_DESC_Q_NUM_BITS 10 51#define CQ_DESC_Q_NUM_BITS 10
51#define CQ_DESC_Q_NUM_MASK ((1 << CQ_DESC_Q_NUM_BITS) - 1) 52#define CQ_DESC_Q_NUM_MASK ((1 << CQ_DESC_Q_NUM_BITS) - 1)
52#define CQ_DESC_COMP_NDX_BITS 12 53#define CQ_DESC_COMP_NDX_BITS 12
@@ -58,7 +59,7 @@ static inline void cq_desc_dec(const struct cq_desc *desc_arg,
58 const struct cq_desc *desc = desc_arg; 59 const struct cq_desc *desc = desc_arg;
59 const u8 type_color = desc->type_color; 60 const u8 type_color = desc->type_color;
60 61
61 *color = (type_color >> CQ_DESC_TYPE_BITS) & CQ_DESC_COLOR_MASK; 62 *color = (type_color >> CQ_DESC_COLOR_SHIFT) & CQ_DESC_COLOR_MASK;
62 63
63 /* 64 /*
64 * Make sure color bit is read from desc *before* other fields 65 * Make sure color bit is read from desc *before* other fields
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 7f677e89a788..a832cc5d6a1e 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -33,7 +33,7 @@
33 33
34#define DRV_NAME "enic" 34#define DRV_NAME "enic"
35#define DRV_DESCRIPTION "Cisco 10G Ethernet Driver" 35#define DRV_DESCRIPTION "Cisco 10G Ethernet Driver"
36#define DRV_VERSION "0.0.1-18163.472-k1" 36#define DRV_VERSION "1.0.0.648"
37#define DRV_COPYRIGHT "Copyright 2008 Cisco Systems, Inc" 37#define DRV_COPYRIGHT "Copyright 2008 Cisco Systems, Inc"
38#define PFX DRV_NAME ": " 38#define PFX DRV_NAME ": "
39 39
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 180e968dc54d..d039e16f2763 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -273,6 +273,8 @@ static struct ethtool_ops enic_ethtool_ops = {
273 .set_sg = ethtool_op_set_sg, 273 .set_sg = ethtool_op_set_sg,
274 .get_tso = ethtool_op_get_tso, 274 .get_tso = ethtool_op_get_tso,
275 .set_tso = enic_set_tso, 275 .set_tso = enic_set_tso,
276 .get_flags = ethtool_op_get_flags,
277 .set_flags = ethtool_op_set_flags,
276}; 278};
277 279
278static void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf) 280static void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf)
@@ -409,8 +411,8 @@ static irqreturn_t enic_isr_legacy(int irq, void *data)
409 } 411 }
410 412
411 if (ENIC_TEST_INTR(pba, ENIC_INTX_WQ_RQ)) { 413 if (ENIC_TEST_INTR(pba, ENIC_INTX_WQ_RQ)) {
412 if (netif_rx_schedule_prep(netdev, &enic->napi)) 414 if (netif_rx_schedule_prep(&enic->napi))
413 __netif_rx_schedule(netdev, &enic->napi); 415 __netif_rx_schedule(&enic->napi);
414 } else { 416 } else {
415 vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]); 417 vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]);
416 } 418 }
@@ -438,7 +440,7 @@ static irqreturn_t enic_isr_msi(int irq, void *data)
438 * writes). 440 * writes).
439 */ 441 */
440 442
441 netif_rx_schedule(enic->netdev, &enic->napi); 443 netif_rx_schedule(&enic->napi);
442 444
443 return IRQ_HANDLED; 445 return IRQ_HANDLED;
444} 446}
@@ -448,7 +450,7 @@ static irqreturn_t enic_isr_msix_rq(int irq, void *data)
448 struct enic *enic = data; 450 struct enic *enic = data;
449 451
450 /* schedule NAPI polling for RQ cleanup */ 452 /* schedule NAPI polling for RQ cleanup */
451 netif_rx_schedule(enic->netdev, &enic->napi); 453 netif_rx_schedule(&enic->napi);
452 454
453 return IRQ_HANDLED; 455 return IRQ_HANDLED;
454} 456}
@@ -895,6 +897,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
895 int skipped, void *opaque) 897 int skipped, void *opaque)
896{ 898{
897 struct enic *enic = vnic_dev_priv(rq->vdev); 899 struct enic *enic = vnic_dev_priv(rq->vdev);
900 struct net_device *netdev = enic->netdev;
898 struct sk_buff *skb; 901 struct sk_buff *skb;
899 902
900 u8 type, color, eop, sop, ingress_port, vlan_stripped; 903 u8 type, color, eop, sop, ingress_port, vlan_stripped;
@@ -929,7 +932,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
929 if (net_ratelimit()) 932 if (net_ratelimit())
930 printk(KERN_ERR PFX 933 printk(KERN_ERR PFX
931 "%s: packet error: bad FCS\n", 934 "%s: packet error: bad FCS\n",
932 enic->netdev->name); 935 netdev->name);
933 } 936 }
934 937
935 dev_kfree_skb_any(skb); 938 dev_kfree_skb_any(skb);
@@ -943,19 +946,18 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
943 */ 946 */
944 947
945 skb_put(skb, bytes_written); 948 skb_put(skb, bytes_written);
946 skb->protocol = eth_type_trans(skb, enic->netdev); 949 skb->protocol = eth_type_trans(skb, netdev);
947 950
948 if (enic->csum_rx_enabled && !csum_not_calc) { 951 if (enic->csum_rx_enabled && !csum_not_calc) {
949 skb->csum = htons(checksum); 952 skb->csum = htons(checksum);
950 skb->ip_summed = CHECKSUM_COMPLETE; 953 skb->ip_summed = CHECKSUM_COMPLETE;
951 } 954 }
952 955
953 skb->dev = enic->netdev; 956 skb->dev = netdev;
954 enic->netdev->last_rx = jiffies;
955 957
956 if (enic->vlan_group && vlan_stripped) { 958 if (enic->vlan_group && vlan_stripped) {
957 959
958 if (ENIC_SETTING(enic, LRO) && ipv4) 960 if ((netdev->features & NETIF_F_LRO) && ipv4)
959 lro_vlan_hwaccel_receive_skb(&enic->lro_mgr, 961 lro_vlan_hwaccel_receive_skb(&enic->lro_mgr,
960 skb, enic->vlan_group, 962 skb, enic->vlan_group,
961 vlan, cq_desc); 963 vlan, cq_desc);
@@ -965,7 +967,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
965 967
966 } else { 968 } else {
967 969
968 if (ENIC_SETTING(enic, LRO) && ipv4) 970 if ((netdev->features & NETIF_F_LRO) && ipv4)
969 lro_receive_skb(&enic->lro_mgr, skb, cq_desc); 971 lro_receive_skb(&enic->lro_mgr, skb, cq_desc);
970 else 972 else
971 netif_receive_skb(skb); 973 netif_receive_skb(skb);
@@ -1063,10 +1065,10 @@ static int enic_poll(struct napi_struct *napi, int budget)
1063 /* If no work done, flush all LROs and exit polling 1065 /* If no work done, flush all LROs and exit polling
1064 */ 1066 */
1065 1067
1066 if (ENIC_SETTING(enic, LRO)) 1068 if (netdev->features & NETIF_F_LRO)
1067 lro_flush_all(&enic->lro_mgr); 1069 lro_flush_all(&enic->lro_mgr);
1068 1070
1069 netif_rx_complete(netdev, napi); 1071 netif_rx_complete(napi);
1070 vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]); 1072 vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]);
1071 } 1073 }
1072 1074
@@ -1107,10 +1109,10 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
1107 /* If no work done, flush all LROs and exit polling 1109 /* If no work done, flush all LROs and exit polling
1108 */ 1110 */
1109 1111
1110 if (ENIC_SETTING(enic, LRO)) 1112 if (netdev->features & NETIF_F_LRO)
1111 lro_flush_all(&enic->lro_mgr); 1113 lro_flush_all(&enic->lro_mgr);
1112 1114
1113 netif_rx_complete(netdev, napi); 1115 netif_rx_complete(napi);
1114 vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]); 1116 vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]);
1115 } 1117 }
1116 1118
@@ -1591,6 +1593,23 @@ static void enic_iounmap(struct enic *enic)
1591 iounmap(enic->bar0.vaddr); 1593 iounmap(enic->bar0.vaddr);
1592} 1594}
1593 1595
1596static const struct net_device_ops enic_netdev_ops = {
1597 .ndo_open = enic_open,
1598 .ndo_stop = enic_stop,
1599 .ndo_start_xmit = enic_hard_start_xmit,
1600 .ndo_get_stats = enic_get_stats,
1601 .ndo_validate_addr = eth_validate_addr,
1602 .ndo_set_multicast_list = enic_set_multicast_list,
1603 .ndo_change_mtu = enic_change_mtu,
1604 .ndo_vlan_rx_register = enic_vlan_rx_register,
1605 .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid,
1606 .ndo_vlan_rx_kill_vid = enic_vlan_rx_kill_vid,
1607 .ndo_tx_timeout = enic_tx_timeout,
1608#ifdef CONFIG_NET_POLL_CONTROLLER
1609 .ndo_poll_controller = enic_poll_controller,
1610#endif
1611};
1612
1594static int __devinit enic_probe(struct pci_dev *pdev, 1613static int __devinit enic_probe(struct pci_dev *pdev,
1595 const struct pci_device_id *ent) 1614 const struct pci_device_id *ent)
1596{ 1615{
@@ -1746,13 +1765,13 @@ static int __devinit enic_probe(struct pci_dev *pdev,
1746 } 1765 }
1747 1766
1748 /* Get available resource counts 1767 /* Get available resource counts
1749 */ 1768 */
1750 1769
1751 enic_get_res_counts(enic); 1770 enic_get_res_counts(enic);
1752 1771
1753 /* Set interrupt mode based on resource counts and system 1772 /* Set interrupt mode based on resource counts and system
1754 * capabilities 1773 * capabilities
1755 */ 1774 */
1756 1775
1757 err = enic_set_intr_mode(enic); 1776 err = enic_set_intr_mode(enic);
1758 if (err) { 1777 if (err) {
@@ -1814,21 +1833,9 @@ static int __devinit enic_probe(struct pci_dev *pdev,
1814 goto err_out_free_vnic_resources; 1833 goto err_out_free_vnic_resources;
1815 } 1834 }
1816 1835
1817 netdev->open = enic_open; 1836 netdev->netdev_ops = &enic_netdev_ops;
1818 netdev->stop = enic_stop;
1819 netdev->hard_start_xmit = enic_hard_start_xmit;
1820 netdev->get_stats = enic_get_stats;
1821 netdev->set_multicast_list = enic_set_multicast_list;
1822 netdev->change_mtu = enic_change_mtu;
1823 netdev->vlan_rx_register = enic_vlan_rx_register;
1824 netdev->vlan_rx_add_vid = enic_vlan_rx_add_vid;
1825 netdev->vlan_rx_kill_vid = enic_vlan_rx_kill_vid;
1826 netdev->tx_timeout = enic_tx_timeout;
1827 netdev->watchdog_timeo = 2 * HZ; 1837 netdev->watchdog_timeo = 2 * HZ;
1828 netdev->ethtool_ops = &enic_ethtool_ops; 1838 netdev->ethtool_ops = &enic_ethtool_ops;
1829#ifdef CONFIG_NET_POLL_CONTROLLER
1830 netdev->poll_controller = enic_poll_controller;
1831#endif
1832 1839
1833 switch (vnic_dev_get_intr_mode(enic->vdev)) { 1840 switch (vnic_dev_get_intr_mode(enic->vdev)) {
1834 default: 1841 default:
@@ -1845,22 +1852,23 @@ static int __devinit enic_probe(struct pci_dev *pdev,
1845 if (ENIC_SETTING(enic, TSO)) 1852 if (ENIC_SETTING(enic, TSO))
1846 netdev->features |= NETIF_F_TSO | 1853 netdev->features |= NETIF_F_TSO |
1847 NETIF_F_TSO6 | NETIF_F_TSO_ECN; 1854 NETIF_F_TSO6 | NETIF_F_TSO_ECN;
1855 if (ENIC_SETTING(enic, LRO))
1856 netdev->features |= NETIF_F_LRO;
1848 if (using_dac) 1857 if (using_dac)
1849 netdev->features |= NETIF_F_HIGHDMA; 1858 netdev->features |= NETIF_F_HIGHDMA;
1850 1859
1851 1860
1852 enic->csum_rx_enabled = ENIC_SETTING(enic, RXCSUM); 1861 enic->csum_rx_enabled = ENIC_SETTING(enic, RXCSUM);
1853 1862
1854 if (ENIC_SETTING(enic, LRO)) { 1863 enic->lro_mgr.max_aggr = ENIC_LRO_MAX_AGGR;
1855 enic->lro_mgr.max_aggr = ENIC_LRO_MAX_AGGR; 1864 enic->lro_mgr.max_desc = ENIC_LRO_MAX_DESC;
1856 enic->lro_mgr.max_desc = ENIC_LRO_MAX_DESC; 1865 enic->lro_mgr.lro_arr = enic->lro_desc;
1857 enic->lro_mgr.lro_arr = enic->lro_desc; 1866 enic->lro_mgr.get_skb_header = enic_get_skb_header;
1858 enic->lro_mgr.get_skb_header = enic_get_skb_header; 1867 enic->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
1859 enic->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID; 1868 enic->lro_mgr.dev = netdev;
1860 enic->lro_mgr.dev = netdev; 1869 enic->lro_mgr.ip_summed = CHECKSUM_COMPLETE;
1861 enic->lro_mgr.ip_summed = CHECKSUM_COMPLETE; 1870 enic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
1862 enic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY; 1871
1863 }
1864 1872
1865 err = register_netdev(netdev); 1873 err = register_netdev(netdev);
1866 if (err) { 1874 if (err) {
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 95184b9108ef..e5fc9384f8f5 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -90,11 +90,8 @@ int enic_get_vnic_config(struct enic *enic)
90 90
91 c->intr_timer = min_t(u16, VNIC_INTR_TIMER_MAX, c->intr_timer); 91 c->intr_timer = min_t(u16, VNIC_INTR_TIMER_MAX, c->intr_timer);
92 92
93 printk(KERN_INFO PFX "vNIC MAC addr %02x:%02x:%02x:%02x:%02x:%02x " 93 printk(KERN_INFO PFX "vNIC MAC addr %pM wq/rq %d/%d\n",
94 "wq/rq %d/%d\n", 94 enic->mac_addr, c->wq_desc_count, c->rq_desc_count);
95 enic->mac_addr[0], enic->mac_addr[1], enic->mac_addr[2],
96 enic->mac_addr[3], enic->mac_addr[4], enic->mac_addr[5],
97 c->wq_desc_count, c->rq_desc_count);
98 printk(KERN_INFO PFX "vNIC mtu %d csum tx/rx %d/%d tso/lro %d/%d " 95 printk(KERN_INFO PFX "vNIC mtu %d csum tx/rx %d/%d tso/lro %d/%d "
99 "intr timer %d\n", 96 "intr timer %d\n",
100 c->mtu, ENIC_SETTING(enic, TXCSUM), 97 c->mtu, ENIC_SETTING(enic, TXCSUM),
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 68534a29b7ac..7bf272fa859b 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -58,8 +58,6 @@ static inline void enic_queue_wq_desc_ex(struct vnic_wq *wq,
58 (u16)vlan_tag, 58 (u16)vlan_tag,
59 0 /* loopback */); 59 0 /* loopback */);
60 60
61 wmb();
62
63 vnic_wq_post(wq, os_buf, dma_addr, len, sop, eop); 61 vnic_wq_post(wq, os_buf, dma_addr, len, sop, eop);
64} 62}
65 63
@@ -127,8 +125,6 @@ static inline void enic_queue_rq_desc(struct vnic_rq *rq,
127 (u64)dma_addr | VNIC_PADDR_TARGET, 125 (u64)dma_addr | VNIC_PADDR_TARGET,
128 type, (u16)len); 126 type, (u16)len);
129 127
130 wmb();
131
132 vnic_rq_post(rq, os_buf, os_buf_index, dma_addr, len); 128 vnic_rq_post(rq, os_buf, os_buf_index, dma_addr, len);
133} 129}
134 130
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index 4d104f5c30f9..11708579b6ce 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -43,6 +43,7 @@ struct vnic_dev {
43 struct vnic_devcmd_notify *notify; 43 struct vnic_devcmd_notify *notify;
44 struct vnic_devcmd_notify notify_copy; 44 struct vnic_devcmd_notify notify_copy;
45 dma_addr_t notify_pa; 45 dma_addr_t notify_pa;
46 u32 notify_sz;
46 u32 *linkstatus; 47 u32 *linkstatus;
47 dma_addr_t linkstatus_pa; 48 dma_addr_t linkstatus_pa;
48 struct vnic_stats *stats; 49 struct vnic_stats *stats;
@@ -235,14 +236,6 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
235 struct vnic_devcmd __iomem *devcmd = vdev->devcmd; 236 struct vnic_devcmd __iomem *devcmd = vdev->devcmd;
236 int delay; 237 int delay;
237 u32 status; 238 u32 status;
238 int dev_cmd_err[] = {
239 /* convert from fw's version of error.h to host's version */
240 0, /* ERR_SUCCESS */
241 EINVAL, /* ERR_EINVAL */
242 EFAULT, /* ERR_EFAULT */
243 EPERM, /* ERR_EPERM */
244 EBUSY, /* ERR_EBUSY */
245 };
246 int err; 239 int err;
247 240
248 status = ioread32(&devcmd->status); 241 status = ioread32(&devcmd->status);
@@ -270,10 +263,12 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
270 if (!(status & STAT_BUSY)) { 263 if (!(status & STAT_BUSY)) {
271 264
272 if (status & STAT_ERROR) { 265 if (status & STAT_ERROR) {
273 err = dev_cmd_err[(int)readq(&devcmd->args[0])]; 266 err = (int)readq(&devcmd->args[0]);
274 printk(KERN_ERR "Error %d devcmd %d\n", 267 if (err != ERR_ECMDUNKNOWN ||
275 err, _CMD_N(cmd)); 268 cmd != CMD_CAPABILITY)
276 return -err; 269 printk(KERN_ERR "Error %d devcmd %d\n",
270 err, _CMD_N(cmd));
271 return err;
277 } 272 }
278 273
279 if (_CMD_DIR(cmd) & _CMD_DIR_READ) { 274 if (_CMD_DIR(cmd) & _CMD_DIR_READ) {
@@ -290,6 +285,17 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
290 return -ETIMEDOUT; 285 return -ETIMEDOUT;
291} 286}
292 287
288static int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd)
289{
290 u64 a0 = (u32)cmd, a1 = 0;
291 int wait = 1000;
292 int err;
293
294 err = vnic_dev_cmd(vdev, CMD_CAPABILITY, &a0, &a1, wait);
295
296 return !(err || a0);
297}
298
293int vnic_dev_fw_info(struct vnic_dev *vdev, 299int vnic_dev_fw_info(struct vnic_dev *vdev,
294 struct vnic_devcmd_fw_info **fw_info) 300 struct vnic_devcmd_fw_info **fw_info)
295{ 301{
@@ -489,10 +495,7 @@ void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
489 495
490 err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait); 496 err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
491 if (err) 497 if (err)
492 printk(KERN_ERR 498 printk(KERN_ERR "Can't add addr [%pM], %d\n", addr, err);
493 "Can't add addr [%02x:%02x:%02x:%02x:%02x:%02x], %d\n",
494 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
495 err);
496} 499}
497 500
498void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr) 501void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
@@ -507,16 +510,14 @@ void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
507 510
508 err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait); 511 err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait);
509 if (err) 512 if (err)
510 printk(KERN_ERR 513 printk(KERN_ERR "Can't del addr [%pM], %d\n", addr, err);
511 "Can't del addr [%02x:%02x:%02x:%02x:%02x:%02x], %d\n",
512 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
513 err);
514} 514}
515 515
516int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) 516int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
517{ 517{
518 u64 a0, a1; 518 u64 a0, a1;
519 int wait = 1000; 519 int wait = 1000;
520 int r;
520 521
521 if (!vdev->notify) { 522 if (!vdev->notify) {
522 vdev->notify = pci_alloc_consistent(vdev->pdev, 523 vdev->notify = pci_alloc_consistent(vdev->pdev,
@@ -524,13 +525,16 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
524 &vdev->notify_pa); 525 &vdev->notify_pa);
525 if (!vdev->notify) 526 if (!vdev->notify)
526 return -ENOMEM; 527 return -ENOMEM;
528 memset(vdev->notify, 0, sizeof(struct vnic_devcmd_notify));
527 } 529 }
528 530
529 a0 = vdev->notify_pa; 531 a0 = vdev->notify_pa;
530 a1 = ((u64)intr << 32) & 0x0000ffff00000000ULL; 532 a1 = ((u64)intr << 32) & 0x0000ffff00000000ULL;
531 a1 += sizeof(struct vnic_devcmd_notify); 533 a1 += sizeof(struct vnic_devcmd_notify);
532 534
533 return vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait); 535 r = vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);
536 vdev->notify_sz = (r == 0) ? (u32)a1 : 0;
537 return r;
534} 538}
535 539
536void vnic_dev_notify_unset(struct vnic_dev *vdev) 540void vnic_dev_notify_unset(struct vnic_dev *vdev)
@@ -543,22 +547,22 @@ void vnic_dev_notify_unset(struct vnic_dev *vdev)
543 a1 += sizeof(struct vnic_devcmd_notify); 547 a1 += sizeof(struct vnic_devcmd_notify);
544 548
545 vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait); 549 vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);
550 vdev->notify_sz = 0;
546} 551}
547 552
548static int vnic_dev_notify_ready(struct vnic_dev *vdev) 553static int vnic_dev_notify_ready(struct vnic_dev *vdev)
549{ 554{
550 u32 *words; 555 u32 *words;
551 unsigned int nwords = sizeof(struct vnic_devcmd_notify) / 4; 556 unsigned int nwords = vdev->notify_sz / 4;
552 unsigned int i; 557 unsigned int i;
553 u32 csum; 558 u32 csum;
554 559
555 if (!vdev->notify) 560 if (!vdev->notify || !vdev->notify_sz)
556 return 0; 561 return 0;
557 562
558 do { 563 do {
559 csum = 0; 564 csum = 0;
560 memcpy(&vdev->notify_copy, vdev->notify, 565 memcpy(&vdev->notify_copy, vdev->notify, vdev->notify_sz);
561 sizeof(struct vnic_devcmd_notify));
562 words = (u32 *)&vdev->notify_copy; 566 words = (u32 *)&vdev->notify_copy;
563 for (i = 1; i < nwords; i++) 567 for (i = 1; i < nwords; i++)
564 csum += words[i]; 568 csum += words[i];
@@ -571,7 +575,20 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg)
571{ 575{
572 u64 a0 = (u32)arg, a1 = 0; 576 u64 a0 = (u32)arg, a1 = 0;
573 int wait = 1000; 577 int wait = 1000;
574 return vnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait); 578 int r = 0;
579
580 if (vnic_dev_capable(vdev, CMD_INIT))
581 r = vnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait);
582 else {
583 vnic_dev_cmd(vdev, CMD_INIT_v1, &a0, &a1, wait);
584 if (a0 & CMD_INITF_DEFAULT_MAC) {
585 // Emulate these for old CMD_INIT_v1 which
586 // didn't pass a0 so no CMD_INITF_*.
587 vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait);
588 vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
589 }
590 }
591 return r;
575} 592}
576 593
577int vnic_dev_link_status(struct vnic_dev *vdev) 594int vnic_dev_link_status(struct vnic_dev *vdev)
@@ -672,3 +689,4 @@ err_out:
672 return NULL; 689 return NULL;
673} 690}
674 691
692
diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h
index d8617a3373b1..8062c75154e6 100644
--- a/drivers/net/enic/vnic_devcmd.h
+++ b/drivers/net/enic/vnic_devcmd.h
@@ -168,7 +168,8 @@ enum vnic_devcmd_cmd {
168 CMD_CLOSE = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 25), 168 CMD_CLOSE = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 25),
169 169
170 /* initialize virtual link: (u32)a0=flags (see CMD_INITF_*) */ 170 /* initialize virtual link: (u32)a0=flags (see CMD_INITF_*) */
171 CMD_INIT = _CMDCNW(_CMD_DIR_READ, _CMD_VTYPE_ALL, 26), 171/***** Replaced by CMD_INIT *****/
172 CMD_INIT_v1 = _CMDCNW(_CMD_DIR_READ, _CMD_VTYPE_ALL, 26),
172 173
173 /* variant of CMD_INIT, with provisioning info 174 /* variant of CMD_INIT, with provisioning info
174 * (u64)a0=paddr of vnic_devcmd_provinfo 175 * (u64)a0=paddr of vnic_devcmd_provinfo
@@ -198,6 +199,14 @@ enum vnic_devcmd_cmd {
198 199
199 /* undo initialize of virtual link */ 200 /* undo initialize of virtual link */
200 CMD_DEINIT = _CMDCNW(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 34), 201 CMD_DEINIT = _CMDCNW(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 34),
202
203 /* initialize virtual link: (u32)a0=flags (see CMD_INITF_*) */
204 CMD_INIT = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 35),
205
206 /* check fw capability of a cmd:
207 * in: (u32)a0=cmd
208 * out: (u32)a0=errno, 0:valid cmd, a1=supported VNIC_STF_* bits */
209 CMD_CAPABILITY = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 36),
201}; 210};
202 211
203/* flags for CMD_OPEN */ 212/* flags for CMD_OPEN */
@@ -249,8 +258,16 @@ struct vnic_devcmd_notify {
249 u32 uif; /* uplink interface */ 258 u32 uif; /* uplink interface */
250 u32 status; /* status bits (see VNIC_STF_*) */ 259 u32 status; /* status bits (see VNIC_STF_*) */
251 u32 error; /* error code (see ERR_*) for first ERR */ 260 u32 error; /* error code (see ERR_*) for first ERR */
261 u32 link_down_cnt; /* running count of link down transitions */
252}; 262};
253#define VNIC_STF_FATAL_ERR 0x0001 /* fatal fw error */ 263#define VNIC_STF_FATAL_ERR 0x0001 /* fatal fw error */
264#define VNIC_STF_STD_PAUSE 0x0002 /* standard link-level pause on */
265#define VNIC_STF_PFC_PAUSE 0x0004 /* priority flow control pause on */
266/* all supported status flags */
267#define VNIC_STF_ALL (VNIC_STF_FATAL_ERR |\
268 VNIC_STF_STD_PAUSE |\
269 VNIC_STF_PFC_PAUSE |\
270 0)
254 271
255struct vnic_devcmd_provinfo { 272struct vnic_devcmd_provinfo {
256 u8 oui[3]; 273 u8 oui[3];
diff --git a/drivers/net/enic/vnic_intr.h b/drivers/net/enic/vnic_intr.h
index ccc408116af8..ce633a5a7e3c 100644
--- a/drivers/net/enic/vnic_intr.h
+++ b/drivers/net/enic/vnic_intr.h
@@ -78,7 +78,7 @@ static inline void vnic_intr_return_credits(struct vnic_intr *intr,
78 78
79static inline u32 vnic_intr_legacy_pba(u32 __iomem *legacy_pba) 79static inline u32 vnic_intr_legacy_pba(u32 __iomem *legacy_pba)
80{ 80{
81 /* get and ack interrupt in one read (clear-and-ack-on-read) */ 81 /* read PBA without clearing */
82 return ioread32(legacy_pba); 82 return ioread32(legacy_pba);
83} 83}
84 84
diff --git a/drivers/net/enic/vnic_resource.h b/drivers/net/enic/vnic_resource.h
index 144d2812f081..b61c22aec41a 100644
--- a/drivers/net/enic/vnic_resource.h
+++ b/drivers/net/enic/vnic_resource.h
@@ -38,7 +38,7 @@ enum vnic_res_type {
38 RES_TYPE_INTR_CTRL, /* Interrupt ctrl table */ 38 RES_TYPE_INTR_CTRL, /* Interrupt ctrl table */
39 RES_TYPE_INTR_TABLE, /* MSI/MSI-X Interrupt table */ 39 RES_TYPE_INTR_TABLE, /* MSI/MSI-X Interrupt table */
40 RES_TYPE_INTR_PBA, /* MSI/MSI-X PBA table */ 40 RES_TYPE_INTR_PBA, /* MSI/MSI-X PBA table */
41 RES_TYPE_INTR_PBA_LEGACY, /* Legacy intr status, r2c */ 41 RES_TYPE_INTR_PBA_LEGACY, /* Legacy intr status */
42 RES_TYPE_RSVD6, 42 RES_TYPE_RSVD6,
43 RES_TYPE_RSVD7, 43 RES_TYPE_RSVD7,
44 RES_TYPE_DEVCMD, /* Device command region */ 44 RES_TYPE_DEVCMD, /* Device command region */
diff --git a/drivers/net/enic/vnic_rq.h b/drivers/net/enic/vnic_rq.h
index 82bfca67cc4d..fd0ef66d2e9f 100644
--- a/drivers/net/enic/vnic_rq.h
+++ b/drivers/net/enic/vnic_rq.h
@@ -132,8 +132,15 @@ static inline void vnic_rq_post(struct vnic_rq *rq,
132#define VNIC_RQ_RETURN_RATE 0xf /* keep 2^n - 1 */ 132#define VNIC_RQ_RETURN_RATE 0xf /* keep 2^n - 1 */
133#endif 133#endif
134 134
135 if ((buf->index & VNIC_RQ_RETURN_RATE) == 0) 135 if ((buf->index & VNIC_RQ_RETURN_RATE) == 0) {
136 /* Adding write memory barrier prevents compiler and/or CPU
137 * reordering, thus avoiding descriptor posting before
138 * descriptor is initialized. Otherwise, hardware can read
139 * stale descriptor fields.
140 */
141 wmb();
136 iowrite32(buf->index, &rq->ctrl->posted_index); 142 iowrite32(buf->index, &rq->ctrl->posted_index);
143 }
137} 144}
138 145
139static inline void vnic_rq_return_descs(struct vnic_rq *rq, unsigned int count) 146static inline void vnic_rq_return_descs(struct vnic_rq *rq, unsigned int count)
diff --git a/drivers/net/enic/vnic_rss.h b/drivers/net/enic/vnic_rss.h
index e325d65d7c34..5fbb3c923bcd 100644
--- a/drivers/net/enic/vnic_rss.h
+++ b/drivers/net/enic/vnic_rss.h
@@ -1,6 +1,19 @@
1/* 1/*
2 * Copyright 2008 Cisco Systems, Inc. All rights reserved. 2 * Copyright 2008 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved. 3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
4 */ 17 */
5 18
6#ifndef _VNIC_RSS_H_ 19#ifndef _VNIC_RSS_H_
diff --git a/drivers/net/enic/vnic_wq.h b/drivers/net/enic/vnic_wq.h
index 7081828d8a42..c826137dc651 100644
--- a/drivers/net/enic/vnic_wq.h
+++ b/drivers/net/enic/vnic_wq.h
@@ -108,8 +108,15 @@ static inline void vnic_wq_post(struct vnic_wq *wq,
108 buf->len = len; 108 buf->len = len;
109 109
110 buf = buf->next; 110 buf = buf->next;
111 if (eop) 111 if (eop) {
112 /* Adding write memory barrier prevents compiler and/or CPU
113 * reordering, thus avoiding descriptor posting before
114 * descriptor is initialized. Otherwise, hardware can read
115 * stale descriptor fields.
116 */
117 wmb();
112 iowrite32(buf->index, &wq->ctrl->posted_index); 118 iowrite32(buf->index, &wq->ctrl->posted_index);
119 }
113 wq->to_use = buf; 120 wq->to_use = buf;
114 121
115 wq->ring.desc_avail--; 122 wq->ring.desc_avail--;