From: Bernard Iremonger <hidden> Date: 2016-08-18 13:48:50
This RFC patchset contains new DPDK API's requested by AT&T for use
with the Virtual Function Daemon (VFD).
The need to configure and manage VF's on a NIC has grown to the
point where AT&T have devloped a DPDK based tool, VFD, to do this.
This RFC proposes to add the following API extensions to DPDK:
mailbox communication callback support
VF configuration
Nine new functions have been added to the eth_dev_ops structure.
Corresponding functions have been added to the ixgbe PMD for the
Niantic NIC.
Two new callback functions have been added.
Changes have been made to the ixgbe_rcv_msg_from_vf function to
use the callback functions.
Changes have been made to testpmd to facilitate testing of the new API's.
The testpmd documentation has been updated to document the testpmd changes.
Note:
Adding new functions to the eth_dev_ops structure will cause an
ABI breakage.
Bernard Iremonger (5):
librte_ether: add internal callback functions
net/ixgbe: add callback to user app on VF to PF mbox msg
librte_ether: add API's for VF management
net/ixgbe: add functions for VF management
app/test_pmd: add tests for new API's
app/test-pmd/cmdline.c | 700 ++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 68 ++-
drivers/net/ixgbe/ixgbe_ethdev.c | 179 +++++++
drivers/net/ixgbe/ixgbe_pf.c | 39 +-
lib/librte_ether/rte_ethdev.c | 176 +++++++
lib/librte_ether/rte_ethdev.h | 284 +++++++++++
lib/librte_ether/rte_ether_version.map | 16 +
7 files changed, 1455 insertions(+), 7 deletions(-)
--
2.9.0
From: Bernard Iremonger <hidden> Date: 2016-08-18 13:48:52
add _rte_eth_dev_callback_process_vf function.
add _rte_eth_dev_callback_process_generic function
Adding a callback to the user application on VF to PF mailbox message,
allows passing information to the application controlling the PF
when a VF mailbox event message is received, such as VF reset.
Signed-off-by: azelezniak <redacted>
Signed-off-by: Bernard Iremonger <redacted>
---
lib/librte_ether/rte_ethdev.c | 17 ++++++++++
lib/librte_ether/rte_ethdev.h | 61 ++++++++++++++++++++++++++++++++++
lib/librte_ether/rte_ether_version.map | 7 ++++
3 files changed, 85 insertions(+)
@@ -3047,9 +3047,27 @@ enum rte_eth_event_type {/**< queue state event (enabled/disabled) */RTE_ETH_EVENT_INTR_RESET,/**< reset interrupt event, sent to VF on PF reset */+RTE_ETH_EVENT_VF_MBOX,/**< PF mailbox processing callback */RTE_ETH_EVENT_MAX/**< max value of this enum */};+/**+*Responsesentbacktoixgbedriverfromuserappaftercallback+*/+enumrte_eth_mb_event_rsp{+RTE_ETH_MB_EVENT_NOOP_ACK,/**< skip mbox request and ACK */+RTE_ETH_MB_EVENT_NOOP_NACK,/**< skip mbox request and NACK */+RTE_ETH_MB_EVENT_PROCEED,/**< proceed with mbox request */+RTE_ETH_MB_EVENT_MAX/**< max value of this enum */+};++structrte_eth_mb_event_param{+uint16_tvfid;+uint16_tmsg_type;+uint16_tretval;+void*userdata;+};+typedefvoid(*rte_eth_dev_cb_fn)(uint8_tport_id,\enumrte_eth_event_typeevent,void*cb_arg);/**< user application callback to be registered for interrupts */
From: Bernard Iremonger <hidden> Date: 2016-08-18 13:48:53
call _rte_eth_dev_callback_process_vf from ixgbe_rcv_msg_from_vf function.
The callback asks the user application if it is allowed to perform
the function.
If the cb_param.retval is RTE_ETH_MB_EVENT_PROCEED then continue,
if 0, do nothing and send ACK to VF
if > 1, do nothing and send NAK to VF.
Signed-off-by: azelezniak <redacted>
Signed-off-by: Bernard Iremonger <redacted>
---
drivers/net/ixgbe/ixgbe_pf.c | 39 ++++++++++++++++++++++++++++++++++-----
1 file changed, 34 insertions(+), 5 deletions(-)
@@ -674,27 +675,54 @@ ixgbe_rcv_msg_from_vf(struct rte_eth_dev *dev, uint16_t vf)/* flush the ack before we write any messages back */IXGBE_WRITE_FLUSH(hw);+/**+*initialisestructuretosendtouserapplication+*willreturnresponsefromuserinretvalfield+*/+cb_param.retval=RTE_ETH_MB_EVENT_PROCEED;+cb_param.vfid=vf;+cb_param.msg_type=msgbuf[0]&0xFFFF;+cb_param.userdata=(void*)msgbuf;+/* perform VF reset */if(msgbuf[0]==IXGBE_VF_RESET){intret=ixgbe_vf_reset(dev,vf,msgbuf);vfinfo[vf].clear_to_send=true;++/* notify application about VF reset */+_rte_eth_dev_callback_process_vf(dev,RTE_ETH_EVENT_VF_MBOX,&cb_param);returnret;}+/**+*askuserapplicationifweallowedtoperformthosefunctions+*ifwegetcb_param.retval==RTE_ETH_MB_EVENT_PROCEEDthenbusiness+*asusual,+*if0,donothingandsendACKtoVF+*ifcb_param.retval>1,donothingandsendNAKtoVF+*/+_rte_eth_dev_callback_process_vf(dev,RTE_ETH_EVENT_VF_MBOX,&cb_param);++retval=cb_param.retval;+/* check & process VF to PF mailbox message */switch((msgbuf[0]&0xFFFF)){caseIXGBE_VF_SET_MAC_ADDR:-retval=ixgbe_vf_set_mac_addr(dev,vf,msgbuf);+if(retval==RTE_ETH_MB_EVENT_PROCEED)+retval=ixgbe_vf_set_mac_addr(dev,vf,msgbuf);break;caseIXGBE_VF_SET_MULTICAST:-retval=ixgbe_vf_set_multicast(dev,vf,msgbuf);+if(retval==RTE_ETH_MB_EVENT_PROCEED)+retval=ixgbe_vf_set_multicast(dev,vf,msgbuf);break;caseIXGBE_VF_SET_LPE:-retval=ixgbe_set_vf_lpe(dev,vf,msgbuf);+if(retval==RTE_ETH_MB_EVENT_PROCEED)+retval=ixgbe_set_vf_lpe(dev,vf,msgbuf);break;caseIXGBE_VF_SET_VLAN:-retval=ixgbe_vf_set_vlan(dev,vf,msgbuf);+if(retval==RTE_ETH_MB_EVENT_PROCEED)+retval=ixgbe_vf_set_vlan(dev,vf,msgbuf);break;caseIXGBE_VF_API_NEGOTIATE:retval=ixgbe_negotiate_vf_api(dev,vf,msgbuf);
@@ -4604,6 +4654,135 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,returnret;}+staticvoid+ixgbe_set_vf_vlan_anti_spoof(structrte_eth_dev*dev,+uint16_tvf,uint8_ton)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);++structixgbe_mac_info*mac=&hw->mac;++mac->ops.set_vlan_anti_spoofing(hw,on,vf);+}++staticvoid+ixgbe_set_vf_mac_anti_spoof(structrte_eth_dev*dev,+uint16_tvf,uint8_ton)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+structixgbe_mac_info*mac=&hw->mac;++mac->ops.set_mac_anti_spoofing(hw,on,vf);+}++staticint+ixgbe_vf_ping(structrte_eth_dev*dev,int32_tvf)+{+intret=0;+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);++structixgbe_vf_info*vfinfo=+*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);++u32ping;+inti;++for(i=0;i<dev->pci_dev->max_vfs;i++){+ping=IXGBE_PF_CONTROL_MSG;+if(vfinfo[i].clear_to_send)+ping|=IXGBE_VT_MSGTYPE_CTS;++/* ping every VF or only one specified */+if(vf<0||vf==i)+ixgbe_write_mbx(hw,&ping,1,i);+}++returnret;+}++staticvoid+ixgbe_set_vf_vlan_insert(structrte_eth_dev*dev,uint16_tvf,intvlan)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_tctrl;++PMD_INIT_FUNC_TRACE();++ctrl=IXGBE_READ_REG(hw,IXGBE_VMVIR(vf));+if(vlan){+ctrl=vlan;+ctrl|=IXGBE_VMVIR_VLANA_DEFAULT;+}else{+ctrl=0;+}++IXGBE_WRITE_REG(hw,IXGBE_VMVIR(vf),ctrl);+}++staticvoid+ixgbe_set_tx_loopback(structrte_eth_dev*dev,inton)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_tctrl;++PMD_INIT_FUNC_TRACE();++ctrl=IXGBE_READ_REG(hw,IXGBE_PFDTXGSWC);+/* enable or disable VMDQ loopback */+if(on)+ctrl|=IXGBE_PFDTXGSWC_VT_LBEN;+else+ctrl&=~IXGBE_PFDTXGSWC_VT_LBEN;++IXGBE_WRITE_REG(hw,IXGBE_PFDTXGSWC,ctrl);+}++staticvoid+ixgbe_set_all_queues_drop_en(structrte_eth_dev*dev,intstate)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_treg_value;+inti;+intnum_queues=(int)(IXGBE_QDE_IDX_MASK>>IXGBE_QDE_IDX_SHIFT);++PMD_INIT_FUNC_TRACE();++for(i=0;i<=num_queues;i++){+reg_value=IXGBE_QDE_WRITE|+(i<<IXGBE_QDE_IDX_SHIFT)|+(state&IXGBE_QDE_ENABLE);+IXGBE_WRITE_REG(hw,IXGBE_QDE,reg_value);+}+}++staticvoid+ixgbe_set_vf_split_drop_en(structrte_eth_dev*dev,uint16_tvf,intstate)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_treg_value;++PMD_INIT_FUNC_TRACE();++/* only support VF's 0 to 63 */+if(vf>63)+return;++reg_value=IXGBE_READ_REG(hw,IXGBE_SRRCTL(vf));+if(state)+reg_value|=IXGBE_SRRCTL_DROP_EN;+else+reg_value&=~IXGBE_SRRCTL_DROP_EN;++IXGBE_WRITE_REG(hw,IXGBE_SRRCTL(vf),reg_value);+}+#define IXGBE_MRCTL_VPME 0x01 /* Virtual Pool Mirroring. */#define IXGBE_MRCTL_UPME 0x02 /* Uplink Port Mirroring. */#define IXGBE_MRCTL_DPME 0x04 /* Downlink Port Mirroring. */
@@ -1230,6 +1230,11 @@ typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,structether_addr*mac_addr);/**< @internal Set a MAC address into Receive Address Address Register */+typedefint(*eth_set_vf_mac_addr_t)(structrte_eth_dev*dev,+uint16_tvf,+structether_addr*mac_addr);+/**< @internal Set VF address into Receive Address Address Register */+typedefint(*eth_uc_hash_table_set_t)(structrte_eth_dev*dev,structether_addr*mac_addr,uint8_ton);
@@ -1261,6 +1266,43 @@ typedef int (*eth_set_vf_vlan_filter_t)(struct rte_eth_dev *dev,uint8_tvlan_on);/**< @internal Set VF VLAN pool filter */+typedefvoid(*eth_set_vf_vlan_anti_spoof_t)(structrte_eth_dev*dev,+uint16_tvf,+uint8_ton);+/**< @internal Set VF VLAN anti spoof */++typedefvoid(*eth_set_vf_mac_anti_spoof_t)(structrte_eth_dev*dev,+uint16_tvf,+uint8_ton);+/**< @internal Set VF MAC anti spoof */++typedefint(*eth_vf_ping_t)(structrte_eth_dev*dev,+int32_tvf);+/**< @internal ping one or all vf's */++typedefvoid(*eth_set_vf_vlan_strip_t)(structrte_eth_dev*dev,+inton,+uint16_tqueues_per_pool);+/**< @internal Set VF vlan strip */++typedefvoid(*eth_set_vf_vlan_insert_t)(structrte_eth_dev*dev,+uint16_tvf,+intvlan);+/**< @internal Set VF vlan insert */++typedefvoid(*eth_set_tx_loopback_t)(structrte_eth_dev*dev,+inton);+/**< @internal Set tx loopback */++typedefvoid(*eth_set_all_queues_drop_en_t)(structrte_eth_dev*dev,+intstate);+/**< @internal Set all queues drop */++typedefvoid(*eth_set_vf_split_drop_en_t)(structrte_eth_dev*dev,+uint16_tvf,+intstate);+/**< @internal Set the enable drop bit in the VF split rx control register */+typedefint(*eth_set_queue_rate_limit_t)(structrte_eth_dev*dev,uint16_tqueue_idx,uint16_ttx_rate);
@@ -1465,6 +1507,7 @@ struct eth_dev_ops {eth_mac_addr_remove_tmac_addr_remove;/**< Remove MAC address */eth_mac_addr_add_tmac_addr_add;/**< Add a MAC address */eth_mac_addr_set_tmac_addr_set;/**< Set a MAC address */+eth_set_vf_mac_addr_tset_vf_mac_addr;/**< Set a VF MAC address */eth_uc_hash_table_set_tuc_hash_table_set;/**< Set Unicast Table Array */eth_uc_all_hash_table_set_tuc_all_hash_table_set;/**< Set Unicast hash bitmap */eth_mirror_rule_set_tmirror_rule_set;/**< Add a traffic mirror rule.*/
@@ -1473,6 +1516,14 @@ struct eth_dev_ops {eth_set_vf_rx_tset_vf_rx;/**< enable/disable a VF receive */eth_set_vf_tx_tset_vf_tx;/**< enable/disable a VF transmit */eth_set_vf_vlan_filter_tset_vf_vlan_filter;/**< Set VF VLAN filter */+eth_set_vf_vlan_anti_spoof_tset_vf_vlan_anti_spoof;/**< Set VF VLAN anti spoof */+eth_set_vf_mac_anti_spoof_tset_vf_mac_anti_spoof;/**< Set VF MAC anti spoof */+eth_vf_ping_tvf_ping;/**< Ping one or all VF's */+eth_set_vf_vlan_strip_tset_vf_vlan_strip;/** <Set VF VLAN strip */+eth_set_vf_vlan_insert_tset_vf_vlan_insert;/** <Set VF VLAN insert */+eth_set_tx_loopback_tset_tx_loopback;/** <Set tx loopback */+eth_set_all_queues_drop_en_tset_all_queues_drop_en;/** <Set queue drop enable bit */+eth_set_vf_split_drop_en_tset_vf_split_drop_en;/** <Set split drop enable bit.*//** Add UDP tunnel port. */eth_udp_tunnel_port_add_tudp_tunnel_port_add;/** Del UDP tunnel port. */
@@ -3389,7 +3440,25 @@ int rte_eth_dev_mac_addr_remove(uint8_t port, struct ether_addr *mac_addr);*/intrte_eth_dev_default_mac_addr_set(uint8_tport,structether_addr*mac_addr);+/**+*SettheVFMACaddress.+*+*@paramport+*TheportidentifieroftheEthernetdevice.+*@paramvf+*VFid.+*@parammac_addr+*VFMACaddress.+*@return+*-(0)ifsuccessful,or*mac_addr*didn'texist.+*-(-ENOTSUP)ifhardwaredoesn'tsupport.+*-(-ENODEV)if*port*invalid.+*-(-EINVAL)ifMACaddressisinvalid.+*/++intrte_eth_dev_set_vf_mac_addr(uint8_tport,uint16_tvf,+structether_addr*mac_addr);/***UpdateRedirectionTable(RETA)ofReceiveSideScalingofEthernetdevice.*
From: Bernard Iremonger <hidden> Date: 2016-08-18 13:48:56
add test for vf vlan anti spoof
add test for vf mac anti spoof
add test for vf ping
add test for vf vlan strip
add test for vf vlan insert
add test for tx loopback
add test for all queues drop enable bit
add test for vf split drop enable bit
add test for vf mac address
add new API's to the testpmd guide
Signed-off-by: Bernard Iremonger <redacted>
---
app/test-pmd/cmdline.c | 700 ++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 68 ++-
2 files changed, 766 insertions(+), 2 deletions(-)
@@ -10585,6 +10585,697 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {},};+/* vf vlan anti spoof configuration */++/* Common result structure for vf vlan anti spoof */+structcmd_vf_vlan_anti_spoof_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tantispoof;+uint8_tport_id;+uint32_tvf_id;+uint8_ton;+};++/* Common CLI fields for vf vlan anti spoof enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_antispoof=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+antispoof,"antispoof");+cmdline_parse_token_num_tcmd_vf_vlan_anti_spoof_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_anti_spoof_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vf_id,UINT32);+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_on=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+on,UINT8);++staticvoid+cmd_set_vf_vlan_anti_spoof_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_anti_spoof_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}+ret=rte_eth_dev_set_vf_vlan_anti_spoof(res->port_id,res->vf_id,res->on);+if(ret<0)+printf("vf vlan anti spoofing programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_vlan_anti_spoof={+.f=cmd_set_vf_vlan_anti_spoof_parsed,+.data=NULL,+.help_str="enable/disable vf vlan anti spoof",+.tokens={+(void*)&cmd_vf_vlan_anti_spoof_set,+(void*)&cmd_vf_vlan_anti_spoof_vf,+(void*)&cmd_vf_vlan_anti_spoof_vlan,+(void*)&cmd_vf_vlan_anti_spoof_antispoof,+(void*)&cmd_vf_vlan_anti_spoof_port_id,+(void*)&cmd_vf_vlan_anti_spoof_vf_id,+(void*)&cmd_vf_vlan_anti_spoof_on,+NULL,+},+};++/* vf mac anti spoof configuration */++/* Common result structure for vf mac anti spoof */+structcmd_vf_mac_anti_spoof_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tmac;+cmdline_fixed_string_tantispoof;+uint8_tport_id;+uint32_tvf_id;+uint8_ton;+};++/* Common CLI fields for vf mac anti spoof enable disable */+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_mac=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+mac,"mac");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_antispoof=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+antispoof,"antispoof");+cmdline_parse_token_num_tcmd_vf_mac_anti_spoof_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_mac_anti_spoof_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+vf_id,UINT32);+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_on=+TOKEN_NUM_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+on,UINT8);++staticvoid+cmd_set_vf_mac_anti_spoof_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_mac_anti_spoof_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_mac_anti_spoof(res->port_id,res->vf_id,res->on);+if(ret<0)+printf("vf vlan mac spoofing programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_mac_anti_spoof={+.f=cmd_set_vf_mac_anti_spoof_parsed,+.data=NULL,+.help_str="enable/disable vf mac anti spoof",+.tokens={+(void*)&cmd_vf_mac_anti_spoof_set,+(void*)&cmd_vf_mac_anti_spoof_vf,+(void*)&cmd_vf_mac_anti_spoof_mac,+(void*)&cmd_vf_mac_anti_spoof_antispoof,+(void*)&cmd_vf_mac_anti_spoof_port_id,+(void*)&cmd_vf_mac_anti_spoof_vf_id,+(void*)&cmd_vf_mac_anti_spoof_on,+NULL,+},+};++/* vf ping configuration */++/* Common result structure for vf ping */+structcmd_vf_ping_result{+cmdline_fixed_string_tvf;+cmdline_fixed_string_tping;+uint8_tport_id;+int32_tvf_id;+};++/* Common CLI fields for ping vfs */+cmdline_parse_token_string_tcmd_vf_ping_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_ping_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_ping_ping=+TOKEN_STRING_INITIALIZER+(structcmd_vf_ping_result,+ping,"ping");+cmdline_parse_token_num_tcmd_vf_ping_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_ping_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_ping_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_ping_result,+vf_id,INT32);++staticvoid+cmd_vf_ping_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_ping_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_vf_ping(res->port_id,res->vf_id);+if(ret<0)+printf("ping vfs programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_vf_ping={+.f=cmd_vf_ping_parsed,+.data=NULL,+.help_str="ping all or specified vf",+.tokens={+(void*)&cmd_vf_ping_vf,+(void*)&cmd_vf_ping_ping,+(void*)&cmd_vf_ping_port_id,+(void*)&cmd_vf_ping_vf_id,+NULL,+},+};++/* vf vlan strip configuration */++/* Common result structure for vf mac anti spoof */+structcmd_vf_vlan_strip_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tstrip;+uint8_tport_id;+uint16_tvf_id;+uint8_ton;+};++/* Common CLI fields for vf vlan strip enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_strip_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_strip_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_strip_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_strip_strip=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+strip,"strip");+cmdline_parse_token_num_tcmd_vf_vlan_strip_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_strip_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_strip_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_strip_result,+vf_id,UINT16);+cmdline_parse_token_string_tcmd_vf_vlan_strip_on=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_strip_result,+on,UINT8);++staticvoid+cmd_set_vf_vlan_strip_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_strip_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_vlan_strip(res->port_id,res->vf_id,res->on);+if(ret<0)+printf("vf vlan strip programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_vlan_strip={+.f=cmd_set_vf_vlan_strip_parsed,+.data=NULL,+.help_str="enable/disable vf vlan strip",+.tokens={+(void*)&cmd_vf_vlan_strip_set,+(void*)&cmd_vf_vlan_strip_vf,+(void*)&cmd_vf_vlan_strip_vlan,+(void*)&cmd_vf_vlan_strip_strip,+(void*)&cmd_vf_vlan_strip_port_id,+(void*)&cmd_vf_vlan_strip_vf_id,+(void*)&cmd_vf_vlan_strip_on,+NULL,+},+};++/* vf vlan insert configuration */++/* Common result structure for vf vlan insert */+structcmd_vf_vlan_insert_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tinsert;+uint8_tport_id;+uint16_tvf_id;+uint8_ton;+};++/* Common CLI fields for vf vlan insert enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_insert_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_insert_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_insert_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_insert_insert=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+insert,"insert");+cmdline_parse_token_num_tcmd_vf_vlan_insert_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_insert_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_insert_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_insert_result,+vf_id,UINT16);+cmdline_parse_token_string_tcmd_vf_vlan_insert_on=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_insert_result,+on,UINT8);++staticvoid+cmd_set_vf_vlan_insert_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_insert_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_vlan_insert(res->port_id,res->vf_id,res->on);+if(ret<0)+printf("vf vlan insert programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_vlan_insert={+.f=cmd_set_vf_vlan_insert_parsed,+.data=NULL,+.help_str="enable/disable vf vlan insert",+.tokens={+(void*)&cmd_vf_vlan_insert_set,+(void*)&cmd_vf_vlan_insert_vf,+(void*)&cmd_vf_vlan_insert_vlan,+(void*)&cmd_vf_vlan_insert_insert,+(void*)&cmd_vf_vlan_insert_port_id,+(void*)&cmd_vf_vlan_insert_vf_id,+(void*)&cmd_vf_vlan_insert_on,+NULL,+},+};++/* tx loopback configuration */++/* Common result structure for tx loopback */+structcmd_tx_loopback_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_ttx;+cmdline_fixed_string_tloopback;+uint8_tport_id;+uint8_ton;+};++/* Common CLI fields for tx loopback enable disable */+cmdline_parse_token_string_tcmd_tx_loopback_set=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+set,"set");+cmdline_parse_token_string_tcmd_tx_loopback_tx=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+tx,"tx");+cmdline_parse_token_string_tcmd_tx_loopback_loopback=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+loopback,"loopback");+cmdline_parse_token_num_tcmd_tx_loopback_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_tx_loopback_result,+port_id,UINT8);+cmdline_parse_token_string_tcmd_tx_loopback_on=+TOKEN_NUM_INITIALIZER+(structcmd_tx_loopback_result,+on,UINT8);++staticvoid+cmd_set_tx_loopback_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_tx_loopback_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++ret=rte_eth_dev_set_tx_loopback(res->port_id,res->on);+if(ret<0)+printf("tx loopback programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_tx_loopback={+.f=cmd_set_tx_loopback_parsed,+.data=NULL,+.help_str="enable/disable vf vlan insert",+.tokens={+(void*)&cmd_tx_loopback_set,+(void*)&cmd_tx_loopback_tx,+(void*)&cmd_tx_loopback_loopback,+(void*)&cmd_tx_loopback_port_id,+(void*)&cmd_tx_loopback_on,+NULL,+},+};++/* all queues drop enable configuration */++/* Common result structure for all queues drop enable */+structcmd_all_queues_drop_en_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tall;+cmdline_fixed_string_tqueues;+cmdline_fixed_string_tdrop;+uint8_tport_id;+uint8_ton;+};++/* Common CLI fields for tx loopback enable disable */+cmdline_parse_token_string_tcmd_all_queues_drop_en_set=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+set,"set");+cmdline_parse_token_string_tcmd_all_queues_drop_en_all=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+all,"all");+cmdline_parse_token_string_tcmd_all_queues_drop_en_queues=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+queues,"queues");+cmdline_parse_token_string_tcmd_all_queues_drop_en_drop=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+drop,"drop");+cmdline_parse_token_num_tcmd_all_queues_drop_en_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_all_queues_drop_en_result,+port_id,UINT8);+cmdline_parse_token_string_tcmd_all_queues_drop_en_on=+TOKEN_NUM_INITIALIZER+(structcmd_all_queues_drop_en_result,+on,UINT8);++staticvoid+cmd_set_all_queues_drop_en_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_all_queues_drop_en_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++ret=rte_eth_dev_set_all_queues_drop_en(res->port_id,res->on);+if(ret<0)+printf("all queues drop enable programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_all_queues_drop_en={+.f=cmd_set_all_queues_drop_en_parsed,+.data=NULL,+.help_str="enable/disable all queues drop enable bits",+.tokens={+(void*)&cmd_all_queues_drop_en_set,+(void*)&cmd_all_queues_drop_en_all,+(void*)&cmd_all_queues_drop_en_queues,+(void*)&cmd_all_queues_drop_en_drop,+(void*)&cmd_all_queues_drop_en_port_id,+(void*)&cmd_all_queues_drop_en_on,+NULL,+},+};++/* vf split drop enable configuration */++/* Common result structure for vf split drop enable */+structcmd_vf_split_drop_en_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tsplit;+cmdline_fixed_string_tdrop;+uint8_tport_id;+uint16_tvf_id;+uint8_ton;+};++/* Common CLI fields for vf split drop enable disable */+cmdline_parse_token_string_tcmd_vf_split_drop_en_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_split_drop_en_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_split_drop_en_split=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+split,"split");+cmdline_parse_token_string_tcmd_vf_split_drop_en_drop=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+drop,"drop");+cmdline_parse_token_num_tcmd_vf_split_drop_en_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_split_drop_en_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_split_drop_en_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_split_drop_en_result,+vf_id,UINT16);+cmdline_parse_token_string_tcmd_vf_split_drop_en_on=+TOKEN_NUM_INITIALIZER+(structcmd_vf_split_drop_en_result,+on,UINT8);++staticvoid+cmd_set_vf_split_drop_en_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_split_drop_en_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_split_drop_en(res->port_id,res->vf_id,res->on);+if(ret<0)+printf("vf split drop enable programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_split_drop_en={+.f=cmd_set_vf_split_drop_en_parsed,+.data=NULL,+.help_str="enable/disable vf split drop enable",+.tokens={+(void*)&cmd_vf_split_drop_en_set,+(void*)&cmd_vf_split_drop_en_vf,+(void*)&cmd_vf_split_drop_en_split,+(void*)&cmd_vf_split_drop_en_drop,+(void*)&cmd_vf_split_drop_en_port_id,+(void*)&cmd_vf_split_drop_en_vf_id,+(void*)&cmd_vf_split_drop_en_on,+NULL,+},+};++/* vf mac address configuration */++/* Common result structure for vf mac address */+structcmd_set_vf_mac_addr_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tmac;+cmdline_fixed_string_taddr;+uint8_tport_id;+uint16_tvf_id;+structether_addrmac_addr;++};++/* Common CLI fields for vf split drop enable disable */+cmdline_parse_token_string_tcmd_set_vf_mac_addr_set=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+set,"set");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_vf=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+vf,"vf");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_mac=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+mac,"mac");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_addr=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+addr,"addr");+cmdline_parse_token_num_tcmd_set_vf_mac_addr_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_set_vf_mac_addr_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_set_vf_mac_addr_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_set_vf_mac_addr_result,+vf_id,UINT16);+cmdline_parse_token_etheraddr_tcmd_set_vf_mac_addr_mac_addr=+TOKEN_ETHERADDR_INITIALIZER(structcmd_set_vf_mac_addr_result,+mac_addr);++staticvoid+cmd_set_vf_mac_addr_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_set_vf_mac_addr_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_mac_addr(res->port_id,res->vf_id,&res->mac_addr);+if(ret<0)+printf("set vf mac addr programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_mac_addr={+.f=cmd_set_vf_mac_addr_parsed,+.data=NULL,+.help_str="set vf mac address",+.tokens={+(void*)&cmd_set_vf_mac_addr_set,+(void*)&cmd_set_vf_mac_addr_vf,+(void*)&cmd_set_vf_mac_addr_mac,+(void*)&cmd_set_vf_mac_addr_addr,+(void*)&cmd_set_vf_mac_addr_port_id,+(void*)&cmd_set_vf_mac_addr_vf_id,+(void*)&cmd_set_vf_mac_addr_mac_addr,+NULL,+},+};+/* ******************************************************************************** *//* list of instructions */
@@ -473,6 +473,41 @@ For example, to change the port forwarding: RX P=1/Q=0 (socket 0) -> TX P=3/Q=0 (socket 0) peer=02:00:00:00:00:03 RX P=3/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:02+set tx loopback+~~~~~~~~~~~~~~~++Enable/disable tx loopback::++ testpmd> set tx loopback (port_id) (on|off)++set drop enable+~~~~~~~~~~~~~~~++set drop enable bit for all queues::++ testpmd> set all queues drop (port_id) (on|off)++set split drop enable (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++set split drop enable bit for VF from PF::++ testpmd> set vf split drop (port_id) (vf_id) (on|off)++set mac antispoof (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~++Set mac antispoof for a VF from the PF::++ testpmd> set vf mac antispoof (port_id) (vf_id) (on|off)++ping VF+~~~~~~~++Ping VF or all VF's from PF::++ testpmd> vf ping (port_id) (vf_id | -1)+ vlan set strip ~~~~~~~~~~~~~~
@@ -487,6 +522,28 @@ Set the VLAN strip for a queue on a port:: testpmd> vlan set stripq (on|off) (port_id,queue_id)+vlan set strip (for VF)+~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN strip for a VF from the PF::++ testpmd> set vf vlan strip (port_id) (vf_id) (on|off)++vlan set insert (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN insert for a VF from the PF::++ testpmd> set vf vlan insert (port_id) (vf_id) (on|off)++vlan set antispoof (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN antispoof for a VF from the PF::++ testpmd> set vf vlan antispoof (port_id) (vf_id) (on|off)++ vlan set filter ~~~~~~~~~~~~~~~
@@ -727,13 +784,20 @@ Remove a MAC address from a port:: testpmd> mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)-mac_addr add(for VF)-~~~~~~~~~~~~~~~~~~~~+mac_addr add (for VF)+~~~~~~~~~~~~~~~~~~~~~ Add an alternative MAC address for a VF to a port:: testpmd> mac_add add port (port_id) vf (vf_id) (XX:XX:XX:XX:XX:XX)+mac_addr set (for VF)+~~~~~~~~~~~~~~~~~~~~~++Set the MAC address for a VF from the PF::++ testpmd> set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)+ set port-uta ~~~~~~~~~~~~
From: Bernard Iremonger <hidden> Date: 2016-08-26 09:10:25
This RFC patchset contains new DPDK API's requested by AT&T for use
with the Virtual Function Daemon (VFD).
The need to configure and manage VF's on a NIC has grown to the
point where AT&T have devloped a DPDK based tool, VFD, to do this.
This RFC proposes to add the following API extensions to DPDK:
mailbox communication callback support
VF configuration
Nine new functions have been added to the eth_dev_ops structure.
Corresponding functions have been added to the ixgbe PMD for the
Niantic NIC.
Two new callback functions have been added.
Changes have been made to the ixgbe_rcv_msg_from_vf function to
use the callback functions.
Changes have been made to testpmd to facilitate testing of the new API's.
The testpmd documentation has been updated to document the testpmd changes.
Note:
Adding new functions to the eth_dev_ops structure will cause an
ABI breakage.
Changes in V2:
rebase to latest master branch.
fix compile error with clang.
Bernard Iremonger (5):
librte_ether: add internal callback functions
net/ixgbe: add callback to user app on VF to PF mbox msg
librte_ether: add API's for VF management
net/ixgbe: add functions for VF management
app/test_pmd: add tests for new API's
app/test-pmd/cmdline.c | 700 ++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 68 ++-
drivers/net/ixgbe/ixgbe_ethdev.c | 179 +++++++
drivers/net/ixgbe/ixgbe_pf.c | 39 +-
lib/librte_ether/rte_ethdev.c | 176 +++++++
lib/librte_ether/rte_ethdev.h | 284 +++++++++++
lib/librte_ether/rte_ether_version.map | 16 +
7 files changed, 1455 insertions(+), 7 deletions(-)
--
2.9.0
From: Bernard Iremonger <hidden> Date: 2016-08-26 09:10:27
add _rte_eth_dev_callback_process_vf function.
add _rte_eth_dev_callback_process_generic function
Adding a callback to the user application on VF to PF mailbox message,
allows passing information to the application controlling the PF
when a VF mailbox event message is received, such as VF reset.
Signed-off-by: azelezniak <redacted>
Signed-off-by: Bernard Iremonger <redacted>
---
lib/librte_ether/rte_ethdev.c | 17 ++++++++++
lib/librte_ether/rte_ethdev.h | 61 ++++++++++++++++++++++++++++++++++
lib/librte_ether/rte_ether_version.map | 7 ++++
3 files changed, 85 insertions(+)
@@ -3047,9 +3047,27 @@ enum rte_eth_event_type {/**< queue state event (enabled/disabled) */RTE_ETH_EVENT_INTR_RESET,/**< reset interrupt event, sent to VF on PF reset */+RTE_ETH_EVENT_VF_MBOX,/**< PF mailbox processing callback */RTE_ETH_EVENT_MAX/**< max value of this enum */};+/**+*Responsesentbacktoixgbedriverfromuserappaftercallback+*/+enumrte_eth_mb_event_rsp{+RTE_ETH_MB_EVENT_NOOP_ACK,/**< skip mbox request and ACK */+RTE_ETH_MB_EVENT_NOOP_NACK,/**< skip mbox request and NACK */+RTE_ETH_MB_EVENT_PROCEED,/**< proceed with mbox request */+RTE_ETH_MB_EVENT_MAX/**< max value of this enum */+};++structrte_eth_mb_event_param{+uint16_tvfid;+uint16_tmsg_type;+uint16_tretval;+void*userdata;+};+typedefvoid(*rte_eth_dev_cb_fn)(uint8_tport_id,\enumrte_eth_event_typeevent,void*cb_arg);/**< user application callback to be registered for interrupts */
From: Bernard Iremonger <hidden> Date: 2016-08-26 09:10:28
call _rte_eth_dev_callback_process_vf from ixgbe_rcv_msg_from_vf function.
The callback asks the user application if it is allowed to perform
the function.
If the cb_param.retval is RTE_ETH_MB_EVENT_PROCEED then continue,
if 0, do nothing and send ACK to VF
if > 1, do nothing and send NAK to VF.
Signed-off-by: azelezniak <redacted>
Signed-off-by: Bernard Iremonger <redacted>
---
drivers/net/ixgbe/ixgbe_pf.c | 39 ++++++++++++++++++++++++++++++++++-----
1 file changed, 34 insertions(+), 5 deletions(-)
@@ -674,27 +675,54 @@ ixgbe_rcv_msg_from_vf(struct rte_eth_dev *dev, uint16_t vf)/* flush the ack before we write any messages back */IXGBE_WRITE_FLUSH(hw);+/**+*initialisestructuretosendtouserapplication+*willreturnresponsefromuserinretvalfield+*/+cb_param.retval=RTE_ETH_MB_EVENT_PROCEED;+cb_param.vfid=vf;+cb_param.msg_type=msgbuf[0]&0xFFFF;+cb_param.userdata=(void*)msgbuf;+/* perform VF reset */if(msgbuf[0]==IXGBE_VF_RESET){intret=ixgbe_vf_reset(dev,vf,msgbuf);vfinfo[vf].clear_to_send=true;++/* notify application about VF reset */+_rte_eth_dev_callback_process_vf(dev,RTE_ETH_EVENT_VF_MBOX,&cb_param);returnret;}+/**+*askuserapplicationifweallowedtoperformthosefunctions+*ifwegetcb_param.retval==RTE_ETH_MB_EVENT_PROCEEDthenbusiness+*asusual,+*if0,donothingandsendACKtoVF+*ifcb_param.retval>1,donothingandsendNAKtoVF+*/+_rte_eth_dev_callback_process_vf(dev,RTE_ETH_EVENT_VF_MBOX,&cb_param);++retval=cb_param.retval;+/* check & process VF to PF mailbox message */switch((msgbuf[0]&0xFFFF)){caseIXGBE_VF_SET_MAC_ADDR:-retval=ixgbe_vf_set_mac_addr(dev,vf,msgbuf);+if(retval==RTE_ETH_MB_EVENT_PROCEED)+retval=ixgbe_vf_set_mac_addr(dev,vf,msgbuf);break;caseIXGBE_VF_SET_MULTICAST:-retval=ixgbe_vf_set_multicast(dev,vf,msgbuf);+if(retval==RTE_ETH_MB_EVENT_PROCEED)+retval=ixgbe_vf_set_multicast(dev,vf,msgbuf);break;caseIXGBE_VF_SET_LPE:-retval=ixgbe_set_vf_lpe(dev,vf,msgbuf);+if(retval==RTE_ETH_MB_EVENT_PROCEED)+retval=ixgbe_set_vf_lpe(dev,vf,msgbuf);break;caseIXGBE_VF_SET_VLAN:-retval=ixgbe_vf_set_vlan(dev,vf,msgbuf);+if(retval==RTE_ETH_MB_EVENT_PROCEED)+retval=ixgbe_vf_set_vlan(dev,vf,msgbuf);break;caseIXGBE_VF_API_NEGOTIATE:retval=ixgbe_negotiate_vf_api(dev,vf,msgbuf);
@@ -1230,6 +1230,11 @@ typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,structether_addr*mac_addr);/**< @internal Set a MAC address into Receive Address Address Register */+typedefint(*eth_set_vf_mac_addr_t)(structrte_eth_dev*dev,+uint16_tvf,+structether_addr*mac_addr);+/**< @internal Set VF address into Receive Address Address Register */+typedefint(*eth_uc_hash_table_set_t)(structrte_eth_dev*dev,structether_addr*mac_addr,uint8_ton);
@@ -1261,6 +1266,43 @@ typedef int (*eth_set_vf_vlan_filter_t)(struct rte_eth_dev *dev,uint8_tvlan_on);/**< @internal Set VF VLAN pool filter */+typedefvoid(*eth_set_vf_vlan_anti_spoof_t)(structrte_eth_dev*dev,+uint16_tvf,+uint8_ton);+/**< @internal Set VF VLAN anti spoof */++typedefvoid(*eth_set_vf_mac_anti_spoof_t)(structrte_eth_dev*dev,+uint16_tvf,+uint8_ton);+/**< @internal Set VF MAC anti spoof */++typedefint(*eth_vf_ping_t)(structrte_eth_dev*dev,+int32_tvf);+/**< @internal ping one or all vf's */++typedefvoid(*eth_set_vf_vlan_strip_t)(structrte_eth_dev*dev,+inton,+uint16_tqueues_per_pool);+/**< @internal Set VF vlan strip */++typedefvoid(*eth_set_vf_vlan_insert_t)(structrte_eth_dev*dev,+uint16_tvf,+intvlan);+/**< @internal Set VF vlan insert */++typedefvoid(*eth_set_tx_loopback_t)(structrte_eth_dev*dev,+inton);+/**< @internal Set tx loopback */++typedefvoid(*eth_set_all_queues_drop_en_t)(structrte_eth_dev*dev,+intstate);+/**< @internal Set all queues drop */++typedefvoid(*eth_set_vf_split_drop_en_t)(structrte_eth_dev*dev,+uint16_tvf,+intstate);+/**< @internal Set the enable drop bit in the VF split rx control register */+typedefint(*eth_set_queue_rate_limit_t)(structrte_eth_dev*dev,uint16_tqueue_idx,uint16_ttx_rate);
@@ -1465,6 +1507,7 @@ struct eth_dev_ops {eth_mac_addr_remove_tmac_addr_remove;/**< Remove MAC address */eth_mac_addr_add_tmac_addr_add;/**< Add a MAC address */eth_mac_addr_set_tmac_addr_set;/**< Set a MAC address */+eth_set_vf_mac_addr_tset_vf_mac_addr;/**< Set a VF MAC address */eth_uc_hash_table_set_tuc_hash_table_set;/**< Set Unicast Table Array */eth_uc_all_hash_table_set_tuc_all_hash_table_set;/**< Set Unicast hash bitmap */eth_mirror_rule_set_tmirror_rule_set;/**< Add a traffic mirror rule.*/
@@ -1473,6 +1516,14 @@ struct eth_dev_ops {eth_set_vf_rx_tset_vf_rx;/**< enable/disable a VF receive */eth_set_vf_tx_tset_vf_tx;/**< enable/disable a VF transmit */eth_set_vf_vlan_filter_tset_vf_vlan_filter;/**< Set VF VLAN filter */+eth_set_vf_vlan_anti_spoof_tset_vf_vlan_anti_spoof;/**< Set VF VLAN anti spoof */+eth_set_vf_mac_anti_spoof_tset_vf_mac_anti_spoof;/**< Set VF MAC anti spoof */+eth_vf_ping_tvf_ping;/**< Ping one or all VF's */+eth_set_vf_vlan_strip_tset_vf_vlan_strip;/** <Set VF VLAN strip */+eth_set_vf_vlan_insert_tset_vf_vlan_insert;/** <Set VF VLAN insert */+eth_set_tx_loopback_tset_tx_loopback;/** <Set tx loopback */+eth_set_all_queues_drop_en_tset_all_queues_drop_en;/** <Set queue drop enable bit */+eth_set_vf_split_drop_en_tset_vf_split_drop_en;/** <Set split drop enable bit.*//** Add UDP tunnel port. */eth_udp_tunnel_port_add_tudp_tunnel_port_add;/** Del UDP tunnel port. */
@@ -3389,7 +3440,25 @@ int rte_eth_dev_mac_addr_remove(uint8_t port, struct ether_addr *mac_addr);*/intrte_eth_dev_default_mac_addr_set(uint8_tport,structether_addr*mac_addr);+/**+*SettheVFMACaddress.+*+*@paramport+*TheportidentifieroftheEthernetdevice.+*@paramvf+*VFid.+*@parammac_addr+*VFMACaddress.+*@return+*-(0)ifsuccessful,or*mac_addr*didn'texist.+*-(-ENOTSUP)ifhardwaredoesn'tsupport.+*-(-ENODEV)if*port*invalid.+*-(-EINVAL)ifMACaddressisinvalid.+*/++intrte_eth_dev_set_vf_mac_addr(uint8_tport,uint16_tvf,+structether_addr*mac_addr);/***UpdateRedirectionTable(RETA)ofReceiveSideScalingofEthernetdevice.*
@@ -4661,6 +4711,135 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,returnret;}+staticvoid+ixgbe_set_vf_vlan_anti_spoof(structrte_eth_dev*dev,+uint16_tvf,uint8_ton)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);++structixgbe_mac_info*mac=&hw->mac;++mac->ops.set_vlan_anti_spoofing(hw,on,vf);+}++staticvoid+ixgbe_set_vf_mac_anti_spoof(structrte_eth_dev*dev,+uint16_tvf,uint8_ton)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+structixgbe_mac_info*mac=&hw->mac;++mac->ops.set_mac_anti_spoofing(hw,on,vf);+}++staticint+ixgbe_vf_ping(structrte_eth_dev*dev,int32_tvf)+{+intret=0;+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);++structixgbe_vf_info*vfinfo=+*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);++u32ping;+inti;++for(i=0;i<dev->pci_dev->max_vfs;i++){+ping=IXGBE_PF_CONTROL_MSG;+if(vfinfo[i].clear_to_send)+ping|=IXGBE_VT_MSGTYPE_CTS;++/* ping every VF or only one specified */+if(vf<0||vf==i)+ixgbe_write_mbx(hw,&ping,1,i);+}++returnret;+}++staticvoid+ixgbe_set_vf_vlan_insert(structrte_eth_dev*dev,uint16_tvf,intvlan)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_tctrl;++PMD_INIT_FUNC_TRACE();++ctrl=IXGBE_READ_REG(hw,IXGBE_VMVIR(vf));+if(vlan){+ctrl=vlan;+ctrl|=IXGBE_VMVIR_VLANA_DEFAULT;+}else{+ctrl=0;+}++IXGBE_WRITE_REG(hw,IXGBE_VMVIR(vf),ctrl);+}++staticvoid+ixgbe_set_tx_loopback(structrte_eth_dev*dev,inton)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_tctrl;++PMD_INIT_FUNC_TRACE();++ctrl=IXGBE_READ_REG(hw,IXGBE_PFDTXGSWC);+/* enable or disable VMDQ loopback */+if(on)+ctrl|=IXGBE_PFDTXGSWC_VT_LBEN;+else+ctrl&=~IXGBE_PFDTXGSWC_VT_LBEN;++IXGBE_WRITE_REG(hw,IXGBE_PFDTXGSWC,ctrl);+}++staticvoid+ixgbe_set_all_queues_drop_en(structrte_eth_dev*dev,intstate)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_treg_value;+inti;+intnum_queues=(int)(IXGBE_QDE_IDX_MASK>>IXGBE_QDE_IDX_SHIFT);++PMD_INIT_FUNC_TRACE();++for(i=0;i<=num_queues;i++){+reg_value=IXGBE_QDE_WRITE|+(i<<IXGBE_QDE_IDX_SHIFT)|+(state&IXGBE_QDE_ENABLE);+IXGBE_WRITE_REG(hw,IXGBE_QDE,reg_value);+}+}++staticvoid+ixgbe_set_vf_split_drop_en(structrte_eth_dev*dev,uint16_tvf,intstate)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_treg_value;++PMD_INIT_FUNC_TRACE();++/* only support VF's 0 to 63 */+if(vf>63)+return;++reg_value=IXGBE_READ_REG(hw,IXGBE_SRRCTL(vf));+if(state)+reg_value|=IXGBE_SRRCTL_DROP_EN;+else+reg_value&=~IXGBE_SRRCTL_DROP_EN;++IXGBE_WRITE_REG(hw,IXGBE_SRRCTL(vf),reg_value);+}+#define IXGBE_MRCTL_VPME 0x01 /* Virtual Pool Mirroring. */#define IXGBE_MRCTL_UPME 0x02 /* Uplink Port Mirroring. */#define IXGBE_MRCTL_DPME 0x04 /* Downlink Port Mirroring. */
From: Bernard Iremonger <hidden> Date: 2016-08-26 09:10:33
add test for vf vlan anti spoof
add test for vf mac anti spoof
add test for vf ping
add test for vf vlan strip
add test for vf vlan insert
add test for tx loopback
add test for all queues drop enable bit
add test for vf split drop enable bit
add test for vf mac address
add new API's to the testpmd guide
Signed-off-by: Bernard Iremonger <redacted>
---
app/test-pmd/cmdline.c | 700 ++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 68 ++-
2 files changed, 766 insertions(+), 2 deletions(-)
@@ -10585,6 +10585,697 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {},};+/* vf vlan anti spoof configuration */++/* Common result structure for vf vlan anti spoof */+structcmd_vf_vlan_anti_spoof_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tantispoof;+uint8_tport_id;+uint32_tvf_id;+uint8_ton;+};++/* Common CLI fields for vf vlan anti spoof enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_antispoof=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+antispoof,"antispoof");+cmdline_parse_token_num_tcmd_vf_vlan_anti_spoof_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_anti_spoof_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vf_id,UINT32);+cmdline_parse_token_num_tcmd_vf_vlan_anti_spoof_on=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+on,UINT8);++staticvoid+cmd_set_vf_vlan_anti_spoof_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_anti_spoof_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}+ret=rte_eth_dev_set_vf_vlan_anti_spoof(res->port_id,res->vf_id,res->on);+if(ret<0)+printf("vf vlan anti spoofing programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_vlan_anti_spoof={+.f=cmd_set_vf_vlan_anti_spoof_parsed,+.data=NULL,+.help_str="enable/disable vf vlan anti spoof",+.tokens={+(void*)&cmd_vf_vlan_anti_spoof_set,+(void*)&cmd_vf_vlan_anti_spoof_vf,+(void*)&cmd_vf_vlan_anti_spoof_vlan,+(void*)&cmd_vf_vlan_anti_spoof_antispoof,+(void*)&cmd_vf_vlan_anti_spoof_port_id,+(void*)&cmd_vf_vlan_anti_spoof_vf_id,+(void*)&cmd_vf_vlan_anti_spoof_on,+NULL,+},+};++/* vf mac anti spoof configuration */++/* Common result structure for vf mac anti spoof */+structcmd_vf_mac_anti_spoof_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tmac;+cmdline_fixed_string_tantispoof;+uint8_tport_id;+uint32_tvf_id;+uint8_ton;+};++/* Common CLI fields for vf mac anti spoof enable disable */+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_mac=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+mac,"mac");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_antispoof=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+antispoof,"antispoof");+cmdline_parse_token_num_tcmd_vf_mac_anti_spoof_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_mac_anti_spoof_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+vf_id,UINT32);+cmdline_parse_token_num_tcmd_vf_mac_anti_spoof_on=+TOKEN_NUM_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+on,UINT8);++staticvoid+cmd_set_vf_mac_anti_spoof_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_mac_anti_spoof_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_mac_anti_spoof(res->port_id,res->vf_id,res->on);+if(ret<0)+printf("vf vlan mac spoofing programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_mac_anti_spoof={+.f=cmd_set_vf_mac_anti_spoof_parsed,+.data=NULL,+.help_str="enable/disable vf mac anti spoof",+.tokens={+(void*)&cmd_vf_mac_anti_spoof_set,+(void*)&cmd_vf_mac_anti_spoof_vf,+(void*)&cmd_vf_mac_anti_spoof_mac,+(void*)&cmd_vf_mac_anti_spoof_antispoof,+(void*)&cmd_vf_mac_anti_spoof_port_id,+(void*)&cmd_vf_mac_anti_spoof_vf_id,+(void*)&cmd_vf_mac_anti_spoof_on,+NULL,+},+};++/* vf ping configuration */++/* Common result structure for vf ping */+structcmd_vf_ping_result{+cmdline_fixed_string_tvf;+cmdline_fixed_string_tping;+uint8_tport_id;+int32_tvf_id;+};++/* Common CLI fields for ping vfs */+cmdline_parse_token_string_tcmd_vf_ping_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_ping_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_ping_ping=+TOKEN_STRING_INITIALIZER+(structcmd_vf_ping_result,+ping,"ping");+cmdline_parse_token_num_tcmd_vf_ping_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_ping_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_ping_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_ping_result,+vf_id,INT32);++staticvoid+cmd_vf_ping_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_ping_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_vf_ping(res->port_id,res->vf_id);+if(ret<0)+printf("ping vfs programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_vf_ping={+.f=cmd_vf_ping_parsed,+.data=NULL,+.help_str="ping all or specified vf",+.tokens={+(void*)&cmd_vf_ping_vf,+(void*)&cmd_vf_ping_ping,+(void*)&cmd_vf_ping_port_id,+(void*)&cmd_vf_ping_vf_id,+NULL,+},+};++/* vf vlan strip configuration */++/* Common result structure for vf mac anti spoof */+structcmd_vf_vlan_strip_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tstrip;+uint8_tport_id;+uint16_tvf_id;+uint8_ton;+};++/* Common CLI fields for vf vlan strip enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_strip_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_strip_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_strip_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_strip_strip=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+strip,"strip");+cmdline_parse_token_num_tcmd_vf_vlan_strip_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_strip_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_strip_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_strip_result,+vf_id,UINT16);+cmdline_parse_token_num_tcmd_vf_vlan_strip_on=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_strip_result,+on,UINT8);++staticvoid+cmd_set_vf_vlan_strip_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_strip_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_vlan_strip(res->port_id,res->vf_id,res->on);+if(ret<0)+printf("vf vlan strip programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_vlan_strip={+.f=cmd_set_vf_vlan_strip_parsed,+.data=NULL,+.help_str="enable/disable vf vlan strip",+.tokens={+(void*)&cmd_vf_vlan_strip_set,+(void*)&cmd_vf_vlan_strip_vf,+(void*)&cmd_vf_vlan_strip_vlan,+(void*)&cmd_vf_vlan_strip_strip,+(void*)&cmd_vf_vlan_strip_port_id,+(void*)&cmd_vf_vlan_strip_vf_id,+(void*)&cmd_vf_vlan_strip_on,+NULL,+},+};++/* vf vlan insert configuration */++/* Common result structure for vf vlan insert */+structcmd_vf_vlan_insert_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tinsert;+uint8_tport_id;+uint16_tvf_id;+uint8_ton;+};++/* Common CLI fields for vf vlan insert enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_insert_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_insert_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_insert_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_insert_insert=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+insert,"insert");+cmdline_parse_token_num_tcmd_vf_vlan_insert_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_insert_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_insert_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_insert_result,+vf_id,UINT16);+cmdline_parse_token_num_tcmd_vf_vlan_insert_on=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_insert_result,+on,UINT8);++staticvoid+cmd_set_vf_vlan_insert_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_insert_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_vlan_insert(res->port_id,res->vf_id,res->on);+if(ret<0)+printf("vf vlan insert programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_vlan_insert={+.f=cmd_set_vf_vlan_insert_parsed,+.data=NULL,+.help_str="enable/disable vf vlan insert",+.tokens={+(void*)&cmd_vf_vlan_insert_set,+(void*)&cmd_vf_vlan_insert_vf,+(void*)&cmd_vf_vlan_insert_vlan,+(void*)&cmd_vf_vlan_insert_insert,+(void*)&cmd_vf_vlan_insert_port_id,+(void*)&cmd_vf_vlan_insert_vf_id,+(void*)&cmd_vf_vlan_insert_on,+NULL,+},+};++/* tx loopback configuration */++/* Common result structure for tx loopback */+structcmd_tx_loopback_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_ttx;+cmdline_fixed_string_tloopback;+uint8_tport_id;+uint8_ton;+};++/* Common CLI fields for tx loopback enable disable */+cmdline_parse_token_string_tcmd_tx_loopback_set=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+set,"set");+cmdline_parse_token_string_tcmd_tx_loopback_tx=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+tx,"tx");+cmdline_parse_token_string_tcmd_tx_loopback_loopback=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+loopback,"loopback");+cmdline_parse_token_num_tcmd_tx_loopback_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_tx_loopback_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_tx_loopback_on=+TOKEN_NUM_INITIALIZER+(structcmd_tx_loopback_result,+on,UINT8);++staticvoid+cmd_set_tx_loopback_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_tx_loopback_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++ret=rte_eth_dev_set_tx_loopback(res->port_id,res->on);+if(ret<0)+printf("tx loopback programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_tx_loopback={+.f=cmd_set_tx_loopback_parsed,+.data=NULL,+.help_str="enable/disable vf vlan insert",+.tokens={+(void*)&cmd_tx_loopback_set,+(void*)&cmd_tx_loopback_tx,+(void*)&cmd_tx_loopback_loopback,+(void*)&cmd_tx_loopback_port_id,+(void*)&cmd_tx_loopback_on,+NULL,+},+};++/* all queues drop enable configuration */++/* Common result structure for all queues drop enable */+structcmd_all_queues_drop_en_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tall;+cmdline_fixed_string_tqueues;+cmdline_fixed_string_tdrop;+uint8_tport_id;+uint8_ton;+};++/* Common CLI fields for tx loopback enable disable */+cmdline_parse_token_string_tcmd_all_queues_drop_en_set=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+set,"set");+cmdline_parse_token_string_tcmd_all_queues_drop_en_all=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+all,"all");+cmdline_parse_token_string_tcmd_all_queues_drop_en_queues=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+queues,"queues");+cmdline_parse_token_string_tcmd_all_queues_drop_en_drop=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+drop,"drop");+cmdline_parse_token_num_tcmd_all_queues_drop_en_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_all_queues_drop_en_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_all_queues_drop_en_on=+TOKEN_NUM_INITIALIZER+(structcmd_all_queues_drop_en_result,+on,UINT8);++staticvoid+cmd_set_all_queues_drop_en_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_all_queues_drop_en_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++ret=rte_eth_dev_set_all_queues_drop_en(res->port_id,res->on);+if(ret<0)+printf("all queues drop enable programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_all_queues_drop_en={+.f=cmd_set_all_queues_drop_en_parsed,+.data=NULL,+.help_str="enable/disable all queues drop enable bits",+.tokens={+(void*)&cmd_all_queues_drop_en_set,+(void*)&cmd_all_queues_drop_en_all,+(void*)&cmd_all_queues_drop_en_queues,+(void*)&cmd_all_queues_drop_en_drop,+(void*)&cmd_all_queues_drop_en_port_id,+(void*)&cmd_all_queues_drop_en_on,+NULL,+},+};++/* vf split drop enable configuration */++/* Common result structure for vf split drop enable */+structcmd_vf_split_drop_en_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tsplit;+cmdline_fixed_string_tdrop;+uint8_tport_id;+uint16_tvf_id;+uint8_ton;+};++/* Common CLI fields for vf split drop enable disable */+cmdline_parse_token_string_tcmd_vf_split_drop_en_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_split_drop_en_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_split_drop_en_split=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+split,"split");+cmdline_parse_token_string_tcmd_vf_split_drop_en_drop=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+drop,"drop");+cmdline_parse_token_num_tcmd_vf_split_drop_en_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_split_drop_en_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_split_drop_en_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_split_drop_en_result,+vf_id,UINT16);+cmdline_parse_token_num_tcmd_vf_split_drop_en_on=+TOKEN_NUM_INITIALIZER+(structcmd_vf_split_drop_en_result,+on,UINT8);++staticvoid+cmd_set_vf_split_drop_en_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_split_drop_en_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_split_drop_en(res->port_id,res->vf_id,res->on);+if(ret<0)+printf("vf split drop enable programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_split_drop_en={+.f=cmd_set_vf_split_drop_en_parsed,+.data=NULL,+.help_str="enable/disable vf split drop enable",+.tokens={+(void*)&cmd_vf_split_drop_en_set,+(void*)&cmd_vf_split_drop_en_vf,+(void*)&cmd_vf_split_drop_en_split,+(void*)&cmd_vf_split_drop_en_drop,+(void*)&cmd_vf_split_drop_en_port_id,+(void*)&cmd_vf_split_drop_en_vf_id,+(void*)&cmd_vf_split_drop_en_on,+NULL,+},+};++/* vf mac address configuration */++/* Common result structure for vf mac address */+structcmd_set_vf_mac_addr_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tmac;+cmdline_fixed_string_taddr;+uint8_tport_id;+uint16_tvf_id;+structether_addrmac_addr;++};++/* Common CLI fields for vf split drop enable disable */+cmdline_parse_token_string_tcmd_set_vf_mac_addr_set=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+set,"set");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_vf=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+vf,"vf");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_mac=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+mac,"mac");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_addr=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+addr,"addr");+cmdline_parse_token_num_tcmd_set_vf_mac_addr_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_set_vf_mac_addr_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_set_vf_mac_addr_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_set_vf_mac_addr_result,+vf_id,UINT16);+cmdline_parse_token_etheraddr_tcmd_set_vf_mac_addr_mac_addr=+TOKEN_ETHERADDR_INITIALIZER(structcmd_set_vf_mac_addr_result,+mac_addr);++staticvoid+cmd_set_vf_mac_addr_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_set_vf_mac_addr_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_mac_addr(res->port_id,res->vf_id,&res->mac_addr);+if(ret<0)+printf("set vf mac addr programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_mac_addr={+.f=cmd_set_vf_mac_addr_parsed,+.data=NULL,+.help_str="set vf mac address",+.tokens={+(void*)&cmd_set_vf_mac_addr_set,+(void*)&cmd_set_vf_mac_addr_vf,+(void*)&cmd_set_vf_mac_addr_mac,+(void*)&cmd_set_vf_mac_addr_addr,+(void*)&cmd_set_vf_mac_addr_port_id,+(void*)&cmd_set_vf_mac_addr_vf_id,+(void*)&cmd_set_vf_mac_addr_mac_addr,+NULL,+},+};+/* ******************************************************************************** *//* list of instructions */
@@ -473,6 +473,41 @@ For example, to change the port forwarding: RX P=1/Q=0 (socket 0) -> TX P=3/Q=0 (socket 0) peer=02:00:00:00:00:03 RX P=3/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:02+set tx loopback+~~~~~~~~~~~~~~~++Enable/disable tx loopback::++ testpmd> set tx loopback (port_id) (on|off)++set drop enable+~~~~~~~~~~~~~~~++set drop enable bit for all queues::++ testpmd> set all queues drop (port_id) (on|off)++set split drop enable (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++set split drop enable bit for VF from PF::++ testpmd> set vf split drop (port_id) (vf_id) (on|off)++set mac antispoof (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~++Set mac antispoof for a VF from the PF::++ testpmd> set vf mac antispoof (port_id) (vf_id) (on|off)++ping VF+~~~~~~~++Ping VF or all VF's from PF::++ testpmd> vf ping (port_id) (vf_id | -1)+ vlan set strip ~~~~~~~~~~~~~~
@@ -487,6 +522,28 @@ Set the VLAN strip for a queue on a port:: testpmd> vlan set stripq (on|off) (port_id,queue_id)+vlan set strip (for VF)+~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN strip for a VF from the PF::++ testpmd> set vf vlan strip (port_id) (vf_id) (on|off)++vlan set insert (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN insert for a VF from the PF::++ testpmd> set vf vlan insert (port_id) (vf_id) (on|off)++vlan set antispoof (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN antispoof for a VF from the PF::++ testpmd> set vf vlan antispoof (port_id) (vf_id) (on|off)++ vlan set filter ~~~~~~~~~~~~~~~
@@ -727,13 +784,20 @@ Remove a MAC address from a port:: testpmd> mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)-mac_addr add(for VF)-~~~~~~~~~~~~~~~~~~~~+mac_addr add (for VF)+~~~~~~~~~~~~~~~~~~~~~ Add an alternative MAC address for a VF to a port:: testpmd> mac_add add port (port_id) vf (vf_id) (XX:XX:XX:XX:XX:XX)+mac_addr set (for VF)+~~~~~~~~~~~~~~~~~~~~~++Set the MAC address for a VF from the PF::++ testpmd> set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)+ set port-uta ~~~~~~~~~~~~
Hi,
Ping for comments on this patch series.
Thanks,
Reshma
-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Bernard Iremonger
Sent: Friday, August 26, 2016 10:10 AM
To: Shah, Rahul R <redacted>; Lu, Wenzhuo
[off-list ref]; dev@dpdk.org
Cc: Iremonger, Bernard <redacted>
Subject: [dpdk-dev] [RFC PATCH v2 0/5] add API's for VF management
Hi Thomas and Ferruh,
Can you take a look and provide comments on ixgbe driver and ethdev changes.
Thanks,
Reshma
-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Bernard Iremonger
Sent: Friday, August 26, 2016 10:10 AM
To: Shah, Rahul R <redacted>; Lu, Wenzhuo
[off-list ref]; dev@dpdk.org
Cc: Iremonger, Bernard <redacted>
Subject: [dpdk-dev] [RFC PATCH v2 0/5] add API's for VF management
This RFC patchset contains new DPDK API's requested by AT&T for use with the
Virtual Function Daemon (VFD).
The need to configure and manage VF's on a NIC has grown to the point where
AT&T have devloped a DPDK based tool, VFD, to do this.
This RFC proposes to add the following API extensions to DPDK:
mailbox communication callback support
VF configuration
Nine new functions have been added to the eth_dev_ops structure.
Corresponding functions have been added to the ixgbe PMD for the Niantic NIC.
Two new callback functions have been added.
Changes have been made to the ixgbe_rcv_msg_from_vf function to use the
callback functions.
Changes have been made to testpmd to facilitate testing of the new API's.
The testpmd documentation has been updated to document the testpmd
changes.
Note:
Adding new functions to the eth_dev_ops structure will cause an ABI breakage.
Changes in V2:
rebase to latest master branch.
fix compile error with clang.
Bernard Iremonger (5):
librte_ether: add internal callback functions
net/ixgbe: add callback to user app on VF to PF mbox msg
librte_ether: add API's for VF management
net/ixgbe: add functions for VF management
app/test_pmd: add tests for new API's
app/test-pmd/cmdline.c | 700 ++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 68 ++-
drivers/net/ixgbe/ixgbe_ethdev.c | 179 +++++++
drivers/net/ixgbe/ixgbe_pf.c | 39 +-
lib/librte_ether/rte_ethdev.c | 176 +++++++
lib/librte_ether/rte_ethdev.h | 284 +++++++++++
lib/librte_ether/rte_ether_version.map | 16 +
7 files changed, 1455 insertions(+), 7 deletions(-)
--
2.9.0
From: Thomas Monjalon <hidden> Date: 2016-09-09 13:02:49
2016-09-09 08:49, Pattan, Reshma:
Hi Thomas and Ferruh,
Can you take a look and provide comments on ixgbe driver and ethdev changes.
We could try.
But honestly we have a lot of work to do for DPDK, except reviews.
So I would appreciate to see more reviewers on ethdev stuff.
Volunteers are more than welcome!
From: Jerin Jacob <hidden> Date: 2016-09-09 14:11:00
On Fri, Aug 26, 2016 at 10:10:16AM +0100, Bernard Iremonger wrote:
quoted hunk
add _rte_eth_dev_callback_process_vf function.
add _rte_eth_dev_callback_process_generic function
Adding a callback to the user application on VF to PF mailbox message,
allows passing information to the application controlling the PF
when a VF mailbox event message is received, such as VF reset.
Signed-off-by: azelezniak <redacted>
Signed-off-by: Bernard Iremonger <redacted>
---
lib/librte_ether/rte_ethdev.c | 17 ++++++++++
lib/librte_ether/rte_ethdev.h | 61 ++++++++++++++++++++++++++++++++++
lib/librte_ether/rte_ether_version.map | 7 ++++
3 files changed, 85 insertions(+)
@@ -3047,9 +3047,27 @@ enum rte_eth_event_type {/**< queue state event (enabled/disabled) */RTE_ETH_EVENT_INTR_RESET,/**< reset interrupt event, sent to VF on PF reset */+RTE_ETH_EVENT_VF_MBOX,/**< PF mailbox processing callback */RTE_ETH_EVENT_MAX/**< max value of this enum */};+/**+*Responsesentbacktoixgbedriverfromuserappaftercallback+*/+enumrte_eth_mb_event_rsp{+RTE_ETH_MB_EVENT_NOOP_ACK,/**< skip mbox request and ACK */+RTE_ETH_MB_EVENT_NOOP_NACK,/**< skip mbox request and NACK */+RTE_ETH_MB_EVENT_PROCEED,/**< proceed with mbox request */+RTE_ETH_MB_EVENT_MAX/**< max value of this enum */+};
Do we really need to define the specifics of PF to VF MBOX communication
in normative ethdev specification?
Each drivers may have different PF to VF MBOX definitions so it may not be
very portable.
What is the use-case here? If its for VF configuration, I think we can
do it as separate 'sync' functions for each functionality so that
PMDs will have room hiding the specifics on MBOX definitions.
From: Jerin Jacob <hidden> Date: 2016-09-09 14:23:18
On Fri, Aug 26, 2016 at 10:10:18AM +0100, Bernard Iremonger wrote:
Add new API functions to configure and manage VF's on a NIC.
add rte_eth_dev_vf_ping function.
add rte_eth_dev_set_vf_vlan_anti_spoof function.
add rte_eth_dev_set_vf_mac_anti_spoof function.
Signed-off-by: azelezniak <redacted>
add rte_eth_dev_set_vf_vlan_strip function.
add rte_eth_dev_set_vf_vlan_insert function.
add rte_eth_dev_set_loopback function.
add rte_eth_dev_set_all_queues_drop function.
add rte_eth_dev_set_vf_split_drop_en function
add rte_eth_dev_set_vf_mac_addr function.
Do we really need to expose VF specific functions here?
It can be generic(PF/VF) function indexed only through port_id.
(example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id, uint8_t on))
For instance, In Thunderx PMD, We are not exposing a separate port_id
for PF. We only enumerate 0..N VFs as 0..N ethdev port_id
From: Yuanhan Liu <hidden> Date: 2016-09-11 12:35:25
On Fri, Aug 26, 2016 at 10:10:20AM +0100, Bernard Iremonger wrote:
add test for vf vlan anti spoof
add test for vf mac anti spoof
add test for vf ping
add test for vf vlan strip
add test for vf vlan insert
add test for tx loopback
add test for all queues drop enable bit
add test for vf split drop enable bit
add test for vf mac address
add new API's to the testpmd guide
Signed-off-by: Bernard Iremonger <redacted>
Hi,
FYI, my testrobot caught some errors when this patch is applied.
(BTW, gcc builds fine)
--yliu
---
x86_64-native-linuxapp-clang
============================
/root/dpdk/app/test-pmd/cmdline.c:10629:8: error: expression which evaluates to zero treated as a null pointer constant of type 'const char *' [-Werror,-Wnon-literal-null-conversion]
on, UINT8);
^~~~~
/root/dpdk/x86_64-native-linuxapp-clang/include/cmdline_parse_num.h:107:3: note: expanded from macro 'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:10710:8: error: expression which evaluates to zero treated as a null pointer constant of type 'const char *' [-Werror,-Wnon-literal-null-conversion]
on, UINT8);
^~~~~
/root/dpdk/x86_64-native-linuxapp-clang/include/cmdline_parse_num.h:107:3: note: expanded from macro 'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:10856:8: error: expression which evaluates to zero treated as a null pointer constant of type 'const char *' [-Werror,-Wnon-literal-null-conversion]
on, UINT8);
^~~~~
/root/dpdk/x86_64-native-linuxapp-clang/include/cmdline_parse_num.h:107:3: note: expanded from macro 'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:10938:8: error: expression which evaluates to zero treated as a null pointer constant of type 'const char *' [-Werror,-Wnon-literal-null-conversion]
on, UINT8);
^~~~~
/root/dpdk/x86_64-native-linuxapp-clang/include/cmdline_parse_num.h:107:3: note: expanded from macro 'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:11010:8: error: expression which evaluates to zero treated as a null pointer constant of type 'const char *' [-Werror,-Wnon-literal-null-conversion]
on, UINT8);
^~~~~
/root/dpdk/x86_64-native-linuxapp-clang/include/cmdline_parse_num.h:107:3: note: expanded from macro 'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:11080:8: error: expression which evaluates to zero treated as a null pointer constant of type 'const char *' [-Werror,-Wnon-literal-null-conversion]
on, UINT8);
^~~~~
/root/dpdk/x86_64-native-linuxapp-clang/include/cmdline_parse_num.h:107:3: note: expanded from macro 'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:11156:8: error: expression which evaluates to zero treated as a null pointer constant of type 'const char *' [-Werror,-Wnon-literal-null-conversion]
on, UINT8);
^~~~~
/root/dpdk/x86_64-native-linuxapp-clang/include/cmdline_parse_num.h:107:3: note: expanded from macro 'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
7 errors generated.
make[5]: *** [cmdline.o] Error 1
make[5]: *** Waiting for unfinished jobs....
make[4]: *** [test-pmd] Error 2
make[4]: *** Waiting for unfinished jobs....
make[3]: *** [app] Error 2
make[2]: *** [all] Error 2
make[1]: *** [pre_install] Error 2
make: *** [install] Error 2
error: build failed
From: Iremonger, Bernard <hidden> Date: 2016-09-12 15:57:22
Hi Yuanhan,
<snip>
Subject: Re: [dpdk-dev] [RFC PATCH v2 5/5] app/test_pmd: add tests for
new API's
On Fri, Aug 26, 2016 at 10:10:20AM +0100, Bernard Iremonger wrote:
quoted
add test for vf vlan anti spoof
add test for vf mac anti spoof
add test for vf ping
add test for vf vlan strip
add test for vf vlan insert
add test for tx loopback
add test for all queues drop enable bit add test for vf split drop
enable bit add test for vf mac address add new API's to the testpmd
guide
Signed-off-by: Bernard Iremonger <redacted>
Hi,
FYI, my testrobot caught some errors when this patch is applied.
(BTW, gcc builds fine)
--yliu
---
x86_64-native-linuxapp-clang
============================
/root/dpdk/app/test-pmd/cmdline.c:10629:8: error: expression which
evaluates to zero treated as a null pointer constant of type 'const char *' [-
Werror,-Wnon-literal-null-conversion]
on, UINT8);
^~~~~
/root/dpdk/x86_64-native-linuxapp-
clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:10710:8: error: expression which
evaluates to zero treated as a null pointer constant of type 'const char *' [-
Werror,-Wnon-literal-null-conversion]
on, UINT8);
^~~~~
/root/dpdk/x86_64-native-linuxapp-
clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:10856:8: error: expression which
evaluates to zero treated as a null pointer constant of type 'const char *' [-
Werror,-Wnon-literal-null-conversion]
on, UINT8);
^~~~~
/root/dpdk/x86_64-native-linuxapp-
clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:10938:8: error: expression which
evaluates to zero treated as a null pointer constant of type 'const char *' [-
Werror,-Wnon-literal-null-conversion]
on, UINT8);
^~~~~
/root/dpdk/x86_64-native-linuxapp-
clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:11010:8: error: expression which
evaluates to zero treated as a null pointer constant of type 'const char *' [-
Werror,-Wnon-literal-null-conversion]
on, UINT8);
^~~~~
/root/dpdk/x86_64-native-linuxapp-
clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:11080:8: error: expression which
evaluates to zero treated as a null pointer constant of type 'const char *' [-
Werror,-Wnon-literal-null-conversion]
on, UINT8);
^~~~~
/root/dpdk/x86_64-native-linuxapp-
clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:11156:8: error: expression which
evaluates to zero treated as a null pointer constant of type 'const char *' [-
Werror,-Wnon-literal-null-conversion]
on, UINT8);
^~~~~
/root/dpdk/x86_64-native-linuxapp-
clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
7 errors generated.
make[5]: *** [cmdline.o] Error 1
make[5]: *** Waiting for unfinished jobs....
make[4]: *** [test-pmd] Error 2
make[4]: *** Waiting for unfinished jobs....
make[3]: *** [app] Error 2
make[2]: *** [all] Error 2
make[1]: *** [pre_install] Error 2
make: *** [install] Error 2
error: build failed
I am not seeing the above errors when I build with the following commands:
make config T=x86_64-native-linuxapp-clang
make install T=x86_64-native-linuxapp-clang -j
Are you using a different clang config file?
Regards,
Bernard.
From: Iremonger, Bernard <hidden> Date: 2016-09-12 16:28:10
Hi Jerin,
<snip>
Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
management
On Fri, Aug 26, 2016 at 10:10:18AM +0100, Bernard Iremonger wrote:
quoted
Add new API functions to configure and manage VF's on a NIC.
add rte_eth_dev_vf_ping function.
add rte_eth_dev_set_vf_vlan_anti_spoof function.
add rte_eth_dev_set_vf_mac_anti_spoof function.
Signed-off-by: azelezniak <redacted>
add rte_eth_dev_set_vf_vlan_strip function.
add rte_eth_dev_set_vf_vlan_insert function.
add rte_eth_dev_set_loopback function.
add rte_eth_dev_set_all_queues_drop function.
add rte_eth_dev_set_vf_split_drop_en function add
rte_eth_dev_set_vf_mac_addr function.
Do we really need to expose VF specific functions here?
It can be generic(PF/VF) function indexed only through port_id.
(example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id, uint8_t on))
For instance, In Thunderx PMD, We are not exposing a separate port_id for
PF. We only enumerate 0..N VFs as 0..N ethdev port_id
Our intention with this patch is to control the VF from the PF.
The following librte_ether functions already work in a similar way:
rte_eth_dev_set_vf_rxmode(uint8_t port_id, uint16_t vf, uint16_t rx_mode, uint8_t on)
rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t tx_rate, uint64_t q_msk)
quoted
increment LIBABIVER to 5.
Signed-off-by: Bernard Iremonger <redacted>
---
lib/librte_ether/rte_ethdev.c | 159 +++++++++++++++++++++++
lib/librte_ether/rte_ethdev.h | 223
From: Yuanhan Liu <hidden> Date: 2016-09-13 04:34:28
On Mon, Sep 12, 2016 at 03:57:19PM +0000, Iremonger, Bernard wrote:
quoted
/root/dpdk/x86_64-native-linuxapp-
clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:11156:8: error: expression which
evaluates to zero treated as a null pointer constant of type 'const char *' [-
Werror,-Wnon-literal-null-conversion]
on, UINT8);
^~~~~
/root/dpdk/x86_64-native-linuxapp-
clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
'TOKEN_NUM_INITIALIZER'
numtype, /* type */ \
^~~~~~~
7 errors generated.
make[5]: *** [cmdline.o] Error 1
make[5]: *** Waiting for unfinished jobs....
make[4]: *** [test-pmd] Error 2
make[4]: *** Waiting for unfinished jobs....
make[3]: *** [app] Error 2
make[2]: *** [all] Error 2
make[1]: *** [pre_install] Error 2
make: *** [install] Error 2
error: build failed
I am not seeing the above errors when I build with the following commands:
make config T=x86_64-native-linuxapp-clang
make install T=x86_64-native-linuxapp-clang -j
Are you using a different clang config file?
Not really (well, I disabled KNI and UIO stuff). FYI, I'm using the
default clang compiler from ubuntu 16.04-x86_64.
--yliu
From: Thomas Monjalon <hidden> Date: 2016-09-13 09:24:31
2016-09-12 16:28, Iremonger, Bernard:
quoted
On Fri, Aug 26, 2016 at 10:10:18AM +0100, Bernard Iremonger wrote:
quoted
Add new API functions to configure and manage VF's on a NIC.
add rte_eth_dev_vf_ping function.
add rte_eth_dev_set_vf_vlan_anti_spoof function.
add rte_eth_dev_set_vf_mac_anti_spoof function.
Signed-off-by: azelezniak <redacted>
add rte_eth_dev_set_vf_vlan_strip function.
add rte_eth_dev_set_vf_vlan_insert function.
add rte_eth_dev_set_loopback function.
add rte_eth_dev_set_all_queues_drop function.
add rte_eth_dev_set_vf_split_drop_en function add
rte_eth_dev_set_vf_mac_addr function.
Do we really need to expose VF specific functions here?
It can be generic(PF/VF) function indexed only through port_id.
(example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id, uint8_t on))
For instance, In Thunderx PMD, We are not exposing a separate port_id for
PF. We only enumerate 0..N VFs as 0..N ethdev port_id
Our intention with this patch is to control the VF from the PF.
The following librte_ether functions already work in a similar way:
rte_eth_dev_set_vf_rxmode(uint8_t port_id, uint16_t vf, uint16_t rx_mode, uint8_t on)
rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t tx_rate, uint64_t q_msk)
I have a bad feeling with these functions dedicated to VF from PF.
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
On Fri, Aug 26, 2016 at 10:10:18AM +0100, Bernard Iremonger wrote:
quoted
Add new API functions to configure and manage VF's on a NIC.
add rte_eth_dev_vf_ping function.
add rte_eth_dev_set_vf_vlan_anti_spoof function.
add rte_eth_dev_set_vf_mac_anti_spoof function.
Signed-off-by: azelezniak <redacted>
add rte_eth_dev_set_vf_vlan_strip function.
add rte_eth_dev_set_vf_vlan_insert function.
add rte_eth_dev_set_loopback function.
add rte_eth_dev_set_all_queues_drop function.
add rte_eth_dev_set_vf_split_drop_en function add
rte_eth_dev_set_vf_mac_addr function.
Do we really need to expose VF specific functions here?
It can be generic(PF/VF) function indexed only through port_id.
(example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id,
uint8_t on)) For instance, In Thunderx PMD, We are not exposing a
separate port_id for PF. We only enumerate 0..N VFs as 0..N ethdev
port_id
Our intention with this patch is to control the VF from the PF.
The following librte_ether functions already work in a similar way:
rte_eth_dev_set_vf_rxmode(uint8_t port_id, uint16_t vf, uint16_t
rx_mode, uint8_t on)
rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t
tx_rate, uint64_t q_msk)
I have a bad feeling with these functions dedicated to VF from PF.
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the VF is not visible to the PF.
I don't think there is another way to do this.
Regards,
Bernard.
@@ -4661,6 +4698,135 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,returnret;}+staticvoid+ixgbe_set_vf_vlan_anti_spoof(structrte_eth_dev*dev,+uint16_tvf,uint8_ton)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);++structixgbe_mac_info*mac=&hw->mac;++mac->ops.set_vlan_anti_spoofing(hw,on,vf);+}++staticvoid+ixgbe_set_vf_mac_anti_spoof(structrte_eth_dev*dev,+uint16_tvf,uint8_ton)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+structixgbe_mac_info*mac=&hw->mac;++mac->ops.set_mac_anti_spoofing(hw,on,vf);+}++staticint+ixgbe_vf_ping(structrte_eth_dev*dev,int32_tvf)+{+intret=0;+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);++structixgbe_vf_info*vfinfo=+*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);++u32ping;+inti;++for(i=0;i<dev->pci_dev->max_vfs;i++){+ping=IXGBE_PF_CONTROL_MSG;+if(vfinfo[i].clear_to_send)+ping|=IXGBE_VT_MSGTYPE_CTS;++/* ping every VF or only one specified */+if(vf<0||vf==i)+ixgbe_write_mbx(hw,&ping,1,i);+}++returnret;+}++staticvoid+ixgbe_set_vf_vlan_insert(structrte_eth_dev*dev,uint16_tvf,intvlan)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_tctrl;++PMD_INIT_FUNC_TRACE();++ctrl=IXGBE_READ_REG(hw,IXGBE_VMVIR(vf));+if(vlan){+ctrl=vlan;+ctrl|=IXGBE_VMVIR_VLANA_DEFAULT;+}else{+ctrl=0;+}++IXGBE_WRITE_REG(hw,IXGBE_VMVIR(vf),ctrl);+}++staticvoid+ixgbe_set_tx_loopback(structrte_eth_dev*dev,inton)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_tctrl;++PMD_INIT_FUNC_TRACE();++ctrl=IXGBE_READ_REG(hw,IXGBE_PFDTXGSWC);+/* enable or disable VMDQ loopback */+if(on)+ctrl|=IXGBE_PFDTXGSWC_VT_LBEN;+else+ctrl&=~IXGBE_PFDTXGSWC_VT_LBEN;++IXGBE_WRITE_REG(hw,IXGBE_PFDTXGSWC,ctrl);+}++staticvoid+ixgbe_set_all_queues_drop_en(structrte_eth_dev*dev,intstate)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_treg_value;+inti;+intnum_queues=(int)(IXGBE_QDE_IDX_MASK>>IXGBE_QDE_IDX_SHIFT);++PMD_INIT_FUNC_TRACE();++for(i=0;i<=num_queues;i++){+reg_value=IXGBE_QDE_WRITE|+(i<<IXGBE_QDE_IDX_SHIFT)|+(state&IXGBE_QDE_ENABLE);+IXGBE_WRITE_REG(hw,IXGBE_QDE,reg_value);+}+}++staticvoid+ixgbe_set_vf_split_drop_en(structrte_eth_dev*dev,uint16_tvf,intstate)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_treg_value;++PMD_INIT_FUNC_TRACE();++/* only support VF's 0 to 63 */+if(vf>63)+return;++reg_value=IXGBE_READ_REG(hw,IXGBE_SRRCTL(vf));+if(state)+reg_value|=IXGBE_SRRCTL_DROP_EN;+else+reg_value&=~IXGBE_SRRCTL_DROP_EN;++IXGBE_WRITE_REG(hw,IXGBE_SRRCTL(vf),reg_value);+}+#define IXGBE_MRCTL_VPME 0x01 /* Virtual Pool Mirroring. */#define IXGBE_MRCTL_UPME 0x02 /* Uplink Port Mirroring. */#define IXGBE_MRCTL_DPME 0x04 /* Downlink Port Mirroring. */
@@ -1233,6 +1233,11 @@ typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,structether_addr*mac_addr);/**< @internal Set a MAC address into Receive Address Address Register */+typedefint(*eth_set_vf_mac_addr_t)(structrte_eth_dev*dev,+uint16_tvf,+structether_addr*mac_addr);+/**< @internal Set VF address into Receive Address Address Register */+typedefint(*eth_uc_hash_table_set_t)(structrte_eth_dev*dev,structether_addr*mac_addr,uint8_ton);
@@ -1264,6 +1269,38 @@ typedef int (*eth_set_vf_vlan_filter_t)(struct rte_eth_dev *dev,uint8_tvlan_on);/**< @internal Set VF VLAN pool filter */+typedefvoid(*eth_set_vf_vlan_anti_spoof_t)(structrte_eth_dev*dev,+uint16_tvf,+uint8_ton);+/**< @internal Set VF VLAN anti spoof */++typedefvoid(*eth_set_vf_mac_anti_spoof_t)(structrte_eth_dev*dev,+uint16_tvf,+uint8_ton);+/**< @internal Set VF MAC anti spoof */++typedefint(*eth_vf_ping_t)(structrte_eth_dev*dev,+int32_tvf);+/**< @internal ping one or all vf's */++typedefvoid(*eth_set_vf_vlan_insert_t)(structrte_eth_dev*dev,+uint16_tvf,+intvlan);+/**< @internal Set VF vlan insert */++typedefvoid(*eth_set_tx_loopback_t)(structrte_eth_dev*dev,+inton);+/**< @internal Set tx loopback */++typedefvoid(*eth_set_all_queues_drop_en_t)(structrte_eth_dev*dev,+intstate);+/**< @internal Set all queues drop */++typedefvoid(*eth_set_vf_split_drop_en_t)(structrte_eth_dev*dev,+uint16_tvf,+intstate);+/**< @internal Set the enable drop bit in the VF split rx control register */+typedefint(*eth_set_queue_rate_limit_t)(structrte_eth_dev*dev,uint16_tqueue_idx,uint16_ttx_rate);
@@ -1468,6 +1505,7 @@ struct eth_dev_ops {eth_mac_addr_remove_tmac_addr_remove;/**< Remove MAC address */eth_mac_addr_add_tmac_addr_add;/**< Add a MAC address */eth_mac_addr_set_tmac_addr_set;/**< Set a MAC address */+eth_set_vf_mac_addr_tset_vf_mac_addr;/**< Set a VF MAC address */eth_uc_hash_table_set_tuc_hash_table_set;/**< Set Unicast Table Array */eth_uc_all_hash_table_set_tuc_all_hash_table_set;/**< Set Unicast hash bitmap */eth_mirror_rule_set_tmirror_rule_set;/**< Add a traffic mirror rule.*/
@@ -1476,6 +1514,13 @@ struct eth_dev_ops {eth_set_vf_rx_tset_vf_rx;/**< enable/disable a VF receive */eth_set_vf_tx_tset_vf_tx;/**< enable/disable a VF transmit */eth_set_vf_vlan_filter_tset_vf_vlan_filter;/**< Set VF VLAN filter */+eth_set_vf_vlan_anti_spoof_tset_vf_vlan_anti_spoof;/**< Set VF VLAN anti spoof */+eth_set_vf_mac_anti_spoof_tset_vf_mac_anti_spoof;/**< Set VF MAC anti spoof */+eth_vf_ping_tvf_ping;/**< Ping one or all VF's */+eth_set_vf_vlan_insert_tset_vf_vlan_insert;/** <Set VF VLAN insert */+eth_set_tx_loopback_tset_tx_loopback;/** <Set tx loopback */+eth_set_all_queues_drop_en_tset_all_queues_drop_en;/** <Set queue drop enable bit */+eth_set_vf_split_drop_en_tset_vf_split_drop_en;/** <Set split drop enable bit.*//** Add UDP tunnel port. */eth_udp_tunnel_port_add_tudp_tunnel_port_add;/** Del UDP tunnel port. */
@@ -3332,7 +3377,23 @@ int rte_eth_dev_mac_addr_remove(uint8_t port, struct ether_addr *mac_addr);*/intrte_eth_dev_default_mac_addr_set(uint8_tport,structether_addr*mac_addr);-+/**+*SettheVFMACaddress.+*+*@paramport+*TheportidentifieroftheEthernetdevice.+*@paramvf+*VFid.+*@parammac_addr+*VFMACaddress.+*@return+*-(0)ifsuccessful,or*mac_addr*didn'texist.+*-(-ENOTSUP)ifhardwaredoesn'tsupport.+*-(-ENODEV)if*port*invalid.+*-(-EINVAL)ifMACaddressisinvalid.+*/+intrte_eth_dev_set_vf_mac_addr(uint8_tport,uint16_tvf,+structether_addr*mac_addr);/***UpdateRedirectionTable(RETA)ofReceiveSideScalingofEthernetdevice.*
From: Bernard Iremonger <hidden> Date: 2016-09-16 11:05:47
add test for vf vlan anti spoof
add test for vf mac anti spoof
add test for vf ping
add test for vf vlan strip
add test for vf vlan insert
add test for tx loopback
add test for all queues drop enable bit
add test for vf split drop enable bit
add test for vf mac address
add new API's to the testpmd guide
Signed-off-by: Bernard Iremonger <redacted>
---
app/test-pmd/cmdline.c | 707 ++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 70 ++-
2 files changed, 774 insertions(+), 3 deletions(-)
@@ -10585,6 +10585,704 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {},};+/* vf vlan anti spoof configuration */++/* Common result structure for vf vlan anti spoof */+structcmd_vf_vlan_anti_spoof_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tantispoof;+uint8_tport_id;+uint32_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf vlan anti spoof enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_antispoof=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+antispoof,"antispoof");+cmdline_parse_token_num_tcmd_vf_vlan_anti_spoof_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_anti_spoof_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vf_id,UINT32);+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+on_off,"on#off");++staticvoid+cmd_set_vf_vlan_anti_spoof_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_anti_spoof_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}+ret=rte_eth_dev_set_vf_vlan_anti_spoof(res->port_id,res->vf_id,is_on);+if(ret<0)+printf("vf vlan anti spoofing programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_vlan_anti_spoof={+.f=cmd_set_vf_vlan_anti_spoof_parsed,+.data=NULL,+.help_str="set vf vlan antispoof port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_vlan_anti_spoof_set,+(void*)&cmd_vf_vlan_anti_spoof_vf,+(void*)&cmd_vf_vlan_anti_spoof_vlan,+(void*)&cmd_vf_vlan_anti_spoof_antispoof,+(void*)&cmd_vf_vlan_anti_spoof_port_id,+(void*)&cmd_vf_vlan_anti_spoof_vf_id,+(void*)&cmd_vf_vlan_anti_spoof_on_off,+NULL,+},+};++/* vf mac anti spoof configuration */++/* Common result structure for vf mac anti spoof */+structcmd_vf_mac_anti_spoof_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tmac;+cmdline_fixed_string_tantispoof;+uint8_tport_id;+uint32_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf mac anti spoof enable disable */+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_mac=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+mac,"mac");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_antispoof=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+antispoof,"antispoof");+cmdline_parse_token_num_tcmd_vf_mac_anti_spoof_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_mac_anti_spoof_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+vf_id,UINT32);+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+on_off,"on#off");++staticvoid+cmd_set_vf_mac_anti_spoof_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_mac_anti_spoof_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_mac_anti_spoof(res->port_id,res->vf_id,is_on);+if(ret<0)+printf("vf vlan mac spoofing programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_mac_anti_spoof={+.f=cmd_set_vf_mac_anti_spoof_parsed,+.data=NULL,+.help_str="set vf mac antispoof port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_mac_anti_spoof_set,+(void*)&cmd_vf_mac_anti_spoof_vf,+(void*)&cmd_vf_mac_anti_spoof_mac,+(void*)&cmd_vf_mac_anti_spoof_antispoof,+(void*)&cmd_vf_mac_anti_spoof_port_id,+(void*)&cmd_vf_mac_anti_spoof_vf_id,+(void*)&cmd_vf_mac_anti_spoof_on_off,+NULL,+},+};++/* vf ping configuration */++/* Common result structure for vf ping */+structcmd_vf_ping_result{+cmdline_fixed_string_tvf;+cmdline_fixed_string_tping;+uint8_tport_id;+int32_tvf_id;+};++/* Common CLI fields for ping vfs */+cmdline_parse_token_string_tcmd_vf_ping_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_ping_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_ping_ping=+TOKEN_STRING_INITIALIZER+(structcmd_vf_ping_result,+ping,"ping");+cmdline_parse_token_num_tcmd_vf_ping_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_ping_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_ping_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_ping_result,+vf_id,INT32);++staticvoid+cmd_vf_ping_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_ping_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_vf_ping(res->port_id,res->vf_id);+if(ret<0)+printf("ping vfs programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_vf_ping={+.f=cmd_vf_ping_parsed,+.data=NULL,+.help_str="vf ping port_id vf_id|-1",+.tokens={+(void*)&cmd_vf_ping_vf,+(void*)&cmd_vf_ping_ping,+(void*)&cmd_vf_ping_port_id,+(void*)&cmd_vf_ping_vf_id,+NULL,+},+};++/* vf vlan strip configuration */++/* Common result structure for vf mac anti spoof */+structcmd_vf_vlan_strip_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tstrip;+uint8_tport_id;+uint16_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf vlan strip enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_strip_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_strip_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_strip_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_strip_strip=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+strip,"strip");+cmdline_parse_token_num_tcmd_vf_vlan_strip_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_strip_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_strip_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_strip_result,+vf_id,UINT16);+cmdline_parse_token_string_tcmd_vf_vlan_strip_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+on_off,"on#off");++staticvoid+cmd_set_vf_vlan_strip_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_strip_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_vlan_strip(res->port_id,res->vf_id,is_on);+if(ret<0)+printf("vf vlan strip programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_vlan_strip={+.f=cmd_set_vf_vlan_strip_parsed,+.data=NULL,+.help_str="set vf vlan strip port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_vlan_strip_set,+(void*)&cmd_vf_vlan_strip_vf,+(void*)&cmd_vf_vlan_strip_vlan,+(void*)&cmd_vf_vlan_strip_strip,+(void*)&cmd_vf_vlan_strip_port_id,+(void*)&cmd_vf_vlan_strip_vf_id,+(void*)&cmd_vf_vlan_strip_on_off,+NULL,+},+};++/* vf vlan insert configuration */++/* Common result structure for vf vlan insert */+structcmd_vf_vlan_insert_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tinsert;+uint8_tport_id;+uint16_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf vlan insert enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_insert_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_insert_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_insert_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_insert_insert=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+insert,"insert");+cmdline_parse_token_num_tcmd_vf_vlan_insert_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_insert_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_insert_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_insert_result,+vf_id,UINT16);+cmdline_parse_token_string_tcmd_vf_vlan_insert_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+on_off,"on#off");++staticvoid+cmd_set_vf_vlan_insert_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_insert_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_vlan_insert(res->port_id,res->vf_id,is_on);+if(ret<0)+printf("vf vlan insert programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_vlan_insert={+.f=cmd_set_vf_vlan_insert_parsed,+.data=NULL,+.help_str="set vf vlan insert port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_vlan_insert_set,+(void*)&cmd_vf_vlan_insert_vf,+(void*)&cmd_vf_vlan_insert_vlan,+(void*)&cmd_vf_vlan_insert_insert,+(void*)&cmd_vf_vlan_insert_port_id,+(void*)&cmd_vf_vlan_insert_vf_id,+(void*)&cmd_vf_vlan_insert_on_off,+NULL,+},+};++/* tx loopback configuration */++/* Common result structure for tx loopback */+structcmd_tx_loopback_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_ttx;+cmdline_fixed_string_tloopback;+uint8_tport_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for tx loopback enable disable */+cmdline_parse_token_string_tcmd_tx_loopback_set=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+set,"set");+cmdline_parse_token_string_tcmd_tx_loopback_tx=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+tx,"tx");+cmdline_parse_token_string_tcmd_tx_loopback_loopback=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+loopback,"loopback");+cmdline_parse_token_num_tcmd_tx_loopback_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_tx_loopback_result,+port_id,UINT8);+cmdline_parse_token_string_tcmd_tx_loopback_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+on_off,"on#off");++staticvoid+cmd_set_tx_loopback_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_tx_loopback_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++ret=rte_eth_dev_set_tx_loopback(res->port_id,is_on);+if(ret<0)+printf("tx loopback programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_tx_loopback={+.f=cmd_set_tx_loopback_parsed,+.data=NULL,+.help_str="set tx loopback port_id on|off",+.tokens={+(void*)&cmd_tx_loopback_set,+(void*)&cmd_tx_loopback_tx,+(void*)&cmd_tx_loopback_loopback,+(void*)&cmd_tx_loopback_port_id,+(void*)&cmd_tx_loopback_on_off,+NULL,+},+};++/* all queues drop enable configuration */++/* Common result structure for all queues drop enable */+structcmd_all_queues_drop_en_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tall;+cmdline_fixed_string_tqueues;+cmdline_fixed_string_tdrop;+uint8_tport_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for tx loopback enable disable */+cmdline_parse_token_string_tcmd_all_queues_drop_en_set=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+set,"set");+cmdline_parse_token_string_tcmd_all_queues_drop_en_all=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+all,"all");+cmdline_parse_token_string_tcmd_all_queues_drop_en_queues=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+queues,"queues");+cmdline_parse_token_string_tcmd_all_queues_drop_en_drop=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+drop,"drop");+cmdline_parse_token_num_tcmd_all_queues_drop_en_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_all_queues_drop_en_result,+port_id,UINT8);+cmdline_parse_token_string_tcmd_all_queues_drop_en_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+on_off,"on#off");++staticvoid+cmd_set_all_queues_drop_en_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_all_queues_drop_en_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++ret=rte_eth_dev_set_all_queues_drop_en(res->port_id,is_on);+if(ret<0)+printf("all queues drop enable programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_all_queues_drop_en={+.f=cmd_set_all_queues_drop_en_parsed,+.data=NULL,+.help_str="set all queues drop port_id on|off",+.tokens={+(void*)&cmd_all_queues_drop_en_set,+(void*)&cmd_all_queues_drop_en_all,+(void*)&cmd_all_queues_drop_en_queues,+(void*)&cmd_all_queues_drop_en_drop,+(void*)&cmd_all_queues_drop_en_port_id,+(void*)&cmd_all_queues_drop_en_on_off,+NULL,+},+};++/* vf split drop enable configuration */++/* Common result structure for vf split drop enable */+structcmd_vf_split_drop_en_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tsplit;+cmdline_fixed_string_tdrop;+uint8_tport_id;+uint16_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf split drop enable disable */+cmdline_parse_token_string_tcmd_vf_split_drop_en_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_split_drop_en_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_split_drop_en_split=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+split,"split");+cmdline_parse_token_string_tcmd_vf_split_drop_en_drop=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+drop,"drop");+cmdline_parse_token_num_tcmd_vf_split_drop_en_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_split_drop_en_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_split_drop_en_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_split_drop_en_result,+vf_id,UINT16);+cmdline_parse_token_string_tcmd_vf_split_drop_en_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+on_off,"on#off");++staticvoid+cmd_set_vf_split_drop_en_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_split_drop_en_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_split_drop_en(res->port_id,res->vf_id,is_on);+if(ret<0)+printf("vf split drop enable programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_split_drop_en={+.f=cmd_set_vf_split_drop_en_parsed,+.data=NULL,+.help_str="set vf split drop port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_split_drop_en_set,+(void*)&cmd_vf_split_drop_en_vf,+(void*)&cmd_vf_split_drop_en_split,+(void*)&cmd_vf_split_drop_en_drop,+(void*)&cmd_vf_split_drop_en_port_id,+(void*)&cmd_vf_split_drop_en_vf_id,+(void*)&cmd_vf_split_drop_en_on_off,+NULL,+},+};++/* vf mac address configuration */++/* Common result structure for vf mac address */+structcmd_set_vf_mac_addr_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tmac;+cmdline_fixed_string_taddr;+uint8_tport_id;+uint16_tvf_id;+structether_addrmac_addr;++};++/* Common CLI fields for vf split drop enable disable */+cmdline_parse_token_string_tcmd_set_vf_mac_addr_set=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+set,"set");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_vf=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+vf,"vf");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_mac=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+mac,"mac");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_addr=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+addr,"addr");+cmdline_parse_token_num_tcmd_set_vf_mac_addr_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_set_vf_mac_addr_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_set_vf_mac_addr_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_set_vf_mac_addr_result,+vf_id,UINT16);+cmdline_parse_token_etheraddr_tcmd_set_vf_mac_addr_mac_addr=+TOKEN_ETHERADDR_INITIALIZER(structcmd_set_vf_mac_addr_result,+mac_addr);++staticvoid+cmd_set_vf_mac_addr_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_set_vf_mac_addr_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_mac_addr(res->port_id,res->vf_id,&res->mac_addr);+if(ret<0)+printf("set vf mac addr programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_mac_addr={+.f=cmd_set_vf_mac_addr_parsed,+.data=NULL,+.help_str="set vf mac addr port_id vf_id xx:xx:xx:xx:xx:xx",+.tokens={+(void*)&cmd_set_vf_mac_addr_set,+(void*)&cmd_set_vf_mac_addr_vf,+(void*)&cmd_set_vf_mac_addr_mac,+(void*)&cmd_set_vf_mac_addr_addr,+(void*)&cmd_set_vf_mac_addr_port_id,+(void*)&cmd_set_vf_mac_addr_vf_id,+(void*)&cmd_set_vf_mac_addr_mac_addr,+NULL,+},+};+/* ******************************************************************************** *//* list of instructions */
@@ -1,5 +1,5 @@.. BSD LICENSE- Copyright(c) 2010-2015 Intel Corporation. All rights reserved.+ Copyright(c) 2010-2016 Intel Corporation. All rights reserved. All rights reserved. Redistribution and use in source and binary forms, with or without
@@ -473,6 +473,41 @@ For example, to change the port forwarding: RX P=1/Q=0 (socket 0) -> TX P=3/Q=0 (socket 0) peer=02:00:00:00:00:03 RX P=3/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:02+set tx loopback+~~~~~~~~~~~~~~~++Enable/disable tx loopback::++ testpmd> set tx loopback (port_id) (on|off)++set drop enable+~~~~~~~~~~~~~~~++set drop enable bit for all queues::++ testpmd> set all queues drop (port_id) (on|off)++set split drop enable (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++set split drop enable bit for VF from PF::++ testpmd> set vf split drop (port_id) (vf_id) (on|off)++set mac antispoof (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~++Set mac antispoof for a VF from the PF::++ testpmd> set vf mac antispoof (port_id) (vf_id) (on|off)++ping VF+~~~~~~~++Ping VF or all VF's from PF::++ testpmd> vf ping (port_id) (vf_id | -1)+ vlan set strip ~~~~~~~~~~~~~~
@@ -487,6 +522,28 @@ Set the VLAN strip for a queue on a port:: testpmd> vlan set stripq (on|off) (port_id,queue_id)+vlan set strip (for VF)+~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN strip for a VF from the PF::++ testpmd> set vf vlan strip (port_id) (vf_id) (on|off)++vlan set insert (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN insert for a VF from the PF::++ testpmd> set vf vlan insert (port_id) (vf_id) (on|off)++vlan set antispoof (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN antispoof for a VF from the PF::++ testpmd> set vf vlan antispoof (port_id) (vf_id) (on|off)++ vlan set filter ~~~~~~~~~~~~~~~
@@ -727,13 +784,20 @@ Remove a MAC address from a port:: testpmd> mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)-mac_addr add(for VF)-~~~~~~~~~~~~~~~~~~~~+mac_addr add (for VF)+~~~~~~~~~~~~~~~~~~~~~ Add an alternative MAC address for a VF to a port:: testpmd> mac_add add port (port_id) vf (vf_id) (XX:XX:XX:XX:XX:XX)+mac_addr set (for VF)+~~~~~~~~~~~~~~~~~~~~~++Set the MAC address for a VF from the PF::++ testpmd> set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)+ set port-uta ~~~~~~~~~~~~
From: Bernard Iremonger <hidden> Date: 2016-09-16 11:06:37
This patchset contains new DPDK API's requested by AT&T for use
with the Virtual Function Daemon (VFD).
The need to configure and manage VF's on a NIC has grown to the
point where AT&T have devloped a DPDK based tool, VFD, to do this.
This patch set adds API extensions to DPDK VF configuration.
Nine new functions have been added to the eth_dev_ops structure.
Corresponding functions have been added to the ixgbe PMD for the
Intel 82559 NIC.
Changes have been made to testpmd to facilitate testing of the new API's.
The testpmd documentation has been updated to document the testpmd changes.
Note:
Adding new functions to the eth_dev_ops structure will cause an
ABI breakage.
Changes in v3:
rebase to latest master branch.
drop patches for callback functions
revise VF id checks in new librte_ether functions
revise testpmd commands for new API's
Changes in V2:
rebase to latest master branch.
fix compile error with clang.
Bernard Iremonger (3):
librte_ether: add API's for VF management
net/ixgbe: add functions for VF management
app/test_pmd: add tests for new API's
app/test-pmd/cmdline.c | 707 ++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 70 ++-
drivers/net/ixgbe/ixgbe_ethdev.c | 166 +++++++
lib/librte_ether/rte_ethdev.c | 192 ++++++++
lib/librte_ether/rte_ethdev.h | 217 ++++++++-
lib/librte_ether/rte_ether_version.map | 14 +
6 files changed, 1362 insertions(+), 4 deletions(-)
--
2.9.0
From: Bernard Iremonger <hidden> Date: 2016-09-16 14:16:00
This patchset contains new DPDK API's requested by AT&T for use
with the Virtual Function Daemon (VFD).
The need to configure and manage VF's on a NIC has grown to the
point where AT&T have devloped a DPDK based tool, VFD, to do this.
This patch set adds API extensions to DPDK VF configuration.
Nine new functions have been added to the eth_dev_ops structure.
Corresponding functions have been added to the ixgbe PMD for the
Intel 82559 NIC.
Changes have been made to testpmd to facilitate testing of the new API's.
The testpmd documentation has been updated to document the testpmd changes.
Note:
Adding new functions to the eth_dev_ops structure will cause an
ABI breakage.
Changes in v3:
rebase to latest master branch.
drop patches for callback functions
revise VF id checks in new librte_ether functions
revise testpmd commands for new API's
Changes in V2:
rebase to latest master branch.
fix compile error with clang.
Bernard Iremonger (3):
librte_ether: add API's for VF management
net/ixgbe: add functions for VF management
app/test_pmd: add tests for new API's
app/test-pmd/cmdline.c | 707 ++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 70 ++-
drivers/net/ixgbe/ixgbe_ethdev.c | 166 +++++++
lib/librte_ether/rte_ethdev.c | 192 ++++++++
lib/librte_ether/rte_ethdev.h | 217 ++++++++-
lib/librte_ether/rte_ether_version.map | 14 +
6 files changed, 1362 insertions(+), 4 deletions(-)
--
2.9.0
@@ -1233,6 +1233,11 @@ typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,structether_addr*mac_addr);/**< @internal Set a MAC address into Receive Address Address Register */+typedefint(*eth_set_vf_mac_addr_t)(structrte_eth_dev*dev,+uint16_tvf,+structether_addr*mac_addr);+/**< @internal Set VF address into Receive Address Address Register */+typedefint(*eth_uc_hash_table_set_t)(structrte_eth_dev*dev,structether_addr*mac_addr,uint8_ton);
@@ -1264,6 +1269,38 @@ typedef int (*eth_set_vf_vlan_filter_t)(struct rte_eth_dev *dev,uint8_tvlan_on);/**< @internal Set VF VLAN pool filter */+typedefvoid(*eth_set_vf_vlan_anti_spoof_t)(structrte_eth_dev*dev,+uint16_tvf,+uint8_ton);+/**< @internal Set VF VLAN anti spoof */++typedefvoid(*eth_set_vf_mac_anti_spoof_t)(structrte_eth_dev*dev,+uint16_tvf,+uint8_ton);+/**< @internal Set VF MAC anti spoof */++typedefint(*eth_vf_ping_t)(structrte_eth_dev*dev,+int32_tvf);+/**< @internal ping one or all vf's */++typedefvoid(*eth_set_vf_vlan_insert_t)(structrte_eth_dev*dev,+uint16_tvf,+intvlan);+/**< @internal Set VF vlan insert */++typedefvoid(*eth_set_tx_loopback_t)(structrte_eth_dev*dev,+inton);+/**< @internal Set tx loopback */++typedefvoid(*eth_set_all_queues_drop_en_t)(structrte_eth_dev*dev,+intstate);+/**< @internal Set all queues drop */++typedefvoid(*eth_set_vf_split_drop_en_t)(structrte_eth_dev*dev,+uint16_tvf,+intstate);+/**< @internal Set the enable drop bit in the VF split rx control register */+typedefint(*eth_set_queue_rate_limit_t)(structrte_eth_dev*dev,uint16_tqueue_idx,uint16_ttx_rate);
@@ -1468,6 +1505,7 @@ struct eth_dev_ops {eth_mac_addr_remove_tmac_addr_remove;/**< Remove MAC address */eth_mac_addr_add_tmac_addr_add;/**< Add a MAC address */eth_mac_addr_set_tmac_addr_set;/**< Set a MAC address */+eth_set_vf_mac_addr_tset_vf_mac_addr;/**< Set a VF MAC address */eth_uc_hash_table_set_tuc_hash_table_set;/**< Set Unicast Table Array */eth_uc_all_hash_table_set_tuc_all_hash_table_set;/**< Set Unicast hash bitmap */eth_mirror_rule_set_tmirror_rule_set;/**< Add a traffic mirror rule.*/
@@ -1476,6 +1514,13 @@ struct eth_dev_ops {eth_set_vf_rx_tset_vf_rx;/**< enable/disable a VF receive */eth_set_vf_tx_tset_vf_tx;/**< enable/disable a VF transmit */eth_set_vf_vlan_filter_tset_vf_vlan_filter;/**< Set VF VLAN filter */+eth_set_vf_vlan_anti_spoof_tset_vf_vlan_anti_spoof;/**< Set VF VLAN anti spoof */+eth_set_vf_mac_anti_spoof_tset_vf_mac_anti_spoof;/**< Set VF MAC anti spoof */+eth_vf_ping_tvf_ping;/**< Ping one or all VF's */+eth_set_vf_vlan_insert_tset_vf_vlan_insert;/** <Set VF VLAN insert */+eth_set_tx_loopback_tset_tx_loopback;/** <Set tx loopback */+eth_set_all_queues_drop_en_tset_all_queues_drop_en;/** <Set queue drop enable bit */+eth_set_vf_split_drop_en_tset_vf_split_drop_en;/** <Set split drop enable bit.*//** Add UDP tunnel port. */eth_udp_tunnel_port_add_tudp_tunnel_port_add;/** Del UDP tunnel port. */
@@ -3332,7 +3377,23 @@ int rte_eth_dev_mac_addr_remove(uint8_t port, struct ether_addr *mac_addr);*/intrte_eth_dev_default_mac_addr_set(uint8_tport,structether_addr*mac_addr);-+/**+*SettheVFMACaddress.+*+*@paramport+*TheportidentifieroftheEthernetdevice.+*@paramvf+*VFid.+*@parammac_addr+*VFMACaddress.+*@return+*-(0)ifsuccessful,or*mac_addr*didn'texist.+*-(-ENOTSUP)ifhardwaredoesn'tsupport.+*-(-ENODEV)if*port*invalid.+*-(-EINVAL)ifMACaddressisinvalid.+*/+intrte_eth_dev_set_vf_mac_addr(uint8_tport,uint16_tvf,+structether_addr*mac_addr);/***UpdateRedirectionTable(RETA)ofReceiveSideScalingofEthernetdevice.*
@@ -4661,6 +4698,135 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,returnret;}+staticvoid+ixgbe_set_vf_vlan_anti_spoof(structrte_eth_dev*dev,+uint16_tvf,uint8_ton)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);++structixgbe_mac_info*mac=&hw->mac;++mac->ops.set_vlan_anti_spoofing(hw,on,vf);+}++staticvoid+ixgbe_set_vf_mac_anti_spoof(structrte_eth_dev*dev,+uint16_tvf,uint8_ton)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+structixgbe_mac_info*mac=&hw->mac;++mac->ops.set_mac_anti_spoofing(hw,on,vf);+}++staticint+ixgbe_vf_ping(structrte_eth_dev*dev,int32_tvf)+{+intret=0;+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);++structixgbe_vf_info*vfinfo=+*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);++u32ping;+inti;++for(i=0;i<dev->pci_dev->max_vfs;i++){+ping=IXGBE_PF_CONTROL_MSG;+if(vfinfo[i].clear_to_send)+ping|=IXGBE_VT_MSGTYPE_CTS;++/* ping every VF or only one specified */+if(vf<0||vf==i)+ixgbe_write_mbx(hw,&ping,1,i);+}++returnret;+}++staticvoid+ixgbe_set_vf_vlan_insert(structrte_eth_dev*dev,uint16_tvf,intvlan)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_tctrl;++PMD_INIT_FUNC_TRACE();++ctrl=IXGBE_READ_REG(hw,IXGBE_VMVIR(vf));+if(vlan){+ctrl=vlan;+ctrl|=IXGBE_VMVIR_VLANA_DEFAULT;+}else{+ctrl=0;+}++IXGBE_WRITE_REG(hw,IXGBE_VMVIR(vf),ctrl);+}++staticvoid+ixgbe_set_tx_loopback(structrte_eth_dev*dev,inton)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_tctrl;++PMD_INIT_FUNC_TRACE();++ctrl=IXGBE_READ_REG(hw,IXGBE_PFDTXGSWC);+/* enable or disable VMDQ loopback */+if(on)+ctrl|=IXGBE_PFDTXGSWC_VT_LBEN;+else+ctrl&=~IXGBE_PFDTXGSWC_VT_LBEN;++IXGBE_WRITE_REG(hw,IXGBE_PFDTXGSWC,ctrl);+}++staticvoid+ixgbe_set_all_queues_drop_en(structrte_eth_dev*dev,intstate)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_treg_value;+inti;+intnum_queues=(int)(IXGBE_QDE_IDX_MASK>>IXGBE_QDE_IDX_SHIFT);++PMD_INIT_FUNC_TRACE();++for(i=0;i<=num_queues;i++){+reg_value=IXGBE_QDE_WRITE|+(i<<IXGBE_QDE_IDX_SHIFT)|+(state&IXGBE_QDE_ENABLE);+IXGBE_WRITE_REG(hw,IXGBE_QDE,reg_value);+}+}++staticvoid+ixgbe_set_vf_split_drop_en(structrte_eth_dev*dev,uint16_tvf,intstate)+{+structixgbe_hw*hw=+IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);+uint32_treg_value;++PMD_INIT_FUNC_TRACE();++/* only support VF's 0 to 63 */+if(vf>63)+return;++reg_value=IXGBE_READ_REG(hw,IXGBE_SRRCTL(vf));+if(state)+reg_value|=IXGBE_SRRCTL_DROP_EN;+else+reg_value&=~IXGBE_SRRCTL_DROP_EN;++IXGBE_WRITE_REG(hw,IXGBE_SRRCTL(vf),reg_value);+}+#define IXGBE_MRCTL_VPME 0x01 /* Virtual Pool Mirroring. */#define IXGBE_MRCTL_UPME 0x02 /* Uplink Port Mirroring. */#define IXGBE_MRCTL_DPME 0x04 /* Downlink Port Mirroring. */
From: Bernard Iremonger <hidden> Date: 2016-09-16 14:16:03
add test for vf vlan anti spoof
add test for vf mac anti spoof
add test for vf ping
add test for vf vlan strip
add test for vf vlan insert
add test for tx loopback
add test for all queues drop enable bit
add test for vf split drop enable bit
add test for vf mac address
add new API's to the testpmd guide
Signed-off-by: Bernard Iremonger <redacted>
---
app/test-pmd/cmdline.c | 707 ++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 70 ++-
2 files changed, 774 insertions(+), 3 deletions(-)
@@ -10585,6 +10585,704 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {},};+/* vf vlan anti spoof configuration */++/* Common result structure for vf vlan anti spoof */+structcmd_vf_vlan_anti_spoof_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tantispoof;+uint8_tport_id;+uint32_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf vlan anti spoof enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_antispoof=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+antispoof,"antispoof");+cmdline_parse_token_num_tcmd_vf_vlan_anti_spoof_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_anti_spoof_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vf_id,UINT32);+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+on_off,"on#off");++staticvoid+cmd_set_vf_vlan_anti_spoof_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_anti_spoof_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}+ret=rte_eth_dev_set_vf_vlan_anti_spoof(res->port_id,res->vf_id,is_on);+if(ret<0)+printf("vf vlan anti spoofing programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_vlan_anti_spoof={+.f=cmd_set_vf_vlan_anti_spoof_parsed,+.data=NULL,+.help_str="set vf vlan antispoof port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_vlan_anti_spoof_set,+(void*)&cmd_vf_vlan_anti_spoof_vf,+(void*)&cmd_vf_vlan_anti_spoof_vlan,+(void*)&cmd_vf_vlan_anti_spoof_antispoof,+(void*)&cmd_vf_vlan_anti_spoof_port_id,+(void*)&cmd_vf_vlan_anti_spoof_vf_id,+(void*)&cmd_vf_vlan_anti_spoof_on_off,+NULL,+},+};++/* vf mac anti spoof configuration */++/* Common result structure for vf mac anti spoof */+structcmd_vf_mac_anti_spoof_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tmac;+cmdline_fixed_string_tantispoof;+uint8_tport_id;+uint32_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf mac anti spoof enable disable */+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_mac=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+mac,"mac");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_antispoof=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+antispoof,"antispoof");+cmdline_parse_token_num_tcmd_vf_mac_anti_spoof_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_mac_anti_spoof_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+vf_id,UINT32);+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+on_off,"on#off");++staticvoid+cmd_set_vf_mac_anti_spoof_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_mac_anti_spoof_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_mac_anti_spoof(res->port_id,res->vf_id,is_on);+if(ret<0)+printf("vf vlan mac spoofing programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_mac_anti_spoof={+.f=cmd_set_vf_mac_anti_spoof_parsed,+.data=NULL,+.help_str="set vf mac antispoof port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_mac_anti_spoof_set,+(void*)&cmd_vf_mac_anti_spoof_vf,+(void*)&cmd_vf_mac_anti_spoof_mac,+(void*)&cmd_vf_mac_anti_spoof_antispoof,+(void*)&cmd_vf_mac_anti_spoof_port_id,+(void*)&cmd_vf_mac_anti_spoof_vf_id,+(void*)&cmd_vf_mac_anti_spoof_on_off,+NULL,+},+};++/* vf ping configuration */++/* Common result structure for vf ping */+structcmd_vf_ping_result{+cmdline_fixed_string_tvf;+cmdline_fixed_string_tping;+uint8_tport_id;+int32_tvf_id;+};++/* Common CLI fields for ping vfs */+cmdline_parse_token_string_tcmd_vf_ping_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_ping_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_ping_ping=+TOKEN_STRING_INITIALIZER+(structcmd_vf_ping_result,+ping,"ping");+cmdline_parse_token_num_tcmd_vf_ping_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_ping_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_ping_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_ping_result,+vf_id,INT32);++staticvoid+cmd_vf_ping_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_ping_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_vf_ping(res->port_id,res->vf_id);+if(ret<0)+printf("ping vfs programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_vf_ping={+.f=cmd_vf_ping_parsed,+.data=NULL,+.help_str="vf ping port_id vf_id|-1",+.tokens={+(void*)&cmd_vf_ping_vf,+(void*)&cmd_vf_ping_ping,+(void*)&cmd_vf_ping_port_id,+(void*)&cmd_vf_ping_vf_id,+NULL,+},+};++/* vf vlan strip configuration */++/* Common result structure for vf mac anti spoof */+structcmd_vf_vlan_strip_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tstrip;+uint8_tport_id;+uint16_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf vlan strip enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_strip_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_strip_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_strip_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_strip_strip=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+strip,"strip");+cmdline_parse_token_num_tcmd_vf_vlan_strip_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_strip_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_strip_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_strip_result,+vf_id,UINT16);+cmdline_parse_token_string_tcmd_vf_vlan_strip_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_strip_result,+on_off,"on#off");++staticvoid+cmd_set_vf_vlan_strip_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_strip_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_vlan_strip(res->port_id,res->vf_id,is_on);+if(ret<0)+printf("vf vlan strip programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_vlan_strip={+.f=cmd_set_vf_vlan_strip_parsed,+.data=NULL,+.help_str="set vf vlan strip port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_vlan_strip_set,+(void*)&cmd_vf_vlan_strip_vf,+(void*)&cmd_vf_vlan_strip_vlan,+(void*)&cmd_vf_vlan_strip_strip,+(void*)&cmd_vf_vlan_strip_port_id,+(void*)&cmd_vf_vlan_strip_vf_id,+(void*)&cmd_vf_vlan_strip_on_off,+NULL,+},+};++/* vf vlan insert configuration */++/* Common result structure for vf vlan insert */+structcmd_vf_vlan_insert_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tinsert;+uint8_tport_id;+uint16_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf vlan insert enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_insert_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_insert_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_insert_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_insert_insert=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+insert,"insert");+cmdline_parse_token_num_tcmd_vf_vlan_insert_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_insert_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_insert_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_insert_result,+vf_id,UINT16);+cmdline_parse_token_string_tcmd_vf_vlan_insert_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+on_off,"on#off");++staticvoid+cmd_set_vf_vlan_insert_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_insert_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_vlan_insert(res->port_id,res->vf_id,is_on);+if(ret<0)+printf("vf vlan insert programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_vlan_insert={+.f=cmd_set_vf_vlan_insert_parsed,+.data=NULL,+.help_str="set vf vlan insert port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_vlan_insert_set,+(void*)&cmd_vf_vlan_insert_vf,+(void*)&cmd_vf_vlan_insert_vlan,+(void*)&cmd_vf_vlan_insert_insert,+(void*)&cmd_vf_vlan_insert_port_id,+(void*)&cmd_vf_vlan_insert_vf_id,+(void*)&cmd_vf_vlan_insert_on_off,+NULL,+},+};++/* tx loopback configuration */++/* Common result structure for tx loopback */+structcmd_tx_loopback_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_ttx;+cmdline_fixed_string_tloopback;+uint8_tport_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for tx loopback enable disable */+cmdline_parse_token_string_tcmd_tx_loopback_set=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+set,"set");+cmdline_parse_token_string_tcmd_tx_loopback_tx=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+tx,"tx");+cmdline_parse_token_string_tcmd_tx_loopback_loopback=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+loopback,"loopback");+cmdline_parse_token_num_tcmd_tx_loopback_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_tx_loopback_result,+port_id,UINT8);+cmdline_parse_token_string_tcmd_tx_loopback_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+on_off,"on#off");++staticvoid+cmd_set_tx_loopback_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_tx_loopback_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++ret=rte_eth_dev_set_tx_loopback(res->port_id,is_on);+if(ret<0)+printf("tx loopback programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_tx_loopback={+.f=cmd_set_tx_loopback_parsed,+.data=NULL,+.help_str="set tx loopback port_id on|off",+.tokens={+(void*)&cmd_tx_loopback_set,+(void*)&cmd_tx_loopback_tx,+(void*)&cmd_tx_loopback_loopback,+(void*)&cmd_tx_loopback_port_id,+(void*)&cmd_tx_loopback_on_off,+NULL,+},+};++/* all queues drop enable configuration */++/* Common result structure for all queues drop enable */+structcmd_all_queues_drop_en_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tall;+cmdline_fixed_string_tqueues;+cmdline_fixed_string_tdrop;+uint8_tport_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for tx loopback enable disable */+cmdline_parse_token_string_tcmd_all_queues_drop_en_set=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+set,"set");+cmdline_parse_token_string_tcmd_all_queues_drop_en_all=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+all,"all");+cmdline_parse_token_string_tcmd_all_queues_drop_en_queues=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+queues,"queues");+cmdline_parse_token_string_tcmd_all_queues_drop_en_drop=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+drop,"drop");+cmdline_parse_token_num_tcmd_all_queues_drop_en_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_all_queues_drop_en_result,+port_id,UINT8);+cmdline_parse_token_string_tcmd_all_queues_drop_en_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+on_off,"on#off");++staticvoid+cmd_set_all_queues_drop_en_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_all_queues_drop_en_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++ret=rte_eth_dev_set_all_queues_drop_en(res->port_id,is_on);+if(ret<0)+printf("all queues drop enable programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_all_queues_drop_en={+.f=cmd_set_all_queues_drop_en_parsed,+.data=NULL,+.help_str="set all queues drop port_id on|off",+.tokens={+(void*)&cmd_all_queues_drop_en_set,+(void*)&cmd_all_queues_drop_en_all,+(void*)&cmd_all_queues_drop_en_queues,+(void*)&cmd_all_queues_drop_en_drop,+(void*)&cmd_all_queues_drop_en_port_id,+(void*)&cmd_all_queues_drop_en_on_off,+NULL,+},+};++/* vf split drop enable configuration */++/* Common result structure for vf split drop enable */+structcmd_vf_split_drop_en_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tsplit;+cmdline_fixed_string_tdrop;+uint8_tport_id;+uint16_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf split drop enable disable */+cmdline_parse_token_string_tcmd_vf_split_drop_en_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_split_drop_en_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_split_drop_en_split=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+split,"split");+cmdline_parse_token_string_tcmd_vf_split_drop_en_drop=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+drop,"drop");+cmdline_parse_token_num_tcmd_vf_split_drop_en_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_split_drop_en_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_split_drop_en_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_split_drop_en_result,+vf_id,UINT16);+cmdline_parse_token_string_tcmd_vf_split_drop_en_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+on_off,"on#off");++staticvoid+cmd_set_vf_split_drop_en_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_split_drop_en_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_split_drop_en(res->port_id,res->vf_id,is_on);+if(ret<0)+printf("vf split drop enable programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_split_drop_en={+.f=cmd_set_vf_split_drop_en_parsed,+.data=NULL,+.help_str="set vf split drop port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_split_drop_en_set,+(void*)&cmd_vf_split_drop_en_vf,+(void*)&cmd_vf_split_drop_en_split,+(void*)&cmd_vf_split_drop_en_drop,+(void*)&cmd_vf_split_drop_en_port_id,+(void*)&cmd_vf_split_drop_en_vf_id,+(void*)&cmd_vf_split_drop_en_on_off,+NULL,+},+};++/* vf mac address configuration */++/* Common result structure for vf mac address */+structcmd_set_vf_mac_addr_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tmac;+cmdline_fixed_string_taddr;+uint8_tport_id;+uint16_tvf_id;+structether_addrmac_addr;++};++/* Common CLI fields for vf split drop enable disable */+cmdline_parse_token_string_tcmd_set_vf_mac_addr_set=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+set,"set");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_vf=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+vf,"vf");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_mac=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+mac,"mac");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_addr=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+addr,"addr");+cmdline_parse_token_num_tcmd_set_vf_mac_addr_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_set_vf_mac_addr_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_set_vf_mac_addr_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_set_vf_mac_addr_result,+vf_id,UINT16);+cmdline_parse_token_etheraddr_tcmd_set_vf_mac_addr_mac_addr=+TOKEN_ETHERADDR_INITIALIZER(structcmd_set_vf_mac_addr_result,+mac_addr);++staticvoid+cmd_set_vf_mac_addr_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_set_vf_mac_addr_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_mac_addr(res->port_id,res->vf_id,&res->mac_addr);+if(ret<0)+printf("set vf mac addr programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_mac_addr={+.f=cmd_set_vf_mac_addr_parsed,+.data=NULL,+.help_str="set vf mac addr port_id vf_id xx:xx:xx:xx:xx:xx",+.tokens={+(void*)&cmd_set_vf_mac_addr_set,+(void*)&cmd_set_vf_mac_addr_vf,+(void*)&cmd_set_vf_mac_addr_mac,+(void*)&cmd_set_vf_mac_addr_addr,+(void*)&cmd_set_vf_mac_addr_port_id,+(void*)&cmd_set_vf_mac_addr_vf_id,+(void*)&cmd_set_vf_mac_addr_mac_addr,+NULL,+},+};+/* ******************************************************************************** *//* list of instructions */
@@ -1,5 +1,5 @@.. BSD LICENSE- Copyright(c) 2010-2015 Intel Corporation. All rights reserved.+ Copyright(c) 2010-2016 Intel Corporation. All rights reserved. All rights reserved. Redistribution and use in source and binary forms, with or without
@@ -473,6 +473,41 @@ For example, to change the port forwarding: RX P=1/Q=0 (socket 0) -> TX P=3/Q=0 (socket 0) peer=02:00:00:00:00:03 RX P=3/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:02+set tx loopback+~~~~~~~~~~~~~~~++Enable/disable tx loopback::++ testpmd> set tx loopback (port_id) (on|off)++set drop enable+~~~~~~~~~~~~~~~++set drop enable bit for all queues::++ testpmd> set all queues drop (port_id) (on|off)++set split drop enable (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++set split drop enable bit for VF from PF::++ testpmd> set vf split drop (port_id) (vf_id) (on|off)++set mac antispoof (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~++Set mac antispoof for a VF from the PF::++ testpmd> set vf mac antispoof (port_id) (vf_id) (on|off)++ping VF+~~~~~~~++Ping VF or all VF's from PF::++ testpmd> vf ping (port_id) (vf_id | -1)+ vlan set strip ~~~~~~~~~~~~~~
@@ -487,6 +522,28 @@ Set the VLAN strip for a queue on a port:: testpmd> vlan set stripq (on|off) (port_id,queue_id)+vlan set strip (for VF)+~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN strip for a VF from the PF::++ testpmd> set vf vlan strip (port_id) (vf_id) (on|off)++vlan set insert (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN insert for a VF from the PF::++ testpmd> set vf vlan insert (port_id) (vf_id) (on|off)++vlan set antispoof (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN antispoof for a VF from the PF::++ testpmd> set vf vlan antispoof (port_id) (vf_id) (on|off)++ vlan set filter ~~~~~~~~~~~~~~~
@@ -727,13 +784,20 @@ Remove a MAC address from a port:: testpmd> mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)-mac_addr add(for VF)-~~~~~~~~~~~~~~~~~~~~+mac_addr add (for VF)+~~~~~~~~~~~~~~~~~~~~~ Add an alternative MAC address for a VF to a port:: testpmd> mac_add add port (port_id) vf (vf_id) (XX:XX:XX:XX:XX:XX)+mac_addr set (for VF)+~~~~~~~~~~~~~~~~~~~~~++Set the MAC address for a VF from the PF::++ testpmd> set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)+ set port-uta ~~~~~~~~~~~~
From: Bernard Iremonger <hidden> Date: 2016-09-21 10:20:12
This patchset contains new DPDK API's requested by AT&T for use
with the Virtual Function Daemon (VFD).
The need to configure and manage VF's on a NIC has grown to the
point where AT&T have devloped a DPDK based tool, VFD, to do this.
This patch set adds API extensions to DPDK VF configuration.
Eight new functions have been added to the eth_dev_ops structure.
Corresponding functions have been added to the ixgbe PMD for the
Intel 82559 NIC.
Changes have been made to testpmd to facilitate testing of the new API's.
The testpmd documentation has been updated to document the testpmd changes.
Note:
Adding new functions to the eth_dev_ops structure will cause an
ABI breakage.
Changes in v4:
rebase to latest master branch.
The rte_eth_dev_vf_ping API has been dropped as it is a work around for a bug.
The rte_eth_dev_set_vf_vlan_strip API has been renamed to
rte_eth_dev_set_vf_vlan_stripq.
Changes in v3:
rebase to latest master branch.
drop patches for callback functions
revise VF id checks in new librte_ether functions
revise testpmd commands for new API's
Changes in V2:
rebase to latest master branch.
fix compile error with clang.
Bernard Iremonger (3):
librte_ether: add API's for VF management
net/ixgbe: add functions for VF management
app/test_pmd: add tests for new API's
app/test-pmd/cmdline.c | 644 ++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 62 ++-
drivers/net/ixgbe/ixgbe_ethdev.c | 138 ++++++
lib/librte_ether/rte_ethdev.c | 169 ++++++++
lib/librte_ether/rte_ethdev.h | 195 ++++++++-
lib/librte_ether/rte_ether_version.map | 13 +
6 files changed, 1217 insertions(+), 4 deletions(-)
--
2.9.0
@@ -1233,6 +1233,11 @@ typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,structether_addr*mac_addr);/**< @internal Set a MAC address into Receive Address Address Register */+typedefint(*eth_set_vf_mac_addr_t)(structrte_eth_dev*dev,+uint16_tvf,+structether_addr*mac_addr);+/**< @internal Set VF address into Receive Address Address Register */+typedefint(*eth_uc_hash_table_set_t)(structrte_eth_dev*dev,structether_addr*mac_addr,uint8_ton);
@@ -1264,6 +1269,34 @@ typedef int (*eth_set_vf_vlan_filter_t)(struct rte_eth_dev *dev,uint8_tvlan_on);/**< @internal Set VF VLAN pool filter */+typedefvoid(*eth_set_vf_vlan_anti_spoof_t)(structrte_eth_dev*dev,+uint16_tvf,+uint8_ton);+/**< @internal Set VF VLAN anti spoof */++typedefvoid(*eth_set_vf_mac_anti_spoof_t)(structrte_eth_dev*dev,+uint16_tvf,+uint8_ton);+/**< @internal Set VF MAC anti spoof */++typedefvoid(*eth_set_vf_vlan_insert_t)(structrte_eth_dev*dev,+uint16_tvf,+intvlan);+/**< @internal Set VF vlan insert */++typedefvoid(*eth_set_tx_loopback_t)(structrte_eth_dev*dev,+inton);+/**< @internal Set tx loopback */++typedefvoid(*eth_set_all_queues_drop_en_t)(structrte_eth_dev*dev,+intstate);+/**< @internal Set all queues drop */++typedefvoid(*eth_set_vf_split_drop_en_t)(structrte_eth_dev*dev,+uint16_tvf,+intstate);+/**< @internal Set the enable drop bit in the VF split rx control register */+typedefint(*eth_set_queue_rate_limit_t)(structrte_eth_dev*dev,uint16_tqueue_idx,uint16_ttx_rate);
@@ -1468,6 +1501,7 @@ struct eth_dev_ops {eth_mac_addr_remove_tmac_addr_remove;/**< Remove MAC address */eth_mac_addr_add_tmac_addr_add;/**< Add a MAC address */eth_mac_addr_set_tmac_addr_set;/**< Set a MAC address */+eth_set_vf_mac_addr_tset_vf_mac_addr;/**< Set a VF MAC address */eth_uc_hash_table_set_tuc_hash_table_set;/**< Set Unicast Table Array */eth_uc_all_hash_table_set_tuc_all_hash_table_set;/**< Set Unicast hash bitmap */eth_mirror_rule_set_tmirror_rule_set;/**< Add a traffic mirror rule.*/
@@ -1476,6 +1510,12 @@ struct eth_dev_ops {eth_set_vf_rx_tset_vf_rx;/**< enable/disable a VF receive */eth_set_vf_tx_tset_vf_tx;/**< enable/disable a VF transmit */eth_set_vf_vlan_filter_tset_vf_vlan_filter;/**< Set VF VLAN filter */+eth_set_vf_vlan_anti_spoof_tset_vf_vlan_anti_spoof;/**< Set VF VLAN anti spoof */+eth_set_vf_mac_anti_spoof_tset_vf_mac_anti_spoof;/**< Set VF MAC anti spoof */+eth_set_vf_vlan_insert_tset_vf_vlan_insert;/** <Set VF VLAN insert */+eth_set_tx_loopback_tset_tx_loopback;/** <Set tx loopback */+eth_set_all_queues_drop_en_tset_all_queues_drop_en;/** <Set queue drop enable bit */+eth_set_vf_split_drop_en_tset_vf_split_drop_en;/** <Set split drop enable bit.*//** Add UDP tunnel port. */eth_udp_tunnel_port_add_tudp_tunnel_port_add;/** Del UDP tunnel port. */
@@ -3332,7 +3372,23 @@ int rte_eth_dev_mac_addr_remove(uint8_t port, struct ether_addr *mac_addr);*/intrte_eth_dev_default_mac_addr_set(uint8_tport,structether_addr*mac_addr);-+/**+*SettheVFMACaddress.+*+*@paramport+*TheportidentifieroftheEthernetdevice.+*@paramvf+*VFid.+*@parammac_addr+*VFMACaddress.+*@return+*-(0)ifsuccessful,or*mac_addr*didn'texist.+*-(-ENOTSUP)ifhardwaredoesn'tsupport.+*-(-ENODEV)if*port*invalid.+*-(-EINVAL)ifMACaddressisinvalid.+*/+intrte_eth_dev_set_vf_mac_addr(uint8_tport,uint16_tvf,+structether_addr*mac_addr);/***UpdateRedirectionTable(RETA)ofReceiveSideScalingofEthernetdevice.*
From: Bernard Iremonger <hidden> Date: 2016-09-21 10:20:22
add test for vf vlan anti spoof
add test for vf mac anti spoof
add test for vf vlan stripq
add test for vf vlan insert
add test for tx loopback
add test for all queues drop enable bit
add test for vf split drop enable bit
add test for vf mac address
add new API's to the testpmd guide
Signed-off-by: Bernard Iremonger <redacted>
---
app/test-pmd/cmdline.c | 644 ++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 62 ++-
2 files changed, 703 insertions(+), 3 deletions(-)
@@ -10585,6 +10585,642 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {},};+/* vf vlan anti spoof configuration */++/* Common result structure for vf vlan anti spoof */+structcmd_vf_vlan_anti_spoof_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tantispoof;+uint8_tport_id;+uint32_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf vlan anti spoof enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_antispoof=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+antispoof,"antispoof");+cmdline_parse_token_num_tcmd_vf_vlan_anti_spoof_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_anti_spoof_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vf_id,UINT32);+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+on_off,"on#off");++staticvoid+cmd_set_vf_vlan_anti_spoof_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_anti_spoof_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}+ret=rte_eth_dev_set_vf_vlan_anti_spoof(res->port_id,res->vf_id,is_on);+if(ret<0)+printf("vf vlan anti spoofing programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_vlan_anti_spoof={+.f=cmd_set_vf_vlan_anti_spoof_parsed,+.data=NULL,+.help_str="set vf vlan antispoof port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_vlan_anti_spoof_set,+(void*)&cmd_vf_vlan_anti_spoof_vf,+(void*)&cmd_vf_vlan_anti_spoof_vlan,+(void*)&cmd_vf_vlan_anti_spoof_antispoof,+(void*)&cmd_vf_vlan_anti_spoof_port_id,+(void*)&cmd_vf_vlan_anti_spoof_vf_id,+(void*)&cmd_vf_vlan_anti_spoof_on_off,+NULL,+},+};++/* vf mac anti spoof configuration */++/* Common result structure for vf mac anti spoof */+structcmd_vf_mac_anti_spoof_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tmac;+cmdline_fixed_string_tantispoof;+uint8_tport_id;+uint32_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf mac anti spoof enable disable */+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_mac=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+mac,"mac");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_antispoof=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+antispoof,"antispoof");+cmdline_parse_token_num_tcmd_vf_mac_anti_spoof_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_mac_anti_spoof_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+vf_id,UINT32);+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+on_off,"on#off");++staticvoid+cmd_set_vf_mac_anti_spoof_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_mac_anti_spoof_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_mac_anti_spoof(res->port_id,res->vf_id,is_on);+if(ret<0)+printf("vf vlan mac spoofing programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_mac_anti_spoof={+.f=cmd_set_vf_mac_anti_spoof_parsed,+.data=NULL,+.help_str="set vf mac antispoof port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_mac_anti_spoof_set,+(void*)&cmd_vf_mac_anti_spoof_vf,+(void*)&cmd_vf_mac_anti_spoof_mac,+(void*)&cmd_vf_mac_anti_spoof_antispoof,+(void*)&cmd_vf_mac_anti_spoof_port_id,+(void*)&cmd_vf_mac_anti_spoof_vf_id,+(void*)&cmd_vf_mac_anti_spoof_on_off,+NULL,+},+};++++/* vf vlan strip queue configuration */++/* Common result structure for vf mac anti spoof */+structcmd_vf_vlan_stripq_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tstripq;+uint8_tport_id;+uint16_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf vlan strip enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_stripq_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_stripq_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_stripq_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_stripq_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_stripq_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_stripq_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_stripq_stripq=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_stripq_result,+stripq,"stripq");+cmdline_parse_token_num_tcmd_vf_vlan_stripq_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_stripq_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_stripq_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_stripq_result,+vf_id,UINT16);+cmdline_parse_token_string_tcmd_vf_vlan_stripq_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_stripq_result,+on_off,"on#off");++staticvoid+cmd_set_vf_vlan_stripq_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_stripq_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_vlan_stripq(res->port_id,res->vf_id,is_on);+if(ret<0)+printf("vf vlan strip programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_vlan_stripq={+.f=cmd_set_vf_vlan_stripq_parsed,+.data=NULL,+.help_str="set vf vlan stripq port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_vlan_stripq_set,+(void*)&cmd_vf_vlan_stripq_vf,+(void*)&cmd_vf_vlan_stripq_vlan,+(void*)&cmd_vf_vlan_stripq_stripq,+(void*)&cmd_vf_vlan_stripq_port_id,+(void*)&cmd_vf_vlan_stripq_vf_id,+(void*)&cmd_vf_vlan_stripq_on_off,+NULL,+},+};++/* vf vlan insert configuration */++/* Common result structure for vf vlan insert */+structcmd_vf_vlan_insert_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tinsert;+uint8_tport_id;+uint16_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf vlan insert enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_insert_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_insert_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_insert_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_insert_insert=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+insert,"insert");+cmdline_parse_token_num_tcmd_vf_vlan_insert_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_insert_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_insert_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_insert_result,+vf_id,UINT16);+cmdline_parse_token_string_tcmd_vf_vlan_insert_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+on_off,"on#off");++staticvoid+cmd_set_vf_vlan_insert_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_insert_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_vlan_insert(res->port_id,res->vf_id,is_on);+if(ret<0)+printf("vf vlan insert programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_vlan_insert={+.f=cmd_set_vf_vlan_insert_parsed,+.data=NULL,+.help_str="set vf vlan insert port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_vlan_insert_set,+(void*)&cmd_vf_vlan_insert_vf,+(void*)&cmd_vf_vlan_insert_vlan,+(void*)&cmd_vf_vlan_insert_insert,+(void*)&cmd_vf_vlan_insert_port_id,+(void*)&cmd_vf_vlan_insert_vf_id,+(void*)&cmd_vf_vlan_insert_on_off,+NULL,+},+};++/* tx loopback configuration */++/* Common result structure for tx loopback */+structcmd_tx_loopback_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_ttx;+cmdline_fixed_string_tloopback;+uint8_tport_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for tx loopback enable disable */+cmdline_parse_token_string_tcmd_tx_loopback_set=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+set,"set");+cmdline_parse_token_string_tcmd_tx_loopback_tx=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+tx,"tx");+cmdline_parse_token_string_tcmd_tx_loopback_loopback=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+loopback,"loopback");+cmdline_parse_token_num_tcmd_tx_loopback_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_tx_loopback_result,+port_id,UINT8);+cmdline_parse_token_string_tcmd_tx_loopback_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+on_off,"on#off");++staticvoid+cmd_set_tx_loopback_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_tx_loopback_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++ret=rte_eth_dev_set_tx_loopback(res->port_id,is_on);+if(ret<0)+printf("tx loopback programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_tx_loopback={+.f=cmd_set_tx_loopback_parsed,+.data=NULL,+.help_str="set tx loopback port_id on|off",+.tokens={+(void*)&cmd_tx_loopback_set,+(void*)&cmd_tx_loopback_tx,+(void*)&cmd_tx_loopback_loopback,+(void*)&cmd_tx_loopback_port_id,+(void*)&cmd_tx_loopback_on_off,+NULL,+},+};++/* all queues drop enable configuration */++/* Common result structure for all queues drop enable */+structcmd_all_queues_drop_en_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tall;+cmdline_fixed_string_tqueues;+cmdline_fixed_string_tdrop;+uint8_tport_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for tx loopback enable disable */+cmdline_parse_token_string_tcmd_all_queues_drop_en_set=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+set,"set");+cmdline_parse_token_string_tcmd_all_queues_drop_en_all=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+all,"all");+cmdline_parse_token_string_tcmd_all_queues_drop_en_queues=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+queues,"queues");+cmdline_parse_token_string_tcmd_all_queues_drop_en_drop=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+drop,"drop");+cmdline_parse_token_num_tcmd_all_queues_drop_en_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_all_queues_drop_en_result,+port_id,UINT8);+cmdline_parse_token_string_tcmd_all_queues_drop_en_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+on_off,"on#off");++staticvoid+cmd_set_all_queues_drop_en_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_all_queues_drop_en_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++ret=rte_eth_dev_set_all_queues_drop_en(res->port_id,is_on);+if(ret<0)+printf("all queues drop enable programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_all_queues_drop_en={+.f=cmd_set_all_queues_drop_en_parsed,+.data=NULL,+.help_str="set all queues drop port_id on|off",+.tokens={+(void*)&cmd_all_queues_drop_en_set,+(void*)&cmd_all_queues_drop_en_all,+(void*)&cmd_all_queues_drop_en_queues,+(void*)&cmd_all_queues_drop_en_drop,+(void*)&cmd_all_queues_drop_en_port_id,+(void*)&cmd_all_queues_drop_en_on_off,+NULL,+},+};++/* vf split drop enable configuration */++/* Common result structure for vf split drop enable */+structcmd_vf_split_drop_en_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tsplit;+cmdline_fixed_string_tdrop;+uint8_tport_id;+uint16_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf split drop enable disable */+cmdline_parse_token_string_tcmd_vf_split_drop_en_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_split_drop_en_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_split_drop_en_split=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+split,"split");+cmdline_parse_token_string_tcmd_vf_split_drop_en_drop=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+drop,"drop");+cmdline_parse_token_num_tcmd_vf_split_drop_en_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_split_drop_en_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_split_drop_en_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_split_drop_en_result,+vf_id,UINT16);+cmdline_parse_token_string_tcmd_vf_split_drop_en_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+on_off,"on#off");++staticvoid+cmd_set_vf_split_drop_en_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_split_drop_en_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_split_drop_en(res->port_id,res->vf_id,is_on);+if(ret<0)+printf("vf split drop enable programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_split_drop_en={+.f=cmd_set_vf_split_drop_en_parsed,+.data=NULL,+.help_str="set vf split drop port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_split_drop_en_set,+(void*)&cmd_vf_split_drop_en_vf,+(void*)&cmd_vf_split_drop_en_split,+(void*)&cmd_vf_split_drop_en_drop,+(void*)&cmd_vf_split_drop_en_port_id,+(void*)&cmd_vf_split_drop_en_vf_id,+(void*)&cmd_vf_split_drop_en_on_off,+NULL,+},+};++/* vf mac address configuration */++/* Common result structure for vf mac address */+structcmd_set_vf_mac_addr_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tmac;+cmdline_fixed_string_taddr;+uint8_tport_id;+uint16_tvf_id;+structether_addrmac_addr;++};++/* Common CLI fields for vf split drop enable disable */+cmdline_parse_token_string_tcmd_set_vf_mac_addr_set=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+set,"set");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_vf=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+vf,"vf");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_mac=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+mac,"mac");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_addr=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+addr,"addr");+cmdline_parse_token_num_tcmd_set_vf_mac_addr_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_set_vf_mac_addr_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_set_vf_mac_addr_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_set_vf_mac_addr_result,+vf_id,UINT16);+cmdline_parse_token_etheraddr_tcmd_set_vf_mac_addr_mac_addr=+TOKEN_ETHERADDR_INITIALIZER(structcmd_set_vf_mac_addr_result,+mac_addr);++staticvoid+cmd_set_vf_mac_addr_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_set_vf_mac_addr_result*res=parsed_result;+intret=0;++if(port_id_is_invalid(res->port_id,ENABLED_WARN))+return;++if(res->vf_id>63){+printf("vf_id must be less than 64.\n");+return;+}++ret=rte_eth_dev_set_vf_mac_addr(res->port_id,res->vf_id,&res->mac_addr);+if(ret<0)+printf("set vf mac addr programming error: (%s)\n",+strerror(-ret));+}++cmdline_parse_inst_tcmd_set_vf_mac_addr={+.f=cmd_set_vf_mac_addr_parsed,+.data=NULL,+.help_str="set vf mac addr port_id vf_id xx:xx:xx:xx:xx:xx",+.tokens={+(void*)&cmd_set_vf_mac_addr_set,+(void*)&cmd_set_vf_mac_addr_vf,+(void*)&cmd_set_vf_mac_addr_mac,+(void*)&cmd_set_vf_mac_addr_addr,+(void*)&cmd_set_vf_mac_addr_port_id,+(void*)&cmd_set_vf_mac_addr_vf_id,+(void*)&cmd_set_vf_mac_addr_mac_addr,+NULL,+},+};+/* ******************************************************************************** *//* list of instructions */
@@ -1,5 +1,5 @@.. BSD LICENSE- Copyright(c) 2010-2015 Intel Corporation. All rights reserved.+ Copyright(c) 2010-2016 Intel Corporation. All rights reserved. All rights reserved. Redistribution and use in source and binary forms, with or without
@@ -473,6 +473,34 @@ For example, to change the port forwarding: RX P=1/Q=0 (socket 0) -> TX P=3/Q=0 (socket 0) peer=02:00:00:00:00:03 RX P=3/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:02+set tx loopback+~~~~~~~~~~~~~~~++Enable/disable tx loopback::++ testpmd> set tx loopback (port_id) (on|off)++set drop enable+~~~~~~~~~~~~~~~++set drop enable bit for all queues::++ testpmd> set all queues drop (port_id) (on|off)++set split drop enable (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++set split drop enable bit for VF from PF::++ testpmd> set vf split drop (port_id) (vf_id) (on|off)++set mac antispoof (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~++Set mac antispoof for a VF from the PF::++ testpmd> set vf mac antispoof (port_id) (vf_id) (on|off)+ vlan set strip ~~~~~~~~~~~~~~
@@ -487,6 +515,27 @@ Set the VLAN strip for a queue on a port:: testpmd> vlan set stripq (on|off) (port_id,queue_id)+vlan set stripq (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN strip for all queues in a pool for a VF from the PF::++ testpmd> set vf vlan stripq (port_id) (vf_id) (on|off)++vlan set insert (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN insert for a VF from the PF::++ testpmd> set vf vlan insert (port_id) (vf_id) (on|off)++vlan set antispoof (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN antispoof for a VF from the PF::++ testpmd> set vf vlan antispoof (port_id) (vf_id) (on|off)+ vlan set filter ~~~~~~~~~~~~~~~
@@ -727,13 +776,20 @@ Remove a MAC address from a port:: testpmd> mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)-mac_addr add(for VF)-~~~~~~~~~~~~~~~~~~~~+mac_addr add (for VF)+~~~~~~~~~~~~~~~~~~~~~ Add an alternative MAC address for a VF to a port:: testpmd> mac_add add port (port_id) vf (vf_id) (XX:XX:XX:XX:XX:XX)+mac_addr set (for VF)+~~~~~~~~~~~~~~~~~~~~~++Set the MAC address for a VF from the PF::++ testpmd> set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)+ set port-uta ~~~~~~~~~~~~
From: Thomas Monjalon <hidden> Date: 2016-09-22 17:04:39
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
Do we really need to expose VF specific functions here?
It can be generic(PF/VF) function indexed only through port_id.
(example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id,
uint8_t on)) For instance, In Thunderx PMD, We are not exposing a
separate port_id for PF. We only enumerate 0..N VFs as 0..N ethdev
port_id
Our intention with this patch is to control the VF from the PF.
The following librte_ether functions already work in a similar way:
rte_eth_dev_set_vf_rxmode(uint8_t port_id, uint16_t vf, uint16_t
rx_mode, uint8_t on)
rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t
tx_rate, uint64_t q_msk)
I have a bad feeling with these functions dedicated to VF from PF.
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the VF is not visible to the PF.
I don't think there is another way to do this.
I don't understand why we could not assign a port id to the VF from the
host instead of having the couple PF port id / VF id.
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array rte_eth_devices?
From: Bruce Richardson <hidden> Date: 2016-09-23 09:20:52
On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
quoted
Do we really need to expose VF specific functions here?
It can be generic(PF/VF) function indexed only through port_id.
(example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id,
uint8_t on)) For instance, In Thunderx PMD, We are not exposing a
separate port_id for PF. We only enumerate 0..N VFs as 0..N ethdev
port_id
Our intention with this patch is to control the VF from the PF.
The following librte_ether functions already work in a similar way:
rte_eth_dev_set_vf_rxmode(uint8_t port_id, uint16_t vf, uint16_t
rx_mode, uint8_t on)
rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t
tx_rate, uint64_t q_msk)
I have a bad feeling with these functions dedicated to VF from PF.
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the VF is not visible to the PF.
I don't think there is another way to do this.
I don't understand why we could not assign a port id to the VF from the
host instead of having the couple PF port id / VF id.
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array rte_eth_devices?
Hi Thomas,
The VF is not a port visible to DPDK, though, so it shouldn't have a port id
IMHO. DPDK can't actually do anything with it.
The PCI device for the VF is likely passed through to a different VM and being
used there. Unfortunately, the VF still needs certain things done for it by the
PF, so if the PF is under DPDK control, it needs to provide the functionality
to assist the VF.
/Bruce
From: Thomas Monjalon <hidden> Date: 2016-09-23 09:36:23
2016-09-23 10:20, Bruce Richardson:
On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
quoted
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
quoted
Do we really need to expose VF specific functions here?
It can be generic(PF/VF) function indexed only through port_id.
(example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id,
uint8_t on)) For instance, In Thunderx PMD, We are not exposing a
separate port_id for PF. We only enumerate 0..N VFs as 0..N ethdev
port_id
Our intention with this patch is to control the VF from the PF.
The following librte_ether functions already work in a similar way:
rte_eth_dev_set_vf_rxmode(uint8_t port_id, uint16_t vf, uint16_t
rx_mode, uint8_t on)
rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t
tx_rate, uint64_t q_msk)
I have a bad feeling with these functions dedicated to VF from PF.
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the VF is not visible to the PF.
I don't think there is another way to do this.
I don't understand why we could not assign a port id to the VF from the
host instead of having the couple PF port id / VF id.
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array rte_eth_devices?
Hi Thomas,
The VF is not a port visible to DPDK, though, so it shouldn't have a port id
IMHO. DPDK can't actually do anything with it.
You say the contrary below.
The PCI device for the VF is likely passed through to a different VM and being
used there. Unfortunately, the VF still needs certain things done for it by the
PF, so if the PF is under DPDK control, it needs to provide the functionality
to assist the VF.
Why not have a VF_from_PF driver which does the mailbox things?
So you can manage the VF from the PF with a simple port id.
It really seems to be the cleanest design to me.
From: Richardson, Bruce <hidden> Date: 2016-09-23 09:53:53
-----Original Message-----
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
Sent: Friday, September 23, 2016 10:36 AM
To: Richardson, Bruce <redacted>
Cc: Iremonger, Bernard <redacted>; dev@dpdk.org; Jerin
Jacob [off-list ref]; Shah, Rahul R
[off-list ref]; Lu, Wenzhuo [off-list ref]; azelezniak
[off-list ref]
Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
management
2016-09-23 10:20, Bruce Richardson:
quoted
On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
quoted
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
quoted
Do we really need to expose VF specific functions here?
It can be generic(PF/VF) function indexed only through
port_id.
quoted
quoted
quoted
quoted
quoted
quoted
(example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t
port_id, uint8_t on)) For instance, In Thunderx PMD, We are
not exposing a separate port_id for PF. We only enumerate
0..N VFs as 0..N ethdev port_id
Our intention with this patch is to control the VF from the PF.
The following librte_ether functions already work in a similar
I have a bad feeling with these functions dedicated to VF from PF.
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the VF is not visible to
the PF.
quoted
quoted
quoted
I don't think there is another way to do this.
I don't understand why we could not assign a port id to the VF from
the host instead of having the couple PF port id / VF id.
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array rte_eth_devices?
Hi Thomas,
The VF is not a port visible to DPDK, though, so it shouldn't have a
port id IMHO. DPDK can't actually do anything with it.
You say the contrary below.
Well, yes and no. The driver can manipulate things for the VF, but DPDK doesn't actually have a device that corresponds to the VF. There are no PCI bar mappings for it, DPDK can't do RX and TX with it etc.?
quoted
The PCI device for the VF is likely passed through to a different VM
and being used there. Unfortunately, the VF still needs certain things
done for it by the PF, so if the PF is under DPDK control, it needs to
provide the functionality to assist the VF.
Why not have a VF_from_PF driver which does the mailbox things?
So you can manage the VF from the PF with a simple port id.
It really seems to be the cleanest design to me.
While I see your point, and it could work, I just want to be sure that we are ok with the results of that. Suppose we do create ethdevs for the VFs controlled by the PF. Does the new VF get counted in the rte_eth_dev_count() value (I assume yes)? How are apps meant to use the port? Do they have to put in a special case when iterating through all the port ids to check that it's not a pseudo port that can't do anything. None of the standard ethdev calls from an app will work on it, you can't configure nb rx/tx queues on it, you can't start or stop it, you can't do rx or tx on it, etc, etc.
/Bruce
From: Bruce Richardson <hidden> Date: 2016-09-23 10:34:16
On Fri, Sep 23, 2016 at 11:36:21AM +0200, Thomas Monjalon wrote:
2016-09-23 10:20, Bruce Richardson:
quoted
On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
quoted
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
quoted
Do we really need to expose VF specific functions here?
It can be generic(PF/VF) function indexed only through port_id.
(example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id,
uint8_t on)) For instance, In Thunderx PMD, We are not exposing a
separate port_id for PF. We only enumerate 0..N VFs as 0..N ethdev
port_id
Our intention with this patch is to control the VF from the PF.
The following librte_ether functions already work in a similar way:
rte_eth_dev_set_vf_rxmode(uint8_t port_id, uint16_t vf, uint16_t
rx_mode, uint8_t on)
rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t
tx_rate, uint64_t q_msk)
I have a bad feeling with these functions dedicated to VF from PF.
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the VF is not visible to the PF.
I don't think there is another way to do this.
I don't understand why we could not assign a port id to the VF from the
host instead of having the couple PF port id / VF id.
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array rte_eth_devices?
Hi Thomas,
The VF is not a port visible to DPDK, though, so it shouldn't have a port id
IMHO. DPDK can't actually do anything with it.
You say the contrary below.
quoted
The PCI device for the VF is likely passed through to a different VM and being
used there. Unfortunately, the VF still needs certain things done for it by the
PF, so if the PF is under DPDK control, it needs to provide the functionality
to assist the VF.
Why not have a VF_from_PF driver which does the mailbox things?
So you can manage the VF from the PF with a simple port id.
It really seems to be the cleanest design to me.
Just to confirm I am understanding your suggestion correctly:
* for a normal app, eg. testpmd or l2fwd, things stay exactly as they are
* for an app that wants to control VFs from PFs, then we provide a new
ethdev driver, and a call in the PF to create an new instance of it
e.g. rte_eth_vf_from_pf(pf_port_id, vf_number)
* then to control the VF, you make regular rte_ethdev calls using the new
ethdev port id you got from the vf_from_pf call.
* it's up to that app to know what ports are regular ports that can do IO,
and what ports are VF control ports, though we may add in an ethdev flag value
somewhere to assist in this.
Is that basically it?
/Bruce
From: Thomas Monjalon <hidden> Date: 2016-09-23 13:15:28
2016-09-23 09:53, Richardson, Bruce:
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 10:20, Bruce Richardson:
quoted
On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
quoted
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
quoted
Do we really need to expose VF specific functions here?
It can be generic(PF/VF) function indexed only through
port_id.
quoted
quoted
quoted
quoted
quoted
quoted
(example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t
port_id, uint8_t on)) For instance, In Thunderx PMD, We are
not exposing a separate port_id for PF. We only enumerate
0..N VFs as 0..N ethdev port_id
Our intention with this patch is to control the VF from the PF.
The following librte_ether functions already work in a similar
I have a bad feeling with these functions dedicated to VF from PF.
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the VF is not visible to
the PF.
quoted
quoted
quoted
I don't think there is another way to do this.
I don't understand why we could not assign a port id to the VF from
the host instead of having the couple PF port id / VF id.
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array rte_eth_devices?
Hi Thomas,
The VF is not a port visible to DPDK, though, so it shouldn't have a
port id IMHO. DPDK can't actually do anything with it.
You say the contrary below.
Well, yes and no. The driver can manipulate things for the VF, but DPDK doesn't actually have a device that corresponds to the VF. There are no PCI bar mappings for it, DPDK can't do RX and TX with it etc.?
Very good point.
There are only few ethdev functions which are supported by every drivers,
like Rx/Tx and would not be available for VF from PF interface.
quoted
quoted
The PCI device for the VF is likely passed through to a different VM
and being used there. Unfortunately, the VF still needs certain things
done for it by the PF, so if the PF is under DPDK control, it needs to
provide the functionality to assist the VF.
Why not have a VF_from_PF driver which does the mailbox things?
So you can manage the VF from the PF with a simple port id.
It really seems to be the cleanest design to me.
While I see your point, and it could work, I just want to be sure that we are ok with the results of that. Suppose we do create ethdevs for the VFs controlled by the PF. Does the new VF get counted in the rte_eth_dev_count() value (I assume yes)? How are apps meant to use the port? Do they have to put in a special case when iterating through all the port ids to check that it's not a pseudo port that can't do anything. None of the standard ethdev calls from an app will work on it, you can't configure nb rx/tx queues on it, you can't start or stop it, you can't do rx or tx on it, etc, etc.
Yes these devices would be special because their supported API would be
quite different. I was thinking that in the future you could add most
of the configuration functions through the VF mailbox.
But the Intel mailbox currently support only some special configurations
which are not supported by other devices even its own VF device (except
setting MAC address).
And when I read "set drop enable bit in the VF split rx control register",
it becomes clear it is really specific and has nothing to do in the
generic ethdev API.
That's why it is a NACK.
When we want to use these very specific features we are aware of the
underlying device and driver. So we can directly include a header from
the driver. I suggest to retrieve a handler for the device which is not
a port id and will allow to call ixgbe functions directly.
It could be achieved by adding an ethdev function like discussed here:
http://dpdk.org/ml/archives/dev/2016-September/047392.html
From: Iremonger, Bernard <hidden> Date: 2016-09-23 17:02:20
Hi Thoms
-----Original Message-----
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
Sent: Friday, September 23, 2016 2:15 PM
To: Richardson, Bruce <redacted>; Iremonger, Bernard
[off-list ref]
Cc: dev@dpdk.org; Jerin Jacob <redacted>; Shah,
Rahul R [off-list ref]; Lu, Wenzhuo [off-list ref];
azelezniak [off-list ref]
Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
management
2016-09-23 09:53, Richardson, Bruce:
quoted
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 10:20, Bruce Richardson:
quoted
On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
quoted
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
quoted
Do we really need to expose VF specific functions here?
It can be generic(PF/VF) function indexed only through
port_id.
quoted
quoted
quoted
quoted
quoted
quoted
(example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t
port_id, uint8_t on)) For instance, In Thunderx PMD, We
are not exposing a separate port_id for PF. We only
enumerate 0..N VFs as 0..N ethdev port_id
Our intention with this patch is to control the VF from the PF.
The following librte_ether functions already work in a
similar
I have a bad feeling with these functions dedicated to VF from PF.
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the VF is not
visible to
the PF.
quoted
quoted
quoted
I don't think there is another way to do this.
I don't understand why we could not assign a port id to the VF
from the host instead of having the couple PF port id / VF id.
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array rte_eth_devices?
Hi Thomas,
The VF is not a port visible to DPDK, though, so it shouldn't have
a port id IMHO. DPDK can't actually do anything with it.
You say the contrary below.
Well, yes and no. The driver can manipulate things for the VF, but DPDK
doesn't actually have a device that corresponds to the VF. There are no PCI
bar mappings for it, DPDK can't do RX and TX with it etc.?
Very good point.
There are only few ethdev functions which are supported by every drivers,
like Rx/Tx and would not be available for VF from PF interface.
quoted
quoted
quoted
The PCI device for the VF is likely passed through to a different
VM and being used there. Unfortunately, the VF still needs certain
things done for it by the PF, so if the PF is under DPDK control,
it needs to provide the functionality to assist the VF.
Why not have a VF_from_PF driver which does the mailbox things?
So you can manage the VF from the PF with a simple port id.
It really seems to be the cleanest design to me.
While I see your point, and it could work, I just want to be sure that we are
ok with the results of that. Suppose we do create ethdevs for the VFs
controlled by the PF. Does the new VF get counted in the
rte_eth_dev_count() value (I assume yes)? How are apps meant to use the
port? Do they have to put in a special case when iterating through all the port
ids to check that it's not a pseudo port that can't do anything. None of the
standard ethdev calls from an app will work on it, you can't configure nb rx/tx
queues on it, you can't start or stop it, you can't do rx or tx on it, etc, etc.
Yes these devices would be special because their supported API would be
quite different. I was thinking that in the future you could add most of the
configuration functions through the VF mailbox.
But the Intel mailbox currently support only some special configurations
which are not supported by other devices even its own VF device (except
setting MAC address).
And when I read "set drop enable bit in the VF split rx control register", it
becomes clear it is really specific and has nothing to do in the generic ethdev
API.
That's why it is a NACK.
When we want to use these very specific features we are aware of the
underlying device and driver. So we can directly include a header from the
driver. I suggest to retrieve a handler for the device which is not a port id and
will allow to call ixgbe functions directly.
It could be achieved by adding an ethdev function like discussed here:
http://dpdk.org/ml/archives/dev/2016-September/047392.html
I have been reading the net/vhost mail thread above. The following quote is from this thread.
"It means I would be in favor of introducing API in drivers for very specific features."
At present all the PMD functions are accessed through the eth_dev_ops structure, there are no PMD API's.
Is your proposal to add API(s) to the DPDK ixgbe PMD (similar to a driver ioctl API) which can be accessed through a generic API in the ethdev?
What will this generic API look like?
Regards,
Bernard.
From: Thomas Monjalon <hidden> Date: 2016-09-23 17:18:45
2016-09-23 17:02, Iremonger, Bernard:
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 09:53, Richardson, Bruce:
quoted
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 10:20, Bruce Richardson:
quoted
On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
quoted
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
quoted
Do we really need to expose VF specific functions here?
It can be generic(PF/VF) function indexed only through
port_id.
quoted
quoted
quoted
quoted
quoted
quoted
(example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t
port_id, uint8_t on)) For instance, In Thunderx PMD, We
are not exposing a separate port_id for PF. We only
enumerate 0..N VFs as 0..N ethdev port_id
Our intention with this patch is to control the VF from the PF.
The following librte_ether functions already work in a
similar
I have a bad feeling with these functions dedicated to VF from PF.
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the VF is not
visible to
the PF.
quoted
quoted
quoted
I don't think there is another way to do this.
I don't understand why we could not assign a port id to the VF
from the host instead of having the couple PF port id / VF id.
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array rte_eth_devices?
Hi Thomas,
The VF is not a port visible to DPDK, though, so it shouldn't have
a port id IMHO. DPDK can't actually do anything with it.
You say the contrary below.
Well, yes and no. The driver can manipulate things for the VF, but DPDK
doesn't actually have a device that corresponds to the VF. There are no PCI
bar mappings for it, DPDK can't do RX and TX with it etc.?
Very good point.
There are only few ethdev functions which are supported by every drivers,
like Rx/Tx and would not be available for VF from PF interface.
quoted
quoted
quoted
The PCI device for the VF is likely passed through to a different
VM and being used there. Unfortunately, the VF still needs certain
things done for it by the PF, so if the PF is under DPDK control,
it needs to provide the functionality to assist the VF.
Why not have a VF_from_PF driver which does the mailbox things?
So you can manage the VF from the PF with a simple port id.
It really seems to be the cleanest design to me.
While I see your point, and it could work, I just want to be sure that we are
ok with the results of that. Suppose we do create ethdevs for the VFs
controlled by the PF. Does the new VF get counted in the
rte_eth_dev_count() value (I assume yes)? How are apps meant to use the
port? Do they have to put in a special case when iterating through all the port
ids to check that it's not a pseudo port that can't do anything. None of the
standard ethdev calls from an app will work on it, you can't configure nb rx/tx
queues on it, you can't start or stop it, you can't do rx or tx on it, etc, etc.
Yes these devices would be special because their supported API would be
quite different. I was thinking that in the future you could add most of the
configuration functions through the VF mailbox.
But the Intel mailbox currently support only some special configurations
which are not supported by other devices even its own VF device (except
setting MAC address).
And when I read "set drop enable bit in the VF split rx control register", it
becomes clear it is really specific and has nothing to do in the generic ethdev
API.
That's why it is a NACK.
When we want to use these very specific features we are aware of the
underlying device and driver. So we can directly include a header from the
driver. I suggest to retrieve a handler for the device which is not a port id and
will allow to call ixgbe functions directly.
It could be achieved by adding an ethdev function like discussed here:
http://dpdk.org/ml/archives/dev/2016-September/047392.html
I have been reading the net/vhost mail thread above. The following quote is from this thread.
"It means I would be in favor of introducing API in drivers for very specific features."
At present all the PMD functions are accessed through the eth_dev_ops structure, there are no PMD API's.
Is your proposal to add API(s) to the DPDK ixgbe PMD (similar to a driver ioctl API) which can be accessed through a generic API in the ethdev?
Not exactly. I'm thinking about a PMD specific API.
The only ethdev API you need would be a function to retrieve a handler
(an opaque pointer on the device struct) from the port id.
Then you can include rte_ixgbe.h and directly call the specific ixgbe
function, passing the device handler.
How does it sound?
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 09:53, Richardson, Bruce:
quoted
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 10:20, Bruce Richardson:
quoted
On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
quoted
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
quoted
Do we really need to expose VF specific functions here?
It can be generic(PF/VF) function indexed only
through
port_id.
quoted
quoted
quoted
quoted
quoted
quoted
(example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t
port_id, uint8_t on)) For instance, In Thunderx PMD,
We are not exposing a separate port_id for PF. We
only enumerate 0..N VFs as 0..N ethdev port_id
Our intention with this patch is to control the VF from the PF.
The following librte_ether functions already work in a
similar
I have a bad feeling with these functions dedicated to VF from
PF.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the VF is not
visible to
the PF.
quoted
quoted
quoted
I don't think there is another way to do this.
I don't understand why we could not assign a port id to the
VF from the host instead of having the couple PF port id / VF id.
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array rte_eth_devices?
Hi Thomas,
The VF is not a port visible to DPDK, though, so it shouldn't
have a port id IMHO. DPDK can't actually do anything with it.
You say the contrary below.
Well, yes and no. The driver can manipulate things for the VF, but
DPDK
doesn't actually have a device that corresponds to the VF. There are
no PCI bar mappings for it, DPDK can't do RX and TX with it etc.?
Very good point.
There are only few ethdev functions which are supported by every
drivers, like Rx/Tx and would not be available for VF from PF interface.
quoted
quoted
quoted
The PCI device for the VF is likely passed through to a
different VM and being used there. Unfortunately, the VF still
needs certain things done for it by the PF, so if the PF is
under DPDK control, it needs to provide the functionality to assist
the VF.
quoted
quoted
quoted
quoted
Why not have a VF_from_PF driver which does the mailbox things?
So you can manage the VF from the PF with a simple port id.
It really seems to be the cleanest design to me.
While I see your point, and it could work, I just want to be sure
that we are
ok with the results of that. Suppose we do create ethdevs for the
VFs controlled by the PF. Does the new VF get counted in the
rte_eth_dev_count() value (I assume yes)? How are apps meant to use
the port? Do they have to put in a special case when iterating
through all the port ids to check that it's not a pseudo port that
can't do anything. None of the standard ethdev calls from an app
will work on it, you can't configure nb rx/tx queues on it, you can't start or
stop it, you can't do rx or tx on it, etc, etc.
quoted
quoted
Yes these devices would be special because their supported API would
be quite different. I was thinking that in the future you could add
most of the configuration functions through the VF mailbox.
But the Intel mailbox currently support only some special
configurations which are not supported by other devices even its own
VF device (except setting MAC address).
And when I read "set drop enable bit in the VF split rx control
register", it becomes clear it is really specific and has nothing to
do in the generic ethdev API.
That's why it is a NACK.
When we want to use these very specific features we are aware of the
underlying device and driver. So we can directly include a header
from the driver. I suggest to retrieve a handler for the device
which is not a port id and will allow to call ixgbe functions directly.
It could be achieved by adding an ethdev function like discussed here:
http://dpdk.org/ml/archives/dev/2016-September/047392.html
I have been reading the net/vhost mail thread above. The following quote
is from this thread.
quoted
"It means I would be in favor of introducing API in drivers for very specific
features."
quoted
At present all the PMD functions are accessed through the eth_dev_ops
structure, there are no PMD API's.
quoted
Is your proposal to add API(s) to the DPDK ixgbe PMD (similar to a driver
ioctl API) which can be accessed through a generic API in the ethdev?
Not exactly. I'm thinking about a PMD specific API.
The only ethdev API you need would be a function to retrieve a handler (an
opaque pointer on the device struct) from the port id.
Then you can include rte_ixgbe.h and directly call the specific ixgbe function,
passing the device handler.
How does it sound?
I have been prototyping this proposed solution, it appears to work.
I have added the following function:
int rte_eth_dev_get_pmd_handle(uint8_t port_id, void** pmd_handle);
The pmd_handle is a pointer to a dev_ops structure containing driver specific functions.
Using the pmd_handle the driver specific functions can be called (without having them in struct eth_dev_ops)
Has this proposal been superseded by the discussion on the following patch?
[PATCH] net/vhost: Add function to retreive the 'vid' for a given port id
Regards,
Bernard.
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 09:53, Richardson, Bruce:
quoted
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 10:20, Bruce Richardson:
quoted
On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
quoted
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
quoted
Do we really need to expose VF specific functions here?
It can be generic(PF/VF) function indexed only
through
port_id.
quoted
quoted
quoted
quoted
quoted
quoted
(example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t
port_id, uint8_t on)) For instance, In Thunderx PMD,
We are not exposing a separate port_id for PF. We
only enumerate 0..N VFs as 0..N ethdev port_id
Our intention with this patch is to control the VF from the PF.
The following librte_ether functions already work in a
similar
I have a bad feeling with these functions dedicated to VF from
PF.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the VF is not
visible to
the PF.
quoted
quoted
quoted
I don't think there is another way to do this.
I don't understand why we could not assign a port id to the
VF from the host instead of having the couple PF port id / VF id.
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array rte_eth_devices?
Hi Thomas,
The VF is not a port visible to DPDK, though, so it shouldn't
have a port id IMHO. DPDK can't actually do anything with it.
You say the contrary below.
Well, yes and no. The driver can manipulate things for the VF, but
DPDK
doesn't actually have a device that corresponds to the VF. There are
no PCI bar mappings for it, DPDK can't do RX and TX with it etc.?
Very good point.
There are only few ethdev functions which are supported by every
drivers, like Rx/Tx and would not be available for VF from PF interface.
quoted
quoted
quoted
The PCI device for the VF is likely passed through to a
different VM and being used there. Unfortunately, the VF still
needs certain things done for it by the PF, so if the PF is
under DPDK control, it needs to provide the functionality to assist
the VF.
quoted
quoted
quoted
quoted
Why not have a VF_from_PF driver which does the mailbox things?
So you can manage the VF from the PF with a simple port id.
It really seems to be the cleanest design to me.
While I see your point, and it could work, I just want to be sure
that we are
ok with the results of that. Suppose we do create ethdevs for the
VFs controlled by the PF. Does the new VF get counted in the
rte_eth_dev_count() value (I assume yes)? How are apps meant to use
the port? Do they have to put in a special case when iterating
through all the port ids to check that it's not a pseudo port that
can't do anything. None of the standard ethdev calls from an app
will work on it, you can't configure nb rx/tx queues on it, you can't start or
stop it, you can't do rx or tx on it, etc, etc.
quoted
quoted
Yes these devices would be special because their supported API would
be quite different. I was thinking that in the future you could add
most of the configuration functions through the VF mailbox.
But the Intel mailbox currently support only some special
configurations which are not supported by other devices even its own
VF device (except setting MAC address).
And when I read "set drop enable bit in the VF split rx control
register", it becomes clear it is really specific and has nothing to
do in the generic ethdev API.
That's why it is a NACK.
When we want to use these very specific features we are aware of the
underlying device and driver. So we can directly include a header
from the driver. I suggest to retrieve a handler for the device
which is not a port id and will allow to call ixgbe functions directly.
It could be achieved by adding an ethdev function like discussed here:
http://dpdk.org/ml/archives/dev/2016-September/047392.html
I have been reading the net/vhost mail thread above. The following quote
is from this thread.
quoted
"It means I would be in favor of introducing API in drivers for very specific
features."
quoted
At present all the PMD functions are accessed through the eth_dev_ops
structure, there are no PMD API's.
quoted
Is your proposal to add API(s) to the DPDK ixgbe PMD (similar to a driver
ioctl API) which can be accessed through a generic API in the ethdev?
Not exactly. I'm thinking about a PMD specific API.
The only ethdev API you need would be a function to retrieve a handler (an
opaque pointer on the device struct) from the port id.
Then you can include rte_ixgbe.h and directly call the specific ixgbe function,
passing the device handler.
How does it sound?
I have been prototyping this proposed solution, it appears to work.
I have added the following function:
int rte_eth_dev_get_pmd_handle(uint8_t port_id, void** pmd_handle);
The pmd_handle is a pointer to a dev_ops structure containing driver specific functions.
Using the pmd_handle the driver specific functions can be called (without having them in struct eth_dev_ops)
Has this proposal been superseded by the discussion on the following patch?
[PATCH] net/vhost: Add function to retreive the 'vid' for a given port id
Maybe, it can be superseded by this discussion, yes.
Bruce thinks we do not need rte_eth_dev_get_pmd_handle().
What is your opinion about using port_id directly and retrieving the
structs from the driver via rte_eth_devices?
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 09:53, Richardson, Bruce:
quoted
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 10:20, Bruce Richardson:
quoted
On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon
wrote:
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
quoted
Do we really need to expose VF specific functions
here?
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
It can be generic(PF/VF) function indexed only
through
port_id.
quoted
quoted
quoted
quoted
quoted
quoted
(example: as
rte_eth_dev_set_vlan_anti_spoof(uint8_t
port_id, uint8_t on)) For instance, In Thunderx
PMD, We are not exposing a separate port_id for
PF. We only enumerate 0..N VFs as 0..N ethdev
port_id
Our intention with this patch is to control the VF from the
PF.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
The following librte_ether functions already work
in a similar
I have a bad feeling with these functions dedicated
to VF from
PF.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the VF is
not visible to
the PF.
quoted
quoted
quoted
I don't think there is another way to do this.
I don't understand why we could not assign a port id to
the VF from the host instead of having the couple PF port id /
VF id.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array
rte_eth_devices?
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Hi Thomas,
The VF is not a port visible to DPDK, though, so it
shouldn't have a port id IMHO. DPDK can't actually do anything
with it.
quoted
quoted
quoted
quoted
quoted
quoted
You say the contrary below.
Well, yes and no. The driver can manipulate things for the VF,
but DPDK
doesn't actually have a device that corresponds to the VF. There
are no PCI bar mappings for it, DPDK can't do RX and TX with it etc.?
Very good point.
There are only few ethdev functions which are supported by every
drivers, like Rx/Tx and would not be available for VF from PF
interface.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
The PCI device for the VF is likely passed through to a
different VM and being used there. Unfortunately, the VF
still needs certain things done for it by the PF, so if
the PF is under DPDK control, it needs to provide the
functionality to assist
the VF.
quoted
quoted
quoted
quoted
Why not have a VF_from_PF driver which does the mailbox
things?
quoted
quoted
quoted
quoted
quoted
quoted
So you can manage the VF from the PF with a simple port id.
It really seems to be the cleanest design to me.
While I see your point, and it could work, I just want to be
sure that we are
ok with the results of that. Suppose we do create ethdevs for
the VFs controlled by the PF. Does the new VF get counted in the
rte_eth_dev_count() value (I assume yes)? How are apps meant to
use the port? Do they have to put in a special case when
iterating through all the port ids to check that it's not a
pseudo port that can't do anything. None of the standard ethdev
calls from an app will work on it, you can't configure nb rx/tx
queues on it, you can't start or
stop it, you can't do rx or tx on it, etc, etc.
quoted
quoted
Yes these devices would be special because their supported API
would be quite different. I was thinking that in the future you
could add most of the configuration functions through the VF
mailbox.
quoted
quoted
quoted
quoted
But the Intel mailbox currently support only some special
configurations which are not supported by other devices even its
own VF device (except setting MAC address).
And when I read "set drop enable bit in the VF split rx control
register", it becomes clear it is really specific and has
nothing to do in the generic ethdev API.
That's why it is a NACK.
When we want to use these very specific features we are aware of
the underlying device and driver. So we can directly include a
header from the driver. I suggest to retrieve a handler for the
device which is not a port id and will allow to call ixgbe functions
I have been reading the net/vhost mail thread above. The following
quote
is from this thread.
quoted
"It means I would be in favor of introducing API in drivers for
very specific
features."
quoted
At present all the PMD functions are accessed through the
eth_dev_ops
structure, there are no PMD API's.
quoted
Is your proposal to add API(s) to the DPDK ixgbe PMD (similar to a
driver
ioctl API) which can be accessed through a generic API in the ethdev?
Not exactly. I'm thinking about a PMD specific API.
The only ethdev API you need would be a function to retrieve a
handler (an opaque pointer on the device struct) from the port id.
Then you can include rte_ixgbe.h and directly call the specific
ixgbe function, passing the device handler.
How does it sound?
I have been prototyping this proposed solution, it appears to work.
I have added the following function:
int rte_eth_dev_get_pmd_handle(uint8_t port_id, void** pmd_handle);
The pmd_handle is a pointer to a dev_ops structure containing driver
specific functions.
quoted
Using the pmd_handle the driver specific functions can be called
(without having them in struct eth_dev_ops)
Has this proposal been superseded by the discussion on the following
patch?
quoted
[PATCH] net/vhost: Add function to retreive the 'vid' for a given port
id
Maybe, it can be superseded by this discussion, yes.
Bruce thinks we do not need rte_eth_dev_get_pmd_handle().
What is your opinion about using port_id directly and retrieving the structs
from the driver via rte_eth_devices?
Looking at the code in rte_eth_devices[]
struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
struct rte_eth_dev {
...
const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
...
void *pmd_ops; /** < exported PMD specific functions */
}
The PMD functions are only accessible at present if they are in struct eth_dev_ops.
Adding a pmd_ops field to struct rte_eth_dev {} makes the PMD functions accessible and is a simpler solution than using rte_eth_dev_get_pmd_handle() to get access to the PMD functions.
Regards,
Bernard.
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 09:53, Richardson, Bruce:
quoted
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 10:20, Bruce Richardson:
quoted
On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon
wrote:
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
quoted
Do we really need to expose VF specific functions
here?
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
It can be generic(PF/VF) function indexed only
through
port_id.
quoted
quoted
quoted
quoted
quoted
quoted
(example: as
rte_eth_dev_set_vlan_anti_spoof(uint8_t
port_id, uint8_t on)) For instance, In Thunderx
PMD, We are not exposing a separate port_id for
PF. We only enumerate 0..N VFs as 0..N ethdev
port_id
Our intention with this patch is to control the VF from the
PF.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
The following librte_ether functions already work
in a similar
I have a bad feeling with these functions dedicated
to VF from
PF.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the VF is
not visible to
the PF.
quoted
quoted
quoted
I don't think there is another way to do this.
I don't understand why we could not assign a port id to
the VF from the host instead of having the couple PF port id /
VF id.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array
rte_eth_devices?
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Hi Thomas,
The VF is not a port visible to DPDK, though, so it
shouldn't have a port id IMHO. DPDK can't actually do anything
with it.
quoted
quoted
quoted
quoted
quoted
quoted
You say the contrary below.
Well, yes and no. The driver can manipulate things for the VF,
but DPDK
doesn't actually have a device that corresponds to the VF. There
are no PCI bar mappings for it, DPDK can't do RX and TX with it etc.?
Very good point.
There are only few ethdev functions which are supported by every
drivers, like Rx/Tx and would not be available for VF from PF
interface.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
The PCI device for the VF is likely passed through to a
different VM and being used there. Unfortunately, the VF
still needs certain things done for it by the PF, so if
the PF is under DPDK control, it needs to provide the
functionality to assist
the VF.
quoted
quoted
quoted
quoted
Why not have a VF_from_PF driver which does the mailbox
things?
quoted
quoted
quoted
quoted
quoted
quoted
So you can manage the VF from the PF with a simple port id.
It really seems to be the cleanest design to me.
While I see your point, and it could work, I just want to be
sure that we are
ok with the results of that. Suppose we do create ethdevs for
the VFs controlled by the PF. Does the new VF get counted in the
rte_eth_dev_count() value (I assume yes)? How are apps meant to
use the port? Do they have to put in a special case when
iterating through all the port ids to check that it's not a
pseudo port that can't do anything. None of the standard ethdev
calls from an app will work on it, you can't configure nb rx/tx
queues on it, you can't start or
stop it, you can't do rx or tx on it, etc, etc.
quoted
quoted
Yes these devices would be special because their supported API
would be quite different. I was thinking that in the future you
could add most of the configuration functions through the VF
mailbox.
quoted
quoted
quoted
quoted
But the Intel mailbox currently support only some special
configurations which are not supported by other devices even its
own VF device (except setting MAC address).
And when I read "set drop enable bit in the VF split rx control
register", it becomes clear it is really specific and has
nothing to do in the generic ethdev API.
That's why it is a NACK.
When we want to use these very specific features we are aware of
the underlying device and driver. So we can directly include a
header from the driver. I suggest to retrieve a handler for the
device which is not a port id and will allow to call ixgbe functions
I have been reading the net/vhost mail thread above. The following
quote
is from this thread.
quoted
"It means I would be in favor of introducing API in drivers for
very specific
features."
quoted
At present all the PMD functions are accessed through the
eth_dev_ops
structure, there are no PMD API's.
quoted
Is your proposal to add API(s) to the DPDK ixgbe PMD (similar to a
driver
ioctl API) which can be accessed through a generic API in the ethdev?
Not exactly. I'm thinking about a PMD specific API.
The only ethdev API you need would be a function to retrieve a
handler (an opaque pointer on the device struct) from the port id.
Then you can include rte_ixgbe.h and directly call the specific
ixgbe function, passing the device handler.
How does it sound?
I have been prototyping this proposed solution, it appears to work.
I have added the following function:
int rte_eth_dev_get_pmd_handle(uint8_t port_id, void** pmd_handle);
The pmd_handle is a pointer to a dev_ops structure containing driver
specific functions.
quoted
Using the pmd_handle the driver specific functions can be called
(without having them in struct eth_dev_ops)
Has this proposal been superseded by the discussion on the following
patch?
quoted
[PATCH] net/vhost: Add function to retreive the 'vid' for a given port
id
Maybe, it can be superseded by this discussion, yes.
Bruce thinks we do not need rte_eth_dev_get_pmd_handle().
What is your opinion about using port_id directly and retrieving the structs
from the driver via rte_eth_devices?
Looking at the code in rte_eth_devices[]
struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
struct rte_eth_dev {
...
const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
...
void *pmd_ops; /** < exported PMD specific functions */
}
The PMD functions are only accessible at present if they are in struct eth_dev_ops.
Adding a pmd_ops field to struct rte_eth_dev {} makes the PMD functions accessible and is a simpler solution than using rte_eth_dev_get_pmd_handle() to get access to the PMD functions.
Regards,
Why would an ops structure be needed? If it's a private API for a driver, there
should be no need for function pointers, and instead the driver can define
regular functions in it's header file, no?
/Bruce
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 09:53, Richardson, Bruce:
quoted
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 10:20, Bruce Richardson:
quoted
On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas
Monjalon
wrote:
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
quoted
Do we really need to expose VF specific
functions
here?
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
It can be generic(PF/VF) function indexed
only through
port_id.
quoted
quoted
quoted
quoted
quoted
quoted
(example: as
rte_eth_dev_set_vlan_anti_spoof(uint8_t
port_id, uint8_t on)) For instance, In
Thunderx PMD, We are not exposing a separate
port_id for PF. We only enumerate 0..N VFs
as 0..N ethdev port_id
Our intention with this patch is to control
the VF from the
PF.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
The following librte_ether functions already
work in a similar
I have a bad feeling with these functions
dedicated to VF from
PF.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the VF
is not visible to
the PF.
quoted
quoted
quoted
I don't think there is another way to do this.
I don't understand why we could not assign a port id
to the VF from the host instead of having the couple
PF port id /
VF id.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array
rte_eth_devices?
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Hi Thomas,
The VF is not a port visible to DPDK, though, so it
shouldn't have a port id IMHO. DPDK can't actually do
anything
with it.
quoted
quoted
quoted
quoted
quoted
quoted
You say the contrary below.
Well, yes and no. The driver can manipulate things for the
VF, but DPDK
doesn't actually have a device that corresponds to the VF.
There are no PCI bar mappings for it, DPDK can't do RX and TX with
it etc.?
quoted
quoted
quoted
quoted
quoted
quoted
Very good point.
There are only few ethdev functions which are supported by
every drivers, like Rx/Tx and would not be available for VF
from PF
interface.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
The PCI device for the VF is likely passed through to
a different VM and being used there. Unfortunately,
the VF still needs certain things done for it by the
PF, so if the PF is under DPDK control, it needs to
provide the functionality to assist
the VF.
quoted
quoted
quoted
quoted
Why not have a VF_from_PF driver which does the mailbox
things?
quoted
quoted
quoted
quoted
quoted
quoted
So you can manage the VF from the PF with a simple port id.
It really seems to be the cleanest design to me.
While I see your point, and it could work, I just want to
be sure that we are
ok with the results of that. Suppose we do create ethdevs
for the VFs controlled by the PF. Does the new VF get
counted in the
rte_eth_dev_count() value (I assume yes)? How are apps meant
to use the port? Do they have to put in a special case when
iterating through all the port ids to check that it's not a
pseudo port that can't do anything. None of the standard
ethdev calls from an app will work on it, you can't
configure nb rx/tx queues on it, you can't start or
stop it, you can't do rx or tx on it, etc, etc.
quoted
quoted
Yes these devices would be special because their supported
API would be quite different. I was thinking that in the
future you could add most of the configuration functions
through the VF
mailbox.
quoted
quoted
quoted
quoted
But the Intel mailbox currently support only some special
configurations which are not supported by other devices even
its own VF device (except setting MAC address).
And when I read "set drop enable bit in the VF split rx
control register", it becomes clear it is really specific
and has nothing to do in the generic ethdev API.
That's why it is a NACK.
When we want to use these very specific features we are
aware of the underlying device and driver. So we can
directly include a header from the driver. I suggest to
retrieve a handler for the device which is not a port id and
will allow to call ixgbe functions
directly.
quoted
quoted
quoted
quoted
It could be achieved by adding an ethdev function like discussed
I have been reading the net/vhost mail thread above. The
following quote
is from this thread.
quoted
"It means I would be in favor of introducing API in drivers
for very specific
features."
quoted
At present all the PMD functions are accessed through the
eth_dev_ops
structure, there are no PMD API's.
quoted
Is your proposal to add API(s) to the DPDK ixgbe PMD (similar
to a driver
ioctl API) which can be accessed through a generic API in the ethdev?
Not exactly. I'm thinking about a PMD specific API.
The only ethdev API you need would be a function to retrieve a
handler (an opaque pointer on the device struct) from the port id.
Then you can include rte_ixgbe.h and directly call the specific
ixgbe function, passing the device handler.
How does it sound?
I have been prototyping this proposed solution, it appears to work.
I have added the following function:
int rte_eth_dev_get_pmd_handle(uint8_t port_id, void**
pmd_handle);
The pmd_handle is a pointer to a dev_ops structure containing
driver
specific functions.
quoted
Using the pmd_handle the driver specific functions can be called
(without having them in struct eth_dev_ops)
Has this proposal been superseded by the discussion on the
following
patch?
quoted
[PATCH] net/vhost: Add function to retreive the 'vid' for a given
port id
Maybe, it can be superseded by this discussion, yes.
Bruce thinks we do not need rte_eth_dev_get_pmd_handle().
What is your opinion about using port_id directly and retrieving the
structs from the driver via rte_eth_devices?
Looking at the code in rte_eth_devices[]
struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
struct rte_eth_dev {
...
const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
...
void *pmd_ops; /** < exported PMD specific functions */
}
The PMD functions are only accessible at present if they are in struct
eth_dev_ops.
quoted
Adding a pmd_ops field to struct rte_eth_dev {} makes the PMD functions
accessible and is a simpler solution than using
rte_eth_dev_get_pmd_handle() to get access to the PMD functions.
quoted
Regards,
Why would an ops structure be needed? If it's a private API for a driver,
there should be no need for function pointers, and instead the driver can
define regular functions in it's header file, no?
/Bruce
The driver functions were static, I have made them public and added them to the rte_pmd_ixgbe.h file, and it works. These functions will also need to be added to the rte_pmd_ixgbe_version.map file, previously there were no public functions.
Regards,
Bernard.
From: Ananyev, Konstantin <hidden> Date: 2016-09-28 11:23:42
Hi lads,
-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Iremonger, Bernard
Sent: Tuesday, September 27, 2016 3:13 PM
To: Richardson, Bruce <redacted>
Cc: Thomas Monjalon <redacted>; dev@dpdk.org; Jerin Jacob <redacted>; Shah, Rahul
R [off-list ref]; Lu, Wenzhuo [off-list ref]; azelezniak [off-list ref]
Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF management
Hi Bruce,
<snip>
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 09:53, Richardson, Bruce:
quoted
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 10:20, Bruce Richardson:
quoted
On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas
Monjalon
wrote:
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
quoted
Do we really need to expose VF specific
functions
here?
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
It can be generic(PF/VF) function indexed
only through
port_id.
quoted
quoted
quoted
quoted
quoted
quoted
(example: as
rte_eth_dev_set_vlan_anti_spoof(uint8_t
port_id, uint8_t on)) For instance, In
Thunderx PMD, We are not exposing a
separate port_id for PF. We only enumerate
0..N VFs as 0..N ethdev port_id
Our intention with this patch is to control
the VF from the
PF.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
The following librte_ether functions already
work in a similar
I have a bad feeling with these functions
dedicated to VF from
PF.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the
VF is not visible to
the PF.
quoted
quoted
quoted
I don't think there is another way to do this.
I don't understand why we could not assign a port
id to the VF from the host instead of having the
couple PF port id /
VF id.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array
rte_eth_devices?
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Hi Thomas,
The VF is not a port visible to DPDK, though, so it
shouldn't have a port id IMHO. DPDK can't actually
do anything
with it.
quoted
quoted
quoted
quoted
quoted
quoted
You say the contrary below.
Well, yes and no. The driver can manipulate things for
the VF, but DPDK
doesn't actually have a device that corresponds to the VF.
There are no PCI bar mappings for it, DPDK can't do RX and
TX with
it etc.?
quoted
quoted
quoted
quoted
quoted
quoted
Very good point.
There are only few ethdev functions which are supported by
every drivers, like Rx/Tx and would not be available for
VF from PF
interface.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
The PCI device for the VF is likely passed through
to a different VM and being used there.
Unfortunately, the VF still needs certain things
done for it by the PF, so if the PF is under DPDK
control, it needs to provide the functionality to
assist
the VF.
quoted
quoted
quoted
quoted
Why not have a VF_from_PF driver which does the
mailbox
things?
quoted
quoted
quoted
quoted
quoted
quoted
So you can manage the VF from the PF with a simple port id.
It really seems to be the cleanest design to me.
While I see your point, and it could work, I just want
to be sure that we are
ok with the results of that. Suppose we do create ethdevs
for the VFs controlled by the PF. Does the new VF get
counted in the
rte_eth_dev_count() value (I assume yes)? How are apps
meant to use the port? Do they have to put in a special
case when iterating through all the port ids to check that
it's not a pseudo port that can't do anything. None of the
standard ethdev calls from an app will work on it, you
can't configure nb rx/tx queues on it, you can't start or
stop it, you can't do rx or tx on it, etc, etc.
quoted
quoted
Yes these devices would be special because their supported
API would be quite different. I was thinking that in the
future you could add most of the configuration functions
through the VF
mailbox.
quoted
quoted
quoted
quoted
But the Intel mailbox currently support only some special
configurations which are not supported by other devices
even its own VF device (except setting MAC address).
And when I read "set drop enable bit in the VF split rx
control register", it becomes clear it is really specific
and has nothing to do in the generic ethdev API.
That's why it is a NACK.
When we want to use these very specific features we are
aware of the underlying device and driver. So we can
directly include a header from the driver. I suggest to
retrieve a handler for the device which is not a port id
and will allow to call ixgbe functions
directly.
quoted
quoted
quoted
quoted
It could be achieved by adding an ethdev function like
discussed
I have been reading the net/vhost mail thread above. The
following quote
is from this thread.
quoted
"It means I would be in favor of introducing API in drivers
for very specific
features."
quoted
At present all the PMD functions are accessed through the
eth_dev_ops
structure, there are no PMD API's.
quoted
Is your proposal to add API(s) to the DPDK ixgbe PMD
(similar to a driver
ioctl API) which can be accessed through a generic API in the ethdev?
Not exactly. I'm thinking about a PMD specific API.
The only ethdev API you need would be a function to retrieve a
handler (an opaque pointer on the device struct) from the port id.
Then you can include rte_ixgbe.h and directly call the
specific ixgbe function, passing the device handler.
How does it sound?
I have been prototyping this proposed solution, it appears to work.
I have added the following function:
int rte_eth_dev_get_pmd_handle(uint8_t port_id, void**
pmd_handle);
The pmd_handle is a pointer to a dev_ops structure containing
driver
specific functions.
quoted
Using the pmd_handle the driver specific functions can be called
(without having them in struct eth_dev_ops)
Has this proposal been superseded by the discussion on the
following
patch?
quoted
[PATCH] net/vhost: Add function to retreive the 'vid' for a
given port id
Maybe, it can be superseded by this discussion, yes.
Bruce thinks we do not need rte_eth_dev_get_pmd_handle().
What is your opinion about using port_id directly and retrieving
the structs from the driver via rte_eth_devices?
Looking at the code in rte_eth_devices[]
struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
struct rte_eth_dev {
...
const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
...
void *pmd_ops; /** < exported PMD specific functions */
}
The PMD functions are only accessible at present if they are in
struct
eth_dev_ops.
quoted
Adding a pmd_ops field to struct rte_eth_dev {} makes the PMD
functions
accessible and is a simpler solution than using
rte_eth_dev_get_pmd_handle() to get access to the PMD functions.
quoted
Regards,
Why would an ops structure be needed? If it's a private API for a
driver, there should be no need for function pointers, and instead the
driver can define regular functions in it's header file, no?
/Bruce
The driver functions were static, I have made them public and added them to the rte_pmd_ixgbe.h file, and it works. These functions
will also need to be added to the rte_pmd_ixgbe_version.map file, previously there were no public functions.
Sorry for being late in the discussion, but I have a question:
If we this way (force user to include driver specific headers and call driver specific functions),
how you guys plan to make this functionality available for multiple driver types.
From discussion with Bernard understand that customers would need similar functionality for i40e.
Does it mean that they'll have to re-implement this part of their code again?
Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
Basically their own version of rte_ethdev?
Konstantin
From: Iremonger, Bernard <hidden> Date: 2016-09-28 12:31:54
Hi Bruce, Konstantin,
<snip>
Subject: RE: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
management
Hi lads,
quoted
-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Iremonger,
Bernard
Sent: Tuesday, September 27, 2016 3:13 PM
To: Richardson, Bruce <redacted>
Cc: Thomas Monjalon <redacted>; dev@dpdk.org;
Jerin
quoted
Jacob [off-list ref]; Shah, Rahul R
[off-list ref]; Lu, Wenzhuo [off-list ref];
azelezniak [off-list ref]
Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for
VF management
Hi Bruce,
<snip>
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 09:53, Richardson, Bruce:
quoted
From: Thomas Monjalon
[mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 10:20, Bruce Richardson:
quoted
On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas
Monjalon
wrote:
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
quoted
Do we really need to expose VF specific
functions
here?
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
It can be generic(PF/VF) function
indexed only through
port_id.
quoted
quoted
quoted
quoted
quoted
quoted
(example: as
rte_eth_dev_set_vlan_anti_spoof(uint8_t
port_id, uint8_t on)) For instance, In
Thunderx PMD, We are not exposing a
separate port_id for PF. We only
enumerate 0..N VFs as 0..N ethdev
port_id
Our intention with this patch is to
control the VF from the
PF.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
The following librte_ether functions
already work in a similar
I have a bad feeling with these functions
dedicated to VF from
PF.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.
When the VF is used in a VM the port ID of the
VF is not visible to
the PF.
quoted
quoted
quoted
I don't think there is another way to do this.
I don't understand why we could not assign a
port id to the VF from the host instead of
having the couple PF port id /
VF id.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array
rte_eth_devices?
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Hi Thomas,
The VF is not a port visible to DPDK, though, so
it shouldn't have a port id IMHO. DPDK can't
actually do anything
with it.
quoted
quoted
quoted
quoted
quoted
quoted
You say the contrary below.
Well, yes and no. The driver can manipulate things for
the VF, but DPDK
doesn't actually have a device that corresponds to the VF.
There are no PCI bar mappings for it, DPDK can't do RX
and TX with
it etc.?
quoted
quoted
quoted
quoted
quoted
quoted
Very good point.
There are only few ethdev functions which are supported
by every drivers, like Rx/Tx and would not be available
for VF from PF
interface.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
The PCI device for the VF is likely passed through
to a different VM and being used there.
Unfortunately, the VF still needs certain things
done for it by the PF, so if the PF is under DPDK
control, it needs to provide the functionality to
assist
the VF.
quoted
quoted
quoted
quoted
Why not have a VF_from_PF driver which does the
mailbox
things?
quoted
quoted
quoted
quoted
quoted
quoted
So you can manage the VF from the PF with a simple port
id.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
It really seems to be the cleanest design to me.
While I see your point, and it could work, I just want
to be sure that we are
ok with the results of that. Suppose we do create
ethdevs for the VFs controlled by the PF. Does the new
VF get counted in the
rte_eth_dev_count() value (I assume yes)? How are apps
meant to use the port? Do they have to put in a special
case when iterating through all the port ids to check
that it's not a pseudo port that can't do anything. None
of the standard ethdev calls from an app will work on
it, you can't configure nb rx/tx queues on it, you can't
start or
stop it, you can't do rx or tx on it, etc, etc.
quoted
quoted
Yes these devices would be special because their
supported API would be quite different. I was thinking
that in the future you could add most of the
configuration functions through the VF
mailbox.
quoted
quoted
quoted
quoted
But the Intel mailbox currently support only some
special configurations which are not supported by other
devices even its own VF device (except setting MAC address).
And when I read "set drop enable bit in the VF split rx
control register", it becomes clear it is really
specific and has nothing to do in the generic ethdev API.
That's why it is a NACK.
When we want to use these very specific features we are
aware of the underlying device and driver. So we can
directly include a header from the driver. I suggest to
retrieve a handler for the device which is not a port id
and will allow to call ixgbe functions
directly.
quoted
quoted
quoted
quoted
It could be achieved by adding an ethdev function like
discussed
I have been reading the net/vhost mail thread above. The
following quote
is from this thread.
quoted
"It means I would be in favor of introducing API in
drivers for very specific
features."
quoted
At present all the PMD functions are accessed through the
eth_dev_ops
structure, there are no PMD API's.
quoted
Is your proposal to add API(s) to the DPDK ixgbe PMD
(similar to a driver
ioctl API) which can be accessed through a generic API in the
ethdev?
quoted
quoted
quoted
quoted
quoted
quoted
Not exactly. I'm thinking about a PMD specific API.
The only ethdev API you need would be a function to retrieve
a handler (an opaque pointer on the device struct) from the port
id.
quoted
quoted
quoted
quoted
quoted
quoted
Then you can include rte_ixgbe.h and directly call the
specific ixgbe function, passing the device handler.
How does it sound?
I have been prototyping this proposed solution, it appears to work.
I have added the following function:
int rte_eth_dev_get_pmd_handle(uint8_t port_id, void**
pmd_handle);
The pmd_handle is a pointer to a dev_ops structure containing
driver
specific functions.
quoted
Using the pmd_handle the driver specific functions can be
called (without having them in struct eth_dev_ops)
Has this proposal been superseded by the discussion on the
following
patch?
quoted
[PATCH] net/vhost: Add function to retreive the 'vid' for a
given port id
Maybe, it can be superseded by this discussion, yes.
Bruce thinks we do not need rte_eth_dev_get_pmd_handle().
What is your opinion about using port_id directly and retrieving
the structs from the driver via rte_eth_devices?
Looking at the code in rte_eth_devices[]
struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
struct rte_eth_dev {
...
const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD
*/
...
void *pmd_ops; /** < exported PMD specific functions */
}
The PMD functions are only accessible at present if they are in
struct
eth_dev_ops.
quoted
Adding a pmd_ops field to struct rte_eth_dev {} makes the PMD
functions
accessible and is a simpler solution than using
rte_eth_dev_get_pmd_handle() to get access to the PMD functions.
quoted
Regards,
Why would an ops structure be needed? If it's a private API for a
driver, there should be no need for function pointers, and instead
the driver can define regular functions in it's header file, no?
/Bruce
The driver functions were static, I have made them public and added
them to the rte_pmd_ixgbe.h file, and it works. These functions will also
need to be added to the rte_pmd_ixgbe_version.map file, previously there
were no public functions.
Sorry for being late in the discussion, but I have a question:
If we this way (force user to include driver specific headers and call driver
specific functions), how you guys plan to make this functionality available for
multiple driver types.
From discussion with Bernard understand that customers would need similar
functionality for i40e.
Does it mean that they'll have to re-implement this part of their code again?
Or would have to create (and maintain) their own shim layer that would
provide some s of abstraction?
Basically their own version of rte_ethdev?
Konstantin
Adding the pmd_ops field to struct eth_devops {} discussed previously in this email thread will allow driver specific functions for multiple drivers and will get rid of the driver specific header file rte_pmd_driver.h.
Regards,
Bernard.
From: Richardson, Bruce <hidden> Date: 2016-09-28 13:01:08
-----Original Message-----
From: Ananyev, Konstantin
Sent: Wednesday, September 28, 2016 12:24 PM
To: Iremonger, Bernard <redacted>; Richardson, Bruce
[off-list ref]
Cc: Thomas Monjalon <redacted>; dev@dpdk.org; Jerin Jacob
[off-list ref]; Shah, Rahul R [off-list ref];
Lu, Wenzhuo [off-list ref]; azelezniak [off-list ref]
Subject: RE: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
management
Hi lads,
quoted
-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Iremonger,
Bernard
Sent: Tuesday, September 27, 2016 3:13 PM
To: Richardson, Bruce <redacted>
Cc: Thomas Monjalon <redacted>; dev@dpdk.org; Jerin
Jacob [off-list ref]; Shah, Rahul R
[off-list ref]; Lu, Wenzhuo [off-list ref];
azelezniak [off-list ref]
Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for
VF management
Hi Bruce,
<snip>
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 09:53, Richardson, Bruce:
quoted
From: Thomas Monjalon
[mailto:thomas.monjalon@6wind.com]
quoted
2016-09-23 10:20, Bruce Richardson:
quoted
On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas
Monjalon
wrote:
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
2016-09-15 16:46, Iremonger, Bernard:
quoted
quoted
quoted
quoted
Do we really need to expose VF specific
functions
here?
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
It can be generic(PF/VF) function
indexed only through
port_id.
quoted
quoted
quoted
quoted
quoted
quoted
(example: as
rte_eth_dev_set_vlan_anti_spoof(uint8_t
port_id, uint8_t on)) For instance, In
Thunderx PMD, We are not exposing a
separate port_id for PF. We only
enumerate 0..N VFs as 0..N ethdev
port_id
Our intention with this patch is to
control the VF from the
PF.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
The following librte_ether functions
already work in a similar
I have a bad feeling with these functions
dedicated to VF from
PF.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Are we sure there is no other way?
I mean we just need to know the VF with a port
ID.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
When the VF is used in a VM the port ID of the
VF is not visible to
the PF.
quoted
quoted
quoted
I don't think there is another way to do this.
I don't understand why we could not assign a
port id to the VF from the host instead of
having the couple PF port id /
VF id.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array
rte_eth_devices?
quoted
quoted
quoted
quoted
quoted
quoted
quoted
Hi Thomas,
The VF is not a port visible to DPDK, though, so
it shouldn't have a port id IMHO. DPDK can't
actually do anything
with it.
quoted
quoted
quoted
quoted
quoted
quoted
You say the contrary below.
Well, yes and no. The driver can manipulate things for
the VF, but DPDK
doesn't actually have a device that corresponds to the VF.
There are no PCI bar mappings for it, DPDK can't do RX
and TX with
it etc.?
quoted
quoted
quoted
quoted
quoted
quoted
Very good point.
There are only few ethdev functions which are supported
by every drivers, like Rx/Tx and would not be available
for VF from PF
interface.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
The PCI device for the VF is likely passed through
to a different VM and being used there.
Unfortunately, the VF still needs certain things
done for it by the PF, so if the PF is under DPDK
control, it needs to provide the functionality to
assist
the VF.
quoted
quoted
quoted
quoted
Why not have a VF_from_PF driver which does the
mailbox
things?
quoted
quoted
quoted
quoted
quoted
quoted
So you can manage the VF from the PF with a simple
port id.
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
It really seems to be the cleanest design to me.
While I see your point, and it could work, I just want
to be sure that we are
ok with the results of that. Suppose we do create
ethdevs for the VFs controlled by the PF. Does the new
VF get counted in the
rte_eth_dev_count() value (I assume yes)? How are apps
meant to use the port? Do they have to put in a special
case when iterating through all the port ids to check
that it's not a pseudo port that can't do anything. None
of the standard ethdev calls from an app will work on
it, you can't configure nb rx/tx queues on it, you can't
start or
stop it, you can't do rx or tx on it, etc, etc.
quoted
quoted
Yes these devices would be special because their
supported API would be quite different. I was thinking
that in the future you could add most of the
configuration functions through the VF
mailbox.
quoted
quoted
quoted
quoted
But the Intel mailbox currently support only some
special configurations which are not supported by other
devices even its own VF device (except setting MAC
address).
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
And when I read "set drop enable bit in the VF split rx
control register", it becomes clear it is really
specific and has nothing to do in the generic ethdev API.
That's why it is a NACK.
When we want to use these very specific features we are
aware of the underlying device and driver. So we can
directly include a header from the driver. I suggest to
retrieve a handler for the device which is not a port id
and will allow to call ixgbe functions
directly.
quoted
quoted
quoted
quoted
It could be achieved by adding an ethdev function like
discussed
I have been reading the net/vhost mail thread above. The
following quote
is from this thread.
quoted
"It means I would be in favor of introducing API in
drivers for very specific
features."
quoted
At present all the PMD functions are accessed through the
eth_dev_ops
structure, there are no PMD API's.
quoted
Is your proposal to add API(s) to the DPDK ixgbe PMD
(similar to a driver
ioctl API) which can be accessed through a generic API in the
ethdev?
quoted
quoted
quoted
quoted
quoted
quoted
Not exactly. I'm thinking about a PMD specific API.
The only ethdev API you need would be a function to retrieve
a handler (an opaque pointer on the device struct) from the
port id.
quoted
quoted
quoted
quoted
quoted
quoted
Then you can include rte_ixgbe.h and directly call the
specific ixgbe function, passing the device handler.
How does it sound?
I have been prototyping this proposed solution, it appears to
work.
quoted
quoted
quoted
quoted
quoted
I have added the following function:
int rte_eth_dev_get_pmd_handle(uint8_t port_id, void**
pmd_handle);
The pmd_handle is a pointer to a dev_ops structure containing
driver
specific functions.
quoted
Using the pmd_handle the driver specific functions can be
called (without having them in struct eth_dev_ops)
Has this proposal been superseded by the discussion on the
following
patch?
quoted
[PATCH] net/vhost: Add function to retreive the 'vid' for a
given port id
Maybe, it can be superseded by this discussion, yes.
Bruce thinks we do not need rte_eth_dev_get_pmd_handle().
What is your opinion about using port_id directly and retrieving
the structs from the driver via rte_eth_devices?
Looking at the code in rte_eth_devices[]
struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
struct rte_eth_dev {
...
const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD
*/
...
void *pmd_ops; /** < exported PMD specific functions */
}
The PMD functions are only accessible at present if they are in
struct
eth_dev_ops.
quoted
Adding a pmd_ops field to struct rte_eth_dev {} makes the PMD
functions
accessible and is a simpler solution than using
rte_eth_dev_get_pmd_handle() to get access to the PMD functions.
quoted
Regards,
Why would an ops structure be needed? If it's a private API for a
driver, there should be no need for function pointers, and instead
the driver can define regular functions in it's header file, no?
/Bruce
The driver functions were static, I have made them public and added
them to the rte_pmd_ixgbe.h file, and it works. These functions will
also need to be added to the rte_pmd_ixgbe_version.map file, previously
there were no public functions.
Sorry for being late in the discussion, but I have a question:
If we this way (force user to include driver specific headers and call
driver specific functions), how you guys plan to make this functionality
available for multiple driver types.
From discussion with Bernard understand that customers would need similar
functionality for i40e.
Does it mean that they'll have to re-implement this part of their code
again?
Or would have to create (and maintain) their own shim layer that would
provide some s of abstraction?
Basically their own version of rte_ethdev?
Konstantin
Yes, it's a problem. However, the concern right now is that this functionality is not generic across NICs, and will only be implemented for ixgbe and i40e. If it turns out to be implemented for a significant subset of DPDK PMDs, e.g. 4 or 5 drivers from at least two vendors, then I would expect the case to be made to "promote" this functionality to ethdev.
Does this sound reasonable. Any other thoughts?
/Bruce
From: Thomas Monjalon <hidden> Date: 2016-09-28 13:03:21
2016-09-28 11:23, Ananyev, Konstantin:
If we this way (force user to include driver specific headers and call driver specific functions),
how you guys plan to make this functionality available for multiple driver types.
Multiple drivers won't have exactly the same specific features.
But yes, there are some things common to several Intel NICs.
From discussion with Bernard understand that customers would need similar functionality for i40e.
Does it mean that they'll have to re-implement this part of their code again?
Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
Basically their own version of rte_ethdev?
No definitive answer.
But we can argue the contrary: how to handle a generic API which is implemented
only in 1 or 2 drivers? If the application tries to use it, we can imagine
that a specific range of hardware is expected.
I think it is an important question.
Previously we had the issue of having some API which are too specific
and need a rework to be used with other NICs. In order to avoid such
rework and API break, we can try to make them available in a driver-specific
or vendor-specific staging area, waiting for a later generalization.
From: Ananyev, Konstantin <hidden> Date: 2016-09-28 13:26:39
-----Original Message-----
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
Sent: Wednesday, September 28, 2016 2:03 PM
To: Ananyev, Konstantin <redacted>
Cc: Iremonger, Bernard <redacted>; Richardson, Bruce <redacted>; dev@dpdk.org; Jerin
Jacob [off-list ref]; Shah, Rahul R [off-list ref]; Lu, Wenzhuo [off-list ref];
azelezniak [off-list ref]
Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF management
2016-09-28 11:23, Ananyev, Konstantin:
quoted
If we this way (force user to include driver specific headers and
call driver specific functions), how you guys plan to make this functionality available for multiple driver types.
Multiple drivers won't have exactly the same specific features.
But yes, there are some things common to several Intel NICs.
quoted
From discussion with Bernard understand that customers would need similar functionality for i40e.
Does it mean that they'll have to re-implement this part of their code again?
Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
Basically their own version of rte_ethdev?
No definitive answer.
But we can argue the contrary: how to handle a generic API which is implemented only in 1 or 2 drivers? If the application tries to use
it, we can imagine that a specific range of hardware is expected.
Yes, as I understand, it is a specific subset of supported HW (just Inel NICs for now, but different models/drivers).
Obviously users would like to have an ability to run their app on all HW from this subset without rebuilding/implementing the app.
I think it is an important question.
Previously we had the issue of having some API which are too specific and need a rework to be used with other NICs. In order to avoid
such rework and API break, we can try to make them available in a driver-specific or vendor-specific staging area, waiting for a later
generalization.
Could you remind me why you guys were that opposed to ioctl style approach?
It is not my favorite thing either, but it seems pretty generic way to handle such situations.
Konstantin
From: Thomas Monjalon <hidden> Date: 2016-09-28 14:24:08
2016-09-28 13:26, Ananyev, Konstantin:
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-28 11:23, Ananyev, Konstantin:
quoted
If we this way (force user to include driver specific headers and
call driver specific functions), how you guys plan to make this functionality available for multiple driver types.
Multiple drivers won't have exactly the same specific features.
But yes, there are some things common to several Intel NICs.
quoted
From discussion with Bernard understand that customers would need similar functionality for i40e.
Does it mean that they'll have to re-implement this part of their code again?
Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
Basically their own version of rte_ethdev?
No definitive answer.
But we can argue the contrary: how to handle a generic API which is implemented only in 1 or 2 drivers? If the application tries to use
it, we can imagine that a specific range of hardware is expected.
Yes, as I understand, it is a specific subset of supported HW (just Inel NICs for now, but different models/drivers).
Obviously users would like to have an ability to run their app on all HW from this subset without rebuilding/implementing the app.
quoted
I think it is an important question.
Previously we had the issue of having some API which are too specific and need a rework to be used with other NICs. In order to avoid
such rework and API break, we can try to make them available in a driver-specific or vendor-specific staging area, waiting for a later
generalization.
Could you remind me why you guys were that opposed to ioctl style approach?
It is not my favorite thing either, but it seems pretty generic way to handle such situations.
We prefer having well-defined functions instead of opaque ioctl-style encoding.
And it was not clear what is the benefit of ioctl.
Now I think I understand you would like to have a common ioctl service for
features available on 2 drivers. Right? Example (trying to read your mind):
rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF id>);
instead of
rte_pmd_ixgbe_vf_ping(port_id, vf_id);
rte_pmd_i40e_vf_ping(port_id, vf_id);
Please confirm I understand what you are thinking about.
From: Ananyev, Konstantin <hidden> Date: 2016-09-28 14:31:09
-----Original Message-----
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
Sent: Wednesday, September 28, 2016 3:24 PM
To: Ananyev, Konstantin <redacted>
Cc: Iremonger, Bernard <redacted>; Richardson, Bruce <redacted>; dev@dpdk.org; Jerin
Jacob [off-list ref]; Shah, Rahul R [off-list ref]; Lu, Wenzhuo [off-list ref];
azelezniak [off-list ref]
Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF management
2016-09-28 13:26, Ananyev, Konstantin:
quoted
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-28 11:23, Ananyev, Konstantin:
quoted
If we this way (force user to include driver specific headers and
call driver specific functions), how you guys plan to make this functionality available for multiple driver types.
Multiple drivers won't have exactly the same specific features.
But yes, there are some things common to several Intel NICs.
quoted
From discussion with Bernard understand that customers would need similar functionality for i40e.
Does it mean that they'll have to re-implement this part of their code again?
Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
Basically their own version of rte_ethdev?
No definitive answer.
But we can argue the contrary: how to handle a generic API which is
implemented only in 1 or 2 drivers? If the application tries to use it, we can imagine that a specific range of hardware is expected.
Yes, as I understand, it is a specific subset of supported HW (just Inel NICs for now, but different models/drivers).
Obviously users would like to have an ability to run their app on all HW from this subset without rebuilding/implementing the app.
quoted
I think it is an important question.
Previously we had the issue of having some API which are too
specific and need a rework to be used with other NICs. In order to
avoid such rework and API break, we can try to make them available in a driver-specific or vendor-specific staging area, waiting for
a later generalization.
quoted
Could you remind me why you guys were that opposed to ioctl style approach?
It is not my favorite thing either, but it seems pretty generic way to handle such situations.
We prefer having well-defined functions instead of opaque ioctl-style encoding.
And it was not clear what is the benefit of ioctl.
Now I think I understand you would like to have a common ioctl service for features available on 2 drivers. Right?
Yes.
Example (trying to read your mind):
rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF id>); instead of
rte_pmd_ixgbe_vf_ping(port_id, vf_id);
rte_pmd_i40e_vf_ping(port_id, vf_id);
Please confirm I understand what you are thinking about.
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-28 11:23, Ananyev, Konstantin:
quoted
If we this way (force user to include driver specific headers
and call driver specific functions), how you guys plan to make this
functionality available for multiple driver types.
quoted
quoted
quoted
Multiple drivers won't have exactly the same specific features.
But yes, there are some things common to several Intel NICs.
quoted
From discussion with Bernard understand that customers would
need similar functionality for i40e.
quoted
quoted
quoted
quoted
Does it mean that they'll have to re-implement this part of their code
again?
quoted
quoted
quoted
quoted
Or would have to create (and maintain) their own shim layer that
would provide some s of abstraction?
quoted
quoted
quoted
quoted
Basically their own version of rte_ethdev?
No definitive answer.
But we can argue the contrary: how to handle a generic API which
is implemented only in 1 or 2 drivers? If the application tries to use it,
we can imagine that a specific range of hardware is expected.
quoted
quoted
Yes, as I understand, it is a specific subset of supported HW (just Inel NICs
for now, but different models/drivers).
quoted
quoted
Obviously users would like to have an ability to run their app on all HW
from this subset without rebuilding/implementing the app.
quoted
quoted
quoted
I think it is an important question.
Previously we had the issue of having some API which are too
specific and need a rework to be used with other NICs. In order to
avoid such rework and API break, we can try to make them available
in a driver-specific or vendor-specific staging area, waiting for
a later generalization.
quoted
Could you remind me why you guys were that opposed to ioctl style
approach?
quoted
quoted
It is not my favorite thing either, but it seems pretty generic way to
handle such situations.
quoted
We prefer having well-defined functions instead of opaque ioctl-style
encoding.
quoted
And it was not clear what is the benefit of ioctl.
Now I think I understand you would like to have a common ioctl service for
features available on 2 drivers. Right?
Yes.
quoted
Example (trying to read your mind):
rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF
id>); instead of
quoted
rte_pmd_ixgbe_vf_ping(port_id, vf_id);
rte_pmd_i40e_vf_ping(port_id, vf_id); Please confirm I understand
what you are thinking about.
Yep, you read my mind correctly :)
Konstantin
Adding the pmd_ops field to struct eth_devops {} discussed previously in this email thread will allow driver specific functions for multiple drivers and will get rid of the driver specific header file rte_pmd_driver.h.
Would this be an acceptable solution?
Regards,
Bernard.
From: Thomas Monjalon <hidden> Date: 2016-09-28 14:59:05
2016-09-28 14:30, Ananyev, Konstantin:
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-28 13:26, Ananyev, Konstantin:
quoted
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-28 11:23, Ananyev, Konstantin:
quoted
If we this way (force user to include driver specific headers and
call driver specific functions), how you guys plan to make this functionality available for multiple driver types.
Multiple drivers won't have exactly the same specific features.
But yes, there are some things common to several Intel NICs.
quoted
From discussion with Bernard understand that customers would need similar functionality for i40e.
Does it mean that they'll have to re-implement this part of their code again?
Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
Basically their own version of rte_ethdev?
No definitive answer.
But we can argue the contrary: how to handle a generic API which is
implemented only in 1 or 2 drivers? If the application tries to use it, we can imagine that a specific range of hardware is expected.
Yes, as I understand, it is a specific subset of supported HW (just Inel NICs for now, but different models/drivers).
Obviously users would like to have an ability to run their app on all HW from this subset without rebuilding/implementing the app.
quoted
I think it is an important question.
Previously we had the issue of having some API which are too
specific and need a rework to be used with other NICs. In order to
avoid such rework and API break, we can try to make them available in a driver-specific or vendor-specific staging area, waiting for
a later generalization.
quoted
Could you remind me why you guys were that opposed to ioctl style approach?
It is not my favorite thing either, but it seems pretty generic way to handle such situations.
We prefer having well-defined functions instead of opaque ioctl-style encoding.
And it was not clear what is the benefit of ioctl.
Now I think I understand you would like to have a common ioctl service for features available on 2 drivers. Right?
Yes.
quoted
Example (trying to read your mind):
rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF id>); instead of
rte_pmd_ixgbe_vf_ping(port_id, vf_id);
rte_pmd_i40e_vf_ping(port_id, vf_id);
Please confirm I understand what you are thinking about.
Yep, you read my mind correctly :)
Both could coexist (if ioctl was accepted by community).
What about starting to implement the PMD functions and postpone
ioctl to later with a dedicated thread?
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-28 11:23, Ananyev, Konstantin:
quoted
If we this way (force user to include driver specific headers
and call driver specific functions), how you guys plan to make this
functionality available for multiple driver types.
quoted
quoted
quoted
Multiple drivers won't have exactly the same specific features.
But yes, there are some things common to several Intel NICs.
quoted
From discussion with Bernard understand that customers would
need similar functionality for i40e.
quoted
quoted
quoted
quoted
Does it mean that they'll have to re-implement this part of their code
again?
quoted
quoted
quoted
quoted
Or would have to create (and maintain) their own shim layer that
would provide some s of abstraction?
quoted
quoted
quoted
quoted
Basically their own version of rte_ethdev?
No definitive answer.
But we can argue the contrary: how to handle a generic API which
is implemented only in 1 or 2 drivers? If the application tries to use it,
we can imagine that a specific range of hardware is expected.
quoted
quoted
Yes, as I understand, it is a specific subset of supported HW (just Inel NICs
for now, but different models/drivers).
quoted
quoted
Obviously users would like to have an ability to run their app on all HW
from this subset without rebuilding/implementing the app.
quoted
quoted
quoted
I think it is an important question.
Previously we had the issue of having some API which are too
specific and need a rework to be used with other NICs. In order to
avoid such rework and API break, we can try to make them available
in a driver-specific or vendor-specific staging area, waiting for
a later generalization.
quoted
Could you remind me why you guys were that opposed to ioctl style
approach?
quoted
quoted
It is not my favorite thing either, but it seems pretty generic way to
handle such situations.
quoted
We prefer having well-defined functions instead of opaque ioctl-style
encoding.
quoted
And it was not clear what is the benefit of ioctl.
Now I think I understand you would like to have a common ioctl service for
features available on 2 drivers. Right?
Yes.
quoted
Example (trying to read your mind):
rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF
id>); instead of
quoted
rte_pmd_ixgbe_vf_ping(port_id, vf_id);
rte_pmd_i40e_vf_ping(port_id, vf_id); Please confirm I understand
what you are thinking about.
Yep, you read my mind correctly :)
Konstantin
Adding the pmd_ops field to struct eth_devops {} discussed previously in this email thread will allow driver specific functions for multiple drivers and will get rid of the driver specific header file rte_pmd_driver.h.
Would this be an acceptable solution?
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-28 11:23, Ananyev, Konstantin:
quoted
If we this way (force user to include driver specific
headers and call driver specific functions), how you guys
plan to make this
functionality available for multiple driver types.
quoted
quoted
quoted
Multiple drivers won't have exactly the same specific features.
But yes, there are some things common to several Intel NICs.
quoted
From discussion with Bernard understand that customers
would
need similar functionality for i40e.
quoted
quoted
quoted
quoted
Does it mean that they'll have to re-implement this part of
their code
again?
quoted
quoted
quoted
quoted
Or would have to create (and maintain) their own shim layer
that
would provide some s of abstraction?
quoted
quoted
quoted
quoted
Basically their own version of rte_ethdev?
No definitive answer.
But we can argue the contrary: how to handle a generic API
which is implemented only in 1 or 2 drivers? If the
application tries to use it,
we can imagine that a specific range of hardware is expected.
quoted
quoted
Yes, as I understand, it is a specific subset of supported HW
(just Inel NICs
for now, but different models/drivers).
quoted
quoted
Obviously users would like to have an ability to run their app
on all HW
from this subset without rebuilding/implementing the app.
quoted
quoted
quoted
I think it is an important question.
Previously we had the issue of having some API which are too
specific and need a rework to be used with other NICs. In
order to avoid such rework and API break, we can try to make
them available in a driver-specific or vendor-specific staging
area, waiting for
a later generalization.
quoted
Could you remind me why you guys were that opposed to ioctl
style
approach?
quoted
quoted
It is not my favorite thing either, but it seems pretty generic
way to
handle such situations.
quoted
We prefer having well-defined functions instead of opaque
ioctl-style
encoding.
quoted
And it was not clear what is the benefit of ioctl.
Now I think I understand you would like to have a common ioctl
service for
features available on 2 drivers. Right?
Yes.
quoted
Example (trying to read your mind):
rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF
id>); instead of
quoted
rte_pmd_ixgbe_vf_ping(port_id, vf_id);
rte_pmd_i40e_vf_ping(port_id, vf_id); Please confirm I understand
what you are thinking about.
Yep, you read my mind correctly :)
Konstantin
Adding the pmd_ops field to struct eth_devops {} discussed previously in
this email thread will allow driver specific functions for multiple drivers and
will get rid of the driver specific header file rte_pmd_driver.h.
quoted
Would this be an acceptable solution?
How pmd_ops would be different of eth_devops?
There is not a lot of difference, however it would separate generic ethdev functions from driver specific functions.
Regards,
Bernard.
From: Ananyev, Konstantin <hidden> Date: 2016-09-28 16:52:43
2016-09-28 14:30, Ananyev, Konstantin:
quoted
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-28 13:26, Ananyev, Konstantin:
quoted
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-28 11:23, Ananyev, Konstantin:
quoted
If we this way (force user to include driver specific headers
and call driver specific functions), how you guys plan to make this functionality available for multiple driver types.
Multiple drivers won't have exactly the same specific features.
But yes, there are some things common to several Intel NICs.
quoted
From discussion with Bernard understand that customers would need similar functionality for i40e.
Does it mean that they'll have to re-implement this part of their code again?
Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
Basically their own version of rte_ethdev?
No definitive answer.
But we can argue the contrary: how to handle a generic API which
is implemented only in 1 or 2 drivers? If the application tries to use it, we can imagine that a specific range of hardware is
expected.
quoted
quoted
quoted
Yes, as I understand, it is a specific subset of supported HW (just Inel NICs for now, but different models/drivers).
Obviously users would like to have an ability to run their app on all HW from this subset without rebuilding/implementing the
app.
quoted
quoted
quoted
quoted
I think it is an important question.
Previously we had the issue of having some API which are too
specific and need a rework to be used with other NICs. In order
to avoid such rework and API break, we can try to make them
available in a driver-specific or vendor-specific staging area,
waiting for
a later generalization.
quoted
Could you remind me why you guys were that opposed to ioctl style approach?
It is not my favorite thing either, but it seems pretty generic way to handle such situations.
We prefer having well-defined functions instead of opaque ioctl-style encoding.
And it was not clear what is the benefit of ioctl.
Now I think I understand you would like to have a common ioctl service for features available on 2 drivers. Right?
Yes.
quoted
Example (trying to read your mind):
rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF id>); instead of
rte_pmd_ixgbe_vf_ping(port_id, vf_id);
rte_pmd_i40e_vf_ping(port_id, vf_id); Please confirm I understand
what you are thinking about.
Yep, you read my mind correctly :)
Both could coexist (if ioctl was accepted by community).
True.
What about starting to implement the PMD functions and postpone ioctl to later with a dedicated thread?
You mean something like:
- 16.11: implement rte_pmd_ixgbe_vf_ping()
- 17.02:
a) implement rte_pmd_i40e_vf_ping()
b) introduce ioctl PMD API
c) make possible to vf_ping via ioctl API
?
If so, then it sounds like reasonable approach to me.
Though would be inserting to hear what other guys think.
Konstantin
From: Thomas Monjalon <hidden> Date: 2016-09-28 18:02:24
2016-09-28 16:52, Ananyev, Konstantin:
quoted
2016-09-28 14:30, Ananyev, Konstantin:
quoted
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-28 13:26, Ananyev, Konstantin:
quoted
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
quoted
2016-09-28 11:23, Ananyev, Konstantin:
quoted
If we this way (force user to include driver specific headers
and call driver specific functions), how you guys plan to make this functionality available for multiple driver types.
Multiple drivers won't have exactly the same specific features.
But yes, there are some things common to several Intel NICs.
quoted
From discussion with Bernard understand that customers would need similar functionality for i40e.
Does it mean that they'll have to re-implement this part of their code again?
Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
Basically their own version of rte_ethdev?
No definitive answer.
But we can argue the contrary: how to handle a generic API which
is implemented only in 1 or 2 drivers? If the application tries to use it, we can imagine that a specific range of hardware is
expected.
quoted
quoted
quoted
Yes, as I understand, it is a specific subset of supported HW (just Inel NICs for now, but different models/drivers).
Obviously users would like to have an ability to run their app on all HW from this subset without rebuilding/implementing the
app.
quoted
quoted
quoted
quoted
I think it is an important question.
Previously we had the issue of having some API which are too
specific and need a rework to be used with other NICs. In order
to avoid such rework and API break, we can try to make them
available in a driver-specific or vendor-specific staging area,
waiting for
a later generalization.
quoted
Could you remind me why you guys were that opposed to ioctl style approach?
It is not my favorite thing either, but it seems pretty generic way to handle such situations.
We prefer having well-defined functions instead of opaque ioctl-style encoding.
And it was not clear what is the benefit of ioctl.
Now I think I understand you would like to have a common ioctl service for features available on 2 drivers. Right?
Yes.
quoted
Example (trying to read your mind):
rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF id>); instead of
rte_pmd_ixgbe_vf_ping(port_id, vf_id);
rte_pmd_i40e_vf_ping(port_id, vf_id); Please confirm I understand
what you are thinking about.
Yep, you read my mind correctly :)
Both could coexist (if ioctl was accepted by community).
True.
quoted
What about starting to implement the PMD functions and postpone ioctl to later with a dedicated thread?
You mean something like:
- 16.11: implement rte_pmd_ixgbe_vf_ping()
- 17.02:
a) implement rte_pmd_i40e_vf_ping()
b) introduce ioctl PMD API
c) make possible to vf_ping via ioctl API
?
If so, then it sounds like reasonable approach to me.
Though would be inserting to hear what other guys think.
Yes.
I would just add that we have to start a discussion thread to decide
wether we'll add an ioctl call in 17.02 or not.
@@ -3499,7 +3499,28 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,uint8_tvlan_on);/**-*SetatrafficmirroringruleonanEthernetdevice+*Enable/Disablevfvlanstripforallqueuesinapool+*+*@paramport+*TheportidentifieroftheEthernetdevice.+*@paramvf+*IDspecifyingVF.+*@paramon+*1-EnableVF'svlanstriponRXqueues.+*0-DisableVF'svlanstriponRXqueues.+*@paramqueues_per_pool+*Thenumberofqueuesperpool.+*+*@return+*-(0)ifsuccessful.+*-(-ENOTSUP)ifhardwaredoesn'tsupportthisfeature.+*-(-ENODEV)if*port*invalid.+*-(-EINVAL)ifbadparameter.+*/+int+rte_eth_dev_set_vf_vlan_stripq(uint8_tport,uint16_tvf,inton);++/** Set a traffic mirroring rule on an Ethernet device**@paramport_id*TheportidentifieroftheEthernetdevice.
From: Bernard Iremonger <hidden> Date: 2016-09-29 14:16:44
This patchset contains new DPDK API's requested by AT&T for use
with the Virtual Function Daemon (VFD).
The need to configure and manage VF's on a NIC has grown to the
point where AT&T have devloped a DPDK based tool, VFD, to do this.
This patch set adds API extensions to DPDK VF configuration.
Eight new API's have been added for the Intel 82559 NIC.
Changes have been made to testpmd to facilitate testing of the new API's.
The testpmd documentation has been updated to document the testpmd changes.
Changes in v5:
rebase to latest master branch.
remove new API's from eth_dev_ops structure.
add public API's to ixgbe PMD.
revise testpmd commands for new API's
Changes in v4:
The rte_eth_dev_vf_ping API has been dropped as it is a work around for a bug.
The rte_eth_dev_set_vf_vlan_strip API has been renamed to
rte_eth_dev_set_vf_vlan_stripq.
Changes in v3:
rebase to latest master branch.
drop patches for callback functions
revise VF id checks in new librte_ether functions
revise testpmd commands for new API's
Changes in V2:
rebase to latest master branch.
fix compile error with clang.
Bernard Iremonger (3):
librte_ether: add API for VF management
net/ixgbe: add API's for VF management
app/test_pmd: add tests for new API's
app/test-pmd/cmdline.c | 675 ++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 62 ++-
drivers/net/ixgbe/Makefile | 2 +
drivers/net/ixgbe/ixgbe_ethdev.c | 200 +++++++++
drivers/net/ixgbe/rte_pmd_ixgbe.h | 162 +++++++
drivers/net/ixgbe/rte_pmd_ixgbe_version.map | 12 +
lib/librte_ether/rte_ethdev.c | 27 ++
lib/librte_ether/rte_ethdev.h | 23 +-
lib/librte_ether/rte_ether_version.map | 6 +
9 files changed, 1165 insertions(+), 4 deletions(-)
create mode 100644 drivers/net/ixgbe/rte_pmd_ixgbe.h
--
2.9.0
From: Bernard Iremonger <hidden> Date: 2016-09-29 14:16:49
add test for set vf vlan anti spoof
add test for set vf mac anti spoof
add test for set vf vlan stripq
add test for set vf vlan insert
add test for set tx loopback
add test for set all queues drop enable bit
add test for set vf split drop enable bit
add test for set vf mac address
add new API's to the testpmd guide
Signed-off-by: Bernard Iremonger <redacted>
---
app/test-pmd/cmdline.c | 675 ++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 62 ++-
2 files changed, 734 insertions(+), 3 deletions(-)
@@ -10585,6 +10586,672 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {},};+/* vf vlan anti spoof configuration */++/* Common result structure for vf vlan anti spoof */+structcmd_vf_vlan_anti_spoof_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tantispoof;+uint8_tport_id;+uint32_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf vlan anti spoof enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_antispoof=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+antispoof,"antispoof");+cmdline_parse_token_num_tcmd_vf_vlan_anti_spoof_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_anti_spoof_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+vf_id,UINT32);+cmdline_parse_token_string_tcmd_vf_vlan_anti_spoof_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_anti_spoof_result,+on_off,"on#off");++staticvoid+cmd_set_vf_vlan_anti_spoof_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_anti_spoof_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++ret=rte_pmd_ixgbe_set_vf_vlan_anti_spoof(res->port_id,res->vf_id,is_on);+switch(ret){+case0:+break;+case-EINVAL:+printf("invalid vf_id %d\n",res->vf_id);+break;+case-ENODEV:+printf("invalid port_id %d\n",res->port_id);+break;+default:+printf("programming error: (%s)\n",strerror(-ret));+}+}++cmdline_parse_inst_tcmd_set_vf_vlan_anti_spoof={+.f=cmd_set_vf_vlan_anti_spoof_parsed,+.data=NULL,+.help_str="set vf vlan antispoof port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_vlan_anti_spoof_set,+(void*)&cmd_vf_vlan_anti_spoof_vf,+(void*)&cmd_vf_vlan_anti_spoof_vlan,+(void*)&cmd_vf_vlan_anti_spoof_antispoof,+(void*)&cmd_vf_vlan_anti_spoof_port_id,+(void*)&cmd_vf_vlan_anti_spoof_vf_id,+(void*)&cmd_vf_vlan_anti_spoof_on_off,+NULL,+},+};++/* vf mac anti spoof configuration */++/* Common result structure for vf mac anti spoof */+structcmd_vf_mac_anti_spoof_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tmac;+cmdline_fixed_string_tantispoof;+uint8_tport_id;+uint32_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf mac anti spoof enable disable */+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_mac=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+mac,"mac");+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_antispoof=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+antispoof,"antispoof");+cmdline_parse_token_num_tcmd_vf_mac_anti_spoof_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_mac_anti_spoof_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+vf_id,UINT32);+cmdline_parse_token_string_tcmd_vf_mac_anti_spoof_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_mac_anti_spoof_result,+on_off,"on#off");++staticvoid+cmd_set_vf_mac_anti_spoof_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_mac_anti_spoof_result*res=parsed_result;+intret;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++ret=rte_pmd_ixgbe_set_vf_mac_anti_spoof(res->port_id,res->vf_id,is_on);+switch(ret){+case0:+break;+case-EINVAL:+printf("invalid vf_id %d or is_on %d\n",res->vf_id,is_on);+break;+case-ENODEV:+printf("invalid port_id %d\n",res->port_id);+break;+default:+printf("programming error: (%s)\n",strerror(-ret));+}+}++cmdline_parse_inst_tcmd_set_vf_mac_anti_spoof={+.f=cmd_set_vf_mac_anti_spoof_parsed,+.data=NULL,+.help_str="set vf mac antispoof port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_mac_anti_spoof_set,+(void*)&cmd_vf_mac_anti_spoof_vf,+(void*)&cmd_vf_mac_anti_spoof_mac,+(void*)&cmd_vf_mac_anti_spoof_antispoof,+(void*)&cmd_vf_mac_anti_spoof_port_id,+(void*)&cmd_vf_mac_anti_spoof_vf_id,+(void*)&cmd_vf_mac_anti_spoof_on_off,+NULL,+},+};++/* vf vlan strip queue configuration */++/* Common result structure for vf mac anti spoof */+structcmd_vf_vlan_stripq_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tstripq;+uint8_tport_id;+uint16_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf vlan strip enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_stripq_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_stripq_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_stripq_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_stripq_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_stripq_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_stripq_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_stripq_stripq=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_stripq_result,+stripq,"stripq");+cmdline_parse_token_num_tcmd_vf_vlan_stripq_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_stripq_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_stripq_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_stripq_result,+vf_id,UINT16);+cmdline_parse_token_string_tcmd_vf_vlan_stripq_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_stripq_result,+on_off,"on#off");++staticvoid+cmd_set_vf_vlan_stripq_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_stripq_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++ret=rte_eth_dev_set_vf_vlan_stripq(res->port_id,res->vf_id,is_on);+switch(ret){+case0:+break;+case-EINVAL:+printf("invalid vf_id %d or is_on %d\n",res->vf_id,is_on);+break;+case-ENODEV:+printf("invalid port_id %d\n",res->port_id);+break;+default:+printf("programming error: (%s)\n",strerror(-ret));+}+}++cmdline_parse_inst_tcmd_set_vf_vlan_stripq={+.f=cmd_set_vf_vlan_stripq_parsed,+.data=NULL,+.help_str="set vf vlan stripq port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_vlan_stripq_set,+(void*)&cmd_vf_vlan_stripq_vf,+(void*)&cmd_vf_vlan_stripq_vlan,+(void*)&cmd_vf_vlan_stripq_stripq,+(void*)&cmd_vf_vlan_stripq_port_id,+(void*)&cmd_vf_vlan_stripq_vf_id,+(void*)&cmd_vf_vlan_stripq_on_off,+NULL,+},+};++/* vf vlan insert configuration */++/* Common result structure for vf vlan insert */+structcmd_vf_vlan_insert_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tvlan;+cmdline_fixed_string_tinsert;+uint8_tport_id;+uint16_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf vlan insert enable disable */+cmdline_parse_token_string_tcmd_vf_vlan_insert_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_vlan_insert_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_vlan_insert_vlan=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+vlan,"vlan");+cmdline_parse_token_string_tcmd_vf_vlan_insert_insert=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+insert,"insert");+cmdline_parse_token_num_tcmd_vf_vlan_insert_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_insert_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_vlan_insert_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_vlan_insert_result,+vf_id,UINT16);+cmdline_parse_token_string_tcmd_vf_vlan_insert_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_vlan_insert_result,+on_off,"on#off");++staticvoid+cmd_set_vf_vlan_insert_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_vlan_insert_result*res=parsed_result;+intret;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++ret=rte_pmd_ixgbe_set_vf_vlan_insert(res->port_id,res->vf_id,is_on);+switch(ret){+case0:+break;+case-EINVAL:+printf("invalid vf_id %d or is_on %d\n",res->vf_id,is_on);+break;+case-ENODEV:+printf("invalid port_id %d\n",res->port_id);+break;+default:+printf("programming error: (%s)\n",strerror(-ret));+}+}++cmdline_parse_inst_tcmd_set_vf_vlan_insert={+.f=cmd_set_vf_vlan_insert_parsed,+.data=NULL,+.help_str="set vf vlan insert port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_vlan_insert_set,+(void*)&cmd_vf_vlan_insert_vf,+(void*)&cmd_vf_vlan_insert_vlan,+(void*)&cmd_vf_vlan_insert_insert,+(void*)&cmd_vf_vlan_insert_port_id,+(void*)&cmd_vf_vlan_insert_vf_id,+(void*)&cmd_vf_vlan_insert_on_off,+NULL,+},+};++/* tx loopback configuration */++/* Common result structure for tx loopback */+structcmd_tx_loopback_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_ttx;+cmdline_fixed_string_tloopback;+uint8_tport_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for tx loopback enable disable */+cmdline_parse_token_string_tcmd_tx_loopback_set=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+set,"set");+cmdline_parse_token_string_tcmd_tx_loopback_tx=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+tx,"tx");+cmdline_parse_token_string_tcmd_tx_loopback_loopback=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+loopback,"loopback");+cmdline_parse_token_num_tcmd_tx_loopback_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_tx_loopback_result,+port_id,UINT8);+cmdline_parse_token_string_tcmd_tx_loopback_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_tx_loopback_result,+on_off,"on#off");++staticvoid+cmd_set_tx_loopback_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_tx_loopback_result*res=parsed_result;+intret;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++ret=rte_pmd_ixgbe_set_tx_loopback(res->port_id,is_on);+switch(ret){+case0:+break;+case-EINVAL:+printf("invalid is_on %d\n",is_on);+break;+case-ENODEV:+printf("invalid port_id %d\n",res->port_id);+break;+default:+printf("programming error: (%s)\n",strerror(-ret));+}+}++cmdline_parse_inst_tcmd_set_tx_loopback={+.f=cmd_set_tx_loopback_parsed,+.data=NULL,+.help_str="set tx loopback port_id on|off",+.tokens={+(void*)&cmd_tx_loopback_set,+(void*)&cmd_tx_loopback_tx,+(void*)&cmd_tx_loopback_loopback,+(void*)&cmd_tx_loopback_port_id,+(void*)&cmd_tx_loopback_on_off,+NULL,+},+};++/* all queues drop enable configuration */++/* Common result structure for all queues drop enable */+structcmd_all_queues_drop_en_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tall;+cmdline_fixed_string_tqueues;+cmdline_fixed_string_tdrop;+uint8_tport_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for tx loopback enable disable */+cmdline_parse_token_string_tcmd_all_queues_drop_en_set=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+set,"set");+cmdline_parse_token_string_tcmd_all_queues_drop_en_all=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+all,"all");+cmdline_parse_token_string_tcmd_all_queues_drop_en_queues=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+queues,"queues");+cmdline_parse_token_string_tcmd_all_queues_drop_en_drop=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+drop,"drop");+cmdline_parse_token_num_tcmd_all_queues_drop_en_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_all_queues_drop_en_result,+port_id,UINT8);+cmdline_parse_token_string_tcmd_all_queues_drop_en_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_all_queues_drop_en_result,+on_off,"on#off");++staticvoid+cmd_set_all_queues_drop_en_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_all_queues_drop_en_result*res=parsed_result;+intret=0;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++ret=rte_pmd_ixgbe_set_all_queues_drop_en(res->port_id,is_on);+switch(ret){+case0:+break;+case-EINVAL:+printf("invalid is_on %d\n",is_on);+break;+case-ENODEV:+printf("invalid port_id %d\n",res->port_id);+break;+default:+printf("programming error: (%s)\n",strerror(-ret));+}+}++cmdline_parse_inst_tcmd_set_all_queues_drop_en={+.f=cmd_set_all_queues_drop_en_parsed,+.data=NULL,+.help_str="set all queues drop port_id on|off",+.tokens={+(void*)&cmd_all_queues_drop_en_set,+(void*)&cmd_all_queues_drop_en_all,+(void*)&cmd_all_queues_drop_en_queues,+(void*)&cmd_all_queues_drop_en_drop,+(void*)&cmd_all_queues_drop_en_port_id,+(void*)&cmd_all_queues_drop_en_on_off,+NULL,+},+};++/* vf split drop enable configuration */++/* Common result structure for vf split drop enable */+structcmd_vf_split_drop_en_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tsplit;+cmdline_fixed_string_tdrop;+uint8_tport_id;+uint16_tvf_id;+cmdline_fixed_string_ton_off;+};++/* Common CLI fields for vf split drop enable disable */+cmdline_parse_token_string_tcmd_vf_split_drop_en_set=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+set,"set");+cmdline_parse_token_string_tcmd_vf_split_drop_en_vf=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+vf,"vf");+cmdline_parse_token_string_tcmd_vf_split_drop_en_split=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+split,"split");+cmdline_parse_token_string_tcmd_vf_split_drop_en_drop=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+drop,"drop");+cmdline_parse_token_num_tcmd_vf_split_drop_en_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_split_drop_en_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_vf_split_drop_en_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_vf_split_drop_en_result,+vf_id,UINT16);+cmdline_parse_token_string_tcmd_vf_split_drop_en_on_off=+TOKEN_STRING_INITIALIZER+(structcmd_vf_split_drop_en_result,+on_off,"on#off");++staticvoid+cmd_set_vf_split_drop_en_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_vf_split_drop_en_result*res=parsed_result;+intret;+intis_on=(strcmp(res->on_off,"on")==0)?1:0;++ret=rte_pmd_ixgbe_set_vf_split_drop_en(res->port_id,res->vf_id,is_on);+switch(ret){+case0:+break;+case-EINVAL:+printf("invalid vf_id %d or is_on %d\n",res->vf_id,is_on);+break;+case-ENODEV:+printf("invalid port_id %d\n",res->port_id);+break;+default:+printf("programming error: (%s)\n",strerror(-ret));+}+}++cmdline_parse_inst_tcmd_set_vf_split_drop_en={+.f=cmd_set_vf_split_drop_en_parsed,+.data=NULL,+.help_str="set vf split drop port_id vf_id on|off",+.tokens={+(void*)&cmd_vf_split_drop_en_set,+(void*)&cmd_vf_split_drop_en_vf,+(void*)&cmd_vf_split_drop_en_split,+(void*)&cmd_vf_split_drop_en_drop,+(void*)&cmd_vf_split_drop_en_port_id,+(void*)&cmd_vf_split_drop_en_vf_id,+(void*)&cmd_vf_split_drop_en_on_off,+NULL,+},+};++/* vf mac address configuration */++/* Common result structure for vf mac address */+structcmd_set_vf_mac_addr_result{+cmdline_fixed_string_tset;+cmdline_fixed_string_tvf;+cmdline_fixed_string_tmac;+cmdline_fixed_string_taddr;+uint8_tport_id;+uint16_tvf_id;+structether_addrmac_addr;++};++/* Common CLI fields for vf split drop enable disable */+cmdline_parse_token_string_tcmd_set_vf_mac_addr_set=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+set,"set");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_vf=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+vf,"vf");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_mac=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+mac,"mac");+cmdline_parse_token_string_tcmd_set_vf_mac_addr_addr=+TOKEN_STRING_INITIALIZER+(structcmd_set_vf_mac_addr_result,+addr,"addr");+cmdline_parse_token_num_tcmd_set_vf_mac_addr_port_id=+TOKEN_NUM_INITIALIZER+(structcmd_set_vf_mac_addr_result,+port_id,UINT8);+cmdline_parse_token_num_tcmd_set_vf_mac_addr_vf_id=+TOKEN_NUM_INITIALIZER+(structcmd_set_vf_mac_addr_result,+vf_id,UINT16);+cmdline_parse_token_etheraddr_tcmd_set_vf_mac_addr_mac_addr=+TOKEN_ETHERADDR_INITIALIZER(structcmd_set_vf_mac_addr_result,+mac_addr);++staticvoid+cmd_set_vf_mac_addr_parsed(+void*parsed_result,+__attribute__((unused))structcmdline*cl,+__attribute__((unused))void*data)+{+structcmd_set_vf_mac_addr_result*res=parsed_result;+intret;++ret=rte_pmd_ixgbe_set_vf_mac_addr(res->port_id,res->vf_id,&res->mac_addr);+switch(ret){+case0:+break;+case-EINVAL:+printf("invalid vf_id %d or mac_addr\n",res->vf_id);+break;+case-ENODEV:+printf("invalid port_id %d\n",res->port_id);+break;+default:+printf("programming error: (%s)\n",strerror(-ret));+}+}++cmdline_parse_inst_tcmd_set_vf_mac_addr={+.f=cmd_set_vf_mac_addr_parsed,+.data=NULL,+.help_str="set vf mac addr port_id vf_id xx:xx:xx:xx:xx:xx",+.tokens={+(void*)&cmd_set_vf_mac_addr_set,+(void*)&cmd_set_vf_mac_addr_vf,+(void*)&cmd_set_vf_mac_addr_mac,+(void*)&cmd_set_vf_mac_addr_addr,+(void*)&cmd_set_vf_mac_addr_port_id,+(void*)&cmd_set_vf_mac_addr_vf_id,+(void*)&cmd_set_vf_mac_addr_mac_addr,+NULL,+},+};+++/* get PMD dev_ops handle */++/* Common result structure for vf mac address */+structcmd_get_pmd_handle_result{+cmdline_fixed_string_tget;+cmdline_fixed_string_tpmd;+cmdline_fixed_string_thandle;+uint8_tport_id;+};+++/* ******************************************************************************** *//* list of instructions */
@@ -1,5 +1,5 @@.. BSD LICENSE- Copyright(c) 2010-2015 Intel Corporation. All rights reserved.+ Copyright(c) 2010-2016 Intel Corporation. All rights reserved. All rights reserved. Redistribution and use in source and binary forms, with or without
@@ -473,6 +473,34 @@ For example, to change the port forwarding: RX P=1/Q=0 (socket 0) -> TX P=3/Q=0 (socket 0) peer=02:00:00:00:00:03 RX P=3/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:02+set tx loopback+~~~~~~~~~~~~~~~++Enable/disable tx loopback::++ testpmd> set tx loopback (port_id) (on|off)++set drop enable+~~~~~~~~~~~~~~~++set drop enable bit for all queues::++ testpmd> set all queues drop (port_id) (on|off)++set split drop enable (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++set split drop enable bit for VF from PF::++ testpmd> set vf split drop (port_id) (vf_id) (on|off)++set mac antispoof (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~++Set mac antispoof for a VF from the PF::++ testpmd> set vf mac antispoof (port_id) (vf_id) (on|off)+ vlan set strip ~~~~~~~~~~~~~~
@@ -487,6 +515,27 @@ Set the VLAN strip for a queue on a port:: testpmd> vlan set stripq (on|off) (port_id,queue_id)+vlan set stripq (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN strip for all queues in a pool for a VF from the PF::++ testpmd> set vf vlan stripq (port_id) (vf_id) (on|off)++vlan set insert (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN insert for a VF from the PF::++ testpmd> set vf vlan insert (port_id) (vf_id) (on|off)++vlan set antispoof (for VF)+~~~~~~~~~~~~~~~~~~~~~~~~~~~++Set VLAN antispoof for a VF from the PF::++ testpmd> set vf vlan antispoof (port_id) (vf_id) (on|off)+ vlan set filter ~~~~~~~~~~~~~~~
@@ -727,13 +776,20 @@ Remove a MAC address from a port:: testpmd> mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)-mac_addr add(for VF)-~~~~~~~~~~~~~~~~~~~~+mac_addr add (for VF)+~~~~~~~~~~~~~~~~~~~~~ Add an alternative MAC address for a VF to a port:: testpmd> mac_add add port (port_id) vf (vf_id) (XX:XX:XX:XX:XX:XX)+mac_addr set (for VF)+~~~~~~~~~~~~~~~~~~~~~++Set the MAC address for a VF from the PF::++ testpmd> set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)+ set port-uta ~~~~~~~~~~~~
From: Thomas Monjalon <hidden> Date: 2016-09-29 14:30:08
2016-09-29 15:16, Bernard Iremonger:
Add new API function to configure and manage VF's on a NIC.
add rte_eth_dev_set_vf_vlan_stripq function.
Signed-off-by: azelezniak <redacted>
We need the full name of azelezniak.
Signed-off-by: Bernard Iremonger <redacted>
[...]
+int
+rte_eth_dev_set_vf_vlan_stripq(uint8_t port, uint16_t vf, int on);
Why keeping this function in ethdev?
I think it would be more consistent to have also existing VF functions
moving from ethdev to rte_pmd_ixgbe.h.
You cannot remove them, but you can create their ixgbe-specific version
and announce that the ethdev ones are deprecated.
From: Iremonger, Bernard <hidden> Date: 2016-09-29 15:16:51
Hi Thomas,
<snip>
Subject: Re: [dpdk-dev] [PATCH v5 1/3] librte_ether: add API for VF
management
2016-09-29 15:16, Bernard Iremonger:
quoted
Add new API function to configure and manage VF's on a NIC.
add rte_eth_dev_set_vf_vlan_stripq function.
Signed-off-by: azelezniak <redacted>
We need the full name of azelezniak.
It is Alex Zelezniak, I will update the commit messages.
quoted
Signed-off-by: Bernard Iremonger <redacted>
[...]
quoted
+int
+rte_eth_dev_set_vf_vlan_stripq(uint8_t port, uint16_t vf, int on);
Why keeping this function in ethdev?
This function is using an existing API in the eth_dev_ops structure.
dev->dev_ops->vlan_strip_queue_set
The vlan_strip_queue_set API is used by the i40e, ixgbe and mlx5 PMD's.
I think it would be more consistent to have also existing VF functions moving
from ethdev to rte_pmd_ixgbe.h.
You cannot remove them, but you can create their ixgbe-specific version and
announce that the ethdev ones are deprecated.
There are 5 existing VF functions which are only used by ixgbe PMD at present.
It would make sense to create ixgbe-specific versions, however I think this should be done in a separate patchset.
Regards,
Bernard
From: Thomas Monjalon <hidden> Date: 2016-09-29 16:19:25
2016-09-29 15:16, Iremonger, Bernard:
quoted
2016-09-29 15:16, Bernard Iremonger:
quoted
+int
+rte_eth_dev_set_vf_vlan_stripq(uint8_t port, uint16_t vf, int on);
Why keeping this function in ethdev?
This function is using an existing API in the eth_dev_ops structure.
dev->dev_ops->vlan_strip_queue_set
The vlan_strip_queue_set API is used by the i40e, ixgbe and mlx5 PMD's.
OK but it was not used to control VF from PF.
This line:
(*dev->dev_ops->vlan_strip_queue_set)(dev, q + vf * queues_per_pool, on);
seems Intel specific.
Please keep "VF from PF" outside of ethdev for 16.11.
quoted
I think it would be more consistent to have also existing VF functions moving
from ethdev to rte_pmd_ixgbe.h.
You cannot remove them, but you can create their ixgbe-specific version and
announce that the ethdev ones are deprecated.
There are 5 existing VF functions which are only used by ixgbe PMD at present.
It would make sense to create ixgbe-specific versions, however I think this should be done in a separate patchset.
Yes it can be a separate patchset for RC2 of course.
From: Iremonger, Bernard <hidden> Date: 2016-09-29 16:38:13
Hi Thomas,
Subject: Re: [dpdk-dev] [PATCH v5 1/3] librte_ether: add API for VF
management
2016-09-29 15:16, Iremonger, Bernard:
quoted
quoted
2016-09-29 15:16, Bernard Iremonger:
quoted
+int
+rte_eth_dev_set_vf_vlan_stripq(uint8_t port, uint16_t vf, int
+on);
Why keeping this function in ethdev?
This function is using an existing API in the eth_dev_ops structure.
dev->dev_ops->vlan_strip_queue_set
The vlan_strip_queue_set API is used by the i40e, ixgbe and mlx5 PMD's.
OK but it was not used to control VF from PF.
This line:
(*dev->dev_ops->vlan_strip_queue_set)(dev, q + vf *
queues_per_pool, on); seems Intel specific.
Please keep "VF from PF" outside of ethdev for 16.11.
I will try calling (*dev->dev_ops->vlan_strip_queue_set) from an ixgbe-specific function.
Will this be acceptable?
Regards,
Bernard.