aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSathya Perla <sathya.perla@emulex.com>2013-08-27 07:27:33 -0400
committerDavid S. Miller <davem@davemloft.net>2013-08-27 15:57:05 -0400
commitbea5098848925351ed6fc84dc84c88b2765237f7 (patch)
tree904f5a0f9a7ee0b8e69b1c8edbfda99fdb2689e5 /drivers
parent92bf14abf7a064936b5e6baab30661da86a86e52 (diff)
be2net: Fix be_cmd_if_create() to use MBOX if MCCQ is not created
Currently the IF_CREATE FW cmd is issued only *after* MCCQ is created as it was coded to only use MCCQ. By fixing this, cmd_if_create() can be called before MCCQ is created and the same routine for VF provisioning can be called after. This allows for consolidating all the queue create routines by moving the be_cmd_if_create() call above all queue create calls in be_setup(). Signed-off-by: Sathya Perla <sathya.perla@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c109
1 files changed, 85 insertions, 24 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 5458a4357ae0..70d5db043f1e 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -633,6 +633,12 @@ static inline struct be_sge *nonembedded_sgl(struct be_mcc_wrb *wrb)
633 return &wrb->payload.sgl[0]; 633 return &wrb->payload.sgl[0];
634} 634}
635 635
636static inline void fill_wrb_tags(struct be_mcc_wrb *wrb,
637 unsigned long addr)
638{
639 wrb->tag0 = addr & 0xFFFFFFFF;
640 wrb->tag1 = upper_32_bits(addr);
641}
636 642
637/* Don't touch the hdr after it's prepared */ 643/* Don't touch the hdr after it's prepared */
638/* mem will be NULL for embedded commands */ 644/* mem will be NULL for embedded commands */
@@ -641,17 +647,12 @@ static void be_wrb_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
641 struct be_mcc_wrb *wrb, struct be_dma_mem *mem) 647 struct be_mcc_wrb *wrb, struct be_dma_mem *mem)
642{ 648{
643 struct be_sge *sge; 649 struct be_sge *sge;
644 unsigned long addr = (unsigned long)req_hdr;
645 u64 req_addr = addr;
646 650
647 req_hdr->opcode = opcode; 651 req_hdr->opcode = opcode;
648 req_hdr->subsystem = subsystem; 652 req_hdr->subsystem = subsystem;
649 req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr)); 653 req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
650 req_hdr->version = 0; 654 req_hdr->version = 0;
651 655 fill_wrb_tags(wrb, (ulong) req_hdr);
652 wrb->tag0 = req_addr & 0xFFFFFFFF;
653 wrb->tag1 = upper_32_bits(req_addr);
654
655 wrb->payload_length = cmd_len; 656 wrb->payload_length = cmd_len;
656 if (mem) { 657 if (mem) {
657 wrb->embedded |= (1 & MCC_WRB_SGE_CNT_MASK) << 658 wrb->embedded |= (1 & MCC_WRB_SGE_CNT_MASK) <<
@@ -705,6 +706,78 @@ static struct be_mcc_wrb *wrb_from_mccq(struct be_adapter *adapter)
705 return wrb; 706 return wrb;
706} 707}
707 708
709static bool use_mcc(struct be_adapter *adapter)
710{
711 return adapter->mcc_obj.q.created;
712}
713
714/* Must be used only in process context */
715static int be_cmd_lock(struct be_adapter *adapter)
716{
717 if (use_mcc(adapter)) {
718 spin_lock_bh(&adapter->mcc_lock);
719 return 0;
720 } else {
721 return mutex_lock_interruptible(&adapter->mbox_lock);
722 }
723}
724
725/* Must be used only in process context */
726static void be_cmd_unlock(struct be_adapter *adapter)
727{
728 if (use_mcc(adapter))
729 spin_unlock_bh(&adapter->mcc_lock);
730 else
731 return mutex_unlock(&adapter->mbox_lock);
732}
733
734static struct be_mcc_wrb *be_cmd_copy(struct be_adapter *adapter,
735 struct be_mcc_wrb *wrb)
736{
737 struct be_mcc_wrb *dest_wrb;
738
739 if (use_mcc(adapter)) {
740 dest_wrb = wrb_from_mccq(adapter);
741 if (!dest_wrb)
742 return NULL;
743 } else {
744 dest_wrb = wrb_from_mbox(adapter);
745 }
746
747 memcpy(dest_wrb, wrb, sizeof(*wrb));
748 if (wrb->embedded & cpu_to_le32(MCC_WRB_EMBEDDED_MASK))
749 fill_wrb_tags(dest_wrb, (ulong) embedded_payload(wrb));
750
751 return dest_wrb;
752}
753
754/* Must be used only in process context */
755static int be_cmd_notify_wait(struct be_adapter *adapter,
756 struct be_mcc_wrb *wrb)
757{
758 struct be_mcc_wrb *dest_wrb;
759 int status;
760
761 status = be_cmd_lock(adapter);
762 if (status)
763 return status;
764
765 dest_wrb = be_cmd_copy(adapter, wrb);
766 if (!dest_wrb)
767 return -EBUSY;
768
769 if (use_mcc(adapter))
770 status = be_mcc_notify_wait(adapter);
771 else
772 status = be_mbox_notify_wait(adapter);
773
774 if (!status)
775 memcpy(wrb, dest_wrb, sizeof(*wrb));
776
777 be_cmd_unlock(adapter);
778 return status;
779}
780
708/* Tell fw we're about to start firing cmds by writing a 781/* Tell fw we're about to start firing cmds by writing a
709 * special pattern across the wrb hdr; uses mbox 782 * special pattern across the wrb hdr; uses mbox
710 */ 783 */
@@ -1290,44 +1363,32 @@ err:
1290} 1363}
1291 1364
1292/* Create an rx filtering policy configuration on an i/f 1365/* Create an rx filtering policy configuration on an i/f
1293 * Uses MCCQ 1366 * Will use MBOX only if MCCQ has not been created.
1294 */ 1367 */
1295int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, 1368int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
1296 u32 *if_handle, u32 domain) 1369 u32 *if_handle, u32 domain)
1297{ 1370{
1298 struct be_mcc_wrb *wrb; 1371 struct be_mcc_wrb wrb = {0};
1299 struct be_cmd_req_if_create *req; 1372 struct be_cmd_req_if_create *req;
1300 int status; 1373 int status;
1301 1374
1302 spin_lock_bh(&adapter->mcc_lock); 1375 req = embedded_payload(&wrb);
1303
1304 wrb = wrb_from_mccq(adapter);
1305 if (!wrb) {
1306 status = -EBUSY;
1307 goto err;
1308 }
1309 req = embedded_payload(wrb);
1310
1311 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, 1376 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1312 OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req), wrb, NULL); 1377 OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req), &wrb, NULL);
1313 req->hdr.domain = domain; 1378 req->hdr.domain = domain;
1314 req->capability_flags = cpu_to_le32(cap_flags); 1379 req->capability_flags = cpu_to_le32(cap_flags);
1315 req->enable_flags = cpu_to_le32(en_flags); 1380 req->enable_flags = cpu_to_le32(en_flags);
1316
1317 req->pmac_invalid = true; 1381 req->pmac_invalid = true;
1318 1382
1319 status = be_mcc_notify_wait(adapter); 1383 status = be_cmd_notify_wait(adapter, &wrb);
1320 if (!status) { 1384 if (!status) {
1321 struct be_cmd_resp_if_create *resp = embedded_payload(wrb); 1385 struct be_cmd_resp_if_create *resp = embedded_payload(&wrb);
1322 *if_handle = le32_to_cpu(resp->interface_id); 1386 *if_handle = le32_to_cpu(resp->interface_id);
1323 1387
1324 /* Hack to retrieve VF's pmac-id on BE3 */ 1388 /* Hack to retrieve VF's pmac-id on BE3 */
1325 if (BE3_chip(adapter) && !be_physfn(adapter)) 1389 if (BE3_chip(adapter) && !be_physfn(adapter))
1326 adapter->pmac_id[0] = le32_to_cpu(resp->pmac_id); 1390 adapter->pmac_id[0] = le32_to_cpu(resp->pmac_id);
1327 } 1391 }
1328
1329err:
1330 spin_unlock_bh(&adapter->mcc_lock);
1331 return status; 1392 return status;
1332} 1393}
1333 1394