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

Commit 6e0ae74b authored by Narsimhulu Musini's avatar Narsimhulu Musini Committed by Martin K. Petersen
Browse files

snic: Handling control path queue issues



Fix handles control path queue issues such as queue full and sudden
removal of hardware.

Signed-off-by: default avatarNarsimhulu Musini <nmusini@cisco.com>
Signed-off-by: default avatarSesidhar Baddela <sebaddel@cisco.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent f352a0d5
Loading
Loading
Loading
Loading
+30 −14
Original line number Diff line number Diff line
@@ -263,12 +263,20 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
	int wait)
{
	struct devcmd2_controller *dc2c = vdev->devcmd2;
	struct devcmd2_result *result = dc2c->result + dc2c->next_result;
	struct devcmd2_result *result = NULL;
	unsigned int i;
	int delay;
	int err;
	u32 posted;
	u32 fetch_idx;
	u32 new_posted;
	u8 color;

	fetch_idx = ioread32(&dc2c->wq_ctrl->fetch_index);
	if (fetch_idx == 0xFFFFFFFF) { /* check for hardware gone  */
		/* Hardware surprise removal: return error */
		return -ENODEV;
	}

	posted = ioread32(&dc2c->wq_ctrl->posted_index);

@@ -278,6 +286,13 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
	}

	new_posted = (posted + 1) % DEVCMD2_RING_SIZE;
	if (new_posted == fetch_idx) {
		pr_err("%s: wq is full while issuing devcmd2 command %d, fetch index: %u, posted index: %u\n",
			pci_name(vdev->pdev), _CMD_N(cmd), fetch_idx, posted);

		return -EBUSY;
	}

	dc2c->cmd_ring[posted].cmd = cmd;
	dc2c->cmd_ring[posted].flags = 0;

@@ -299,14 +314,22 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
	if (dc2c->cmd_ring[posted].flags & DEVCMD2_FNORESULT)
		return 0;

	for (delay = 0; delay < wait; delay++) {
		udelay(100);
		if (result->color == dc2c->color) {
	result = dc2c->result + dc2c->next_result;
	color = dc2c->color;

	/*
	 * Increment next_result, after posting the devcmd, irrespective of
	 * devcmd result, and it should be done only once.
	 */
	dc2c->next_result++;
	if (dc2c->next_result == dc2c->result_size) {
		dc2c->next_result = 0;
		dc2c->color = dc2c->color ? 0 : 1;
	}

	for (delay = 0; delay < wait; delay++) {
		udelay(100);
		if (result->color == color) {
			if (result->error) {
				err = (int) result->error;
				if (err != ERR_ECMDUNKNOWN ||
@@ -317,13 +340,6 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
				return err;
			}
			if (_CMD_DIR(cmd) & _CMD_DIR_READ) {
				/*
				 * Adding the rmb() prevents the compiler
				 * and/or CPU from reordering the reads which
				 * would potentially result in reading stale
				 * values.
				 */
				rmb();
				for (i = 0; i < VNIC_DEVCMD_NARGS; i++)
					vdev->args[i] = result->results[i];
			}