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 <linux/delay.h> 47 #include <linux/sched.h> 48 49 #include "common.h" 50 #include "zip_deflate.h" 51 52 /* Prepares the deflate zip command */ 53 static int prepare_zip_command(struct zip_operation *zip_ops, 54 struct zip_state *s, union zip_inst_s *zip_cmd) 55 { 56 union zip_zres_s *result_ptr = &s->result; 57 58 memset(zip_cmd, 0, sizeof(s->zip_cmd)); 59 memset(result_ptr, 0, sizeof(s->result)); 60 61 /* IWORD #0 */ 62 /* History gather */ 63 zip_cmd->s.hg = 0; 64 /* compression enable = 1 for deflate */ 65 zip_cmd->s.ce = 1; 66 /* sf (sync flush) */ 67 zip_cmd->s.sf = 1; 68 /* ef (end of file) */ 69 if (zip_ops->flush == ZIP_FLUSH_FINISH) { 70 zip_cmd->s.ef = 1; 71 zip_cmd->s.sf = 0; 72 } 73 74 zip_cmd->s.cc = zip_ops->ccode; 75 /* ss (compression speed/storage) */ 76 zip_cmd->s.ss = zip_ops->speed; 77 78 /* IWORD #1 */ 79 /* adler checksum */ 80 zip_cmd->s.adlercrc32 = zip_ops->csum; 81 zip_cmd->s.historylength = zip_ops->history_len; 82 zip_cmd->s.dg = 0; 83 84 /* IWORD # 6 and 7 - compression input/history pointer */ 85 zip_cmd->s.inp_ptr_addr.s.addr = __pa(zip_ops->input); 86 zip_cmd->s.inp_ptr_ctl.s.length = (zip_ops->input_len + 87 zip_ops->history_len); 88 zip_cmd->s.ds = 0; 89 90 /* IWORD # 8 and 9 - Output pointer */ 91 zip_cmd->s.out_ptr_addr.s.addr = __pa(zip_ops->output); 92 zip_cmd->s.out_ptr_ctl.s.length = zip_ops->output_len; 93 /* maximum number of output-stream bytes that can be written */ 94 zip_cmd->s.totaloutputlength = zip_ops->output_len; 95 96 /* IWORD # 10 and 11 - Result pointer */ 97 zip_cmd->s.res_ptr_addr.s.addr = __pa(result_ptr); 98 /* Clearing completion code */ 99 result_ptr->s.compcode = 0; 100 101 return 0; 102 } 103 104 /** 105 * zip_deflate - API to offload deflate operation to hardware 106 * @zip_ops: Pointer to zip operation structure 107 * @s: Pointer to the structure representing zip state 108 * @zip_dev: Pointer to zip device structure 109 * 110 * This function prepares the zip deflate command and submits it to the zip 111 * engine for processing. 112 * 113 * Return: 0 if successful or error code 114 */ 115 int zip_deflate(struct zip_operation *zip_ops, struct zip_state *s, 116 struct zip_device *zip_dev) 117 { 118 union zip_inst_s *zip_cmd = &s->zip_cmd; 119 union zip_zres_s *result_ptr = &s->result; 120 u32 queue; 121 122 /* Prepares zip command based on the input parameters */ 123 prepare_zip_command(zip_ops, s, zip_cmd); 124 125 atomic64_add(zip_ops->input_len, &zip_dev->stats.comp_in_bytes); 126 /* Loads zip command into command queues and rings door bell */ 127 queue = zip_load_instr(zip_cmd, zip_dev); 128 129 /* Stats update for compression requests submitted */ 130 atomic64_inc(&zip_dev->stats.comp_req_submit); 131 132 while (!result_ptr->s.compcode) 133 continue; 134 135 /* Stats update for compression requests completed */ 136 atomic64_inc(&zip_dev->stats.comp_req_complete); 137 138 zip_ops->compcode = result_ptr->s.compcode; 139 switch (zip_ops->compcode) { 140 case ZIP_CMD_NOTDONE: 141 zip_dbg("Zip instruction not yet completed"); 142 return ZIP_ERROR; 143 144 case ZIP_CMD_SUCCESS: 145 zip_dbg("Zip instruction completed successfully"); 146 zip_update_cmd_bufs(zip_dev, queue); 147 break; 148 149 case ZIP_CMD_DTRUNC: 150 zip_dbg("Output Truncate error"); 151 /* Returning ZIP_ERROR to avoid copy to user */ 152 return ZIP_ERROR; 153 154 default: 155 zip_err("Zip instruction failed. Code:%d", zip_ops->compcode); 156 return ZIP_ERROR; 157 } 158 159 /* Update the CRC depending on the format */ 160 switch (zip_ops->format) { 161 case RAW_FORMAT: 162 zip_dbg("RAW Format: %d ", zip_ops->format); 163 /* Get checksum from engine, need to feed it again */ 164 zip_ops->csum = result_ptr->s.adler32; 165 break; 166 167 case ZLIB_FORMAT: 168 zip_dbg("ZLIB Format: %d ", zip_ops->format); 169 zip_ops->csum = result_ptr->s.adler32; 170 break; 171 172 case GZIP_FORMAT: 173 zip_dbg("GZIP Format: %d ", zip_ops->format); 174 zip_ops->csum = result_ptr->s.crc32; 175 break; 176 177 case LZS_FORMAT: 178 zip_dbg("LZS Format: %d ", zip_ops->format); 179 break; 180 181 default: 182 zip_err("Unknown Format:%d\n", zip_ops->format); 183 } 184 185 atomic64_add(result_ptr->s.totalbyteswritten, 186 &zip_dev->stats.comp_out_bytes); 187 188 /* Update output_len */ 189 if (zip_ops->output_len < result_ptr->s.totalbyteswritten) { 190 /* Dynamic stop && strm->output_len < zipconstants[onfsize] */ 191 zip_err("output_len (%d) < total bytes written(%d)\n", 192 zip_ops->output_len, result_ptr->s.totalbyteswritten); 193 zip_ops->output_len = 0; 194 195 } else { 196 zip_ops->output_len = result_ptr->s.totalbyteswritten; 197 } 198 199 return 0; 200 } 201