]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/net/benet/be_cmds.c
be2net: Adding PCI SRIOV support
[net-next-2.6.git] / drivers / net / benet / be_cmds.c
index fee6eee7ae5ba583bf345a79a4be188fbdd2345d..9f53d9e86e2bd8b208c70db221479c958b48957b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -104,10 +104,26 @@ static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
        return NULL;
 }
 
-int be_process_mcc(struct be_adapter *adapter)
+void be_async_mcc_enable(struct be_adapter *adapter)
+{
+       spin_lock_bh(&adapter->mcc_cq_lock);
+
+       be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, 0);
+       adapter->mcc_obj.rearm_cq = true;
+
+       spin_unlock_bh(&adapter->mcc_cq_lock);
+}
+
+void be_async_mcc_disable(struct be_adapter *adapter)
+{
+       adapter->mcc_obj.rearm_cq = false;
+}
+
+int be_process_mcc(struct be_adapter *adapter, int *status)
 {
        struct be_mcc_compl *compl;
-       int num = 0, status = 0;
+       int num = 0;
+       struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
 
        spin_lock_bh(&adapter->mcc_cq_lock);
        while ((compl = be_mcc_compl_get(adapter))) {
@@ -119,31 +135,31 @@ int be_process_mcc(struct be_adapter *adapter)
                        be_async_link_state_process(adapter,
                                (struct be_async_event_link_state *) compl);
                } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
-                               status = be_mcc_compl_process(adapter, compl);
-                               atomic_dec(&adapter->mcc_obj.q.used);
+                               *status = be_mcc_compl_process(adapter, compl);
+                               atomic_dec(&mcc_obj->q.used);
                }
                be_mcc_compl_use(compl);
                num++;
        }
 
-       if (num)
-               be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, num);
-
        spin_unlock_bh(&adapter->mcc_cq_lock);
-       return status;
+       return num;
 }
 
 /* Wait till no more pending mcc requests are present */
 static int be_mcc_wait_compl(struct be_adapter *adapter)
 {
 #define mcc_timeout            120000 /* 12s timeout */
-       int i, status;
+       int i, num, status = 0;
+       struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
+
        for (i = 0; i < mcc_timeout; i++) {
-               status = be_process_mcc(adapter);
-               if (status)
-                       return status;
+               num = be_process_mcc(adapter, &status);
+               if (num)
+                       be_cq_notify(adapter, mcc_obj->cq.id,
+                               mcc_obj->rearm_cq, num);
 
-               if (atomic_read(&adapter->mcc_obj.q.used) == 0)
+               if (atomic_read(&mcc_obj->q.used) == 0)
                        break;
                udelay(100);
        }
@@ -151,7 +167,7 @@ static int be_mcc_wait_compl(struct be_adapter *adapter)
                dev_err(&adapter->pdev->dev, "mccq poll timed out\n");
                return -1;
        }
-       return 0;
+       return status;
 }
 
 /* Notify MCC requests and wait for completion */
@@ -167,7 +183,14 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
        u32 ready;
 
        do {
-               ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
+               ready = ioread32(db);
+               if (ready == 0xffffffff) {
+                       dev_err(&adapter->pdev->dev,
+                               "pci slot disconnected\n");
+                       return -1;
+               }
+
+               ready &= MPU_MAILBOX_DB_RDY_MASK;
                if (ready)
                        break;
 
@@ -198,6 +221,11 @@ static int be_mbox_notify_wait(struct be_adapter *adapter)
        struct be_mcc_mailbox *mbox = mbox_mem->va;
        struct be_mcc_compl *compl = &mbox->compl;
 
+       /* wait for ready to be set */
+       status = be_mbox_db_ready_wait(adapter, db);
+       if (status != 0)
+               return status;
+
        val |= MPU_MAILBOX_DB_HI_MASK;
        /* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
        val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
@@ -296,6 +324,7 @@ static void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
        req_hdr->opcode = opcode;
        req_hdr->subsystem = subsystem;
        req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
+       req_hdr->version = 0;
 }
 
 static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
@@ -396,6 +425,9 @@ int be_cmd_fw_clean(struct be_adapter *adapter)
        u8 *wrb;
        int status;
 
+       if (adapter->eeh_err)
+               return -EIO;
+
        spin_lock(&adapter->mbox_lock);
 
        wrb = (u8 *)wrb_from_mbox(adapter);
@@ -433,8 +465,6 @@ int be_cmd_eq_create(struct be_adapter *adapter,
 
        req->num_pages =  cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
 
-       AMAP_SET_BITS(struct amap_eq_context, func, req->context,
-                       be_pci_func(adapter));
        AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
        /* 4byte eqe*/
        AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
@@ -597,7 +627,6 @@ int be_cmd_cq_create(struct be_adapter *adapter,
        AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
        AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
        AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1);
-       AMAP_SET_BITS(struct amap_cq_context, func, ctxt, be_pci_func(adapter));
        be_dws_cpu_to_le(ctxt, sizeof(req->context));
 
        be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
@@ -644,9 +673,8 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
                        OPCODE_COMMON_MCC_CREATE, sizeof(*req));
 
