Skip to content

Commit

Permalink
Merge branch 'octeontx2-Flow-control-support-and-other-misc-changes'
Browse files Browse the repository at this point in the history
Sunil Goutham says:

====================
octeontx2: Flow control support and other misc changes

This patch series adds flow control support (802.3 pause frames) and
has other changes wrt generic admin function (AF) driver functionality.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 2, 2020
2 parents 48938b1 + dc819c1 commit aeaf0cc
Show file tree
Hide file tree
Showing 15 changed files with 671 additions and 85 deletions.
174 changes: 121 additions & 53 deletions drivers/net/ethernet/marvell/octeontx2/af/cgx.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,107 @@ int cgx_lmac_tx_enable(void *cgxd, int lmac_id, bool enable)
return !!(last & DATA_PKT_TX_EN);
}

int cgx_lmac_get_pause_frm(void *cgxd, int lmac_id,
u8 *tx_pause, u8 *rx_pause)
{
struct cgx *cgx = cgxd;
u64 cfg;

if (!cgx || lmac_id >= cgx->lmac_count)
return -ENODEV;

cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
*rx_pause = !!(cfg & CGX_SMUX_RX_FRM_CTL_CTL_BCK);

cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_TX_CTL);
*tx_pause = !!(cfg & CGX_SMUX_TX_CTL_L2P_BP_CONV);
return 0;
}

int cgx_lmac_set_pause_frm(void *cgxd, int lmac_id,
u8 tx_pause, u8 rx_pause)
{
struct cgx *cgx = cgxd;
u64 cfg;

if (!cgx || lmac_id >= cgx->lmac_count)
return -ENODEV;

cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
cfg &= ~CGX_SMUX_RX_FRM_CTL_CTL_BCK;
cfg |= rx_pause ? CGX_SMUX_RX_FRM_CTL_CTL_BCK : 0x0;
cgx_write(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL, cfg);

cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_TX_CTL);
cfg &= ~CGX_SMUX_TX_CTL_L2P_BP_CONV;
cfg |= tx_pause ? CGX_SMUX_TX_CTL_L2P_BP_CONV : 0x0;
cgx_write(cgx, lmac_id, CGXX_SMUX_TX_CTL, cfg);

cfg = cgx_read(cgx, 0, CGXX_CMR_RX_OVR_BP);
if (tx_pause) {
cfg &= ~CGX_CMR_RX_OVR_BP_EN(lmac_id);
} else {
cfg |= CGX_CMR_RX_OVR_BP_EN(lmac_id);
cfg &= ~CGX_CMR_RX_OVR_BP_BP(lmac_id);
}
cgx_write(cgx, 0, CGXX_CMR_RX_OVR_BP, cfg);
return 0;
}

static void cgx_lmac_pause_frm_config(struct cgx *cgx, int lmac_id, bool enable)
{
u64 cfg;

if (!cgx || lmac_id >= cgx->lmac_count)
return;
if (enable) {
/* Enable receive pause frames */
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
cfg |= CGX_SMUX_RX_FRM_CTL_CTL_BCK;
cgx_write(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL, cfg);

cfg = cgx_read(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL);
cfg |= CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK;
cgx_write(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL, cfg);

/* Enable pause frames transmission */
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_TX_CTL);
cfg |= CGX_SMUX_TX_CTL_L2P_BP_CONV;
cgx_write(cgx, lmac_id, CGXX_SMUX_TX_CTL, cfg);

/* Set pause time and interval */
cgx_write(cgx, lmac_id, CGXX_SMUX_TX_PAUSE_PKT_TIME,
DEFAULT_PAUSE_TIME);
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_TX_PAUSE_PKT_INTERVAL);
cfg &= ~0xFFFFULL;
cgx_write(cgx, lmac_id, CGXX_SMUX_TX_PAUSE_PKT_INTERVAL,
cfg | (DEFAULT_PAUSE_TIME / 2));

cgx_write(cgx, lmac_id, CGXX_GMP_GMI_TX_PAUSE_PKT_TIME,
DEFAULT_PAUSE_TIME);

