summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/cavium/liquidio/octeon_droq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/cavium/liquidio/octeon_droq.c')
-rw-r--r--drivers/net/ethernet/cavium/liquidio/octeon_droq.c101
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;
}