Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'bnxt_en-ntuple-fuilter-support'

Michael Chan says:

====================
bnxt_en: Add basic ntuple filter support

The current driver only supports ntuple filters added by aRFS. This
patch series adds basic support for user defined TCP/UDP ntuple filters
added by the user using ethtool. Many of the patches are refactoring
patches to make the existing code more general to support both aRFS
and user defined filters. aRFS filters always have the Toeplitz hash
value from the NIC. A Toepliz hash function is added in patch 5 to
get the same hash value for user defined filters. The hash is used
to store all ntuple filters in the table and all filters must be
hashed identically using the same function and key.

v2: Fix compile error in patch #4 when CONFIG_BNXT_SRIOV is disabled.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+938 -248
+539 -180
drivers/net/ethernet/broadcom/bnxt/bnxt.c
··· 4199 4199 vnic->fw_l2_ctx_id = INVALID_HW_RING_ID; 4200 4200 4201 4201 if (bp->vnic_info[i].rss_hash_key) { 4202 - if (i == 0) 4202 + if (!i) { 4203 + u8 *key = (void *)vnic->rss_hash_key; 4204 + int k; 4205 + 4206 + bp->toeplitz_prefix = 0; 4203 4207 get_random_bytes(vnic->rss_hash_key, 4204 4208 HW_HASH_KEY_SIZE); 4205 - else 4209 + for (k = 0; k < 8; k++) { 4210 + bp->toeplitz_prefix <<= 8; 4211 + bp->toeplitz_prefix |= key[k]; 4212 + } 4213 + } else { 4206 4214 memcpy(vnic->rss_hash_key, 4207 4215 bp->vnic_info[0].rss_hash_key, 4208 4216 HW_HASH_KEY_SIZE); 4217 + } 4209 4218 } 4210 4219 } 4211 4220 } ··· 4798 4789 } 4799 4790 } 4800 4791 4801 - static void bnxt_free_ntp_fltrs(struct bnxt *bp, bool irq_reinit) 4792 + static void bnxt_free_ntp_fltrs(struct bnxt *bp, bool all) 4802 4793 { 4803 - #ifdef CONFIG_RFS_ACCEL 4804 4794 int i; 4805 4795 4806 4796 /* Under rtnl_lock and all our NAPIs have been disabled. It's ··· 4811 4803 struct bnxt_ntuple_filter *fltr; 4812 4804 4813 4805 head = &bp->ntp_fltr_hash_tbl[i]; 4814 - hlist_for_each_entry_safe(fltr, tmp, head, hash) { 4815 - hlist_del(&fltr->hash); 4806 + hlist_for_each_entry_safe(fltr, tmp, head, base.hash) { 4807 + bnxt_del_l2_filter(bp, fltr->l2_fltr); 4808 + if (!all && (fltr->base.flags & BNXT_ACT_FUNC_DST)) 4809 + continue; 4810 + hlist_del(&fltr->base.hash); 4811 + clear_bit(fltr->base.sw_id, bp->ntp_fltr_bmap); 4812 + bp->ntp_fltr_count--; 4816 4813 kfree(fltr); 4817 4814 } 4818 4815 } 4819 - if (irq_reinit) { 4820 - bitmap_free(bp->ntp_fltr_bmap); 4821 - bp->ntp_fltr_bmap = NULL; 4822 - } 4816 + if (!all) 4817 + return; 4818 + 4819 + bitmap_free(bp->ntp_fltr_bmap); 4820 + bp->ntp_fltr_bmap = NULL; 4823 4821 bp->ntp_fltr_count = 0; 4824 - #endif 4825 4822 } 4826 4823 4827 4824 static int bnxt_alloc_ntp_fltrs(struct bnxt *bp) 4828 4825 { 4829 - #ifdef CONFIG_RFS_ACCEL 4830 4826 int i, rc = 0; 4831 4827 4832 - if (!(bp->flags & BNXT_FLAG_RFS)) 4828 + if (!(bp->flags & BNXT_FLAG_RFS) || bp->ntp_fltr_bmap) 4833 4829 return 0; 4834 4830 4835 4831 for (i = 0; i < BNXT_NTP_FLTR_HASH_SIZE; i++) 4836 4832 INIT_HLIST_HEAD(&bp->ntp_fltr_hash_tbl[i]); 4837 4833 4838 4834 bp->ntp_fltr_count = 0; 4839 - bp->ntp_fltr_bmap = bitmap_zalloc(BNXT_NTP_FLTR_MAX_FLTR, GFP_KERNEL); 4835 + bp->ntp_fltr_bmap = bitmap_zalloc(BNXT_MAX_FLTR, GFP_KERNEL); 4840 4836 4841 4837 if (!bp->ntp_fltr_bmap) 4842 4838 rc = -ENOMEM; 4843 4839 4844 4840 return rc; 4845 - #else 4846 - return 0; 4847 - #endif 4841 + } 4842 + 4843 + static void bnxt_free_l2_filters(struct bnxt *bp, bool all) 4844 + { 4845 + int i; 4846 + 4847 + for (i = 0; i < BNXT_L2_FLTR_HASH_SIZE; i++) { 4848 + struct hlist_head *head; 4849 + struct hlist_node *tmp; 4850 + struct bnxt_l2_filter *fltr; 4851 + 4852 + head = &bp->l2_fltr_hash_tbl[i]; 4853 + hlist_for_each_entry_safe(fltr, tmp, head, base.hash) { 4854 + if (!all && (fltr->base.flags & BNXT_ACT_FUNC_DST)) 4855 + continue; 4856 + hlist_del(&fltr->base.hash); 4857 + if (fltr->base.flags) { 4858 + clear_bit(fltr->base.sw_id, bp->ntp_fltr_bmap); 4859 + bp->ntp_fltr_count--; 4860 + } 4861 + kfree(fltr); 4862 + } 4863 + } 4864 + } 4865 + 4866 + static void bnxt_init_l2_fltr_tbl(struct bnxt *bp) 4867 + { 4868 + int i; 4869 + 4870 + for (i = 0; i < BNXT_L2_FLTR_HASH_SIZE; i++) 4871 + INIT_HLIST_HEAD(&bp->l2_fltr_hash_tbl[i]); 4872 + get_random_bytes(&bp->hash_seed, sizeof(bp->hash_seed)); 4848 4873 } 4849 4874 4850 4875 static void bnxt_free_mem(struct bnxt *bp, bool irq_re_init) ··· 4887 4846 bnxt_free_rx_rings(bp); 4888 4847 bnxt_free_cp_rings(bp); 4889 4848 bnxt_free_all_cp_arrays(bp); 4890 - bnxt_free_ntp_fltrs(bp, irq_re_init); 4849 + bnxt_free_ntp_fltrs(bp, false); 4850 + bnxt_free_l2_filters(bp, false); 4891 4851 if (irq_re_init) { 4892 4852 bnxt_free_ring_stats(bp); 4893 4853 if (!(bp->phy_flags & BNXT_PHY_FL_PORT_STATS_NO_RESET) || ··· 5332 5290 return hwrm_req_send_silent(bp, req); 5333 5291 } 5334 5292 5293 + void bnxt_del_l2_filter(struct bnxt *bp, struct bnxt_l2_filter *fltr) 5294 + { 5295 + if (!atomic_dec_and_test(&fltr->refcnt)) 5296 + return; 5297 + spin_lock_bh(&bp->ntp_fltr_lock); 5298 + if (!test_and_clear_bit(BNXT_FLTR_INSERTED, &fltr->base.state)) { 5299 + spin_unlock_bh(&bp->ntp_fltr_lock); 5300 + return; 5301 + } 5302 + hlist_del_rcu(&fltr->base.hash); 5303 + if (fltr->base.flags) { 5304 + clear_bit(fltr->base.sw_id, bp->ntp_fltr_bmap); 5305 + bp->ntp_fltr_count--; 5306 + } 5307 + spin_unlock_bh(&bp->ntp_fltr_lock); 5308 + kfree_rcu(fltr, base.rcu); 5309 + } 5310 + 5311 + static struct bnxt_l2_filter *__bnxt_lookup_l2_filter(struct bnxt *bp, 5312 + struct bnxt_l2_key *key, 5313 + u32 idx) 5314 + { 5315 + struct hlist_head *head = &bp->l2_fltr_hash_tbl[idx]; 5316 + struct bnxt_l2_filter *fltr; 5317 + 5318 + hlist_for_each_entry_rcu(fltr, head, base.hash) { 5319 + struct bnxt_l2_key *l2_key = &fltr->l2_key; 5320 + 5321 + if (ether_addr_equal(l2_key->dst_mac_addr, key->dst_mac_addr) && 5322 + l2_key->vlan == key->vlan) 5323 + return fltr; 5324 + } 5325 + return NULL; 5326 + } 5327 + 5328 + static struct bnxt_l2_filter *bnxt_lookup_l2_filter(struct bnxt *bp, 5329 + struct bnxt_l2_key *key, 5330 + u32 idx) 5331 + { 5332 + struct bnxt_l2_filter *fltr = NULL; 5333 + 5334 + rcu_read_lock(); 5335 + fltr = __bnxt_lookup_l2_filter(bp, key, idx); 5336 + if (fltr) 5337 + atomic_inc(&fltr->refcnt); 5338 + rcu_read_unlock(); 5339 + return fltr; 5340 + } 5341 + 5342 + #define BNXT_IPV4_4TUPLE(bp, fkeys) \ 5343 + (((fkeys)->basic.ip_proto == IPPROTO_TCP && \ 5344 + (bp)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV4) || \ 5345 + ((fkeys)->basic.ip_proto == IPPROTO_UDP && \ 5346 + (bp)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV4)) 5347 + 5348 + #define BNXT_IPV6_4TUPLE(bp, fkeys) \ 5349 + (((fkeys)->basic.ip_proto == IPPROTO_TCP && \ 5350 + (bp)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV6) || \ 5351 + ((fkeys)->basic.ip_proto == IPPROTO_UDP && \ 5352 + (bp)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6)) 5353 + 5354 + static u32 bnxt_get_rss_flow_tuple_len(struct bnxt *bp, struct flow_keys *fkeys) 5355 + { 5356 + if (fkeys->basic.n_proto == htons(ETH_P_IP)) { 5357 + if (BNXT_IPV4_4TUPLE(bp, fkeys)) 5358 + return sizeof(fkeys->addrs.v4addrs) + 5359 + sizeof(fkeys->ports); 5360 + 5361 + if (bp->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_IPV4) 5362 + return sizeof(fkeys->addrs.v4addrs); 5363 + } 5364 + 5365 + if (fkeys->basic.n_proto == htons(ETH_P_IPV6)) { 5366 + if (BNXT_IPV6_4TUPLE(bp, fkeys)) 5367 + return sizeof(fkeys->addrs.v6addrs) + 5368 + sizeof(fkeys->ports); 5369 + 5370 + if (bp->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6) 5371 + return sizeof(fkeys->addrs.v6addrs); 5372 + } 5373 + 5374 + return 0; 5375 + } 5376 + 5377 + static u32 bnxt_toeplitz(struct bnxt *bp, struct flow_keys *fkeys, 5378 + const unsigned char *key) 5379 + { 5380 + u64 prefix = bp->toeplitz_prefix, hash = 0; 5381 + struct bnxt_ipv4_tuple tuple4; 5382 + struct bnxt_ipv6_tuple tuple6; 5383 + int i, j, len = 0; 5384 + u8 *four_tuple; 5385 + 5386 + len = bnxt_get_rss_flow_tuple_len(bp, fkeys); 5387 + if (!len) 5388 + return 0; 5389 + 5390 + if (fkeys->basic.n_proto == htons(ETH_P_IP)) { 5391 + tuple4.v4addrs = fkeys->addrs.v4addrs; 5392 + tuple4.ports = fkeys->ports; 5393 + four_tuple = (unsigned char *)&tuple4; 5394 + } else { 5395 + tuple6.v6addrs = fkeys->addrs.v6addrs; 5396 + tuple6.ports = fkeys->ports; 5397 + four_tuple = (unsigned char *)&tuple6; 5398 + } 5399 + 5400 + for (i = 0, j = 8; i < len; i++, j++) { 5401 + u8 byte = four_tuple[i]; 5402 + int bit; 5403 + 5404 + for (bit = 0; bit < 8; bit++, prefix <<= 1, byte <<= 1) { 5405 + if (byte & 0x80) 5406 + hash ^= prefix; 5407 + } 5408 + prefix |= (j < HW_HASH_KEY_SIZE) ? key[j] : 0; 5409 + } 5410 + 5411 + /* The valid part of the hash is in the upper 32 bits. */ 5412 + return (hash >> 32) & BNXT_NTP_FLTR_HASH_MASK; 5413 + } 5414 + 5335 5415 #ifdef CONFIG_RFS_ACCEL 5336 - static int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp, 5337 - struct bnxt_ntuple_filter *fltr) 5416 + static struct bnxt_l2_filter * 5417 + bnxt_lookup_l2_filter_from_key(struct bnxt *bp, struct bnxt_l2_key *key) 5418 + { 5419 + struct bnxt_l2_filter *fltr; 5420 + u32 idx; 5421 + 5422 + idx = jhash2(&key->filter_key, BNXT_L2_KEY_SIZE, bp->hash_seed) & 5423 + BNXT_L2_FLTR_HASH_MASK; 5424 + fltr = bnxt_lookup_l2_filter(bp, key, idx); 5425 + return fltr; 5426 + } 5427 + #endif 5428 + 5429 + static int bnxt_init_l2_filter(struct bnxt *bp, struct bnxt_l2_filter *fltr, 5430 + struct bnxt_l2_key *key, u32 idx) 5431 + { 5432 + struct hlist_head *head; 5433 + 5434 + ether_addr_copy(fltr->l2_key.dst_mac_addr, key->dst_mac_addr); 5435 + fltr->l2_key.vlan = key->vlan; 5436 + fltr->base.type = BNXT_FLTR_TYPE_L2; 5437 + if (fltr->base.flags) { 5438 + int bit_id; 5439 + 5440 + bit_id = bitmap_find_free_region(bp->ntp_fltr_bmap, 5441 + BNXT_MAX_FLTR, 0); 5442 + if (bit_id < 0) 5443 + return -ENOMEM; 5444 + fltr->base.sw_id = (u16)bit_id; 5445 + } 5446 + head = &bp->l2_fltr_hash_tbl[idx]; 5447 + hlist_add_head_rcu(&fltr->base.hash, head); 5448 + set_bit(BNXT_FLTR_INSERTED, &fltr->base.state); 5449 + atomic_set(&fltr->refcnt, 1); 5450 + return 0; 5451 + } 5452 + 5453 + static struct bnxt_l2_filter *bnxt_alloc_l2_filter(struct bnxt *bp, 5454 + struct bnxt_l2_key *key, 5455 + gfp_t gfp) 5456 + { 5457 + struct bnxt_l2_filter *fltr; 5458 + u32 idx; 5459 + int rc; 5460 + 5461 + idx = jhash2(&key->filter_key, BNXT_L2_KEY_SIZE, bp->hash_seed) & 5462 + BNXT_L2_FLTR_HASH_MASK; 5463 + fltr = bnxt_lookup_l2_filter(bp, key, idx); 5464 + if (fltr) 5465 + return fltr; 5466 + 5467 + fltr = kzalloc(sizeof(*fltr), gfp); 5468 + if (!fltr) 5469 + return ERR_PTR(-ENOMEM); 5470 + spin_lock_bh(&bp->ntp_fltr_lock); 5471 + rc = bnxt_init_l2_filter(bp, fltr, key, idx); 5472 + spin_unlock_bh(&bp->ntp_fltr_lock); 5473 + if (rc) { 5474 + bnxt_del_l2_filter(bp, fltr); 5475 + fltr = ERR_PTR(rc); 5476 + } 5477 + return fltr; 5478 + } 5479 + 5480 + static u16 bnxt_vf_target_id(struct bnxt_pf_info *pf, u16 vf_idx) 5481 + { 5482 + #ifdef CONFIG_BNXT_SRIOV 5483 + struct bnxt_vf_info *vf = &pf->vf[vf_idx]; 5484 + 5485 + return vf->fw_fid; 5486 + #else 5487 + return INVALID_HW_RING_ID; 5488 + #endif 5489 + } 5490 + 5491 + int bnxt_hwrm_l2_filter_free(struct bnxt *bp, struct bnxt_l2_filter *fltr) 5492 + { 5493 + struct hwrm_cfa_l2_filter_free_input *req; 5494 + u16 target_id = 0xffff; 5495 + int rc; 5496 + 5497 + if (fltr->base.flags & BNXT_ACT_FUNC_DST) { 5498 + struct bnxt_pf_info *pf = &bp->pf; 5499 + 5500 + if (fltr->base.vf_idx >= pf->active_vfs) 5501 + return -EINVAL; 5502 + 5503 + target_id = bnxt_vf_target_id(pf, fltr->base.vf_idx); 5504 + if (target_id == INVALID_HW_RING_ID) 5505 + return -EINVAL; 5506 + } 5507 + 5508 + rc = hwrm_req_init(bp, req, HWRM_CFA_L2_FILTER_FREE); 5509 + if (rc) 5510 + return rc; 5511 + 5512 + req->target_id = cpu_to_le16(target_id); 5513 + req->l2_filter_id = fltr->base.filter_id; 5514 + return hwrm_req_send(bp, req); 5515 + } 5516 + 5517 + int bnxt_hwrm_l2_filter_alloc(struct bnxt *bp, struct bnxt_l2_filter *fltr) 5518 + { 5519 + struct hwrm_cfa_l2_filter_alloc_output *resp; 5520 + struct hwrm_cfa_l2_filter_alloc_input *req; 5521 + u16 target_id = 0xffff; 5522 + int rc; 5523 + 5524 + if (fltr->base.flags & BNXT_ACT_FUNC_DST) { 5525 + struct bnxt_pf_info *pf = &bp->pf; 5526 + 5527 + if (fltr->base.vf_idx >= pf->active_vfs) 5528 + return -EINVAL; 5529 + 5530 + target_id = bnxt_vf_target_id(pf, fltr->base.vf_idx); 5531 + } 5532 + rc = hwrm_req_init(bp, req, HWRM_CFA_L2_FILTER_ALLOC); 5533 + if (rc) 5534 + return rc; 5535 + 5536 + req->target_id = cpu_to_le16(target_id); 5537 + req->flags = cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_FLAGS_PATH_RX); 5538 + 5539 + if (!BNXT_CHIP_TYPE_NITRO_A0(bp)) 5540 + req->flags |= 5541 + cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_FLAGS_OUTERMOST); 5542 + req->dst_id = cpu_to_le16(fltr->base.fw_vnic_id); 5543 + req->enables = 5544 + cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_ADDR | 5545 + CFA_L2_FILTER_ALLOC_REQ_ENABLES_DST_ID | 5546 + CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_ADDR_MASK); 5547 + ether_addr_copy(req->l2_addr, fltr->l2_key.dst_mac_addr); 5548 + eth_broadcast_addr(req->l2_addr_mask); 5549 + 5550 + if (fltr->l2_key.vlan) { 5551 + req->enables |= 5552 + cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_IVLAN | 5553 + CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_IVLAN_MASK | 5554 + CFA_L2_FILTER_ALLOC_REQ_ENABLES_NUM_VLANS); 5555 + req->num_vlans = 1; 5556 + req->l2_ivlan = cpu_to_le16(fltr->l2_key.vlan); 5557 + req->l2_ivlan_mask = cpu_to_le16(0xfff); 5558 + } 5559 + 5560 + resp = hwrm_req_hold(bp, req); 5561 + rc = hwrm_req_send(bp, req); 5562 + if (!rc) { 5563 + fltr->base.filter_id = resp->l2_filter_id; 5564 + set_bit(BNXT_FLTR_VALID, &fltr->base.state); 5565 + } 5566 + hwrm_req_drop(bp, req); 5567 + return rc; 5568 + } 5569 + 5570 + int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp, 5571 + struct bnxt_ntuple_filter *fltr) 5338 5572 { 5339 5573 struct hwrm_cfa_ntuple_filter_free_input *req; 5340 5574 int rc; 5341 5575 5576 + set_bit(BNXT_FLTR_FW_DELETED, &fltr->base.state); 5342 5577 rc = hwrm_req_init(bp, req, HWRM_CFA_NTUPLE_FILTER_FREE); 5343 5578 if (rc) 5344 5579 return rc; 5345 5580 5346 - req->ntuple_filter_id = fltr->filter_id; 5581 + req->ntuple_filter_id = fltr->base.filter_id; 5347 5582 return hwrm_req_send(bp, req); 5348 5583 } 5349 5584 5350 5585 #define BNXT_NTP_FLTR_FLAGS \ 5351 5586 (CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_L2_FILTER_ID | \ 5352 5587 CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_ETHERTYPE | \ 5353 - CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_MACADDR | \ 5354 5588 CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_IPADDR_TYPE | \ 5355 5589 CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_IPADDR | \ 5356 5590 CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_IPADDR_MASK | \ ··· 5642 5324 #define BNXT_NTP_TUNNEL_FLTR_FLAG \ 5643 5325 CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_TUNNEL_TYPE 5644 5326 5645 - static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp, 5646 - struct bnxt_ntuple_filter *fltr) 5327 + void bnxt_fill_ipv6_mask(__be32 mask[4]) 5328 + { 5329 + int i; 5330 + 5331 + for (i = 0; i < 4; i++) 5332 + mask[i] = cpu_to_be32(~0); 5333 + } 5334 + 5335 + int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp, 5336 + struct bnxt_ntuple_filter *fltr) 5647 5337 { 5648 5338 struct hwrm_cfa_ntuple_filter_alloc_output *resp; 5649 5339 struct hwrm_cfa_ntuple_filter_alloc_input *req; 5650 5340 struct flow_keys *keys = &fltr->fkeys; 5341 + struct bnxt_l2_filter *l2_fltr; 5651 5342 struct bnxt_vnic_info *vnic; 5652 5343 u32 flags = 0; 5653 5344 int rc; ··· 5665 5338 if (rc) 5666 5339 return rc; 5667 5340 5668 - req->l2_filter_id = bp->vnic_info[0].fw_l2_filter_id[fltr->l2_fltr_idx]; 5341 + l2_fltr = fltr->l2_fltr; 5342 + req->l2_filter_id = l2_fltr->base.filter_id; 5343 + 5669 5344 5670 5345 if (bp->fw_cap & BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V2) { 5671 5346 flags = CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_DEST_RFS_RING_IDX; 5672 - req->dst_id = cpu_to_le16(fltr->rxq); 5347 + req->dst_id = cpu_to_le16(fltr->base.rxq); 5673 5348 } else { 5674 - vnic = &bp->vnic_info[fltr->rxq + 1]; 5349 + vnic = &bp->vnic_info[fltr->base.rxq + 1]; 5675 5350 req->dst_id = cpu_to_le16(vnic->fw_vnic_id); 5676 5351 } 5677 5352 req->flags = cpu_to_le32(flags); 5678 5353 req->enables = cpu_to_le32(BNXT_NTP_FLTR_FLAGS); 5679 5354 5680 5355 req->ethertype = htons(ETH_P_IP); 5681 - memcpy(req->src_macaddr, fltr->src_mac_addr, ETH_ALEN); 5682 5356 req->ip_addr_type = CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV4; 5683 5357 req->ip_protocol = keys->basic.ip_proto; 5684 5358 5685 5359 if (keys->basic.n_proto == htons(ETH_P_IPV6)) { 5686 - int i; 5687 - 5688 5360 req->ethertype = htons(ETH_P_IPV6); 5689 5361 req->ip_addr_type = 5690 5362 CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV6; 5691 - *(struct in6_addr *)&req->src_ipaddr[0] = 5692 - keys->addrs.v6addrs.src; 5693 - *(struct in6_addr *)&req->dst_ipaddr[0] = 5694 - keys->addrs.v6addrs.dst; 5695 - for (i = 0; i < 4; i++) { 5696 - req->src_ipaddr_mask[i] = cpu_to_be32(0xffffffff); 5697 - req->dst_ipaddr_mask[i] = cpu_to_be32(0xffffffff); 5363 + if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) { 5364 + *(struct in6_addr *)&req->src_ipaddr[0] = 5365 + keys->addrs.v6addrs.src; 5366 + bnxt_fill_ipv6_mask(req->src_ipaddr_mask); 5367 + } 5368 + if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) { 5369 + *(struct in6_addr *)&req->dst_ipaddr[0] = 5370 + keys->addrs.v6addrs.dst; 5371 + bnxt_fill_ipv6_mask(req->dst_ipaddr_mask); 5698 5372 } 5699 5373 } else { 5700 - req->src_ipaddr[0] = keys->addrs.v4addrs.src; 5701 - req->src_ipaddr_mask[0] = cpu_to_be32(0xffffffff); 5702 - req->dst_ipaddr[0] = keys->addrs.v4addrs.dst; 5703 - req->dst_ipaddr_mask[0] = cpu_to_be32(0xffffffff); 5374 + if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) { 5375 + req->src_ipaddr[0] = keys->addrs.v4addrs.src; 5376 + req->src_ipaddr_mask[0] = cpu_to_be32(0xffffffff); 5377 + } 5378 + if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) { 5379 + req->dst_ipaddr[0] = keys->addrs.v4addrs.dst; 5380 + req->dst_ipaddr_mask[0] = cpu_to_be32(0xffffffff); 5381 + } 5704 5382 } 5705 5383 if (keys->control.flags & FLOW_DIS_ENCAPSULATION) { 5706 5384 req->enables |= cpu_to_le32(BNXT_NTP_TUNNEL_FLTR_FLAG); ··· 5713 5381 CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_ANYTUNNEL; 5714 5382 } 5715 5383 5716 - req->src_port = keys->ports.src; 5717 - req->src_port_mask = cpu_to_be16(0xffff); 5718 - req->dst_port = keys->ports.dst; 5719 - req->dst_port_mask = cpu_to_be16(0xffff); 5384 + if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_PORT) { 5385 + req->src_port = keys->ports.src; 5386 + req->src_port_mask = cpu_to_be16(0xffff); 5387 + } 5388 + if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_PORT) { 5389 + req->dst_port = keys->ports.dst; 5390 + req->dst_port_mask = cpu_to_be16(0xffff); 5391 + } 5720 5392 5721 5393 resp = hwrm_req_hold(bp, req); 5722 5394 rc = hwrm_req_send(bp, req); 5723 5395 if (!rc) 5724 - fltr->filter_id = resp->ntuple_filter_id; 5396 + fltr->base.filter_id = resp->ntuple_filter_id; 5725 5397 hwrm_req_drop(bp, req); 5726 5398 return rc; 5727 5399 } 5728 - #endif 5729 5400 5730 5401 static int bnxt_hwrm_set_vnic_filter(struct bnxt *bp, u16 vnic_id, u16 idx, 5731 5402 const u8 *mac_addr) 5732 5403 { 5733 - struct hwrm_cfa_l2_filter_alloc_output *resp; 5734 - struct hwrm_cfa_l2_filter_alloc_input *req; 5404 + struct bnxt_l2_filter *fltr; 5405 + struct bnxt_l2_key key; 5735 5406 int rc; 5736 5407 5737 - rc = hwrm_req_init(bp, req, HWRM_CFA_L2_FILTER_ALLOC); 5408 + ether_addr_copy(key.dst_mac_addr, mac_addr); 5409 + key.vlan = 0; 5410 + fltr = bnxt_alloc_l2_filter(bp, &key, GFP_KERNEL); 5411 + if (IS_ERR(fltr)) 5412 + return PTR_ERR(fltr); 5413 + 5414 + fltr->base.fw_vnic_id = bp->vnic_info[vnic_id].fw_vnic_id; 5415 + rc = bnxt_hwrm_l2_filter_alloc(bp, fltr); 5738 5416 if (rc) 5739 - return rc; 5740 - 5741 - req->flags = cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_FLAGS_PATH_RX); 5742 - if (!BNXT_CHIP_TYPE_NITRO_A0(bp)) 5743 - req->flags |= 5744 - cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_FLAGS_OUTERMOST); 5745 - req->dst_id = cpu_to_le16(bp->vnic_info[vnic_id].fw_vnic_id); 5746 - req->enables = 5747 - cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_ADDR | 5748 - CFA_L2_FILTER_ALLOC_REQ_ENABLES_DST_ID | 5749 - CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_ADDR_MASK); 5750 - memcpy(req->l2_addr, mac_addr, ETH_ALEN); 5751 - req->l2_addr_mask[0] = 0xff; 5752 - req->l2_addr_mask[1] = 0xff; 5753 - req->l2_addr_mask[2] = 0xff; 5754 - req->l2_addr_mask[3] = 0xff; 5755 - req->l2_addr_mask[4] = 0xff; 5756 - req->l2_addr_mask[5] = 0xff; 5757 - 5758 - resp = hwrm_req_hold(bp, req); 5759 - rc = hwrm_req_send(bp, req); 5760 - if (!rc) 5761 - bp->vnic_info[vnic_id].fw_l2_filter_id[idx] = 5762 - resp->l2_filter_id; 5763 - hwrm_req_drop(bp, req); 5417 + bnxt_del_l2_filter(bp, fltr); 5418 + else 5419 + bp->vnic_info[vnic_id].l2_filters[idx] = fltr; 5764 5420 return rc; 5765 5421 } 5766 5422 5767 5423 static int bnxt_hwrm_clear_vnic_filter(struct bnxt *bp) 5768 5424 { 5769 - struct hwrm_cfa_l2_filter_free_input *req; 5770 5425 u16 i, j, num_of_vnics = 1; /* only vnic 0 supported */ 5771 - int rc; 5426 + int rc = 0; 5772 5427 5773 5428 /* Any associated ntuple filters will also be cleared by firmware. */ 5774 - rc = hwrm_req_init(bp, req, HWRM_CFA_L2_FILTER_FREE); 5775 - if (rc) 5776 - return rc; 5777 - hwrm_req_hold(bp, req); 5778 5429 for (i = 0; i < num_of_vnics; i++) { 5779 5430 struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; 5780 5431 5781 5432 for (j = 0; j < vnic->uc_filter_count; j++) { 5782 - req->l2_filter_id = vnic->fw_l2_filter_id[j]; 5433 + struct bnxt_l2_filter *fltr = vnic->l2_filters[j]; 5783 5434 5784 - rc = hwrm_req_send(bp, req); 5435 + bnxt_hwrm_l2_filter_free(bp, fltr); 5436 + bnxt_del_l2_filter(bp, fltr); 5785 5437 } 5786 5438 vnic->uc_filter_count = 0; 5787 5439 } 5788 - hwrm_req_drop(bp, req); 5440 + 5789 5441 return rc; 5790 5442 } 5791 5443 ··· 9686 9370 9687 9371 static int bnxt_alloc_rfs_vnics(struct bnxt *bp) 9688 9372 { 9689 - #ifdef CONFIG_RFS_ACCEL 9690 9373 int i, rc = 0; 9691 9374 9692 9375 if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) ··· 9714 9399 break; 9715 9400 } 9716 9401 return rc; 9717 - #else 9718 - return 0; 9719 - #endif 9720 9402 } 9721 9403 9722 9404 /* Allow PF, trusted VFs and VFs with default VLAN to be in promiscuous mode */ ··· 10041 9729 return rc; 10042 9730 } 10043 9731 10044 - #ifdef CONFIG_RFS_ACCEL 10045 9732 static unsigned int bnxt_get_max_func_rss_ctxs(struct bnxt *bp) 10046 9733 { 10047 9734 return bp->hw_resc.max_rsscos_ctxs; ··· 10050 9739 { 10051 9740 return bp->hw_resc.max_vnics; 10052 9741 } 10053 - #endif 10054 9742 10055 9743 unsigned int bnxt_get_max_func_stat_ctxs(struct bnxt *bp) 10056 9744 { ··· 12052 11742 { 12053 11743 struct net_device *dev = bp->dev; 12054 11744 struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; 12055 - struct hwrm_cfa_l2_filter_free_input *req; 12056 11745 struct netdev_hw_addr *ha; 12057 11746 int i, off = 0, rc; 12058 11747 bool uc_update; ··· 12063 11754 if (!uc_update) 12064 11755 goto skip_uc; 12065 11756 12066 - rc = hwrm_req_init(bp, req, HWRM_CFA_L2_FILTER_FREE); 12067 - if (rc) 12068 - return rc; 12069 - hwrm_req_hold(bp, req); 12070 11757 for (i = 1; i < vnic->uc_filter_count; i++) { 12071 - req->l2_filter_id = vnic->fw_l2_filter_id[i]; 11758 + struct bnxt_l2_filter *fltr = vnic->l2_filters[i]; 12072 11759 12073 - rc = hwrm_req_send(bp, req); 11760 + bnxt_hwrm_l2_filter_free(bp, fltr); 11761 + bnxt_del_l2_filter(bp, fltr); 12074 11762 } 12075 - hwrm_req_drop(bp, req); 12076 11763 12077 11764 vnic->uc_filter_count = 1; 12078 11765 ··· 12163 11858 /* If runtime conditions support RFS */ 12164 11859 static bool bnxt_rfs_capable(struct bnxt *bp) 12165 11860 { 12166 - #ifdef CONFIG_RFS_ACCEL 12167 11861 int vnics, max_vnics, max_rss_ctxs; 12168 11862 12169 11863 if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) ··· 12198 11894 netdev_warn(bp->dev, "Unable to reserve resources to support NTUPLE filters.\n"); 12199 11895 bnxt_hwrm_reserve_rings(bp, 0, 0, 0, 0, 0, 1); 12200 11896 return false; 12201 - #else 12202 - return false; 12203 - #endif 12204 11897 } 12205 11898 12206 11899 static netdev_features_t bnxt_fix_features(struct net_device *dev, ··· 13860 13559 } 13861 13560 } 13862 13561 13863 - #ifdef CONFIG_RFS_ACCEL 13562 + u32 bnxt_get_ntp_filter_idx(struct bnxt *bp, struct flow_keys *fkeys, 13563 + const struct sk_buff *skb) 13564 + { 13565 + struct bnxt_vnic_info *vnic; 13566 + 13567 + if (skb) 13568 + return skb_get_hash_raw(skb) & BNXT_NTP_FLTR_HASH_MASK; 13569 + 13570 + vnic = &bp->vnic_info[0]; 13571 + return bnxt_toeplitz(bp, fkeys, (void *)vnic->rss_hash_key); 13572 + } 13573 + 13574 + int bnxt_insert_ntp_filter(struct bnxt *bp, struct bnxt_ntuple_filter *fltr, 13575 + u32 idx) 13576 + { 13577 + struct hlist_head *head; 13578 + int bit_id; 13579 + 13580 + spin_lock_bh(&bp->ntp_fltr_lock); 13581 + bit_id = bitmap_find_free_region(bp->ntp_fltr_bmap, BNXT_MAX_FLTR, 0); 13582 + if (bit_id < 0) { 13583 + spin_unlock_bh(&bp->ntp_fltr_lock); 13584 + return -ENOMEM; 13585 + } 13586 + 13587 + fltr->base.sw_id = (u16)bit_id; 13588 + fltr->base.type = BNXT_FLTR_TYPE_NTUPLE; 13589 + fltr->base.flags |= BNXT_ACT_RING_DST; 13590 + head = &bp->ntp_fltr_hash_tbl[idx]; 13591 + hlist_add_head_rcu(&fltr->base.hash, head); 13592 + set_bit(BNXT_FLTR_INSERTED, &fltr->base.state); 13593 + bp->ntp_fltr_count++; 13594 + spin_unlock_bh(&bp->ntp_fltr_lock); 13595 + return 0; 13596 + } 13597 + 13864 13598 static bool bnxt_fltr_match(struct bnxt_ntuple_filter *f1, 13865 13599 struct bnxt_ntuple_filter *f2) 13866 13600 { 13867 13601 struct flow_keys *keys1 = &f1->fkeys; 13868 13602 struct flow_keys *keys2 = &f2->fkeys; 13869 13603 13604 + if (f1->ntuple_flags != f2->ntuple_flags) 13605 + return false; 13606 + 13870 13607 if (keys1->basic.n_proto != keys2->basic.n_proto || 13871 13608 keys1->basic.ip_proto != keys2->basic.ip_proto) 13872 13609 return false; 13873 13610 13874 13611 if (keys1->basic.n_proto == htons(ETH_P_IP)) { 13875 - if (keys1->addrs.v4addrs.src != keys2->addrs.v4addrs.src || 13876 - keys1->addrs.v4addrs.dst != keys2->addrs.v4addrs.dst) 13612 + if (((f1->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) && 13613 + keys1->addrs.v4addrs.src != keys2->addrs.v4addrs.src) || 13614 + ((f1->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) && 13615 + keys1->addrs.v4addrs.dst != keys2->addrs.v4addrs.dst)) 13877 13616 return false; 13878 13617 } else { 13879 - if (memcmp(&keys1->addrs.v6addrs.src, &keys2->addrs.v6addrs.src, 13880 - sizeof(keys1->addrs.v6addrs.src)) || 13881 - memcmp(&keys1->addrs.v6addrs.dst, &keys2->addrs.v6addrs.dst, 13882 - sizeof(keys1->addrs.v6addrs.dst))) 13618 + if (((f1->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) && 13619 + memcmp(&keys1->addrs.v6addrs.src, 13620 + &keys2->addrs.v6addrs.src, 13621 + sizeof(keys1->addrs.v6addrs.src))) || 13622 + ((f1->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) && 13623 + memcmp(&keys1->addrs.v6addrs.dst, 13624 + &keys2->addrs.v6addrs.dst, 13625 + sizeof(keys1->addrs.v6addrs.dst)))) 13883 13626 return false; 13884 13627 } 13885 13628 13886 - if (keys1->ports.ports == keys2->ports.ports && 13887 - keys1->control.flags == keys2->control.flags && 13888 - ether_addr_equal(f1->src_mac_addr, f2->src_mac_addr) && 13889 - ether_addr_equal(f1->dst_mac_addr, f2->dst_mac_addr)) 13629 + if (((f1->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_PORT) && 13630 + keys1->ports.src != keys2->ports.src) || 13631 + ((f1->ntuple_flags & BNXT_NTUPLE_MATCH_DST_PORT) && 13632 + keys1->ports.dst != keys2->ports.dst)) 13633 + return false; 13634 + 13635 + if (keys1->control.flags == keys2->control.flags && 13636 + f1->l2_fltr == f2->l2_fltr) 13890 13637 return true; 13891 13638 13892 13639 return false; 13893 13640 } 13894 13641 13642 + struct bnxt_ntuple_filter * 13643 + bnxt_lookup_ntp_filter_from_idx(struct bnxt *bp, 13644 + struct bnxt_ntuple_filter *fltr, u32 idx) 13645 + { 13646 + struct bnxt_ntuple_filter *f; 13647 + struct hlist_head *head; 13648 + 13649 + head = &bp->ntp_fltr_hash_tbl[idx]; 13650 + hlist_for_each_entry_rcu(f, head, base.hash) { 13651 + if (bnxt_fltr_match(f, fltr)) 13652 + return f; 13653 + } 13654 + return NULL; 13655 + } 13656 + 13657 + #ifdef CONFIG_RFS_ACCEL 13895 13658 static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, 13896 13659 u16 rxq_index, u32 flow_id) 13897 13660 { ··· 13963 13598 struct bnxt_ntuple_filter *fltr, *new_fltr; 13964 13599 struct flow_keys *fkeys; 13965 13600 struct ethhdr *eth = (struct ethhdr *)skb_mac_header(skb); 13966 - int rc = 0, idx, bit_id, l2_idx = 0; 13967 - struct hlist_head *head; 13601 + struct bnxt_l2_filter *l2_fltr; 13602 + int rc = 0, idx; 13968 13603 u32 flags; 13969 13604 13970 - if (!ether_addr_equal(dev->dev_addr, eth->h_dest)) { 13971 - struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; 13972 - int off = 0, j; 13605 + if (ether_addr_equal(dev->dev_addr, eth->h_dest)) { 13606 + l2_fltr = bp->vnic_info[0].l2_filters[0]; 13607 + atomic_inc(&l2_fltr->refcnt); 13608 + } else { 13609 + struct bnxt_l2_key key; 13973 13610 13974 - netif_addr_lock_bh(dev); 13975 - for (j = 0; j < vnic->uc_filter_count; j++, off += ETH_ALEN) { 13976 - if (ether_addr_equal(eth->h_dest, 13977 - vnic->uc_list + off)) { 13978 - l2_idx = j + 1; 13979 - break; 13980 - } 13981 - } 13982 - netif_addr_unlock_bh(dev); 13983 - if (!l2_idx) 13611 + ether_addr_copy(key.dst_mac_addr, eth->h_dest); 13612 + key.vlan = 0; 13613 + l2_fltr = bnxt_lookup_l2_filter_from_key(bp, &key); 13614 + if (!l2_fltr) 13984 13615 return -EINVAL; 13616 + if (l2_fltr->base.flags & BNXT_ACT_FUNC_DST) { 13617 + bnxt_del_l2_filter(bp, l2_fltr); 13618 + return -EINVAL; 13619 + } 13985 13620 } 13986 13621 new_fltr = kzalloc(sizeof(*new_fltr), GFP_ATOMIC); 13987 - if (!new_fltr) 13622 + if (!new_fltr) { 13623 + bnxt_del_l2_filter(bp, l2_fltr); 13988 13624 return -ENOMEM; 13625 + } 13989 13626 13990 13627 fkeys = &new_fltr->fkeys; 13991 13628 if (!skb_flow_dissect_flow_keys(skb, fkeys, 0)) { ··· 14014 13647 goto err_free; 14015 13648 } 14016 13649 14017 - memcpy(new_fltr->dst_mac_addr, eth->h_dest, ETH_ALEN); 14018 - memcpy(new_fltr->src_mac_addr, eth->h_source, ETH_ALEN); 13650 + new_fltr->l2_fltr = l2_fltr; 13651 + new_fltr->ntuple_flags = BNXT_NTUPLE_MATCH_ALL; 14019 13652 14020 - idx = skb_get_hash_raw(skb) & BNXT_NTP_FLTR_HASH_MASK; 14021 - head = &bp->ntp_fltr_hash_tbl[idx]; 13653 + idx = bnxt_get_ntp_filter_idx(bp, fkeys, skb); 14022 13654 rcu_read_lock(); 14023 - hlist_for_each_entry_rcu(fltr, head, hash) { 14024 - if (bnxt_fltr_match(fltr, new_fltr)) { 14025 - rc = fltr->sw_id; 14026 - rcu_read_unlock(); 14027 - goto err_free; 14028 - } 13655 + fltr = bnxt_lookup_ntp_filter_from_idx(bp, new_fltr, idx); 13656 + if (fltr) { 13657 + rcu_read_unlock(); 13658 + rc = fltr->base.sw_id; 13659 + goto err_free; 14029 13660 } 14030 13661 rcu_read_unlock(); 14031 13662 14032 - spin_lock_bh(&bp->ntp_fltr_lock); 14033 - bit_id = bitmap_find_free_region(bp->ntp_fltr_bmap, 14034 - BNXT_NTP_FLTR_MAX_FLTR, 0); 14035 - if (bit_id < 0) { 14036 - spin_unlock_bh(&bp->ntp_fltr_lock); 14037 - rc = -ENOMEM; 14038 - goto err_free; 13663 + new_fltr->flow_id = flow_id; 13664 + new_fltr->base.rxq = rxq_index; 13665 + rc = bnxt_insert_ntp_filter(bp, new_fltr, idx); 13666 + if (!rc) { 13667 + bnxt_queue_sp_work(bp, BNXT_RX_NTP_FLTR_SP_EVENT); 13668 + return new_fltr->base.sw_id; 14039 13669 } 14040 13670 14041 - new_fltr->sw_id = (u16)bit_id; 14042 - new_fltr->flow_id = flow_id; 14043 - new_fltr->l2_fltr_idx = l2_idx; 14044 - new_fltr->rxq = rxq_index; 14045 - hlist_add_head_rcu(&new_fltr->hash, head); 14046 - bp->ntp_fltr_count++; 14047 - spin_unlock_bh(&bp->ntp_fltr_lock); 14048 - 14049 - bnxt_queue_sp_work(bp, BNXT_RX_NTP_FLTR_SP_EVENT); 14050 - 14051 - return new_fltr->sw_id; 14052 - 14053 13671 err_free: 13672 + bnxt_del_l2_filter(bp, l2_fltr); 14054 13673 kfree(new_fltr); 14055 13674 return rc; 13675 + } 13676 + #endif 13677 + 13678 + void bnxt_del_ntp_filter(struct bnxt *bp, struct bnxt_ntuple_filter *fltr) 13679 + { 13680 + spin_lock_bh(&bp->ntp_fltr_lock); 13681 + if (!test_and_clear_bit(BNXT_FLTR_INSERTED, &fltr->base.state)) { 13682 + spin_unlock_bh(&bp->ntp_fltr_lock); 13683 + return; 13684 + } 13685 + hlist_del_rcu(&fltr->base.hash); 13686 + bp->ntp_fltr_count--; 13687 + spin_unlock_bh(&bp->ntp_fltr_lock); 13688 + bnxt_del_l2_filter(bp, fltr->l2_fltr); 13689 + clear_bit(fltr->base.sw_id, bp->ntp_fltr_bmap); 13690 + kfree_rcu(fltr, base.rcu); 14056 13691 } 14057 13692 14058 13693 static void bnxt_cfg_ntp_filters(struct bnxt *bp) ··· 14068 13699 int rc; 14069 13700 14070 13701 head = &bp->ntp_fltr_hash_tbl[i]; 14071 - hlist_for_each_entry_safe(fltr, tmp, head, hash) { 13702 + hlist_for_each_entry_safe(fltr, tmp, head, base.hash) { 14072 13703 bool del = false; 14073 13704 14074 - if (test_bit(BNXT_FLTR_VALID, &fltr->state)) { 14075 - if (rps_may_expire_flow(bp->dev, fltr->rxq, 13705 + if (test_bit(BNXT_FLTR_VALID, &fltr->base.state)) { 13706 + if (fltr->base.flags & BNXT_ACT_NO_AGING) 13707 + continue; 13708 + if (rps_may_expire_flow(bp->dev, fltr->base.rxq, 14076 13709 fltr->flow_id, 14077 - fltr->sw_id)) { 13710 + fltr->base.sw_id)) { 14078 13711 bnxt_hwrm_cfa_ntuple_filter_free(bp, 14079 13712 fltr); 14080 13713 del = true; ··· 14087 13716 if (rc) 14088 13717 del = true; 14089 13718 else 14090 - set_bit(BNXT_FLTR_VALID, &fltr->state); 13719 + set_bit(BNXT_FLTR_VALID, &fltr->base.state); 14091 13720 } 14092 13721 14093 - if (del) { 14094 - spin_lock_bh(&bp->ntp_fltr_lock); 14095 - hlist_del_rcu(&fltr->hash); 14096 - bp->ntp_fltr_count--; 14097 - spin_unlock_bh(&bp->ntp_fltr_lock); 14098 - synchronize_rcu(); 14099 - clear_bit(fltr->sw_id, bp->ntp_fltr_bmap); 14100 - kfree(fltr); 14101 - } 13722 + if (del) 13723 + bnxt_del_ntp_filter(bp, fltr); 14102 13724 } 14103 13725 } 14104 13726 if (test_and_clear_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event)) 14105 13727 netdev_info(bp->dev, "Receive PF driver unload event!\n"); 14106 13728 } 14107 - 14108 - #else 14109 - 14110 - static void bnxt_cfg_ntp_filters(struct bnxt *bp) 14111 - { 14112 - } 14113 - 14114 - #endif /* CONFIG_RFS_ACCEL */ 14115 13729 14116 13730 static int bnxt_udp_tunnel_set_port(struct net_device *netdev, unsigned int table, 14117 13731 unsigned int entry, struct udp_tunnel_info *ti) ··· 14256 13900 14257 13901 bnxt_ptp_clear(bp); 14258 13902 unregister_netdev(dev); 13903 + bnxt_free_l2_filters(bp, true); 13904 + bnxt_free_ntp_fltrs(bp, true); 14259 13905 clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); 14260 13906 /* Flush any pending tasks */ 14261 13907 cancel_work_sync(&bp->sp_task); ··· 14807 14449 if (rc) 14808 14450 goto init_err_pci_clean; 14809 14451 14452 + bnxt_init_l2_fltr_tbl(bp); 14810 14453 bnxt_set_rx_skb_mode(bp, false); 14811 14454 bnxt_set_tpa_flags(bp); 14812 14455 bnxt_set_ring_params(bp);
+84 -8
drivers/net/ethernet/broadcom/bnxt/bnxt.h
··· 1219 1219 u16 fw_rss_cos_lb_ctx[BNXT_MAX_CTX_PER_VNIC]; 1220 1220 u16 fw_l2_ctx_id; 1221 1221 #define BNXT_MAX_UC_ADDRS 4 1222 - __le64 fw_l2_filter_id[BNXT_MAX_UC_ADDRS]; 1222 + struct bnxt_l2_filter *l2_filters[BNXT_MAX_UC_ADDRS]; 1223 1223 /* index 0 always dev_addr */ 1224 1224 u16 uc_filter_count; 1225 1225 u8 *uc_list; ··· 1332 1332 struct bnxt_vf_info *vf; 1333 1333 }; 1334 1334 1335 - struct bnxt_ntuple_filter { 1335 + struct bnxt_filter_base { 1336 1336 struct hlist_node hash; 1337 - u8 dst_mac_addr[ETH_ALEN]; 1338 - u8 src_mac_addr[ETH_ALEN]; 1339 - struct flow_keys fkeys; 1340 1337 __le64 filter_id; 1338 + u8 type; 1339 + #define BNXT_FLTR_TYPE_NTUPLE 1 1340 + #define BNXT_FLTR_TYPE_L2 2 1341 + u8 flags; 1342 + #define BNXT_ACT_DROP 1 1343 + #define BNXT_ACT_RING_DST 2 1344 + #define BNXT_ACT_FUNC_DST 4 1345 + #define BNXT_ACT_NO_AGING 8 1341 1346 u16 sw_id; 1342 - u8 l2_fltr_idx; 1343 1347 u16 rxq; 1344 - u32 flow_id; 1348 + u16 fw_vnic_id; 1349 + u16 vf_idx; 1345 1350 unsigned long state; 1346 1351 #define BNXT_FLTR_VALID 0 1347 - #define BNXT_FLTR_UPDATE 1 1352 + #define BNXT_FLTR_INSERTED 1 1353 + #define BNXT_FLTR_FW_DELETED 2 1354 + 1355 + struct rcu_head rcu; 1356 + }; 1357 + 1358 + struct bnxt_ntuple_filter { 1359 + struct bnxt_filter_base base; 1360 + struct flow_keys fkeys; 1361 + struct bnxt_l2_filter *l2_fltr; 1362 + u32 ntuple_flags; 1363 + #define BNXT_NTUPLE_MATCH_SRC_IP 1 1364 + #define BNXT_NTUPLE_MATCH_DST_IP 2 1365 + #define BNXT_NTUPLE_MATCH_SRC_PORT 4 1366 + #define BNXT_NTUPLE_MATCH_DST_PORT 8 1367 + #define BNXT_NTUPLE_MATCH_ALL (BNXT_NTUPLE_MATCH_SRC_IP | \ 1368 + BNXT_NTUPLE_MATCH_DST_IP | \ 1369 + BNXT_NTUPLE_MATCH_SRC_PORT | \ 1370 + BNXT_NTUPLE_MATCH_DST_PORT) 1371 + u32 flow_id; 1372 + }; 1373 + 1374 + struct bnxt_l2_key { 1375 + union { 1376 + struct { 1377 + u8 dst_mac_addr[ETH_ALEN]; 1378 + u16 vlan; 1379 + }; 1380 + u32 filter_key; 1381 + }; 1382 + }; 1383 + 1384 + struct bnxt_ipv4_tuple { 1385 + struct flow_dissector_key_ipv4_addrs v4addrs; 1386 + struct flow_dissector_key_ports ports; 1387 + }; 1388 + 1389 + struct bnxt_ipv6_tuple { 1390 + struct flow_dissector_key_ipv6_addrs v6addrs; 1391 + struct flow_dissector_key_ports ports; 1392 + }; 1393 + 1394 + #define BNXT_L2_KEY_SIZE (sizeof(struct bnxt_l2_key) / 4) 1395 + 1396 + struct bnxt_l2_filter { 1397 + struct bnxt_filter_base base; 1398 + struct bnxt_l2_key l2_key; 1399 + atomic_t refcnt; 1348 1400 }; 1349 1401 1350 1402 struct bnxt_link_info { ··· 2419 2367 int db_size; 2420 2368 2421 2369 #define BNXT_NTP_FLTR_MAX_FLTR 4096 2370 + #define BNXT_MAX_FLTR (BNXT_NTP_FLTR_MAX_FLTR + BNXT_L2_FLTR_MAX_FLTR) 2422 2371 #define BNXT_NTP_FLTR_HASH_SIZE 512 2423 2372 #define BNXT_NTP_FLTR_HASH_MASK (BNXT_NTP_FLTR_HASH_SIZE - 1) 2424 2373 struct hlist_head ntp_fltr_hash_tbl[BNXT_NTP_FLTR_HASH_SIZE]; ··· 2427 2374 2428 2375 unsigned long *ntp_fltr_bmap; 2429 2376 int ntp_fltr_count; 2377 + 2378 + #define BNXT_L2_FLTR_MAX_FLTR 1024 2379 + #define BNXT_L2_FLTR_HASH_SIZE 32 2380 + #define BNXT_L2_FLTR_HASH_MASK (BNXT_L2_FLTR_HASH_SIZE - 1) 2381 + struct hlist_head l2_fltr_hash_tbl[BNXT_L2_FLTR_HASH_SIZE]; 2382 + 2383 + u32 hash_seed; 2384 + u64 toeplitz_prefix; 2430 2385 2431 2386 /* To protect link related settings during link changes and 2432 2387 * ethtool settings changes. ··· 2643 2582 int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap, 2644 2583 int bmap_size, bool async_only); 2645 2584 int bnxt_hwrm_func_drv_unrgtr(struct bnxt *bp); 2585 + void bnxt_del_l2_filter(struct bnxt *bp, struct bnxt_l2_filter *fltr); 2586 + int bnxt_hwrm_l2_filter_free(struct bnxt *bp, struct bnxt_l2_filter *fltr); 2587 + int bnxt_hwrm_l2_filter_alloc(struct bnxt *bp, struct bnxt_l2_filter *fltr); 2588 + int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp, 2589 + struct bnxt_ntuple_filter *fltr); 2590 + int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp, 2591 + struct bnxt_ntuple_filter *fltr); 2592 + void bnxt_fill_ipv6_mask(__be32 mask[4]); 2646 2593 int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings); 2647 2594 int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id); 2648 2595 int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings); ··· 2694 2625 int bnxt_fw_init_one(struct bnxt *bp); 2695 2626 bool bnxt_hwrm_reset_permitted(struct bnxt *bp); 2696 2627 int bnxt_setup_mq_tc(struct net_device *dev, u8 tc); 2628 + struct bnxt_ntuple_filter *bnxt_lookup_ntp_filter_from_idx(struct bnxt *bp, 2629 + struct bnxt_ntuple_filter *fltr, u32 idx); 2630 + u32 bnxt_get_ntp_filter_idx(struct bnxt *bp, struct flow_keys *fkeys, 2631 + const struct sk_buff *skb); 2632 + int bnxt_insert_ntp_filter(struct bnxt *bp, struct bnxt_ntuple_filter *fltr, 2633 + u32 idx); 2634 + void bnxt_del_ntp_filter(struct bnxt *bp, struct bnxt_ntuple_filter *fltr); 2697 2635 int bnxt_get_max_rings(struct bnxt *, int *, int *, bool); 2698 2636 int bnxt_restore_pf_fw_resources(struct bnxt *bp); 2699 2637 int bnxt_get_port_parent_id(struct net_device *dev,
+315 -60
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
··· 1011 1011 return rc; 1012 1012 } 1013 1013 1014 - #ifdef CONFIG_RFS_ACCEL 1014 + static u32 bnxt_get_all_fltr_ids_rcu(struct bnxt *bp, struct hlist_head tbl[], 1015 + int tbl_size, u32 *ids, u32 start, 1016 + u32 id_cnt) 1017 + { 1018 + int i, j = start; 1019 + 1020 + if (j >= id_cnt) 1021 + return j; 1022 + for (i = 0; i < tbl_size; i++) { 1023 + struct hlist_head *head; 1024 + struct bnxt_filter_base *fltr; 1025 + 1026 + head = &tbl[i]; 1027 + hlist_for_each_entry_rcu(fltr, head, hash) { 1028 + if (!fltr->flags || 1029 + test_bit(BNXT_FLTR_FW_DELETED, &fltr->state)) 1030 + continue; 1031 + ids[j++] = fltr->sw_id; 1032 + if (j == id_cnt) 1033 + return j; 1034 + } 1035 + } 1036 + return j; 1037 + } 1038 + 1039 + static struct bnxt_filter_base *bnxt_get_one_fltr_rcu(struct bnxt *bp, 1040 + struct hlist_head tbl[], 1041 + int tbl_size, u32 id) 1042 + { 1043 + int i; 1044 + 1045 + for (i = 0; i < tbl_size; i++) { 1046 + struct hlist_head *head; 1047 + struct bnxt_filter_base *fltr; 1048 + 1049 + head = &tbl[i]; 1050 + hlist_for_each_entry_rcu(fltr, head, hash) { 1051 + if (fltr->flags && fltr->sw_id == id) 1052 + return fltr; 1053 + } 1054 + } 1055 + return NULL; 1056 + } 1057 + 1015 1058 static int bnxt_grxclsrlall(struct bnxt *bp, struct ethtool_rxnfc *cmd, 1016 1059 u32 *rule_locs) 1017 1060 { 1018 - int i, j = 0; 1019 - 1020 1061 cmd->data = bp->ntp_fltr_count; 1021 - for (i = 0; i < BNXT_NTP_FLTR_HASH_SIZE; i++) { 1022 - struct hlist_head *head; 1023 - struct bnxt_ntuple_filter *fltr; 1062 + rcu_read_lock(); 1063 + cmd->rule_cnt = bnxt_get_all_fltr_ids_rcu(bp, bp->ntp_fltr_hash_tbl, 1064 + BNXT_NTP_FLTR_HASH_SIZE, 1065 + rule_locs, 0, cmd->rule_cnt); 1066 + rcu_read_unlock(); 1024 1067 1025 - head = &bp->ntp_fltr_hash_tbl[i]; 1026 - rcu_read_lock(); 1027 - hlist_for_each_entry_rcu(fltr, head, hash) { 1028 - if (j == cmd->rule_cnt) 1029 - break; 1030 - rule_locs[j++] = fltr->sw_id; 1031 - } 1032 - rcu_read_unlock(); 1033 - if (j == cmd->rule_cnt) 1034 - break; 1035 - } 1036 - cmd->rule_cnt = j; 1037 1068 return 0; 1038 1069 } 1039 1070 ··· 1072 1041 { 1073 1042 struct ethtool_rx_flow_spec *fs = 1074 1043 (struct ethtool_rx_flow_spec *)&cmd->fs; 1044 + struct bnxt_filter_base *fltr_base; 1075 1045 struct bnxt_ntuple_filter *fltr; 1076 1046 struct flow_keys *fkeys; 1077 - int i, rc = -EINVAL; 1047 + int rc = -EINVAL; 1078 1048 1079 1049 if (fs->location >= BNXT_NTP_FLTR_MAX_FLTR) 1080 1050 return rc; 1081 1051 1082 - for (i = 0; i < BNXT_NTP_FLTR_HASH_SIZE; i++) { 1083 - struct hlist_head *head; 1084 - 1085 - head = &bp->ntp_fltr_hash_tbl[i]; 1086 - rcu_read_lock(); 1087 - hlist_for_each_entry_rcu(fltr, head, hash) { 1088 - if (fltr->sw_id == fs->location) 1089 - goto fltr_found; 1090 - } 1052 + rcu_read_lock(); 1053 + fltr_base = bnxt_get_one_fltr_rcu(bp, bp->ntp_fltr_hash_tbl, 1054 + BNXT_NTP_FLTR_HASH_SIZE, 1055 + fs->location); 1056 + if (!fltr_base) { 1091 1057 rcu_read_unlock(); 1058 + return rc; 1092 1059 } 1093 - return rc; 1060 + fltr = container_of(fltr_base, struct bnxt_ntuple_filter, base); 1094 1061 1095 - fltr_found: 1096 1062 fkeys = &fltr->fkeys; 1097 1063 if (fkeys->basic.n_proto == htons(ETH_P_IP)) { 1098 1064 if (fkeys->basic.ip_proto == IPPROTO_TCP) ··· 1099 1071 else 1100 1072 goto fltr_err; 1101 1073 1102 - fs->h_u.tcp_ip4_spec.ip4src = fkeys->addrs.v4addrs.src; 1103 - fs->m_u.tcp_ip4_spec.ip4src = cpu_to_be32(~0); 1104 - 1105 - fs->h_u.tcp_ip4_spec.ip4dst = fkeys->addrs.v4addrs.dst; 1106 - fs->m_u.tcp_ip4_spec.ip4dst = cpu_to_be32(~0); 1107 - 1108 - fs->h_u.tcp_ip4_spec.psrc = fkeys->ports.src; 1109 - fs->m_u.tcp_ip4_spec.psrc = cpu_to_be16(~0); 1110 - 1111 - fs->h_u.tcp_ip4_spec.pdst = fkeys->ports.dst; 1112 - fs->m_u.tcp_ip4_spec.pdst = cpu_to_be16(~0); 1074 + if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) { 1075 + fs->h_u.tcp_ip4_spec.ip4src = fkeys->addrs.v4addrs.src; 1076 + fs->m_u.tcp_ip4_spec.ip4src = cpu_to_be32(~0); 1077 + } 1078 + if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) { 1079 + fs->h_u.tcp_ip4_spec.ip4dst = fkeys->addrs.v4addrs.dst; 1080 + fs->m_u.tcp_ip4_spec.ip4dst = cpu_to_be32(~0); 1081 + } 1082 + if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_PORT) { 1083 + fs->h_u.tcp_ip4_spec.psrc = fkeys->ports.src; 1084 + fs->m_u.tcp_ip4_spec.psrc = cpu_to_be16(~0); 1085 + } 1086 + if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_PORT) { 1087 + fs->h_u.tcp_ip4_spec.pdst = fkeys->ports.dst; 1088 + fs->m_u.tcp_ip4_spec.pdst = cpu_to_be16(~0); 1089 + } 1113 1090 } else { 1114 - int i; 1115 - 1116 1091 if (fkeys->basic.ip_proto == IPPROTO_TCP) 1117 1092 fs->flow_type = TCP_V6_FLOW; 1118 1093 else if (fkeys->basic.ip_proto == IPPROTO_UDP) ··· 1123 1092 else 1124 1093 goto fltr_err; 1125 1094 1126 - *(struct in6_addr *)&fs->h_u.tcp_ip6_spec.ip6src[0] = 1127 - fkeys->addrs.v6addrs.src; 1128 - *(struct in6_addr *)&fs->h_u.tcp_ip6_spec.ip6dst[0] = 1129 - fkeys->addrs.v6addrs.dst; 1130 - for (i = 0; i < 4; i++) { 1131 - fs->m_u.tcp_ip6_spec.ip6src[i] = cpu_to_be32(~0); 1132 - fs->m_u.tcp_ip6_spec.ip6dst[i] = cpu_to_be32(~0); 1095 + if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) { 1096 + *(struct in6_addr *)&fs->h_u.tcp_ip6_spec.ip6src[0] = 1097 + fkeys->addrs.v6addrs.src; 1098 + bnxt_fill_ipv6_mask(fs->m_u.tcp_ip6_spec.ip6src); 1133 1099 } 1134 - fs->h_u.tcp_ip6_spec.psrc = fkeys->ports.src; 1135 - fs->m_u.tcp_ip6_spec.psrc = cpu_to_be16(~0); 1136 - 1137 - fs->h_u.tcp_ip6_spec.pdst = fkeys->ports.dst; 1138 - fs->m_u.tcp_ip6_spec.pdst = cpu_to_be16(~0); 1100 + if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) { 1101 + *(struct in6_addr *)&fs->h_u.tcp_ip6_spec.ip6dst[0] = 1102 + fkeys->addrs.v6addrs.dst; 1103 + bnxt_fill_ipv6_mask(fs->m_u.tcp_ip6_spec.ip6dst); 1104 + } 1105 + if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_PORT) { 1106 + fs->h_u.tcp_ip6_spec.psrc = fkeys->ports.src; 1107 + fs->m_u.tcp_ip6_spec.psrc = cpu_to_be16(~0); 1108 + } 1109 + if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_PORT) { 1110 + fs->h_u.tcp_ip6_spec.pdst = fkeys->ports.dst; 1111 + fs->m_u.tcp_ip6_spec.pdst = cpu_to_be16(~0); 1112 + } 1139 1113 } 1140 1114 1141 - fs->ring_cookie = fltr->rxq; 1115 + fs->ring_cookie = fltr->base.rxq; 1142 1116 rc = 0; 1143 1117 1144 1118 fltr_err: ··· 1151 1115 1152 1116 return rc; 1153 1117 } 1154 - #endif 1118 + 1119 + #define IPV4_ALL_MASK ((__force __be32)~0) 1120 + #define L4_PORT_ALL_MASK ((__force __be16)~0) 1121 + 1122 + static bool ipv6_mask_is_full(__be32 mask[4]) 1123 + { 1124 + return (mask[0] & mask[1] & mask[2] & mask[3]) == IPV4_ALL_MASK; 1125 + } 1126 + 1127 + static bool ipv6_mask_is_zero(__be32 mask[4]) 1128 + { 1129 + return !(mask[0] | mask[1] | mask[2] | mask[3]); 1130 + } 1131 + 1132 + static int bnxt_add_ntuple_cls_rule(struct bnxt *bp, 1133 + struct ethtool_rx_flow_spec *fs) 1134 + { 1135 + u8 vf = ethtool_get_flow_spec_ring_vf(fs->ring_cookie); 1136 + u32 ring = ethtool_get_flow_spec_ring(fs->ring_cookie); 1137 + struct bnxt_ntuple_filter *new_fltr, *fltr; 1138 + struct bnxt_l2_filter *l2_fltr; 1139 + u32 flow_type = fs->flow_type; 1140 + struct flow_keys *fkeys; 1141 + u32 idx; 1142 + int rc; 1143 + 1144 + if (!bp->vnic_info) 1145 + return -EAGAIN; 1146 + 1147 + if ((flow_type & (FLOW_MAC_EXT | FLOW_EXT)) || vf) 1148 + return -EOPNOTSUPP; 1149 + 1150 + new_fltr = kzalloc(sizeof(*new_fltr), GFP_KERNEL); 1151 + if (!new_fltr) 1152 + return -ENOMEM; 1153 + 1154 + l2_fltr = bp->vnic_info[0].l2_filters[0]; 1155 + atomic_inc(&l2_fltr->refcnt); 1156 + new_fltr->l2_fltr = l2_fltr; 1157 + fkeys = &new_fltr->fkeys; 1158 + 1159 + rc = -EOPNOTSUPP; 1160 + switch (flow_type) { 1161 + case TCP_V4_FLOW: 1162 + case UDP_V4_FLOW: { 1163 + struct ethtool_tcpip4_spec *ip_spec = &fs->h_u.tcp_ip4_spec; 1164 + struct ethtool_tcpip4_spec *ip_mask = &fs->m_u.tcp_ip4_spec; 1165 + 1166 + fkeys->basic.ip_proto = IPPROTO_TCP; 1167 + if (flow_type == UDP_V4_FLOW) 1168 + fkeys->basic.ip_proto = IPPROTO_UDP; 1169 + fkeys->basic.n_proto = htons(ETH_P_IP); 1170 + 1171 + if (ip_mask->ip4src == IPV4_ALL_MASK) { 1172 + fkeys->addrs.v4addrs.src = ip_spec->ip4src; 1173 + new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_SRC_IP; 1174 + } else if (ip_mask->ip4src) { 1175 + goto ntuple_err; 1176 + } 1177 + if (ip_mask->ip4dst == IPV4_ALL_MASK) { 1178 + fkeys->addrs.v4addrs.dst = ip_spec->ip4dst; 1179 + new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_DST_IP; 1180 + } else if (ip_mask->ip4dst) { 1181 + goto ntuple_err; 1182 + } 1183 + 1184 + if (ip_mask->psrc == L4_PORT_ALL_MASK) { 1185 + fkeys->ports.src = ip_spec->psrc; 1186 + new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_SRC_PORT; 1187 + } else if (ip_mask->psrc) { 1188 + goto ntuple_err; 1189 + } 1190 + if (ip_mask->pdst == L4_PORT_ALL_MASK) { 1191 + fkeys->ports.dst = ip_spec->pdst; 1192 + new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_DST_PORT; 1193 + } else if (ip_mask->pdst) { 1194 + goto ntuple_err; 1195 + } 1196 + break; 1197 + } 1198 + case TCP_V6_FLOW: 1199 + case UDP_V6_FLOW: { 1200 + struct ethtool_tcpip6_spec *ip_spec = &fs->h_u.tcp_ip6_spec; 1201 + struct ethtool_tcpip6_spec *ip_mask = &fs->m_u.tcp_ip6_spec; 1202 + 1203 + fkeys->basic.ip_proto = IPPROTO_TCP; 1204 + if (flow_type == UDP_V6_FLOW) 1205 + fkeys->basic.ip_proto = IPPROTO_UDP; 1206 + fkeys->basic.n_proto = htons(ETH_P_IPV6); 1207 + 1208 + if (ipv6_mask_is_full(ip_mask->ip6src)) { 1209 + fkeys->addrs.v6addrs.src = 1210 + *(struct in6_addr *)&ip_spec->ip6src; 1211 + new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_SRC_IP; 1212 + } else if (!ipv6_mask_is_zero(ip_mask->ip6src)) { 1213 + goto ntuple_err; 1214 + } 1215 + if (ipv6_mask_is_full(ip_mask->ip6dst)) { 1216 + fkeys->addrs.v6addrs.dst = 1217 + *(struct in6_addr *)&ip_spec->ip6dst; 1218 + new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_DST_IP; 1219 + } else if (!ipv6_mask_is_zero(ip_mask->ip6dst)) { 1220 + goto ntuple_err; 1221 + } 1222 + 1223 + if (ip_mask->psrc == L4_PORT_ALL_MASK) { 1224 + fkeys->ports.src = ip_spec->psrc; 1225 + new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_SRC_PORT; 1226 + } else if (ip_mask->psrc) { 1227 + goto ntuple_err; 1228 + } 1229 + if (ip_mask->pdst == L4_PORT_ALL_MASK) { 1230 + fkeys->ports.dst = ip_spec->pdst; 1231 + new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_DST_PORT; 1232 + } else if (ip_mask->pdst) { 1233 + goto ntuple_err; 1234 + } 1235 + break; 1236 + } 1237 + default: 1238 + rc = -EOPNOTSUPP; 1239 + goto ntuple_err; 1240 + } 1241 + if (!new_fltr->ntuple_flags) 1242 + goto ntuple_err; 1243 + 1244 + idx = bnxt_get_ntp_filter_idx(bp, fkeys, NULL); 1245 + rcu_read_lock(); 1246 + fltr = bnxt_lookup_ntp_filter_from_idx(bp, new_fltr, idx); 1247 + if (fltr) { 1248 + rcu_read_unlock(); 1249 + rc = -EEXIST; 1250 + goto ntuple_err; 1251 + } 1252 + rcu_read_unlock(); 1253 + 1254 + new_fltr->base.rxq = ring; 1255 + new_fltr->base.flags = BNXT_ACT_NO_AGING; 1256 + __set_bit(BNXT_FLTR_VALID, &new_fltr->base.state); 1257 + rc = bnxt_insert_ntp_filter(bp, new_fltr, idx); 1258 + if (!rc) { 1259 + rc = bnxt_hwrm_cfa_ntuple_filter_alloc(bp, new_fltr); 1260 + if (rc) { 1261 + bnxt_del_ntp_filter(bp, new_fltr); 1262 + return rc; 1263 + } 1264 + fs->location = new_fltr->base.sw_id; 1265 + return 0; 1266 + } 1267 + 1268 + ntuple_err: 1269 + atomic_dec(&l2_fltr->refcnt); 1270 + kfree(new_fltr); 1271 + return rc; 1272 + } 1273 + 1274 + static int bnxt_srxclsrlins(struct bnxt *bp, struct ethtool_rxnfc *cmd) 1275 + { 1276 + struct ethtool_rx_flow_spec *fs = &cmd->fs; 1277 + u32 ring, flow_type; 1278 + int rc; 1279 + u8 vf; 1280 + 1281 + if (!netif_running(bp->dev)) 1282 + return -EAGAIN; 1283 + if (!(bp->flags & BNXT_FLAG_RFS)) 1284 + return -EPERM; 1285 + if (fs->location != RX_CLS_LOC_ANY) 1286 + return -EINVAL; 1287 + 1288 + ring = ethtool_get_flow_spec_ring(fs->ring_cookie); 1289 + vf = ethtool_get_flow_spec_ring_vf(fs->ring_cookie); 1290 + if (BNXT_VF(bp) && vf) 1291 + return -EINVAL; 1292 + if (BNXT_PF(bp) && vf > bp->pf.active_vfs) 1293 + return -EINVAL; 1294 + if (!vf && ring >= bp->rx_nr_rings) 1295 + return -EINVAL; 1296 + 1297 + flow_type = fs->flow_type; 1298 + if (flow_type & (FLOW_MAC_EXT | FLOW_RSS)) 1299 + return -EINVAL; 1300 + flow_type &= ~FLOW_EXT; 1301 + if (flow_type == ETHER_FLOW) 1302 + rc = -EOPNOTSUPP; 1303 + else 1304 + rc = bnxt_add_ntuple_cls_rule(bp, fs); 1305 + return rc; 1306 + } 1307 + 1308 + static int bnxt_srxclsrldel(struct bnxt *bp, struct ethtool_rxnfc *cmd) 1309 + { 1310 + struct ethtool_rx_flow_spec *fs = &cmd->fs; 1311 + struct bnxt_filter_base *fltr_base; 1312 + 1313 + rcu_read_lock(); 1314 + fltr_base = bnxt_get_one_fltr_rcu(bp, bp->ntp_fltr_hash_tbl, 1315 + BNXT_NTP_FLTR_HASH_SIZE, 1316 + fs->location); 1317 + if (fltr_base) { 1318 + struct bnxt_ntuple_filter *fltr; 1319 + 1320 + fltr = container_of(fltr_base, struct bnxt_ntuple_filter, base); 1321 + rcu_read_unlock(); 1322 + if (!(fltr->base.flags & BNXT_ACT_NO_AGING)) 1323 + return -EINVAL; 1324 + bnxt_hwrm_cfa_ntuple_filter_free(bp, fltr); 1325 + bnxt_del_ntp_filter(bp, fltr); 1326 + return 0; 1327 + } 1328 + 1329 + rcu_read_unlock(); 1330 + return -ENOENT; 1331 + } 1155 1332 1156 1333 static u64 get_ethtool_ipv4_rss(struct bnxt *bp) 1157 1334 { ··· 1514 1265 int rc = 0; 1515 1266 1516 1267 switch (cmd->cmd) { 1517 - #ifdef CONFIG_RFS_ACCEL 1518 1268 case ETHTOOL_GRXRINGS: 1519 1269 cmd->data = bp->rx_nr_rings; 1520 1270 break; 1521 1271 1522 1272 case ETHTOOL_GRXCLSRLCNT: 1523 1273 cmd->rule_cnt = bp->ntp_fltr_count; 1524 - cmd->data = BNXT_NTP_FLTR_MAX_FLTR; 1274 + cmd->data = BNXT_NTP_FLTR_MAX_FLTR | RX_CLS_LOC_SPECIAL; 1525 1275 break; 1526 1276 1527 1277 case ETHTOOL_GRXCLSRLALL: ··· 1530 1282 case ETHTOOL_GRXCLSRULE: 1531 1283 rc = bnxt_grxclsrule(bp, cmd); 1532 1284 break; 1533 - #endif 1534 1285 1535 1286 case ETHTOOL_GRXFH: 1536 1287 rc = bnxt_grxfh(bp, cmd); ··· 1551 1304 switch (cmd->cmd) { 1552 1305 case ETHTOOL_SRXFH: 1553 1306 rc = bnxt_srxfh(bp, cmd); 1307 + break; 1308 + 1309 + case ETHTOOL_SRXCLSRLINS: 1310 + rc = bnxt_srxclsrlins(bp, cmd); 1311 + break; 1312 + 1313 + case ETHTOOL_SRXCLSRLDEL: 1314 + rc = bnxt_srxclsrldel(bp, cmd); 1554 1315 break; 1555 1316 1556 1317 default: