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

Commit 3a1e19d3 authored by Matt Carlson's avatar Matt Carlson Committed by David S. Miller
Browse files

tg3: Add function status reporting



This patch adds code to update the status of the function to a common
location to the critical section added in the previous patch.

Signed-off-by: default avatarMatt Carlson <mcarlson@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6f5c8f83
Loading
Loading
Loading
Loading
+87 −24
Original line number Diff line number Diff line
@@ -2192,18 +2192,66 @@ static int tg3_phy_reset(struct tg3 *tp)
	return 0;
}

#define TG3_GPIO_MSG_DRVR_PRES		 0x00000001
#define TG3_GPIO_MSG_NEED_VAUX		 0x00000002
#define TG3_GPIO_MSG_MASK		 (TG3_GPIO_MSG_DRVR_PRES | \
					  TG3_GPIO_MSG_NEED_VAUX)
#define TG3_GPIO_MSG_ALL_DRVR_PRES_MASK \
	((TG3_GPIO_MSG_DRVR_PRES << 0) | \
	 (TG3_GPIO_MSG_DRVR_PRES << 4) | \
	 (TG3_GPIO_MSG_DRVR_PRES << 8) | \
	 (TG3_GPIO_MSG_DRVR_PRES << 12))

#define TG3_GPIO_MSG_ALL_NEED_VAUX_MASK \
	((TG3_GPIO_MSG_NEED_VAUX << 0) | \
	 (TG3_GPIO_MSG_NEED_VAUX << 4) | \
	 (TG3_GPIO_MSG_NEED_VAUX << 8) | \
	 (TG3_GPIO_MSG_NEED_VAUX << 12))

static inline u32 tg3_set_function_status(struct tg3 *tp, u32 newstat)
{
	u32 status, shift;

	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
		status = tg3_ape_read32(tp, TG3_APE_GPIO_MSG);
	else
		status = tr32(TG3_CPMU_DRV_STATUS);

	shift = TG3_APE_GPIO_MSG_SHIFT + 4 * tp->pci_fn;
	status &= ~(TG3_GPIO_MSG_MASK << shift);
	status |= (newstat << shift);

	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
		tg3_ape_write32(tp, TG3_APE_GPIO_MSG, status);
	else
		tw32(TG3_CPMU_DRV_STATUS, status);

	return status >> TG3_APE_GPIO_MSG_SHIFT;
}

static inline int tg3_pwrsrc_switch_to_vmain(struct tg3 *tp)
{
	if (!tg3_flag(tp, IS_NIC))
		return;
		return 0;

	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
		if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
		return 0;
			return -EIO;

		tg3_set_function_status(tp, TG3_GPIO_MSG_DRVR_PRES);

		tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl,
			    TG3_GRC_LCLCTL_PWRSW_DELAY);

		tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
	} else {
		tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl,
			    TG3_GRC_LCLCTL_PWRSW_DELAY);
	}

	return 0;
}
@@ -2217,10 +2265,6 @@ static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp)
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)
		return;


	if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
		return;

	grc_local_ctrl = tp->grc_local_ctrl | GRC_LCLCTRL_GPIO_OE1;

	tw32_wait_f(GRC_LOCAL_CTRL,
@@ -2234,8 +2278,6 @@ static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp)
	tw32_wait_f(GRC_LOCAL_CTRL,
		    grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1,
		    TG3_GRC_LCLCTL_PWRSW_DELAY);

	tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
}

static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
@@ -2243,9 +2285,6 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
	if (!tg3_flag(tp, IS_NIC))
		return;

	if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
		return;

	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
		tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
@@ -2316,7 +2355,31 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
				    TG3_GRC_LCLCTL_PWRSW_DELAY);
		}
	}
}

static void tg3_frob_aux_power_5717(struct tg3 *tp)
{
	u32 msg = 0;

	/* Serialize power state transitions */
	if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
		return;

	if (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE) ||
	    tg3_flag(tp, WOL_ENABLE))
		msg = TG3_GPIO_MSG_NEED_VAUX;

	msg = tg3_set_function_status(tp, msg);

	if (msg & TG3_GPIO_MSG_ALL_DRVR_PRES_MASK)
		goto done;

	if (msg & TG3_GPIO_MSG_ALL_NEED_VAUX_MASK)
		tg3_pwrsrc_switch_to_vaux(tp);
	else
		tg3_pwrsrc_die_with_vmain(tp);

done:
	tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
}

@@ -2326,15 +2389,17 @@ static void tg3_frob_aux_power(struct tg3 *tp)

	/* The GPIOs do something completely different on 57765. */
	if (!tg3_flag(tp, IS_NIC) ||
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
		return;

	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) &&
	    tp->pdev_peer != tp->pdev) {
	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
		tg3_frob_aux_power_5717(tp);
		return;
	}

	if (tp->pdev_peer && tp->pdev_peer != tp->pdev) {
		struct net_device *dev_peer;

		dev_peer = pci_get_drvdata(tp->pdev_peer);
@@ -13692,9 +13757,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
	}

	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)
		tp->pdev_peer = tg3_find_peer(tp);

	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+4 −0
Original line number Diff line number Diff line
@@ -1065,6 +1065,8 @@
#define  RCVLSC_STATUS_ERROR_ATTN	 0x00000004
/* 0x3408 --> 0x3600 unused */

#define TG3_CPMU_DRV_STATUS		0x0000344c

/* CPMU registers */
#define TG3_CPMU_CTRL			0x00003600
#define  CPMU_CTRL_LINK_IDLE_MODE	 0x00000200
@@ -2277,6 +2279,8 @@


/* APE registers.  Accessible through BAR1 */
#define TG3_APE_GPIO_MSG		0x0008
#define TG3_APE_GPIO_MSG_SHIFT		4
#define TG3_APE_EVENT			0x000c
#define  APE_EVENT_1			 0x00000001
#define TG3_APE_LOCK_REQ		0x002c