aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/emulex
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/emulex')
-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