linux/drivers/crypto/cavium/zip/zip_main.c
<<
>>
Prefs
   1/***********************license start************************************
   2 * Copyright (c) 2003-2017 Cavium, Inc.
   3 * All rights reserved.
   4 *
   5 * License: one of 'Cavium License' or 'GNU General Public License Version 2'
   6 *
   7 * This file is provided under the terms of the Cavium License (see below)
   8 * or under the terms of GNU General Public License, Version 2, as
   9 * published by the Free Software Foundation. When using or redistributing
  10 * this file, you may do so under either license.
  11 *
  12 * Cavium License:  Redistribution and use in source and binary forms, with
  13 * or without modification, are permitted provided that the following
  14 * conditions are met:
  15 *
  16 *  * Redistributions of source code must retain the above copyright
  17 *    notice, this list of conditions and the following disclaimer.
  18 *
  19 *  * Redistributions in binary form must reproduce the above
  20 *    copyright notice, this list of conditions and the following
  21 *    disclaimer in the documentation and/or other materials provided
  22 *    with the distribution.
  23 *
  24 *  * Neither the name of Cavium Inc. nor the names of its contributors may be
  25 *    used to endorse or promote products derived from this software without
  26 *    specific prior written permission.
  27 *
  28 * This Software, including technical data, may be subject to U.S. export
  29 * control laws, including the U.S. Export Administration Act and its
  30 * associated regulations, and may be subject to export or import
  31 * regulations in other countries.
  32 *
  33 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
  34 * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS
  35 * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
  36 * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
  37 * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
  38 * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY)
  39 * WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A
  40 * PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET
  41 * ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE
  42 * ENTIRE  RISK ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES
  43 * WITH YOU.
  44 ***********************license end**************************************/
  45
  46#include "common.h"
  47#include "zip_crypto.h"
  48
  49#define DRV_NAME                "ThunderX-ZIP"
  50
  51static struct zip_device *zip_dev[MAX_ZIP_DEVICES];
  52
  53static const struct pci_device_id zip_id_table[] = {
  54        { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVICE_ID_THUNDERX_ZIP) },
  55        { 0, }
  56};
  57
  58void zip_reg_write(u64 val, u64 __iomem *addr)
  59{
  60        writeq(val, addr);
  61}
  62
  63u64 zip_reg_read(u64 __iomem *addr)
  64{
  65        return readq(addr);
  66}
  67
  68/*
  69 * Allocates new ZIP device structure
  70 * Returns zip_device pointer or NULL if cannot allocate memory for zip_device
  71 */
  72static struct zip_device *zip_alloc_device(struct pci_dev *pdev)
  73{
  74        struct zip_device *zip = NULL;
  75        int idx;
  76
  77        for (idx = 0; idx < MAX_ZIP_DEVICES; idx++) {
  78                if (!zip_dev[idx])
  79                        break;
  80        }
  81
  82        /* To ensure that the index is within the limit */
  83        if (idx < MAX_ZIP_DEVICES)
  84                zip = devm_kzalloc(&pdev->dev, sizeof(*zip), GFP_KERNEL);
  85
  86        if (!zip)
  87                return NULL;
  88
  89        zip_dev[idx] = zip;
  90        zip->index = idx;
  91        return zip;
  92}
  93
  94/**
  95 * zip_get_device - Get ZIP device based on node id of cpu
  96 *
  97 * @node: Node id of the current cpu
  98 * Return: Pointer to Zip device structure
  99 */
 100struct zip_device *zip_get_device(int node)
 101{
 102        if ((node < MAX_ZIP_DEVICES) && (node >= 0))
 103                return zip_dev[node];
 104
 105        zip_err("ZIP device not found for node id %d\n", node);
 106        return NULL;
 107}
 108
 109/**
 110 * zip_get_node_id - Get the node id of the current cpu
 111 *
 112 * Return: Node id of the current cpu
 113 */
 114int zip_get_node_id(void)
 115{
 116        return cpu_to_node(raw_smp_processor_id());
 117}
 118
 119/* Initializes the ZIP h/w sub-system */
 120static int zip_init_hw(struct zip_device *zip)
 121{
 122        union zip_cmd_ctl    cmd_ctl;
 123        union zip_constants  constants;
 124        union zip_que_ena    que_ena;
 125        union zip_quex_map   que_map;
 126        union zip_que_pri    que_pri;
 127
 128        union zip_quex_sbuf_addr que_sbuf_addr;
 129        union zip_quex_sbuf_ctl  que_sbuf_ctl;
 130
 131        int q = 0;
 132
 133        /* Enable the ZIP Engine(Core) Clock */
 134        cmd_ctl.u_reg64 = zip_reg_read(zip->reg_base + ZIP_CMD_CTL);
 135        cmd_ctl.s.forceclk = 1;
 136        zip_reg_write(cmd_ctl.u_reg64 & 0xFF, (zip->reg_base + ZIP_CMD_CTL));
 137
 138        zip_msg("ZIP_CMD_CTL  : 0x%016llx",
 139                zip_reg_read(zip->reg_base + ZIP_CMD_CTL));
 140
 141        constants.u_reg64 = zip_reg_read(zip->reg_base + ZIP_CONSTANTS);
 142        zip->depth    = constants.s.depth;
 143        zip->onfsize  = constants.s.onfsize;
 144        zip->ctxsize  = constants.s.ctxsize;
 145
 146        zip_msg("depth: 0x%016llx , onfsize : 0x%016llx , ctxsize : 0x%016llx",
 147                zip->depth, zip->onfsize, zip->ctxsize);
 148
 149        /*
 150         * Program ZIP_QUE(0..7)_SBUF_ADDR and ZIP_QUE(0..7)_SBUF_CTL to
 151         * have the correct buffer pointer and size configured for each
 152         * instruction queue.
 153         */
 154        for (q = 0; q < ZIP_NUM_QUEUES; q++) {
 155                que_sbuf_ctl.u_reg64 = 0ull;
 156                que_sbuf_ctl.s.size = (ZIP_CMD_QBUF_SIZE / sizeof(u64));
 157                que_sbuf_ctl.s.inst_be   = 0;
 158                que_sbuf_ctl.s.stream_id = 0;
 159                zip_reg_write(que_sbuf_ctl.u_reg64,
 160                              (zip->reg_base + ZIP_QUEX_SBUF_CTL(q)));
 161
 162                zip_msg("QUEX_SBUF_CTL[%d]: 0x%016llx", q,
 163                        zip_reg_read(zip->reg_base + ZIP_QUEX_SBUF_CTL(q)));
 164        }
 165
 166        for (q = 0; q < ZIP_NUM_QUEUES; q++) {
 167                memset(&zip->iq[q], 0x0, sizeof(struct zip_iq));
 168
 169                spin_lock_init(&zip->iq[q].lock);
 170
 171                if (zip_cmd_qbuf_alloc(zip, q)) {
 172                        while (q != 0) {
 173                                q--;
 174                                zip_cmd_qbuf_free(zip, q);
 175                        }
 176                        return -ENOMEM;
 177                }
 178
 179                /* Initialize tail ptr to head */
 180                zip->iq[q].sw_tail = zip->iq[q].sw_head;
 181                zip->iq[q].hw_tail = zip->iq[q].sw_head;
 182
 183                /* Write the physical addr to register */
 184                que_sbuf_addr.u_reg64   = 0ull;
 185                que_sbuf_addr.s.ptr = (__pa(zip->iq[q].sw_head) >>
 186                                       ZIP_128B_ALIGN);
 187
 188                zip_msg("QUE[%d]_PTR(PHYS): 0x%016llx", q,
 189                        (u64)que_sbuf_addr.s.ptr);
 190
 191                zip_reg_write(que_sbuf_addr.u_reg64,
 192                              (zip->reg_base + ZIP_QUEX_SBUF_ADDR(q)));
 193
 194                zip_msg("QUEX_SBUF_ADDR[%d]: 0x%016llx", q,
 195                        zip_reg_read(zip->reg_base + ZIP_QUEX_SBUF_ADDR(q)));
 196
 197                zip_dbg("sw_head :0x%lx sw_tail :0x%lx hw_tail :0x%lx",
 198                        zip->iq[q].sw_head, zip->iq[q].sw_tail,
 199                        zip->iq[q].hw_tail);
 200                zip_dbg("sw_head phy addr : 0x%lx", que_sbuf_addr.s.ptr);
 201        }
 202
 203        /*
 204         * Queue-to-ZIP core mapping
 205         * If a queue is not mapped to a particular core, it is equivalent to
 206         * the ZIP core being disabled.
 207         */
 208        que_ena.u_reg64 = 0x0ull;
 209        /* Enabling queues based on ZIP_NUM_QUEUES */
 210        for (q = 0; q < ZIP_NUM_QUEUES; q++)
 211                que_ena.s.ena |= (0x1 << q);
 212        zip_reg_write(que_ena.u_reg64, (zip->reg_base + ZIP_QUE_ENA));
 213
 214        zip_msg("QUE_ENA      : 0x%016llx",
 215                zip_reg_read(zip->reg_base + ZIP_QUE_ENA));
 216
 217        for (q = 0; q < ZIP_NUM_QUEUES; q++) {
 218                que_map.u_reg64 = 0ull;
 219                /* Mapping each queue to two ZIP cores */
 220                que_map.s.zce = 0x3;
 221                zip_reg_write(que_map.u_reg64,
 222                              (zip->reg_base + ZIP_QUEX_MAP(q)));
 223
 224                zip_msg("QUE_MAP(%d)   : 0x%016llx", q,
 225                        zip_reg_read(zip->reg_base + ZIP_QUEX_MAP(q)));
 226        }
 227
 228        que_pri.u_reg64 = 0ull;
 229        for (q = 0; q < ZIP_NUM_QUEUES; q++)
 230                que_pri.s.pri |= (0x1 << q); /* Higher Priority RR */
 231        zip_reg_write(que_pri.u_reg64, (zip->reg_base + ZIP_QUE_PRI));
 232
 233        zip_msg("QUE_PRI %016llx", zip_reg_read(zip->reg_base + ZIP_QUE_PRI));
 234
 235        return 0;
 236}
 237
 238static int zip_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 239{
 240        struct device *dev = &pdev->dev;
 241        struct zip_device *zip = NULL;
 242        int    err;
 243
 244        zip = zip_alloc_device(pdev);
 245        if (!zip)
 246                return -ENOMEM;
 247
 248        dev_info(dev, "Found ZIP device %d %x:%x on Node %d\n", zip->index,
 249                 pdev->vendor, pdev->device, dev_to_node(dev));
 250
 251        pci_set_drvdata(pdev, zip);
 252        zip->pdev = pdev;
 253
 254        err = pci_enable_device(pdev);
 255        if (err) {
 256                dev_err(dev, "Failed to enable PCI device");
 257                goto err_free_device;
 258        }
 259
 260        err = pci_request_regions(pdev, DRV_NAME);
 261        if (err) {
 262                dev_err(dev, "PCI request regions failed 0x%x", err);
 263                goto err_disable_device;
 264        }
 265
 266        err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(48));
 267        if (err) {
 268                dev_err(dev, "Unable to get usable 48-bit DMA configuration\n");
 269                goto err_release_regions;
 270        }
 271
 272        /* MAP configuration registers */
 273        zip->reg_base = pci_ioremap_bar(pdev, PCI_CFG_ZIP_PF_BAR0);
 274        if (!zip->reg_base) {
 275                dev_err(dev, "ZIP: Cannot map BAR0 CSR memory space, aborting");
 276                err = -ENOMEM;
 277                goto err_release_regions;
 278        }
 279
 280        /* Initialize ZIP Hardware */
 281        err = zip_init_hw(zip);
 282        if (err)
 283                goto err_release_regions;
 284
 285        return 0;
 286
 287err_release_regions:
 288        if (zip->reg_base)
 289                iounmap(zip->reg_base);
 290        pci_release_regions(pdev);
 291
 292err_disable_device:
 293        pci_disable_device(pdev);
 294
 295err_free_device:
 296        pci_set_drvdata(pdev, NULL);
 297
 298        /* Remove zip_dev from zip_device list, free the zip_device memory */
 299        zip_dev[zip->index] = NULL;
 300        devm_kfree(dev, zip);
 301
 302        return err;
 303}
 304
 305static void zip_remove(struct pci_dev *pdev)
 306{
 307        struct zip_device *zip = pci_get_drvdata(pdev);
 308        union zip_cmd_ctl cmd_ctl;
 309        int q = 0;
 310
 311        if (!zip)
 312                return;
 313
 314        if (zip->reg_base) {
 315                cmd_ctl.u_reg64 = 0x0ull;
 316                cmd_ctl.s.reset = 1;  /* Forces ZIP cores to do reset */
 317                zip_reg_write(cmd_ctl.u_reg64, (zip->reg_base + ZIP_CMD_CTL));
 318                iounmap(zip->reg_base);
 319        }
 320
 321        pci_release_regions(pdev);
 322        pci_disable_device(pdev);
 323
 324        /*
 325         * Free Command Queue buffers. This free should be called for all
 326         * the enabled Queues.
 327         */
 328        for (q = 0; q < ZIP_NUM_QUEUES; q++)
 329                zip_cmd_qbuf_free(zip, q);
 330
 331        pci_set_drvdata(pdev, NULL);
 332        /* remove zip device from zip device list */
 333        zip_dev[zip->index] = NULL;
 334}
 335
 336/* PCI Sub-System Interface */
 337static struct pci_driver zip_driver = {
 338        .name       =  DRV_NAME,
 339        .id_table   =  zip_id_table,
 340        .probe      =  zip_probe,
 341        .remove     =  zip_remove,
 342};
 343
 344/* Kernel Crypto Subsystem Interface */
 345
 346static struct crypto_alg zip_comp_deflate = {
 347        .cra_name               = "deflate",
 348        .cra_driver_name        = "deflate-cavium",
 349        .cra_flags              = CRYPTO_ALG_TYPE_COMPRESS,
 350        .cra_ctxsize            = sizeof(struct zip_kernel_ctx),
 351        .cra_priority           = 300,
 352        .cra_module             = THIS_MODULE,
 353        .cra_init               = zip_alloc_comp_ctx_deflate,
 354        .cra_exit               = zip_free_comp_ctx,
 355        .cra_u                  = { .compress = {
 356                .coa_compress   = zip_comp_compress,
 357                .coa_decompress = zip_comp_decompress
 358                 } }
 359};
 360
 361static struct crypto_alg zip_comp_lzs = {
 362        .cra_name               = "lzs",
 363        .cra_driver_name        = "lzs-cavium",
 364        .cra_flags              = CRYPTO_ALG_TYPE_COMPRESS,
 365        .cra_ctxsize            = sizeof(struct zip_kernel_ctx),
 366        .cra_priority           = 300,
 367        .cra_module             = THIS_MODULE,
 368        .cra_init               = zip_alloc_comp_ctx_lzs,
 369        .cra_exit               = zip_free_comp_ctx,
 370        .cra_u                  = { .compress = {
 371                .coa_compress   = zip_comp_compress,
 372                .coa_decompress = zip_comp_decompress
 373                 } }
 374};
 375
 376static struct scomp_alg zip_scomp_deflate = {
 377        .alloc_ctx              = zip_alloc_scomp_ctx_deflate,
 378        .free_ctx               = zip_free_scomp_ctx,
 379        .compress               = zip_scomp_compress,
 380        .decompress             = zip_scomp_decompress,
 381        .base                   = {
 382                .cra_name               = "deflate",
 383                .cra_driver_name        = "deflate-scomp-cavium",
 384                .cra_module             = THIS_MODULE,
 385                .cra_priority           = 300,
 386        }
 387};
 388
 389static struct scomp_alg zip_scomp_lzs = {
 390        .alloc_ctx              = zip_alloc_scomp_ctx_lzs,
 391        .free_ctx               = zip_free_scomp_ctx,
 392        .compress               = zip_scomp_compress,
 393        .decompress             = zip_scomp_decompress,
 394        .base                   = {
 395                .cra_name               = "lzs",
 396                .cra_driver_name        = "lzs-scomp-cavium",
 397                .cra_module             = THIS_MODULE,
 398                .cra_priority           = 300,
 399        }
 400};
 401
 402static int zip_register_compression_device(void)
 403{
 404        int ret;
 405
 406        ret = crypto_register_alg(&zip_comp_deflate);
 407        if (ret < 0) {
 408                zip_err("Deflate algorithm registration failed\n");
 409                return ret;
 410        }
 411
 412        ret = crypto_register_alg(&zip_comp_lzs);
 413        if (ret < 0) {
 414                zip_err("LZS algorithm registration failed\n");
 415                goto err_unregister_alg_deflate;
 416        }
 417
 418        ret = crypto_register_scomp(&zip_scomp_deflate);
 419        if (ret < 0) {
 420                zip_err("Deflate scomp algorithm registration failed\n");
 421                goto err_unregister_alg_lzs;
 422        }
 423
 424        ret = crypto_register_scomp(&zip_scomp_lzs);
 425        if (ret < 0) {
 426                zip_err("LZS scomp algorithm registration failed\n");
 427                goto err_unregister_scomp_deflate;
 428        }
 429
 430        return ret;
 431
 432err_unregister_scomp_deflate:
 433        crypto_unregister_scomp(&zip_scomp_deflate);
 434err_unregister_alg_lzs:
 435        crypto_unregister_alg(&zip_comp_lzs);
 436err_unregister_alg_deflate:
 437        crypto_unregister_alg(&zip_comp_deflate);
 438
 439        return ret;
 440}
 441
 442static void zip_unregister_compression_device(void)
 443{
 444        crypto_unregister_alg(&zip_comp_deflate);
 445        crypto_unregister_alg(&zip_comp_lzs);
 446        crypto_unregister_scomp(&zip_scomp_deflate);
 447        crypto_unregister_scomp(&zip_scomp_lzs);
 448}
 449
 450/*
 451 * debugfs functions
 452 */
 453#ifdef CONFIG_DEBUG_FS
 454#include <linux/debugfs.h>
 455
 456/* Displays ZIP device statistics */
 457static int zip_stats_show(struct seq_file *s, void *unused)
 458{
 459        u64 val = 0ull;
 460        u64 avg_chunk = 0ull, avg_cr = 0ull;
 461        u32 q = 0;
 462
 463        int index  = 0;
 464        struct zip_device *zip;
 465        struct zip_stats  *st;
 466
 467        for (index = 0; index < MAX_ZIP_DEVICES; index++) {
 468                u64 pending = 0;
 469
 470                if (zip_dev[index]) {
 471                        zip = zip_dev[index];
 472                        st  = &zip->stats;
 473
 474                        /* Get all the pending requests */
 475                        for (q = 0; q < ZIP_NUM_QUEUES; q++) {
 476                                val = zip_reg_read((zip->reg_base +
 477                                                    ZIP_DBG_QUEX_STA(q)));
 478                                pending += val >> 32 & 0xffffff;
 479                        }
 480
 481                        val = atomic64_read(&st->comp_req_complete);
 482                        avg_chunk = (val) ? atomic64_read(&st->comp_in_bytes) / val : 0;
 483
 484                        val = atomic64_read(&st->comp_out_bytes);
 485                        avg_cr = (val) ? atomic64_read(&st->comp_in_bytes) / val : 0;
 486                        seq_printf(s, "        ZIP Device %d Stats\n"
 487                                      "-----------------------------------\n"
 488                                      "Comp Req Submitted        : \t%lld\n"
 489                                      "Comp Req Completed        : \t%lld\n"
 490                                      "Compress In Bytes         : \t%lld\n"
 491                                      "Compressed Out Bytes      : \t%lld\n"
 492                                      "Average Chunk size        : \t%llu\n"
 493                                      "Average Compression ratio : \t%llu\n"
 494                                      "Decomp Req Submitted      : \t%lld\n"
 495                                      "Decomp Req Completed      : \t%lld\n"
 496                                      "Decompress In Bytes       : \t%lld\n"
 497                                      "Decompressed Out Bytes    : \t%lld\n"
 498                                      "Decompress Bad requests   : \t%lld\n"
 499                                      "Pending Req               : \t%lld\n"
 500                                        "---------------------------------\n",
 501                                       index,
 502                                       (u64)atomic64_read(&st->comp_req_submit),
 503                                       (u64)atomic64_read(&st->comp_req_complete),
 504                                       (u64)atomic64_read(&st->comp_in_bytes),
 505                                       (u64)atomic64_read(&st->comp_out_bytes),
 506                                       avg_chunk,
 507                                       avg_cr,
 508                                       (u64)atomic64_read(&st->decomp_req_submit),
 509                                       (u64)atomic64_read(&st->decomp_req_complete),
 510                                       (u64)atomic64_read(&st->decomp_in_bytes),
 511                                       (u64)atomic64_read(&st->decomp_out_bytes),
 512                                       (u64)atomic64_read(&st->decomp_bad_reqs),
 513                                       pending);
 514                }
 515        }
 516        return 0;
 517}
 518
 519/* Clears stats data */
 520static int zip_clear_show(struct seq_file *s, void *unused)
 521{
 522        int index = 0;
 523
 524        for (index = 0; index < MAX_ZIP_DEVICES; index++) {
 525                if (zip_dev[index]) {
 526                        memset(&zip_dev[index]->stats, 0,
 527                               sizeof(struct zip_stats));
 528                        seq_printf(s, "Cleared stats for zip %d\n", index);
 529                }
 530        }
 531
 532        return 0;
 533}
 534
 535static struct zip_registers zipregs[64] = {
 536        {"ZIP_CMD_CTL        ",  0x0000ull},
 537        {"ZIP_THROTTLE       ",  0x0010ull},
 538        {"ZIP_CONSTANTS      ",  0x00A0ull},
 539        {"ZIP_QUE0_MAP       ",  0x1400ull},
 540        {"ZIP_QUE1_MAP       ",  0x1408ull},
 541        {"ZIP_QUE_ENA        ",  0x0500ull},
 542        {"ZIP_QUE_PRI        ",  0x0508ull},
 543        {"ZIP_QUE0_DONE      ",  0x2000ull},
 544        {"ZIP_QUE1_DONE      ",  0x2008ull},
 545        {"ZIP_QUE0_DOORBELL  ",  0x4000ull},
 546        {"ZIP_QUE1_DOORBELL  ",  0x4008ull},
 547        {"ZIP_QUE0_SBUF_ADDR ",  0x1000ull},
 548        {"ZIP_QUE1_SBUF_ADDR ",  0x1008ull},
 549        {"ZIP_QUE0_SBUF_CTL  ",  0x1200ull},
 550        {"ZIP_QUE1_SBUF_CTL  ",  0x1208ull},
 551        { NULL, 0}
 552};
 553
 554/* Prints registers' contents */
 555static int zip_regs_show(struct seq_file *s, void *unused)
 556{
 557        u64 val = 0;
 558        int i = 0, index = 0;
 559
 560        for (index = 0; index < MAX_ZIP_DEVICES; index++) {
 561                if (zip_dev[index]) {
 562                        seq_printf(s, "--------------------------------\n"
 563                                      "     ZIP Device %d Registers\n"
 564                                      "--------------------------------\n",
 565                                      index);
 566
 567                        i = 0;
 568
 569                        while (zipregs[i].reg_name) {
 570                                val = zip_reg_read((zip_dev[index]->reg_base +
 571                                                    zipregs[i].reg_offset));
 572                                seq_printf(s, "%s: 0x%016llx\n",
 573                                           zipregs[i].reg_name, val);
 574                                i++;
 575                        }
 576                }
 577        }
 578        return 0;
 579}
 580
 581DEFINE_SHOW_ATTRIBUTE(zip_stats);
 582DEFINE_SHOW_ATTRIBUTE(zip_clear);
 583DEFINE_SHOW_ATTRIBUTE(zip_regs);
 584
 585/* Root directory for thunderx_zip debugfs entry */
 586static struct dentry *zip_debugfs_root;
 587
 588static void __init zip_debugfs_init(void)
 589{
 590        if (!debugfs_initialized())
 591                return;
 592
 593        zip_debugfs_root = debugfs_create_dir("thunderx_zip", NULL);
 594
 595        /* Creating files for entries inside thunderx_zip directory */
 596        debugfs_create_file("zip_stats", 0444, zip_debugfs_root, NULL,
 597                            &zip_stats_fops);
 598
 599        debugfs_create_file("zip_clear", 0444, zip_debugfs_root, NULL,
 600                            &zip_clear_fops);
 601
 602        debugfs_create_file("zip_regs", 0444, zip_debugfs_root, NULL,
 603                            &zip_regs_fops);
 604
 605}
 606
 607static void __exit zip_debugfs_exit(void)
 608{
 609        debugfs_remove_recursive(zip_debugfs_root);
 610}
 611
 612#else
 613static void __init zip_debugfs_init(void) { }
 614static void __exit zip_debugfs_exit(void) { }
 615#endif
 616/* debugfs - end */
 617
 618static int __init zip_init_module(void)
 619{
 620        int ret;
 621
 622        zip_msg("%s\n", DRV_NAME);
 623
 624        ret = pci_register_driver(&zip_driver);
 625        if (ret < 0) {
 626                zip_err("ZIP: pci_register_driver() failed\n");
 627                return ret;
 628        }
 629
 630        /* Register with the Kernel Crypto Interface */
 631        ret = zip_register_compression_device();
 632        if (ret < 0) {
 633                zip_err("ZIP: Kernel Crypto Registration failed\n");
 634                goto err_pci_unregister;
 635        }
 636
 637        /* comp-decomp statistics are handled with debugfs interface */
 638        zip_debugfs_init();
 639
 640        return ret;
 641
 642err_pci_unregister:
 643        pci_unregister_driver(&zip_driver);
 644        return ret;
 645}
 646
 647static void __exit zip_cleanup_module(void)
 648{
 649        zip_debugfs_exit();
 650
 651        /* Unregister from the kernel crypto interface */
 652        zip_unregister_compression_device();
 653
 654        /* Unregister this driver for pci zip devices */
 655        pci_unregister_driver(&zip_driver);
 656}
 657
 658module_init(zip_init_module);
 659module_exit(zip_cleanup_module);
 660
 661MODULE_AUTHOR("Cavium Inc");
 662MODULE_DESCRIPTION("Cavium Inc ThunderX ZIP Driver");
 663MODULE_LICENSE("GPL v2");
 664MODULE_DEVICE_TABLE(pci, zip_id_table);
 665