X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fcxgbe%2Fmps_tcam.c;h=abbf06e1a1b88e2a57a3c951ff4ac992ec48c559;hb=9fda31c3229ca6e036cae80392578ed6e5a51119;hp=02ec69a9228e22846ce19d44cad822f3ca098787;hpb=6fda3f0ddda9127c8562e724e3abc0f808c0bfd5;p=dpdk.git diff --git a/drivers/net/cxgbe/mps_tcam.c b/drivers/net/cxgbe/mps_tcam.c index 02ec69a922..abbf06e1a1 100644 --- a/drivers/net/cxgbe/mps_tcam.c +++ b/drivers/net/cxgbe/mps_tcam.c @@ -8,8 +8,8 @@ static inline bool match_entry(struct mps_tcam_entry *entry, const u8 *eth_addr, const u8 *mask) { - if (!memcmp(eth_addr, entry->eth_addr, ETHER_ADDR_LEN) && - !memcmp(mask, entry->mask, ETHER_ADDR_LEN)) + if (!memcmp(eth_addr, entry->eth_addr, RTE_ETHER_ADDR_LEN) && + !memcmp(mask, entry->mask, RTE_ETHER_ADDR_LEN)) return true; return false; } @@ -49,7 +49,8 @@ cxgbe_mpstcam_lookup(struct mpstcam_table *t, const u8 *eth_addr, return NULL; for (i = 0; i < t->size; i++) { - if (entry[i].state == MPS_ENTRY_UNUSED) + if (entry[i].state == MPS_ENTRY_UNUSED || + entry[i].state == MPS_ENTRY_RAWF) continue; /* entry is not being used */ if (match_entry(&entry[i], eth_addr, mask)) return &entry[i]; @@ -75,7 +76,7 @@ int cxgbe_mpstcam_alloc(struct port_info *pi, const u8 *eth_addr, t4_os_write_lock(&mpstcam->lock); entry = cxgbe_mpstcam_lookup(adap->mpstcam, eth_addr, mask); if (entry) { - rte_atomic32_add(&entry->refcnt, 1); + __atomic_add_fetch(&entry->refcnt, 1, __ATOMIC_RELAXED); t4_os_write_unlock(&mpstcam->lock); return entry->idx; } @@ -95,9 +96,9 @@ int cxgbe_mpstcam_alloc(struct port_info *pi, const u8 *eth_addr, /* Fill in the new values */ entry = &mpstcam->entry[ret]; - memcpy(entry->eth_addr, eth_addr, ETHER_ADDR_LEN); - memcpy(entry->mask, mask, ETHER_ADDR_LEN); - rte_atomic32_set(&entry->refcnt, 1); + memcpy(entry->eth_addr, eth_addr, RTE_ETHER_ADDR_LEN); + memcpy(entry->mask, mask, RTE_ETHER_ADDR_LEN); + __atomic_store_n(&entry->refcnt, 1, __ATOMIC_RELAXED); entry->state = MPS_ENTRY_USED; if (cxgbe_update_free_idx(mpstcam)) @@ -139,13 +140,14 @@ int cxgbe_mpstcam_modify(struct port_info *pi, int idx, const u8 *addr) /* idx can now be different from what user provided */ entry = &mpstcam->entry[idx]; - memcpy(entry->eth_addr, addr, ETHER_ADDR_LEN); + memcpy(entry->eth_addr, addr, RTE_ETHER_ADDR_LEN); + memset(entry->mask, ~0, RTE_ETHER_ADDR_LEN); /* NOTE: we have considered the case that idx returned by t4_change_mac * will be different from the user provided value only if user * provided value is -1 */ if (entry->state == MPS_ENTRY_UNUSED) { - rte_atomic32_set(&entry->refcnt, 1); + __atomic_store_n(&entry->refcnt, 1, __ATOMIC_RELAXED); entry->state = MPS_ENTRY_USED; } @@ -161,9 +163,9 @@ int cxgbe_mpstcam_modify(struct port_info *pi, int idx, const u8 *addr) */ static inline void reset_mpstcam_entry(struct mps_tcam_entry *entry) { - memset(entry->eth_addr, 0, ETHER_ADDR_LEN); - memset(entry->mask, 0, ETHER_ADDR_LEN); - rte_atomic32_clear(&entry->refcnt); + memset(entry->eth_addr, 0, RTE_ETHER_ADDR_LEN); + memset(entry->mask, 0, RTE_ETHER_ADDR_LEN); + __atomic_store_n(&entry->refcnt, 0, __ATOMIC_RELAXED); entry->state = MPS_ENTRY_UNUSED; } @@ -183,17 +185,17 @@ int cxgbe_mpstcam_remove(struct port_info *pi, u16 idx) return -EOPNOTSUPP; t4_os_write_lock(&t->lock); entry = &t->entry[idx]; - if (entry->state == MPS_ENTRY_UNUSED) { + if (entry->state != MPS_ENTRY_USED) { t4_os_write_unlock(&t->lock); return -EINVAL; } - if (rte_atomic32_read(&entry->refcnt) == 1) + if (__atomic_load_n(&entry->refcnt, __ATOMIC_RELAXED) == 1) ret = t4_free_raw_mac_filt(adap, pi->viid, entry->eth_addr, entry->mask, idx, 1, pi->port_id, false); else - ret = rte_atomic32_sub_return(&entry->refcnt, 1); + ret = __atomic_sub_fetch(&entry->refcnt, 1, __ATOMIC_RELAXED); if (ret == 0) { reset_mpstcam_entry(entry); @@ -205,11 +207,73 @@ int cxgbe_mpstcam_remove(struct port_info *pi, u16 idx) return ret; } +int cxgbe_mpstcam_rawf_enable(struct port_info *pi) +{ + struct adapter *adap = pi->adapter; + struct mps_tcam_entry *entry; + struct mpstcam_table *t; + u16 rawf_idx; + int ret = 0; + + t = adap->mpstcam; + if (adap->params.rawf_size == 0 || t == NULL) + return -EOPNOTSUPP; + + t4_os_write_lock(&t->lock); + rawf_idx = adap->params.rawf_start + pi->port_id; + entry = &t->entry[rawf_idx]; + if (__atomic_load_n(&entry->refcnt, __ATOMIC_RELAXED) == 1) + goto out_unlock; + + ret = t4_alloc_raw_mac_filt(adap, pi->viid, entry->eth_addr, + entry->mask, rawf_idx, 0, pi->port_id, + false); + if (ret < 0) + goto out_unlock; + + __atomic_store_n(&entry->refcnt, 1, __ATOMIC_RELAXED); + +out_unlock: + t4_os_write_unlock(&t->lock); + return ret; +} + +int cxgbe_mpstcam_rawf_disable(struct port_info *pi) +{ + struct adapter *adap = pi->adapter; + struct mps_tcam_entry *entry; + struct mpstcam_table *t; + u16 rawf_idx; + int ret = 0; + + t = adap->mpstcam; + if (adap->params.rawf_size == 0 || t == NULL) + return -EOPNOTSUPP; + + t4_os_write_lock(&t->lock); + rawf_idx = adap->params.rawf_start + pi->port_id; + entry = &t->entry[rawf_idx]; + if (__atomic_load_n(&entry->refcnt, __ATOMIC_RELAXED) != 1) + goto out_unlock; + + ret = t4_free_raw_mac_filt(adap, pi->viid, entry->eth_addr, + entry->mask, rawf_idx, 0, pi->port_id, + false); + if (ret < 0) + goto out_unlock; + + __atomic_store_n(&entry->refcnt, 0, __ATOMIC_RELAXED); + +out_unlock: + t4_os_write_unlock(&t->lock); + return ret; +} + struct mpstcam_table *t4_init_mpstcam(struct adapter *adap) { + u16 size = adap->params.arch.mps_tcam_size; struct mpstcam_table *t; int i; - u16 size = adap->params.arch.mps_tcam_size; t = t4_os_alloc(sizeof(*t) + size * sizeof(struct mps_tcam_entry)); if (!t) @@ -225,6 +289,12 @@ struct mpstcam_table *t4_init_mpstcam(struct adapter *adap) t->entry[i].idx = i; } + /* RAW MAC entries are reserved for match-all wildcard to + * match all promiscuous traffic. So, mark them special. + */ + for (i = 0; i < adap->params.rawf_size; i++) + t->entry[adap->params.rawf_start + i].state = MPS_ENTRY_RAWF; + /* first entry is used by chip. this is overwritten only * in t4_cleanup_mpstcam() */ @@ -236,8 +306,6 @@ struct mpstcam_table *t4_init_mpstcam(struct adapter *adap) void t4_cleanup_mpstcam(struct adapter *adap) { - if (adap->mpstcam) { - t4_os_free(adap->mpstcam->entry); + if (adap->mpstcam) t4_os_free(adap->mpstcam); - } }