be2net: Fallback to the older opcode if MCC_CREATE_EXT opcode is not supported on...
authorSomnath Kotur <somnath.kotur@emulex.com>
Wed, 1 Jun 2011 00:33:22 +0000 (00:33 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 1 Jun 2011 05:15:28 +0000 (22:15 -0700)
Instead of failing the init/probe code in the driver fallback to the older opcode to ensure
the driver is loaded thereby enabling users to upgrade the f/w to whatever version is required.

Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/benet/be_cmds.c
drivers/net/benet/be_cmds.h
drivers/net/benet/be_main.c

index 81654ae16c63b99627046b4836e25ab0b1a05115..0c12c2d4532aa9c16936093e924d96c021da34d2 100644 (file)
@@ -799,12 +799,12 @@ static u32 be_encoded_q_len(int q_len)
        return len_encoded;
 }
 
-int be_cmd_mccq_create(struct be_adapter *adapter,
+int be_cmd_mccq_ext_create(struct be_adapter *adapter,
                        struct be_queue_info *mccq,
                        struct be_queue_info *cq)
 {
        struct be_mcc_wrb *wrb;
-       struct be_cmd_req_mcc_create *req;
+       struct be_cmd_req_mcc_ext_create *req;
        struct be_dma_mem *q_mem = &mccq->dma_mem;
        void *ctxt;
        int status;
@@ -859,6 +859,67 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
        return status;
 }
 
+int be_cmd_mccq_org_create(struct be_adapter *adapter,
+                       struct be_queue_info *mccq,
+                       struct be_queue_info *cq)
+{
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_mcc_create *req;
+       struct be_dma_mem *q_mem = &mccq->dma_mem;
+       void *ctxt;
+       int status;
+
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
+
+       wrb = wrb_from_mbox(adapter);
+       req = embedded_payload(wrb);
+       ctxt = &req->context;
+
+       be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+                       OPCODE_COMMON_MCC_CREATE);
+
+       be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+                       OPCODE_COMMON_MCC_CREATE, sizeof(*req));
+
+       req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
+
+       AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1);
+       AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt,
+                       be_encoded_q_len(mccq->len));
+       AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id);
+
+       be_dws_cpu_to_le(ctxt, sizeof(req->context));
+
+       be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
+
+       status = be_mbox_notify_wait(adapter);
+       if (!status) {
+               struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
+               mccq->id = le16_to_cpu(resp->id);
+               mccq->created = true;
+       }
+
+       mutex_unlock(&adapter->mbox_lock);
+       return status;
+}
+
+int be_cmd_mccq_create(struct be_adapter *adapter,
+                       struct be_queue_info *mccq,
+                       struct be_queue_info *cq)
+{
+       int status;
+
+       status = be_cmd_mccq_ext_create(adapter, mccq, cq);
+       if (status && !lancer_chip(adapter)) {
+               dev_warn(&adapter->pdev->dev, "Upgrade to F/W ver 2.102.235.0 "
+                       "or newer to avoid conflicting priorities between NIC "
+                       "and FCoE traffic");
+               status = be_cmd_mccq_org_create(adapter, mccq, cq);
+       }
+       return status;
+}
+
 int be_cmd_txq_create(struct be_adapter *adapter,
                        struct be_queue_info *txq,
                        struct be_queue_info *cq)
index 8148cc66cbe90350e358d468f40aabcced9e3f9a..d08289e21f61a8f5e113795b7fed86aaed61d455 100644 (file)
@@ -431,6 +431,14 @@ struct amap_mcc_context_lancer {
 } __packed;
 
 struct be_cmd_req_mcc_create {
+       struct be_cmd_req_hdr hdr;
+       u16 num_pages;
+       u16 cq_id;
+       u8 context[sizeof(struct amap_mcc_context_be) / 8];
+       struct phys_addr pages[8];
+} __packed;
+
+struct be_cmd_req_mcc_ext_create {
        struct be_cmd_req_hdr hdr;
        u16 num_pages;
        u16 cq_id;
index a485f7fdaf37a51c26ae01bf42e5d5f0a48ec222..5824c95c78439352872c30220b4e2196bedd1b52 100644 (file)
@@ -3396,6 +3396,11 @@ static int __devinit be_probe(struct pci_dev *pdev,
        }
 
        dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num);
+       /* By default all priorities are enabled.
+        * Needed in case of no GRP5 evt support
+        */
+       adapter->vlan_prio_bmap = 0xff;
+
        schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
        return 0;