cfg = cgx_read(cgx, lmac_id,
CGXX_GMP_GMI_TX_PAUSE_PKT_INTERVAL);
cfg &= ~0xFFFFULL;
cgx_write(cgx, lmac_id, CGXX_GMP_GMI_TX_PAUSE_PKT_INTERVAL,
cfg | (DEFAULT_PAUSE_TIME / 2));
} else {
/* ALL pause frames received are completely ignored */
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
cfg &= ~CGX_SMUX_RX_FRM_CTL_CTL_BCK;
cgx_write(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL, cfg);

cfg = cgx_read(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL);
cfg &= ~CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK;
cgx_write(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL, cfg);

/* Disable pause frames transmission */
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_TX_CTL);
cfg &= ~CGX_SMUX_TX_CTL_L2P_BP_CONV;
cgx_write(cgx, lmac_id, CGXX_SMUX_TX_CTL, cfg);
}
}

/* CGX Firmware interface low level support */
static int cgx_fwi_cmd_send(u64 req, u64 *resp, struct lmac *lmac)
{
Expand Down Expand Up @@ -544,59 +645,6 @@ static inline bool cgx_event_is_linkevent(u64 event)
return false;
}

static inline int cgx_fwi_get_mkex_prfl_sz(u64 *prfl_sz,
struct cgx *cgx)
{
u64 req = 0;
u64 resp;
int err;

req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_MKEX_PRFL_SIZE, req);
err = cgx_fwi_cmd_generic(req, &resp, cgx, 0);
if (!err)
*prfl_sz = FIELD_GET(RESP_MKEX_PRFL_SIZE, resp);

return err;
}

static inline int cgx_fwi_get_mkex_prfl_addr(u64 *prfl_addr,
struct cgx *cgx)
{
u64 req = 0;
u64 resp;
int err;

req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_MKEX_PRFL_ADDR, req);
err = cgx_fwi_cmd_generic(req, &resp, cgx, 0);
if (!err)
*prfl_addr = FIELD_GET(RESP_MKEX_PRFL_ADDR, resp);

return err;
}

int cgx_get_mkex_prfl_info(u64 *addr, u64 *size)
{
struct cgx *cgx_dev;
int err;

if (!addr || !size)
return -EINVAL;

cgx_dev = list_first_entry(&cgx_list, struct cgx, cgx_list);
if (!cgx_dev)
return -ENXIO;

err = cgx_fwi_get_mkex_prfl_sz(size, cgx_dev);
if (err)
return -EIO;

err = cgx_fwi_get_mkex_prfl_addr(addr, cgx_dev);
if (err)
return -EIO;

return 0;
}

static irqreturn_t cgx_fwi_event_handler(int irq, void *data)
{
struct lmac *lmac = data;
Expand Down Expand Up @@ -680,6 +728,24 @@ int cgx_lmac_evh_unregister(void *cgxd, int lmac_id)
return 0;
}

int cgx_get_fwdata_base(u64 *base)
{
u64 req = 0, resp;
struct cgx *cgx;
int err;

cgx = list_first_entry_or_null(&cgx_list, struct cgx, cgx_list);
if (!cgx)
return -ENXIO;

req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_FWD_BASE, req);
err = cgx_fwi_cmd_generic(req, &resp, cgx, 0);
if (!err)
*base = FIELD_GET(RESP_FWD_BASE, resp);

return err;
}

static int cgx_fwi_link_change(struct cgx *cgx, int lmac_id, bool enable)
{
u64 req = 0;
Expand Down Expand Up @@ -787,6 +853,7 @@ static int cgx_lmac_init(struct cgx *cgx)

/* Add reference */
cgx->lmac_idmap[i] = lmac;
cgx_lmac_pause_frm_config(cgx, i, true);
}

return cgx_lmac_verify_fwi_version(cgx);
Expand All @@ -805,6 +872,7 @@ static int cgx_lmac_exit(struct cgx *cgx)