-       req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
+       req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
 
-       AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt, be_pci_func(adapter));
        AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
        AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
                be_encoded_q_len(mccq->len));
@@ -695,8 +723,6 @@ int be_cmd_txq_create(struct be_adapter *adapter,
 
        AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt,
                be_encoded_q_len(txq->len));
-       AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt,
-                       be_pci_func(adapter));
        AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1);
        AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id);
 
@@ -768,6 +794,9 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
        u8 subsys = 0, opcode = 0;
        int status;
 
+       if (adapter->eeh_err)
+               return -EIO;
+
        spin_lock(&adapter->mbox_lock);
 
        wrb = wrb_from_mbox(adapter);
@@ -814,7 +843,8 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
  * Uses mbox
  */
 int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
-               u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id)
+               u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id,
+               u32 domain)
 {
        struct be_mcc_wrb *wrb;
        struct be_cmd_req_if_create *req;
@@ -831,6 +861,7 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
                OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req));
 
+       req->hdr.domain = domain;
        req->capability_flags = cpu_to_le32(cap_flags);
        req->enable_flags = cpu_to_le32(en_flags);
        req->pmac_invalid = pmac_invalid;
@@ -856,6 +887,9 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id)
        struct be_cmd_req_if_destroy *req;
        int status;
 
+       if (adapter->eeh_err)
+               return -EIO;
+
        spin_lock(&adapter->mbox_lock);
 
        wrb = wrb_from_mbox(adapter);
@@ -1096,8 +1130,7 @@ err:
  * (mc == NULL) => multicast promiscous
  */
 int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
-               struct dev_mc_list *mc_list, u32 mc_count,
-               struct be_dma_mem *mem)
+               struct net_device *netdev, struct be_dma_mem *mem)
 {
        struct be_mcc_wrb *wrb;
        struct be_cmd_req_mcast_mac_config *req = mem->va;
@@ -1124,13 +1157,14 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
                OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req));
 
        req->interface_id = if_id;
-       if (mc_list) {
+       if (netdev) {
                int i;
                struct dev_mc_list *mc;
 
-               req->num_mac = cpu_to_le16(mc_count);
+               req->num_mac = cpu_to_le16(netdev_mc_count(netdev));
 
-               for (mc = mc_list, i = 0; mc; mc = mc->next, i++)
+               i = 0;
+               netdev_for_each_mc_addr(mc, netdev)
                        memcpy(req->mac[i].byte, mc->dmi_addr, ETH_ALEN);
        } else {
                req->promiscuous = 1;
@@ -1374,7 +1408,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
                        u32 flash_type, u32 flash_opcode, u32 buf_size)
 {
        struct be_mcc_wrb *wrb;
-       struct be_cmd_write_flashrom *req = cmd->va;
+       struct be_cmd_write_flashrom *req;
        struct be_sge *sge;
        int status;
 
@@ -1408,7 +1442,8 @@ err:
        return status;
 }
 
-int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc)
+int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
+                        int offset)
 {
        struct be_mcc_wrb *wrb;
        struct be_cmd_write_flashrom *req;
@@ -1429,9 +1464,9 @@ int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc)
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
                OPCODE_COMMON_READ_FLASHROM, sizeof(*req)+4);
 
-       req->params.op_type = cpu_to_le32(FLASHROM_TYPE_REDBOOT);
+       req->params.op_type = cpu_to_le32(IMG_TYPE_REDBOOT);
        req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT);
-       req->params.offset = 0x3FFFC;
+       req->params.offset = offset;
        req->params.data_buf_size = 0x4;
 
        status = be_mcc_notify_wait(adapter);
@@ -1607,3 +1642,33 @@ err:
        spin_unlock_bh(&adapter->mcc_lock);
        return status;
 }
+
+extern int be_cmd_get_seeprom_data(struct be_adapter *adapter,
+                               struct be_dma_mem *nonemb_cmd)
+{
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_seeprom_read *req;
+       struct be_sge *sge;
+       int status;
+
+       spin_lock_bh(&adapter->mcc_lock);
+
+       wrb = wrb_from_mccq(adapter);
+       req = nonemb_cmd->va;
+       sge = nonembedded_sgl(wrb);
+
+       be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
+                       OPCODE_COMMON_SEEPROM_READ);
+
+       be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+                       OPCODE_COMMON_SEEPROM_READ, sizeof(*req));
+
+       sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
+       sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
+       sge->len = cpu_to_le32(nonemb_cmd->size);
+
+       status = be_mcc_notify_wait(adapter);
+
+       spin_unlock_bh(&adapter->mcc_lock);
+       return status;
+}