]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/ethernet/emulex/benet/be_main.c
be2net: Avoid flashing BE3 UFI on BE3-R chip.
[karo-tx-linux.git] / drivers / net / ethernet / emulex / benet / be_main.c
index 08e54f3d288bc9a2e23faa8bb954dcb4bd8cf584..c70b8fff8cff8abd44528647117a2e6c6ed12bbd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 - 2011 Emulex
+ * Copyright (C) 2005 - 2013 Emulex
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -146,20 +146,16 @@ static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q,
        q->entry_size = entry_size;
        mem->size = len * entry_size;
        mem->va = dma_alloc_coherent(&adapter->pdev->dev, mem->size, &mem->dma,
-                                    GFP_KERNEL);
+                                    GFP_KERNEL | __GFP_ZERO);
        if (!mem->va)
                return -ENOMEM;
-       memset(mem->va, 0, mem->size);
        return 0;
 }
 
-static void be_intr_set(struct be_adapter *adapter, bool enable)
+static void be_reg_intr_set(struct be_adapter *adapter, bool enable)
 {
        u32 reg, enabled;
 
-       if (adapter->eeh_error)
-               return;
-
        pci_read_config_dword(adapter->pdev, PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET,
                                &reg);
        enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
@@ -175,6 +171,22 @@ static void be_intr_set(struct be_adapter *adapter, bool enable)
                        PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET, reg);
 }
 
+static void be_intr_set(struct be_adapter *adapter, bool enable)
+{
+       int status = 0;
+
+       /* On lancer interrupts can't be controlled via this register */
+       if (lancer_chip(adapter))
+               return;
+
+       if (adapter->eeh_error)
+               return;
+
+       status = be_cmd_intr_set(adapter, enable);
+       if (status)
+               be_reg_intr_set(adapter, enable);
+}
+
 static void be_rxq_notify(struct be_adapter *adapter, u16 qid, u16 posted)
 {
        u32 val = 0;
@@ -185,14 +197,15 @@ static void be_rxq_notify(struct be_adapter *adapter, u16 qid, u16 posted)
        iowrite32(val, adapter->db + DB_RQ_OFFSET);
 }
 
-static void be_txq_notify(struct be_adapter *adapter, u16 qid, u16 posted)
+static void be_txq_notify(struct be_adapter *adapter, struct be_tx_obj *txo,
+                         u16 posted)
 {
        u32 val = 0;
-       val |= qid & DB_TXULP_RING_ID_MASK;
+       val |= txo->q.id & DB_TXULP_RING_ID_MASK;
        val |= (posted & DB_TXULP_NUM_POSTED_MASK) << DB_TXULP_NUM_POSTED_SHIFT;
 
        wmb();
-       iowrite32(val, adapter->db + DB_TXULP1_OFFSET);
+       iowrite32(val, adapter->db + txo->db_offset);
 }
 
 static void be_eq_notify(struct be_adapter *adapter, u16 qid,
@@ -759,7 +772,7 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter,
 
        if (vlan_tx_tag_present(skb)) {
                vlan_tag = be_get_tx_vlan_tag(adapter, skb);
-               __vlan_put_tag(skb, vlan_tag);
+               __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
                skb->vlan_tci = 0;
        }
 
@@ -821,7 +834,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb,
                        stopped = true;
                }
 
-               be_txq_notify(adapter, txq->id, wrb_cnt);
+               be_txq_notify(adapter, txo, wrb_cnt);
 
                be_tx_stats_update(txo, wrb_cnt, copied, gso_segs, stopped);
        } else {
@@ -890,7 +903,7 @@ set_vlan_promisc:
        return status;
 }
 
-static int be_vlan_add_vid(struct net_device *netdev, u16 vid)
+static int be_vlan_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
 {
        struct be_adapter *adapter = netdev_priv(netdev);
        int status = 0;
@@ -916,7 +929,7 @@ ret:
        return status;
 }
 
-static int be_vlan_rem_vid(struct net_device *netdev, u16 vid)
+static int be_vlan_rem_vid(struct net_device *netdev, __be16 proto, u16 vid)
 {
        struct be_adapter *adapter = netdev_priv(netdev);
        int status = 0;
@@ -1371,7 +1384,7 @@ static void be_rx_compl_process(struct be_rx_obj *rxo,
 
 
        if (rxcp->vlanf)
-               __vlan_hwaccel_put_tag(skb, rxcp->vlan_tag);
+               __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), rxcp->vlan_tag);
 
        netif_receive_skb(skb);
 }
