Skip to content

Commit

Permalink
octeontx2-af: NIX block admin queue init
Browse files Browse the repository at this point in the history
Initialize NIX admin queue (AQ) i.e alloc memory for
AQ instructions and for the results. All NIX LFs will submit
instructions to AQ to init/write/read RQ/SQ/CQ/RSS contexts
and in case of read, get context from result memory.

Also before configuring/using NIX block calibrate X2P bus
and check if NIX interfaces like CGX and LBK are in active
and working state.

Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Sunil Goutham authored and David S. Miller committed Oct 18, 2018
1 parent 57856dd commit aba53d5
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 1 deletion.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/marvell/octeontx2/af/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ obj-$(CONFIG_OCTEONTX2_MBOX) += octeontx2_mbox.o
obj-$(CONFIG_OCTEONTX2_AF) += octeontx2_af.o

octeontx2_mbox-y := mbox.o
octeontx2_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o
octeontx2_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o
5 changes: 5 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu.c
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,7 @@ static void rvu_free_hw_resources(struct rvu *rvu)
u64 cfg;

rvu_npa_freemem(rvu);
rvu_nix_freemem(rvu);

/* Free block LF bitmaps */
for (id = 0; id < BLK_COUNT; id++) {
Expand Down Expand Up @@ -774,6 +775,10 @@ static int rvu_setup_hw_resources(struct rvu *rvu)
if (err)
return err;

err = rvu_nix_init(rvu);
if (err)
return err;

return 0;
}

Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,8 @@ int rvu_mbox_handler_NPA_LF_ALLOC(struct rvu *rvu,
struct npa_lf_alloc_rsp *rsp);
int rvu_mbox_handler_NPA_LF_FREE(struct rvu *rvu, struct msg_req *req,
struct msg_rsp *rsp);

/* NIX APIs */
int rvu_nix_init(struct rvu *rvu);
void rvu_nix_freemem(struct rvu *rvu);
#endif /* RVU_H */
138 changes: 138 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// SPDX-License-Identifier: GPL-2.0
/* Marvell OcteonTx2 RVU Admin Function driver
*
* Copyright (C) 2018 Marvell International Ltd.
*
* This program 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.
*/

#include <linux/module.h>
#include <linux/pci.h>

#include "rvu_struct.h"
#include "rvu_reg.h"
#include "rvu.h"
#include "cgx.h"

static int nix_calibrate_x2p(struct rvu *rvu, int blkaddr)
{
int idx, err;
u64 status;

/* Start X2P bus calibration */
rvu_write64(rvu, blkaddr, NIX_AF_CFG,
rvu_read64(rvu, blkaddr, NIX_AF_CFG) | BIT_ULL(9));
/* Wait for calibration to complete */
err = rvu_poll_reg(rvu, blkaddr,
NIX_AF_STATUS, BIT_ULL(10), false);
if (err) {
dev_err(rvu->dev, "NIX X2P bus calibration failed\n");
return err;
}

status = rvu_read64(rvu, blkaddr, NIX_AF_STATUS);
/* Check if CGX devices are ready */
for (idx = 0; idx < cgx_get_cgx_cnt(); idx++) {
if (status & (BIT_ULL(16 + idx)))
continue;
dev_err(rvu->dev,
"CGX%d didn't respond to NIX X2P calibration\n", idx);
err = -EBUSY;
}

/* Check if LBK is ready */
if (!(status & BIT_ULL(19))) {
dev_err(rvu->dev,
"LBK didn't respond to NIX X2P calibration\n");
err = -EBUSY;
}

/* Clear 'calibrate_x2p' bit */
rvu_write64(rvu, blkaddr, NIX_AF_CFG,
rvu_read64(rvu, blkaddr, NIX_AF_CFG) & ~BIT_ULL(9));
if (err || (status & 0x3FFULL))
dev_err(rvu->dev,
"NIX X2P calibration failed, status 0x%llx\n", status);
if (err)
return err;
return 0;
}

