Raghu Vatsavayi | f21fb3e | 2015-06-09 18:15:23 -0700 | [diff] [blame^] | 1 | /********************************************************************** |
| 2 | * Author: Cavium, Inc. |
| 3 | * |
| 4 | * Contact: support@cavium.com |
| 5 | * Please include "LiquidIO" in the subject. |
| 6 | * |
| 7 | * Copyright (c) 2003-2015 Cavium, Inc. |
| 8 | * |
| 9 | * This file is free software; you can redistribute it and/or modify |
| 10 | * it under the terms of the GNU General Public License, Version 2, as |
| 11 | * published by the Free Software Foundation. |
| 12 | * |
| 13 | * This file is distributed in the hope that it will be useful, but |
| 14 | * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty |
| 15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or |
| 16 | * NONINFRINGEMENT. See the GNU General Public License for more |
| 17 | * details. |
| 18 | * |
| 19 | * This file may also be available under a different license from Cavium. |
| 20 | * Contact Cavium, Inc. for more information |
| 21 | **********************************************************************/ |
| 22 | |
| 23 | /*! \file octeon_droq.h |
| 24 | * \brief Implementation of Octeon Output queues. "Output" is with |
| 25 | * respect to the Octeon device on the NIC. From this driver's point of |
| 26 | * view they are ingress queues. |
| 27 | */ |
| 28 | |
| 29 | #ifndef __OCTEON_DROQ_H__ |
| 30 | #define __OCTEON_DROQ_H__ |
| 31 | |
| 32 | /* Default number of packets that will be processed in one iteration. */ |
| 33 | #define MAX_PACKET_BUDGET 0xFFFFFFFF |
| 34 | |
| 35 | /** Octeon descriptor format. |
| 36 | * The descriptor ring is made of descriptors which have 2 64-bit values: |
| 37 | * -# Physical (bus) address of the data buffer. |
| 38 | * -# Physical (bus) address of a octeon_droq_info structure. |
| 39 | * The Octeon device DMA's incoming packets and its information at the address |
| 40 | * given by these descriptor fields. |
| 41 | */ |
| 42 | struct octeon_droq_desc { |
| 43 | /** The buffer pointer */ |
| 44 | u64 buffer_ptr; |
| 45 | |
| 46 | /** The Info pointer */ |
| 47 | u64 info_ptr; |
| 48 | }; |
| 49 | |
| 50 | #define OCT_DROQ_DESC_SIZE (sizeof(struct octeon_droq_desc)) |
| 51 | |
| 52 | /** Information about packet DMA'ed by Octeon. |
| 53 | * The format of the information available at Info Pointer after Octeon |
| 54 | * has posted a packet. Not all descriptors have valid information. Only |
| 55 | * the Info field of the first descriptor for a packet has information |
| 56 | * about the packet. |
| 57 | */ |
| 58 | struct octeon_droq_info { |
| 59 | /** The Output Receive Header. */ |
| 60 | union octeon_rh rh; |
| 61 | |
| 62 | /** The Length of the packet. */ |
| 63 | u64 length; |
| 64 | }; |
| 65 | |
| 66 | #define OCT_DROQ_INFO_SIZE (sizeof(struct octeon_droq_info)) |
| 67 | |
| 68 | /** Pointer to data buffer. |
| 69 | * Driver keeps a pointer to the data buffer that it made available to |
| 70 | * the Octeon device. Since the descriptor ring keeps physical (bus) |
| 71 | * addresses, this field is required for the driver to keep track of |
| 72 | * the virtual address pointers. |
| 73 | */ |
| 74 | struct octeon_recv_buffer { |
| 75 | /** Packet buffer, including metadata. */ |
| 76 | void *buffer; |
| 77 | |
| 78 | /** Data in the packet buffer. */ |
| 79 | u8 *data; |
| 80 | }; |
| 81 | |
| 82 | #define OCT_DROQ_RECVBUF_SIZE (sizeof(struct octeon_recv_buffer)) |
| 83 | |
| 84 | /** Output Queue statistics. Each output queue has four stats fields. */ |
| 85 | struct oct_droq_stats { |
| 86 | /** Number of packets received in this queue. */ |
| 87 | u64 pkts_received; |
| 88 | |
| 89 | /** Bytes received by this queue. */ |
| 90 | u64 bytes_received; |
| 91 | |
| 92 | /** Packets dropped due to no dispatch function. */ |
| 93 | u64 dropped_nodispatch; |
| 94 | |
| 95 | /** Packets dropped due to no memory available. */ |
| 96 | u64 dropped_nomem; |
| 97 | |
| 98 | /** Packets dropped due to large number of pkts to process. */ |
| 99 | u64 dropped_toomany; |
| 100 | |
| 101 | /** Number of packets sent to stack from this queue. */ |
| 102 | u64 rx_pkts_received; |
| 103 | |
| 104 | /** Number of Bytes sent to stack from this queue. */ |
| 105 | u64 rx_bytes_received; |
| 106 | |
| 107 | /** Num of Packets dropped due to receive path failures. */ |
| 108 | u64 rx_dropped; |
| 109 | }; |
| 110 | |
| 111 | #define POLL_EVENT_INTR_ARRIVED 1 |
| 112 | #define POLL_EVENT_PROCESS_PKTS 2 |
| 113 | #define POLL_EVENT_PENDING_PKTS 3 |
| 114 | #define POLL_EVENT_ENABLE_INTR 4 |
| 115 | |
| 116 | /* The maximum number of buffers that can be dispatched from the |
| 117 | * output/dma queue. Set to 64 assuming 1K buffers in DROQ and the fact that |
| 118 | * max packet size from DROQ is 64K. |
| 119 | */ |
| 120 | #define MAX_RECV_BUFS 64 |
| 121 | |
| 122 | /** Receive Packet format used when dispatching output queue packets |
| 123 | * with non-raw opcodes. |
| 124 | * The received packet will be sent to the upper layers using this |
| 125 | * structure which is passed as a parameter to the dispatch function |
| 126 | */ |
| 127 | struct octeon_recv_pkt { |
| 128 | /** Number of buffers in this received packet */ |
| 129 | u16 buffer_count; |
| 130 | |
| 131 | /** Id of the device that is sending the packet up */ |
| 132 | u16 octeon_id; |
| 133 | |
| 134 | /** Length of data in the packet buffer */ |
| 135 | u32 length; |
| 136 | |
| 137 | /** The receive header */ |
| 138 | union octeon_rh rh; |
| 139 | |
| 140 | /** Pointer to the OS-specific packet buffer */ |
| 141 | void *buffer_ptr[MAX_RECV_BUFS]; |
| 142 | |
| 143 | /** Size of the buffers pointed to by ptr's in buffer_ptr */ |
| 144 | u32 buffer_size[MAX_RECV_BUFS]; |
| 145 | }; |
| 146 | |
| 147 | #define OCT_RECV_PKT_SIZE (sizeof(struct octeon_recv_pkt)) |
| 148 | |
| 149 | /** The first parameter of a dispatch function. |
| 150 | * For a raw mode opcode, the driver dispatches with the device |
| 151 | * pointer in this structure. |
| 152 | * For non-raw mode opcode, the driver dispatches the recv_pkt |
| 153 | * created to contain the buffers with data received from Octeon. |
| 154 | * --------------------- |
| 155 | * | *recv_pkt ----|--- |
| 156 | * |-------------------| | |
| 157 | * | 0 or more bytes | | |
| 158 | * | reserved by driver| | |
| 159 | * |-------------------|<-/ |
| 160 | * | octeon_recv_pkt | |
| 161 | * | | |
| 162 | * |___________________| |
| 163 | */ |
| 164 | struct octeon_recv_info { |
| 165 | void *rsvd; |
| 166 | struct octeon_recv_pkt *recv_pkt; |
| 167 | }; |
| 168 | |
| 169 | #define OCT_RECV_INFO_SIZE (sizeof(struct octeon_recv_info)) |
| 170 | |
| 171 | /** Allocate a recv_info structure. The recv_pkt pointer in the recv_info |
| 172 | * structure is filled in before this call returns. |
| 173 | * @param extra_bytes - extra bytes to be allocated at the end of the recv info |
| 174 | * structure. |
| 175 | * @return - pointer to a newly allocated recv_info structure. |
| 176 | */ |
| 177 | static inline struct octeon_recv_info *octeon_alloc_recv_info(int extra_bytes) |
| 178 | { |
| 179 | struct octeon_recv_info *recv_info; |
| 180 | u8 *buf; |
| 181 | |
| 182 | buf = kmalloc(OCT_RECV_PKT_SIZE + OCT_RECV_INFO_SIZE + |
| 183 | extra_bytes, GFP_ATOMIC); |
| 184 | if (!buf) |
| 185 | return NULL; |
| 186 | |
| 187 | recv_info = (struct octeon_recv_info *)buf; |
| 188 | recv_info->recv_pkt = |
| 189 | (struct octeon_recv_pkt *)(buf + OCT_RECV_INFO_SIZE); |
| 190 | recv_info->rsvd = NULL; |
| 191 | if (extra_bytes) |
| 192 | recv_info->rsvd = buf + OCT_RECV_INFO_SIZE + OCT_RECV_PKT_SIZE; |
| 193 | |
| 194 | return recv_info; |
| 195 | } |
| 196 | |
| 197 | /** Free a recv_info structure. |
| 198 | * @param recv_info - Pointer to receive_info to be freed |
| 199 | */ |
| 200 | static inline void octeon_free_recv_info(struct octeon_recv_info *recv_info) |
| 201 | { |
| 202 | kfree(recv_info); |
| 203 | } |
| 204 | |
| 205 | typedef int (*octeon_dispatch_fn_t)(struct octeon_recv_info *, void *); |
| 206 | |
| 207 | /** Used by NIC module to register packet handler and to get device |
| 208 | * information for each octeon device. |
| 209 | */ |
| 210 | struct octeon_droq_ops { |
| 211 | /** This registered function will be called by the driver with |
| 212 | * the octeon id, pointer to buffer from droq and length of |
| 213 | * data in the buffer. The receive header gives the port |
| 214 | * number to the caller. Function pointer is set by caller. |
| 215 | */ |
| 216 | void (*fptr)(u32, void *, u32, union octeon_rh *, void *); |
| 217 | |
| 218 | /* This function will be called by the driver for all NAPI related |
| 219 | * events. The first param is the octeon id. The second param is the |
| 220 | * output queue number. The third is the NAPI event that occurred. |
| 221 | */ |
| 222 | void (*napi_fn)(void *); |
| 223 | |
| 224 | u32 poll_mode; |
| 225 | |
| 226 | /** Flag indicating if the DROQ handler should drop packets that |
| 227 | * it cannot handle in one iteration. Set by caller. |
| 228 | */ |
| 229 | u32 drop_on_max; |
| 230 | }; |
| 231 | |
| 232 | /** The Descriptor Ring Output Queue structure. |
| 233 | * This structure has all the information required to implement a |
| 234 | * Octeon DROQ. |
| 235 | */ |
| 236 | struct octeon_droq { |
| 237 | /** A spinlock to protect access to this ring. */ |
| 238 | spinlock_t lock; |
| 239 | |
| 240 | u32 q_no; |
| 241 | |
| 242 | struct octeon_droq_ops ops; |
| 243 | |
| 244 | struct octeon_device *oct_dev; |
| 245 | |
| 246 | /** The 8B aligned descriptor ring starts at this address. */ |
| 247 | struct octeon_droq_desc *desc_ring; |
| 248 | |
| 249 | /** Index in the ring where the driver should read the next packet */ |
| 250 | u32 read_idx; |
| 251 | |
| 252 | /** Index in the ring where Octeon will write the next packet */ |
| 253 | u32 write_idx; |
| 254 | |
| 255 | /** Index in the ring where the driver will refill the descriptor's |
| 256 | * buffer |
| 257 | */ |
| 258 | u32 refill_idx; |
| 259 | |
| 260 | /** Packets pending to be processed */ |
| 261 | atomic_t pkts_pending; |
| 262 | |
| 263 | /** Number of descriptors in this ring. */ |
| 264 | u32 max_count; |
| 265 | |
| 266 | /** The number of descriptors pending refill. */ |
| 267 | u32 refill_count; |
| 268 | |
| 269 | u32 pkts_per_intr; |
| 270 | u32 refill_threshold; |
| 271 | |
| 272 | /** The max number of descriptors in DROQ without a buffer. |
| 273 | * This field is used to keep track of empty space threshold. If the |
| 274 | * refill_count reaches this value, the DROQ cannot accept a max-sized |
| 275 | * (64K) packet. |
| 276 | */ |
| 277 | u32 max_empty_descs; |
| 278 | |
| 279 | /** The 8B aligned info ptrs begin from this address. */ |
| 280 | struct octeon_droq_info *info_list; |
| 281 | |
| 282 | /** The receive buffer list. This list has the virtual addresses of the |
| 283 | * buffers. |
| 284 | */ |
| 285 | struct octeon_recv_buffer *recv_buf_list; |
| 286 | |
| 287 | /** The size of each buffer pointed by the buffer pointer. */ |
| 288 | u32 buffer_size; |
| 289 | |
| 290 | /** Pointer to the mapped packet credit register. |
| 291 | * Host writes number of info/buffer ptrs available to this register |
| 292 | */ |
| 293 | void __iomem *pkts_credit_reg; |
| 294 | |
| 295 | /** Pointer to the mapped packet sent register. |
| 296 | * Octeon writes the number of packets DMA'ed to host memory |
| 297 | * in this register. |
| 298 | */ |
| 299 | void __iomem *pkts_sent_reg; |
| 300 | |
| 301 | struct list_head dispatch_list; |
| 302 | |
| 303 | /** Statistics for this DROQ. */ |
| 304 | struct oct_droq_stats stats; |
| 305 | |
| 306 | /** DMA mapped address of the DROQ descriptor ring. */ |
| 307 | size_t desc_ring_dma; |
| 308 | |
| 309 | /** Info ptr list are allocated at this virtual address. */ |
| 310 | size_t info_base_addr; |
| 311 | |
| 312 | /** DMA mapped address of the info list */ |
| 313 | size_t info_list_dma; |
| 314 | |
| 315 | /** Allocated size of info list. */ |
| 316 | u32 info_alloc_size; |
| 317 | |
| 318 | /** application context */ |
| 319 | void *app_ctx; |
| 320 | |
| 321 | struct napi_struct napi; |
| 322 | |
| 323 | u32 cpu_id; |
| 324 | |
| 325 | struct call_single_data csd; |
| 326 | }; |
| 327 | |
| 328 | #define OCT_DROQ_SIZE (sizeof(struct octeon_droq)) |
| 329 | |
| 330 | /** |
| 331 | * Allocates space for the descriptor ring for the droq and sets the |
| 332 | * base addr, num desc etc in Octeon registers. |
| 333 | * |
| 334 | * @param oct_dev - pointer to the octeon device structure |
| 335 | * @param q_no - droq no. ranges from 0 - 3. |
| 336 | * @param app_ctx - pointer to application context |
| 337 | * @return Success: 0 Failure: 1 |
| 338 | */ |
| 339 | int octeon_init_droq(struct octeon_device *oct_dev, |
| 340 | u32 q_no, |
| 341 | u32 num_descs, |
| 342 | u32 desc_size, |
| 343 | void *app_ctx); |
| 344 | |
| 345 | /** |
| 346 | * Frees the space for descriptor ring for the droq. |
| 347 | * |
| 348 | * @param oct_dev - pointer to the octeon device structure |
| 349 | * @param q_no - droq no. ranges from 0 - 3. |
| 350 | * @return: Success: 0 Failure: 1 |
| 351 | */ |
| 352 | int octeon_delete_droq(struct octeon_device *oct_dev, u32 q_no); |
| 353 | |
| 354 | /** Register a change in droq operations. The ops field has a pointer to a |
| 355 | * function which will called by the DROQ handler for all packets arriving |
| 356 | * on output queues given by q_no irrespective of the type of packet. |
| 357 | * The ops field also has a flag which if set tells the DROQ handler to |
| 358 | * drop packets if it receives more than what it can process in one |
| 359 | * invocation of the handler. |
| 360 | * @param oct - octeon device |
| 361 | * @param q_no - octeon output queue number (0 <= q_no <= MAX_OCTEON_DROQ-1 |
| 362 | * @param ops - the droq_ops settings for this queue |
| 363 | * @return - 0 on success, -ENODEV or -EINVAL on error. |
| 364 | */ |
| 365 | int |
| 366 | octeon_register_droq_ops(struct octeon_device *oct, |
| 367 | u32 q_no, |
| 368 | struct octeon_droq_ops *ops); |
| 369 | |
| 370 | /** Resets the function pointer and flag settings made by |
| 371 | * octeon_register_droq_ops(). After this routine is called, the DROQ handler |
| 372 | * will lookup dispatch function for each arriving packet on the output queue |
| 373 | * given by q_no. |
| 374 | * @param oct - octeon device |
| 375 | * @param q_no - octeon output queue number (0 <= q_no <= MAX_OCTEON_DROQ-1 |
| 376 | * @return - 0 on success, -ENODEV or -EINVAL on error. |
| 377 | */ |
| 378 | int octeon_unregister_droq_ops(struct octeon_device *oct, u32 q_no); |
| 379 | |
| 380 | /** Register a dispatch function for a opcode/subcode. The driver will call |
| 381 | * this dispatch function when it receives a packet with the given |
| 382 | * opcode/subcode in its output queues along with the user specified |
| 383 | * argument. |
| 384 | * @param oct - the octeon device to register with. |
| 385 | * @param opcode - the opcode for which the dispatch will be registered. |
| 386 | * @param subcode - the subcode for which the dispatch will be registered |
| 387 | * @param fn - the dispatch function. |
| 388 | * @param fn_arg - user specified that will be passed along with the |
| 389 | * dispatch function by the driver. |
| 390 | * @return Success: 0; Failure: 1 |
| 391 | */ |
| 392 | int octeon_register_dispatch_fn(struct octeon_device *oct, |
| 393 | u16 opcode, |
| 394 | u16 subcode, |
| 395 | octeon_dispatch_fn_t fn, void *fn_arg); |
| 396 | |
| 397 | /** Remove registration for an opcode/subcode. This will delete the mapping for |
| 398 | * an opcode/subcode. The dispatch function will be unregistered and will no |
| 399 | * longer be called if a packet with the opcode/subcode arrives in the driver |
| 400 | * output queues. |
| 401 | * @param oct - the octeon device to unregister from. |
| 402 | * @param opcode - the opcode to be unregistered. |
| 403 | * @param subcode - the subcode to be unregistered. |
| 404 | * |
| 405 | * @return Success: 0; Failure: 1 |
| 406 | */ |
| 407 | int octeon_unregister_dispatch_fn(struct octeon_device *oct, |
| 408 | u16 opcode, |
| 409 | u16 subcode); |
| 410 | |
| 411 | void octeon_droq_print_stats(void); |
| 412 | |
| 413 | u32 octeon_droq_check_hw_for_pkts(struct octeon_device *oct, |
| 414 | struct octeon_droq *droq); |
| 415 | |
| 416 | int octeon_create_droq(struct octeon_device *oct, u32 q_no, |
| 417 | u32 num_descs, u32 desc_size, void *app_ctx); |
| 418 | |
| 419 | int octeon_droq_process_packets(struct octeon_device *oct, |
| 420 | struct octeon_droq *droq, |
| 421 | u32 budget); |
| 422 | |
| 423 | int octeon_process_droq_poll_cmd(struct octeon_device *oct, u32 q_no, |
| 424 | int cmd, u32 arg); |
| 425 | |
| 426 | #endif /*__OCTEON_DROQ_H__ */ |