History

iavf: Fix VLAN_V2 addition/rejection

Fix VLAN addition, so that PF driver does not reject whole VLAN batch. Add VLAN reject handling, so rejected VLANs, won't litter VLAN filter list. Fix handling of active_(c/s)vlans, so it will be possible to re-add VLAN filters for user. Without this patch, after changing trust to off, with VLAN filters saturated, no VLAN is added, due to PF rejecting addition.

Przemyslaw Patynowski committed 4 years ago

Commit 968996c1 parent 7b02f403 files · +74 −10Browse files

Unified · Split

3 files
  1. drivers/net/ethernet/intel/iavf/iavf.h +7 −2
  2. drivers/net/ethernet/intel/iavf/iavf_main.c +4 −6
  3. drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +63 −2
drivers/net/ethernet/intel/iavf/iavf.h+7−2
@@ -159,8 +159,12 @@ struct iavf_vlan { · 158 unmodified lines
159struct iavf_vlan_filter {159struct iavf_vlan_filter {
160 struct list_head list;160 struct list_head list;
161 struct iavf_vlan vlan;161 struct iavf_vlan vlan;
162 bool remove; /* filter needs to be removed */162 struct {
163 bool add; /* filter needs to be added */163 u8 is_new_vlan:1; /* filter is new, wait for PF answer */
164 u8 remove:1; /* filter needs to be removed */
165 u8 add:1; /* filter needs to be added */
166 u8 padding:5;
167 };
164};168};
165 169
166#define IAVF_MAX_TRAFFIC_CLASS 4170#define IAVF_MAX_TRAFFIC_CLASS 4
@@ -520,6 +524,7 @@ int iavf_get_vf_config(struct iavf_adapter *adapter); · 353 unmodified lines
520int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter);524int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter);
521int iavf_send_vf_offload_vlan_v2_msg(struct iavf_adapter *adapter);525int iavf_send_vf_offload_vlan_v2_msg(struct iavf_adapter *adapter);
522void iavf_set_queue_vlan_tag_loc(struct iavf_adapter *adapter);526void iavf_set_queue_vlan_tag_loc(struct iavf_adapter *adapter);
527u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter);
523void iavf_irq_enable(struct iavf_adapter *adapter, bool flush);528void iavf_irq_enable(struct iavf_adapter *adapter, bool flush);
524void iavf_configure_queues(struct iavf_adapter *adapter);529void iavf_configure_queues(struct iavf_adapter *adapter);
525void iavf_deconfigure_queues(struct iavf_adapter *adapter);530void iavf_deconfigure_queues(struct iavf_adapter *adapter);
drivers/net/ethernet/intel/iavf/iavf_main.c+4−6
@@ -843,7 +843,7 @@ static void iavf_restore_filters(struct iavf_adapter *adapter) · 842 unmodified lines
843 * iavf_get_num_vlans_added - get number of VLANs added843 * iavf_get_num_vlans_added - get number of VLANs added
844 * @adapter: board private structure844 * @adapter: board private structure
845 */845 */
846static u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter)846u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter)
847{847{
848 return bitmap_weight(adapter->vsi.active_cvlans, VLAN_N_VID) +848 return bitmap_weight(adapter->vsi.active_cvlans, VLAN_N_VID) +
849 bitmap_weight(adapter->vsi.active_svlans, VLAN_N_VID);849 bitmap_weight(adapter->vsi.active_svlans, VLAN_N_VID);
@@ -906,11 +906,6 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev, · 56 unmodified lines
906 if (!iavf_add_vlan(adapter, IAVF_VLAN(vid, be16_to_cpu(proto))))906 if (!iavf_add_vlan(adapter, IAVF_VLAN(vid, be16_to_cpu(proto))))
907 return -ENOMEM;907 return -ENOMEM;
908 908
909 if (proto == cpu_to_be16(ETH_P_8021Q))
910 set_bit(vid, adapter->vsi.active_cvlans);
911 else
912 set_bit(vid, adapter->vsi.active_svlans);
913
914 return 0;909 return 0;
915}910}
916 911
@@ -2956,6 +2951,9 @@ continue_reset: · 2039 unmodified lines
2956 adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER;2951 adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER;
2957 iavf_misc_irq_enable(adapter);2952 iavf_misc_irq_enable(adapter);
2958 2953
2954 bitmap_clear(adapter->vsi.active_cvlans, 0, VLAN_N_VID);
2955 bitmap_clear(adapter->vsi.active_svlans, 0, VLAN_N_VID);
2956
2959 mod_delayed_work(iavf_wq, &adapter->watchdog_task, 2);2957 mod_delayed_work(iavf_wq, &adapter->watchdog_task, 2);
2960 2958
2961 /* We were running when the reset started, so we need to restore some2959 /* We were running when the reset started, so we need to restore some
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c+63−2
@@ -626,6 +626,33 @@ static void iavf_mac_add_reject(struct iavf_adapter *adapter) · 625 unmodified lines
626 spin_unlock_bh(&adapter->mac_vlan_list_lock);626 spin_unlock_bh(&adapter->mac_vlan_list_lock);
627}627}
628 628
629/**
630 * iavf_vlan_add_reject
631 * @adapter: adapter structure
632 *
633 * Remove VLAN filters from list based on PF response.
634 **/
635static void iavf_vlan_add_reject(struct iavf_adapter *adapter)
636{
637 struct iavf_vlan_filter *f, *ftmp;
638
639 spin_lock_bh(&adapter->mac_vlan_list_lock);
640 list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
641 if (f->is_new_vlan) {
642 if (f->vlan.tpid == ETH_P_8021Q)
643 clear_bit(f->vlan.vid,
644 adapter->vsi.active_cvlans);
645 else
646 clear_bit(f->vlan.vid,
647 adapter->vsi.active_svlans);
648
649 list_del(&f->list);
650 kfree(f);
651 }
652 }
653 spin_unlock_bh(&adapter->mac_vlan_list_lock);
654}
655
629/**656/**
630 * iavf_add_vlans657 * iavf_add_vlans
631 * @adapter: adapter structure658 * @adapter: adapter structure
@@ -683,6 +710,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter) · 51 unmodified lines
683 vvfl->vlan_id[i] = f->vlan.vid;710 vvfl->vlan_id[i] = f->vlan.vid;
684 i++;711 i++;
685 f->add = false;712 f->add = false;
713 f->is_new_vlan = true;
686 if (i == count)714 if (i == count)
687 break;715 break;
688 }716 }
@@ -695,10 +723,18 @@ void iavf_add_vlans(struct iavf_adapter *adapter) · 6 unmodified lines
695 iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);723 iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);
696 kfree(vvfl);724 kfree(vvfl);
697 } else {725 } else {
726 u16 max_vlans = adapter->vlan_v2_caps.filtering.max_filters;
727 u16 current_vlans = iavf_get_num_vlans_added(adapter);
698 struct virtchnl_vlan_filter_list_v2 *vvfl_v2;728 struct virtchnl_vlan_filter_list_v2 *vvfl_v2;
699 729
700 adapter->current_op = VIRTCHNL_OP_ADD_VLAN_V2;730 adapter->current_op = VIRTCHNL_OP_ADD_VLAN_V2;
701 731
732 if ((count + current_vlans) > max_vlans &&
733 current_vlans < max_vlans) {
734 count = max_vlans - iavf_get_num_vlans_added(adapter);
735 more = true;
736 }
737
702 len = sizeof(*vvfl_v2) + ((count - 1) *738 len = sizeof(*vvfl_v2) + ((count - 1) *
703 sizeof(struct virtchnl_vlan_filter));739 sizeof(struct virtchnl_vlan_filter));
704 if (len > IAVF_MAX_AQ_BUF_SIZE) {740 if (len > IAVF_MAX_AQ_BUF_SIZE) {
@@ -725,6 +761,9 @@ void iavf_add_vlans(struct iavf_adapter *adapter) · 20 unmodified lines
725 &adapter->vlan_v2_caps.filtering.filtering_support;761 &adapter->vlan_v2_caps.filtering.filtering_support;
726 struct virtchnl_vlan *vlan;762 struct virtchnl_vlan *vlan;
727 763
764 if (i == count)
765 break;
766
728 /* give priority over outer if it's enabled */767 /* give priority over outer if it's enabled */
729 if (filtering_support->outer)768 if (filtering_support->outer)
730 vlan = &vvfl_v2->filters[i].outer;769 vlan = &vvfl_v2->filters[i].outer;
@@ -736,8 +775,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter) · 5 unmodified lines
736 775
737 i++;776 i++;
738 f->add = false;777 f->add = false;
739 if (i == count)778 f->is_new_vlan = true;
740 break;
741 }779 }
742 }780 }
743 781
@@ -2080,6 +2118,11 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, · 1336 unmodified lines
2080 */2118 */
2081 iavf_netdev_features_vlan_strip_set(netdev, true);2119 iavf_netdev_features_vlan_strip_set(netdev, true);
2082 break;2120 break;
2121 case VIRTCHNL_OP_ADD_VLAN_V2:
2122 iavf_vlan_add_reject(adapter);
2123 dev_warn(&adapter->pdev->dev, "Failed to add VLAN filter, error %s\n",
2124 iavf_stat_str(&adapter->hw, v_retval));
2125 break;
2083 default:2126 default:
2084 dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n",2127 dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n",
2085 v_retval, iavf_stat_str(&adapter->hw, v_retval),2128 v_retval, iavf_stat_str(&adapter->hw, v_retval),
@@ -2332,6 +2375,24 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, · 246 unmodified lines
2332 spin_unlock_bh(&adapter->adv_rss_lock);2375 spin_unlock_bh(&adapter->adv_rss_lock);
2333 }2376 }
2334 break;2377 break;
2378 case VIRTCHNL_OP_ADD_VLAN_V2: {
2379 struct iavf_vlan_filter *f;
2380
2381 spin_lock_bh(&adapter->mac_vlan_list_lock);
2382 list_for_each_entry(f, &adapter->vlan_filter_list, list) {
2383 if (f->is_new_vlan) {
2384 f->is_new_vlan = false;
2385 if (f->vlan.tpid == ETH_P_8021Q)
2386 set_bit(f->vlan.vid,
2387 adapter->vsi.active_cvlans);
2388 else
2389 set_bit(f->vlan.vid,
2390 adapter->vsi.active_svlans);
2391 }
2392 }
2393 spin_unlock_bh(&adapter->mac_vlan_list_lock);
2394 }
2395 break;
2335 case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:2396 case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
2336 /* PF enabled vlan strip on this VF.2397 /* PF enabled vlan strip on this VF.
2337 * Update netdev->features if needed to be in sync with ethtool.2398 * Update netdev->features if needed to be in sync with ethtool.