143e610bbSSunila Sahu /* SPDX-License-Identifier: BSD-3-Clause 243e610bbSSunila Sahu * Copyright(c) 2018 Cavium, Inc 343e610bbSSunila Sahu */ 443e610bbSSunila Sahu 543e610bbSSunila Sahu #include <string.h> 643e610bbSSunila Sahu 743e610bbSSunila Sahu #include <rte_byteorder.h> 843e610bbSSunila Sahu #include <rte_common.h> 943e610bbSSunila Sahu #include <rte_cpuflags.h> 1043e610bbSSunila Sahu #include <rte_malloc.h> 1143e610bbSSunila Sahu 1243e610bbSSunila Sahu #include "otx_zip.h" 1343e610bbSSunila Sahu 14c378f084SAshish Gupta static const struct rte_compressdev_capabilities 15c378f084SAshish Gupta octtx_zip_pmd_capabilities[] = { 16c378f084SAshish Gupta { .algo = RTE_COMP_ALGO_DEFLATE, 17c378f084SAshish Gupta /* Deflate */ 18c378f084SAshish Gupta .comp_feature_flags = RTE_COMP_FF_HUFFMAN_FIXED | 1909442498SMahipal Challa RTE_COMP_FF_HUFFMAN_DYNAMIC | 2009442498SMahipal Challa RTE_COMP_FF_OOP_SGL_IN_SGL_OUT | 2109442498SMahipal Challa RTE_COMP_FF_OOP_SGL_IN_LB_OUT | 2209442498SMahipal Challa RTE_COMP_FF_OOP_LB_IN_SGL_OUT, 23c378f084SAshish Gupta /* Non sharable Priv XFORM and Stateless */ 24c378f084SAshish Gupta .window_size = { 25c378f084SAshish Gupta .min = 1, 26c378f084SAshish Gupta .max = 14, 27c378f084SAshish Gupta .increment = 1 28c378f084SAshish Gupta /* size supported 2^1 to 2^14 */ 29c378f084SAshish Gupta }, 30c378f084SAshish Gupta }, 31c378f084SAshish Gupta RTE_COMP_END_OF_CAPABILITIES_LIST() 32c378f084SAshish Gupta }; 3343e610bbSSunila Sahu 3452048f8fSAshish Gupta /* 3552048f8fSAshish Gupta * Reset session to default state for next set of stateless operation 3652048f8fSAshish Gupta */ 3752048f8fSAshish Gupta static inline void 38938f3f5fSMahipal Challa reset_stream(union zip_inst_s *inst) 3952048f8fSAshish Gupta { 4052048f8fSAshish Gupta inst->s.bf = 1; 4152048f8fSAshish Gupta inst->s.ef = 0; 4252048f8fSAshish Gupta } 4352048f8fSAshish Gupta 4452048f8fSAshish Gupta int 4552048f8fSAshish Gupta zip_process_op(struct rte_comp_op *op, 4652048f8fSAshish Gupta struct zipvf_qp *qp, 47938f3f5fSMahipal Challa struct zip_stream *zstrm, int num) 4852048f8fSAshish Gupta { 49938f3f5fSMahipal Challa union zip_inst_s *inst = zstrm->inst[num]; 5052048f8fSAshish Gupta volatile union zip_zres_s *zresult = NULL; 5152048f8fSAshish Gupta 5209442498SMahipal Challa if (op->m_src->nb_segs > 1) 5309442498SMahipal Challa if (rte_mempool_get(qp->vf->sg_mp, (void *)&qp->g_info) < 0) { 5409442498SMahipal Challa ZIP_PMD_ERR("Can't1 allocate object from SG pool"); 5509442498SMahipal Challa return (-ENOMEM); 5652048f8fSAshish Gupta } 5752048f8fSAshish Gupta 5809442498SMahipal Challa if (op->m_dst->nb_segs > 1) 5909442498SMahipal Challa if (rte_mempool_get(qp->vf->sg_mp, (void *)&qp->s_info) < 0) { 6009442498SMahipal Challa rte_mempool_put(qp->vf->sg_mp, qp->g_info); 6109442498SMahipal Challa ZIP_PMD_ERR("Can't allocate object from SG pool"); 6209442498SMahipal Challa return (-ENOMEM); 6309442498SMahipal Challa } 6409442498SMahipal Challa 6509442498SMahipal Challa if (zipvf_prepare_cmd_stateless(op, qp, inst)) { 6609442498SMahipal Challa op->status = RTE_COMP_OP_STATUS_INVALID_ARGS; 6709442498SMahipal Challa rte_mempool_put(qp->vf->sg_mp, qp->g_info); 6809442498SMahipal Challa rte_mempool_put(qp->vf->sg_mp, qp->s_info); 6909442498SMahipal Challa 7009442498SMahipal Challa ZIP_PMD_ERR("Can't fill SGL buffers"); 7109442498SMahipal Challa return -EINVAL; 7209442498SMahipal Challa } 7352048f8fSAshish Gupta 74938f3f5fSMahipal Challa zresult = (union zip_zres_s *)zstrm->bufs[RES_BUF + num]; 7552048f8fSAshish Gupta zresult->s.compcode = 0; 7652048f8fSAshish Gupta 7752048f8fSAshish Gupta #ifdef ZIP_DBG 7852048f8fSAshish Gupta zip_dump_instruction(inst); 7952048f8fSAshish Gupta #endif 8052048f8fSAshish Gupta 8152048f8fSAshish Gupta /* Submit zip command */ 8252048f8fSAshish Gupta zipvf_push_command(qp, (void *)inst); 8352048f8fSAshish Gupta 8452048f8fSAshish Gupta return 0; 8552048f8fSAshish Gupta } 8652048f8fSAshish Gupta 87b43ebc65SAshish Gupta /** Parse xform parameters and setup a stream */ 88b43ebc65SAshish Gupta static int 89b43ebc65SAshish Gupta zip_set_stream_parameters(struct rte_compressdev *dev, 90b43ebc65SAshish Gupta const struct rte_comp_xform *xform, 91b43ebc65SAshish Gupta struct zip_stream *z_stream) 92b43ebc65SAshish Gupta { 93b43ebc65SAshish Gupta struct zip_vf *vf = (struct zip_vf *)dev->data->dev_private; 94938f3f5fSMahipal Challa union zip_inst_s *inst; 95b43ebc65SAshish Gupta void *res; 96938f3f5fSMahipal Challa int ret, i; 97b43ebc65SAshish Gupta 98b43ebc65SAshish Gupta /* Allocate resources required by a stream */ 99b43ebc65SAshish Gupta ret = rte_mempool_get_bulk(vf->zip_mp, 100938f3f5fSMahipal Challa z_stream->bufs, (MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE)); 101b43ebc65SAshish Gupta if (ret < 0) 102b43ebc65SAshish Gupta return -1; 103b43ebc65SAshish Gupta 104938f3f5fSMahipal Challa for (i = 0; i < ZIP_BURST_SIZE; i++) { 105b43ebc65SAshish Gupta /* get one command buffer from pool and set up */ 106938f3f5fSMahipal Challa inst = (union zip_inst_s *)z_stream->bufs[(CMD_BUF * ZIP_BURST_SIZE) + i]; 107938f3f5fSMahipal Challa res = z_stream->bufs[(RES_BUF * ZIP_BURST_SIZE) + i]; 108b43ebc65SAshish Gupta memset(inst->u, 0, sizeof(inst->u)); 109b43ebc65SAshish Gupta 110b43ebc65SAshish Gupta /* set bf for only first ops of stream */ 111b43ebc65SAshish Gupta inst->s.bf = 1; 112b43ebc65SAshish Gupta 113b43ebc65SAshish Gupta if (xform->type == RTE_COMP_COMPRESS) { 114b43ebc65SAshish Gupta inst->s.op = ZIP_OP_E_COMP; 115b43ebc65SAshish Gupta 116b43ebc65SAshish Gupta switch (xform->compress.deflate.huffman) { 117b43ebc65SAshish Gupta case RTE_COMP_HUFFMAN_DEFAULT: 118b43ebc65SAshish Gupta inst->s.cc = ZIP_CC_DEFAULT; 119b43ebc65SAshish Gupta break; 120b43ebc65SAshish Gupta case RTE_COMP_HUFFMAN_FIXED: 121b43ebc65SAshish Gupta inst->s.cc = ZIP_CC_FIXED_HUFF; 122b43ebc65SAshish Gupta break; 123b43ebc65SAshish Gupta case RTE_COMP_HUFFMAN_DYNAMIC: 124b43ebc65SAshish Gupta inst->s.cc = ZIP_CC_DYN_HUFF; 125b43ebc65SAshish Gupta break; 126b43ebc65SAshish Gupta default: 127b43ebc65SAshish Gupta ret = -1; 128b43ebc65SAshish Gupta goto err; 129b43ebc65SAshish Gupta } 130b43ebc65SAshish Gupta 131b43ebc65SAshish Gupta switch (xform->compress.level) { 132b43ebc65SAshish Gupta case RTE_COMP_LEVEL_MIN: 133b43ebc65SAshish Gupta inst->s.ss = ZIP_COMP_E_LEVEL_MIN; 134b43ebc65SAshish Gupta break; 135b43ebc65SAshish Gupta case RTE_COMP_LEVEL_MAX: 136b43ebc65SAshish Gupta inst->s.ss = ZIP_COMP_E_LEVEL_MAX; 137b43ebc65SAshish Gupta break; 138b43ebc65SAshish Gupta case RTE_COMP_LEVEL_NONE: 139b43ebc65SAshish Gupta ZIP_PMD_ERR("Compression level not supported"); 140b43ebc65SAshish Gupta ret = -1; 141b43ebc65SAshish Gupta goto err; 142b43ebc65SAshish Gupta default: 143b43ebc65SAshish Gupta /* for any value between min and max , choose 144b43ebc65SAshish Gupta * PMD default. 145b43ebc65SAshish Gupta */ 146b43ebc65SAshish Gupta inst->s.ss = ZIP_COMP_E_LEVEL_MED; /** PMD default **/ 147b43ebc65SAshish Gupta break; 148b43ebc65SAshish Gupta } 149b43ebc65SAshish Gupta } else if (xform->type == RTE_COMP_DECOMPRESS) { 150b43ebc65SAshish Gupta inst->s.op = ZIP_OP_E_DECOMP; 151b43ebc65SAshish Gupta /* from HRM, 152b43ebc65SAshish Gupta * For DEFLATE decompression, [CC] must be 0x0. 153b43ebc65SAshish Gupta * For decompression, [SS] must be 0x0 154b43ebc65SAshish Gupta */ 155b43ebc65SAshish Gupta inst->s.cc = 0; 156b43ebc65SAshish Gupta /* Speed bit should not be set for decompression */ 157b43ebc65SAshish Gupta inst->s.ss = 0; 158b43ebc65SAshish Gupta /* decompression context is supported only for STATEFUL 159b43ebc65SAshish Gupta * operations. Currently we support STATELESS ONLY so 160b43ebc65SAshish Gupta * skip setting of ctx pointer 161b43ebc65SAshish Gupta */ 162b43ebc65SAshish Gupta 163b43ebc65SAshish Gupta } else { 164*f665790aSDavid Marchand ZIP_PMD_ERR("xform type not supported"); 165b43ebc65SAshish Gupta ret = -1; 166b43ebc65SAshish Gupta goto err; 167b43ebc65SAshish Gupta } 168b43ebc65SAshish Gupta 169b43ebc65SAshish Gupta inst->s.res_ptr_addr.s.addr = rte_mempool_virt2iova(res); 170b43ebc65SAshish Gupta inst->s.res_ptr_ctl.s.length = 0; 171b43ebc65SAshish Gupta 172938f3f5fSMahipal Challa z_stream->inst[i] = inst; 173938f3f5fSMahipal Challa } 174938f3f5fSMahipal Challa 17552048f8fSAshish Gupta z_stream->func = zip_process_op; 176b43ebc65SAshish Gupta 177b43ebc65SAshish Gupta return 0; 178b43ebc65SAshish Gupta 179b43ebc65SAshish Gupta err: 180b43ebc65SAshish Gupta rte_mempool_put_bulk(vf->zip_mp, 181b43ebc65SAshish Gupta (void *)&(z_stream->bufs[0]), 182938f3f5fSMahipal Challa (MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE)); 183b43ebc65SAshish Gupta 184b43ebc65SAshish Gupta return ret; 185b43ebc65SAshish Gupta } 186b43ebc65SAshish Gupta 187c378f084SAshish Gupta /** Configure device */ 188c378f084SAshish Gupta static int 189c378f084SAshish Gupta zip_pmd_config(struct rte_compressdev *dev, 190c378f084SAshish Gupta struct rte_compressdev_config *config) 191c378f084SAshish Gupta { 192c378f084SAshish Gupta char res_pool[RTE_MEMZONE_NAMESIZE]; 19309442498SMahipal Challa char sg_pool[RTE_MEMZONE_NAMESIZE]; 194c378f084SAshish Gupta struct rte_mempool *zip_buf_mp; 19509442498SMahipal Challa struct rte_mempool *zip_sg_mp; 19609442498SMahipal Challa struct zip_vf *vf; 19709442498SMahipal Challa int nb_streams; 198c378f084SAshish Gupta 199c378f084SAshish Gupta if (!config || !dev) 200c378f084SAshish Gupta return -EIO; 201c378f084SAshish Gupta 202c378f084SAshish Gupta vf = (struct zip_vf *)(dev->data->dev_private); 203c378f084SAshish Gupta 204c378f084SAshish Gupta /* create pool with maximum numbers of resources 205c378f084SAshish Gupta * required by streams 206c378f084SAshish Gupta */ 207c378f084SAshish Gupta 208c378f084SAshish Gupta /* use common pool for non-shareable priv_xform and stream */ 209c378f084SAshish Gupta nb_streams = config->max_nb_priv_xforms + config->max_nb_streams; 210c378f084SAshish Gupta 211c378f084SAshish Gupta snprintf(res_pool, RTE_MEMZONE_NAMESIZE, "octtx_zip_res_pool%u", 212c378f084SAshish Gupta dev->data->dev_id); 213c378f084SAshish Gupta 21409442498SMahipal Challa snprintf(sg_pool, RTE_MEMZONE_NAMESIZE, "octtx_zip_sg_pool%u", 21509442498SMahipal Challa dev->data->dev_id); 21609442498SMahipal Challa 217c378f084SAshish Gupta /** TBD Should we use the per core object cache for stream resources */ 218c378f084SAshish Gupta zip_buf_mp = rte_mempool_create( 219c378f084SAshish Gupta res_pool, 220938f3f5fSMahipal Challa (nb_streams * MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE), 221c378f084SAshish Gupta ZIP_BUF_SIZE, 222c378f084SAshish Gupta 0, 223c378f084SAshish Gupta 0, 224c378f084SAshish Gupta NULL, 225c378f084SAshish Gupta NULL, 226c378f084SAshish Gupta NULL, 227c378f084SAshish Gupta NULL, 228c378f084SAshish Gupta SOCKET_ID_ANY, 229c378f084SAshish Gupta 0); 230c378f084SAshish Gupta 231c378f084SAshish Gupta if (zip_buf_mp == NULL) { 232c378f084SAshish Gupta ZIP_PMD_ERR( 233c378f084SAshish Gupta "Failed to create buf mempool octtx_zip_res_pool%u", 234c378f084SAshish Gupta dev->data->dev_id); 235c378f084SAshish Gupta return -1; 236c378f084SAshish Gupta } 237c378f084SAshish Gupta 23809442498SMahipal Challa /* Scatter gather buffer pool */ 23909442498SMahipal Challa zip_sg_mp = rte_mempool_create( 24009442498SMahipal Challa sg_pool, 24109442498SMahipal Challa (2 * nb_streams * ZIP_BURST_SIZE * ZIP_MAX_SEGS), 24209442498SMahipal Challa ZIP_SGBUF_SIZE, 24309442498SMahipal Challa 0, 24409442498SMahipal Challa 0, 24509442498SMahipal Challa NULL, 24609442498SMahipal Challa NULL, 24709442498SMahipal Challa NULL, 24809442498SMahipal Challa NULL, 24909442498SMahipal Challa SOCKET_ID_ANY, 25009442498SMahipal Challa MEMPOOL_F_NO_SPREAD); 25109442498SMahipal Challa 25209442498SMahipal Challa if (zip_sg_mp == NULL) { 25309442498SMahipal Challa ZIP_PMD_ERR("Failed to create SG buf mempool octtx_zip_sg_pool%u", 25409442498SMahipal Challa dev->data->dev_id); 25509442498SMahipal Challa 25609442498SMahipal Challa rte_mempool_free(vf->zip_mp); 25709442498SMahipal Challa return -1; 25809442498SMahipal Challa } 25909442498SMahipal Challa 260c378f084SAshish Gupta vf->zip_mp = zip_buf_mp; 26109442498SMahipal Challa vf->sg_mp = zip_sg_mp; 262c378f084SAshish Gupta 263c378f084SAshish Gupta return 0; 264c378f084SAshish Gupta } 265c378f084SAshish Gupta 266c378f084SAshish Gupta /** Start device */ 267c378f084SAshish Gupta static int 268c378f084SAshish Gupta zip_pmd_start(__rte_unused struct rte_compressdev *dev) 269c378f084SAshish Gupta { 270c378f084SAshish Gupta return 0; 271c378f084SAshish Gupta } 272c378f084SAshish Gupta 273c378f084SAshish Gupta /** Stop device */ 274c378f084SAshish Gupta static void 275c378f084SAshish Gupta zip_pmd_stop(__rte_unused struct rte_compressdev *dev) 276c378f084SAshish Gupta { 277c378f084SAshish Gupta 278c378f084SAshish Gupta } 279c378f084SAshish Gupta 280c378f084SAshish Gupta /** Close device */ 281c378f084SAshish Gupta static int 282c378f084SAshish Gupta zip_pmd_close(struct rte_compressdev *dev) 283c378f084SAshish Gupta { 284c378f084SAshish Gupta if (dev == NULL) 285c378f084SAshish Gupta return -1; 286c378f084SAshish Gupta 287c378f084SAshish Gupta struct zip_vf *vf = (struct zip_vf *)dev->data->dev_private; 288c378f084SAshish Gupta rte_mempool_free(vf->zip_mp); 28909442498SMahipal Challa rte_mempool_free(vf->sg_mp); 290c378f084SAshish Gupta 291c378f084SAshish Gupta return 0; 292c378f084SAshish Gupta } 293c378f084SAshish Gupta 294c378f084SAshish Gupta /** Get device statistics */ 295c378f084SAshish Gupta static void 296c378f084SAshish Gupta zip_pmd_stats_get(struct rte_compressdev *dev, 297c378f084SAshish Gupta struct rte_compressdev_stats *stats) 298c378f084SAshish Gupta { 299c378f084SAshish Gupta int qp_id; 300c378f084SAshish Gupta 301c378f084SAshish Gupta for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { 302c378f084SAshish Gupta struct zipvf_qp *qp = dev->data->queue_pairs[qp_id]; 303c378f084SAshish Gupta 304c378f084SAshish Gupta stats->enqueued_count += qp->qp_stats.enqueued_count; 305c378f084SAshish Gupta stats->dequeued_count += qp->qp_stats.dequeued_count; 306c378f084SAshish Gupta 307c378f084SAshish Gupta stats->enqueue_err_count += qp->qp_stats.enqueue_err_count; 308c378f084SAshish Gupta stats->dequeue_err_count += qp->qp_stats.dequeue_err_count; 309c378f084SAshish Gupta } 310c378f084SAshish Gupta } 311c378f084SAshish Gupta 312c378f084SAshish Gupta /** Reset device statistics */ 313c378f084SAshish Gupta static void 314c378f084SAshish Gupta zip_pmd_stats_reset(struct rte_compressdev *dev) 315c378f084SAshish Gupta { 316c378f084SAshish Gupta int qp_id; 317c378f084SAshish Gupta 318c378f084SAshish Gupta for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { 319c378f084SAshish Gupta struct zipvf_qp *qp = dev->data->queue_pairs[qp_id]; 320c378f084SAshish Gupta memset(&qp->qp_stats, 0, sizeof(qp->qp_stats)); 321c378f084SAshish Gupta } 322c378f084SAshish Gupta } 323c378f084SAshish Gupta 324c378f084SAshish Gupta /** Get device info */ 325c378f084SAshish Gupta static void 326c378f084SAshish Gupta zip_pmd_info_get(struct rte_compressdev *dev, 327c378f084SAshish Gupta struct rte_compressdev_info *dev_info) 328c378f084SAshish Gupta { 329c378f084SAshish Gupta struct zip_vf *vf = (struct zip_vf *)dev->data->dev_private; 330c378f084SAshish Gupta 331c378f084SAshish Gupta if (dev_info != NULL) { 332c378f084SAshish Gupta dev_info->driver_name = dev->device->driver->name; 333c378f084SAshish Gupta dev_info->feature_flags = dev->feature_flags; 334c378f084SAshish Gupta dev_info->capabilities = octtx_zip_pmd_capabilities; 335c378f084SAshish Gupta dev_info->max_nb_queue_pairs = vf->max_nb_queue_pairs; 336c378f084SAshish Gupta } 337c378f084SAshish Gupta } 338c378f084SAshish Gupta 339c378f084SAshish Gupta /** Release queue pair */ 340c378f084SAshish Gupta static int 341c378f084SAshish Gupta zip_pmd_qp_release(struct rte_compressdev *dev, uint16_t qp_id) 342c378f084SAshish Gupta { 343c378f084SAshish Gupta struct zipvf_qp *qp = dev->data->queue_pairs[qp_id]; 344c378f084SAshish Gupta 345c378f084SAshish Gupta if (qp != NULL) { 346c378f084SAshish Gupta zipvf_q_term(qp); 347c378f084SAshish Gupta 348c378f084SAshish Gupta rte_ring_free(qp->processed_pkts); 349c378f084SAshish Gupta 350c378f084SAshish Gupta rte_free(qp); 351c378f084SAshish Gupta dev->data->queue_pairs[qp_id] = NULL; 352c378f084SAshish Gupta } 353c378f084SAshish Gupta return 0; 354c378f084SAshish Gupta } 355c378f084SAshish Gupta 356c378f084SAshish Gupta /** Create a ring to place process packets on */ 357c378f084SAshish Gupta static struct rte_ring * 358c378f084SAshish Gupta zip_pmd_qp_create_processed_pkts_ring(struct zipvf_qp *qp, 359c378f084SAshish Gupta unsigned int ring_size, int socket_id) 360c378f084SAshish Gupta { 361c378f084SAshish Gupta struct rte_ring *r; 362c378f084SAshish Gupta 363c378f084SAshish Gupta r = rte_ring_lookup(qp->name); 364c378f084SAshish Gupta if (r) { 365c378f084SAshish Gupta if (rte_ring_get_size(r) >= ring_size) { 366c378f084SAshish Gupta ZIP_PMD_INFO("Reusing existing ring %s for processed" 367c378f084SAshish Gupta " packets", qp->name); 368c378f084SAshish Gupta return r; 369c378f084SAshish Gupta } 370c378f084SAshish Gupta 371c378f084SAshish Gupta ZIP_PMD_ERR("Unable to reuse existing ring %s for processed" 372c378f084SAshish Gupta " packets", qp->name); 373c378f084SAshish Gupta return NULL; 374c378f084SAshish Gupta } 375c378f084SAshish Gupta 376c378f084SAshish Gupta return rte_ring_create(qp->name, ring_size, socket_id, 377c378f084SAshish Gupta RING_F_EXACT_SZ); 378c378f084SAshish Gupta } 379c378f084SAshish Gupta 380c378f084SAshish Gupta /** Setup a queue pair */ 381c378f084SAshish Gupta static int 382c378f084SAshish Gupta zip_pmd_qp_setup(struct rte_compressdev *dev, uint16_t qp_id, 383c378f084SAshish Gupta uint32_t max_inflight_ops, int socket_id) 384c378f084SAshish Gupta { 385c378f084SAshish Gupta struct zipvf_qp *qp = NULL; 386c378f084SAshish Gupta struct zip_vf *vf; 387c378f084SAshish Gupta char *name; 388c378f084SAshish Gupta int ret; 389c378f084SAshish Gupta 390c378f084SAshish Gupta if (!dev) 391c378f084SAshish Gupta return -1; 392c378f084SAshish Gupta 393c378f084SAshish Gupta vf = (struct zip_vf *) (dev->data->dev_private); 394c378f084SAshish Gupta 395c378f084SAshish Gupta /* Free memory prior to re-allocation if needed. */ 396c378f084SAshish Gupta if (dev->data->queue_pairs[qp_id] != NULL) { 397c378f084SAshish Gupta ZIP_PMD_INFO("Using existing queue pair %d ", qp_id); 398c378f084SAshish Gupta return 0; 399c378f084SAshish Gupta } 400c378f084SAshish Gupta 401c378f084SAshish Gupta name = rte_malloc(NULL, RTE_COMPRESSDEV_NAME_MAX_LEN, 0); 402b072930fSWeiguo Li if (name == NULL) 403b072930fSWeiguo Li return (-ENOMEM); 404c378f084SAshish Gupta snprintf(name, RTE_COMPRESSDEV_NAME_MAX_LEN, 405c378f084SAshish Gupta "zip_pmd_%u_qp_%u", 406c378f084SAshish Gupta dev->data->dev_id, qp_id); 407c378f084SAshish Gupta 408c378f084SAshish Gupta /* Allocate the queue pair data structure. */ 409c378f084SAshish Gupta qp = rte_zmalloc_socket(name, sizeof(*qp), 410c378f084SAshish Gupta RTE_CACHE_LINE_SIZE, socket_id); 411b072930fSWeiguo Li if (qp == NULL) { 412b072930fSWeiguo Li rte_free(name); 413c378f084SAshish Gupta return (-ENOMEM); 414b072930fSWeiguo Li } 415c378f084SAshish Gupta 416c378f084SAshish Gupta qp->name = name; 417c378f084SAshish Gupta 418c378f084SAshish Gupta /* Create completion queue up to max_inflight_ops */ 419c378f084SAshish Gupta qp->processed_pkts = zip_pmd_qp_create_processed_pkts_ring(qp, 420c378f084SAshish Gupta max_inflight_ops, socket_id); 421c378f084SAshish Gupta if (qp->processed_pkts == NULL) 422c378f084SAshish Gupta goto qp_setup_cleanup; 423c378f084SAshish Gupta 424c378f084SAshish Gupta qp->id = qp_id; 425c378f084SAshish Gupta qp->vf = vf; 426c378f084SAshish Gupta 427c378f084SAshish Gupta ret = zipvf_q_init(qp); 428c378f084SAshish Gupta if (ret < 0) 429c378f084SAshish Gupta goto qp_setup_cleanup; 430c378f084SAshish Gupta 431c378f084SAshish Gupta dev->data->queue_pairs[qp_id] = qp; 432c378f084SAshish Gupta 433c378f084SAshish Gupta memset(&qp->qp_stats, 0, sizeof(qp->qp_stats)); 434c378f084SAshish Gupta return 0; 435c378f084SAshish Gupta 436c378f084SAshish Gupta qp_setup_cleanup: 437c378f084SAshish Gupta rte_ring_free(qp->processed_pkts); 438c378f084SAshish Gupta rte_free(qp); 439c378f084SAshish Gupta return -1; 440c378f084SAshish Gupta } 441c378f084SAshish Gupta 442b43ebc65SAshish Gupta static int 443b43ebc65SAshish Gupta zip_pmd_stream_create(struct rte_compressdev *dev, 444b43ebc65SAshish Gupta const struct rte_comp_xform *xform, void **stream) 445b43ebc65SAshish Gupta { 446b43ebc65SAshish Gupta int ret; 447b43ebc65SAshish Gupta struct zip_stream *strm = NULL; 448b43ebc65SAshish Gupta 449b43ebc65SAshish Gupta strm = rte_malloc(NULL, 450b43ebc65SAshish Gupta sizeof(struct zip_stream), 0); 451b43ebc65SAshish Gupta 452b43ebc65SAshish Gupta if (strm == NULL) 453b43ebc65SAshish Gupta return (-ENOMEM); 454b43ebc65SAshish Gupta 455b43ebc65SAshish Gupta ret = zip_set_stream_parameters(dev, xform, strm); 456b43ebc65SAshish Gupta if (ret < 0) { 457b43ebc65SAshish Gupta ZIP_PMD_ERR("failed configure xform parameters"); 458b43ebc65SAshish Gupta rte_free(strm); 459b43ebc65SAshish Gupta return ret; 460b43ebc65SAshish Gupta } 461b43ebc65SAshish Gupta *stream = strm; 462938f3f5fSMahipal Challa 463b43ebc65SAshish Gupta return 0; 464b43ebc65SAshish Gupta } 465b43ebc65SAshish Gupta 466b43ebc65SAshish Gupta static int 467b43ebc65SAshish Gupta zip_pmd_stream_free(struct rte_compressdev *dev, void *stream) 468b43ebc65SAshish Gupta { 469b43ebc65SAshish Gupta struct zip_vf *vf = (struct zip_vf *) (dev->data->dev_private); 470b43ebc65SAshish Gupta struct zip_stream *z_stream; 471b43ebc65SAshish Gupta 472b43ebc65SAshish Gupta if (stream == NULL) 473b43ebc65SAshish Gupta return 0; 474b43ebc65SAshish Gupta 475b43ebc65SAshish Gupta z_stream = (struct zip_stream *)stream; 476b43ebc65SAshish Gupta 477b43ebc65SAshish Gupta /* Free resources back to pool */ 478b43ebc65SAshish Gupta rte_mempool_put_bulk(vf->zip_mp, 479b43ebc65SAshish Gupta (void *)&(z_stream->bufs[0]), 480938f3f5fSMahipal Challa (MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE)); 481b43ebc65SAshish Gupta 482b43ebc65SAshish Gupta /* Zero out the whole structure */ 483b43ebc65SAshish Gupta memset(stream, 0, sizeof(struct zip_stream)); 484b43ebc65SAshish Gupta rte_free(stream); 485b43ebc65SAshish Gupta 486b43ebc65SAshish Gupta return 0; 487b43ebc65SAshish Gupta } 488b43ebc65SAshish Gupta 489b43ebc65SAshish Gupta 49052048f8fSAshish Gupta static uint16_t 491938f3f5fSMahipal Challa zip_pmd_enqueue_burst(void *queue_pair, 49252048f8fSAshish Gupta struct rte_comp_op **ops, uint16_t nb_ops) 49352048f8fSAshish Gupta { 49452048f8fSAshish Gupta struct zipvf_qp *qp = queue_pair; 49552048f8fSAshish Gupta struct zip_stream *zstrm; 496938f3f5fSMahipal Challa struct rte_comp_op *op; 49752048f8fSAshish Gupta int i, ret = 0; 49852048f8fSAshish Gupta uint16_t enqd = 0; 49952048f8fSAshish Gupta 50052048f8fSAshish Gupta for (i = 0; i < nb_ops; i++) { 50152048f8fSAshish Gupta op = ops[i]; 50252048f8fSAshish Gupta 50352048f8fSAshish Gupta if (op->op_type == RTE_COMP_OP_STATEFUL) { 50452048f8fSAshish Gupta op->status = RTE_COMP_OP_STATUS_INVALID_ARGS; 50552048f8fSAshish Gupta } else { 50652048f8fSAshish Gupta /* process stateless ops */ 50752048f8fSAshish Gupta zstrm = (struct zip_stream *)op->private_xform; 50852048f8fSAshish Gupta if (unlikely(zstrm == NULL)) 50952048f8fSAshish Gupta op->status = RTE_COMP_OP_STATUS_INVALID_ARGS; 51052048f8fSAshish Gupta else 511938f3f5fSMahipal Challa ret = zstrm->func(op, qp, zstrm, i); 51252048f8fSAshish Gupta } 51352048f8fSAshish Gupta 51452048f8fSAshish Gupta /* Whatever is out of op, put it into completion queue with 51552048f8fSAshish Gupta * its status 51652048f8fSAshish Gupta */ 51752048f8fSAshish Gupta if (!ret) 51852048f8fSAshish Gupta ret = rte_ring_enqueue(qp->processed_pkts, (void *)op); 51952048f8fSAshish Gupta 52052048f8fSAshish Gupta if (unlikely(ret < 0)) { 52152048f8fSAshish Gupta /* increment count if failed to enqueue op*/ 52252048f8fSAshish Gupta qp->qp_stats.enqueue_err_count++; 52352048f8fSAshish Gupta } else { 52452048f8fSAshish Gupta qp->qp_stats.enqueued_count++; 52552048f8fSAshish Gupta enqd++; 52652048f8fSAshish Gupta } 52752048f8fSAshish Gupta } 528938f3f5fSMahipal Challa 52909442498SMahipal Challa qp->enqed = enqd; 530*f665790aSDavid Marchand ZIP_PMD_LOG(DEBUG, "ops_enqd[nb_ops:%d]:%d", nb_ops, enqd); 53109442498SMahipal Challa 53252048f8fSAshish Gupta return enqd; 53352048f8fSAshish Gupta } 53452048f8fSAshish Gupta 53552048f8fSAshish Gupta static uint16_t 536938f3f5fSMahipal Challa zip_pmd_dequeue_burst(void *queue_pair, 53752048f8fSAshish Gupta struct rte_comp_op **ops, uint16_t nb_ops) 53852048f8fSAshish Gupta { 539938f3f5fSMahipal Challa volatile union zip_zres_s *zresult = NULL; 54052048f8fSAshish Gupta struct zipvf_qp *qp = queue_pair; 54152048f8fSAshish Gupta 54252048f8fSAshish Gupta unsigned int nb_dequeued = 0; 543938f3f5fSMahipal Challa struct zip_stream *zstrm; 544938f3f5fSMahipal Challa struct rte_comp_op *op; 545938f3f5fSMahipal Challa unsigned int i; 54652048f8fSAshish Gupta 54752048f8fSAshish Gupta nb_dequeued = rte_ring_dequeue_burst(qp->processed_pkts, 54852048f8fSAshish Gupta (void **)ops, nb_ops, NULL); 54952048f8fSAshish Gupta qp->qp_stats.dequeued_count += nb_dequeued; 55052048f8fSAshish Gupta 551938f3f5fSMahipal Challa /* Dequeue all the submitted ops */ 552938f3f5fSMahipal Challa for (i = 0; i < nb_dequeued; i++) { 553938f3f5fSMahipal Challa op = ops[i]; 554938f3f5fSMahipal Challa /* process stateless ops */ 555938f3f5fSMahipal Challa zstrm = (struct zip_stream *)op->private_xform; 556938f3f5fSMahipal Challa zresult = (union zip_zres_s *)zstrm->bufs[RES_BUF + i]; 557938f3f5fSMahipal Challa 558938f3f5fSMahipal Challa /* Check and Process results in sync mode */ 559938f3f5fSMahipal Challa do { 560938f3f5fSMahipal Challa } while (!zresult->s.compcode); 561938f3f5fSMahipal Challa 562938f3f5fSMahipal Challa if (zresult->s.compcode == ZIP_COMP_E_SUCCESS) { 563938f3f5fSMahipal Challa op->status = RTE_COMP_OP_STATUS_SUCCESS; 564938f3f5fSMahipal Challa } else { 565938f3f5fSMahipal Challa /* FATAL error cannot do anything */ 566*f665790aSDavid Marchand ZIP_PMD_ERR("operation failed with error code:%d", 567938f3f5fSMahipal Challa zresult->s.compcode); 568938f3f5fSMahipal Challa if (zresult->s.compcode == ZIP_COMP_E_DSTOP) 569938f3f5fSMahipal Challa op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED; 570938f3f5fSMahipal Challa else 571938f3f5fSMahipal Challa op->status = RTE_COMP_OP_STATUS_ERROR; 572938f3f5fSMahipal Challa } 573938f3f5fSMahipal Challa 574*f665790aSDavid Marchand ZIP_PMD_LOG(DEBUG, "written %d", zresult->s.totalbyteswritten); 575938f3f5fSMahipal Challa 576938f3f5fSMahipal Challa /* Update op stats */ 577938f3f5fSMahipal Challa switch (op->status) { 578938f3f5fSMahipal Challa case RTE_COMP_OP_STATUS_SUCCESS: 579938f3f5fSMahipal Challa op->consumed = zresult->s.totalbytesread; 580938f3f5fSMahipal Challa /* Fall-through */ 581938f3f5fSMahipal Challa case RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED: 582938f3f5fSMahipal Challa op->produced = zresult->s.totalbyteswritten; 583938f3f5fSMahipal Challa break; 584938f3f5fSMahipal Challa default: 585*f665790aSDavid Marchand ZIP_PMD_ERR("stats not updated for status:%d", 586938f3f5fSMahipal Challa op->status); 587938f3f5fSMahipal Challa break; 588938f3f5fSMahipal Challa } 589938f3f5fSMahipal Challa 590938f3f5fSMahipal Challa /* zstream is reset irrespective of result */ 591938f3f5fSMahipal Challa reset_stream(zstrm->inst[i]); 592938f3f5fSMahipal Challa zresult->s.compcode = ZIP_COMP_E_NOTDONE; 59309442498SMahipal Challa 59409442498SMahipal Challa if (op->m_src->nb_segs > 1) 59509442498SMahipal Challa rte_mempool_put(qp->vf->sg_mp, qp->g_info); 59609442498SMahipal Challa 59709442498SMahipal Challa if (op->m_dst->nb_segs > 1) 59809442498SMahipal Challa rte_mempool_put(qp->vf->sg_mp, qp->s_info); 599938f3f5fSMahipal Challa } 600938f3f5fSMahipal Challa 601*f665790aSDavid Marchand ZIP_PMD_LOG(DEBUG, "ops_deqd[nb_ops:%d]: %d", nb_ops, nb_dequeued); 60252048f8fSAshish Gupta return nb_dequeued; 60352048f8fSAshish Gupta } 60452048f8fSAshish Gupta 605b74fd6b8SFerruh Yigit static struct rte_compressdev_ops octtx_zip_pmd_ops = { 606c378f084SAshish Gupta .dev_configure = zip_pmd_config, 607c378f084SAshish Gupta .dev_start = zip_pmd_start, 608c378f084SAshish Gupta .dev_stop = zip_pmd_stop, 609c378f084SAshish Gupta .dev_close = zip_pmd_close, 610c378f084SAshish Gupta 611c378f084SAshish Gupta .stats_get = zip_pmd_stats_get, 612c378f084SAshish Gupta .stats_reset = zip_pmd_stats_reset, 613c378f084SAshish Gupta 614c378f084SAshish Gupta .dev_infos_get = zip_pmd_info_get, 615c378f084SAshish Gupta 616c378f084SAshish Gupta .queue_pair_setup = zip_pmd_qp_setup, 617c378f084SAshish Gupta .queue_pair_release = zip_pmd_qp_release, 618b43ebc65SAshish Gupta 619b43ebc65SAshish Gupta .private_xform_create = zip_pmd_stream_create, 620b43ebc65SAshish Gupta .private_xform_free = zip_pmd_stream_free, 621b43ebc65SAshish Gupta .stream_create = NULL, 622b43ebc65SAshish Gupta .stream_free = NULL 62343e610bbSSunila Sahu }; 62443e610bbSSunila Sahu 62543e610bbSSunila Sahu static int 62643e610bbSSunila Sahu zip_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 62743e610bbSSunila Sahu struct rte_pci_device *pci_dev) 62843e610bbSSunila Sahu { 62943e610bbSSunila Sahu int ret = 0; 63043e610bbSSunila Sahu char compressdev_name[RTE_COMPRESSDEV_NAME_MAX_LEN]; 63143e610bbSSunila Sahu struct rte_compressdev *compressdev; 63243e610bbSSunila Sahu struct rte_compressdev_pmd_init_params init_params = { 63343e610bbSSunila Sahu "", 63443e610bbSSunila Sahu rte_socket_id(), 63543e610bbSSunila Sahu }; 63643e610bbSSunila Sahu 63743e610bbSSunila Sahu ZIP_PMD_INFO("vendor_id=0x%x device_id=0x%x", 63843e610bbSSunila Sahu (unsigned int)pci_dev->id.vendor_id, 63943e610bbSSunila Sahu (unsigned int)pci_dev->id.device_id); 64043e610bbSSunila Sahu 64143e610bbSSunila Sahu rte_pci_device_name(&pci_dev->addr, compressdev_name, 64243e610bbSSunila Sahu sizeof(compressdev_name)); 64343e610bbSSunila Sahu 64443e610bbSSunila Sahu compressdev = rte_compressdev_pmd_create(compressdev_name, 64543e610bbSSunila Sahu &pci_dev->device, sizeof(struct zip_vf), &init_params); 64643e610bbSSunila Sahu if (compressdev == NULL) { 64743e610bbSSunila Sahu ZIP_PMD_ERR("driver %s: create failed", init_params.name); 64843e610bbSSunila Sahu return -ENODEV; 64943e610bbSSunila Sahu } 65043e610bbSSunila Sahu 65143e610bbSSunila Sahu /* 65243e610bbSSunila Sahu * create only if proc_type is primary. 65343e610bbSSunila Sahu */ 65443e610bbSSunila Sahu if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 65543e610bbSSunila Sahu /* create vf dev with given pmd dev id */ 65643e610bbSSunila Sahu ret = zipvf_create(compressdev); 65743e610bbSSunila Sahu if (ret < 0) { 65843e610bbSSunila Sahu ZIP_PMD_ERR("Device creation failed"); 65943e610bbSSunila Sahu rte_compressdev_pmd_destroy(compressdev); 66043e610bbSSunila Sahu return ret; 66143e610bbSSunila Sahu } 66243e610bbSSunila Sahu } 66343e610bbSSunila Sahu 66443e610bbSSunila Sahu compressdev->dev_ops = &octtx_zip_pmd_ops; 66543e610bbSSunila Sahu /* register rx/tx burst functions for data path */ 666938f3f5fSMahipal Challa compressdev->dequeue_burst = zip_pmd_dequeue_burst; 667938f3f5fSMahipal Challa compressdev->enqueue_burst = zip_pmd_enqueue_burst; 66843e610bbSSunila Sahu compressdev->feature_flags = RTE_COMPDEV_FF_HW_ACCELERATED; 66943e610bbSSunila Sahu return ret; 67043e610bbSSunila Sahu } 67143e610bbSSunila Sahu 67243e610bbSSunila Sahu static int 67343e610bbSSunila Sahu zip_pci_remove(struct rte_pci_device *pci_dev) 67443e610bbSSunila Sahu { 67543e610bbSSunila Sahu struct rte_compressdev *compressdev; 67643e610bbSSunila Sahu char compressdev_name[RTE_COMPRESSDEV_NAME_MAX_LEN]; 67743e610bbSSunila Sahu 67843e610bbSSunila Sahu if (pci_dev == NULL) { 679*f665790aSDavid Marchand ZIP_PMD_ERR(" Invalid PCI Device"); 68043e610bbSSunila Sahu return -EINVAL; 68143e610bbSSunila Sahu } 68243e610bbSSunila Sahu rte_pci_device_name(&pci_dev->addr, compressdev_name, 68343e610bbSSunila Sahu sizeof(compressdev_name)); 68443e610bbSSunila Sahu 68543e610bbSSunila Sahu compressdev = rte_compressdev_pmd_get_named_dev(compressdev_name); 68643e610bbSSunila Sahu if (compressdev == NULL) 68743e610bbSSunila Sahu return -ENODEV; 68843e610bbSSunila Sahu 68943e610bbSSunila Sahu if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 69043e610bbSSunila Sahu if (zipvf_destroy(compressdev) < 0) 69143e610bbSSunila Sahu return -ENODEV; 69243e610bbSSunila Sahu } 69343e610bbSSunila Sahu return rte_compressdev_pmd_destroy(compressdev); 69443e610bbSSunila Sahu } 69543e610bbSSunila Sahu 69643e610bbSSunila Sahu static struct rte_pci_id pci_id_octtx_zipvf_table[] = { 69743e610bbSSunila Sahu { 69843e610bbSSunila Sahu RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, 69943e610bbSSunila Sahu PCI_DEVICE_ID_OCTEONTX_ZIPVF), 70043e610bbSSunila Sahu }, 70143e610bbSSunila Sahu { 702a80ea5c0SMahipal Challa RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, 703a80ea5c0SMahipal Challa PCI_DEVICE_ID_OCTEONTX2_ZIPVF), 704a80ea5c0SMahipal Challa }, 705a80ea5c0SMahipal Challa { 70643e610bbSSunila Sahu .device_id = 0 70743e610bbSSunila Sahu }, 70843e610bbSSunila Sahu }; 70943e610bbSSunila Sahu 71043e610bbSSunila Sahu /** 71143e610bbSSunila Sahu * Structure that represents a PCI driver 71243e610bbSSunila Sahu */ 71343e610bbSSunila Sahu static struct rte_pci_driver octtx_zip_pmd = { 71443e610bbSSunila Sahu .id_table = pci_id_octtx_zipvf_table, 71543e610bbSSunila Sahu .drv_flags = RTE_PCI_DRV_NEED_MAPPING, 71643e610bbSSunila Sahu .probe = zip_pci_probe, 71743e610bbSSunila Sahu .remove = zip_pci_remove, 71843e610bbSSunila Sahu }; 71943e610bbSSunila Sahu 72043e610bbSSunila Sahu RTE_PMD_REGISTER_PCI(COMPRESSDEV_NAME_ZIP_PMD, octtx_zip_pmd); 72143e610bbSSunila Sahu RTE_PMD_REGISTER_PCI_TABLE(COMPRESSDEV_NAME_ZIP_PMD, pci_id_octtx_zipvf_table); 722eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(octtx_zip_logtype_driver, INFO); 723