diff options
author | Aviad Krawczyk | 2017-08-21 17:55:55 +0200 |
---|---|---|
committer | David S. Miller | 2017-08-22 19:48:53 +0200 |
commit | c4d06d2d208a6cd86bc76e52473cc853f83cad03 (patch) | |
tree | 656ce803be33457218210eaf26a25ea6972c38e8 /drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c | |
parent | net-next/hinic: Add port management commands (diff) | |
download | kernel-qcow2-linux-c4d06d2d208a6cd86bc76e52473cc853f83cad03.tar.gz kernel-qcow2-linux-c4d06d2d208a6cd86bc76e52473cc853f83cad03.tar.xz kernel-qcow2-linux-c4d06d2d208a6cd86bc76e52473cc853f83cad03.zip |
net-next/hinic: Add Rx mode and link event handler
Add port management message for setting Rx mode in the card,
used for rx_mode netdev operation.
The link event handler is used for getting a notification about the
link state.
Signed-off-by: Aviad Krawczyk <aviad.krawczyk@huawei.com>
Signed-off-by: Zhao Chen <zhaochen6@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c')
-rw-r--r-- | drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c index 0150b71a5aba..278dc13f3dae 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c @@ -73,6 +73,46 @@ enum msg_ack_type { }; /** + * hinic_register_mgmt_msg_cb - register msg handler for a msg from a module + * @pf_to_mgmt: PF to MGMT channel + * @mod: module in the chip that this handler will handle its messages + * @handle: private data for the callback + * @callback: the handler that will handle messages + **/ +void hinic_register_mgmt_msg_cb(struct hinic_pf_to_mgmt *pf_to_mgmt, + enum hinic_mod_type mod, + void *handle, + void (*callback)(void *handle, + u8 cmd, void *buf_in, + u16 in_size, void *buf_out, + u16 *out_size)) +{ + struct hinic_mgmt_cb *mgmt_cb = &pf_to_mgmt->mgmt_cb[mod]; + + mgmt_cb->cb = callback; + mgmt_cb->handle = handle; + mgmt_cb->state = HINIC_MGMT_CB_ENABLED; +} + +/** + * hinic_unregister_mgmt_msg_cb - unregister msg handler for a msg from a module + * @pf_to_mgmt: PF to MGMT channel + * @mod: module in the chip that this handler handles its messages + **/ +void hinic_unregister_mgmt_msg_cb(struct hinic_pf_to_mgmt *pf_to_mgmt, + enum hinic_mod_type mod) +{ + struct hinic_mgmt_cb *mgmt_cb = &pf_to_mgmt->mgmt_cb[mod]; + + mgmt_cb->state &= ~HINIC_MGMT_CB_ENABLED; + + while (mgmt_cb->state & HINIC_MGMT_CB_RUNNING) + schedule(); + + mgmt_cb->cb = NULL; +} + +/** * prepare_header - prepare the header of the message * @pf_to_mgmt: PF to MGMT channel * @msg_len: the length of the message @@ -337,9 +377,31 @@ static void mgmt_recv_msg_handler(struct hinic_pf_to_mgmt *pf_to_mgmt, struct hinic_hwif *hwif = pf_to_mgmt->hwif; struct pci_dev *pdev = hwif->pdev; u8 *buf_out = recv_msg->buf_out; + struct hinic_mgmt_cb *mgmt_cb; + unsigned long cb_state; u16 out_size = 0; - dev_err(&pdev->dev, "No MGMT msg handler, mod = %d\n", recv_msg->mod); + if (recv_msg->mod >= HINIC_MOD_MAX) { + dev_err(&pdev->dev, "Unknown MGMT MSG module = %d\n", + recv_msg->mod); + return; + } + + mgmt_cb = &pf_to_mgmt->mgmt_cb[recv_msg->mod]; + + cb_state = cmpxchg(&mgmt_cb->state, + HINIC_MGMT_CB_ENABLED, + HINIC_MGMT_CB_ENABLED | HINIC_MGMT_CB_RUNNING); + + if ((cb_state == HINIC_MGMT_CB_ENABLED) && (mgmt_cb->cb)) + mgmt_cb->cb(mgmt_cb->handle, recv_msg->cmd, + recv_msg->msg, recv_msg->msg_len, + buf_out, &out_size); + else + dev_err(&pdev->dev, "No MGMT msg handler, mod = %d\n", + recv_msg->mod); + + mgmt_cb->state &= ~HINIC_MGMT_CB_RUNNING; if (!recv_msg->async_mgmt_to_pf) /* MGMT sent sync msg, send the response */ |