diff options
Diffstat (limited to 'drivers/net/ethernet/cavium/liquidio/octeon_droq.c')
-rw-r--r-- | drivers/net/ethernet/cavium/liquidio/octeon_droq.c | 101 |
1 files changed, 55 insertions, 46 deletions
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_droq.c b/drivers/net/ethernet/cavium/liquidio/octeon_droq.c index f60e5320daf4..0be87d119a97 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_droq.c +++ b/drivers/net/ethernet/cavium/liquidio/octeon_droq.c @@ -1,24 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 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. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ + * 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. + ***********************************************************************/ #include <linux/pci.h> #include <linux/netdevice.h> #include <linux/vmalloc.h> @@ -32,9 +28,7 @@ #include "cn66xx_regs.h" #include "cn66xx_device.h" #include "cn23xx_pf_device.h" - -#define CVM_MIN(d1, d2) (((d1) < (d2)) ? (d1) : (d2)) -#define CVM_MAX(d1, d2) (((d1) > (d2)) ? (d1) : (d2)) +#include "cn23xx_vf_device.h" struct niclist { struct list_head list; @@ -258,13 +252,18 @@ int octeon_init_droq(struct octeon_device *oct, c_num_descs = num_descs; c_buf_size = desc_size; if (OCTEON_CN6XXX(oct)) { - struct octeon_config *conf6x = CHIP_FIELD(oct, cn6xxx, conf); + struct octeon_config *conf6x = CHIP_CONF(oct, cn6xxx); c_pkts_per_intr = (u32)CFG_GET_OQ_PKTS_PER_INTR(conf6x); c_refill_threshold = (u32)CFG_GET_OQ_REFILL_THRESHOLD(conf6x); } else if (OCTEON_CN23XX_PF(oct)) { - struct octeon_config *conf23 = CHIP_FIELD(oct, cn23xx_pf, conf); + struct octeon_config *conf23 = CHIP_CONF(oct, cn23xx_pf); + + c_pkts_per_intr = (u32)CFG_GET_OQ_PKTS_PER_INTR(conf23); + c_refill_threshold = (u32)CFG_GET_OQ_REFILL_THRESHOLD(conf23); + } else if (OCTEON_CN23XX_VF(oct)) { + struct octeon_config *conf23 = CHIP_CONF(oct, cn23xx_vf); c_pkts_per_intr = (u32)CFG_GET_OQ_PKTS_PER_INTR(conf23); c_refill_threshold = (u32)CFG_GET_OQ_REFILL_THRESHOLD(conf23); @@ -337,7 +336,7 @@ int octeon_init_droq(struct octeon_device *oct, /* For 56xx Pass1, this function won't be called, so no checks. */ oct->fn_list.setup_oq_regs(oct, q_no); - oct->io_qmask.oq |= (1ULL << q_no); + oct->io_qmask.oq |= BIT_ULL(q_no); return 0; @@ -409,7 +408,7 @@ static inline struct octeon_recv_info *octeon_create_recv_info( recv_pkt->buffer_ptr[i] = droq->recv_buf_list[idx].buffer; droq->recv_buf_list[idx].buffer = NULL; - INCR_INDEX_BY1(idx, droq->max_count); + idx = incr_index(idx, 1, droq->max_count); bytes_left -= droq->buffer_size; i++; buf_cnt--; @@ -440,14 +439,15 @@ octeon_droq_refill_pullup_descs(struct octeon_droq *droq, droq->recv_buf_list[refill_index].buffer = NULL; desc_ring[refill_index].buffer_ptr = 0; do { - INCR_INDEX_BY1(droq->refill_idx, - droq->max_count); + droq->refill_idx = incr_index(droq->refill_idx, + 1, + droq->max_count); desc_refilled++; droq->refill_count--; } while (droq->recv_buf_list[droq->refill_idx]. buffer); } - INCR_INDEX_BY1(refill_index, droq->max_count); + refill_index = incr_index(refill_index, 1, droq->max_count); } /* while */ return desc_refilled; } @@ -514,7 +514,8 @@ octeon_droq_refill(struct octeon_device *octeon_dev, struct octeon_droq *droq) /* Reset any previous values in the length field. */ droq->info_list[droq->refill_idx].length = 0; - INCR_INDEX_BY1(droq->refill_idx, droq->max_count); + droq->refill_idx = incr_index(droq->refill_idx, 1, + droq->max_count); desc_refilled++; droq->refill_count--; } @@ -599,7 +600,8 @@ static inline void octeon_droq_drop_packets(struct octeon_device *oct, buf_cnt = 1; } - INCR_INDEX(droq->read_idx, buf_cnt, droq->max_count); + droq->read_idx = incr_index(droq->read_idx, buf_cnt, + droq->max_count); droq->refill_count += buf_cnt; } } @@ -639,11 +641,12 @@ octeon_droq_fast_process_packets(struct octeon_device *oct, rh = &info->rh; total_len += (u32)info->length; - if (OPCODE_SLOW_PATH(rh)) { + if (opcode_slow_path(rh)) { u32 buf_cnt; buf_cnt = octeon_droq_dispatch_pkt(oct, droq, rh, info); - INCR_INDEX(droq->read_idx, buf_cnt, droq->max_count); + droq->read_idx = incr_index(droq->read_idx, + buf_cnt, droq->max_count); droq->refill_count += buf_cnt; } else { if (info->length <= droq->buffer_size) { @@ -657,7 +660,8 @@ octeon_droq_fast_process_packets(struct octeon_device *oct, droq->recv_buf_list[droq->read_idx].buffer = NULL; - INCR_INDEX_BY1(droq->read_idx, droq->max_count); + droq->read_idx = incr_index(droq->read_idx, 1, + droq->max_count); droq->refill_count++; } else { nicbuf = octeon_fast_packet_alloc((u32) @@ -689,8 +693,9 @@ octeon_droq_fast_process_packets(struct octeon_device *oct, } pkt_len += cpy_len; - INCR_INDEX_BY1(droq->read_idx, - droq->max_count); + droq->read_idx = + incr_index(droq->read_idx, 1, + droq->max_count); droq->refill_count++; } } @@ -804,9 +809,8 @@ octeon_droq_process_poll_pkts(struct octeon_device *oct, while (total_pkts_processed < budget) { octeon_droq_check_hw_for_pkts(droq); - pkts_available = - CVM_MIN((budget - total_pkts_processed), - (u32)(atomic_read(&droq->pkts_pending))); + pkts_available = min((budget - total_pkts_processed), + (u32)(atomic_read(&droq->pkts_pending))); if (pkts_available == 0) break; @@ -891,6 +895,10 @@ octeon_process_droq_poll_cmd(struct octeon_device *oct, u32 q_no, int cmd, lio_enable_irq(oct->droq[q_no], oct->instr_queue[q_no]); } break; + + case OCTEON_CN23XX_VF_VID: + lio_enable_irq(oct->droq[q_no], oct->instr_queue[q_no]); + break; } return 0; } @@ -988,7 +996,8 @@ int octeon_create_droq(struct octeon_device *oct, if (!droq) droq = vmalloc(sizeof(*droq)); if (!droq) - goto create_droq_fail; + return -1; + memset(droq, 0, sizeof(struct octeon_droq)); /*Disable the pkt o/p for this Q */ @@ -996,7 +1005,11 @@ int octeon_create_droq(struct octeon_device *oct, oct->droq[q_no] = droq; /* Initialize the Droq */ - octeon_init_droq(oct, q_no, num_descs, desc_size, app_ctx); + if (octeon_init_droq(oct, q_no, num_descs, desc_size, app_ctx)) { + vfree(oct->droq[q_no]); + oct->droq[q_no] = NULL; + return -1; + } oct->num_oqs++; @@ -1009,8 +1022,4 @@ int octeon_create_droq(struct octeon_device *oct, * the same time. */ return 0; - -create_droq_fail: - octeon_delete_droq(oct, q_no); - return -ENOMEM; } |