/* Free all lmac related resources */
for (i = 0; i < cgx->lmac_count; i++) {
cgx_lmac_pause_frm_config(cgx, i, false);
lmac = cgx->lmac_idmap[i];
if (!lmac)
continue;
Expand Down
16 changes: 15 additions & 1 deletion drivers/net/ethernet/marvell/octeontx2/af/cgx.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,20 @@
#define CGX_SMUX_RX_FRM_CTL_CTL_BCK BIT_ULL(3)
#define CGXX_GMP_GMI_RXX_FRM_CTL 0x38028
#define CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK BIT_ULL(3)
#define CGXX_SMUX_TX_CTL 0x20178
#define CGXX_SMUX_TX_PAUSE_PKT_TIME 0x20110
#define CGXX_SMUX_TX_PAUSE_PKT_INTERVAL 0x20120
#define CGXX_GMP_GMI_TX_PAUSE_PKT_TIME 0x38230
#define CGXX_GMP_GMI_TX_PAUSE_PKT_INTERVAL 0x38248
#define CGX_SMUX_TX_CTL_L2P_BP_CONV BIT_ULL(7)
#define CGXX_CMR_RX_OVR_BP 0x130
#define CGX_CMR_RX_OVR_BP_EN(X) BIT_ULL(((X) + 8))
#define CGX_CMR_RX_OVR_BP_BP(X) BIT_ULL(((X) + 4))

#define CGX_COMMAND_REG CGXX_SCRATCH1_REG
#define CGX_EVENT_REG CGXX_SCRATCH0_REG
#define CGX_CMD_TIMEOUT 2200 /* msecs */
#define DEFAULT_PAUSE_TIME 0x7FF

#define CGX_NVEC 37
#define CGX_LMAC_FWI 0
Expand Down Expand Up @@ -124,5 +134,9 @@ int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable);
int cgx_get_link_info(void *cgxd, int lmac_id,
struct cgx_link_user_info *linfo);
int cgx_lmac_linkup_start(void *cgxd);
int cgx_get_mkex_prfl_info(u64 *addr, u64 *size);
int cgx_get_fwdata_base(u64 *base);
int cgx_lmac_get_pause_frm(void *cgxd, int lmac_id,
u8 *tx_pause, u8 *rx_pause);
int cgx_lmac_set_pause_frm(void *cgxd, int lmac_id,
u8 tx_pause, u8 rx_pause);
#endif /* CGX_H */
8 changes: 7 additions & 1 deletion drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ enum cgx_cmd_id {
CGX_CMD_MODE_CHANGE, /* hot plug support */
CGX_CMD_INTF_SHUTDOWN,
CGX_CMD_GET_MKEX_PRFL_SIZE,
CGX_CMD_GET_MKEX_PRFL_ADDR
CGX_CMD_GET_MKEX_PRFL_ADDR,
CGX_CMD_GET_FWD_BASE, /* get base address of shared FW data */
};

