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 | 19c378f084SAshish Gupta RTE_COMP_FF_HUFFMAN_DYNAMIC, 20c378f084SAshish Gupta /* Non sharable Priv XFORM and Stateless */ 21c378f084SAshish Gupta .window_size = { 22c378f084SAshish Gupta .min = 1, 23c378f084SAshish Gupta .max = 14, 24c378f084SAshish Gupta .increment = 1 25c378f084SAshish Gupta /* size supported 2^1 to 2^14 */ 26c378f084SAshish Gupta }, 27c378f084SAshish Gupta }, 28c378f084SAshish Gupta RTE_COMP_END_OF_CAPABILITIES_LIST() 29c378f084SAshish Gupta }; 3043e610bbSSunila Sahu 3152048f8fSAshish Gupta /* 3252048f8fSAshish Gupta * Reset session to default state for next set of stateless operation 3352048f8fSAshish Gupta */ 3452048f8fSAshish Gupta static inline void 35*938f3f5fSMahipal Challa reset_stream(union zip_inst_s *inst) 3652048f8fSAshish Gupta { 3752048f8fSAshish Gupta inst->s.bf = 1; 3852048f8fSAshish Gupta inst->s.ef = 0; 3952048f8fSAshish Gupta } 4052048f8fSAshish Gupta 4152048f8fSAshish Gupta int 4252048f8fSAshish Gupta zip_process_op(struct rte_comp_op *op, 4352048f8fSAshish Gupta struct zipvf_qp *qp, 44*938f3f5fSMahipal Challa struct zip_stream *zstrm, int num) 4552048f8fSAshish Gupta { 46*938f3f5fSMahipal Challa union zip_inst_s *inst = zstrm->inst[num]; 4752048f8fSAshish Gupta volatile union zip_zres_s *zresult = NULL; 4852048f8fSAshish Gupta 4952048f8fSAshish Gupta if ((op->m_src->nb_segs > 1) || (op->m_dst->nb_segs > 1) || 5052048f8fSAshish Gupta (op->src.offset > rte_pktmbuf_pkt_len(op->m_src)) || 5152048f8fSAshish Gupta (op->dst.offset > rte_pktmbuf_pkt_len(op->m_dst))) { 5252048f8fSAshish Gupta op->status = RTE_COMP_OP_STATUS_INVALID_ARGS; 5352048f8fSAshish Gupta ZIP_PMD_ERR("Segmented packet is not supported\n"); 5452048f8fSAshish Gupta return 0; 5552048f8fSAshish Gupta } 5652048f8fSAshish Gupta 57*938f3f5fSMahipal Challa zipvf_prepare_cmd_stateless(op, inst); 5852048f8fSAshish Gupta 59*938f3f5fSMahipal Challa zresult = (union zip_zres_s *)zstrm->bufs[RES_BUF + num]; 6052048f8fSAshish Gupta zresult->s.compcode = 0; 6152048f8fSAshish Gupta 6252048f8fSAshish Gupta #ifdef ZIP_DBG 6352048f8fSAshish Gupta zip_dump_instruction(inst); 6452048f8fSAshish Gupta #endif 6552048f8fSAshish Gupta 6652048f8fSAshish Gupta /* Submit zip command */ 6752048f8fSAshish Gupta zipvf_push_command(qp, (void *)inst); 6852048f8fSAshish Gupta 6952048f8fSAshish Gupta return 0; 7052048f8fSAshish Gupta } 7152048f8fSAshish Gupta 72b43ebc65SAshish Gupta /** Parse xform parameters and setup a stream */ 73b43ebc65SAshish Gupta static int 74b43ebc65SAshish Gupta zip_set_stream_parameters(struct rte_compressdev *dev, 75b43ebc65SAshish Gupta const struct rte_comp_xform *xform, 76b43ebc65SAshish Gupta struct zip_stream *z_stream) 77b43ebc65SAshish Gupta { 78b43ebc65SAshish Gupta struct zip_vf *vf = (struct zip_vf *)dev->data->dev_private; 79*938f3f5fSMahipal Challa union zip_inst_s *inst; 80b43ebc65SAshish Gupta void *res; 81*938f3f5fSMahipal Challa int ret, i; 82b43ebc65SAshish Gupta 83b43ebc65SAshish Gupta /* Allocate resources required by a stream */ 84b43ebc65SAshish Gupta ret = rte_mempool_get_bulk(vf->zip_mp, 85*938f3f5fSMahipal Challa z_stream->bufs, (MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE)); 86b43ebc65SAshish Gupta if (ret < 0) 87b43ebc65SAshish Gupta return -1; 88b43ebc65SAshish Gupta 89*938f3f5fSMahipal Challa for (i = 0; i < ZIP_BURST_SIZE; i++) { 90b43ebc65SAshish Gupta /* get one command buffer from pool and set up */ 91*938f3f5fSMahipal Challa inst = (union zip_inst_s *)z_stream->bufs[(CMD_BUF * ZIP_BURST_SIZE) + i]; 92*938f3f5fSMahipal Challa res = z_stream->bufs[(RES_BUF * ZIP_BURST_SIZE) + i]; 93b43ebc65SAshish Gupta memset(inst->u, 0, sizeof(inst->u)); 94b43ebc65SAshish Gupta 95b43ebc65SAshish Gupta /* set bf for only first ops of stream */ 96b43ebc65SAshish Gupta inst->s.bf = 1; 97b43ebc65SAshish Gupta 98b43ebc65SAshish Gupta if (xform->type == RTE_COMP_COMPRESS) { 99b43ebc65SAshish Gupta inst->s.op = ZIP_OP_E_COMP; 100b43ebc65SAshish Gupta 101b43ebc65SAshish Gupta switch (xform->compress.deflate.huffman) { 102b43ebc65SAshish Gupta case RTE_COMP_HUFFMAN_DEFAULT: 103b43ebc65SAshish Gupta inst->s.cc = ZIP_CC_DEFAULT; 104b43ebc65SAshish Gupta break; 105b43ebc65SAshish Gupta case RTE_COMP_HUFFMAN_FIXED: 106b43ebc65SAshish Gupta inst->s.cc = ZIP_CC_FIXED_HUFF; 107b43ebc65SAshish Gupta break; 108b43ebc65SAshish Gupta case RTE_COMP_HUFFMAN_DYNAMIC: 109b43ebc65SAshish Gupta inst->s.cc = ZIP_CC_DYN_HUFF; 110b43ebc65SAshish Gupta break; 111b43ebc65SAshish Gupta default: 112b43ebc65SAshish Gupta ret = -1; 113b43ebc65SAshish Gupta goto err; 114b43ebc65SAshish Gupta } 115b43ebc65SAshish Gupta 116b43ebc65SAshish Gupta switch (xform->compress.level) { 117b43ebc65SAshish Gupta case RTE_COMP_LEVEL_MIN: 118b43ebc65SAshish Gupta inst->s.ss = ZIP_COMP_E_LEVEL_MIN; 119b43ebc65SAshish Gupta break; 120b43ebc65SAshish Gupta case RTE_COMP_LEVEL_MAX: 121b43ebc65SAshish Gupta inst->s.ss = ZIP_COMP_E_LEVEL_MAX; 122b43ebc65SAshish Gupta break; 123b43ebc65SAshish Gupta case RTE_COMP_LEVEL_NONE: 124b43ebc65SAshish Gupta ZIP_PMD_ERR("Compression level not supported"); 125b43ebc65SAshish Gupta ret = -1; 126b43ebc65SAshish Gupta goto err; 127b43ebc65SAshish Gupta default: 128b43ebc65SAshish Gupta /* for any value between min and max , choose 129b43ebc65SAshish Gupta * PMD default. 130b43ebc65SAshish Gupta */ 131b43ebc65SAshish Gupta inst->s.ss = ZIP_COMP_E_LEVEL_MED; /** PMD default **/ 132b43ebc65SAshish Gupta break; 133b43ebc65SAshish Gupta } 134b43ebc65SAshish Gupta } else if (xform->type == RTE_COMP_DECOMPRESS) { 135b43ebc65SAshish Gupta inst->s.op = ZIP_OP_E_DECOMP; 136b43ebc65SAshish Gupta /* from HRM, 137b43ebc65SAshish Gupta * For DEFLATE decompression, [CC] must be 0x0. 138b43ebc65SAshish Gupta * For decompression, [SS] must be 0x0 139b43ebc65SAshish Gupta */ 140b43ebc65SAshish Gupta inst->s.cc = 0; 141b43ebc65SAshish Gupta /* Speed bit should not be set for decompression */ 142b43ebc65SAshish Gupta inst->s.ss = 0; 143b43ebc65SAshish Gupta /* decompression context is supported only for STATEFUL 144b43ebc65SAshish Gupta * operations. Currently we support STATELESS ONLY so 145b43ebc65SAshish Gupta * skip setting of ctx pointer 146b43ebc65SAshish Gupta */ 147b43ebc65SAshish Gupta 148b43ebc65SAshish Gupta } else { 149b43ebc65SAshish Gupta ZIP_PMD_ERR("\nxform type not supported"); 150b43ebc65SAshish Gupta ret = -1; 151b43ebc65SAshish Gupta goto err; 152b43ebc65SAshish Gupta } 153b43ebc65SAshish Gupta 154b43ebc65SAshish Gupta inst->s.res_ptr_addr.s.addr = rte_mempool_virt2iova(res); 155b43ebc65SAshish Gupta inst->s.res_ptr_ctl.s.length = 0; 156b43ebc65SAshish Gupta 157*938f3f5fSMahipal Challa z_stream->inst[i] = inst; 158*938f3f5fSMahipal Challa } 159*938f3f5fSMahipal Challa 16052048f8fSAshish Gupta z_stream->func = zip_process_op; 161b43ebc65SAshish Gupta 162b43ebc65SAshish Gupta return 0; 163b43ebc65SAshish Gupta 164b43ebc65SAshish Gupta err: 165b43ebc65SAshish Gupta rte_mempool_put_bulk(vf->zip_mp, 166b43ebc65SAshish Gupta (void *)&(z_stream->bufs[0]), 167*938f3f5fSMahipal Challa (MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE)); 168b43ebc65SAshish Gupta 169b43ebc65SAshish Gupta return ret; 170b43ebc65SAshish Gupta } 171b43ebc65SAshish Gupta 172c378f084SAshish Gupta /** Configure device */ 173c378f084SAshish Gupta static int 174c378f084SAshish Gupta zip_pmd_config(struct rte_compressdev *dev, 175c378f084SAshish Gupta struct rte_compressdev_config *config) 176c378f084SAshish Gupta { 177c378f084SAshish Gupta int nb_streams; 178c378f084SAshish Gupta char res_pool[RTE_MEMZONE_NAMESIZE]; 179c378f084SAshish Gupta struct zip_vf *vf; 180c378f084SAshish Gupta struct rte_mempool *zip_buf_mp; 181c378f084SAshish Gupta 182c378f084SAshish Gupta if (!config || !dev) 183c378f084SAshish Gupta return -EIO; 184c378f084SAshish Gupta 185c378f084SAshish Gupta vf = (struct zip_vf *)(dev->data->dev_private); 186c378f084SAshish Gupta 187c378f084SAshish Gupta /* create pool with maximum numbers of resources 188c378f084SAshish Gupta * required by streams 189c378f084SAshish Gupta */ 190c378f084SAshish Gupta 191c378f084SAshish Gupta /* use common pool for non-shareable priv_xform and stream */ 192c378f084SAshish Gupta nb_streams = config->max_nb_priv_xforms + config->max_nb_streams; 193c378f084SAshish Gupta 194c378f084SAshish Gupta snprintf(res_pool, RTE_MEMZONE_NAMESIZE, "octtx_zip_res_pool%u", 195c378f084SAshish Gupta dev->data->dev_id); 196c378f084SAshish Gupta 197c378f084SAshish Gupta /** TBD Should we use the per core object cache for stream resources */ 198c378f084SAshish Gupta zip_buf_mp = rte_mempool_create( 199c378f084SAshish Gupta res_pool, 200*938f3f5fSMahipal Challa (nb_streams * MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE), 201c378f084SAshish Gupta ZIP_BUF_SIZE, 202c378f084SAshish Gupta 0, 203c378f084SAshish Gupta 0, 204c378f084SAshish Gupta NULL, 205c378f084SAshish Gupta NULL, 206c378f084SAshish Gupta NULL, 207c378f084SAshish Gupta NULL, 208c378f084SAshish Gupta SOCKET_ID_ANY, 209c378f084SAshish Gupta 0); 210c378f084SAshish Gupta 211c378f084SAshish Gupta if (zip_buf_mp == NULL) { 212c378f084SAshish Gupta ZIP_PMD_ERR( 213c378f084SAshish Gupta "Failed to create buf mempool octtx_zip_res_pool%u", 214c378f084SAshish Gupta dev->data->dev_id); 215c378f084SAshish Gupta return -1; 216c378f084SAshish Gupta } 217c378f084SAshish Gupta 218c378f084SAshish Gupta vf->zip_mp = zip_buf_mp; 219c378f084SAshish Gupta 220c378f084SAshish Gupta return 0; 221c378f084SAshish Gupta } 222c378f084SAshish Gupta 223c378f084SAshish Gupta /** Start device */ 224c378f084SAshish Gupta static int 225c378f084SAshish Gupta zip_pmd_start(__rte_unused struct rte_compressdev *dev) 226c378f084SAshish Gupta { 227c378f084SAshish Gupta return 0; 228c378f084SAshish Gupta } 229c378f084SAshish Gupta 230c378f084SAshish Gupta /** Stop device */ 231c378f084SAshish Gupta static void 232c378f084SAshish Gupta zip_pmd_stop(__rte_unused struct rte_compressdev *dev) 233c378f084SAshish Gupta { 234c378f084SAshish Gupta 235c378f084SAshish Gupta } 236c378f084SAshish Gupta 237c378f084SAshish Gupta /** Close device */ 238c378f084SAshish Gupta static int 239c378f084SAshish Gupta zip_pmd_close(struct rte_compressdev *dev) 240c378f084SAshish Gupta { 241c378f084SAshish Gupta if (dev == NULL) 242c378f084SAshish Gupta return -1; 243c378f084SAshish Gupta 244c378f084SAshish Gupta struct zip_vf *vf = (struct zip_vf *)dev->data->dev_private; 245c378f084SAshish Gupta rte_mempool_free(vf->zip_mp); 246c378f084SAshish Gupta 247c378f084SAshish Gupta return 0; 248c378f084SAshish Gupta } 249c378f084SAshish Gupta 250c378f084SAshish Gupta /** Get device statistics */ 251c378f084SAshish Gupta static void 252c378f084SAshish Gupta zip_pmd_stats_get(struct rte_compressdev *dev, 253c378f084SAshish Gupta struct rte_compressdev_stats *stats) 254c378f084SAshish Gupta { 255c378f084SAshish Gupta int qp_id; 256c378f084SAshish Gupta 257c378f084SAshish Gupta for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { 258c378f084SAshish Gupta struct zipvf_qp *qp = dev->data->queue_pairs[qp_id]; 259c378f084SAshish Gupta 260c378f084SAshish Gupta stats->enqueued_count += qp->qp_stats.enqueued_count; 261c378f084SAshish Gupta stats->dequeued_count += qp->qp_stats.dequeued_count; 262c378f084SAshish Gupta 263c378f084SAshish Gupta stats->enqueue_err_count += qp->qp_stats.enqueue_err_count; 264c378f084SAshish Gupta stats->dequeue_err_count += qp->qp_stats.dequeue_err_count; 265c378f084SAshish Gupta } 266c378f084SAshish Gupta } 267c378f084SAshish Gupta 268c378f084SAshish Gupta /** Reset device statistics */ 269c378f084SAshish Gupta static void 270c378f084SAshish Gupta zip_pmd_stats_reset(struct rte_compressdev *dev) 271c378f084SAshish Gupta { 272c378f084SAshish Gupta int qp_id; 273c378f084SAshish Gupta 274c378f084SAshish Gupta for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { 275c378f084SAshish Gupta struct zipvf_qp *qp = dev->data->queue_pairs[qp_id]; 276c378f084SAshish Gupta memset(&qp->qp_stats, 0, sizeof(qp->qp_stats)); 277c378f084SAshish Gupta } 278c378f084SAshish Gupta } 279c378f084SAshish Gupta 280c378f084SAshish Gupta /** Get device info */ 281c378f084SAshish Gupta static void 282c378f084SAshish Gupta zip_pmd_info_get(struct rte_compressdev *dev, 283c378f084SAshish Gupta struct rte_compressdev_info *dev_info) 284c378f084SAshish Gupta { 285c378f084SAshish Gupta struct zip_vf *vf = (struct zip_vf *)dev->data->dev_private; 286c378f084SAshish Gupta 287c378f084SAshish Gupta if (dev_info != NULL) { 288c378f084SAshish Gupta dev_info->driver_name = dev->device->driver->name; 289c378f084SAshish Gupta dev_info->feature_flags = dev->feature_flags; 290c378f084SAshish Gupta dev_info->capabilities = octtx_zip_pmd_capabilities; 291c378f084SAshish Gupta dev_info->max_nb_queue_pairs = vf->max_nb_queue_pairs; 292c378f084SAshish Gupta } 293c378f084SAshish Gupta } 294c378f084SAshish Gupta 295c378f084SAshish Gupta /** Release queue pair */ 296c378f084SAshish Gupta static int 297c378f084SAshish Gupta zip_pmd_qp_release(struct rte_compressdev *dev, uint16_t qp_id) 298c378f084SAshish Gupta { 299c378f084SAshish Gupta struct zipvf_qp *qp = dev->data->queue_pairs[qp_id]; 300c378f084SAshish Gupta 301c378f084SAshish Gupta if (qp != NULL) { 302c378f084SAshish Gupta zipvf_q_term(qp); 303c378f084SAshish Gupta 304c378f084SAshish Gupta rte_ring_free(qp->processed_pkts); 305c378f084SAshish Gupta 306c378f084SAshish Gupta rte_free(qp); 307c378f084SAshish Gupta dev->data->queue_pairs[qp_id] = NULL; 308c378f084SAshish Gupta } 309c378f084SAshish Gupta return 0; 310c378f084SAshish Gupta } 311c378f084SAshish Gupta 312c378f084SAshish Gupta /** Create a ring to place process packets on */ 313c378f084SAshish Gupta static struct rte_ring * 314c378f084SAshish Gupta zip_pmd_qp_create_processed_pkts_ring(struct zipvf_qp *qp, 315c378f084SAshish Gupta unsigned int ring_size, int socket_id) 316c378f084SAshish Gupta { 317c378f084SAshish Gupta struct rte_ring *r; 318c378f084SAshish Gupta 319c378f084SAshish Gupta r = rte_ring_lookup(qp->name); 320c378f084SAshish Gupta if (r) { 321c378f084SAshish Gupta if (rte_ring_get_size(r) >= ring_size) { 322c378f084SAshish Gupta ZIP_PMD_INFO("Reusing existing ring %s for processed" 323c378f084SAshish Gupta " packets", qp->name); 324c378f084SAshish Gupta return r; 325c378f084SAshish Gupta } 326c378f084SAshish Gupta 327c378f084SAshish Gupta ZIP_PMD_ERR("Unable to reuse existing ring %s for processed" 328c378f084SAshish Gupta " packets", qp->name); 329c378f084SAshish Gupta return NULL; 330c378f084SAshish Gupta } 331c378f084SAshish Gupta 332c378f084SAshish Gupta return rte_ring_create(qp->name, ring_size, socket_id, 333c378f084SAshish Gupta RING_F_EXACT_SZ); 334c378f084SAshish Gupta } 335c378f084SAshish Gupta 336c378f084SAshish Gupta /** Setup a queue pair */ 337c378f084SAshish Gupta static int 338c378f084SAshish Gupta zip_pmd_qp_setup(struct rte_compressdev *dev, uint16_t qp_id, 339c378f084SAshish Gupta uint32_t max_inflight_ops, int socket_id) 340c378f084SAshish Gupta { 341c378f084SAshish Gupta struct zipvf_qp *qp = NULL; 342c378f084SAshish Gupta struct zip_vf *vf; 343c378f084SAshish Gupta char *name; 344c378f084SAshish Gupta int ret; 345c378f084SAshish Gupta 346c378f084SAshish Gupta if (!dev) 347c378f084SAshish Gupta return -1; 348c378f084SAshish Gupta 349c378f084SAshish Gupta vf = (struct zip_vf *) (dev->data->dev_private); 350c378f084SAshish Gupta 351c378f084SAshish Gupta /* Free memory prior to re-allocation if needed. */ 352c378f084SAshish Gupta if (dev->data->queue_pairs[qp_id] != NULL) { 353c378f084SAshish Gupta ZIP_PMD_INFO("Using existing queue pair %d ", qp_id); 354c378f084SAshish Gupta return 0; 355c378f084SAshish Gupta } 356c378f084SAshish Gupta 357c378f084SAshish Gupta name = rte_malloc(NULL, RTE_COMPRESSDEV_NAME_MAX_LEN, 0); 358b072930fSWeiguo Li if (name == NULL) 359b072930fSWeiguo Li return (-ENOMEM); 360c378f084SAshish Gupta snprintf(name, RTE_COMPRESSDEV_NAME_MAX_LEN, 361c378f084SAshish Gupta "zip_pmd_%u_qp_%u", 362c378f084SAshish Gupta dev->data->dev_id, qp_id); 363c378f084SAshish Gupta 364c378f084SAshish Gupta /* Allocate the queue pair data structure. */ 365c378f084SAshish Gupta qp = rte_zmalloc_socket(name, sizeof(*qp), 366c378f084SAshish Gupta RTE_CACHE_LINE_SIZE, socket_id); 367b072930fSWeiguo Li if (qp == NULL) { 368b072930fSWeiguo Li rte_free(name); 369c378f084SAshish Gupta return (-ENOMEM); 370b072930fSWeiguo Li } 371c378f084SAshish Gupta 372c378f084SAshish Gupta qp->name = name; 373c378f084SAshish Gupta 374c378f084SAshish Gupta /* Create completion queue up to max_inflight_ops */ 375c378f084SAshish Gupta qp->processed_pkts = zip_pmd_qp_create_processed_pkts_ring(qp, 376c378f084SAshish Gupta max_inflight_ops, socket_id); 377c378f084SAshish Gupta if (qp->processed_pkts == NULL) 378c378f084SAshish Gupta goto qp_setup_cleanup; 379c378f084SAshish Gupta 380c378f084SAshish Gupta qp->id = qp_id; 381c378f084SAshish Gupta qp->vf = vf; 382c378f084SAshish Gupta 383c378f084SAshish Gupta ret = zipvf_q_init(qp); 384c378f084SAshish Gupta if (ret < 0) 385c378f084SAshish Gupta goto qp_setup_cleanup; 386c378f084SAshish Gupta 387c378f084SAshish Gupta dev->data->queue_pairs[qp_id] = qp; 388c378f084SAshish Gupta 389c378f084SAshish Gupta memset(&qp->qp_stats, 0, sizeof(qp->qp_stats)); 390c378f084SAshish Gupta return 0; 391c378f084SAshish Gupta 392c378f084SAshish Gupta qp_setup_cleanup: 393c378f084SAshish Gupta rte_ring_free(qp->processed_pkts); 394c378f084SAshish Gupta rte_free(qp); 395c378f084SAshish Gupta return -1; 396c378f084SAshish Gupta } 397c378f084SAshish Gupta 398b43ebc65SAshish Gupta static int 399b43ebc65SAshish Gupta zip_pmd_stream_create(struct rte_compressdev *dev, 400b43ebc65SAshish Gupta const struct rte_comp_xform *xform, void **stream) 401b43ebc65SAshish Gupta { 402b43ebc65SAshish Gupta int ret; 403b43ebc65SAshish Gupta struct zip_stream *strm = NULL; 404b43ebc65SAshish Gupta 405b43ebc65SAshish Gupta strm = rte_malloc(NULL, 406b43ebc65SAshish Gupta sizeof(struct zip_stream), 0); 407b43ebc65SAshish Gupta 408b43ebc65SAshish Gupta if (strm == NULL) 409b43ebc65SAshish Gupta return (-ENOMEM); 410b43ebc65SAshish Gupta 411b43ebc65SAshish Gupta ret = zip_set_stream_parameters(dev, xform, strm); 412b43ebc65SAshish Gupta if (ret < 0) { 413b43ebc65SAshish Gupta ZIP_PMD_ERR("failed configure xform parameters"); 414b43ebc65SAshish Gupta rte_free(strm); 415b43ebc65SAshish Gupta return ret; 416b43ebc65SAshish Gupta } 417b43ebc65SAshish Gupta *stream = strm; 418*938f3f5fSMahipal Challa 419b43ebc65SAshish Gupta return 0; 420b43ebc65SAshish Gupta } 421b43ebc65SAshish Gupta 422b43ebc65SAshish Gupta static int 423b43ebc65SAshish Gupta zip_pmd_stream_free(struct rte_compressdev *dev, void *stream) 424b43ebc65SAshish Gupta { 425b43ebc65SAshish Gupta struct zip_vf *vf = (struct zip_vf *) (dev->data->dev_private); 426b43ebc65SAshish Gupta struct zip_stream *z_stream; 427b43ebc65SAshish Gupta 428b43ebc65SAshish Gupta if (stream == NULL) 429b43ebc65SAshish Gupta return 0; 430b43ebc65SAshish Gupta 431b43ebc65SAshish Gupta z_stream = (struct zip_stream *)stream; 432b43ebc65SAshish Gupta 433b43ebc65SAshish Gupta /* Free resources back to pool */ 434b43ebc65SAshish Gupta rte_mempool_put_bulk(vf->zip_mp, 435b43ebc65SAshish Gupta (void *)&(z_stream->bufs[0]), 436*938f3f5fSMahipal Challa (MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE)); 437b43ebc65SAshish Gupta 438b43ebc65SAshish Gupta /* Zero out the whole structure */ 439b43ebc65SAshish Gupta memset(stream, 0, sizeof(struct zip_stream)); 440b43ebc65SAshish Gupta rte_free(stream); 441b43ebc65SAshish Gupta 442b43ebc65SAshish Gupta return 0; 443b43ebc65SAshish Gupta } 444b43ebc65SAshish Gupta 445b43ebc65SAshish Gupta 44652048f8fSAshish Gupta static uint16_t 447*938f3f5fSMahipal Challa zip_pmd_enqueue_burst(void *queue_pair, 44852048f8fSAshish Gupta struct rte_comp_op **ops, uint16_t nb_ops) 44952048f8fSAshish Gupta { 45052048f8fSAshish Gupta struct zipvf_qp *qp = queue_pair; 45152048f8fSAshish Gupta struct zip_stream *zstrm; 452*938f3f5fSMahipal Challa struct rte_comp_op *op; 45352048f8fSAshish Gupta int i, ret = 0; 45452048f8fSAshish Gupta uint16_t enqd = 0; 45552048f8fSAshish Gupta 45652048f8fSAshish Gupta for (i = 0; i < nb_ops; i++) { 45752048f8fSAshish Gupta op = ops[i]; 45852048f8fSAshish Gupta 45952048f8fSAshish Gupta if (op->op_type == RTE_COMP_OP_STATEFUL) { 46052048f8fSAshish Gupta op->status = RTE_COMP_OP_STATUS_INVALID_ARGS; 46152048f8fSAshish Gupta } else { 46252048f8fSAshish Gupta /* process stateless ops */ 46352048f8fSAshish Gupta zstrm = (struct zip_stream *)op->private_xform; 46452048f8fSAshish Gupta if (unlikely(zstrm == NULL)) 46552048f8fSAshish Gupta op->status = RTE_COMP_OP_STATUS_INVALID_ARGS; 46652048f8fSAshish Gupta else 467*938f3f5fSMahipal Challa ret = zstrm->func(op, qp, zstrm, i); 46852048f8fSAshish Gupta } 46952048f8fSAshish Gupta 47052048f8fSAshish Gupta /* Whatever is out of op, put it into completion queue with 47152048f8fSAshish Gupta * its status 47252048f8fSAshish Gupta */ 47352048f8fSAshish Gupta if (!ret) 47452048f8fSAshish Gupta ret = rte_ring_enqueue(qp->processed_pkts, (void *)op); 47552048f8fSAshish Gupta 47652048f8fSAshish Gupta if (unlikely(ret < 0)) { 47752048f8fSAshish Gupta /* increment count if failed to enqueue op*/ 47852048f8fSAshish Gupta qp->qp_stats.enqueue_err_count++; 47952048f8fSAshish Gupta } else { 48052048f8fSAshish Gupta qp->qp_stats.enqueued_count++; 48152048f8fSAshish Gupta enqd++; 48252048f8fSAshish Gupta } 48352048f8fSAshish Gupta } 484*938f3f5fSMahipal Challa 485*938f3f5fSMahipal Challa #ifdef ZIP_DBG 486*938f3f5fSMahipal Challa ZIP_PMD_INFO("ops_enqd[nb_ops:%d]:%d\n", nb_ops, enqd); 487*938f3f5fSMahipal Challa #endif 48852048f8fSAshish Gupta return enqd; 48952048f8fSAshish Gupta } 49052048f8fSAshish Gupta 49152048f8fSAshish Gupta static uint16_t 492*938f3f5fSMahipal Challa zip_pmd_dequeue_burst(void *queue_pair, 49352048f8fSAshish Gupta struct rte_comp_op **ops, uint16_t nb_ops) 49452048f8fSAshish Gupta { 495*938f3f5fSMahipal Challa volatile union zip_zres_s *zresult = NULL; 49652048f8fSAshish Gupta struct zipvf_qp *qp = queue_pair; 49752048f8fSAshish Gupta 49852048f8fSAshish Gupta unsigned int nb_dequeued = 0; 499*938f3f5fSMahipal Challa struct zip_stream *zstrm; 500*938f3f5fSMahipal Challa struct rte_comp_op *op; 501*938f3f5fSMahipal Challa unsigned int i; 50252048f8fSAshish Gupta 50352048f8fSAshish Gupta nb_dequeued = rte_ring_dequeue_burst(qp->processed_pkts, 50452048f8fSAshish Gupta (void **)ops, nb_ops, NULL); 50552048f8fSAshish Gupta qp->qp_stats.dequeued_count += nb_dequeued; 50652048f8fSAshish Gupta 507*938f3f5fSMahipal Challa /* Dequeue all the submitted ops */ 508*938f3f5fSMahipal Challa for (i = 0; i < nb_dequeued; i++) { 509*938f3f5fSMahipal Challa op = ops[i]; 510*938f3f5fSMahipal Challa /* process stateless ops */ 511*938f3f5fSMahipal Challa zstrm = (struct zip_stream *)op->private_xform; 512*938f3f5fSMahipal Challa zresult = (union zip_zres_s *)zstrm->bufs[RES_BUF + i]; 513*938f3f5fSMahipal Challa 514*938f3f5fSMahipal Challa /* Check and Process results in sync mode */ 515*938f3f5fSMahipal Challa do { 516*938f3f5fSMahipal Challa } while (!zresult->s.compcode); 517*938f3f5fSMahipal Challa 518*938f3f5fSMahipal Challa if (zresult->s.compcode == ZIP_COMP_E_SUCCESS) { 519*938f3f5fSMahipal Challa op->status = RTE_COMP_OP_STATUS_SUCCESS; 520*938f3f5fSMahipal Challa } else { 521*938f3f5fSMahipal Challa /* FATAL error cannot do anything */ 522*938f3f5fSMahipal Challa ZIP_PMD_ERR("operation failed with error code:%d\n", 523*938f3f5fSMahipal Challa zresult->s.compcode); 524*938f3f5fSMahipal Challa if (zresult->s.compcode == ZIP_COMP_E_DSTOP) 525*938f3f5fSMahipal Challa op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED; 526*938f3f5fSMahipal Challa else 527*938f3f5fSMahipal Challa op->status = RTE_COMP_OP_STATUS_ERROR; 528*938f3f5fSMahipal Challa } 529*938f3f5fSMahipal Challa 530*938f3f5fSMahipal Challa #ifdef ZIP_DBG 531*938f3f5fSMahipal Challa ZIP_PMD_INFO("written %d\n", zresult->s.totalbyteswritten); 532*938f3f5fSMahipal Challa #endif 533*938f3f5fSMahipal Challa 534*938f3f5fSMahipal Challa /* Update op stats */ 535*938f3f5fSMahipal Challa switch (op->status) { 536*938f3f5fSMahipal Challa case RTE_COMP_OP_STATUS_SUCCESS: 537*938f3f5fSMahipal Challa op->consumed = zresult->s.totalbytesread; 538*938f3f5fSMahipal Challa /* Fall-through */ 539*938f3f5fSMahipal Challa case RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED: 540*938f3f5fSMahipal Challa op->produced = zresult->s.totalbyteswritten; 541*938f3f5fSMahipal Challa break; 542*938f3f5fSMahipal Challa default: 543*938f3f5fSMahipal Challa ZIP_PMD_ERR("stats not updated for status:%d\n", 544*938f3f5fSMahipal Challa op->status); 545*938f3f5fSMahipal Challa break; 546*938f3f5fSMahipal Challa } 547*938f3f5fSMahipal Challa 548*938f3f5fSMahipal Challa /* zstream is reset irrespective of result */ 549*938f3f5fSMahipal Challa reset_stream(zstrm->inst[i]); 550*938f3f5fSMahipal Challa zresult->s.compcode = ZIP_COMP_E_NOTDONE; 551*938f3f5fSMahipal Challa } 552*938f3f5fSMahipal Challa 553*938f3f5fSMahipal Challa #ifdef ZIP_DBG 554*938f3f5fSMahipal Challa ZIP_PMD_INFO("ops_deqd[nb_ops:%d]: %d\n", nb_ops, nb_dequeued); 555*938f3f5fSMahipal Challa #endif 55652048f8fSAshish Gupta return nb_dequeued; 55752048f8fSAshish Gupta } 55852048f8fSAshish Gupta 559b74fd6b8SFerruh Yigit static struct rte_compressdev_ops octtx_zip_pmd_ops = { 560c378f084SAshish Gupta .dev_configure = zip_pmd_config, 561c378f084SAshish Gupta .dev_start = zip_pmd_start, 562c378f084SAshish Gupta .dev_stop = zip_pmd_stop, 563c378f084SAshish Gupta .dev_close = zip_pmd_close, 564c378f084SAshish Gupta 565c378f084SAshish Gupta .stats_get = zip_pmd_stats_get, 566c378f084SAshish Gupta .stats_reset = zip_pmd_stats_reset, 567c378f084SAshish Gupta 568c378f084SAshish Gupta .dev_infos_get = zip_pmd_info_get, 569c378f084SAshish Gupta 570c378f084SAshish Gupta .queue_pair_setup = zip_pmd_qp_setup, 571c378f084SAshish Gupta .queue_pair_release = zip_pmd_qp_release, 572b43ebc65SAshish Gupta 573b43ebc65SAshish Gupta .private_xform_create = zip_pmd_stream_create, 574b43ebc65SAshish Gupta .private_xform_free = zip_pmd_stream_free, 575b43ebc65SAshish Gupta .stream_create = NULL, 576b43ebc65SAshish Gupta .stream_free = NULL 57743e610bbSSunila Sahu }; 57843e610bbSSunila Sahu 57943e610bbSSunila Sahu static int 58043e610bbSSunila Sahu zip_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 58143e610bbSSunila Sahu struct rte_pci_device *pci_dev) 58243e610bbSSunila Sahu { 58343e610bbSSunila Sahu int ret = 0; 58443e610bbSSunila Sahu char compressdev_name[RTE_COMPRESSDEV_NAME_MAX_LEN]; 58543e610bbSSunila Sahu struct rte_compressdev *compressdev; 58643e610bbSSunila Sahu struct rte_compressdev_pmd_init_params init_params = { 58743e610bbSSunila Sahu "", 58843e610bbSSunila Sahu rte_socket_id(), 58943e610bbSSunila Sahu }; 59043e610bbSSunila Sahu 59143e610bbSSunila Sahu ZIP_PMD_INFO("vendor_id=0x%x device_id=0x%x", 59243e610bbSSunila Sahu (unsigned int)pci_dev->id.vendor_id, 59343e610bbSSunila Sahu (unsigned int)pci_dev->id.device_id); 59443e610bbSSunila Sahu 59543e610bbSSunila Sahu rte_pci_device_name(&pci_dev->addr, compressdev_name, 59643e610bbSSunila Sahu sizeof(compressdev_name)); 59743e610bbSSunila Sahu 59843e610bbSSunila Sahu compressdev = rte_compressdev_pmd_create(compressdev_name, 59943e610bbSSunila Sahu &pci_dev->device, sizeof(struct zip_vf), &init_params); 60043e610bbSSunila Sahu if (compressdev == NULL) { 60143e610bbSSunila Sahu ZIP_PMD_ERR("driver %s: create failed", init_params.name); 60243e610bbSSunila Sahu return -ENODEV; 60343e610bbSSunila Sahu } 60443e610bbSSunila Sahu 60543e610bbSSunila Sahu /* 60643e610bbSSunila Sahu * create only if proc_type is primary. 60743e610bbSSunila Sahu */ 60843e610bbSSunila Sahu if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 60943e610bbSSunila Sahu /* create vf dev with given pmd dev id */ 61043e610bbSSunila Sahu ret = zipvf_create(compressdev); 61143e610bbSSunila Sahu if (ret < 0) { 61243e610bbSSunila Sahu ZIP_PMD_ERR("Device creation failed"); 61343e610bbSSunila Sahu rte_compressdev_pmd_destroy(compressdev); 61443e610bbSSunila Sahu return ret; 61543e610bbSSunila Sahu } 61643e610bbSSunila Sahu } 61743e610bbSSunila Sahu 61843e610bbSSunila Sahu compressdev->dev_ops = &octtx_zip_pmd_ops; 61943e610bbSSunila Sahu /* register rx/tx burst functions for data path */ 620*938f3f5fSMahipal Challa compressdev->dequeue_burst = zip_pmd_dequeue_burst; 621*938f3f5fSMahipal Challa compressdev->enqueue_burst = zip_pmd_enqueue_burst; 62243e610bbSSunila Sahu compressdev->feature_flags = RTE_COMPDEV_FF_HW_ACCELERATED; 62343e610bbSSunila Sahu return ret; 62443e610bbSSunila Sahu } 62543e610bbSSunila Sahu 62643e610bbSSunila Sahu static int 62743e610bbSSunila Sahu zip_pci_remove(struct rte_pci_device *pci_dev) 62843e610bbSSunila Sahu { 62943e610bbSSunila Sahu struct rte_compressdev *compressdev; 63043e610bbSSunila Sahu char compressdev_name[RTE_COMPRESSDEV_NAME_MAX_LEN]; 63143e610bbSSunila Sahu 63243e610bbSSunila Sahu if (pci_dev == NULL) { 63343e610bbSSunila Sahu ZIP_PMD_ERR(" Invalid PCI Device\n"); 63443e610bbSSunila Sahu return -EINVAL; 63543e610bbSSunila Sahu } 63643e610bbSSunila Sahu rte_pci_device_name(&pci_dev->addr, compressdev_name, 63743e610bbSSunila Sahu sizeof(compressdev_name)); 63843e610bbSSunila Sahu 63943e610bbSSunila Sahu compressdev = rte_compressdev_pmd_get_named_dev(compressdev_name); 64043e610bbSSunila Sahu if (compressdev == NULL) 64143e610bbSSunila Sahu return -ENODEV; 64243e610bbSSunila Sahu 64343e610bbSSunila Sahu if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 64443e610bbSSunila Sahu if (zipvf_destroy(compressdev) < 0) 64543e610bbSSunila Sahu return -ENODEV; 64643e610bbSSunila Sahu } 64743e610bbSSunila Sahu return rte_compressdev_pmd_destroy(compressdev); 64843e610bbSSunila Sahu } 64943e610bbSSunila Sahu 65043e610bbSSunila Sahu static struct rte_pci_id pci_id_octtx_zipvf_table[] = { 65143e610bbSSunila Sahu { 65243e610bbSSunila Sahu RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, 65343e610bbSSunila Sahu PCI_DEVICE_ID_OCTEONTX_ZIPVF), 65443e610bbSSunila Sahu }, 65543e610bbSSunila Sahu { 656a80ea5c0SMahipal Challa RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, 657a80ea5c0SMahipal Challa PCI_DEVICE_ID_OCTEONTX2_ZIPVF), 658a80ea5c0SMahipal Challa }, 659a80ea5c0SMahipal Challa { 66043e610bbSSunila Sahu .device_id = 0 66143e610bbSSunila Sahu }, 66243e610bbSSunila Sahu }; 66343e610bbSSunila Sahu 66443e610bbSSunila Sahu /** 66543e610bbSSunila Sahu * Structure that represents a PCI driver 66643e610bbSSunila Sahu */ 66743e610bbSSunila Sahu static struct rte_pci_driver octtx_zip_pmd = { 66843e610bbSSunila Sahu .id_table = pci_id_octtx_zipvf_table, 66943e610bbSSunila Sahu .drv_flags = RTE_PCI_DRV_NEED_MAPPING, 67043e610bbSSunila Sahu .probe = zip_pci_probe, 67143e610bbSSunila Sahu .remove = zip_pci_remove, 67243e610bbSSunila Sahu }; 67343e610bbSSunila Sahu 67443e610bbSSunila Sahu RTE_PMD_REGISTER_PCI(COMPRESSDEV_NAME_ZIP_PMD, octtx_zip_pmd); 67543e610bbSSunila Sahu RTE_PMD_REGISTER_PCI_TABLE(COMPRESSDEV_NAME_ZIP_PMD, pci_id_octtx_zipvf_table); 676eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(octtx_zip_logtype_driver, INFO); 677