@@ -140,6 +140,7 @@ int iavf_send_vf_config_msg(struct iavf_adapter *adapter)
140140 VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM |
141141 VIRTCHNL_VF_OFFLOAD_REQ_QUEUES |
142142 VIRTCHNL_VF_OFFLOAD_ADQ |
143+ VIRTCHNL_VF_OFFLOAD_FDIR_PF |
143144 VIRTCHNL_VF_CAP_ADV_LINK_SPEED ;
144145
145146 adapter -> current_op = VIRTCHNL_OP_GET_VF_RESOURCES ;
@@ -1197,6 +1198,101 @@ void iavf_del_cloud_filter(struct iavf_adapter *adapter)
11971198 kfree (f );
11981199}
11991200
1201+ /**
1202+ * iavf_add_fdir_filter
1203+ * @adapter: the VF adapter structure
1204+ *
1205+ * Request that the PF add Flow Director filters as specified
1206+ * by the user via ethtool.
1207+ **/
1208+ void iavf_add_fdir_filter (struct iavf_adapter * adapter )
1209+ {
1210+ struct iavf_fdir_fltr * fdir ;
1211+ struct virtchnl_fdir_add * f ;
1212+ bool process_fltr = false;
1213+ int len ;
1214+
1215+ if (adapter -> current_op != VIRTCHNL_OP_UNKNOWN ) {
1216+ /* bail because we already have a command pending */
1217+ dev_err (& adapter -> pdev -> dev , "Cannot add Flow Director filter, command %d pending\n" ,
1218+ adapter -> current_op );
1219+ return ;
1220+ }
1221+
1222+ len = sizeof (struct virtchnl_fdir_add );
1223+ f = kzalloc (len , GFP_KERNEL );
1224+ if (!f )
1225+ return ;
1226+
1227+ spin_lock_bh (& adapter -> fdir_fltr_lock );
1228+ list_for_each_entry (fdir , & adapter -> fdir_list_head , list ) {
1229+ if (fdir -> state == IAVF_FDIR_FLTR_ADD_REQUEST ) {
1230+ process_fltr = true;
1231+ fdir -> state = IAVF_FDIR_FLTR_ADD_PENDING ;
1232+ memcpy (f , & fdir -> vc_add_msg , len );
1233+ break ;
1234+ }
1235+ }
1236+ spin_unlock_bh (& adapter -> fdir_fltr_lock );
1237+
1238+ if (!process_fltr ) {
1239+ /* prevent iavf_add_fdir_filter() from being called when there
1240+ * are no filters to add
1241+ */
1242+ adapter -> aq_required &= ~IAVF_FLAG_AQ_ADD_FDIR_FILTER ;
1243+ kfree (f );
1244+ return ;
1245+ }
1246+ adapter -> current_op = VIRTCHNL_OP_ADD_FDIR_FILTER ;
1247+ iavf_send_pf_msg (adapter , VIRTCHNL_OP_ADD_FDIR_FILTER , (u8 * )f , len );
1248+ kfree (f );
1249+ }
1250+
1251+ /**
1252+ * iavf_del_fdir_filter
1253+ * @adapter: the VF adapter structure
1254+ *
1255+ * Request that the PF delete Flow Director filters as specified
1256+ * by the user via ethtool.
1257+ **/
1258+ void iavf_del_fdir_filter (struct iavf_adapter * adapter )
1259+ {
1260+ struct iavf_fdir_fltr * fdir ;
1261+ struct virtchnl_fdir_del f ;
1262+ bool process_fltr = false;
1263+ int len ;
1264+
1265+ if (adapter -> current_op != VIRTCHNL_OP_UNKNOWN ) {
1266+ /* bail because we already have a command pending */
1267+ dev_err (& adapter -> pdev -> dev , "Cannot remove Flow Director filter, command %d pending\n" ,
1268+ adapter -> current_op );
1269+ return ;
1270+ }
1271+
1272+ len = sizeof (struct virtchnl_fdir_del );
1273+
1274+ spin_lock_bh (& adapter -> fdir_fltr_lock );
1275+ list_for_each_entry (fdir , & adapter -> fdir_list_head , list ) {
1276+ if (fdir -> state == IAVF_FDIR_FLTR_DEL_REQUEST ) {
1277+ process_fltr = true;
1278+ memset (& f , 0 , len );
1279+ f .vsi_id = fdir -> vc_add_msg .vsi_id ;
1280+ f .flow_id = fdir -> flow_id ;
1281+ fdir -> state = IAVF_FDIR_FLTR_DEL_PENDING ;
1282+ break ;
1283+ }
1284+ }
1285+ spin_unlock_bh (& adapter -> fdir_fltr_lock );
1286+
1287+ if (!process_fltr ) {
1288+ adapter -> aq_required &= ~IAVF_FLAG_AQ_DEL_FDIR_FILTER ;
1289+ return ;
1290+ }
1291+
1292+ adapter -> current_op = VIRTCHNL_OP_DEL_FDIR_FILTER ;
1293+ iavf_send_pf_msg (adapter , VIRTCHNL_OP_DEL_FDIR_FILTER , (u8 * )& f , len );
1294+ }
1295+
12001296/**
12011297 * iavf_request_reset
12021298 * @adapter: adapter structure
@@ -1357,6 +1453,48 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
13571453 }
13581454 }
13591455 break ;
1456+ case VIRTCHNL_OP_ADD_FDIR_FILTER : {
1457+ struct iavf_fdir_fltr * fdir , * fdir_tmp ;
1458+
1459+ spin_lock_bh (& adapter -> fdir_fltr_lock );
1460+ list_for_each_entry_safe (fdir , fdir_tmp ,
1461+ & adapter -> fdir_list_head ,
1462+ list ) {
1463+ if (fdir -> state == IAVF_FDIR_FLTR_ADD_PENDING ) {
1464+ dev_info (& adapter -> pdev -> dev , "Failed to add Flow Director filter, error %s\n" ,
1465+ iavf_stat_str (& adapter -> hw ,
1466+ v_retval ));
1467+ if (msglen )
1468+ dev_err (& adapter -> pdev -> dev ,
1469+ "%s\n" , msg );
1470+ list_del (& fdir -> list );
1471+ kfree (fdir );
1472+ adapter -> fdir_active_fltr -- ;
1473+ }
1474+ }
1475+ spin_unlock_bh (& adapter -> fdir_fltr_lock );
1476+ }
1477+ break ;
1478+ case VIRTCHNL_OP_DEL_FDIR_FILTER : {
1479+ struct iavf_fdir_fltr * fdir ;
1480+
1481+ spin_lock_bh (& adapter -> fdir_fltr_lock );
1482+ list_for_each_entry (fdir , & adapter -> fdir_list_head ,
1483+ list ) {
1484+ if (fdir -> state == IAVF_FDIR_FLTR_DEL_PENDING ) {
1485+ fdir -> state = IAVF_FDIR_FLTR_ACTIVE ;
1486+ dev_info (& adapter -> pdev -> dev , "Failed to del Flow Director filter, error %s\n" ,
1487+ iavf_stat_str (& adapter -> hw ,
1488+ v_retval ));
1489+ }
1490+ }
1491+ spin_unlock_bh (& adapter -> fdir_fltr_lock );
1492+ }
1493+ break ;
1494+ case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING :
1495+ case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING :
1496+ dev_warn (& adapter -> pdev -> dev , "Changing VLAN Stripping is not allowed when Port VLAN is configured\n" );
1497+ break ;
13601498 default :
13611499 dev_err (& adapter -> pdev -> dev , "PF returned error %d (%s) to our request %d\n" ,
13621500 v_retval , iavf_stat_str (& adapter -> hw , v_retval ),
@@ -1490,6 +1628,52 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
14901628 }
14911629 }
14921630 break ;
1631+ case VIRTCHNL_OP_ADD_FDIR_FILTER : {
1632+ struct virtchnl_fdir_add * add_fltr = (struct virtchnl_fdir_add * )msg ;
1633+ struct iavf_fdir_fltr * fdir , * fdir_tmp ;
1634+
1635+ spin_lock_bh (& adapter -> fdir_fltr_lock );
1636+ list_for_each_entry_safe (fdir , fdir_tmp ,
1637+ & adapter -> fdir_list_head ,
1638+ list ) {
1639+ if (fdir -> state == IAVF_FDIR_FLTR_ADD_PENDING ) {
1640+ if (add_fltr -> status == VIRTCHNL_FDIR_SUCCESS ) {
1641+ fdir -> state = IAVF_FDIR_FLTR_ACTIVE ;
1642+ fdir -> flow_id = add_fltr -> flow_id ;
1643+ } else {
1644+ dev_info (& adapter -> pdev -> dev , "Failed to add Flow Director filter with status: %d\n" ,
1645+ add_fltr -> status );
1646+ list_del (& fdir -> list );
1647+ kfree (fdir );
1648+ adapter -> fdir_active_fltr -- ;
1649+ }
1650+ }
1651+ }
1652+ spin_unlock_bh (& adapter -> fdir_fltr_lock );
1653+ }
1654+ break ;
1655+ case VIRTCHNL_OP_DEL_FDIR_FILTER : {
1656+ struct virtchnl_fdir_del * del_fltr = (struct virtchnl_fdir_del * )msg ;
1657+ struct iavf_fdir_fltr * fdir , * fdir_tmp ;
1658+
1659+ spin_lock_bh (& adapter -> fdir_fltr_lock );
1660+ list_for_each_entry_safe (fdir , fdir_tmp , & adapter -> fdir_list_head ,
1661+ list ) {
1662+ if (fdir -> state == IAVF_FDIR_FLTR_DEL_PENDING ) {
1663+ if (del_fltr -> status == VIRTCHNL_FDIR_SUCCESS ) {
1664+ list_del (& fdir -> list );
1665+ kfree (fdir );
1666+ adapter -> fdir_active_fltr -- ;
1667+ } else {
1668+ fdir -> state = IAVF_FDIR_FLTR_ACTIVE ;
1669+ dev_info (& adapter -> pdev -> dev , "Failed to delete Flow Director filter with status: %d\n" ,
1670+ del_fltr -> status );
1671+ }
1672+ }
1673+ }
1674+ spin_unlock_bh (& adapter -> fdir_fltr_lock );
1675+ }
1676+ break ;
14931677 default :
14941678 if (adapter -> current_op && (v_opcode != adapter -> current_op ))
14951679 dev_warn (& adapter -> pdev -> dev , "Expected response %d from PF, received %d\n" ,
0 commit comments