@@ -1427,7 +1440,7 @@ void be_rx_compl_process_gro(struct be_rx_obj *rxo, struct napi_struct *napi,
                skb->rxhash = rxcp->rss_hash;
 
        if (rxcp->vlanf)
-               __vlan_hwaccel_put_tag(skb, rxcp->vlan_tag);
+               __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), rxcp->vlan_tag);
 
        napi_gro_frags(napi);
 }
@@ -1957,7 +1970,7 @@ static int be_tx_qs_create(struct be_adapter *adapter)
                if (status)
                        return status;
 
-               status = be_cmd_txq_create(adapter, &txo->q, &txo->cq);
+               status = be_cmd_txq_create(adapter, txo);
                if (status)
                        return status;
        }
@@ -2435,9 +2448,6 @@ static int be_close(struct net_device *netdev)
 
        be_roce_dev_close(adapter);
 
-       if (!lancer_chip(adapter))
-               be_intr_set(adapter, false);
-
        for_all_evt_queues(adapter, eqo, i)
                napi_disable(&eqo->napi);
 
@@ -2525,9 +2535,6 @@ static int be_open(struct net_device *netdev)
 
        be_irq_register(adapter);
 
-       if (!lancer_chip(adapter))
-               be_intr_set(adapter, true);
-
        for_all_rx_queues(adapter, rxo, i)
                be_cq_notify(adapter, rxo->cq.id, true, 0);
 
@@ -2562,10 +2569,9 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable)
 
        cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config);
        cmd.va = dma_alloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
-                                   GFP_KERNEL);
+                                   GFP_KERNEL | __GFP_ZERO);
        if (cmd.va == NULL)
                return -1;
-       memset(cmd.va, 0, cmd.size);
 
        if (enable) {
                status = pci_write_config_dword(adapter->pdev,
@@ -2953,7 +2959,8 @@ static int be_get_config(struct be_adapter *adapter)
 
        status = be_cmd_query_fw_cfg(adapter, &adapter->port_num,
                                     &adapter->function_mode,
-                                    &adapter->function_caps);
+                                    &adapter->function_caps,
+                                    &adapter->asic_rev);
        if (status)
                goto err;
 
@@ -3214,7 +3221,7 @@ static int be_flash(struct be_adapter *adapter, const u8 *img,
        return 0;
 }
 
-/* For BE2 and BE3 */
+/* For BE2, BE3 and BE3-R */
 static int be_flash_BEx(struct be_adapter *adapter,
                         const struct firmware *fw,
                         struct be_dma_mem *flash_cmd,
@@ -3457,11 +3464,9 @@ static int lancer_fw_download(struct be_adapter *adapter,
        flash_cmd.size = sizeof(struct lancer_cmd_req_write_object)
                                + LANCER_FW_DOWNLOAD_CHUNK;
        flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
-                                               &flash_cmd.dma, GFP_KERNEL);
+                                         &flash_cmd.dma, GFP_KERNEL);
        if (!flash_cmd.va) {
                status = -ENOMEM;
-               dev_err(&adapter->pdev->dev,
-                       "Memory allocation failure while flashing\n");
                goto lancer_fw_exit;
        }
 
@@ -3529,18 +3534,22 @@ lancer_fw_exit:
 
 #define UFI_TYPE2              2
 #define UFI_TYPE3              3
+#define UFI_TYPE3R             10
 #define UFI_TYPE4              4
 static int be_get_ufi_type(struct be_adapter *adapter,
-                          struct flash_file_hdr_g2 *fhdr)
+                          struct flash_file_hdr_g3 *fhdr)
 {
        if (fhdr == NULL)
                goto be_get_ufi_exit;
 
        if (skyhawk_chip(adapter) && fhdr->build[0] == '4')
                return UFI_TYPE4;
-       else if (BE3_chip(adapter) && fhdr->build[0] == '3')
-               return UFI_TYPE3;
-       else if (BE2_chip(adapter) && fhdr->build[0] == '2')
+       else if (BE3_chip(adapter) && fhdr->build[0] == '3') {
+               if (fhdr->asic_type_rev == 0x10)
+                       return UFI_TYPE3R;
+               else
+                       return UFI_TYPE3;
+       } else if (BE2_chip(adapter) && fhdr->build[0] == '2')
                return UFI_TYPE2;
 
 be_get_ufi_exit:
@@ -3551,7 +3560,6 @@ be_get_ufi_exit:
 
 static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw)
 {
-       struct flash_file_hdr_g2 *fhdr;
        struct flash_file_hdr_g3 *fhdr3;
        struct image_hdr *img_hdr_ptr = NULL;
        struct be_dma_mem flash_cmd;
@@ -3563,29 +3571,41 @@ static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw)
                                          &flash_cmd.dma, GFP_KERNEL);
        if (!flash_cmd.va) {
                status = -ENOMEM;
-               dev_err(&adapter->pdev->dev,
-                       "Memory allocation failure while flashing\n");
                goto be_fw_exit;
        }
 
        p = fw->data;