static int nix_aq_init(struct rvu *rvu, struct rvu_block *block)
{
u64 cfg;
int err;

/* Set admin queue endianness */
cfg = rvu_read64(rvu, block->addr, NIX_AF_CFG);
#ifdef __BIG_ENDIAN
cfg |= BIT_ULL(1);
rvu_write64(rvu, block->addr, NIX_AF_CFG, cfg);
#else
cfg &= ~BIT_ULL(1);
rvu_write64(rvu, block->addr, NIX_AF_CFG, cfg);
#endif

/* Do not bypass NDC cache */
cfg = rvu_read64(rvu, block->addr, NIX_AF_NDC_CFG);
cfg &= ~0x3FFEULL;
rvu_write64(rvu, block->addr, NIX_AF_NDC_CFG, cfg);

/* Result structure can be followed by RQ/SQ/CQ context at
* RES + 128bytes and a write mask at RES + 256 bytes, depending on
* operation type. Alloc sufficient result memory for all operations.
*/
err = rvu_aq_alloc(rvu, &block->aq,
Q_COUNT(AQ_SIZE), sizeof(struct nix_aq_inst_s),
ALIGN(sizeof(struct nix_aq_res_s), 128) + 256);
if (err)
return err;

rvu_write64(rvu, block->addr, NIX_AF_AQ_CFG, AQ_SIZE);
rvu_write64(rvu, block->addr,
NIX_AF_AQ_BASE, (u64)block->aq->inst->iova);
return 0;
}

int rvu_nix_init(struct rvu *rvu)
{
struct rvu_hwinfo *hw = rvu->hw;
struct rvu_block *block;
int blkaddr, err;

blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
if (blkaddr < 0)
return 0;
block = &hw->block[blkaddr];

/* Calibrate X2P bus to check if CGX/LBK links are fine */
err = nix_calibrate_x2p(rvu, blkaddr);
if (err)
return err;

/* Initialize admin queue */
err = nix_aq_init(rvu, block);
if (err)
return err;

/* Restore CINT timer delay to HW reset values */
rvu_write64(rvu, blkaddr, NIX_AF_CINT_DELAY, 0x0ULL);

return 0;
}

void rvu_nix_freemem(struct rvu *rvu)
{
struct rvu_hwinfo *hw = rvu->hw;
struct rvu_block *block;
int blkaddr;

blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
if (blkaddr < 0)
return;

block = &hw->block[blkaddr];
rvu_aq_free(rvu, block->aq);
}
72 changes: 72 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,4 +354,76 @@ struct npa_pool_s {
u64 reserved_896_959; /* W14 */
u64 reserved_960_1023; /* W15 */
};

/* NIX admin queue completion status */
enum nix_aq_comp {
NIX_AQ_COMP_NOTDONE = 0x0,
NIX_AQ_COMP_GOOD = 0x1,
NIX_AQ_COMP_SWERR = 0x2,
NIX_AQ_COMP_CTX_POISON = 0x3,
NIX_AQ_COMP_CTX_FAULT = 0x4,
NIX_AQ_COMP_LOCKERR = 0x5,
NIX_AQ_COMP_SQB_ALLOC_FAIL = 0x6,
};

/* NIX admin queue context types */
enum nix_aq_ctype {
NIX_AQ_CTYPE_RQ = 0x0,
NIX_AQ_CTYPE_SQ = 0x1,
NIX_AQ_CTYPE_CQ = 0x2,
NIX_AQ_CTYPE_MCE = 0x3,
NIX_AQ_CTYPE_RSS = 0x4,
NIX_AQ_CTYPE_DYNO = 0x5,
};

/* NIX admin queue instruction opcodes */
enum nix_aq_instop {
NIX_AQ_INSTOP_NOP = 0x0,
NIX_AQ_INSTOP_INIT = 0x1,
NIX_AQ_INSTOP_WRITE = 0x2,
NIX_AQ_INSTOP_READ = 0x3,
NIX_AQ_INSTOP_LOCK = 0x4,
NIX_AQ_INSTOP_UNLOCK = 0x5,
};

/* NIX admin queue instruction structure */
struct nix_aq_inst_s {
#if defined(__BIG_ENDIAN_BITFIELD)
u64 doneint : 1; /* W0 */
u64 reserved_44_62 : 19;
u64 cindex : 20;
u64 reserved_15_23 : 9;
u64 lf : 7;
u64 ctype : 4;
u64 op : 4;
#else
u64 op : 4;
u64 ctype : 4;
u64 lf : 7;
u64 reserved_15_23 : 9;
u64 cindex : 20;
u64 reserved_44_62 : 19;
u64 doneint : 1;
#endif
u64 res_addr; /* W1 */
};

/* NIX admin queue result structure */
struct nix_aq_res_s {
#if defined(__BIG_ENDIAN_BITFIELD)
u64 reserved_17_63 : 47; /* W0 */
u64 doneint : 1;
u64 compcode : 8;
u64 ctype : 4;
u64 op : 4;
#else
u64 op : 4;
u64 ctype : 4;
u64 compcode : 8;
u64 doneint : 1;
u64 reserved_17_63 : 47;
#endif
u64 reserved_64_127; /* W1 */
};

#endif /* RVU_STRUCT_H */

0 comments on commit aba53d5

Please sign in to comment.