@@ -34,37 +34,6 @@ static int ice_check_vf_init(struct ice_pf *pf, struct ice_vf *vf)
3434 return 0 ;
3535}
3636
37- /**
38- * ice_err_to_virt err - translate errors for VF return code
39- * @ice_err: error return code
40- */
41- static enum virtchnl_status_code ice_err_to_virt_err (enum ice_status ice_err )
42- {
43- switch (ice_err ) {
44- case ICE_SUCCESS :
45- return VIRTCHNL_STATUS_SUCCESS ;
46- case ICE_ERR_BAD_PTR :
47- case ICE_ERR_INVAL_SIZE :
48- case ICE_ERR_DEVICE_NOT_SUPPORTED :
49- case ICE_ERR_PARAM :
50- case ICE_ERR_CFG :
51- return VIRTCHNL_STATUS_ERR_PARAM ;
52- case ICE_ERR_NO_MEMORY :
53- return VIRTCHNL_STATUS_ERR_NO_MEMORY ;
54- case ICE_ERR_NOT_READY :
55- case ICE_ERR_RESET_FAILED :
56- case ICE_ERR_FW_API_VER :
57- case ICE_ERR_AQ_ERROR :
58- case ICE_ERR_AQ_TIMEOUT :
59- case ICE_ERR_AQ_FULL :
60- case ICE_ERR_AQ_NO_WORK :
61- case ICE_ERR_AQ_EMPTY :
62- return VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR ;
63- default :
64- return VIRTCHNL_STATUS_ERR_NOT_SUPPORTED ;
65- }
66- }
67-
6837/**
6938 * ice_vc_vf_broadcast - Broadcast a message to all VFs on PF
7039 * @pf: pointer to the PF structure
@@ -2483,6 +2452,83 @@ static bool ice_can_vf_change_mac(struct ice_vf *vf)
24832452 return true;
24842453}
24852454
2455+ /**
2456+ * ice_vc_add_mac_addr - attempt to add the MAC address passed in
2457+ * @vf: pointer to the VF info
2458+ * @vsi: pointer to the VF's VSI
2459+ * @mac_addr: MAC address to add
2460+ */
2461+ static int
2462+ ice_vc_add_mac_addr (struct ice_vf * vf , struct ice_vsi * vsi , u8 * mac_addr )
2463+ {
2464+ struct device * dev = ice_pf_to_dev (vf -> pf );
2465+ enum ice_status status ;
2466+
2467+ /* default unicast MAC already added */
2468+ if (ether_addr_equal (mac_addr , vf -> dflt_lan_addr .addr ))
2469+ return 0 ;
2470+
2471+ if (is_unicast_ether_addr (mac_addr ) && !ice_can_vf_change_mac (vf )) {
2472+ dev_err (dev , "VF attempting to override administratively set MAC address, bring down and up the VF interface to resume normal operation\n" );
2473+ return - EPERM ;
2474+ }
2475+
2476+ status = ice_vsi_cfg_mac_fltr (vsi , mac_addr , true);
2477+ if (status == ICE_ERR_ALREADY_EXISTS ) {
2478+ dev_err (dev , "MAC %pM already exists for VF %d\n" , mac_addr ,
2479+ vf -> vf_id );
2480+ return - EEXIST ;
2481+ } else if (status ) {
2482+ dev_err (dev , "Failed to add MAC %pM for VF %d\n, error %d\n" ,
2483+ mac_addr , vf -> vf_id , status );
2484+ return - EIO ;
2485+ }
2486+
2487+ /* only set dflt_lan_addr once */
2488+ if (is_zero_ether_addr (vf -> dflt_lan_addr .addr ) &&
2489+ is_unicast_ether_addr (mac_addr ))
2490+ ether_addr_copy (vf -> dflt_lan_addr .addr , mac_addr );
2491+
2492+ vf -> num_mac ++ ;
2493+
2494+ return 0 ;
2495+ }
2496+
2497+ /**
2498+ * ice_vc_del_mac_addr - attempt to delete the MAC address passed in
2499+ * @vf: pointer to the VF info
2500+ * @vsi: pointer to the VF's VSI
2501+ * @mac_addr: MAC address to delete
2502+ */
2503+ static int
2504+ ice_vc_del_mac_addr (struct ice_vf * vf , struct ice_vsi * vsi , u8 * mac_addr )
2505+ {
2506+ struct device * dev = ice_pf_to_dev (vf -> pf );
2507+ enum ice_status status ;
2508+
2509+ if (!ice_can_vf_change_mac (vf ) &&
2510+ ether_addr_equal (mac_addr , vf -> dflt_lan_addr .addr ))
2511+ return 0 ;
2512+
2513+ status = ice_vsi_cfg_mac_fltr (vsi , mac_addr , false);
2514+ if (status == ICE_ERR_DOES_NOT_EXIST ) {
2515+ dev_err (dev , "MAC %pM does not exist for VF %d\n" , mac_addr ,
2516+ vf -> vf_id );
2517+ return - ENOENT ;
2518+ } else if (status ) {
2519+ dev_err (dev , "Failed to delete MAC %pM for VF %d, error %d\n" ,
2520+ mac_addr , vf -> vf_id , status );
2521+ return - EIO ;
2522+ }
2523+
2524+ if (ether_addr_equal (mac_addr , vf -> dflt_lan_addr .addr ))
2525+ eth_zero_addr (vf -> dflt_lan_addr .addr );
2526+
2527+ vf -> num_mac -- ;
2528+
2529+ return 0 ;
2530+ }
2531+
24862532/**
24872533 * ice_vc_handle_mac_addr_msg
24882534 * @vf: pointer to the VF info
@@ -2494,38 +2540,39 @@ static bool ice_can_vf_change_mac(struct ice_vf *vf)
24942540static int
24952541ice_vc_handle_mac_addr_msg (struct ice_vf * vf , u8 * msg , bool set )
24962542{
2543+ int (* ice_vc_cfg_mac )
2544+ (struct ice_vf * vf , struct ice_vsi * vsi , u8 * mac_addr );
24972545 enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS ;
24982546 struct virtchnl_ether_addr_list * al =
24992547 (struct virtchnl_ether_addr_list * )msg ;
25002548 struct ice_pf * pf = vf -> pf ;
25012549 enum virtchnl_ops vc_op ;
2502- enum ice_status status ;
25032550 struct ice_vsi * vsi ;
2504- struct device * dev ;
2505- int mac_count = 0 ;
25062551 int i ;
25072552
2508- dev = ice_pf_to_dev (pf );
2509-
2510- if (set )
2553+ if (set ) {
25112554 vc_op = VIRTCHNL_OP_ADD_ETH_ADDR ;
2512- else
2555+ ice_vc_cfg_mac = ice_vc_add_mac_addr ;
2556+ } else {
25132557 vc_op = VIRTCHNL_OP_DEL_ETH_ADDR ;
2558+ ice_vc_cfg_mac = ice_vc_del_mac_addr ;
2559+ }
25142560
25152561 if (!test_bit (ICE_VF_STATE_ACTIVE , vf -> vf_states ) ||
25162562 !ice_vc_isvalid_vsi_id (vf , al -> vsi_id )) {
25172563 v_ret = VIRTCHNL_STATUS_ERR_PARAM ;
25182564 goto handle_mac_exit ;
25192565 }
25202566
2567+ /* If this VF is not privileged, then we can't add more than a
2568+ * limited number of addresses. Check to make sure that the
2569+ * additions do not push us over the limit.
2570+ */
25212571 if (set && !ice_is_vf_trusted (vf ) &&
25222572 (vf -> num_mac + al -> num_elements ) > ICE_MAX_MACADDR_PER_VF ) {
2523- dev_err (dev ,
2573+ dev_err (ice_pf_to_dev ( pf ) ,
25242574 "Can't add more MAC addresses, because VF-%d is not trusted, switch the VF to trusted mode in order to add more functionalities\n" ,
25252575 vf -> vf_id );
2526- /* There is no need to let VF know about not being trusted
2527- * to add more MAC addr, so we can just return success message.
2528- */
25292576 v_ret = VIRTCHNL_STATUS_ERR_PARAM ;
25302577 goto handle_mac_exit ;
25312578 }
@@ -2537,70 +2584,22 @@ ice_vc_handle_mac_addr_msg(struct ice_vf *vf, u8 *msg, bool set)
25372584 }
25382585
25392586 for (i = 0 ; i < al -> num_elements ; i ++ ) {
2540- u8 * maddr = al -> list [i ].addr ;
2587+ u8 * mac_addr = al -> list [i ].addr ;
2588+ int result ;
25412589
2542- if (ether_addr_equal (maddr , vf -> dflt_lan_addr .addr ) ||
2543- is_broadcast_ether_addr (maddr )) {
2544- if (set ) {
2545- /* VF is trying to add filters that the PF
2546- * already added. Just continue.
2547- */
2548- dev_info (dev ,
2549- "MAC %pM already set for VF %d\n" ,
2550- maddr , vf -> vf_id );
2551- continue ;
2552- } else {
2553- /* VF can't remove dflt_lan_addr/bcast MAC */
2554- dev_err (dev ,
2555- "VF can't remove default MAC address or MAC %pM programmed by PF for VF %d\n" ,
2556- maddr , vf -> vf_id );
2557- continue ;
2558- }
2559- }
2560-
2561- /* check for the invalid cases and bail if necessary */
2562- if (is_zero_ether_addr (maddr )) {
2563- dev_err (dev ,
2564- "invalid MAC %pM provided for VF %d\n" ,
2565- maddr , vf -> vf_id );
2566- v_ret = VIRTCHNL_STATUS_ERR_PARAM ;
2567- goto handle_mac_exit ;
2568- }
2569-
2570- if (is_unicast_ether_addr (maddr ) &&
2571- !ice_can_vf_change_mac (vf )) {
2572- dev_err (dev ,
2573- "can't change unicast MAC for untrusted VF %d\n" ,
2574- vf -> vf_id );
2575- v_ret = VIRTCHNL_STATUS_ERR_PARAM ;
2576- goto handle_mac_exit ;
2577- }
2590+ if (is_broadcast_ether_addr (mac_addr ) ||
2591+ is_zero_ether_addr (mac_addr ))
2592+ continue ;
25782593
2579- /* program the updated filter list */
2580- status = ice_vsi_cfg_mac_fltr (vsi , maddr , set );
2581- if (status == ICE_ERR_DOES_NOT_EXIST ||
2582- status == ICE_ERR_ALREADY_EXISTS ) {
2583- dev_info (dev ,
2584- "can't %s MAC filters %pM for VF %d, error %d\n" ,
2585- set ? "add" : "remove" , maddr , vf -> vf_id ,
2586- status );
2587- } else if (status ) {
2588- dev_err (dev ,
2589- "can't %s MAC filters for VF %d, error %d\n" ,
2590- set ? "add" : "remove" , vf -> vf_id , status );
2591- v_ret = ice_err_to_virt_err (status );
2594+ result = ice_vc_cfg_mac (vf , vsi , mac_addr );
2595+ if (result == - EEXIST || result == - ENOENT ) {
2596+ continue ;
2597+ } else if (result ) {
2598+ v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR ;
25922599 goto handle_mac_exit ;
25932600 }
2594-
2595- mac_count ++ ;
25962601 }
25972602
2598- /* Track number of MAC filters programmed for the VF VSI */
2599- if (set )
2600- vf -> num_mac += mac_count ;
2601- else
2602- vf -> num_mac -= mac_count ;
2603-
26042603handle_mac_exit :
26052604 /* send the response to the VF */
26062605 return ice_vc_send_msg_to_vf (vf , vc_op , v_ret , NULL , 0 );
0 commit comments