/* async event ids */
Expand Down Expand Up @@ -149,6 +150,11 @@ enum cgx_cmd_own {
*/
#define RESP_MKEX_PRFL_ADDR GENMASK_ULL(63, 9)

/* Response to cmd ID as CGX_CMD_GET_FWD_BASE with cmd status as
* CGX_STAT_SUCCESS
*/
#define RESP_FWD_BASE GENMASK_ULL(56, 9)

/* Response to cmd ID - CGX_CMD_LINK_BRING_UP/DOWN, event ID CGX_EVT_LINK_CHANGE
* status can be either CGX_STAT_FAIL or CGX_STAT_SUCCESS
*
Expand Down
38 changes: 36 additions & 2 deletions drivers/net/ethernet/marvell/octeontx2/af/mbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ static inline struct mbox_msghdr *otx2_mbox_alloc_msg(struct otx2_mbox *mbox,
M(READY, 0x001, ready, msg_req, ready_msg_rsp) \
M(ATTACH_RESOURCES, 0x002, attach_resources, rsrc_attach, msg_rsp) \
M(DETACH_RESOURCES, 0x003, detach_resources, rsrc_detach, msg_rsp) \
M(MSIX_OFFSET, 0x004, msix_offset, msg_req, msix_offset_rsp) \
M(MSIX_OFFSET, 0x005, msix_offset, msg_req, msix_offset_rsp) \
M(VF_FLR, 0x006, vf_flr, msg_req, msg_rsp) \
M(GET_HW_CAP, 0x008, get_hw_cap, msg_req, get_hw_cap_rsp) \
/* CGX mbox IDs (range 0x200 - 0x3FF) */ \
Expand All @@ -143,6 +143,8 @@ M(CGX_STOP_LINKEVENTS, 0x208, cgx_stop_linkevents, msg_req, msg_rsp) \
M(CGX_GET_LINKINFO, 0x209, cgx_get_linkinfo, msg_req, cgx_link_info_msg) \
M(CGX_INTLBK_ENABLE, 0x20A, cgx_intlbk_enable, msg_req, msg_rsp) \
M(CGX_INTLBK_DISABLE, 0x20B, cgx_intlbk_disable, msg_req, msg_rsp) \
M(CGX_CFG_PAUSE_FRM, 0x20E, cgx_cfg_pause_frm, cgx_pause_frm_cfg, \
cgx_pause_frm_cfg) \
/* NPA mbox IDs (range 0x400 - 0x5FF) */ \
M(NPA_LF_ALLOC, 0x400, npa_lf_alloc, \
npa_lf_alloc_req, npa_lf_alloc_rsp) \
Expand Down Expand Up @@ -211,6 +213,9 @@ M(NIX_LSO_FORMAT_CFG, 0x8011, nix_lso_format_cfg, \
nix_lso_format_cfg, \
nix_lso_format_cfg_rsp) \
M(NIX_RXVLAN_ALLOC, 0x8012, nix_rxvlan_alloc, msg_req, msg_rsp) \
M(NIX_BP_ENABLE, 0x8016, nix_bp_enable, nix_bp_cfg_req, \
nix_bp_cfg_rsp) \
M(NIX_BP_DISABLE, 0x8017, nix_bp_disable, nix_bp_cfg_req, msg_rsp) \
M(NIX_GET_MAC_ADDR, 0x8018, nix_get_mac_addr, msg_req, nix_get_mac_addr_rsp) \

/* Messages initiated by AF (range 0xC00 - 0xDFF) */
Expand Down Expand Up @@ -251,7 +256,8 @@ enum rvu_af_status {

struct ready_msg_rsp {
struct mbox_msghdr hdr;
u16 sclk_feq; /* SCLK frequency */
u16 sclk_freq; /* SCLK frequency (in MHz) */
u16 rclk_freq; /* RCLK frequency (in MHz) */
};

/* Structure for requesting resource provisioning.
Expand Down Expand Up @@ -342,6 +348,15 @@ struct cgx_link_info_msg {
struct cgx_link_user_info link_info;
};

struct cgx_pause_frm_cfg {
struct mbox_msghdr hdr;
u8 set;
/* set = 1 if the request is to config pause frames */
/* set = 0 if the request is to fetch pause frames config */
u8 rx_pause;
u8 tx_pause;
};

/* NPA mbox message formats */

/* NPA mailbox error codes
Expand Down Expand Up @@ -676,6 +691,25 @@ struct nix_lso_format_cfg_rsp {
u8 lso_format_idx;
};

struct nix_bp_cfg_req {
struct mbox_msghdr hdr;
u16 chan_base; /* Starting channel number */
u8 chan_cnt; /* Number of channels */
u8 bpid_per_chan;
/* bpid_per_chan = 0 assigns single bp id for range of channels */
/* bpid_per_chan = 1 assigns separate bp id for each channel */
};

/* PF can be mapped to either CGX or LBK interface,
* so maximum 64 channels are possible.
*/
#define NIX_MAX_BPID_CHAN 64
struct nix_bp_cfg_rsp {
struct mbox_msghdr hdr;
u16 chan_bpid[NIX_MAX_BPID_CHAN]; /* Channel and bpid mapping */
u8 chan_cnt; /* Number of channel for which bpids are assigned */
};

/* NPC mbox message structs */

#define NPC_MCAM_ENTRY_INVALID 0xFFFF
Expand Down
Loading

0 comments on commit aeaf0cc

Please sign in to comment.