|
21 | 21 | #include "octep_pfvf_mbox.h"
|
22 | 22 | #include "octep_ctrl_net.h"
|
23 | 23 |
|
| 24 | +/* When a new command is implemented, the below table should be updated |
| 25 | + * with new command and it's version info. |
| 26 | + */ |
| 27 | +static u32 pfvf_cmd_versions[OCTEP_PFVF_MBOX_CMD_MAX] = { |
| 28 | + [0 ... OCTEP_PFVF_MBOX_CMD_DEV_REMOVE] = OCTEP_PFVF_MBOX_VERSION_V1, |
| 29 | + [OCTEP_PFVF_MBOX_CMD_GET_FW_INFO ... OCTEP_PFVF_MBOX_NOTIF_LINK_STATUS] = |
| 30 | + OCTEP_PFVF_MBOX_VERSION_V2 |
| 31 | +}; |
| 32 | + |
24 | 33 | static void octep_pfvf_validate_version(struct octep_device *oct, u32 vf_id,
|
25 | 34 | union octep_pfvf_mbox_word cmd,
|
26 | 35 | union octep_pfvf_mbox_word *rsp)
|
@@ -87,6 +96,34 @@ static void octep_pfvf_set_rx_state(struct octep_device *oct, u32 vf_id,
|
87 | 96 | rsp->s_link_state.type = OCTEP_PFVF_MBOX_TYPE_RSP_ACK;
|
88 | 97 | }
|
89 | 98 |
|
| 99 | +static int octep_send_notification(struct octep_device *oct, u32 vf_id, |
| 100 | + union octep_pfvf_mbox_word cmd) |
| 101 | +{ |
| 102 | + u32 max_rings_per_vf, vf_mbox_queue; |
| 103 | + struct octep_mbox *mbox; |
| 104 | + |
| 105 | + /* check if VF PF Mailbox is compatible for this notification */ |
| 106 | + if (pfvf_cmd_versions[cmd.s.opcode] > oct->vf_info[vf_id].mbox_version) { |
| 107 | + dev_dbg(&oct->pdev->dev, "VF Mbox doesn't support Notification:%d on VF ver:%d\n", |
| 108 | + cmd.s.opcode, oct->vf_info[vf_id].mbox_version); |
| 109 | + return -EOPNOTSUPP; |
| 110 | + } |
| 111 | + |
| 112 | + max_rings_per_vf = CFG_GET_MAX_RPVF(oct->conf); |
| 113 | + vf_mbox_queue = vf_id * max_rings_per_vf; |
| 114 | + if (!oct->mbox[vf_mbox_queue]) { |
| 115 | + dev_err(&oct->pdev->dev, "Notif obtained for bad mbox vf %d\n", vf_id); |
| 116 | + return -EINVAL; |
| 117 | + } |
| 118 | + mbox = oct->mbox[vf_mbox_queue]; |
| 119 | + |
| 120 | + mutex_lock(&mbox->lock); |
| 121 | + writeq(cmd.u64, mbox->pf_vf_data_reg); |
| 122 | + mutex_unlock(&mbox->lock); |
| 123 | + |
| 124 | + return 0; |
| 125 | +} |
| 126 | + |
90 | 127 | static void octep_pfvf_set_mtu(struct octep_device *oct, u32 vf_id,
|
91 | 128 | union octep_pfvf_mbox_word cmd,
|
92 | 129 | union octep_pfvf_mbox_word *rsp)
|
@@ -326,6 +363,27 @@ static void octep_pfvf_pf_get_data(struct octep_device *oct,
|
326 | 363 | }
|
327 | 364 | }
|
328 | 365 |
|
| 366 | +void octep_pfvf_notify(struct octep_device *oct, struct octep_ctrl_mbox_msg *msg) |
| 367 | +{ |
| 368 | + union octep_pfvf_mbox_word notif = { 0 }; |
| 369 | + struct octep_ctrl_net_f2h_req *req; |
| 370 | + |
| 371 | + req = (struct octep_ctrl_net_f2h_req *)msg->sg_list[0].msg; |
| 372 | + switch (req->hdr.s.cmd) { |
| 373 | + case OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS: |
| 374 | + notif.s_link_status.opcode = OCTEP_PFVF_MBOX_NOTIF_LINK_STATUS; |
| 375 | + notif.s_link_status.status = req->link.state; |
| 376 | + break; |
| 377 | + default: |
| 378 | + pr_info("Unknown mbox notif for vf: %u\n", |
| 379 | + req->hdr.s.cmd); |
| 380 | + return; |
| 381 | + } |
| 382 | + |
| 383 | + notif.s.type = OCTEP_PFVF_MBOX_TYPE_CMD; |
| 384 | + octep_send_notification(oct, msg->hdr.s.vf_idx, notif); |
| 385 | +} |
| 386 | + |
329 | 387 | void octep_pfvf_mbox_work(struct work_struct *work)
|
330 | 388 | {
|
331 | 389 | struct octep_pfvf_mbox_wk *wk = container_of(work, struct octep_pfvf_mbox_wk, work);
|
|
0 commit comments