Skip to content

Commit c1a8161

Browse files
Salil Mehtadavem330
authored andcommitted
net: hns3: Add mailbox interrupt handling to PF driver
All PF mailbox events are conveyed through a common interrupt (vector 0). This interrupt vector is shared by reset and mailbox. This patch adds the handling of mailbox interrupt event and its deferred processing in context to a separate mailbox task. Signed-off-by: Salil Mehta <salil.mehta@huawei.com> Signed-off-by: lipeng <lipeng321@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 84e095d commit c1a8161

File tree

2 files changed

+68
-8
lines changed

2 files changed

+68
-8
lines changed

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2227,6 +2227,12 @@ static int hclge_mac_init(struct hclge_dev *hdev)
22272227
return hclge_cfg_func_mta_filter(hdev, 0, hdev->accept_mta_mc);
22282228
}
22292229

2230+
static void hclge_mbx_task_schedule(struct hclge_dev *hdev)
2231+
{
2232+
if (!test_and_set_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state))
2233+
schedule_work(&hdev->mbx_service_task);
2234+
}
2235+
22302236
static void hclge_reset_task_schedule(struct hclge_dev *hdev)
22312237
{
22322238
if (!test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
@@ -2372,9 +2378,18 @@ static void hclge_service_complete(struct hclge_dev *hdev)
23722378
static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
23732379
{
23742380
u32 rst_src_reg;
2381+
u32 cmdq_src_reg;
23752382

23762383
/* fetch the events from their corresponding regs */
23772384
rst_src_reg = hclge_read_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG);
2385+
cmdq_src_reg = hclge_read_dev(&hdev->hw, HCLGE_VECTOR0_CMDQ_SRC_REG);
2386+
2387+
/* Assumption: If by any chance reset and mailbox events are reported
2388+
* together then we will only process reset event in this go and will
2389+
* defer the processing of the mailbox events. Since, we would have not
2390+
* cleared RX CMDQ event this time we would receive again another
2391+
* interrupt from H/W just for the mailbox.
2392+
*/
23782393

23792394
/* check for vector0 reset event sources */
23802395
if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & rst_src_reg) {
@@ -2395,18 +2410,27 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
23952410
return HCLGE_VECTOR0_EVENT_RST;
23962411
}
23972412

2398-
/* mailbox event sharing vector 0 interrupt would be placed here */
2413+
/* check for vector0 mailbox(=CMDQ RX) event source */
2414+
if (BIT(HCLGE_VECTOR0_RX_CMDQ_INT_B) & cmdq_src_reg) {
2415+
cmdq_src_reg &= ~BIT(HCLGE_VECTOR0_RX_CMDQ_INT_B);
2416+
*clearval = cmdq_src_reg;
2417+
return HCLGE_VECTOR0_EVENT_MBX;
2418+
}
23992419

24002420
return HCLGE_VECTOR0_EVENT_OTHER;
24012421
}
24022422

24032423
static void hclge_clear_event_cause(struct hclge_dev *hdev, u32 event_type,
24042424
u32 regclr)
24052425
{
2406-
if (event_type == HCLGE_VECTOR0_EVENT_RST)
2426+
switch (event_type) {
2427+
case HCLGE_VECTOR0_EVENT_RST:
24072428
hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, regclr);
2408-
2409-
/* mailbox event sharing vector 0 interrupt would be placed here */
2429+
break;
2430+
case HCLGE_VECTOR0_EVENT_MBX:
2431+
hclge_write_dev(&hdev->hw, HCLGE_VECTOR0_CMDQ_SRC_REG, regclr);
2432+
break;
2433+
}
24102434
}
24112435

24122436
static void hclge_enable_vector(struct hclge_misc_vector *vector, bool enable)
@@ -2423,13 +2447,23 @@ static irqreturn_t hclge_misc_irq_handle(int irq, void *data)
24232447
hclge_enable_vector(&hdev->misc_vector, false);
24242448
event_cause = hclge_check_event_cause(hdev, &clearval);
24252449

