Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9c9ad412 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'liquidio-next'



Raghu Vatsavayi says:

====================
liquidio: Updates and Bug fixes

Following are updates for liquidio bug fixes and driver
support for new firmware interface. These updates are divided
into smaller logical patches as mentioned by you. These set of
nine patches should be applied in the following order as some of
them depend on earlier patches in the list.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0b797c85 6a885b60
Loading
Loading
Loading
Loading
+18 −23
Original line number Diff line number Diff line
@@ -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);

@@ -317,7 +315,7 @@ octnet_mdio45_access(struct lio *lio, int op, int loc, int *value)

	retval = octeon_send_soft_command(oct_dev, sc);

	if (retval) {
	if (retval == IQ_SEND_FAILED) {
		dev_err(&oct_dev->pci_dev->dev,
			"octnet_mdio45_access instruction failed status: %x\n",
			retval);
@@ -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;
@@ -653,7 +651,7 @@ static int lio_get_intr_coalesce(struct net_device *netdev,
				intrmod_cfg->intrmod_mincnt_trigger;
		}

		iq = oct->instr_queue[lio->linfo.txpciq[0]];
		iq = oct->instr_queue[lio->linfo.txpciq[0].s.q_no];
		intr_coal->tx_max_coalesced_frames = iq->fill_threshold;
		break;

@@ -722,7 +720,7 @@ static int octnet_set_intrmod_cfg(void *oct, struct oct_intrmod_cfg *intr_cfg)
	sc->wait_time = 1000;

	retval = octeon_send_soft_command(oct_dev, sc);
	if (retval) {
	if (retval == IQ_SEND_FAILED) {
		octeon_free_soft_command(oct_dev, sc);
		return -EINVAL;
	}
@@ -859,7 +857,7 @@ static int lio_set_intr_coalesce(struct net_device *netdev,
	if ((intr_coal->tx_max_coalesced_frames >= CN6XXX_DB_MIN) &&
	    (intr_coal->tx_max_coalesced_frames <= CN6XXX_DB_MAX)) {
		for (j = 0; j < lio->linfo.num_txpciq; j++) {
			q_no = lio->linfo.txpciq[j];
			q_no = lio->linfo.txpciq[j].s.q_no;
			oct->instr_queue[q_no]->fill_threshold =
				intr_coal->tx_max_coalesced_frames;
		}
@@ -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;
+367 −348

File changed.

Preview size limit exceeded, changes collapsed.

+212 −48
Original line number Diff line number Diff line
@@ -174,9 +174,11 @@ static inline void add_sg_size(struct octeon_sg_entry *sg_entry,
/*------------------------- End Scatter/Gather ---------------------------*/

#define   OCTNET_FRM_PTP_HEADER_SIZE  8
#define   OCTNET_FRM_HEADER_SIZE     30 /* PTP timestamp + VLAN + Ethernet */

#define   OCTNET_MIN_FRM_SIZE        (64  + OCTNET_FRM_PTP_HEADER_SIZE)
#define   OCTNET_FRM_HEADER_SIZE     22 /* VLAN + Ethernet */

#define   OCTNET_MIN_FRM_SIZE        64

#define   OCTNET_MAX_FRM_SIZE        (16000 + OCTNET_FRM_HEADER_SIZE)

#define   OCTNET_DEFAULT_FRM_SIZE    (1500 + OCTNET_FRM_HEADER_SIZE)
@@ -258,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;

@@ -283,8 +285,140 @@ union octnet_cmd {

#define   OCTNET_CMD_SIZE     (sizeof(union octnet_cmd))

/* Instruction Header (DPI - CN23xx) - for OCTEON-III models */
struct  octeon_instr_ih3 {
#ifdef __BIG_ENDIAN_BITFIELD

	/** Reserved3 */
	u64     reserved3:1;

	/** Gather indicator 1=gather*/
	u64     gather:1;

	/** Data length OR no. of entries in gather list */
	u64     dlengsz:14;

	/** Front Data size */
	u64     fsz:6;

	/** Reserved2 */
	u64     reserved2:4;

	/** PKI port kind - PKIND */
	u64     pkind:6;

	/** Reserved1 */
	u64     reserved1:32;

#else
	/** Reserved1 */
	u64     reserved1:32;

	/** PKI port kind - PKIND */
	u64     pkind:6;

	/** Reserved2 */
	u64     reserved2:4;

	/** Front Data size */
	u64     fsz:6;

	/** Data length OR no. of entries in gather list */
	u64     dlengsz:14;

	/** Gather indicator 1=gather*/
	u64     gather:1;

	/** Reserved3 */
	u64     reserved3:1;

#endif
};

/* Optional PKI Instruction Header(PKI IH) - for OCTEON CN23XX models */
/** BIG ENDIAN format.   */
struct  octeon_instr_pki_ih3 {
#ifdef __BIG_ENDIAN_BITFIELD

	/** Wider bit */
	u64     w:1;

	/** Raw mode indicator 1 = RAW */
	u64     raw:1;

	/** Use Tag */
	u64     utag:1;

	/** Use QPG */
	u64     uqpg:1;

	/** Reserved2 */
	u64     reserved2:1;

	/** Parse Mode */
	u64     pm:3;

	/** Skip Length */
	u64     sl:8;

	/** Use Tag Type */
	u64     utt:1;

	/** Tag type */
	u64     tagtype:2;

	/** Reserved1 */
	u64     reserved1:2;

	/** QPG Value */
	u64     qpg:11;

	/** Tag Value */
	u64     tag:32;

#else

	/** Tag Value */
	u64     tag:32;

	/** QPG Value */
	u64     qpg:11;

	/** Reserved1 */
	u64     reserved1:2;

	/** Tag type */
	u64     tagtype:2;

	/** Use Tag Type */
	u64     utt:1;

	/** Skip Length */
	u64     sl:8;

	/** Parse Mode */
	u64     pm:3;

	/** Reserved2 */
	u64     reserved2:1;

	/** Use QPG */
	u64     uqpg:1;

	/** Use Tag */
	u64     utag:1;

	/** Raw mode indicator 1 = RAW */
	u64     raw:1;

	/** Wider bit */
	u64     w:1;
#endif

};

/** Instruction Header */
struct octeon_instr_ih {
struct octeon_instr_ih2 {
#ifdef __BIG_ENDIAN_BITFIELD
	/** Raw mode indicator 1 = RAW */
	u64 raw:1;
@@ -412,10 +546,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;
@@ -448,10 +581,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;
@@ -461,30 +593,25 @@ union octeon_rh {

#define  OCT_RH_SIZE   (sizeof(union  octeon_rh))

#define OCT_PKT_PARAM_IPV4OPTS   1
#define OCT_PKT_PARAM_IPV6EXTHDR 2

union octnic_packet_params {
	u32 u32;
	struct {
#ifdef __BIG_ENDIAN_BITFIELD
		u32 reserved:6;
		u32 reserved:24;
		u32 ip_csum:1;		/* Perform IP header checksum(s) */
		/* Perform Outer transport header checksum */
		u32 transport_csum:1;
		/* Find tunnel, and perform transport csum. */
		u32 tnl_csum:1;
		u32 ip_csum:1;
		u32 ipv4opts_ipv6exthdr:2;
		u32 ipsec_ops:4;
		u32 tsflag:1;
		u32 csoffset:9;
		u32 ifidx:8;
		u32 tsflag:1;		/* Timestamp this packet */
		u32 ipsec_ops:4;	/* IPsec operation */
#else
		u32 ifidx:8;
		u32 csoffset:9;
		u32 tsflag:1;
		u32 ipsec_ops:4;
		u32 ipv4opts_ipv6exthdr:2;
		u32 ip_csum:1;
		u32 tsflag:1;
		u32 tnl_csum:1;
		u32 reserved:6;
		u32 transport_csum:1;
		u32 ip_csum:1;
		u32 reserved:24;
#endif
	} s;
};
@@ -496,53 +623,90 @@ 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;
};

/** The txpciq info passed to host from the firmware */

union oct_txpciq {
	u64 u64;

	struct {
#ifdef __BIG_ENDIAN_BITFIELD
		u64 q_no:8;
		u64 port:8;
		u64 pkind:6;
		u64 use_qpg:1;
		u64 qpg:11;
		u64 reserved:30;
#else
		u64 reserved:30;
		u64 qpg:11;
		u64 use_qpg:1;
		u64 pkind:6;
		u64 port:8;
		u64 q_no:8;
#endif
	} s;
};

/** The rxpciq info passed to host from the firmware */

union oct_rxpciq {
	u64 u64;

	struct {
#ifdef __BIG_ENDIAN_BITFIELD
		u64 q_no:8;
		u64 reserved:56;
#else
		u64 reserved:56;
		u64 q_no:8;
#endif
	} s;
};

/** Information for a OCTEON ethernet interface shared between core & host. */
struct oct_link_info {
	union oct_link_status link;
	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

	u8 txpciq[MAX_IOQS_PER_NICIF];
	u8 rxpciq[MAX_IOQS_PER_NICIF];
	union oct_txpciq txpciq[MAX_IOQS_PER_NICIF];
	union oct_rxpciq rxpciq[MAX_IOQS_PER_NICIF];
};

#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 */
+38 −32
Original line number Diff line number Diff line
@@ -741,49 +741,59 @@ struct octeon_device *octeon_allocate_device(u32 pci_id,
	return oct;
}

/* this function is only for setting up the first queue */
int octeon_setup_instr_queues(struct octeon_device *oct)
{
	u32 i, num_iqs = 0;
	u32 num_iqs = 0;
	u32 num_descs = 0;
	u32 iq_no = 0;
	union oct_txpciq txpciq;
	int numa_node = cpu_to_node(iq_no % num_online_cpus());

	/* this causes queue 0 to be default queue */
	if (OCTEON_CN6XXX(oct)) {
	num_iqs = 1;
	/* this causes queue 0 to be default queue */
	if (OCTEON_CN6XXX(oct))
		num_descs =
			CFG_GET_NUM_DEF_TX_DESCS(CHIP_FIELD(oct, cn6xxx, conf));
	}

	oct->num_iqs = 0;

	for (i = 0; i < num_iqs; i++) {
		oct->instr_queue[i] =
	oct->instr_queue[0] = vmalloc_node(sizeof(*oct->instr_queue[0]),
				numa_node);
	if (!oct->instr_queue[0])
		oct->instr_queue[0] =
			vmalloc(sizeof(struct octeon_instr_queue));
		if (!oct->instr_queue[i])
	if (!oct->instr_queue[0])
		return 1;

		memset(oct->instr_queue[i], 0,
		       sizeof(struct octeon_instr_queue));

		oct->instr_queue[i]->app_ctx = (void *)(size_t)i;
		if (octeon_init_instr_queue(oct, i, num_descs))
	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;
	txpciq.s.qpg = 0;
	if (octeon_init_instr_queue(oct, txpciq, num_descs)) {
		/* prevent memory leak */
		vfree(oct->instr_queue[0]);
		return 1;

		oct->num_iqs++;
	}

	oct->num_iqs++;
	return 0;
}

int octeon_setup_output_queues(struct octeon_device *oct)
{
	u32 i, num_oqs = 0;
	u32 num_oqs = 0;
	u32 num_descs = 0;
	u32 desc_size = 0;
	u32 oq_no = 0;
	int numa_node = cpu_to_node(oq_no % num_online_cpus());

	num_oqs = 1;
	/* this causes queue 0 to be default queue */
	if (OCTEON_CN6XXX(oct)) {
		/* CFG_GET_OQ_MAX_BASE_Q(CHIP_FIELD(oct, cn6xxx, conf)); */
		num_oqs = 1;
		num_descs =
			CFG_GET_NUM_DEF_RX_DESCS(CHIP_FIELD(oct, cn6xxx, conf));
		desc_size =
@@ -791,19 +801,15 @@ int octeon_setup_output_queues(struct octeon_device *oct)
	}

	oct->num_oqs = 0;

	for (i = 0; i < num_oqs; i++) {
		oct->droq[i] = vmalloc(sizeof(*oct->droq[i]));
		if (!oct->droq[i])
	oct->droq[0] = vmalloc_node(sizeof(*oct->droq[0]), numa_node);
	if (!oct->droq[0])
		oct->droq[0] = vmalloc(sizeof(*oct->droq[0]));
	if (!oct->droq[0])
		return 1;

		memset(oct->droq[i], 0, sizeof(struct octeon_droq));

		if (octeon_init_droq(oct, i, num_descs, desc_size, NULL))
	if (octeon_init_droq(oct, oq_no, num_descs, desc_size, NULL))
		return 1;

	oct->num_oqs++;
	}

	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -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;
};

Loading