-       fhdr = (struct flash_file_hdr_g2 *)p;
+       fhdr3 = (struct flash_file_hdr_g3 *)p;
 
-       ufi_type = be_get_ufi_type(adapter, fhdr);
+       ufi_type = be_get_ufi_type(adapter, fhdr3);
 
-       fhdr3 = (struct flash_file_hdr_g3 *)fw->data;
        num_imgs = le32_to_cpu(fhdr3->num_imgs);
        for (i = 0; i < num_imgs; i++) {
                img_hdr_ptr = (struct image_hdr *)(fw->data +
                                (sizeof(struct flash_file_hdr_g3) +
                                 i * sizeof(struct image_hdr)));
                if (le32_to_cpu(img_hdr_ptr->imageid) == 1) {
-                       if (ufi_type == UFI_TYPE4)
+                       switch (ufi_type) {
+                       case UFI_TYPE4:
                                status = be_flash_skyhawk(adapter, fw,
                                                        &flash_cmd, num_imgs);
-                       else if (ufi_type == UFI_TYPE3)
+                               break;
+                       case UFI_TYPE3R:
                                status = be_flash_BEx(adapter, fw, &flash_cmd,
                                                      num_imgs);
+                               break;
+                       case UFI_TYPE3:
+                               /* Do not flash this ufi on BE3-R cards */
+                               if (adapter->asic_rev < 0x10)
+                                       status = be_flash_BEx(adapter, fw,
+                                                             &flash_cmd,
+                                                             num_imgs);
+                               else {
+                                       status = -1;
+                                       dev_err(&adapter->pdev->dev,
+                                               "Can't load BE3 UFI on BE3R\n");
+                               }
+                       }
                }
        }
 
@@ -3662,12 +3682,12 @@ static void be_netdev_init(struct net_device *netdev)
 
        netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
                NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
-               NETIF_F_HW_VLAN_TX;
+               NETIF_F_HW_VLAN_CTAG_TX;
        if (be_multi_rxq(adapter))
                netdev->hw_features |= NETIF_F_RXHASH;
 
        netdev->features |= netdev->hw_features |
-               NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
+               NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER;
 
        netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
                NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
@@ -3791,12 +3811,13 @@ static int be_ctrl_init(struct be_adapter *adapter)
 
        rx_filter->size = sizeof(struct be_cmd_req_rx_filter);
        rx_filter->va = dma_alloc_coherent(&adapter->pdev->dev, rx_filter->size,
-                                       &rx_filter->dma, GFP_KERNEL);
+                                          &rx_filter->dma,
+                                          GFP_KERNEL | __GFP_ZERO);
        if (rx_filter->va == NULL) {
                status = -ENOMEM;
                goto free_mbox;
        }
-       memset(rx_filter->va, 0, rx_filter->size);
+
        mutex_init(&adapter->mbox_lock);
        spin_lock_init(&adapter->mcc_lock);
        spin_lock_init(&adapter->mcc_cq_lock);
@@ -3838,10 +3859,9 @@ static int be_stats_init(struct be_adapter *adapter)
                cmd->size = sizeof(struct be_cmd_req_get_stats_v1);
 
        cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma,
-                                    GFP_KERNEL);
+                                    GFP_KERNEL | __GFP_ZERO);
        if (cmd->va == NULL)
                return -1;
-       memset(cmd->va, 0, cmd->size);
        return 0;
 }
 
@@ -3853,6 +3873,7 @@ static void be_remove(struct pci_dev *pdev)
                return;
 
        be_roce_dev_remove(adapter);
+       be_intr_set(adapter, false);
 
        cancel_delayed_work_sync(&adapter->func_recovery_work);
 
@@ -4142,11 +4163,11 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
                        goto ctrl_clean;
        }
 
-       /* The INTR bit may be set in the card when probed by a kdump kernel
-        * after a crash.
-        */
-       if (!lancer_chip(adapter))
-               be_intr_set(adapter, false);
+       /* Wait for interrupts to quiesce after an FLR */
+       msleep(100);
+
+       /* Allow interrupts for other ULPs running on NIC function */
+       be_intr_set(adapter, true);
 
        status = be_stats_init(adapter);
        if (status)