18c2ecf20Sopenharmony_ci/***********************license start************************************ 28c2ecf20Sopenharmony_ci * Copyright (c) 2003-2017 Cavium, Inc. 38c2ecf20Sopenharmony_ci * All rights reserved. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * License: one of 'Cavium License' or 'GNU General Public License Version 2' 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * This file is provided under the terms of the Cavium License (see below) 88c2ecf20Sopenharmony_ci * or under the terms of GNU General Public License, Version 2, as 98c2ecf20Sopenharmony_ci * published by the Free Software Foundation. When using or redistributing 108c2ecf20Sopenharmony_ci * this file, you may do so under either license. 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * Cavium License: Redistribution and use in source and binary forms, with 138c2ecf20Sopenharmony_ci * or without modification, are permitted provided that the following 148c2ecf20Sopenharmony_ci * conditions are met: 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * * Redistributions of source code must retain the above copyright 178c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * * Redistributions in binary form must reproduce the above 208c2ecf20Sopenharmony_ci * copyright notice, this list of conditions and the following 218c2ecf20Sopenharmony_ci * disclaimer in the documentation and/or other materials provided 228c2ecf20Sopenharmony_ci * with the distribution. 238c2ecf20Sopenharmony_ci * 248c2ecf20Sopenharmony_ci * * Neither the name of Cavium Inc. nor the names of its contributors may be 258c2ecf20Sopenharmony_ci * used to endorse or promote products derived from this software without 268c2ecf20Sopenharmony_ci * specific prior written permission. 278c2ecf20Sopenharmony_ci * 288c2ecf20Sopenharmony_ci * This Software, including technical data, may be subject to U.S. export 298c2ecf20Sopenharmony_ci * control laws, including the U.S. Export Administration Act and its 308c2ecf20Sopenharmony_ci * associated regulations, and may be subject to export or import 318c2ecf20Sopenharmony_ci * regulations in other countries. 328c2ecf20Sopenharmony_ci * 338c2ecf20Sopenharmony_ci * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 348c2ecf20Sopenharmony_ci * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS 358c2ecf20Sopenharmony_ci * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH 368c2ecf20Sopenharmony_ci * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY 378c2ecf20Sopenharmony_ci * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT 388c2ecf20Sopenharmony_ci * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) 398c2ecf20Sopenharmony_ci * WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A 408c2ecf20Sopenharmony_ci * PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET 418c2ecf20Sopenharmony_ci * ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE 428c2ecf20Sopenharmony_ci * ENTIRE RISK ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES 438c2ecf20Sopenharmony_ci * WITH YOU. 448c2ecf20Sopenharmony_ci ***********************license end**************************************/ 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#include "common.h" 478c2ecf20Sopenharmony_ci#include "zip_crypto.h" 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#define DRV_NAME "ThunderX-ZIP" 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cistatic struct zip_device *zip_dev[MAX_ZIP_DEVICES]; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistatic const struct pci_device_id zip_id_table[] = { 548c2ecf20Sopenharmony_ci { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVICE_ID_THUNDERX_ZIP) }, 558c2ecf20Sopenharmony_ci { 0, } 568c2ecf20Sopenharmony_ci}; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_civoid zip_reg_write(u64 val, u64 __iomem *addr) 598c2ecf20Sopenharmony_ci{ 608c2ecf20Sopenharmony_ci writeq(val, addr); 618c2ecf20Sopenharmony_ci} 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ciu64 zip_reg_read(u64 __iomem *addr) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci return readq(addr); 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/* 698c2ecf20Sopenharmony_ci * Allocates new ZIP device structure 708c2ecf20Sopenharmony_ci * Returns zip_device pointer or NULL if cannot allocate memory for zip_device 718c2ecf20Sopenharmony_ci */ 728c2ecf20Sopenharmony_cistatic struct zip_device *zip_alloc_device(struct pci_dev *pdev) 738c2ecf20Sopenharmony_ci{ 748c2ecf20Sopenharmony_ci struct zip_device *zip = NULL; 758c2ecf20Sopenharmony_ci int idx; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci for (idx = 0; idx < MAX_ZIP_DEVICES; idx++) { 788c2ecf20Sopenharmony_ci if (!zip_dev[idx]) 798c2ecf20Sopenharmony_ci break; 808c2ecf20Sopenharmony_ci } 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci /* To ensure that the index is within the limit */ 838c2ecf20Sopenharmony_ci if (idx < MAX_ZIP_DEVICES) 848c2ecf20Sopenharmony_ci zip = devm_kzalloc(&pdev->dev, sizeof(*zip), GFP_KERNEL); 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci if (!zip) 878c2ecf20Sopenharmony_ci return NULL; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci zip_dev[idx] = zip; 908c2ecf20Sopenharmony_ci zip->index = idx; 918c2ecf20Sopenharmony_ci return zip; 928c2ecf20Sopenharmony_ci} 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci/** 958c2ecf20Sopenharmony_ci * zip_get_device - Get ZIP device based on node id of cpu 968c2ecf20Sopenharmony_ci * 978c2ecf20Sopenharmony_ci * @node: Node id of the current cpu 988c2ecf20Sopenharmony_ci * Return: Pointer to Zip device structure 998c2ecf20Sopenharmony_ci */ 1008c2ecf20Sopenharmony_cistruct zip_device *zip_get_device(int node) 1018c2ecf20Sopenharmony_ci{ 1028c2ecf20Sopenharmony_ci if ((node < MAX_ZIP_DEVICES) && (node >= 0)) 1038c2ecf20Sopenharmony_ci return zip_dev[node]; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci zip_err("ZIP device not found for node id %d\n", node); 1068c2ecf20Sopenharmony_ci return NULL; 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci/** 1108c2ecf20Sopenharmony_ci * zip_get_node_id - Get the node id of the current cpu 1118c2ecf20Sopenharmony_ci * 1128c2ecf20Sopenharmony_ci * Return: Node id of the current cpu 1138c2ecf20Sopenharmony_ci */ 1148c2ecf20Sopenharmony_ciint zip_get_node_id(void) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci return cpu_to_node(raw_smp_processor_id()); 1178c2ecf20Sopenharmony_ci} 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci/* Initializes the ZIP h/w sub-system */ 1208c2ecf20Sopenharmony_cistatic int zip_init_hw(struct zip_device *zip) 1218c2ecf20Sopenharmony_ci{ 1228c2ecf20Sopenharmony_ci union zip_cmd_ctl cmd_ctl; 1238c2ecf20Sopenharmony_ci union zip_constants constants; 1248c2ecf20Sopenharmony_ci union zip_que_ena que_ena; 1258c2ecf20Sopenharmony_ci union zip_quex_map que_map; 1268c2ecf20Sopenharmony_ci union zip_que_pri que_pri; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci union zip_quex_sbuf_addr que_sbuf_addr; 1298c2ecf20Sopenharmony_ci union zip_quex_sbuf_ctl que_sbuf_ctl; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci int q = 0; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci /* Enable the ZIP Engine(Core) Clock */ 1348c2ecf20Sopenharmony_ci cmd_ctl.u_reg64 = zip_reg_read(zip->reg_base + ZIP_CMD_CTL); 1358c2ecf20Sopenharmony_ci cmd_ctl.s.forceclk = 1; 1368c2ecf20Sopenharmony_ci zip_reg_write(cmd_ctl.u_reg64 & 0xFF, (zip->reg_base + ZIP_CMD_CTL)); 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci zip_msg("ZIP_CMD_CTL : 0x%016llx", 1398c2ecf20Sopenharmony_ci zip_reg_read(zip->reg_base + ZIP_CMD_CTL)); 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci constants.u_reg64 = zip_reg_read(zip->reg_base + ZIP_CONSTANTS); 1428c2ecf20Sopenharmony_ci zip->depth = constants.s.depth; 1438c2ecf20Sopenharmony_ci zip->onfsize = constants.s.onfsize; 1448c2ecf20Sopenharmony_ci zip->ctxsize = constants.s.ctxsize; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci zip_msg("depth: 0x%016llx , onfsize : 0x%016llx , ctxsize : 0x%016llx", 1478c2ecf20Sopenharmony_ci zip->depth, zip->onfsize, zip->ctxsize); 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci /* 1508c2ecf20Sopenharmony_ci * Program ZIP_QUE(0..7)_SBUF_ADDR and ZIP_QUE(0..7)_SBUF_CTL to 1518c2ecf20Sopenharmony_ci * have the correct buffer pointer and size configured for each 1528c2ecf20Sopenharmony_ci * instruction queue. 1538c2ecf20Sopenharmony_ci */ 1548c2ecf20Sopenharmony_ci for (q = 0; q < ZIP_NUM_QUEUES; q++) { 1558c2ecf20Sopenharmony_ci que_sbuf_ctl.u_reg64 = 0ull; 1568c2ecf20Sopenharmony_ci que_sbuf_ctl.s.size = (ZIP_CMD_QBUF_SIZE / sizeof(u64)); 1578c2ecf20Sopenharmony_ci que_sbuf_ctl.s.inst_be = 0; 1588c2ecf20Sopenharmony_ci que_sbuf_ctl.s.stream_id = 0; 1598c2ecf20Sopenharmony_ci zip_reg_write(que_sbuf_ctl.u_reg64, 1608c2ecf20Sopenharmony_ci (zip->reg_base + ZIP_QUEX_SBUF_CTL(q))); 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci zip_msg("QUEX_SBUF_CTL[%d]: 0x%016llx", q, 1638c2ecf20Sopenharmony_ci zip_reg_read(zip->reg_base + ZIP_QUEX_SBUF_CTL(q))); 1648c2ecf20Sopenharmony_ci } 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci for (q = 0; q < ZIP_NUM_QUEUES; q++) { 1678c2ecf20Sopenharmony_ci memset(&zip->iq[q], 0x0, sizeof(struct zip_iq)); 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci spin_lock_init(&zip->iq[q].lock); 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci if (zip_cmd_qbuf_alloc(zip, q)) { 1728c2ecf20Sopenharmony_ci while (q != 0) { 1738c2ecf20Sopenharmony_ci q--; 1748c2ecf20Sopenharmony_ci zip_cmd_qbuf_free(zip, q); 1758c2ecf20Sopenharmony_ci } 1768c2ecf20Sopenharmony_ci return -ENOMEM; 1778c2ecf20Sopenharmony_ci } 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci /* Initialize tail ptr to head */ 1808c2ecf20Sopenharmony_ci zip->iq[q].sw_tail = zip->iq[q].sw_head; 1818c2ecf20Sopenharmony_ci zip->iq[q].hw_tail = zip->iq[q].sw_head; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci /* Write the physical addr to register */ 1848c2ecf20Sopenharmony_ci que_sbuf_addr.u_reg64 = 0ull; 1858c2ecf20Sopenharmony_ci que_sbuf_addr.s.ptr = (__pa(zip->iq[q].sw_head) >> 1868c2ecf20Sopenharmony_ci ZIP_128B_ALIGN); 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci zip_msg("QUE[%d]_PTR(PHYS): 0x%016llx", q, 1898c2ecf20Sopenharmony_ci (u64)que_sbuf_addr.s.ptr); 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci zip_reg_write(que_sbuf_addr.u_reg64, 1928c2ecf20Sopenharmony_ci (zip->reg_base + ZIP_QUEX_SBUF_ADDR(q))); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci zip_msg("QUEX_SBUF_ADDR[%d]: 0x%016llx", q, 1958c2ecf20Sopenharmony_ci zip_reg_read(zip->reg_base + ZIP_QUEX_SBUF_ADDR(q))); 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci zip_dbg("sw_head :0x%lx sw_tail :0x%lx hw_tail :0x%lx", 1988c2ecf20Sopenharmony_ci zip->iq[q].sw_head, zip->iq[q].sw_tail, 1998c2ecf20Sopenharmony_ci zip->iq[q].hw_tail); 2008c2ecf20Sopenharmony_ci zip_dbg("sw_head phy addr : 0x%lx", que_sbuf_addr.s.ptr); 2018c2ecf20Sopenharmony_ci } 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci /* 2048c2ecf20Sopenharmony_ci * Queue-to-ZIP core mapping 2058c2ecf20Sopenharmony_ci * If a queue is not mapped to a particular core, it is equivalent to 2068c2ecf20Sopenharmony_ci * the ZIP core being disabled. 2078c2ecf20Sopenharmony_ci */ 2088c2ecf20Sopenharmony_ci que_ena.u_reg64 = 0x0ull; 2098c2ecf20Sopenharmony_ci /* Enabling queues based on ZIP_NUM_QUEUES */ 2108c2ecf20Sopenharmony_ci for (q = 0; q < ZIP_NUM_QUEUES; q++) 2118c2ecf20Sopenharmony_ci que_ena.s.ena |= (0x1 << q); 2128c2ecf20Sopenharmony_ci zip_reg_write(que_ena.u_reg64, (zip->reg_base + ZIP_QUE_ENA)); 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci zip_msg("QUE_ENA : 0x%016llx", 2158c2ecf20Sopenharmony_ci zip_reg_read(zip->reg_base + ZIP_QUE_ENA)); 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci for (q = 0; q < ZIP_NUM_QUEUES; q++) { 2188c2ecf20Sopenharmony_ci que_map.u_reg64 = 0ull; 2198c2ecf20Sopenharmony_ci /* Mapping each queue to two ZIP cores */ 2208c2ecf20Sopenharmony_ci que_map.s.zce = 0x3; 2218c2ecf20Sopenharmony_ci zip_reg_write(que_map.u_reg64, 2228c2ecf20Sopenharmony_ci (zip->reg_base + ZIP_QUEX_MAP(q))); 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci zip_msg("QUE_MAP(%d) : 0x%016llx", q, 2258c2ecf20Sopenharmony_ci zip_reg_read(zip->reg_base + ZIP_QUEX_MAP(q))); 2268c2ecf20Sopenharmony_ci } 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci que_pri.u_reg64 = 0ull; 2298c2ecf20Sopenharmony_ci for (q = 0; q < ZIP_NUM_QUEUES; q++) 2308c2ecf20Sopenharmony_ci que_pri.s.pri |= (0x1 << q); /* Higher Priority RR */ 2318c2ecf20Sopenharmony_ci zip_reg_write(que_pri.u_reg64, (zip->reg_base + ZIP_QUE_PRI)); 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci zip_msg("QUE_PRI %016llx", zip_reg_read(zip->reg_base + ZIP_QUE_PRI)); 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci return 0; 2368c2ecf20Sopenharmony_ci} 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_cistatic int zip_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 2398c2ecf20Sopenharmony_ci{ 2408c2ecf20Sopenharmony_ci struct device *dev = &pdev->dev; 2418c2ecf20Sopenharmony_ci struct zip_device *zip = NULL; 2428c2ecf20Sopenharmony_ci int err; 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci zip = zip_alloc_device(pdev); 2458c2ecf20Sopenharmony_ci if (!zip) 2468c2ecf20Sopenharmony_ci return -ENOMEM; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci dev_info(dev, "Found ZIP device %d %x:%x on Node %d\n", zip->index, 2498c2ecf20Sopenharmony_ci pdev->vendor, pdev->device, dev_to_node(dev)); 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci pci_set_drvdata(pdev, zip); 2528c2ecf20Sopenharmony_ci zip->pdev = pdev; 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci err = pci_enable_device(pdev); 2558c2ecf20Sopenharmony_ci if (err) { 2568c2ecf20Sopenharmony_ci dev_err(dev, "Failed to enable PCI device"); 2578c2ecf20Sopenharmony_ci goto err_free_device; 2588c2ecf20Sopenharmony_ci } 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci err = pci_request_regions(pdev, DRV_NAME); 2618c2ecf20Sopenharmony_ci if (err) { 2628c2ecf20Sopenharmony_ci dev_err(dev, "PCI request regions failed 0x%x", err); 2638c2ecf20Sopenharmony_ci goto err_disable_device; 2648c2ecf20Sopenharmony_ci } 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci err = pci_set_dma_mask(pdev, DMA_BIT_MASK(48)); 2678c2ecf20Sopenharmony_ci if (err) { 2688c2ecf20Sopenharmony_ci dev_err(dev, "Unable to get usable DMA configuration\n"); 2698c2ecf20Sopenharmony_ci goto err_release_regions; 2708c2ecf20Sopenharmony_ci } 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(48)); 2738c2ecf20Sopenharmony_ci if (err) { 2748c2ecf20Sopenharmony_ci dev_err(dev, "Unable to get 48-bit DMA for allocations\n"); 2758c2ecf20Sopenharmony_ci goto err_release_regions; 2768c2ecf20Sopenharmony_ci } 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci /* MAP configuration registers */ 2798c2ecf20Sopenharmony_ci zip->reg_base = pci_ioremap_bar(pdev, PCI_CFG_ZIP_PF_BAR0); 2808c2ecf20Sopenharmony_ci if (!zip->reg_base) { 2818c2ecf20Sopenharmony_ci dev_err(dev, "ZIP: Cannot map BAR0 CSR memory space, aborting"); 2828c2ecf20Sopenharmony_ci err = -ENOMEM; 2838c2ecf20Sopenharmony_ci goto err_release_regions; 2848c2ecf20Sopenharmony_ci } 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci /* Initialize ZIP Hardware */ 2878c2ecf20Sopenharmony_ci err = zip_init_hw(zip); 2888c2ecf20Sopenharmony_ci if (err) 2898c2ecf20Sopenharmony_ci goto err_release_regions; 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci return 0; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_cierr_release_regions: 2948c2ecf20Sopenharmony_ci if (zip->reg_base) 2958c2ecf20Sopenharmony_ci iounmap(zip->reg_base); 2968c2ecf20Sopenharmony_ci pci_release_regions(pdev); 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_cierr_disable_device: 2998c2ecf20Sopenharmony_ci pci_disable_device(pdev); 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_cierr_free_device: 3028c2ecf20Sopenharmony_ci pci_set_drvdata(pdev, NULL); 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci /* Remove zip_dev from zip_device list, free the zip_device memory */ 3058c2ecf20Sopenharmony_ci zip_dev[zip->index] = NULL; 3068c2ecf20Sopenharmony_ci devm_kfree(dev, zip); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci return err; 3098c2ecf20Sopenharmony_ci} 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_cistatic void zip_remove(struct pci_dev *pdev) 3128c2ecf20Sopenharmony_ci{ 3138c2ecf20Sopenharmony_ci struct zip_device *zip = pci_get_drvdata(pdev); 3148c2ecf20Sopenharmony_ci union zip_cmd_ctl cmd_ctl; 3158c2ecf20Sopenharmony_ci int q = 0; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci if (!zip) 3188c2ecf20Sopenharmony_ci return; 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci if (zip->reg_base) { 3218c2ecf20Sopenharmony_ci cmd_ctl.u_reg64 = 0x0ull; 3228c2ecf20Sopenharmony_ci cmd_ctl.s.reset = 1; /* Forces ZIP cores to do reset */ 3238c2ecf20Sopenharmony_ci zip_reg_write(cmd_ctl.u_reg64, (zip->reg_base + ZIP_CMD_CTL)); 3248c2ecf20Sopenharmony_ci iounmap(zip->reg_base); 3258c2ecf20Sopenharmony_ci } 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ci pci_release_regions(pdev); 3288c2ecf20Sopenharmony_ci pci_disable_device(pdev); 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci /* 3318c2ecf20Sopenharmony_ci * Free Command Queue buffers. This free should be called for all 3328c2ecf20Sopenharmony_ci * the enabled Queues. 3338c2ecf20Sopenharmony_ci */ 3348c2ecf20Sopenharmony_ci for (q = 0; q < ZIP_NUM_QUEUES; q++) 3358c2ecf20Sopenharmony_ci zip_cmd_qbuf_free(zip, q); 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci pci_set_drvdata(pdev, NULL); 3388c2ecf20Sopenharmony_ci /* remove zip device from zip device list */ 3398c2ecf20Sopenharmony_ci zip_dev[zip->index] = NULL; 3408c2ecf20Sopenharmony_ci} 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci/* PCI Sub-System Interface */ 3438c2ecf20Sopenharmony_cistatic struct pci_driver zip_driver = { 3448c2ecf20Sopenharmony_ci .name = DRV_NAME, 3458c2ecf20Sopenharmony_ci .id_table = zip_id_table, 3468c2ecf20Sopenharmony_ci .probe = zip_probe, 3478c2ecf20Sopenharmony_ci .remove = zip_remove, 3488c2ecf20Sopenharmony_ci}; 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci/* Kernel Crypto Subsystem Interface */ 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_cistatic struct crypto_alg zip_comp_deflate = { 3538c2ecf20Sopenharmony_ci .cra_name = "deflate", 3548c2ecf20Sopenharmony_ci .cra_driver_name = "deflate-cavium", 3558c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, 3568c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct zip_kernel_ctx), 3578c2ecf20Sopenharmony_ci .cra_priority = 300, 3588c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 3598c2ecf20Sopenharmony_ci .cra_init = zip_alloc_comp_ctx_deflate, 3608c2ecf20Sopenharmony_ci .cra_exit = zip_free_comp_ctx, 3618c2ecf20Sopenharmony_ci .cra_u = { .compress = { 3628c2ecf20Sopenharmony_ci .coa_compress = zip_comp_compress, 3638c2ecf20Sopenharmony_ci .coa_decompress = zip_comp_decompress 3648c2ecf20Sopenharmony_ci } } 3658c2ecf20Sopenharmony_ci}; 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_cistatic struct crypto_alg zip_comp_lzs = { 3688c2ecf20Sopenharmony_ci .cra_name = "lzs", 3698c2ecf20Sopenharmony_ci .cra_driver_name = "lzs-cavium", 3708c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, 3718c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct zip_kernel_ctx), 3728c2ecf20Sopenharmony_ci .cra_priority = 300, 3738c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 3748c2ecf20Sopenharmony_ci .cra_init = zip_alloc_comp_ctx_lzs, 3758c2ecf20Sopenharmony_ci .cra_exit = zip_free_comp_ctx, 3768c2ecf20Sopenharmony_ci .cra_u = { .compress = { 3778c2ecf20Sopenharmony_ci .coa_compress = zip_comp_compress, 3788c2ecf20Sopenharmony_ci .coa_decompress = zip_comp_decompress 3798c2ecf20Sopenharmony_ci } } 3808c2ecf20Sopenharmony_ci}; 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_cistatic struct scomp_alg zip_scomp_deflate = { 3838c2ecf20Sopenharmony_ci .alloc_ctx = zip_alloc_scomp_ctx_deflate, 3848c2ecf20Sopenharmony_ci .free_ctx = zip_free_scomp_ctx, 3858c2ecf20Sopenharmony_ci .compress = zip_scomp_compress, 3868c2ecf20Sopenharmony_ci .decompress = zip_scomp_decompress, 3878c2ecf20Sopenharmony_ci .base = { 3888c2ecf20Sopenharmony_ci .cra_name = "deflate", 3898c2ecf20Sopenharmony_ci .cra_driver_name = "deflate-scomp-cavium", 3908c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 3918c2ecf20Sopenharmony_ci .cra_priority = 300, 3928c2ecf20Sopenharmony_ci } 3938c2ecf20Sopenharmony_ci}; 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_cistatic struct scomp_alg zip_scomp_lzs = { 3968c2ecf20Sopenharmony_ci .alloc_ctx = zip_alloc_scomp_ctx_lzs, 3978c2ecf20Sopenharmony_ci .free_ctx = zip_free_scomp_ctx, 3988c2ecf20Sopenharmony_ci .compress = zip_scomp_compress, 3998c2ecf20Sopenharmony_ci .decompress = zip_scomp_decompress, 4008c2ecf20Sopenharmony_ci .base = { 4018c2ecf20Sopenharmony_ci .cra_name = "lzs", 4028c2ecf20Sopenharmony_ci .cra_driver_name = "lzs-scomp-cavium", 4038c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 4048c2ecf20Sopenharmony_ci .cra_priority = 300, 4058c2ecf20Sopenharmony_ci } 4068c2ecf20Sopenharmony_ci}; 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_cistatic int zip_register_compression_device(void) 4098c2ecf20Sopenharmony_ci{ 4108c2ecf20Sopenharmony_ci int ret; 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci ret = crypto_register_alg(&zip_comp_deflate); 4138c2ecf20Sopenharmony_ci if (ret < 0) { 4148c2ecf20Sopenharmony_ci zip_err("Deflate algorithm registration failed\n"); 4158c2ecf20Sopenharmony_ci return ret; 4168c2ecf20Sopenharmony_ci } 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci ret = crypto_register_alg(&zip_comp_lzs); 4198c2ecf20Sopenharmony_ci if (ret < 0) { 4208c2ecf20Sopenharmony_ci zip_err("LZS algorithm registration failed\n"); 4218c2ecf20Sopenharmony_ci goto err_unregister_alg_deflate; 4228c2ecf20Sopenharmony_ci } 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci ret = crypto_register_scomp(&zip_scomp_deflate); 4258c2ecf20Sopenharmony_ci if (ret < 0) { 4268c2ecf20Sopenharmony_ci zip_err("Deflate scomp algorithm registration failed\n"); 4278c2ecf20Sopenharmony_ci goto err_unregister_alg_lzs; 4288c2ecf20Sopenharmony_ci } 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci ret = crypto_register_scomp(&zip_scomp_lzs); 4318c2ecf20Sopenharmony_ci if (ret < 0) { 4328c2ecf20Sopenharmony_ci zip_err("LZS scomp algorithm registration failed\n"); 4338c2ecf20Sopenharmony_ci goto err_unregister_scomp_deflate; 4348c2ecf20Sopenharmony_ci } 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci return ret; 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_cierr_unregister_scomp_deflate: 4398c2ecf20Sopenharmony_ci crypto_unregister_scomp(&zip_scomp_deflate); 4408c2ecf20Sopenharmony_cierr_unregister_alg_lzs: 4418c2ecf20Sopenharmony_ci crypto_unregister_alg(&zip_comp_lzs); 4428c2ecf20Sopenharmony_cierr_unregister_alg_deflate: 4438c2ecf20Sopenharmony_ci crypto_unregister_alg(&zip_comp_deflate); 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_ci return ret; 4468c2ecf20Sopenharmony_ci} 4478c2ecf20Sopenharmony_ci 4488c2ecf20Sopenharmony_cistatic void zip_unregister_compression_device(void) 4498c2ecf20Sopenharmony_ci{ 4508c2ecf20Sopenharmony_ci crypto_unregister_alg(&zip_comp_deflate); 4518c2ecf20Sopenharmony_ci crypto_unregister_alg(&zip_comp_lzs); 4528c2ecf20Sopenharmony_ci crypto_unregister_scomp(&zip_scomp_deflate); 4538c2ecf20Sopenharmony_ci crypto_unregister_scomp(&zip_scomp_lzs); 4548c2ecf20Sopenharmony_ci} 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci/* 4578c2ecf20Sopenharmony_ci * debugfs functions 4588c2ecf20Sopenharmony_ci */ 4598c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 4608c2ecf20Sopenharmony_ci#include <linux/debugfs.h> 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_ci/* Displays ZIP device statistics */ 4638c2ecf20Sopenharmony_cistatic int zip_stats_show(struct seq_file *s, void *unused) 4648c2ecf20Sopenharmony_ci{ 4658c2ecf20Sopenharmony_ci u64 val = 0ull; 4668c2ecf20Sopenharmony_ci u64 avg_chunk = 0ull, avg_cr = 0ull; 4678c2ecf20Sopenharmony_ci u32 q = 0; 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_ci int index = 0; 4708c2ecf20Sopenharmony_ci struct zip_device *zip; 4718c2ecf20Sopenharmony_ci struct zip_stats *st; 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ci for (index = 0; index < MAX_ZIP_DEVICES; index++) { 4748c2ecf20Sopenharmony_ci u64 pending = 0; 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci if (zip_dev[index]) { 4778c2ecf20Sopenharmony_ci zip = zip_dev[index]; 4788c2ecf20Sopenharmony_ci st = &zip->stats; 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_ci /* Get all the pending requests */ 4818c2ecf20Sopenharmony_ci for (q = 0; q < ZIP_NUM_QUEUES; q++) { 4828c2ecf20Sopenharmony_ci val = zip_reg_read((zip->reg_base + 4838c2ecf20Sopenharmony_ci ZIP_DBG_QUEX_STA(q))); 4848c2ecf20Sopenharmony_ci pending += val >> 32 & 0xffffff; 4858c2ecf20Sopenharmony_ci } 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_ci val = atomic64_read(&st->comp_req_complete); 4888c2ecf20Sopenharmony_ci avg_chunk = (val) ? atomic64_read(&st->comp_in_bytes) / val : 0; 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ci val = atomic64_read(&st->comp_out_bytes); 4918c2ecf20Sopenharmony_ci avg_cr = (val) ? atomic64_read(&st->comp_in_bytes) / val : 0; 4928c2ecf20Sopenharmony_ci seq_printf(s, " ZIP Device %d Stats\n" 4938c2ecf20Sopenharmony_ci "-----------------------------------\n" 4948c2ecf20Sopenharmony_ci "Comp Req Submitted : \t%lld\n" 4958c2ecf20Sopenharmony_ci "Comp Req Completed : \t%lld\n" 4968c2ecf20Sopenharmony_ci "Compress In Bytes : \t%lld\n" 4978c2ecf20Sopenharmony_ci "Compressed Out Bytes : \t%lld\n" 4988c2ecf20Sopenharmony_ci "Average Chunk size : \t%llu\n" 4998c2ecf20Sopenharmony_ci "Average Compression ratio : \t%llu\n" 5008c2ecf20Sopenharmony_ci "Decomp Req Submitted : \t%lld\n" 5018c2ecf20Sopenharmony_ci "Decomp Req Completed : \t%lld\n" 5028c2ecf20Sopenharmony_ci "Decompress In Bytes : \t%lld\n" 5038c2ecf20Sopenharmony_ci "Decompressed Out Bytes : \t%lld\n" 5048c2ecf20Sopenharmony_ci "Decompress Bad requests : \t%lld\n" 5058c2ecf20Sopenharmony_ci "Pending Req : \t%lld\n" 5068c2ecf20Sopenharmony_ci "---------------------------------\n", 5078c2ecf20Sopenharmony_ci index, 5088c2ecf20Sopenharmony_ci (u64)atomic64_read(&st->comp_req_submit), 5098c2ecf20Sopenharmony_ci (u64)atomic64_read(&st->comp_req_complete), 5108c2ecf20Sopenharmony_ci (u64)atomic64_read(&st->comp_in_bytes), 5118c2ecf20Sopenharmony_ci (u64)atomic64_read(&st->comp_out_bytes), 5128c2ecf20Sopenharmony_ci avg_chunk, 5138c2ecf20Sopenharmony_ci avg_cr, 5148c2ecf20Sopenharmony_ci (u64)atomic64_read(&st->decomp_req_submit), 5158c2ecf20Sopenharmony_ci (u64)atomic64_read(&st->decomp_req_complete), 5168c2ecf20Sopenharmony_ci (u64)atomic64_read(&st->decomp_in_bytes), 5178c2ecf20Sopenharmony_ci (u64)atomic64_read(&st->decomp_out_bytes), 5188c2ecf20Sopenharmony_ci (u64)atomic64_read(&st->decomp_bad_reqs), 5198c2ecf20Sopenharmony_ci pending); 5208c2ecf20Sopenharmony_ci } 5218c2ecf20Sopenharmony_ci } 5228c2ecf20Sopenharmony_ci return 0; 5238c2ecf20Sopenharmony_ci} 5248c2ecf20Sopenharmony_ci 5258c2ecf20Sopenharmony_ci/* Clears stats data */ 5268c2ecf20Sopenharmony_cistatic int zip_clear_show(struct seq_file *s, void *unused) 5278c2ecf20Sopenharmony_ci{ 5288c2ecf20Sopenharmony_ci int index = 0; 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ci for (index = 0; index < MAX_ZIP_DEVICES; index++) { 5318c2ecf20Sopenharmony_ci if (zip_dev[index]) { 5328c2ecf20Sopenharmony_ci memset(&zip_dev[index]->stats, 0, 5338c2ecf20Sopenharmony_ci sizeof(struct zip_stats)); 5348c2ecf20Sopenharmony_ci seq_printf(s, "Cleared stats for zip %d\n", index); 5358c2ecf20Sopenharmony_ci } 5368c2ecf20Sopenharmony_ci } 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci return 0; 5398c2ecf20Sopenharmony_ci} 5408c2ecf20Sopenharmony_ci 5418c2ecf20Sopenharmony_cistatic struct zip_registers zipregs[64] = { 5428c2ecf20Sopenharmony_ci {"ZIP_CMD_CTL ", 0x0000ull}, 5438c2ecf20Sopenharmony_ci {"ZIP_THROTTLE ", 0x0010ull}, 5448c2ecf20Sopenharmony_ci {"ZIP_CONSTANTS ", 0x00A0ull}, 5458c2ecf20Sopenharmony_ci {"ZIP_QUE0_MAP ", 0x1400ull}, 5468c2ecf20Sopenharmony_ci {"ZIP_QUE1_MAP ", 0x1408ull}, 5478c2ecf20Sopenharmony_ci {"ZIP_QUE_ENA ", 0x0500ull}, 5488c2ecf20Sopenharmony_ci {"ZIP_QUE_PRI ", 0x0508ull}, 5498c2ecf20Sopenharmony_ci {"ZIP_QUE0_DONE ", 0x2000ull}, 5508c2ecf20Sopenharmony_ci {"ZIP_QUE1_DONE ", 0x2008ull}, 5518c2ecf20Sopenharmony_ci {"ZIP_QUE0_DOORBELL ", 0x4000ull}, 5528c2ecf20Sopenharmony_ci {"ZIP_QUE1_DOORBELL ", 0x4008ull}, 5538c2ecf20Sopenharmony_ci {"ZIP_QUE0_SBUF_ADDR ", 0x1000ull}, 5548c2ecf20Sopenharmony_ci {"ZIP_QUE1_SBUF_ADDR ", 0x1008ull}, 5558c2ecf20Sopenharmony_ci {"ZIP_QUE0_SBUF_CTL ", 0x1200ull}, 5568c2ecf20Sopenharmony_ci {"ZIP_QUE1_SBUF_CTL ", 0x1208ull}, 5578c2ecf20Sopenharmony_ci { NULL, 0} 5588c2ecf20Sopenharmony_ci}; 5598c2ecf20Sopenharmony_ci 5608c2ecf20Sopenharmony_ci/* Prints registers' contents */ 5618c2ecf20Sopenharmony_cistatic int zip_regs_show(struct seq_file *s, void *unused) 5628c2ecf20Sopenharmony_ci{ 5638c2ecf20Sopenharmony_ci u64 val = 0; 5648c2ecf20Sopenharmony_ci int i = 0, index = 0; 5658c2ecf20Sopenharmony_ci 5668c2ecf20Sopenharmony_ci for (index = 0; index < MAX_ZIP_DEVICES; index++) { 5678c2ecf20Sopenharmony_ci if (zip_dev[index]) { 5688c2ecf20Sopenharmony_ci seq_printf(s, "--------------------------------\n" 5698c2ecf20Sopenharmony_ci " ZIP Device %d Registers\n" 5708c2ecf20Sopenharmony_ci "--------------------------------\n", 5718c2ecf20Sopenharmony_ci index); 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_ci i = 0; 5748c2ecf20Sopenharmony_ci 5758c2ecf20Sopenharmony_ci while (zipregs[i].reg_name) { 5768c2ecf20Sopenharmony_ci val = zip_reg_read((zip_dev[index]->reg_base + 5778c2ecf20Sopenharmony_ci zipregs[i].reg_offset)); 5788c2ecf20Sopenharmony_ci seq_printf(s, "%s: 0x%016llx\n", 5798c2ecf20Sopenharmony_ci zipregs[i].reg_name, val); 5808c2ecf20Sopenharmony_ci i++; 5818c2ecf20Sopenharmony_ci } 5828c2ecf20Sopenharmony_ci } 5838c2ecf20Sopenharmony_ci } 5848c2ecf20Sopenharmony_ci return 0; 5858c2ecf20Sopenharmony_ci} 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(zip_stats); 5888c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(zip_clear); 5898c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(zip_regs); 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci/* Root directory for thunderx_zip debugfs entry */ 5928c2ecf20Sopenharmony_cistatic struct dentry *zip_debugfs_root; 5938c2ecf20Sopenharmony_ci 5948c2ecf20Sopenharmony_cistatic void __init zip_debugfs_init(void) 5958c2ecf20Sopenharmony_ci{ 5968c2ecf20Sopenharmony_ci if (!debugfs_initialized()) 5978c2ecf20Sopenharmony_ci return; 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_ci zip_debugfs_root = debugfs_create_dir("thunderx_zip", NULL); 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ci /* Creating files for entries inside thunderx_zip directory */ 6028c2ecf20Sopenharmony_ci debugfs_create_file("zip_stats", 0444, zip_debugfs_root, NULL, 6038c2ecf20Sopenharmony_ci &zip_stats_fops); 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ci debugfs_create_file("zip_clear", 0444, zip_debugfs_root, NULL, 6068c2ecf20Sopenharmony_ci &zip_clear_fops); 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_ci debugfs_create_file("zip_regs", 0444, zip_debugfs_root, NULL, 6098c2ecf20Sopenharmony_ci &zip_regs_fops); 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_ci} 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_cistatic void __exit zip_debugfs_exit(void) 6148c2ecf20Sopenharmony_ci{ 6158c2ecf20Sopenharmony_ci debugfs_remove_recursive(zip_debugfs_root); 6168c2ecf20Sopenharmony_ci} 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_ci#else 6198c2ecf20Sopenharmony_cistatic void __init zip_debugfs_init(void) { } 6208c2ecf20Sopenharmony_cistatic void __exit zip_debugfs_exit(void) { } 6218c2ecf20Sopenharmony_ci#endif 6228c2ecf20Sopenharmony_ci/* debugfs - end */ 6238c2ecf20Sopenharmony_ci 6248c2ecf20Sopenharmony_cistatic int __init zip_init_module(void) 6258c2ecf20Sopenharmony_ci{ 6268c2ecf20Sopenharmony_ci int ret; 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ci zip_msg("%s\n", DRV_NAME); 6298c2ecf20Sopenharmony_ci 6308c2ecf20Sopenharmony_ci ret = pci_register_driver(&zip_driver); 6318c2ecf20Sopenharmony_ci if (ret < 0) { 6328c2ecf20Sopenharmony_ci zip_err("ZIP: pci_register_driver() failed\n"); 6338c2ecf20Sopenharmony_ci return ret; 6348c2ecf20Sopenharmony_ci } 6358c2ecf20Sopenharmony_ci 6368c2ecf20Sopenharmony_ci /* Register with the Kernel Crypto Interface */ 6378c2ecf20Sopenharmony_ci ret = zip_register_compression_device(); 6388c2ecf20Sopenharmony_ci if (ret < 0) { 6398c2ecf20Sopenharmony_ci zip_err("ZIP: Kernel Crypto Registration failed\n"); 6408c2ecf20Sopenharmony_ci goto err_pci_unregister; 6418c2ecf20Sopenharmony_ci } 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_ci /* comp-decomp statistics are handled with debugfs interface */ 6448c2ecf20Sopenharmony_ci zip_debugfs_init(); 6458c2ecf20Sopenharmony_ci 6468c2ecf20Sopenharmony_ci return ret; 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_cierr_pci_unregister: 6498c2ecf20Sopenharmony_ci pci_unregister_driver(&zip_driver); 6508c2ecf20Sopenharmony_ci return ret; 6518c2ecf20Sopenharmony_ci} 6528c2ecf20Sopenharmony_ci 6538c2ecf20Sopenharmony_cistatic void __exit zip_cleanup_module(void) 6548c2ecf20Sopenharmony_ci{ 6558c2ecf20Sopenharmony_ci zip_debugfs_exit(); 6568c2ecf20Sopenharmony_ci 6578c2ecf20Sopenharmony_ci /* Unregister from the kernel crypto interface */ 6588c2ecf20Sopenharmony_ci zip_unregister_compression_device(); 6598c2ecf20Sopenharmony_ci 6608c2ecf20Sopenharmony_ci /* Unregister this driver for pci zip devices */ 6618c2ecf20Sopenharmony_ci pci_unregister_driver(&zip_driver); 6628c2ecf20Sopenharmony_ci} 6638c2ecf20Sopenharmony_ci 6648c2ecf20Sopenharmony_cimodule_init(zip_init_module); 6658c2ecf20Sopenharmony_cimodule_exit(zip_cleanup_module); 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_ciMODULE_AUTHOR("Cavium Inc"); 6688c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Cavium Inc ThunderX ZIP Driver"); 6698c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 6708c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(pci, zip_id_table); 671