aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/benet/be_cmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/benet/be_cmds.c')
-rw-r--r--drivers/net/benet/be_cmds.c368
1 files changed, 285 insertions, 83 deletions
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index d444aed962bc..583517ed56f0 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -17,6 +17,133 @@
17 17
18#include "be.h" 18#include "be.h"
19 19
20static void be_mcc_notify(struct be_ctrl_info *ctrl)
21{
22 struct be_queue_info *mccq = &ctrl->mcc_obj.q;
23 u32 val = 0;
24
25 val |= mccq->id & DB_MCCQ_RING_ID_MASK;
26 val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
27 iowrite32(val, ctrl->db + DB_MCCQ_OFFSET);
28}
29
30/* To check if valid bit is set, check the entire word as we don't know
31 * the endianness of the data (old entry is host endian while a new entry is
32 * little endian) */
33static inline bool be_mcc_compl_is_new(struct be_mcc_cq_entry *compl)
34{
35 if (compl->flags != 0) {
36 compl->flags = le32_to_cpu(compl->flags);
37 BUG_ON((compl->flags & CQE_FLAGS_VALID_MASK) == 0);
38 return true;
39 } else {
40 return false;
41 }
42}
43
44/* Need to reset the entire word that houses the valid bit */
45static inline void be_mcc_compl_use(struct be_mcc_cq_entry *compl)
46{
47 compl->flags = 0;
48}
49
50static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
51 struct be_mcc_cq_entry *compl)
52{
53 u16 compl_status, extd_status;
54
55 /* Just swap the status to host endian; mcc tag is opaquely copied
56 * from mcc_wrb */
57 be_dws_le_to_cpu(compl, 4);
58
59 compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
60 CQE_STATUS_COMPL_MASK;
61 if (compl_status != MCC_STATUS_SUCCESS) {
62 extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
63 CQE_STATUS_EXTD_MASK;
64 printk(KERN_WARNING DRV_NAME
65 " error in cmd completion: status(compl/extd)=%d/%d\n",
66 compl_status, extd_status);
67 return -1;
68 }
69 return 0;
70}
71
72/* Link state evt is a string of bytes; no need for endian swapping */
73static void be_async_link_state_process(struct be_ctrl_info *ctrl,
74 struct be_async_event_link_state *evt)
75{
76 ctrl->async_cb(ctrl->adapter_ctxt,
77 evt->port_link_status == ASYNC_EVENT_LINK_UP ? true : false);
78}
79
80static inline bool is_link_state_evt(u32 trailer)
81{
82 return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
83 ASYNC_TRAILER_EVENT_CODE_MASK) ==
84 ASYNC_EVENT_CODE_LINK_STATE);
85}
86
87static struct be_mcc_cq_entry *be_mcc_compl_get(struct be_ctrl_info *ctrl)
88{
89 struct be_queue_info *mcc_cq = &ctrl->mcc_obj.cq;
90 struct be_mcc_cq_entry *compl = queue_tail_node(mcc_cq);
91
92 if (be_mcc_compl_is_new(compl)) {
93 queue_tail_inc(mcc_cq);
94 return compl;
95 }
96 return NULL;
97}
98
99void be_process_mcc(struct be_ctrl_info *ctrl)
100{
101 struct be_mcc_cq_entry *compl;
102 int num = 0;
103
104 spin_lock_bh(&ctrl->mcc_cq_lock);
105 while ((compl = be_mcc_compl_get(ctrl))) {
106 if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
107 /* Interpret flags as an async trailer */
108 BUG_ON(!is_link_state_evt(compl->flags));
109
110 /* Interpret compl as a async link evt */
111 be_async_link_state_process(ctrl,
112 (struct be_async_event_link_state *) compl);
113 } else {
114 be_mcc_compl_process(ctrl, compl);
115 atomic_dec(&ctrl->mcc_obj.q.used);
116 }
117 be_mcc_compl_use(compl);
118 num++;
119 }
120 if (num)
121 be_cq_notify(ctrl, ctrl->mcc_obj.cq.id, true, num);
122 spin_unlock_bh(&ctrl->mcc_cq_lock);
123}
124
125/* Wait till no more pending mcc requests are present */
126static void be_mcc_wait_compl(struct be_ctrl_info *ctrl)
127{
128#define mcc_timeout 50000 /* 5s timeout */
129 int i;
130 for (i = 0; i < mcc_timeout; i++) {
131 be_process_mcc(ctrl);
132 if (atomic_read(&ctrl->mcc_obj.q.used) == 0)
133 break;
134 udelay(100);
135 }
136 if (i == mcc_timeout)
137 printk(KERN_WARNING DRV_NAME "mcc poll timed out\n");
138}
139
140/* Notify MCC requests and wait for completion */
141static void be_mcc_notify_wait(struct be_ctrl_info *ctrl)
142{
143 be_mcc_notify(ctrl);
144 be_mcc_wait_compl(ctrl);
145}
146
20static int be_mbox_db_ready_wait(void __iomem *db) 147static int be_mbox_db_ready_wait(void __iomem *db)
21{ 148{
22 int cnt = 0, wait = 5; 149 int cnt = 0, wait = 5;
@@ -44,11 +171,11 @@ static int be_mbox_db_ready_wait(void __iomem *db)
44 171
45/* 172/*
46 * Insert the mailbox address into the doorbell in two steps 173 * Insert the mailbox address into the doorbell in two steps
174 * Polls on the mbox doorbell till a command completion (or a timeout) occurs
47 */ 175 */
48static int be_mbox_db_ring(struct be_ctrl_info *ctrl) 176static int be_mbox_db_ring(struct be_ctrl_info *ctrl)
49{ 177{
50 int status; 178 int status;
51 u16 compl_status, extd_status;
52 u32 val = 0; 179 u32 val = 0;
53 void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET; 180 void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
54 struct be_dma_mem *mbox_mem = &ctrl->mbox_mem; 181 struct be_dma_mem *mbox_mem = &ctrl->mbox_mem;
@@ -79,24 +206,17 @@ static int be_mbox_db_ring(struct be_ctrl_info *ctrl)
79 if (status != 0) 206 if (status != 0)
80 return status; 207 return status;
81 208
82 /* compl entry has been made now */ 209 /* A cq entry has been made now */
83 be_dws_le_to_cpu(cqe, sizeof(*cqe)); 210 if (be_mcc_compl_is_new(cqe)) {
84 if (!(cqe->flags & CQE_FLAGS_VALID_MASK)) { 211 status = be_mcc_compl_process(ctrl, &mbox->cqe);
85 printk(KERN_WARNING DRV_NAME ": ERROR invalid mbox compl\n"); 212 be_mcc_compl_use(cqe);
213 if (status)
214 return status;
215 } else {
216 printk(KERN_WARNING DRV_NAME "invalid mailbox completion\n");
86 return -1; 217 return -1;
87 } 218 }
88 219 return 0;
89 compl_status = (cqe->status >> CQE_STATUS_COMPL_SHIFT) &
90 CQE_STATUS_COMPL_MASK;
91 if (compl_status != MCC_STATUS_SUCCESS) {
92 extd_status = (cqe->status >> CQE_STATUS_EXTD_SHIFT) &
93 CQE_STATUS_EXTD_MASK;
94 printk(KERN_WARNING DRV_NAME
95 ": ERROR in cmd compl. status(compl/extd)=%d/%d\n",
96 compl_status, extd_status);
97 }
98
99 return compl_status;
100} 220}
101 221
102static int be_POST_stage_get(struct be_ctrl_info *ctrl, u16 *stage) 222static int be_POST_stage_get(struct be_ctrl_info *ctrl, u16 *stage)
@@ -235,6 +355,18 @@ static inline struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem)
235 return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb; 355 return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
236} 356}
237 357
358static inline struct be_mcc_wrb *wrb_from_mcc(struct be_queue_info *mccq)
359{
360 struct be_mcc_wrb *wrb = NULL;
361 if (atomic_read(&mccq->used) < mccq->len) {
362 wrb = queue_head_node(mccq);
363 queue_head_inc(mccq);
364 atomic_inc(&mccq->used);
365 memset(wrb, 0, sizeof(*wrb));
366 }
367 return wrb;
368}
369
238int be_cmd_eq_create(struct be_ctrl_info *ctrl, 370int be_cmd_eq_create(struct be_ctrl_info *ctrl,
239 struct be_queue_info *eq, int eq_delay) 371 struct be_queue_info *eq, int eq_delay)
240{ 372{
@@ -244,7 +376,7 @@ int be_cmd_eq_create(struct be_ctrl_info *ctrl,
244 struct be_dma_mem *q_mem = &eq->dma_mem; 376 struct be_dma_mem *q_mem = &eq->dma_mem;
245 int status; 377 int status;
246 378
247 spin_lock(&ctrl->cmd_lock); 379 spin_lock(&ctrl->mbox_lock);
248 memset(wrb, 0, sizeof(*wrb)); 380 memset(wrb, 0, sizeof(*wrb));
249 381
250 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 382 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -272,7 +404,7 @@ int be_cmd_eq_create(struct be_ctrl_info *ctrl,
272 eq->id = le16_to_cpu(resp->eq_id); 404 eq->id = le16_to_cpu(resp->eq_id);
273 eq->created = true; 405 eq->created = true;
274 } 406 }
275 spin_unlock(&ctrl->cmd_lock); 407 spin_unlock(&ctrl->mbox_lock);
276 return status; 408 return status;
277} 409}
278 410
@@ -284,7 +416,7 @@ int be_cmd_mac_addr_query(struct be_ctrl_info *ctrl, u8 *mac_addr,
284 struct be_cmd_resp_mac_query *resp = embedded_payload(wrb); 416 struct be_cmd_resp_mac_query *resp = embedded_payload(wrb);
285 int status; 417 int status;
286 418
287 spin_lock(&ctrl->cmd_lock); 419 spin_lock(&ctrl->mbox_lock);
288 memset(wrb, 0, sizeof(*wrb)); 420 memset(wrb, 0, sizeof(*wrb));
289 421
290 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 422 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -304,7 +436,7 @@ int be_cmd_mac_addr_query(struct be_ctrl_info *ctrl, u8 *mac_addr,
304 if (!status) 436 if (!status)
305 memcpy(mac_addr, resp->mac.addr, ETH_ALEN); 437 memcpy(mac_addr, resp->mac.addr, ETH_ALEN);
306 438
307 spin_unlock(&ctrl->cmd_lock); 439 spin_unlock(&ctrl->mbox_lock);
308 return status; 440 return status;
309} 441}
310 442
@@ -315,7 +447,7 @@ int be_cmd_pmac_add(struct be_ctrl_info *ctrl, u8 *mac_addr,
315 struct be_cmd_req_pmac_add *req = embedded_payload(wrb); 447 struct be_cmd_req_pmac_add *req = embedded_payload(wrb);
316 int status; 448 int status;
317 449
318 spin_lock(&ctrl->cmd_lock); 450 spin_lock(&ctrl->mbox_lock);
319 memset(wrb, 0, sizeof(*wrb)); 451 memset(wrb, 0, sizeof(*wrb));
320 452
321 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 453 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -332,7 +464,7 @@ int be_cmd_pmac_add(struct be_ctrl_info *ctrl, u8 *mac_addr,
332 *pmac_id = le32_to_cpu(resp->pmac_id); 464 *pmac_id = le32_to_cpu(resp->pmac_id);
333 } 465 }
334 466
335 spin_unlock(&ctrl->cmd_lock); 467 spin_unlock(&ctrl->mbox_lock);
336 return status; 468 return status;
337} 469}
338 470
@@ -342,7 +474,7 @@ int be_cmd_pmac_del(struct be_ctrl_info *ctrl, u32 if_id, u32 pmac_id)
342 struct be_cmd_req_pmac_del *req = embedded_payload(wrb); 474 struct be_cmd_req_pmac_del *req = embedded_payload(wrb);
343 int status; 475 int status;
344 476
345 spin_lock(&ctrl->cmd_lock); 477 spin_lock(&ctrl->mbox_lock);
346 memset(wrb, 0, sizeof(*wrb)); 478 memset(wrb, 0, sizeof(*wrb));
347 479
348 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 480 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -354,7 +486,7 @@ int be_cmd_pmac_del(struct be_ctrl_info *ctrl, u32 if_id, u32 pmac_id)
354 req->pmac_id = cpu_to_le32(pmac_id); 486 req->pmac_id = cpu_to_le32(pmac_id);
355 487
356 status = be_mbox_db_ring(ctrl); 488 status = be_mbox_db_ring(ctrl);
357 spin_unlock(&ctrl->cmd_lock); 489 spin_unlock(&ctrl->mbox_lock);
358 490
359 return status; 491 return status;
360} 492}
@@ -370,7 +502,7 @@ int be_cmd_cq_create(struct be_ctrl_info *ctrl,
370 void *ctxt = &req->context; 502 void *ctxt = &req->context;
371 int status; 503 int status;
372 504
373 spin_lock(&ctrl->cmd_lock); 505 spin_lock(&ctrl->mbox_lock);
374 memset(wrb, 0, sizeof(*wrb)); 506 memset(wrb, 0, sizeof(*wrb));
375 507
376 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 508 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -388,7 +520,7 @@ int be_cmd_cq_create(struct be_ctrl_info *ctrl,
388 AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts); 520 AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts);
389 AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1); 521 AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
390 AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id); 522 AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
391 AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 0); 523 AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1);
392 AMAP_SET_BITS(struct amap_cq_context, func, ctxt, ctrl->pci_func); 524 AMAP_SET_BITS(struct amap_cq_context, func, ctxt, ctrl->pci_func);
393 be_dws_cpu_to_le(ctxt, sizeof(req->context)); 525 be_dws_cpu_to_le(ctxt, sizeof(req->context));
394 526
@@ -399,7 +531,56 @@ int be_cmd_cq_create(struct be_ctrl_info *ctrl,
399 cq->id = le16_to_cpu(resp->cq_id); 531 cq->id = le16_to_cpu(resp->cq_id);
400 cq->created = true; 532 cq->created = true;
401 } 533 }
402 spin_unlock(&ctrl->cmd_lock); 534 spin_unlock(&ctrl->mbox_lock);
535
536 return status;
537}
538
539static u32 be_encoded_q_len(int q_len)
540{
541 u32 len_encoded = fls(q_len); /* log2(len) + 1 */
542 if (len_encoded == 16)
543 len_encoded = 0;
544 return len_encoded;
545}
546
547int be_cmd_mccq_create(struct be_ctrl_info *ctrl,
548 struct be_queue_info *mccq,
549 struct be_queue_info *cq)
550{
551 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
552 struct be_cmd_req_mcc_create *req = embedded_payload(wrb);
553 struct be_dma_mem *q_mem = &mccq->dma_mem;
554 void *ctxt = &req->context;
555 int status;
556
557 spin_lock(&ctrl->mbox_lock);
558 memset(wrb, 0, sizeof(*wrb));
559
560 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
561
562 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
563 OPCODE_COMMON_MCC_CREATE, sizeof(*req));
564
565 req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
566
567 AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt, ctrl->pci_func);
568 AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
569 AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
570 be_encoded_q_len(mccq->len));
571 AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id);
572
573 be_dws_cpu_to_le(ctxt, sizeof(req->context));
574
575 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
576
577 status = be_mbox_db_ring(ctrl);
578 if (!status) {
579 struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
580 mccq->id = le16_to_cpu(resp->id);
581 mccq->created = true;
582 }
583 spin_unlock(&ctrl->mbox_lock);
403 584
404 return status; 585 return status;
405} 586}
@@ -415,7 +596,7 @@ int be_cmd_txq_create(struct be_ctrl_info *ctrl,
415 int status; 596 int status;
416 u32 len_encoded; 597 u32 len_encoded;
417 598
418 spin_lock(&ctrl->cmd_lock); 599 spin_lock(&ctrl->mbox_lock);
419 memset(wrb, 0, sizeof(*wrb)); 600 memset(wrb, 0, sizeof(*wrb));
420 601
421 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 602 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -446,7 +627,7 @@ int be_cmd_txq_create(struct be_ctrl_info *ctrl,
446 txq->id = le16_to_cpu(resp->cid); 627 txq->id = le16_to_cpu(resp->cid);
447 txq->created = true; 628 txq->created = true;
448 } 629 }
449 spin_unlock(&ctrl->cmd_lock); 630 spin_unlock(&ctrl->mbox_lock);
450 631
451 return status; 632 return status;
452} 633}
@@ -460,7 +641,7 @@ int be_cmd_rxq_create(struct be_ctrl_info *ctrl,
460 struct be_dma_mem *q_mem = &rxq->dma_mem; 641 struct be_dma_mem *q_mem = &rxq->dma_mem;
461 int status; 642 int status;
462 643
463 spin_lock(&ctrl->cmd_lock); 644 spin_lock(&ctrl->mbox_lock);
464 memset(wrb, 0, sizeof(*wrb)); 645 memset(wrb, 0, sizeof(*wrb));
465 646
466 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 647 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -482,7 +663,7 @@ int be_cmd_rxq_create(struct be_ctrl_info *ctrl,
482 rxq->id = le16_to_cpu(resp->id); 663 rxq->id = le16_to_cpu(resp->id);
483 rxq->created = true; 664 rxq->created = true;
484 } 665 }
485 spin_unlock(&ctrl->cmd_lock); 666 spin_unlock(&ctrl->mbox_lock);
486 667
487 return status; 668 return status;
488} 669}
@@ -496,7 +677,7 @@ int be_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
496 u8 subsys = 0, opcode = 0; 677 u8 subsys = 0, opcode = 0;
497 int status; 678 int status;
498 679
499 spin_lock(&ctrl->cmd_lock); 680 spin_lock(&ctrl->mbox_lock);
500 681
501 memset(wrb, 0, sizeof(*wrb)); 682 memset(wrb, 0, sizeof(*wrb));
502 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 683 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -518,6 +699,10 @@ int be_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
518 subsys = CMD_SUBSYSTEM_ETH; 699 subsys = CMD_SUBSYSTEM_ETH;
519 opcode = OPCODE_ETH_RX_DESTROY; 700 opcode = OPCODE_ETH_RX_DESTROY;
520 break; 701 break;
702 case QTYPE_MCCQ:
703 subsys = CMD_SUBSYSTEM_COMMON;
704 opcode = OPCODE_COMMON_MCC_DESTROY;
705 break;
521 default: 706 default:
522 printk(KERN_WARNING DRV_NAME ":bad Q type in Q destroy cmd\n"); 707 printk(KERN_WARNING DRV_NAME ":bad Q type in Q destroy cmd\n");
523 status = -1; 708 status = -1;
@@ -528,7 +713,7 @@ int be_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
528 713
529 status = be_mbox_db_ring(ctrl); 714 status = be_mbox_db_ring(ctrl);
530err: 715err:
531 spin_unlock(&ctrl->cmd_lock); 716 spin_unlock(&ctrl->mbox_lock);
532 717
533 return status; 718 return status;
534} 719}
@@ -541,7 +726,7 @@ int be_cmd_if_create(struct be_ctrl_info *ctrl, u32 flags, u8 *mac,
541 struct be_cmd_req_if_create *req = embedded_payload(wrb); 726 struct be_cmd_req_if_create *req = embedded_payload(wrb);
542 int status; 727 int status;
543 728
544 spin_lock(&ctrl->cmd_lock); 729 spin_lock(&ctrl->mbox_lock);
545 memset(wrb, 0, sizeof(*wrb)); 730 memset(wrb, 0, sizeof(*wrb));
546 731
547 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 732 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -562,7 +747,7 @@ int be_cmd_if_create(struct be_ctrl_info *ctrl, u32 flags, u8 *mac,
562 *pmac_id = le32_to_cpu(resp->pmac_id); 747 *pmac_id = le32_to_cpu(resp->pmac_id);
563 } 748 }
564 749
565 spin_unlock(&ctrl->cmd_lock); 750 spin_unlock(&ctrl->mbox_lock);
566 return status; 751 return status;
567} 752}
568 753
@@ -572,7 +757,7 @@ int be_cmd_if_destroy(struct be_ctrl_info *ctrl, u32 interface_id)
572 struct be_cmd_req_if_destroy *req = embedded_payload(wrb); 757 struct be_cmd_req_if_destroy *req = embedded_payload(wrb);
573 int status; 758 int status;
574 759
575 spin_lock(&ctrl->cmd_lock); 760 spin_lock(&ctrl->mbox_lock);
576 memset(wrb, 0, sizeof(*wrb)); 761 memset(wrb, 0, sizeof(*wrb));
577 762
578 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 763 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -583,7 +768,7 @@ int be_cmd_if_destroy(struct be_ctrl_info *ctrl, u32 interface_id)
583 req->interface_id = cpu_to_le32(interface_id); 768 req->interface_id = cpu_to_le32(interface_id);
584 status = be_mbox_db_ring(ctrl); 769 status = be_mbox_db_ring(ctrl);
585 770
586 spin_unlock(&ctrl->cmd_lock); 771 spin_unlock(&ctrl->mbox_lock);
587 772
588 return status; 773 return status;
589} 774}
@@ -598,7 +783,7 @@ int be_cmd_get_stats(struct be_ctrl_info *ctrl, struct be_dma_mem *nonemb_cmd)
598 struct be_sge *sge = nonembedded_sgl(wrb); 783 struct be_sge *sge = nonembedded_sgl(wrb);
599 int status; 784 int status;
600 785
601 spin_lock(&ctrl->cmd_lock); 786 spin_lock(&ctrl->mbox_lock);
602 memset(wrb, 0, sizeof(*wrb)); 787 memset(wrb, 0, sizeof(*wrb));
603 788
604 memset(req, 0, sizeof(*req)); 789 memset(req, 0, sizeof(*req));
@@ -617,18 +802,20 @@ int be_cmd_get_stats(struct be_ctrl_info *ctrl, struct be_dma_mem *nonemb_cmd)
617 be_dws_le_to_cpu(&resp->hw_stats, sizeof(resp->hw_stats)); 802 be_dws_le_to_cpu(&resp->hw_stats, sizeof(resp->hw_stats));
618 } 803 }
619 804
620 spin_unlock(&ctrl->cmd_lock); 805 spin_unlock(&ctrl->mbox_lock);
621 return status; 806 return status;
622} 807}
623 808
624int be_cmd_link_status_query(struct be_ctrl_info *ctrl, 809int be_cmd_link_status_query(struct be_ctrl_info *ctrl,
625 struct be_link_info *link) 810 bool *link_up)
626{ 811{
627 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); 812 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
628 struct be_cmd_req_link_status *req = embedded_payload(wrb); 813 struct be_cmd_req_link_status *req = embedded_payload(wrb);
629 int status; 814 int status;
630 815
631 spin_lock(&ctrl->cmd_lock); 816 spin_lock(&ctrl->mbox_lock);
817
818 *link_up = false;
632 memset(wrb, 0, sizeof(*wrb)); 819 memset(wrb, 0, sizeof(*wrb));
633 820
634 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 821 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -639,14 +826,11 @@ int be_cmd_link_status_query(struct be_ctrl_info *ctrl,
639 status = be_mbox_db_ring(ctrl); 826 status = be_mbox_db_ring(ctrl);
640 if (!status) { 827 if (!status) {
641 struct be_cmd_resp_link_status *resp = embedded_payload(wrb); 828 struct be_cmd_resp_link_status *resp = embedded_payload(wrb);
642 link->speed = resp->mac_speed; 829 if (resp->mac_speed != PHY_LINK_SPEED_ZERO)
643 link->duplex = resp->mac_duplex; 830 *link_up = true;
644 link->fault = resp->mac_fault;
645 } else {
646 link->speed = PHY_LINK_SPEED_ZERO;
647 } 831 }
648 832
649 spin_unlock(&ctrl->cmd_lock); 833 spin_unlock(&ctrl->mbox_lock);
650 return status; 834 return status;
651} 835}
652 836
@@ -656,7 +840,7 @@ int be_cmd_get_fw_ver(struct be_ctrl_info *ctrl, char *fw_ver)
656 struct be_cmd_req_get_fw_version *req = embedded_payload(wrb); 840 struct be_cmd_req_get_fw_version *req = embedded_payload(wrb);
657 int status; 841 int status;
658 842
659 spin_lock(&ctrl->cmd_lock); 843 spin_lock(&ctrl->mbox_lock);
660 memset(wrb, 0, sizeof(*wrb)); 844 memset(wrb, 0, sizeof(*wrb));
661 845
662 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 846 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -670,7 +854,7 @@ int be_cmd_get_fw_ver(struct be_ctrl_info *ctrl, char *fw_ver)
670 strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN); 854 strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN);
671 } 855 }
672 856
673 spin_unlock(&ctrl->cmd_lock); 857 spin_unlock(&ctrl->mbox_lock);
674 return status; 858 return status;
675} 859}
676 860
@@ -681,7 +865,7 @@ int be_cmd_modify_eqd(struct be_ctrl_info *ctrl, u32 eq_id, u32 eqd)
681 struct be_cmd_req_modify_eq_delay *req = embedded_payload(wrb); 865 struct be_cmd_req_modify_eq_delay *req = embedded_payload(wrb);
682 int status; 866 int status;
683 867
684 spin_lock(&ctrl->cmd_lock); 868 spin_lock(&ctrl->mbox_lock);
685 memset(wrb, 0, sizeof(*wrb)); 869 memset(wrb, 0, sizeof(*wrb));
686 870
687 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 871 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -696,7 +880,7 @@ int be_cmd_modify_eqd(struct be_ctrl_info *ctrl, u32 eq_id, u32 eqd)
696 880
697 status = be_mbox_db_ring(ctrl); 881 status = be_mbox_db_ring(ctrl);
698 882
699 spin_unlock(&ctrl->cmd_lock); 883 spin_unlock(&ctrl->mbox_lock);
700 return status; 884 return status;
701} 885}
702 886
@@ -707,7 +891,7 @@ int be_cmd_vlan_config(struct be_ctrl_info *ctrl, u32 if_id, u16 *vtag_array,
707 struct be_cmd_req_vlan_config *req = embedded_payload(wrb); 891 struct be_cmd_req_vlan_config *req = embedded_payload(wrb);
708 int status; 892 int status;
709 893
710 spin_lock(&ctrl->cmd_lock); 894 spin_lock(&ctrl->mbox_lock);
711 memset(wrb, 0, sizeof(*wrb)); 895 memset(wrb, 0, sizeof(*wrb));
712 896
713 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 897 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -726,18 +910,22 @@ int be_cmd_vlan_config(struct be_ctrl_info *ctrl, u32 if_id, u16 *vtag_array,
726 910
727 status = be_mbox_db_ring(ctrl); 911 status = be_mbox_db_ring(ctrl);
728 912
729 spin_unlock(&ctrl->cmd_lock); 913 spin_unlock(&ctrl->mbox_lock);
730 return status; 914 return status;
731} 915}
732 916
917/* Use MCC for this command as it may be called in BH context */
733int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl, u8 port_num, bool en) 918int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl, u8 port_num, bool en)
734{ 919{
735 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); 920 struct be_mcc_wrb *wrb;
736 struct be_cmd_req_promiscuous_config *req = embedded_payload(wrb); 921 struct be_cmd_req_promiscuous_config *req;
737 int status;
738 922
739 spin_lock(&ctrl->cmd_lock); 923 spin_lock_bh(&ctrl->mcc_lock);
740 memset(wrb, 0, sizeof(*wrb)); 924
925 wrb = wrb_from_mcc(&ctrl->mcc_obj.q);
926 BUG_ON(!wrb);
927
928 req = embedded_payload(wrb);
741 929
742 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 930 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
743 931
@@ -749,21 +937,29 @@ int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl, u8 port_num, bool en)
749 else 937 else
750 req->port0_promiscuous = en; 938 req->port0_promiscuous = en;
751 939
752 status = be_mbox_db_ring(ctrl); 940 be_mcc_notify_wait(ctrl);
753 941
754 spin_unlock(&ctrl->cmd_lock); 942 spin_unlock_bh(&ctrl->mcc_lock);
755 return status; 943 return 0;
756} 944}
757 945
758int be_cmd_mcast_mac_set(struct be_ctrl_info *ctrl, u32 if_id, u8 *mac_table, 946/*
759 u32 num, bool promiscuous) 947 * Use MCC for this command as it may be called in BH context
948 * (mc == NULL) => multicast promiscous
949 */
950int be_cmd_multicast_set(struct be_ctrl_info *ctrl, u32 if_id,
951 struct dev_mc_list *mc_list, u32 mc_count)
760{ 952{
761 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); 953#define BE_MAX_MC 32 /* set mcast promisc if > 32 */
762 struct be_cmd_req_mcast_mac_config *req = embedded_payload(wrb); 954 struct be_mcc_wrb *wrb;
763 int status; 955 struct be_cmd_req_mcast_mac_config *req;
764 956
765 spin_lock(&ctrl->cmd_lock); 957 spin_lock_bh(&ctrl->mcc_lock);
766 memset(wrb, 0, sizeof(*wrb)); 958
959 wrb = wrb_from_mcc(&ctrl->mcc_obj.q);
960 BUG_ON(!wrb);
961
962 req = embedded_payload(wrb);
767 963
768 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 964 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
769 965
@@ -771,17 +967,23 @@ int be_cmd_mcast_mac_set(struct be_ctrl_info *ctrl, u32 if_id, u8 *mac_table,
771 OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req)); 967 OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req));
772 968
773 req->interface_id = if_id; 969 req->interface_id = if_id;
774 req->promiscuous = promiscuous; 970 if (mc_list && mc_count <= BE_MAX_MC) {
775 if (!promiscuous) { 971 int i;
776 req->num_mac = cpu_to_le16(num); 972 struct dev_mc_list *mc;
777 if (num) 973
778 memcpy(req->mac, mac_table, ETH_ALEN * num); 974 req->num_mac = cpu_to_le16(mc_count);
975
976 for (mc = mc_list, i = 0; mc; mc = mc->next, i++)
977 memcpy(req->mac[i].byte, mc->dmi_addr, ETH_ALEN);
978 } else {
979 req->promiscuous = 1;
779 } 980 }
780 981
781 status = be_mbox_db_ring(ctrl); 982 be_mcc_notify_wait(ctrl);
782 983
783 spin_unlock(&ctrl->cmd_lock); 984 spin_unlock_bh(&ctrl->mcc_lock);
784 return status; 985
986 return 0;
785} 987}
786 988
787int be_cmd_set_flow_control(struct be_ctrl_info *ctrl, u32 tx_fc, u32 rx_fc) 989int be_cmd_set_flow_control(struct be_ctrl_info *ctrl, u32 tx_fc, u32 rx_fc)
@@ -790,7 +992,7 @@ int be_cmd_set_flow_control(struct be_ctrl_info *ctrl, u32 tx_fc, u32 rx_fc)
790 struct be_cmd_req_set_flow_control *req = embedded_payload(wrb); 992 struct be_cmd_req_set_flow_control *req = embedded_payload(wrb);
791 int status; 993 int status;
792 994
793 spin_lock(&ctrl->cmd_lock); 995 spin_lock(&ctrl->mbox_lock);
794 996
795 memset(wrb, 0, sizeof(*wrb)); 997 memset(wrb, 0, sizeof(*wrb));
796 998
@@ -804,7 +1006,7 @@ int be_cmd_set_flow_control(struct be_ctrl_info *ctrl, u32 tx_fc, u32 rx_fc)
804 1006
805 status = be_mbox_db_ring(ctrl); 1007 status = be_mbox_db_ring(ctrl);
806 1008
807 spin_unlock(&ctrl->cmd_lock); 1009 spin_unlock(&ctrl->mbox_lock);
808 return status; 1010 return status;
809} 1011}
810 1012
@@ -814,7 +1016,7 @@ int be_cmd_get_flow_control(struct be_ctrl_info *ctrl, u32 *tx_fc, u32 *rx_fc)
814 struct be_cmd_req_get_flow_control *req = embedded_payload(wrb); 1016 struct be_cmd_req_get_flow_control *req = embedded_payload(wrb);
815 int status; 1017 int status;
816 1018
817 spin_lock(&ctrl->cmd_lock); 1019 spin_lock(&ctrl->mbox_lock);
818 1020
819 memset(wrb, 0, sizeof(*wrb)); 1021 memset(wrb, 0, sizeof(*wrb));
820 1022
@@ -831,7 +1033,7 @@ int be_cmd_get_flow_control(struct be_ctrl_info *ctrl, u32 *tx_fc, u32 *rx_fc)
831 *rx_fc = le16_to_cpu(resp->rx_flow_control); 1033 *rx_fc = le16_to_cpu(resp->rx_flow_control);
832 } 1034 }
833 1035
834 spin_unlock(&ctrl->cmd_lock); 1036 spin_unlock(&ctrl->mbox_lock);
835 return status; 1037 return status;
836} 1038}
837 1039
@@ -841,7 +1043,7 @@ int be_cmd_query_fw_cfg(struct be_ctrl_info *ctrl, u32 *port_num)
841 struct be_cmd_req_query_fw_cfg *req = embedded_payload(wrb); 1043 struct be_cmd_req_query_fw_cfg *req = embedded_payload(wrb);
842 int status; 1044 int status;
843 1045
844 spin_lock(&ctrl->cmd_lock); 1046 spin_lock(&ctrl->mbox_lock);
845 1047
846 memset(wrb, 0, sizeof(*wrb)); 1048 memset(wrb, 0, sizeof(*wrb));
847 1049
@@ -856,6 +1058,6 @@ int be_cmd_query_fw_cfg(struct be_ctrl_info *ctrl, u32 *port_num)
856 *port_num = le32_to_cpu(resp->phys_port); 1058 *port_num = le32_to_cpu(resp->phys_port);
857 } 1059 }
858 1060
859 spin_unlock(&ctrl->cmd_lock); 1061 spin_unlock(&ctrl->mbox_lock);
860 return status; 1062 return status;
861} 1063}