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

Commit 520b2756 authored by Matt Carlson's avatar Matt Carlson Committed by David S. Miller
Browse files

tg3: Create funcs for power source switching



The power source switching code is about to get a little more complex.
This patch seeks to simplify future power source switching patches by
clarifying the existing code.

Signed-off-by: default avatarMatt Carlson <mcarlson@broadcom.com>
Reviewed-by: default avatarMichael Chan <mchan@broadcom.com>
Reviewed-by: default avatarBenjamin Li <benli@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@conan.davemloft.net>
parent 221c5637
Loading
Loading
Loading
Loading
+119 −82
Original line number Original line Diff line number Diff line
@@ -107,6 +107,8 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
	 NETIF_MSG_RX_ERR	| \
	 NETIF_MSG_RX_ERR	| \
	 NETIF_MSG_TX_ERR)
	 NETIF_MSG_TX_ERR)


#define TG3_GRC_LCLCTL_PWRSW_DELAY	100

/* length of time before we decide the hardware is borked,
/* length of time before we decide the hardware is borked,
 * and dev->tx_timeout() should be called to fix the problem
 * and dev->tx_timeout() should be called to fix the problem
 */
 */
@@ -2165,42 +2167,46 @@ out:
	return 0;
	return 0;
}
}


static void tg3_frob_aux_power(struct tg3 *tp)
static inline int tg3_pwrsrc_switch_to_vmain(struct tg3 *tp)
{
{
	bool need_vaux = false;
	if (!tg3_flag(tp, IS_NIC))
		return 0;

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

	return 0;
}

static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp)
{
	u32 grc_local_ctrl;


	/* The GPIOs do something completely different on 57765. */
	if (!tg3_flag(tp, IS_NIC) ||
	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_5700 ||
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)
		return;
		return;


	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
	grc_local_ctrl = tp->grc_local_ctrl | GRC_LCLCTRL_GPIO_OE1;
	     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) {
		struct net_device *dev_peer;


		dev_peer = pci_get_drvdata(tp->pdev_peer);
	tw32_wait_f(GRC_LOCAL_CTRL,
		    grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1,
		    TG3_GRC_LCLCTL_PWRSW_DELAY);


		/* remove_one() may have been run on the peer. */
	tw32_wait_f(GRC_LOCAL_CTRL,
		if (dev_peer) {
		    grc_local_ctrl,
			struct tg3 *tp_peer = netdev_priv(dev_peer);
		    TG3_GRC_LCLCTL_PWRSW_DELAY);

			if (tg3_flag(tp_peer, INIT_COMPLETE))
				return;


			if (tg3_flag(tp_peer, WOL_ENABLE) ||
	tw32_wait_f(GRC_LOCAL_CTRL,
			    tg3_flag(tp_peer, ENABLE_ASF))
		    grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1,
				need_vaux = true;
		    TG3_GRC_LCLCTL_PWRSW_DELAY);
		}
}
}


	if (tg3_flag(tp, WOL_ENABLE) || tg3_flag(tp, ENABLE_ASF))
static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
		need_vaux = true;
{
	if (!tg3_flag(tp, IS_NIC))
		return;


	if (need_vaux) {
	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
		tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
		tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
@@ -2209,7 +2215,7 @@ static void tg3_frob_aux_power(struct tg3 *tp)
			     GRC_LCLCTRL_GPIO_OE2 |
			     GRC_LCLCTRL_GPIO_OE2 |
			     GRC_LCLCTRL_GPIO_OUTPUT0 |
			     GRC_LCLCTRL_GPIO_OUTPUT0 |
			     GRC_LCLCTRL_GPIO_OUTPUT1),
			     GRC_LCLCTRL_GPIO_OUTPUT1),
				    100);
			    TG3_GRC_LCLCTL_PWRSW_DELAY);
	} else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
	} else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
		   tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
		   tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
		/* The 5761 non-e device swaps GPIO 0 and GPIO 2. */
		/* The 5761 non-e device swaps GPIO 0 and GPIO 2. */