2426-
/* vector 0 interrupt is shared with reset and mailbox source events.
2427-
* For now, we are not handling mailbox events.
2428-
*/
2450+
/* vector 0 interrupt is shared with reset and mailbox source events.*/
24292451
switch (event_cause) {
24302452
case HCLGE_VECTOR0_EVENT_RST:
24312453
hclge_reset_task_schedule(hdev);
24322454
break;
2455+
case HCLGE_VECTOR0_EVENT_MBX:
2456+
/* If we are here then,
2457+
* 1. Either we are not handling any mbx task and we are not
2458+
* scheduled as well
2459+
* OR
2460+
* 2. We could be handling a mbx task but nothing more is
2461+
* scheduled.
2462+
* In both cases, we should schedule mbx task as there are more
2463+
* mbx messages reported by this interrupt.
2464+
*/
2465+
hclge_mbx_task_schedule(hdev);
2466+
24332467
default:
24342468
dev_dbg(&hdev->pdev->dev,
24352469
"received unknown or unhandled event of vector0\n");
@@ -2708,6 +2742,21 @@ static void hclge_reset_service_task(struct work_struct *work)
27082742
clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
27092743
}
27102744

2745+
static void hclge_mailbox_service_task(struct work_struct *work)
2746+
{
2747+
struct hclge_dev *hdev =
2748+
container_of(work, struct hclge_dev, mbx_service_task);
2749+
2750+
if (test_and_set_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state))
2751+
return;
2752+
2753+
clear_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state);
2754+
2755+
hclge_mbx_handler(hdev);
2756+
2757+
clear_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state);
2758+
}
2759+
27112760
static void hclge_service_task(struct work_struct *work)
27122761
{
27132762
struct hclge_dev *hdev =
@@ -4815,6 +4864,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
48154864
timer_setup(&hdev->service_timer, hclge_service_timer, 0);
48164865
INIT_WORK(&hdev->service_task, hclge_service_task);
48174866
INIT_WORK(&hdev->rst_service_task, hclge_reset_service_task);
4867+
INIT_WORK(&hdev->mbx_service_task, hclge_mailbox_service_task);
48184868

48194869
/* Enable MISC vector(vector0) */
48204870
hclge_enable_vector(&hdev->misc_vector, true);
@@ -4823,6 +4873,8 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
48234873
set_bit(HCLGE_STATE_DOWN, &hdev->state);
48244874
clear_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state);
48254875
clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
4876+
clear_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state);
4877+
clear_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state);
48264878

48274879
pr_info("%s driver initialization finished.\n", HCLGE_DRIVER_NAME);
48284880
return 0;
@@ -4936,6 +4988,8 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
49364988
cancel_work_sync(&hdev->service_task);
49374989
if (hdev->rst_service_task.func)
49384990
cancel_work_sync(&hdev->rst_service_task);
4991+
if (hdev->mbx_service_task.func)
4992+
cancel_work_sync(&hdev->mbx_service_task);
49394993

49404994
if (mac->phydev)
49414995
mdiobus_unregister(mac->mdio_bus);

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@
9292
#define HCLGE_VECTOR0_CORERESET_INT_B 6
9393
#define HCLGE_VECTOR0_IMPRESET_INT_B 7
9494

95+
/* Vector0 interrupt CMDQ event source register(RW) */
96+
#define HCLGE_VECTOR0_CMDQ_SRC_REG 0x27100
97+
/* CMDQ register bits for RX event(=MBX event) */
98+
#define HCLGE_VECTOR0_RX_CMDQ_INT_B 1
99+
95100
enum HCLGE_DEV_STATE {
96101
HCLGE_STATE_REINITING,
97102
HCLGE_STATE_DOWN,
@@ -101,8 +106,8 @@ enum HCLGE_DEV_STATE {
101106
HCLGE_STATE_SERVICE_SCHED,
102107
HCLGE_STATE_RST_SERVICE_SCHED,
103108
HCLGE_STATE_RST_HANDLING,
109+
HCLGE_STATE_MBX_SERVICE_SCHED,
104110
HCLGE_STATE_MBX_HANDLING,
105-
HCLGE_STATE_MBX_IRQ,
106111
HCLGE_STATE_MAX
107112
};
108113

@@ -479,6 +484,7 @@ struct hclge_dev {
479484
struct timer_list service_timer;
480485
struct work_struct service_task;
481486
struct work_struct rst_service_task;
487+
struct work_struct mbx_service_task;
482488

483489
bool cur_promisc;
484490
int num_alloc_vfs; /* Actual number of VFs allocated */

0 commit comments

Comments
 (0)