X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fenic%2Fbase%2Fvnic_dev.c;h=aaca07ca67e546f49c8dc45dd6068af1c312f8da;hb=57ddbf7edd9c5041603e224fbbb62c11ce423135;hp=8e190687d2180e75daaef780b9856cb446fa2462;hpb=d74111a9a1e64688208a41c487ee9908d920f20a;p=dpdk.git diff --git a/drivers/net/enic/base/vnic_dev.c b/drivers/net/enic/base/vnic_dev.c index 8e190687d2..aaca07ca67 100644 --- a/drivers/net/enic/base/vnic_dev.c +++ b/drivers/net/enic/base/vnic_dev.c @@ -6,12 +6,14 @@ #include #include #include +#include #include "vnic_dev.h" #include "vnic_resource.h" #include "vnic_devcmd.h" #include "vnic_nic.h" #include "vnic_stats.h" +#include "vnic_flowman.h" enum vnic_proxy_type { @@ -27,9 +29,9 @@ struct vnic_res { }; struct vnic_intr_coal_timer_info { - u32 mul; - u32 div; - u32 max_usec; + uint32_t mul; + uint32_t div; + uint32_t max_usec; }; struct vnic_dev { @@ -41,22 +43,34 @@ struct vnic_dev { struct vnic_devcmd_notify *notify; struct vnic_devcmd_notify notify_copy; dma_addr_t notify_pa; - u32 notify_sz; + uint32_t notify_sz; dma_addr_t linkstatus_pa; struct vnic_stats *stats; dma_addr_t stats_pa; struct vnic_devcmd_fw_info *fw_info; dma_addr_t fw_info_pa; + struct fm_info *flowman_info; + dma_addr_t flowman_info_pa; enum vnic_proxy_type proxy; - u32 proxy_index; - u64 args[VNIC_DEVCMD_NARGS]; + uint32_t proxy_index; + uint64_t args[VNIC_DEVCMD_NARGS]; int in_reset; struct vnic_intr_coal_timer_info intr_coal_timer_info; void *(*alloc_consistent)(void *priv, size_t size, - dma_addr_t *dma_handle, u8 *name); + dma_addr_t *dma_handle, uint8_t *name); void (*free_consistent)(void *priv, size_t size, void *vaddr, dma_addr_t dma_handle); + /* + * Used to serialize devcmd access, currently from PF and its + * VF representors. When there are no representors, lock is + * not used. + */ + int locked; + void (*lock)(void *priv); + void (*unlock)(void *priv); + struct vnic_dev *pf_vdev; + int vf_id; }; #define VNIC_MAX_RES_HDR_SIZE \ @@ -71,7 +85,7 @@ void *vnic_dev_priv(struct vnic_dev *vdev) void vnic_register_cbacks(struct vnic_dev *vdev, void *(*alloc_consistent)(void *priv, size_t size, - dma_addr_t *dma_handle, u8 *name), + dma_addr_t *dma_handle, uint8_t *name), void (*free_consistent)(void *priv, size_t size, void *vaddr, dma_addr_t dma_handle)) @@ -80,13 +94,21 @@ void vnic_register_cbacks(struct vnic_dev *vdev, vdev->free_consistent = free_consistent; } +void vnic_register_lock(struct vnic_dev *vdev, void (*lock)(void *priv), + void (*unlock)(void *priv)) +{ + vdev->lock = lock; + vdev->unlock = unlock; + vdev->locked = 0; +} + static int vnic_dev_discover_res(struct vnic_dev *vdev, struct vnic_dev_bar *bar, unsigned int num_bars) { struct vnic_resource_header __iomem *rh; struct mgmt_barmap_hdr __iomem *mrh; struct vnic_resource __iomem *r; - u8 type; + uint8_t type; if (num_bars == 0) return -EINVAL; @@ -124,10 +146,10 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev, while ((type = ioread8(&r->type)) != RES_TYPE_EOL) { - u8 bar_num = ioread8(&r->bar); - u32 bar_offset = ioread32(&r->bar_offset); - u32 count = ioread32(&r->count); - u32 len; + uint8_t bar_num = ioread8(&r->bar); + uint32_t bar_offset = ioread32(&r->bar_offset); + uint32_t count = ioread32(&r->count); + uint32_t len; r++; @@ -230,7 +252,7 @@ void vnic_dev_clear_desc_ring(struct vnic_dev_ring *ring) int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring, unsigned int desc_count, unsigned int desc_size, - __attribute__((unused)) unsigned int socket_id, + __rte_unused unsigned int socket_id, char *z_name) { void *alloc_addr; @@ -239,7 +261,7 @@ int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, vnic_dev_desc_ring_size(ring, desc_count, desc_size); alloc_addr = vdev->alloc_consistent(vdev->priv, ring->size_unaligned, - &alloc_pa, (u8 *)z_name); + &alloc_pa, (uint8_t *)z_name); if (!alloc_addr) { pr_err("Failed to allocate ring (size=%d), aborting\n", (int)ring->size); @@ -259,7 +281,7 @@ int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, ring->base_addr = VNIC_ALIGN(ring->base_addr_unaligned, ring->base_align); - ring->descs = (u8 *)ring->descs_unaligned + + ring->descs = (uint8_t *)ring->descs_unaligned + (ring->base_addr - ring->base_addr_unaligned); vnic_dev_clear_desc_ring(ring); @@ -269,7 +291,7 @@ int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, return 0; } -void vnic_dev_free_desc_ring(__attribute__((unused)) struct vnic_dev *vdev, +void vnic_dev_free_desc_ring(__rte_unused struct vnic_dev *vdev, struct vnic_dev_ring *ring) { if (ring->descs) { @@ -287,7 +309,7 @@ static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, struct vnic_devcmd __iomem *devcmd = vdev->devcmd; unsigned int i; int delay; - u32 status; + uint32_t status; int err; status = ioread32(&devcmd->status); @@ -304,7 +326,7 @@ static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, if (_CMD_DIR(cmd) & _CMD_DIR_WRITE) { for (i = 0; i < VNIC_DEVCMD_NARGS; i++) writeq(vdev->args[i], &devcmd->args[i]); - wmb(); /* complete all writes initiated till now */ + rte_wmb(); /* complete all writes initiated till now */ } iowrite32(cmd, &devcmd->cmd); @@ -314,7 +336,7 @@ static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, for (delay = 0; delay < wait; delay++) { - udelay(100); + usleep(100); status = ioread32(&devcmd->status); if (status == 0xFFFFFFFF) { @@ -325,7 +347,9 @@ static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, if (!(status & STAT_BUSY)) { if (status & STAT_ERROR) { err = -(int)readq(&devcmd->args[0]); - if (cmd != CMD_CAPABILITY) + if (cmd != CMD_CAPABILITY && + cmd != CMD_OVERLAY_OFFLOAD_CTRL && + cmd != CMD_GET_SUPP_FEATURE_VER) pr_err("Devcmd %d failed " \ "with error code %d\n", _CMD_N(cmd), err); @@ -333,7 +357,7 @@ static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, } if (_CMD_DIR(cmd) & _CMD_DIR_READ) { - rmb();/* finish all reads initiated till now */ + rte_rmb();/* finish all reads */ for (i = 0; i < VNIC_DEVCMD_NARGS; i++) vdev->args[i] = readq(&devcmd->args[i]); } @@ -348,9 +372,9 @@ static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, static int vnic_dev_cmd_proxy(struct vnic_dev *vdev, enum vnic_devcmd_cmd proxy_cmd, enum vnic_devcmd_cmd cmd, - u64 *args, int nargs, int wait) + uint64_t *args, int nargs, int wait) { - u32 status; + uint32_t status; int err; /* @@ -371,7 +395,7 @@ static int vnic_dev_cmd_proxy(struct vnic_dev *vdev, if (err) return err; - status = (u32)vdev->args[0]; + status = (uint32_t)vdev->args[0]; if (status & STAT_ERROR) { err = (int)vdev->args[1]; if (err != ERR_ECMDUNKNOWN || @@ -386,7 +410,7 @@ static int vnic_dev_cmd_proxy(struct vnic_dev *vdev, } static int vnic_dev_cmd_no_proxy(struct vnic_dev *vdev, - enum vnic_devcmd_cmd cmd, u64 *args, int nargs, int wait) + enum vnic_devcmd_cmd cmd, uint64_t *args, int nargs, int wait) { int err; @@ -404,12 +428,39 @@ static int vnic_dev_cmd_no_proxy(struct vnic_dev *vdev, return err; } +void vnic_dev_cmd_proxy_by_index_start(struct vnic_dev *vdev, uint16_t index) +{ + vdev->proxy = PROXY_BY_INDEX; + vdev->proxy_index = index; +} + +void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev) +{ + vdev->proxy = PROXY_NONE; + vdev->proxy_index = 0; +} + int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, - u64 *a0, u64 *a1, int wait) + uint64_t *a0, uint64_t *a1, int wait) { - u64 args[2]; + uint64_t args[2]; + bool vf_rep; + int vf_idx; int err; + vf_rep = false; + if (vdev->pf_vdev) { + vf_rep = true; + vf_idx = vdev->vf_id; + /* Everything below assumes PF vdev */ + vdev = vdev->pf_vdev; + } + if (vdev->lock) + vdev->lock(vdev->priv); + /* For VF representor, proxy devcmd to VF index */ + if (vf_rep) + vnic_dev_cmd_proxy_by_index_start(vdev, vf_idx); + args[0] = *a0; args[1] = *a1; memset(vdev->args, 0, sizeof(vdev->args)); @@ -429,6 +480,10 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, break; } + if (vf_rep) + vnic_dev_cmd_proxy_end(vdev); + if (vdev->unlock) + vdev->unlock(vdev->priv); if (err == 0) { *a0 = args[0]; *a1 = args[1]; @@ -438,36 +493,60 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, } int vnic_dev_cmd_args(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, - u64 *args, int nargs, int wait) + uint64_t *args, int nargs, int wait) { + bool vf_rep; + int vf_idx; + int err; + + vf_rep = false; + if (vdev->pf_vdev) { + vf_rep = true; + vf_idx = vdev->vf_id; + vdev = vdev->pf_vdev; + } + if (vdev->lock) + vdev->lock(vdev->priv); + if (vf_rep) + vnic_dev_cmd_proxy_by_index_start(vdev, vf_idx); + switch (vdev->proxy) { case PROXY_BY_INDEX: - return vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_INDEX, cmd, + err = vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_INDEX, cmd, args, nargs, wait); + break; case PROXY_BY_BDF: - return vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_BDF, cmd, + err = vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_BDF, cmd, args, nargs, wait); + break; case PROXY_NONE: default: - return vnic_dev_cmd_no_proxy(vdev, cmd, args, nargs, wait); + err = vnic_dev_cmd_no_proxy(vdev, cmd, args, nargs, wait); + break; } + + if (vf_rep) + vnic_dev_cmd_proxy_end(vdev); + if (vdev->unlock) + vdev->unlock(vdev->priv); + return err; } int vnic_dev_fw_info(struct vnic_dev *vdev, struct vnic_devcmd_fw_info **fw_info) { - char name[NAME_MAX]; - u64 a0, a1 = 0; + char name[RTE_MEMZONE_NAMESIZE]; + uint64_t a0, a1 = 0; int wait = 1000; int err = 0; - static u32 instance; + static uint32_t instance; if (!vdev->fw_info) { snprintf((char *)name, sizeof(name), "vnic_fw_info-%u", instance++); vdev->fw_info = vdev->alloc_consistent(vdev->priv, sizeof(struct vnic_devcmd_fw_info), - &vdev->fw_info_pa, (u8 *)name); + &vdev->fw_info_pa, (uint8_t *)name); if (!vdev->fw_info) return -ENOMEM; a0 = vdev->fw_info_pa; @@ -479,7 +558,7 @@ int vnic_dev_fw_info(struct vnic_dev *vdev, return err; } -static int vnic_dev_advanced_filters_cap(struct vnic_dev *vdev, u64 *args, +static int vnic_dev_advanced_filters_cap(struct vnic_dev *vdev, uint64_t *args, int nargs) { memset(args, 0, nargs * sizeof(*args)); @@ -490,18 +569,84 @@ static int vnic_dev_advanced_filters_cap(struct vnic_dev *vdev, u64 *args, int vnic_dev_capable_adv_filters(struct vnic_dev *vdev) { - u64 a0 = CMD_ADD_ADV_FILTER, a1 = 0; + uint64_t a0 = CMD_ADD_ADV_FILTER, a1 = 0; int wait = 1000; int err; err = vnic_dev_cmd(vdev, CMD_CAPABILITY, &a0, &a1, wait); if (err) return 0; - return (a1 >= (u32)FILTER_DPDK_1); + return (a1 >= (uint32_t)FILTER_DPDK_1); +} + +int vnic_dev_flowman_cmd(struct vnic_dev *vdev, uint64_t *args, int nargs) +{ + int wait = 1000; + + return vnic_dev_cmd_args(vdev, CMD_FLOW_MANAGER_OP, args, nargs, wait); +} + +static int vnic_dev_flowman_enable(struct vnic_dev *vdev, uint32_t *mode, + uint8_t *filter_actions) +{ + char name[RTE_MEMZONE_NAMESIZE]; + uint64_t args[3]; + uint64_t ops; + static uint32_t instance; + + /* flowman devcmd available? */ + if (!vnic_dev_capable(vdev, CMD_FLOW_MANAGER_OP)) + return 0; + /* Have the version we are using? */ + args[0] = FM_API_VERSION_QUERY; + if (vnic_dev_flowman_cmd(vdev, args, 1)) + return 0; + if ((args[0] & (1ULL << FM_VERSION)) == 0) + return 0; + /* Select the version */ + args[0] = FM_API_VERSION_SELECT; + args[1] = FM_VERSION; + if (vnic_dev_flowman_cmd(vdev, args, 2)) + return 0; + /* Can we get fm_info? */ + if (!vdev->flowman_info) { + snprintf((char *)name, sizeof(name), "vnic_fm_info-%u", + instance++); + vdev->flowman_info = vdev->alloc_consistent(vdev->priv, + sizeof(struct fm_info), + &vdev->flowman_info_pa, (uint8_t *)name); + if (!vdev->flowman_info) + return 0; + } + args[0] = FM_INFO_QUERY; + args[1] = vdev->flowman_info_pa; + args[2] = sizeof(struct fm_info); + if (vnic_dev_flowman_cmd(vdev, args, 3)) + return 0; + /* Have required operations? */ + ops = (1ULL << FMOP_END) | + (1ULL << FMOP_DROP) | + (1ULL << FMOP_RQ_STEER) | + (1ULL << FMOP_EXACT_MATCH) | + (1ULL << FMOP_MARK) | + (1ULL << FMOP_TAG) | + (1ULL << FMOP_EG_HAIRPIN) | + (1ULL << FMOP_ENCAP) | + (1ULL << FMOP_DECAP_NOSTRIP); + if ((vdev->flowman_info->fm_op_mask & ops) != ops) + return 0; + /* Good to use flowman now */ + *mode = FILTER_FLOWMAN; + *filter_actions = FILTER_ACTION_RQ_STEERING_FLAG | + FILTER_ACTION_FILTER_ID_FLAG | + FILTER_ACTION_COUNTER_FLAG | + FILTER_ACTION_DROP_FLAG; + return 1; } -/* Determine the "best" filtering mode VIC is capaible of. Returns one of 3 +/* Determine the "best" filtering mode VIC is capaible of. Returns one of 4 * value or 0 on error: + * FILTER_FLOWMAN- flowman api capable * FILTER_DPDK_1- advanced filters availabile * FILTER_USNIC_IP_FLAG - advanced filters but with the restriction that * the IP layer must explicitly specified. I.e. cannot have a UDP @@ -510,12 +655,16 @@ int vnic_dev_capable_adv_filters(struct vnic_dev *vdev) * all other filter types are not available. * Retrun true in filter_tags if supported */ -int vnic_dev_capable_filter_mode(struct vnic_dev *vdev, u32 *mode, - u8 *filter_actions) +int vnic_dev_capable_filter_mode(struct vnic_dev *vdev, uint32_t *mode, + uint8_t *filter_actions) { - u64 args[4]; + uint64_t args[4]; int err; - u32 max_level = 0; + uint32_t max_level = 0; + + /* If flowman is available, use it as it is the most capable API */ + if (vnic_dev_flowman_enable(vdev, mode, filter_actions)) + return 0; err = vnic_dev_advanced_filters_cap(vdev, args, 4); @@ -547,7 +696,7 @@ int vnic_dev_capable_filter_mode(struct vnic_dev *vdev, u32 *mode, } max_level = args[1]; parse_max_level: - if (max_level >= (u32)FILTER_USNIC_IP) + if (max_level >= (uint32_t)FILTER_USNIC_IP) *mode = FILTER_USNIC_IP; else *mode = FILTER_IPV4_5TUPLE; @@ -557,7 +706,7 @@ parse_max_level: void vnic_dev_capable_udp_rss_weak(struct vnic_dev *vdev, bool *cfg_chk, bool *weak) { - u64 a0 = CMD_NIC_CFG, a1 = 0; + uint64_t a0 = CMD_NIC_CFG, a1 = 0; int wait = 1000; int err; @@ -572,7 +721,7 @@ void vnic_dev_capable_udp_rss_weak(struct vnic_dev *vdev, bool *cfg_chk, int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd) { - u64 a0 = (u32)cmd, a1 = 0; + uint64_t a0 = (uint32_t)cmd, a1 = 0; int wait = 1000; int err; @@ -584,7 +733,7 @@ int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd) int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, size_t size, void *value) { - u64 a0, a1; + uint64_t a0, a1; int wait = 1000; int err; @@ -595,16 +744,16 @@ int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, size_t size, switch (size) { case 1: - *(u8 *)value = (u8)a0; + *(uint8_t *)value = (uint8_t)a0; break; case 2: - *(u16 *)value = (u16)a0; + *(uint16_t *)value = (uint16_t)a0; break; case 4: - *(u32 *)value = (u32)a0; + *(uint32_t *)value = (uint32_t)a0; break; case 8: - *(u64 *)value = a0; + *(uint64_t *)value = a0; break; default: BUG(); @@ -616,7 +765,7 @@ int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, size_t size, int vnic_dev_stats_clear(struct vnic_dev *vdev) { - u64 a0 = 0, a1 = 0; + uint64_t a0 = 0, a1 = 0; int wait = 1000; return vnic_dev_cmd(vdev, CMD_STATS_CLEAR, &a0, &a1, wait); @@ -624,7 +773,7 @@ int vnic_dev_stats_clear(struct vnic_dev *vdev) int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats) { - u64 a0, a1; + uint64_t a0, a1; int wait = 1000; if (!vdev->stats) @@ -639,7 +788,7 @@ int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats) int vnic_dev_close(struct vnic_dev *vdev) { - u64 a0 = 0, a1 = 0; + uint64_t a0 = 0, a1 = 0; int wait = 1000; return vnic_dev_cmd(vdev, CMD_CLOSE, &a0, &a1, wait); @@ -647,7 +796,7 @@ int vnic_dev_close(struct vnic_dev *vdev) int vnic_dev_enable_wait(struct vnic_dev *vdev) { - u64 a0 = 0, a1 = 0; + uint64_t a0 = 0, a1 = 0; int wait = 1000; if (vnic_dev_capable(vdev, CMD_ENABLE_WAIT)) @@ -658,7 +807,7 @@ int vnic_dev_enable_wait(struct vnic_dev *vdev) int vnic_dev_disable(struct vnic_dev *vdev) { - u64 a0 = 0, a1 = 0; + uint64_t a0 = 0, a1 = 0; int wait = 1000; return vnic_dev_cmd(vdev, CMD_DISABLE, &a0, &a1, wait); @@ -666,7 +815,7 @@ int vnic_dev_disable(struct vnic_dev *vdev) int vnic_dev_open(struct vnic_dev *vdev, int arg) { - u64 a0 = (u32)arg, a1 = 0; + uint64_t a0 = (uint32_t)arg, a1 = 0; int wait = 1000; return vnic_dev_cmd(vdev, CMD_OPEN, &a0, &a1, wait); @@ -674,7 +823,7 @@ int vnic_dev_open(struct vnic_dev *vdev, int arg) int vnic_dev_open_done(struct vnic_dev *vdev, int *done) { - u64 a0 = 0, a1 = 0; + uint64_t a0 = 0, a1 = 0; int wait = 1000; int err; @@ -689,21 +838,21 @@ int vnic_dev_open_done(struct vnic_dev *vdev, int *done) return 0; } -int vnic_dev_get_mac_addr(struct vnic_dev *vdev, u8 *mac_addr) +int vnic_dev_get_mac_addr(struct vnic_dev *vdev, uint8_t *mac_addr) { - u64 a0 = 0, a1 = 0; + uint64_t a0 = 0, a1 = 0; int wait = 1000; int err, i; - for (i = 0; i < ETH_ALEN; i++) + for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) mac_addr[i] = 0; err = vnic_dev_cmd(vdev, CMD_GET_MAC_ADDR, &a0, &a1, wait); if (err) return err; - for (i = 0; i < ETH_ALEN; i++) - mac_addr[i] = ((u8 *)&a0)[i]; + for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) + mac_addr[i] = ((uint8_t *)&a0)[i]; return 0; } @@ -711,7 +860,7 @@ int vnic_dev_get_mac_addr(struct vnic_dev *vdev, u8 *mac_addr) int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, int broadcast, int promisc, int allmulti) { - u64 a0, a1 = 0; + uint64_t a0, a1 = 0; int wait = 1000; int err; @@ -728,15 +877,15 @@ int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, return err; } -int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) +int vnic_dev_add_addr(struct vnic_dev *vdev, uint8_t *addr) { - u64 a0 = 0, a1 = 0; + uint64_t a0 = 0, a1 = 0; int wait = 1000; int err; int i; - for (i = 0; i < ETH_ALEN; i++) - ((u8 *)&a0)[i] = addr[i]; + for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) + ((uint8_t *)&a0)[i] = addr[i]; err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait); if (err) @@ -747,15 +896,15 @@ int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) return err; } -int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr) +int vnic_dev_del_addr(struct vnic_dev *vdev, uint8_t *addr) { - u64 a0 = 0, a1 = 0; + uint64_t a0 = 0, a1 = 0; int wait = 1000; int err; int i; - for (i = 0; i < ETH_ALEN; i++) - ((u8 *)&a0)[i] = addr[i]; + for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) + ((uint8_t *)&a0)[i] = addr[i]; err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait); if (err) @@ -767,9 +916,9 @@ int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr) } int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev, - u8 ig_vlan_rewrite_mode) + uint8_t ig_vlan_rewrite_mode) { - u64 a0 = ig_vlan_rewrite_mode, a1 = 0; + uint64_t a0 = ig_vlan_rewrite_mode, a1 = 0; int wait = 1000; if (vnic_dev_capable(vdev, CMD_IG_VLAN_REWRITE_MODE)) @@ -790,9 +939,9 @@ static inline int vnic_dev_in_reset(struct vnic_dev *vdev) } int vnic_dev_notify_setcmd(struct vnic_dev *vdev, - void *notify_addr, dma_addr_t notify_pa, u16 intr) + void *notify_addr, dma_addr_t notify_pa, uint16_t intr) { - u64 a0, a1; + uint64_t a0, a1; int wait = 1000; int r; @@ -802,23 +951,23 @@ int vnic_dev_notify_setcmd(struct vnic_dev *vdev, vdev->notify_pa = notify_pa; } - a0 = (u64)notify_pa; - a1 = ((u64)intr << 32) & 0x0000ffff00000000ULL; + a0 = (uint64_t)notify_pa; + a1 = ((uint64_t)intr << 32) & 0x0000ffff00000000ULL; a1 += sizeof(struct vnic_devcmd_notify); r = vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait); if (!vnic_dev_in_reset(vdev)) - vdev->notify_sz = (r == 0) ? (u32)a1 : 0; + vdev->notify_sz = (r == 0) ? (uint32_t)a1 : 0; return r; } -int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) +int vnic_dev_notify_set(struct vnic_dev *vdev, uint16_t intr) { void *notify_addr = NULL; dma_addr_t notify_pa = 0; - char name[NAME_MAX]; - static u32 instance; + char name[RTE_MEMZONE_NAMESIZE]; + static uint32_t instance; if (vdev->notify || vdev->notify_pa) { return vnic_dev_notify_setcmd(vdev, vdev->notify, @@ -829,7 +978,7 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) "vnic_notify-%u", instance++); notify_addr = vdev->alloc_consistent(vdev->priv, sizeof(struct vnic_devcmd_notify), - ¬ify_pa, (u8 *)name); + ¬ify_pa, (uint8_t *)name); if (!notify_addr) return -ENOMEM; } @@ -839,7 +988,7 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev) { - u64 a0, a1; + uint64_t a0, a1; int wait = 1000; int err; @@ -871,10 +1020,10 @@ int vnic_dev_notify_unset(struct vnic_dev *vdev) static int vnic_dev_notify_ready(struct vnic_dev *vdev) { - u32 *words; + uint32_t *words; unsigned int nwords = vdev->notify_sz / 4; unsigned int i; - u32 csum; + uint32_t csum; if (!vdev->notify || !vdev->notify_sz) return 0; @@ -882,7 +1031,7 @@ static int vnic_dev_notify_ready(struct vnic_dev *vdev) do { csum = 0; rte_memcpy(&vdev->notify_copy, vdev->notify, vdev->notify_sz); - words = (u32 *)&vdev->notify_copy; + words = (uint32_t *)&vdev->notify_copy; for (i = 1; i < nwords; i++) csum += words[i]; } while (csum != words[0]); @@ -892,7 +1041,7 @@ static int vnic_dev_notify_ready(struct vnic_dev *vdev) int vnic_dev_init(struct vnic_dev *vdev, int arg) { - u64 a0 = (u32)arg, a1 = 0; + uint64_t a0 = (uint32_t)arg, a1 = 0; int wait = 1000; int r = 0; @@ -928,7 +1077,7 @@ int vnic_dev_link_status(struct vnic_dev *vdev) return vdev->notify_copy.link_state; } -u32 vnic_dev_port_speed(struct vnic_dev *vdev) +uint32_t vnic_dev_port_speed(struct vnic_dev *vdev) { if (!vnic_dev_notify_ready(vdev)) return 0; @@ -936,32 +1085,50 @@ u32 vnic_dev_port_speed(struct vnic_dev *vdev) return vdev->notify_copy.port_speed; } -u32 vnic_dev_intr_coal_timer_usec_to_hw(struct vnic_dev *vdev, u32 usec) +uint32_t vnic_dev_mtu(struct vnic_dev *vdev) +{ + if (!vnic_dev_notify_ready(vdev)) + return 0; + + return vdev->notify_copy.mtu; +} + +uint32_t vnic_dev_uif(struct vnic_dev *vdev) +{ + if (!vnic_dev_notify_ready(vdev)) + return 0; + + return vdev->notify_copy.uif; +} + +uint32_t vnic_dev_intr_coal_timer_usec_to_hw(struct vnic_dev *vdev, + uint32_t usec) { return (usec * vdev->intr_coal_timer_info.mul) / vdev->intr_coal_timer_info.div; } -u32 vnic_dev_intr_coal_timer_hw_to_usec(struct vnic_dev *vdev, u32 hw_cycles) +uint32_t vnic_dev_intr_coal_timer_hw_to_usec(struct vnic_dev *vdev, + uint32_t hw_cycles) { return (hw_cycles * vdev->intr_coal_timer_info.div) / vdev->intr_coal_timer_info.mul; } -u32 vnic_dev_get_intr_coal_timer_max(struct vnic_dev *vdev) +uint32_t vnic_dev_get_intr_coal_timer_max(struct vnic_dev *vdev) { return vdev->intr_coal_timer_info.max_usec; } int vnic_dev_alloc_stats_mem(struct vnic_dev *vdev) { - char name[NAME_MAX]; - static u32 instance; + char name[RTE_MEMZONE_NAMESIZE]; + static uint32_t instance; snprintf((char *)name, sizeof(name), "vnic_stats-%u", instance++); vdev->stats = vdev->alloc_consistent(vdev->priv, sizeof(struct vnic_stats), - &vdev->stats_pa, (u8 *)name); + &vdev->stats_pa, (uint8_t *)name); return vdev->stats == NULL ? -ENOMEM : 0; } @@ -977,6 +1144,10 @@ void vnic_dev_unregister(struct vnic_dev *vdev) vdev->free_consistent(vdev->priv, sizeof(struct vnic_stats), vdev->stats, vdev->stats_pa); + if (vdev->flowman_info) + vdev->free_consistent(vdev->priv, + sizeof(struct fm_info), + vdev->flowman_info, vdev->flowman_info_pa); if (vdev->fw_info) vdev->free_consistent(vdev->priv, sizeof(struct vnic_devcmd_fw_info), @@ -990,7 +1161,7 @@ struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, unsigned int num_bars) { if (!vdev) { - char name[NAME_MAX]; + char name[RTE_MEMZONE_NAMESIZE]; snprintf((char *)name, sizeof(name), "%s-vnic", pdev->device.name); vdev = (struct vnic_dev *)rte_zmalloc_socket(name, @@ -1018,6 +1189,23 @@ err_out: return NULL; } +struct vnic_dev *vnic_vf_rep_register(void *priv, struct vnic_dev *pf_vdev, + int vf_id) +{ + struct vnic_dev *vdev; + + vdev = (struct vnic_dev *)rte_zmalloc("enic-vf-rep-vdev", + sizeof(struct vnic_dev), RTE_CACHE_LINE_SIZE); + if (!vdev) + return NULL; + vdev->priv = priv; + vdev->pf_vdev = pf_vdev; + vdev->vf_id = vf_id; + vdev->alloc_consistent = pf_vdev->alloc_consistent; + vdev->free_consistent = pf_vdev->free_consistent; + return vdev; +} + /* * vnic_dev_classifier: Add/Delete classifier entries * @vdev: vdev of the device @@ -1033,16 +1221,16 @@ err_out: * @data: filter data * @action: action data */ -int vnic_dev_classifier(struct vnic_dev *vdev, u8 cmd, u16 *entry, +int vnic_dev_classifier(struct vnic_dev *vdev, uint8_t cmd, uint16_t *entry, struct filter_v2 *data, struct filter_action_v2 *action_v2) { - u64 a0 = 0, a1 = 0; + uint64_t a0 = 0, a1 = 0; int wait = 1000; dma_addr_t tlv_pa; int ret = -EINVAL; struct filter_tlv *tlv, *tlv_va; - u64 tlv_size; - u32 filter_size, action_size; + uint64_t tlv_size; + uint32_t filter_size, action_size; static unsigned int unique_id; char z_name[RTE_MEMZONE_NAMESIZE]; enum vnic_devcmd_cmd dev_cmd; @@ -1059,7 +1247,7 @@ int vnic_dev_classifier(struct vnic_dev *vdev, u8 cmd, u16 *entry, snprintf((char *)z_name, sizeof(z_name), "vnic_clsf_%u", unique_id++); tlv_va = vdev->alloc_consistent(vdev->priv, - tlv_size, &tlv_pa, (u8 *)z_name); + tlv_size, &tlv_pa, (uint8_t *)z_name); if (!tlv_va) return -ENOMEM; tlv = tlv_va; @@ -1078,7 +1266,7 @@ int vnic_dev_classifier(struct vnic_dev *vdev, u8 cmd, u16 *entry, tlv->length = action_size; memcpy(&tlv->val, (void *)action_v2, action_size); ret = vnic_dev_cmd(vdev, dev_cmd, &a0, &a1, wait); - *entry = (u16)a0; + *entry = (uint16_t)a0; vdev->free_consistent(vdev->priv, tlv_size, tlv_va, tlv_pa); } else if (cmd == CLSF_DEL) { a0 = *entry; @@ -1088,20 +1276,21 @@ int vnic_dev_classifier(struct vnic_dev *vdev, u8 cmd, u16 *entry, return ret; } -int vnic_dev_overlay_offload_ctrl(struct vnic_dev *vdev, u8 overlay, u8 config) +int vnic_dev_overlay_offload_ctrl(struct vnic_dev *vdev, uint8_t overlay, + uint8_t config) { - u64 a0 = overlay; - u64 a1 = config; + uint64_t a0 = overlay; + uint64_t a1 = config; int wait = 1000; return vnic_dev_cmd(vdev, CMD_OVERLAY_OFFLOAD_CTRL, &a0, &a1, wait); } -int vnic_dev_overlay_offload_cfg(struct vnic_dev *vdev, u8 overlay, - u16 vxlan_udp_port_number) +int vnic_dev_overlay_offload_cfg(struct vnic_dev *vdev, uint8_t overlay, + uint16_t vxlan_udp_port_number) { - u64 a1 = vxlan_udp_port_number; - u64 a0 = overlay; + uint64_t a1 = vxlan_udp_port_number; + uint64_t a0 = overlay; int wait = 1000; return vnic_dev_cmd(vdev, CMD_OVERLAY_OFFLOAD_CFG, &a0, &a1, wait); @@ -1109,8 +1298,8 @@ int vnic_dev_overlay_offload_cfg(struct vnic_dev *vdev, u8 overlay, int vnic_dev_capable_vxlan(struct vnic_dev *vdev) { - u64 a0 = VIC_FEATURE_VXLAN; - u64 a1 = 0; + uint64_t a0 = VIC_FEATURE_VXLAN; + uint64_t a1 = 0; int wait = 1000; int ret; @@ -1120,3 +1309,14 @@ int vnic_dev_capable_vxlan(struct vnic_dev *vdev) (a1 & (FEATURE_VXLAN_IPV6 | FEATURE_VXLAN_MULTI_WQ)) == (FEATURE_VXLAN_IPV6 | FEATURE_VXLAN_MULTI_WQ); } + +int vnic_dev_capable_geneve(struct vnic_dev *vdev) +{ + uint64_t a0 = VIC_FEATURE_GENEVE; + uint64_t a1 = 0; + int wait = 1000; + int ret; + + ret = vnic_dev_cmd(vdev, CMD_GET_SUPP_FEATURE_VER, &a0, &a1, wait); + return ret == 0 && (a1 & FEATURE_GENEVE_OPTIONS); +}