@@ -2219,23 +2225,26 @@ static void tg3_frob_aux_power(struct tg3 *tp)
				     GRC_LCLCTRL_GPIO_OUTPUT0 |
				     GRC_LCLCTRL_GPIO_OUTPUT0 |
				     GRC_LCLCTRL_GPIO_OUTPUT1 |
				     GRC_LCLCTRL_GPIO_OUTPUT1 |
				     tp->grc_local_ctrl;
				     tp->grc_local_ctrl;
			tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100);
		tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl,
			    TG3_GRC_LCLCTL_PWRSW_DELAY);


		grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT2;
		grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT2;
			tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100);
		tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl,
			    TG3_GRC_LCLCTL_PWRSW_DELAY);


		grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT0;
		grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT0;
			tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100);
		tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl,
			    TG3_GRC_LCLCTL_PWRSW_DELAY);
	} else {
	} else {
		u32 no_gpio2;
		u32 no_gpio2;
		u32 grc_local_ctrl = 0;
		u32 grc_local_ctrl = 0;


		/* Workaround to prevent overdrawing Amps. */
		/* Workaround to prevent overdrawing Amps. */
			if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
			    ASIC_REV_5714) {
			grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
			grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
			tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
			tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
					    grc_local_ctrl, 100);
				    grc_local_ctrl,
				    TG3_GRC_LCLCTL_PWRSW_DELAY);
		}
		}


		/* On 5753 and variants, GPIO2 cannot be used. */
		/* On 5753 and variants, GPIO2 cannot be used. */
@@ -2251,35 +2260,64 @@ static void tg3_frob_aux_power(struct tg3 *tp)
			grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 |
			grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 |
					    GRC_LCLCTRL_GPIO_OUTPUT2);
					    GRC_LCLCTRL_GPIO_OUTPUT2);
		}
		}
			tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
		tw32_wait_f(GRC_LOCAL_CTRL,
						    grc_local_ctrl, 100);
			    tp->grc_local_ctrl | grc_local_ctrl,
			    TG3_GRC_LCLCTL_PWRSW_DELAY);


		grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0;
		grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0;


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


		if (!no_gpio2) {
		if (!no_gpio2) {
			grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2;
			grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2;
				tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
			tw32_wait_f(GRC_LOCAL_CTRL,
					    grc_local_ctrl, 100);
				    tp->grc_local_ctrl | grc_local_ctrl,
				    TG3_GRC_LCLCTL_PWRSW_DELAY);
		}
	}
	}
}
}
	} else {
		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 |
				    (GRC_LCLCTRL_GPIO_OE1 |
				     GRC_LCLCTRL_GPIO_OUTPUT1), 100);


			tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
static void tg3_frob_aux_power(struct tg3 *tp)
				    GRC_LCLCTRL_GPIO_OE1, 100);
{
	bool need_vaux = false;


			tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
	/* The GPIOs do something completely different on 57765. */
				    (GRC_LCLCTRL_GPIO_OE1 |
	if (!tg3_flag(tp, IS_NIC) ||
				     GRC_LCLCTRL_GPIO_OUTPUT1), 100);
	    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) {
		struct net_device *dev_peer;

		dev_peer = pci_get_drvdata(tp->pdev_peer);

		/* remove_one() may have been run on the peer. */
		if (dev_peer) {
			struct tg3 *tp_peer = netdev_priv(dev_peer);

			if (tg3_flag(tp_peer, INIT_COMPLETE))
				return;

			if (tg3_flag(tp_peer, WOL_ENABLE) ||
			    tg3_flag(tp_peer, ENABLE_ASF))
				need_vaux = true;
		}
		}
	}
	}

	if (tg3_flag(tp, WOL_ENABLE) || tg3_flag(tp, ENABLE_ASF))
		need_vaux = true;

	if (need_vaux)
		tg3_pwrsrc_switch_to_vaux(tp);
	else
		tg3_pwrsrc_die_with_vmain(tp);
}
}


static int tg3_5700_link_polarity(struct tg3 *tp, u32 speed)
static int tg3_5700_link_polarity(struct tg3 *tp, u32 speed)
@@ -2624,8 +2662,7 @@ static int tg3_power_up(struct tg3 *tp)
	pci_set_power_state(tp->pdev, PCI_D0);
	pci_set_power_state(tp->pdev, PCI_D0);


	/* Switch out of Vaux if it is a NIC */
	/* Switch out of Vaux if it is a NIC */
	if (tg3_flag(tp, IS_NIC))
	tg3_pwrsrc_switch_to_vmain(tp);
		tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100);


	return 0;
	return 0;
}
}