X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Favf%2Favf_vchnl.c;h=fa71014e1a3e3562239fddf206baf47b883cb880;hb=3a18c44b45dfaa4a0a6c72c2f53b2378d7009123;hp=55a425a7fe9ceb12595baf83bef1762f333c90a1;hpb=69dd4c3d0898559ef326ab8f53beec26b62cc098;p=dpdk.git diff --git a/drivers/net/avf/avf_vchnl.c b/drivers/net/avf/avf_vchnl.c index 55a425a7fe..fa71014e1a 100644 --- a/drivers/net/avf/avf_vchnl.c +++ b/drivers/net/avf/avf_vchnl.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include "avf_log.h" @@ -133,6 +133,41 @@ avf_execute_vf_cmd(struct avf_adapter *adapter, struct avf_cmd_info *args) return err; } +static void +avf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg, + uint16_t msglen) +{ + struct virtchnl_pf_event *pf_msg = + (struct virtchnl_pf_event *)msg; + struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); + + if (msglen < sizeof(struct virtchnl_pf_event)) { + PMD_DRV_LOG(DEBUG, "Error event"); + return; + } + switch (pf_msg->event) { + case VIRTCHNL_EVENT_RESET_IMPENDING: + PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event"); + _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, + NULL); + break; + case VIRTCHNL_EVENT_LINK_CHANGE: + PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event"); + vf->link_up = pf_msg->event_data.link_event.link_status; + vf->link_speed = pf_msg->event_data.link_event.link_speed; + avf_dev_link_update(dev, 0); + _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, + NULL); + break; + case VIRTCHNL_EVENT_PF_DRIVER_CLOSE: + PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_PF_DRIVER_CLOSE event"); + break; + default: + PMD_DRV_LOG(ERR, " unknown event received %u", pf_msg->event); + break; + } +} + void avf_handle_virtchnl_msg(struct rte_eth_dev *dev) { @@ -172,7 +207,8 @@ avf_handle_virtchnl_msg(struct rte_eth_dev *dev) switch (aq_opc) { case avf_aqc_opc_send_msg_to_vf: if (msg_opc == VIRTCHNL_OP_EVENT) { - /* TODO */ + avf_handle_pf_event_msg(dev, info.msg_buf, + info.msg_len); } else { /* read message and it's expected one */ if (msg_opc == vf->pend_cmd) { @@ -657,3 +693,120 @@ avf_add_del_all_mac_addr(struct avf_adapter *adapter, bool add) begin = next_begin; } while (begin < AVF_NUM_MACADDR_MAX); } + +int +avf_query_stats(struct avf_adapter *adapter, + struct virtchnl_eth_stats **pstats) +{ + struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter); + struct virtchnl_queue_select q_stats; + struct avf_cmd_info args; + int err; + + memset(&q_stats, 0, sizeof(q_stats)); + q_stats.vsi_id = vf->vsi_res->vsi_id; + args.ops = VIRTCHNL_OP_GET_STATS; + args.in_args = (uint8_t *)&q_stats; + args.in_args_size = sizeof(q_stats); + args.out_buffer = vf->aq_resp; + args.out_size = AVF_AQ_BUF_SZ; + + err = avf_execute_vf_cmd(adapter, &args); + if (err) { + PMD_DRV_LOG(ERR, "fail to execute command OP_GET_STATS"); + *pstats = NULL; + return err; + } + *pstats = (struct virtchnl_eth_stats *)args.out_buffer; + return 0; +} + +int +avf_config_promisc(struct avf_adapter *adapter, + bool enable_unicast, + bool enable_multicast) +{ + struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter); + struct virtchnl_promisc_info promisc; + struct avf_cmd_info args; + int err; + + promisc.flags = 0; + promisc.vsi_id = vf->vsi_res->vsi_id; + + if (enable_unicast) + promisc.flags |= FLAG_VF_UNICAST_PROMISC; + + if (enable_multicast) + promisc.flags |= FLAG_VF_MULTICAST_PROMISC; + + args.ops = VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE; + args.in_args = (uint8_t *)&promisc; + args.in_args_size = sizeof(promisc); + args.out_buffer = vf->aq_resp; + args.out_size = AVF_AQ_BUF_SZ; + + err = avf_execute_vf_cmd(adapter, &args); + + if (err) + PMD_DRV_LOG(ERR, + "fail to execute command CONFIG_PROMISCUOUS_MODE"); + return err; +} + +int +avf_add_del_eth_addr(struct avf_adapter *adapter, struct ether_addr *addr, + bool add) +{ + struct virtchnl_ether_addr_list *list; + struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter); + uint8_t cmd_buffer[sizeof(struct virtchnl_ether_addr_list) + + sizeof(struct virtchnl_ether_addr)]; + struct avf_cmd_info args; + int err; + + list = (struct virtchnl_ether_addr_list *)cmd_buffer; + list->vsi_id = vf->vsi_res->vsi_id; + list->num_elements = 1; + rte_memcpy(list->list[0].addr, addr->addr_bytes, + sizeof(addr->addr_bytes)); + + args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR : VIRTCHNL_OP_DEL_ETH_ADDR; + args.in_args = cmd_buffer; + args.in_args_size = sizeof(cmd_buffer); + args.out_buffer = vf->aq_resp; + args.out_size = AVF_AQ_BUF_SZ; + err = avf_execute_vf_cmd(adapter, &args); + if (err) + PMD_DRV_LOG(ERR, "fail to execute command %s", + add ? "OP_ADD_ETH_ADDR" : "OP_DEL_ETH_ADDR"); + return err; +} + +int +avf_add_del_vlan(struct avf_adapter *adapter, uint16_t vlanid, bool add) +{ + struct virtchnl_vlan_filter_list *vlan_list; + struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter); + uint8_t cmd_buffer[sizeof(struct virtchnl_vlan_filter_list) + + sizeof(uint16_t)]; + struct avf_cmd_info args; + int err; + + vlan_list = (struct virtchnl_vlan_filter_list *)cmd_buffer; + vlan_list->vsi_id = vf->vsi_res->vsi_id; + vlan_list->num_elements = 1; + vlan_list->vlan_id[0] = vlanid; + + args.ops = add ? VIRTCHNL_OP_ADD_VLAN : VIRTCHNL_OP_DEL_VLAN; + args.in_args = cmd_buffer; + args.in_args_size = sizeof(cmd_buffer); + args.out_buffer = vf->aq_resp; + args.out_size = AVF_AQ_BUF_SZ; + err = avf_execute_vf_cmd(adapter, &args); + if (err) + PMD_DRV_LOG(ERR, "fail to execute command %s", + add ? "OP_ADD_VLAN" : "OP_DEL_VLAN"); + + return err; +}