/********************************************************************** * Author: Cavium, Inc. * * Contact: [email protected] * 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. ***********************************************************************/ #include <linux/pci.h> #include <linux/netdevice.h> #include <linux/vmalloc.h> #include "liquidio_common.h" #include "octeon_droq.h" #include "octeon_iq.h" #include "response_manager.h" #include "octeon_device.h" #include "octeon_main.h" #include "octeon_network.h" #include "cn66xx_regs.h" #include "cn66xx_device.h" #include "cn23xx_pf_device.h" #include "cn23xx_vf_device.h" struct __dispatch { … }; /** Get the argument that the user set when registering dispatch * function for a given opcode/subcode. * @param octeon_dev - the octeon device pointer. * @param opcode - the opcode for which the dispatch argument * is to be checked. * @param subcode - the subcode for which the dispatch argument * is to be checked. * @return Success: void * (argument to the dispatch function) * @return Failure: NULL * */ void *octeon_get_dispatch_arg(struct octeon_device *octeon_dev, u16 opcode, u16 subcode) { … } /** Check for packets on Droq. This function should be called with lock held. * @param droq - Droq on which count is checked. * @return Returns packet count. */ u32 octeon_droq_check_hw_for_pkts(struct octeon_droq *droq) { … } EXPORT_SYMBOL_GPL(…); static void octeon_droq_compute_max_packet_bufs(struct octeon_droq *droq) { … } static void octeon_droq_reset_indices(struct octeon_droq *droq) { … } static void octeon_droq_destroy_ring_buffers(struct octeon_device *oct, struct octeon_droq *droq) { … } static int octeon_droq_setup_ring_buffers(struct octeon_device *oct, struct octeon_droq *droq) { … } int octeon_delete_droq(struct octeon_device *oct, u32 q_no) { … } EXPORT_SYMBOL_GPL(…); int octeon_init_droq(struct octeon_device *oct, u32 q_no, u32 num_descs, u32 desc_size, void *app_ctx) { … } /* octeon_create_recv_info * Parameters: * octeon_dev - pointer to the octeon device structure * droq - droq in which the packet arrived. * buf_cnt - no. of buffers used by the packet. * idx - index in the descriptor for the first buffer in the packet. * Description: * Allocates a recv_info_t and copies the buffer addresses for packet data * into the recv_pkt space which starts at an 8B offset from recv_info_t. * Flags the descriptors for refill later. If available descriptors go * below the threshold to receive a 64K pkt, new buffers are first allocated * before the recv_pkt_t is created. * This routine will be called in interrupt context. * Returns: * Success: Pointer to recv_info_t * Failure: NULL. */ static inline struct octeon_recv_info *octeon_create_recv_info( struct octeon_device *octeon_dev, struct octeon_droq *droq, u32 buf_cnt, u32 idx) { … } /* If we were not able to refill all buffers, try to move around * the buffers that were not dispatched. */ static inline u32 octeon_droq_refill_pullup_descs(struct octeon_droq *droq, struct octeon_droq_desc *desc_ring) { … } /* octeon_droq_refill * Parameters: * droq - droq in which descriptors require new buffers. * Description: * Called during normal DROQ processing in interrupt mode or by the poll * thread to refill the descriptors from which buffers were dispatched * to upper layers. Attempts to allocate new buffers. If that fails, moves * up buffers (that were not dispatched) to form a contiguous ring. * Returns: * No of descriptors refilled. */ static u32 octeon_droq_refill(struct octeon_device *octeon_dev, struct octeon_droq *droq) { … } /** check if we can allocate packets to get out of oom. * @param droq - Droq being checked. * @return 1 if fails to refill minimum */ int octeon_retry_droq_refill(struct octeon_droq *droq) { … } static inline u32 octeon_droq_get_bufcount(u32 buf_size, u32 total_len) { … } static int octeon_droq_dispatch_pkt(struct octeon_device *oct, struct octeon_droq *droq, union octeon_rh *rh, struct octeon_droq_info *info) { … } static inline void octeon_droq_drop_packets(struct octeon_device *oct, struct octeon_droq *droq, u32 cnt) { … } static u32 octeon_droq_fast_process_packets(struct octeon_device *oct, struct octeon_droq *droq, u32 pkts_to_process) { … } int octeon_droq_process_packets(struct octeon_device *oct, struct octeon_droq *droq, u32 budget) { … } EXPORT_SYMBOL_GPL(…); /* * Utility function to poll for packets. check_hw_for_packets must be * called before calling this routine. */ int octeon_droq_process_poll_pkts(struct octeon_device *oct, struct octeon_droq *droq, u32 budget) { … } /* Enable Pkt Interrupt */ int octeon_enable_irq(struct octeon_device *oct, u32 q_no) { … } int octeon_register_droq_ops(struct octeon_device *oct, u32 q_no, struct octeon_droq_ops *ops) { … } int octeon_unregister_droq_ops(struct octeon_device *oct, u32 q_no) { … } EXPORT_SYMBOL_GPL(…); int octeon_create_droq(struct octeon_device *oct, u32 q_no, u32 num_descs, u32 desc_size, void *app_ctx) { … }