Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | /********************************************************************** * Author: Cavium, Inc. * * Contact: support@cavium.com * Please include "LiquidIO" in the subject. * * Copyright (c) 2003-2016 Cavium, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, Version 2, as * published by the Free Software Foundation. * * This file is distributed in the hope that it will be useful, but * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or * NONINFRINGEMENT. See the GNU General Public License for more details. ***********************************************************************/ /*! \file octeon_iq.h * \brief Host Driver: Implementation of Octeon input queues. "Input" is * with respect to the Octeon device on the NIC. From this driver's * point of view they are egress queues. */ #ifndef __OCTEON_IQ_H__ #define __OCTEON_IQ_H__ #define IQ_STATUS_RUNNING 1 #define IQ_SEND_OK 0 #define IQ_SEND_STOP 1 #define IQ_SEND_FAILED -1 /*------------------------- INSTRUCTION QUEUE --------------------------*/ /* \cond */ #define REQTYPE_NONE 0 #define REQTYPE_NORESP_NET 1 #define REQTYPE_NORESP_NET_SG 2 #define REQTYPE_RESP_NET 3 #define REQTYPE_RESP_NET_SG 4 #define REQTYPE_SOFT_COMMAND 5 #define REQTYPE_LAST 5 struct octeon_request_list { u32 reqtype; void *buf; }; /* \endcond */ /** Input Queue statistics. Each input queue has four stats fields. */ struct oct_iq_stats { u64 instr_posted; /**< Instructions posted to this queue. */ u64 instr_processed; /**< Instructions processed in this queue. */ u64 instr_dropped; /**< Instructions that could not be processed */ u64 bytes_sent; /**< Bytes sent through this queue. */ u64 sgentry_sent;/**< Gather entries sent through this queue. */ u64 tx_done;/**< Num of packets sent to network. */ u64 tx_iq_busy;/**< Numof times this iq was found to be full. */ u64 tx_dropped;/**< Numof pkts dropped dueto xmitpath errors. */ u64 tx_tot_bytes;/**< Total count of bytes sento to network. */ u64 tx_gso; /* count of tso */ u64 tx_vxlan; /* tunnel */ u64 tx_dmamap_fail; /* Number of times dma mapping failed */ u64 tx_restart; /* Number of times this queue restarted */ }; #define OCT_IQ_STATS_SIZE (sizeof(struct oct_iq_stats)) /** The instruction (input) queue. * The input queue is used to post raw (instruction) mode data or packet * data to Octeon device from the host. Each input queue (upto 4) for * a Octeon device has one such structure to represent it. */ struct octeon_instr_queue { struct octeon_device *oct_dev; /** A spinlock to protect access to the input ring. */ spinlock_t lock; /** A spinlock to protect while posting on the ring. */ spinlock_t post_lock; /** This flag indicates if the queue can be used for soft commands. * If this flag is set, post_lock must be acquired before posting * a command to the queue. * If this flag is clear, post_lock is invalid for the queue. * All control commands (soft commands) will go through only Queue 0 * (control and data queue). So only queue-0 needs post_lock, * other queues are only data queues and does not need post_lock */ bool allow_soft_cmds; u32 pkt_in_done; u32 pkts_processed; /** A spinlock to protect access to the input ring.*/ spinlock_t iq_flush_running_lock; /** Flag that indicates if the queue uses 64 byte commands. */ u32 iqcmd_64B:1; /** Queue info. */ union oct_txpciq txpciq; u32 rsvd:17; /* Controls whether extra flushing of IQ is done on Tx */ u32 do_auto_flush:1; u32 status:8; /** Maximum no. of instructions in this queue. */ u32 max_count; /** Index in input ring where the driver should write the next packet */ u32 host_write_index; /** Index in input ring where Octeon is expected to read the next * packet. */ u32 octeon_read_index; /** This index aids in finding the window in the queue where Octeon * has read the commands. */ u32 flush_index; /** This field keeps track of the instructions pending in this queue. */ atomic_t instr_pending; u32 reset_instr_cnt; /** Pointer to the Virtual Base addr of the input ring. */ u8 *base_addr; struct octeon_request_list *request_list; /** Octeon doorbell register for the ring. */ void __iomem *doorbell_reg; /** Octeon instruction count register for this ring. */ void __iomem *inst_cnt_reg; /** Number of instructions pending to be posted to Octeon. */ u32 fill_cnt; /** The max. number of instructions that can be held pending by the * driver. */ u32 fill_threshold; /** The last time that the doorbell was rung. */ u64 last_db_time; /** The doorbell timeout. If the doorbell was not rung for this time and * fill_cnt is non-zero, ring the doorbell again. */ u32 db_timeout; /** Statistics for this input queue. */ struct oct_iq_stats stats; /** DMA mapped base address of the input descriptor ring. */ dma_addr_t base_addr_dma; /** Application context */ void *app_ctx; /* network stack queue index */ int q_index; /*os ifidx associated with this queue */ int ifidx; }; /*---------------------- INSTRUCTION FORMAT ----------------------------*/ /** 32-byte instruction format. * Format of instruction for a 32-byte mode input queue. */ struct octeon_instr_32B { /** Pointer where the input data is available. */ u64 dptr; /** Instruction Header. */ u64 ih; /** Pointer where the response for a RAW mode packet will be written * by Octeon. */ u64 rptr; /** Input Request Header. Additional info about the input. */ u64 irh; }; #define OCT_32B_INSTR_SIZE (sizeof(struct octeon_instr_32B)) /** 64-byte instruction format. * Format of instruction for a 64-byte mode input queue. */ struct octeon_instr2_64B { /** Pointer where the input data is available. */ u64 dptr; /** Instruction Header. */ u64 ih2; /** Input Request Header. */ u64 irh; /** opcode/subcode specific parameters */ u64 ossp[2]; /** Return Data Parameters */ u64 rdp; /** Pointer where the response for a RAW mode packet will be written * by Octeon. */ u64 rptr; u64 reserved; }; struct octeon_instr3_64B { /** Pointer where the input data is available. */ u64 dptr; /** Instruction Header. */ u64 ih3; /** Instruction Header. */ u64 pki_ih3; /** Input Request Header. */ u64 irh; /** opcode/subcode specific parameters */ u64 ossp[2]; /** Return Data Parameters */ u64 rdp; /** Pointer where the response for a RAW mode packet will be written * by Octeon. */ u64 rptr; }; union octeon_instr_64B { struct octeon_instr2_64B cmd2; struct octeon_instr3_64B cmd3; }; #define OCT_64B_INSTR_SIZE (sizeof(union octeon_instr_64B)) /** The size of each buffer in soft command buffer pool */ #define SOFT_COMMAND_BUFFER_SIZE 2048 struct octeon_soft_command { /** Soft command buffer info. */ struct list_head node; u64 dma_addr; u32 size; /** Command and return status */ union octeon_instr_64B cmd; #define COMPLETION_WORD_INIT 0xffffffffffffffffULL u64 *status_word; /** Data buffer info */ void *virtdptr; u64 dmadptr; u32 datasize; /** Return buffer info */ void *virtrptr; u64 dmarptr; u32 rdatasize; /** Context buffer info */ void *ctxptr; u32 ctxsize; /** Time out and callback */ size_t expiry_time; u32 iq_no; void (*callback)(struct octeon_device *, u32, void *); void *callback_arg; int caller_is_done; u32 sc_status; struct completion complete; }; /* max timeout (in milli sec) for soft request */ #define LIO_SC_MAX_TMO_MS 60000 /** Maximum number of buffers to allocate into soft command buffer pool */ #define MAX_SOFT_COMMAND_BUFFERS 256 /** Head of a soft command buffer pool. */ struct octeon_sc_buffer_pool { /** List structure to add delete pending entries to */ struct list_head head; /** A lock for this response list */ spinlock_t lock; atomic_t alloc_buf_count; }; #define INCR_INSTRQUEUE_PKT_COUNT(octeon_dev_ptr, iq_no, field, count) \ (((octeon_dev_ptr)->instr_queue[iq_no]->stats.field) += count) int octeon_setup_sc_buffer_pool(struct octeon_device *oct); int octeon_free_sc_done_list(struct octeon_device *oct); int octeon_free_sc_zombie_list(struct octeon_device *oct); int octeon_free_sc_buffer_pool(struct octeon_device *oct); struct octeon_soft_command * octeon_alloc_soft_command(struct octeon_device *oct, u32 datasize, u32 rdatasize, u32 ctxsize); void octeon_free_soft_command(struct octeon_device *oct, struct octeon_soft_command *sc); /** * octeon_init_instr_queue() * @param octeon_dev - pointer to the octeon device structure. * @param txpciq - queue to be initialized (0 <= q_no <= 3). * * Called at driver init time for each input queue. iq_conf has the * configuration parameters for the queue. * * @return Success: 0 Failure: 1 */ int octeon_init_instr_queue(struct octeon_device *octeon_dev, union oct_txpciq txpciq, u32 num_descs); /** * octeon_delete_instr_queue() * @param octeon_dev - pointer to the octeon device structure. * @param iq_no - queue to be deleted (0 <= q_no <= 3). * * Called at driver unload time for each input queue. Deletes all * allocated resources for the input queue. * * @return Success: 0 Failure: 1 */ int octeon_delete_instr_queue(struct octeon_device *octeon_dev, u32 iq_no); int lio_wait_for_instr_fetch(struct octeon_device *oct); void octeon_ring_doorbell_locked(struct octeon_device *oct, u32 iq_no); int octeon_register_reqtype_free_fn(struct octeon_device *oct, int reqtype, void (*fn)(void *)); int lio_process_iq_request_list(struct octeon_device *oct, struct octeon_instr_queue *iq, u32 napi_budget); int octeon_send_command(struct octeon_device *oct, u32 iq_no, u32 force_db, void *cmd, void *buf, u32 datasize, u32 reqtype); void octeon_dump_soft_command(struct octeon_device *oct, struct octeon_soft_command *sc); void octeon_prepare_soft_command(struct octeon_device *oct, struct octeon_soft_command *sc, u8 opcode, u8 subcode, u32 irh_ossp, u64 ossp0, u64 ossp1); int octeon_send_soft_command(struct octeon_device *oct, struct octeon_soft_command *sc); int octeon_setup_iq(struct octeon_device *oct, int ifidx, int q_index, union oct_txpciq iq_no, u32 num_descs, void *app_ctx); int octeon_flush_iq(struct octeon_device *oct, struct octeon_instr_queue *iq, u32 napi_budget); #endif /* __OCTEON_IQ_H__ */ |