0001
0002
0003
0004 #include "ice.h"
0005 #include "ice_fltr.h"
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 void ice_fltr_free_list(struct device *dev, struct list_head *h)
0016 {
0017 struct ice_fltr_list_entry *e, *tmp;
0018
0019 list_for_each_entry_safe(e, tmp, h, list_entry) {
0020 list_del(&e->list_entry);
0021 devm_kfree(dev, e);
0022 }
0023 }
0024
0025
0026
0027
0028
0029
0030
0031 static int
0032 ice_fltr_add_entry_to_list(struct device *dev, struct ice_fltr_info *info,
0033 struct list_head *list)
0034 {
0035 struct ice_fltr_list_entry *entry;
0036
0037 entry = devm_kzalloc(dev, sizeof(*entry), GFP_ATOMIC);
0038 if (!entry)
0039 return -ENOMEM;
0040
0041 entry->fltr_info = *info;
0042
0043 INIT_LIST_HEAD(&entry->list_entry);
0044 list_add(&entry->list_entry, list);
0045
0046 return 0;
0047 }
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 int
0058 ice_fltr_set_vlan_vsi_promisc(struct ice_hw *hw, struct ice_vsi *vsi,
0059 u8 promisc_mask)
0060 {
0061 struct ice_pf *pf = hw->back;
0062 int result;
0063
0064 result = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, false);
0065 if (result && result != -EEXIST)
0066 dev_err(ice_pf_to_dev(pf),
0067 "Error setting promisc mode on VSI %i (rc=%d)\n",
0068 vsi->vsi_num, result);
0069
0070 return result;
0071 }
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 int
0082 ice_fltr_clear_vlan_vsi_promisc(struct ice_hw *hw, struct ice_vsi *vsi,
0083 u8 promisc_mask)
0084 {
0085 struct ice_pf *pf = hw->back;
0086 int result;
0087
0088 result = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, true);
0089 if (result && result != -EEXIST)
0090 dev_err(ice_pf_to_dev(pf),
0091 "Error clearing promisc mode on VSI %i (rc=%d)\n",
0092 vsi->vsi_num, result);
0093
0094 return result;
0095 }
0096
0097
0098
0099
0100
0101
0102
0103
0104 int
0105 ice_fltr_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
0106 u16 vid)
0107 {
0108 struct ice_pf *pf = hw->back;
0109 int result;
0110
0111 result = ice_clear_vsi_promisc(hw, vsi_handle, promisc_mask, vid);
0112 if (result && result != -EEXIST)
0113 dev_err(ice_pf_to_dev(pf),
0114 "Error clearing promisc mode on VSI %i for VID %u (rc=%d)\n",
0115 ice_get_hw_vsi_num(hw, vsi_handle), vid, result);
0116
0117 return result;
0118 }
0119
0120
0121
0122
0123
0124
0125
0126
0127 int
0128 ice_fltr_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
0129 u16 vid)
0130 {
0131 struct ice_pf *pf = hw->back;
0132 int result;
0133
0134 result = ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vid);
0135 if (result && result != -EEXIST)
0136 dev_err(ice_pf_to_dev(pf),
0137 "Error setting promisc mode on VSI %i for VID %u (rc=%d)\n",
0138 ice_get_hw_vsi_num(hw, vsi_handle), vid, result);
0139
0140 return result;
0141 }
0142
0143
0144
0145
0146
0147
0148 int ice_fltr_add_mac_list(struct ice_vsi *vsi, struct list_head *list)
0149 {
0150 return ice_add_mac(&vsi->back->hw, list);
0151 }
0152
0153
0154
0155
0156
0157
0158 int ice_fltr_remove_mac_list(struct ice_vsi *vsi, struct list_head *list)
0159 {
0160 return ice_remove_mac(&vsi->back->hw, list);
0161 }
0162
0163
0164
0165
0166
0167
0168 static int ice_fltr_add_vlan_list(struct ice_vsi *vsi, struct list_head *list)
0169 {
0170 return ice_add_vlan(&vsi->back->hw, list);
0171 }
0172
0173
0174
0175
0176
0177
0178 static int
0179 ice_fltr_remove_vlan_list(struct ice_vsi *vsi, struct list_head *list)
0180 {
0181 return ice_remove_vlan(&vsi->back->hw, list);
0182 }
0183
0184
0185
0186
0187
0188
0189 static int ice_fltr_add_eth_list(struct ice_vsi *vsi, struct list_head *list)
0190 {
0191 return ice_add_eth_mac(&vsi->back->hw, list);
0192 }
0193
0194
0195
0196
0197
0198
0199 static int ice_fltr_remove_eth_list(struct ice_vsi *vsi, struct list_head *list)
0200 {
0201 return ice_remove_eth_mac(&vsi->back->hw, list);
0202 }
0203
0204
0205
0206
0207
0208 void ice_fltr_remove_all(struct ice_vsi *vsi)
0209 {
0210 ice_remove_vsi_fltr(&vsi->back->hw, vsi->idx);
0211 }
0212
0213
0214
0215
0216
0217
0218
0219
0220 int
0221 ice_fltr_add_mac_to_list(struct ice_vsi *vsi, struct list_head *list,
0222 const u8 *mac, enum ice_sw_fwd_act_type action)
0223 {
0224 struct ice_fltr_info info = { 0 };
0225
0226 info.flag = ICE_FLTR_TX;
0227 info.src_id = ICE_SRC_ID_VSI;
0228 info.lkup_type = ICE_SW_LKUP_MAC;
0229 info.fltr_act = action;
0230 info.vsi_handle = vsi->idx;
0231
0232 ether_addr_copy(info.l_data.mac.mac_addr, mac);
0233
0234 return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info,
0235 list);
0236 }
0237
0238
0239
0240
0241
0242
0243
0244 static int
0245 ice_fltr_add_vlan_to_list(struct ice_vsi *vsi, struct list_head *list,
0246 struct ice_vlan *vlan)
0247 {
0248 struct ice_fltr_info info = { 0 };
0249
0250 info.flag = ICE_FLTR_TX;
0251 info.src_id = ICE_SRC_ID_VSI;
0252 info.lkup_type = ICE_SW_LKUP_VLAN;
0253 info.fltr_act = ICE_FWD_TO_VSI;
0254 info.vsi_handle = vsi->idx;
0255 info.l_data.vlan.vlan_id = vlan->vid;
0256 info.l_data.vlan.tpid = vlan->tpid;
0257 info.l_data.vlan.tpid_valid = true;
0258
0259 return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info,
0260 list);
0261 }
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271 static int
0272 ice_fltr_add_eth_to_list(struct ice_vsi *vsi, struct list_head *list,
0273 u16 ethertype, u16 flag,
0274 enum ice_sw_fwd_act_type action)
0275 {
0276 struct ice_fltr_info info = { 0 };
0277
0278 info.flag = flag;
0279 info.lkup_type = ICE_SW_LKUP_ETHERTYPE;
0280 info.fltr_act = action;
0281 info.vsi_handle = vsi->idx;
0282 info.l_data.ethertype_mac.ethertype = ethertype;
0283
0284 if (flag == ICE_FLTR_TX)
0285 info.src_id = ICE_SRC_ID_VSI;
0286 else
0287 info.src_id = ICE_SRC_ID_LPORT;
0288
0289 return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info,
0290 list);
0291 }
0292
0293
0294
0295
0296
0297
0298
0299
0300 static int
0301 ice_fltr_prepare_mac(struct ice_vsi *vsi, const u8 *mac,
0302 enum ice_sw_fwd_act_type action,
0303 int (*mac_action)(struct ice_vsi *, struct list_head *))
0304 {
0305 LIST_HEAD(tmp_list);
0306 int result;
0307
0308 if (ice_fltr_add_mac_to_list(vsi, &tmp_list, mac, action)) {
0309 ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
0310 return -ENOMEM;
0311 }
0312
0313 result = mac_action(vsi, &tmp_list);
0314 ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
0315 return result;
0316 }
0317
0318
0319
0320
0321
0322
0323
0324
0325 static int
0326 ice_fltr_prepare_mac_and_broadcast(struct ice_vsi *vsi, const u8 *mac,
0327 enum ice_sw_fwd_act_type action,
0328 int(*mac_action)
0329 (struct ice_vsi *, struct list_head *))
0330 {
0331 u8 broadcast[ETH_ALEN];
0332 LIST_HEAD(tmp_list);
0333 int result;
0334
0335 eth_broadcast_addr(broadcast);
0336 if (ice_fltr_add_mac_to_list(vsi, &tmp_list, mac, action) ||
0337 ice_fltr_add_mac_to_list(vsi, &tmp_list, broadcast, action)) {
0338 ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
0339 return -ENOMEM;
0340 }
0341
0342 result = mac_action(vsi, &tmp_list);
0343 ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
0344 return result;
0345 }
0346
0347
0348
0349
0350
0351
0352
0353 static int
0354 ice_fltr_prepare_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan,
0355 int (*vlan_action)(struct ice_vsi *, struct list_head *))
0356 {
0357 LIST_HEAD(tmp_list);
0358 int result;
0359
0360 if (ice_fltr_add_vlan_to_list(vsi, &tmp_list, vlan))
0361 return -ENOMEM;
0362
0363 result = vlan_action(vsi, &tmp_list);
0364 ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
0365 return result;
0366 }
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376 static int
0377 ice_fltr_prepare_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
0378 enum ice_sw_fwd_act_type action,
0379 int (*eth_action)(struct ice_vsi *, struct list_head *))
0380 {
0381 LIST_HEAD(tmp_list);
0382 int result;
0383
0384 if (ice_fltr_add_eth_to_list(vsi, &tmp_list, ethertype, flag, action))
0385 return -ENOMEM;
0386
0387 result = eth_action(vsi, &tmp_list);
0388 ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
0389 return result;
0390 }
0391
0392
0393
0394
0395
0396
0397
0398 int ice_fltr_add_mac(struct ice_vsi *vsi, const u8 *mac,
0399 enum ice_sw_fwd_act_type action)
0400 {
0401 return ice_fltr_prepare_mac(vsi, mac, action, ice_fltr_add_mac_list);
0402 }
0403
0404
0405
0406
0407
0408
0409
0410 int
0411 ice_fltr_add_mac_and_broadcast(struct ice_vsi *vsi, const u8 *mac,
0412 enum ice_sw_fwd_act_type action)
0413 {
0414 return ice_fltr_prepare_mac_and_broadcast(vsi, mac, action,
0415 ice_fltr_add_mac_list);
0416 }
0417
0418
0419
0420
0421
0422
0423
0424 int ice_fltr_remove_mac(struct ice_vsi *vsi, const u8 *mac,
0425 enum ice_sw_fwd_act_type action)
0426 {
0427 return ice_fltr_prepare_mac(vsi, mac, action, ice_fltr_remove_mac_list);
0428 }
0429
0430
0431
0432
0433
0434
0435 int ice_fltr_add_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan)
0436 {
0437 return ice_fltr_prepare_vlan(vsi, vlan, ice_fltr_add_vlan_list);
0438 }
0439
0440
0441
0442
0443
0444
0445 int ice_fltr_remove_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan)
0446 {
0447 return ice_fltr_prepare_vlan(vsi, vlan, ice_fltr_remove_vlan_list);
0448 }
0449
0450
0451
0452
0453
0454
0455
0456
0457 int ice_fltr_add_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
0458 enum ice_sw_fwd_act_type action)
0459 {
0460 return ice_fltr_prepare_eth(vsi, ethertype, flag, action,
0461 ice_fltr_add_eth_list);
0462 }
0463
0464
0465
0466
0467
0468
0469
0470
0471 int ice_fltr_remove_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
0472 enum ice_sw_fwd_act_type action)
0473 {
0474 return ice_fltr_prepare_eth(vsi, ethertype, flag, action,
0475 ice_fltr_remove_eth_list);
0476 }