Commit 0cece6c5 authored by Raghu Vatsavayi's avatar Raghu Vatsavayi Committed by David S. Miller

liquidio: Replace ifidx for FW commands

This patch decoupled the firmware side ifidx and host side interface
number. It also has some minor name change for linkinfo sturct field.
Signed-off-by: default avatarDerek Chickles <derek.chickles@caviumnetworks.com>
Signed-off-by: default avatarSatanand Burla <satananda.burla@caviumnetworks.com>
Signed-off-by: default avatarFelix Manlunas <felix.manlunas@caviumnetworks.com>
Signed-off-by: default avatarRaghu Vatsavayi <raghu.vatsavayi@caviumnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7275ebfc
......@@ -127,7 +127,7 @@ static int lio_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
dev_err(&oct->pci_dev->dev, "Unknown link interface reported\n");
}
if (linfo->link.s.status) {
if (linfo->link.s.link_up) {
ethtool_cmd_speed_set(ecmd, linfo->link.s.speed);
ecmd->duplex = linfo->link.s.duplex;
} else {
......@@ -222,23 +222,20 @@ static int octnet_gpio_access(struct net_device *netdev, int addr, int val)
struct lio *lio = GET_LIO(netdev);
struct octeon_device *oct = lio->oct_dev;
struct octnic_ctrl_pkt nctrl;
struct octnic_ctrl_params nparams;
int ret = 0;
memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
nctrl.ncmd.u64 = 0;
nctrl.ncmd.s.cmd = OCTNET_CMD_GPIO_ACCESS;
nctrl.ncmd.s.param1 = lio->linfo.ifidx;
nctrl.ncmd.s.param2 = addr;
nctrl.ncmd.s.param3 = val;
nctrl.ncmd.s.param1 = addr;
nctrl.ncmd.s.param2 = val;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
nparams.resp_order = OCTEON_RESP_ORDERED;
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams);
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
if (ret < 0) {
dev_err(&oct->pci_dev->dev, "Failed to configure gpio value\n");
return -EINVAL;
......@@ -303,9 +300,10 @@ octnet_mdio45_access(struct lio *lio, int op, int loc, int *value)
mdio_cmd->mdio_addr = loc;
if (op)
mdio_cmd->value1 = *value;
mdio_cmd->value2 = lio->linfo.ifidx;
octeon_swap_8B_data((u64 *)mdio_cmd, sizeof(struct oct_mdio_cmd) / 8);
sc->iq_no = lio->linfo.txpciq[0].s.q_no;
octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC, OPCODE_NIC_MDIO45,
0, 0, 0);
......@@ -503,10 +501,10 @@ static void lio_set_msglevel(struct net_device *netdev, u32 msglvl)
if ((msglvl ^ lio->msg_enable) & NETIF_MSG_HW) {
if (msglvl & NETIF_MSG_HW)
liquidio_set_feature(netdev,
OCTNET_CMD_VERBOSE_ENABLE);
OCTNET_CMD_VERBOSE_ENABLE, 0);
else
liquidio_set_feature(netdev,
OCTNET_CMD_VERBOSE_DISABLE);
OCTNET_CMD_VERBOSE_DISABLE, 0);
}
lio->msg_enable = msglvl;
......@@ -950,7 +948,6 @@ static int lio_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
struct octeon_device *oct = lio->oct_dev;
struct oct_link_info *linfo;
struct octnic_ctrl_pkt nctrl;
struct octnic_ctrl_params nparams;
int ret = 0;
/* get the link info */
......@@ -978,9 +975,9 @@ static int lio_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
nctrl.ncmd.u64 = 0;
nctrl.ncmd.s.cmd = OCTNET_CMD_SET_SETTINGS;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 1000;
nctrl.netpndev = (u64)netdev;
nctrl.ncmd.s.param1 = lio->linfo.ifidx;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
/* Passing the parameters sent by ethtool like Speed, Autoneg & Duplex
......@@ -990,19 +987,17 @@ static int lio_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
/* Autoneg ON */
nctrl.ncmd.s.more = OCTNIC_NCMD_PHY_ON |
OCTNIC_NCMD_AUTONEG_ON;
nctrl.ncmd.s.param2 = ecmd->advertising;
nctrl.ncmd.s.param1 = ecmd->advertising;
} else {
/* Autoneg OFF */
nctrl.ncmd.s.more = OCTNIC_NCMD_PHY_ON;
nctrl.ncmd.s.param3 = ecmd->duplex;
nctrl.ncmd.s.param2 = ecmd->duplex;
nctrl.ncmd.s.param2 = ecmd->speed;
nctrl.ncmd.s.param1 = ecmd->speed;
}
nparams.resp_order = OCTEON_RESP_ORDERED;
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams);
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
if (ret < 0) {
dev_err(&oct->pci_dev->dev, "Failed to set settings\n");
return -1;
......
......@@ -260,19 +260,19 @@ union octnet_cmd {
u64 more:6; /* How many udd words follow the command */
u64 param1:29;
u64 reserved:29;
u64 param2:16;
u64 param1:16;
u64 param3:8;
u64 param2:8;
#else
u64 param3:8;
u64 param2:8;
u64 param2:16;
u64 param1:16;
u64 param1:29;
u64 reserved:29;
u64 more:6;
......@@ -414,10 +414,9 @@ union octeon_rh {
u64 opcode:4;
u64 subcode:8;
u64 len:3; /** additional 64-bit words */
u64 rid:13;
u64 reserved:4;
u64 reserved:8;
u64 extra:25;
u64 ifidx:7;
u64 gmxport:16;
} r_nic_info;
#else
u64 u64;
......@@ -450,10 +449,9 @@ union octeon_rh {
u64 opcode:4;
} r_core_drv_init;
struct {
u64 ifidx:7;
u64 gmxport:16;
u64 extra:25;
u64 reserved:4;
u64 rid:13;
u64 reserved:8;
u64 len:3; /** additional 64-bit words */
u64 subcode:8;
u64 opcode:4;
......@@ -467,7 +465,7 @@ union octnic_packet_params {
u32 u32;
struct {
#ifdef __BIG_ENDIAN_BITFIELD
u32 reserved:16;
u32 reserved:24;
u32 ip_csum:1; /* Perform IP header checksum(s) */
/* Perform Outer transport header checksum */
u32 transport_csum:1;
......@@ -475,15 +473,13 @@ union octnic_packet_params {
u32 tnl_csum:1;
u32 tsflag:1; /* Timestamp this packet */
u32 ipsec_ops:4; /* IPsec operation */
u32 ifidx:8;
#else
u32 ifidx:8;
u32 ipsec_ops:4;
u32 tsflag:1;
u32 tnl_csum:1;
u32 transport_csum:1;
u32 ip_csum:1;
u32 reserved:16;
u32 reserved:24;
#endif
} s;
};
......@@ -495,21 +491,21 @@ union oct_link_status {
struct {
#ifdef __BIG_ENDIAN_BITFIELD
u64 duplex:8;
u64 status:8;
u64 mtu:16;
u64 speed:16;
u64 link_up:1;
u64 autoneg:1;
u64 interface:4;
u64 pause:1;
u64 reserved:10;
u64 reserved:17;
#else
u64 reserved:10;
u64 reserved:17;
u64 pause:1;
u64 interface:4;
u64 autoneg:1;
u64 link_up:1;
u64 speed:16;
u64 mtu:16;
u64 status:8;
u64 duplex:8;
#endif
} s;
......@@ -561,17 +557,15 @@ struct oct_link_info {
u64 hw_addr;
#ifdef __BIG_ENDIAN_BITFIELD
u16 gmxport;
u8 rsvd[3];
u8 num_txpciq;
u8 num_rxpciq;
u8 ifidx;
u64 gmxport:16;
u64 rsvd:32;
u64 num_txpciq:8;
u64 num_rxpciq:8;
#else
u8 ifidx;
u8 num_rxpciq;
u8 num_txpciq;
u8 rsvd[3];
u16 gmxport;
u64 num_rxpciq:8;
u64 num_txpciq:8;
u64 rsvd:32;
u64 gmxport:16;
#endif
union oct_txpciq txpciq[MAX_IOQS_PER_NICIF];
......@@ -581,7 +575,6 @@ struct oct_link_info {
#define OCT_LINK_INFO_SIZE (sizeof(struct oct_link_info))
struct liquidio_if_cfg_info {
u64 ifidx;
u64 iqmask; /** mask for IQs enabled for the port */
u64 oqmask; /** mask for OQs enabled for the port */
struct oct_link_info linfo; /** initial link information */
......
......@@ -766,7 +766,9 @@ int octeon_setup_instr_queues(struct octeon_device *oct)
if (!oct->instr_queue[0])
return 1;
memset(oct->instr_queue[0], 0, sizeof(struct octeon_instr_queue));
oct->instr_queue[0]->q_index = 0;
oct->instr_queue[0]->app_ctx = (void *)(size_t)0;
oct->instr_queue[0]->ifidx = 0;
txpciq.u64 = 0;
txpciq.s.q_no = iq_no;
txpciq.s.use_qpg = 0;
......
......@@ -267,6 +267,7 @@ struct octdev_props {
/* Each interface in the Octeon device has a network
* device pointer (used for OS specific calls).
*/
int gmxport;
struct net_device *netdev;
};
......
......@@ -696,7 +696,8 @@ octeon_droq_fast_process_packets(struct octeon_device *oct,
if (droq->ops.fptr) {
droq->ops.fptr(oct->octeon_id,
nicbuf, pkt_len,
rh, &droq->napi);
rh, &droq->napi,
droq->ops.farg);
} else {
recv_buffer_free(nicbuf);
}
......@@ -963,6 +964,7 @@ int octeon_unregister_droq_ops(struct octeon_device *oct, u32 q_no)
spin_lock_irqsave(&droq->lock, flags);
droq->ops.fptr = NULL;
droq->ops.farg = NULL;
droq->ops.drop_on_max = 0;
spin_unlock_irqrestore(&droq->lock, flags);
......
......@@ -231,7 +231,8 @@ struct octeon_droq_ops {
* data in the buffer. The receive header gives the port
* number to the caller. Function pointer is set by caller.
*/
void (*fptr)(u32, void *, u32, union octeon_rh *, void *);
void (*fptr)(u32, void *, u32, union octeon_rh *, void *, void *);
void *farg;
/* This function will be called by the driver for all NAPI related
* events. The first param is the octeon id. The second param is the
......
......@@ -147,6 +147,13 @@ struct octeon_instr_queue {
/** Application context */
void *app_ctx;
/* network stack queue index */
int q_index;
/*os ifidx associated with this queue */
int ifidx;
};
/*---------------------- INSTRUCTION FORMAT ----------------------------*/
......@@ -314,7 +321,8 @@ void octeon_prepare_soft_command(struct octeon_device *oct,
int octeon_send_soft_command(struct octeon_device *oct,
struct octeon_soft_command *sc);
int octeon_setup_iq(struct octeon_device *oct, union oct_txpciq,
u32 num_descs, void *app_ctx);
int octeon_setup_iq(struct octeon_device *oct, int ifidx,
int q_index, union oct_txpciq iq_no, u32 num_descs,
void *app_ctx);
#endif /* __OCTEON_IQ_H__ */
......@@ -67,6 +67,9 @@ struct lio {
/** Link information sent by the core application for this interface. */
struct oct_link_info linfo;
/** counter of link changes */
u64 link_changes;
/** Size of Tx queue for this octeon device. */
u32 tx_qsize;
......@@ -111,8 +114,9 @@ struct lio {
* \brief Enable or disable feature
* @param netdev pointer to network device
* @param cmd Command that just requires acknowledgment
* @param param1 Parameter to command
*/
int liquidio_set_feature(struct net_device *netdev, int cmd);
int liquidio_set_feature(struct net_device *netdev, int cmd, u16 param1);
/**
* \brief Link control command completion callback
......
......@@ -119,8 +119,7 @@ static void octnet_link_ctrl_callback(struct octeon_device *oct,
static inline struct octeon_soft_command
*octnic_alloc_ctrl_pkt_sc(struct octeon_device *oct,
struct octnic_ctrl_pkt *nctrl,
struct octnic_ctrl_params nparams)
struct octnic_ctrl_pkt *nctrl)
{
struct octeon_soft_command *sc = NULL;
u8 *data;
......@@ -143,7 +142,7 @@ static inline struct octeon_soft_command
data = (u8 *)sc->virtdptr;
memcpy(data, &nctrl->ncmd, OCTNET_CMD_SIZE);
memcpy(data, &nctrl->ncmd, OCTNET_CMD_SIZE);
octeon_swap_8B_data((u64 *)data, (OCTNET_CMD_SIZE >> 3));
......@@ -152,6 +151,8 @@ static inline struct octeon_soft_command
memcpy(data + OCTNET_CMD_SIZE, nctrl->udd, uddsize);
}
sc->iq_no = (u32)nctrl->iq_no;
octeon_prepare_soft_command(oct, sc, OPCODE_NIC, OPCODE_NIC_CMD,
0, 0, 0);
......@@ -164,13 +165,12 @@ static inline struct octeon_soft_command
int
octnet_send_nic_ctrl_pkt(struct octeon_device *oct,
struct octnic_ctrl_pkt *nctrl,
struct octnic_ctrl_params nparams)
struct octnic_ctrl_pkt *nctrl)
{
int retval;
struct octeon_soft_command *sc = NULL;
sc = octnic_alloc_ctrl_pkt_sc(oct, nctrl, nparams);
sc = octnic_alloc_ctrl_pkt_sc(oct, nctrl);
if (!sc) {
dev_err(&oct->pci_dev->dev, "%s soft command alloc failed\n",
__func__);
......
......@@ -52,6 +52,9 @@ struct octnic_ctrl_pkt {
/** Additional data that may be needed by some commands. */
u64 udd[MAX_NCTRL_UDD];
/** Input queue to use to send this command. */
u64 iq_no;
/** Time to wait for Octeon software to respond to this control command.
* If wait_time is 0, OSI assumes no response is expected.
*/
......@@ -100,8 +103,7 @@ union octnic_cmd_setup {
u32 ip_csum:1;
u32 transport_csum:1;
u32 tnl_csum:1;
u32 ifidx:8;
u32 rsvd:11;
u32 rsvd:19;
union {
u32 datasize;
......@@ -113,10 +115,6 @@ union octnic_cmd_setup {
};
struct octnic_ctrl_params {
u32 resp_order;
};
static inline int octnet_iq_is_full(struct octeon_device *oct, u32 q_no)
{
return ((u32)atomic_read(&oct->instr_queue[q_no]->instr_pending)
......@@ -131,12 +129,13 @@ static inline int octnet_iq_is_full(struct octeon_device *oct, u32 q_no)
* Assumes the cmd instruction is pre-allocated, but no fields are filled in.
*/
static inline void
octnet_prepare_pci_cmd(struct octeon_instr_64B *cmd,
octnet_prepare_pci_cmd(struct octeon_device *oct, struct octeon_instr_64B *cmd,
union octnic_cmd_setup *setup, u32 tag)
{
struct octeon_instr_ih *ih;
struct octeon_instr_irh *irh;
union octnic_packet_params packet_params;
int port;
memset(cmd, 0, sizeof(struct octeon_instr_64B));
......@@ -150,13 +149,15 @@ octnet_prepare_pci_cmd(struct octeon_instr_64B *cmd,
ih->tagtype = ORDERED_TAG;
ih->grp = DEFAULT_POW_GRP;
port = (int)oct->instr_queue[setup->s.iq_no]->txpciq.s.port;
if (tag)
ih->tag = tag;
else
ih->tag = LIO_DATA(setup->s.ifidx);
ih->tag = LIO_DATA(port);
ih->raw = 1;
ih->qos = (setup->s.ifidx & 3) + 4; /* map qos based on interface */
ih->qos = (port & 3) + 4; /* map qos based on interface */
if (!setup->s.gather) {
ih->dlengsz = setup->s.u.datasize;
......@@ -175,7 +176,6 @@ octnet_prepare_pci_cmd(struct octeon_instr_64B *cmd,
packet_params.s.ip_csum = setup->s.ip_csum;
packet_params.s.transport_csum = setup->s.transport_csum;
packet_params.s.tnl_csum = setup->s.tnl_csum;
packet_params.s.ifidx = setup->s.ifidx;
packet_params.s.tsflag = setup->s.timestamp;
irh->ossp = packet_params.u32;
......@@ -216,7 +216,6 @@ int octnet_send_nic_data_pkt(struct octeon_device *oct,
*/
int
octnet_send_nic_ctrl_pkt(struct octeon_device *oct,
struct octnic_ctrl_pkt *nctrl,
struct octnic_ctrl_params nparams);
struct octnic_ctrl_pkt *nctrl);
#endif
......@@ -202,6 +202,8 @@ int octeon_delete_instr_queue(struct octeon_device *oct, u32 iq_no)
/* Return 0 on success, 1 on failure */
int octeon_setup_iq(struct octeon_device *oct,
int ifidx,
int q_index,
union oct_txpciq txpciq,
u32 num_descs,
void *app_ctx)
......@@ -227,7 +229,10 @@ int octeon_setup_iq(struct octeon_device *oct,
memset(oct->instr_queue[iq_no], 0,
sizeof(struct octeon_instr_queue));
oct->instr_queue[iq_no]->q_index = q_index;
oct->instr_queue[iq_no]->app_ctx = app_ctx;
oct->instr_queue[iq_no]->ifidx = ifidx;
if (octeon_init_instr_queue(oct, txpciq, num_descs)) {
vfree(oct->instr_queue[iq_no]);
oct->instr_queue[iq_no] = NULL;
......
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