Commit 543fb674 authored by Ronak Doshi's avatar Ronak Doshi Committed by Paolo Abeni

vmxnet3: add support for large passthrough BAR register

For vmxnet3 to work in UPT mode, the BAR sizes have been increased.
The PT page has been extended to 2 pages and also includes OOB pages
as a part of PT BAR. This patch enhances vmxnet3 to use appropriate
BAR offsets based on the capability registered. To use new offsets,
VMXNET3_CAP_LARGE_BAR needs to be set by the device. If it is not set
then the device will use legacy PT page layout.
Signed-off-by: default avatarRonak Doshi <doshir@vmware.com>
Acked-by: default avatarGuolin Yang <gyang@vmware.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 6f91f4ba
......@@ -57,8 +57,18 @@ enum {
VMXNET3_REG_RXPROD2 = 0xA00 /* Rx Producer Index for ring 2 */
};
#define VMXNET3_PT_REG_SIZE 4096 /* BAR 0 */
#define VMXNET3_VD_REG_SIZE 4096 /* BAR 1 */
/* For Large PT BAR, the following offset to DB register */
enum {
VMXNET3_REG_LB_TXPROD = 0x1000, /* Tx Producer Index */
VMXNET3_REG_LB_RXPROD = 0x1400, /* Rx Producer Index for ring 1 */
VMXNET3_REG_LB_RXPROD2 = 0x1800, /* Rx Producer Index for ring 2 */
};
#define VMXNET3_PT_REG_SIZE 4096 /* BAR 0 */
#define VMXNET3_LARGE_PT_REG_SIZE 8192 /* large PT pages */
#define VMXNET3_VD_REG_SIZE 4096 /* BAR 1 */
#define VMXNET3_LARGE_BAR0_REG_SIZE (4096 * 4096) /* LARGE BAR 0 */
#define VMXNET3_OOB_REG_SIZE (4094 * 4096) /* OOB pages */
#define VMXNET3_REG_ALIGN 8 /* All registers are 8-byte aligned. */
#define VMXNET3_REG_ALIGN_MASK 0x7
......
......@@ -1207,7 +1207,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
if (tx_num_deferred >= le32_to_cpu(tq->shared->txThreshold)) {
tq->shared->txNumDeferred = 0;
VMXNET3_WRITE_BAR0_REG(adapter,
VMXNET3_REG_TXPROD + tq->qid * 8,
adapter->tx_prod_offset + tq->qid * 8,
tq->tx_ring.next2fill);
}
......@@ -1359,8 +1359,8 @@ static int
vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
struct vmxnet3_adapter *adapter, int quota)
{
static const u32 rxprod_reg[2] = {
VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2
u32 rxprod_reg[2] = {
adapter->rx_prod_offset, adapter->rx_prod2_offset
};
u32 num_pkts = 0;
bool skip_page_frags = false;
......@@ -2783,9 +2783,9 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter)
for (i = 0; i < adapter->num_rx_queues; i++) {
VMXNET3_WRITE_BAR0_REG(adapter,
VMXNET3_REG_RXPROD + i * VMXNET3_REG_ALIGN,
adapter->rx_prod_offset + i * VMXNET3_REG_ALIGN,
adapter->rx_queue[i].rx_ring[0].next2fill);
VMXNET3_WRITE_BAR0_REG(adapter, (VMXNET3_REG_RXPROD2 +
VMXNET3_WRITE_BAR0_REG(adapter, (adapter->rx_prod2_offset +
(i * VMXNET3_REG_ALIGN)),
adapter->rx_queue[i].rx_ring[1].next2fill);
}
......@@ -3608,6 +3608,10 @@ vmxnet3_probe_device(struct pci_dev *pdev,
if (VMXNET3_VERSION_GE_7(adapter)) {
adapter->devcap_supported[0] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_DCR);
adapter->ptcap_supported[0] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_PTCR);
if (adapter->devcap_supported[0] & (1UL << VMXNET3_CAP_LARGE_BAR)) {
adapter->dev_caps[0] = adapter->devcap_supported[0] &
(1UL << VMXNET3_CAP_LARGE_BAR);
}
if (adapter->dev_caps[0])
VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DCR, adapter->dev_caps[0]);
......@@ -3617,6 +3621,17 @@ vmxnet3_probe_device(struct pci_dev *pdev,
spin_unlock_irqrestore(&adapter->cmd_lock, flags);
}
if (VMXNET3_VERSION_GE_7(adapter) &&
adapter->dev_caps[0] & (1UL << VMXNET3_CAP_LARGE_BAR)) {
adapter->tx_prod_offset = VMXNET3_REG_LB_TXPROD;
adapter->rx_prod_offset = VMXNET3_REG_LB_RXPROD;
adapter->rx_prod2_offset = VMXNET3_REG_LB_RXPROD2;
} else {
adapter->tx_prod_offset = VMXNET3_REG_TXPROD;
adapter->rx_prod_offset = VMXNET3_REG_RXPROD;
adapter->rx_prod2_offset = VMXNET3_REG_RXPROD2;
}
if (VMXNET3_VERSION_GE_6(adapter)) {
spin_lock_irqsave(&adapter->cmd_lock, flags);
VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
......
......@@ -520,7 +520,7 @@ vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
for (i = 0; i < adapter->num_tx_queues; i++) {
struct vmxnet3_tx_queue *tq = &adapter->tx_queue[i];
buf[j++] = VMXNET3_READ_BAR0_REG(adapter, VMXNET3_REG_TXPROD +
buf[j++] = VMXNET3_READ_BAR0_REG(adapter, adapter->tx_prod_offset +
i * VMXNET3_REG_ALIGN);
buf[j++] = VMXNET3_GET_ADDR_LO(tq->tx_ring.basePA);
......@@ -548,9 +548,9 @@ vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
for (i = 0; i < adapter->num_rx_queues; i++) {
struct vmxnet3_rx_queue *rq = &adapter->rx_queue[i];
buf[j++] = VMXNET3_READ_BAR0_REG(adapter, VMXNET3_REG_RXPROD +
buf[j++] = VMXNET3_READ_BAR0_REG(adapter, adapter->rx_prod_offset +
i * VMXNET3_REG_ALIGN);
buf[j++] = VMXNET3_READ_BAR0_REG(adapter, VMXNET3_REG_RXPROD2 +
buf[j++] = VMXNET3_READ_BAR0_REG(adapter, adapter->rx_prod2_offset +
i * VMXNET3_REG_ALIGN);
buf[j++] = VMXNET3_GET_ADDR_LO(rq->rx_ring[0].basePA);
......
......@@ -406,6 +406,9 @@ struct vmxnet3_adapter {
u32 devcap_supported[8];
u32 ptcap_supported[8];
u32 dev_caps[8];
u16 tx_prod_offset;
u16 rx_prod_offset;
u16 rx_prod2_offset;
};
#define VMXNET3_WRITE_BAR0_REG(adapter, reg, val) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment