aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tg3.c
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2011-07-13 05:27:32 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-14 11:41:59 -0400
commit3a1e19d383c7b91c8af52e8938ab60c40e3d26b3 (patch)
tree4f8727f59b54c08be891feaa976d430eecf617a9 /drivers/net/tg3.c
parent6f5c8f8317d37045ffc7ea21dab8319a53c1ae57 (diff)
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: Matt Carlson <mcarlson@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r--drivers/net/tg3.c111
1 files changed, 87 insertions, 24 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 4137e4e027a3..0d1b0c0ef483 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -2192,18 +2192,66 @@ out:
2192 return 0; 2192 return 0;
2193} 2193}
2194 2194
2195#define TG3_GPIO_MSG_DRVR_PRES 0x00000001
2196#define TG3_GPIO_MSG_NEED_VAUX 0x00000002
2197#define TG3_GPIO_MSG_MASK (TG3_GPIO_MSG_DRVR_PRES | \
2198 TG3_GPIO_MSG_NEED_VAUX)
2199#define TG3_GPIO_MSG_ALL_DRVR_PRES_MASK \
2200 ((TG3_GPIO_MSG_DRVR_PRES << 0) | \
2201 (TG3_GPIO_MSG_DRVR_PRES << 4) | \
2202 (TG3_GPIO_MSG_DRVR_PRES << 8) | \
2203 (TG3_GPIO_MSG_DRVR_PRES << 12))
2204
2205#define TG3_GPIO_MSG_ALL_NEED_VAUX_MASK \
2206 ((TG3_GPIO_MSG_NEED_VAUX << 0) | \
2207 (TG3_GPIO_MSG_NEED_VAUX << 4) | \
2208 (TG3_GPIO_MSG_NEED_VAUX << 8) | \
2209 (TG3_GPIO_MSG_NEED_VAUX << 12))
2210
2211static inline u32 tg3_set_function_status(struct tg3 *tp, u32 newstat)
2212{
2213 u32 status, shift;
2214
2215 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
2216 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
2217 status = tg3_ape_read32(tp, TG3_APE_GPIO_MSG);
2218 else
2219 status = tr32(TG3_CPMU_DRV_STATUS);
2220
2221 shift = TG3_APE_GPIO_MSG_SHIFT + 4 * tp->pci_fn;
2222 status &= ~(TG3_GPIO_MSG_MASK << shift);
2223 status |= (newstat << shift);
2224
2225 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
2226 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
2227 tg3_ape_write32(tp, TG3_APE_GPIO_MSG, status);
2228 else
2229 tw32(TG3_CPMU_DRV_STATUS, status);
2230
2231 return status >> TG3_APE_GPIO_MSG_SHIFT;
2232}
2233
2195static inline int tg3_pwrsrc_switch_to_vmain(struct tg3 *tp) 2234static inline int tg3_pwrsrc_switch_to_vmain(struct tg3 *tp)
2196{ 2235{
2197 if (!tg3_flag(tp, IS_NIC)) 2236 if (!tg3_flag(tp, IS_NIC))
2198 return;
2199
2200 if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
2201 return 0; 2237 return 0;
2202 2238
2203 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 2239 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
2204 TG3_GRC_LCLCTL_PWRSW_DELAY); 2240 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
2241 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
2242 if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
2243 return -EIO;
2205 2244
2206 tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO); 2245 tg3_set_function_status(tp, TG3_GPIO_MSG_DRVR_PRES);
2246
2247 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl,
2248 TG3_GRC_LCLCTL_PWRSW_DELAY);
2249
2250 tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
2251 } else {
2252 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl,
2253 TG3_GRC_LCLCTL_PWRSW_DELAY);
2254 }
2207 2255
2208 return 0; 2256 return 0;
2209} 2257}
@@ -2217,10 +2265,6 @@ static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp)
2217 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) 2265 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)
2218 return; 2266 return;
2219 2267
2220
2221 if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
2222 return;
2223
2224 grc_local_ctrl = tp->grc_local_ctrl | GRC_LCLCTRL_GPIO_OE1; 2268 grc_local_ctrl = tp->grc_local_ctrl | GRC_LCLCTRL_GPIO_OE1;
2225 2269
2226 tw32_wait_f(GRC_LOCAL_CTRL, 2270 tw32_wait_f(GRC_LOCAL_CTRL,
@@ -2234,8 +2278,6 @@ static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp)
2234 tw32_wait_f(GRC_LOCAL_CTRL, 2278 tw32_wait_f(GRC_LOCAL_CTRL,
2235 grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1, 2279 grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1,
2236 TG3_GRC_LCLCTL_PWRSW_DELAY); 2280 TG3_GRC_LCLCTL_PWRSW_DELAY);
2237
2238 tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
2239} 2281}
2240 2282
2241static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp) 2283static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
@@ -2243,9 +2285,6 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
2243 if (!tg3_flag(tp, IS_NIC)) 2285 if (!tg3_flag(tp, IS_NIC))
2244 return; 2286 return;
2245 2287
2246 if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
2247 return;
2248
2249 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || 2288 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
2250 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { 2289 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
2251 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | 2290 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
@@ -2316,7 +2355,31 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
2316 TG3_GRC_LCLCTL_PWRSW_DELAY); 2355 TG3_GRC_LCLCTL_PWRSW_DELAY);
2317 } 2356 }
2318 } 2357 }
2358}
2359
2360static void tg3_frob_aux_power_5717(struct tg3 *tp)
2361{
2362 u32 msg = 0;
2363
2364 /* Serialize power state transitions */
2365 if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
2366 return;
2367
2368 if (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE) ||
2369 tg3_flag(tp, WOL_ENABLE))
2370 msg = TG3_GPIO_MSG_NEED_VAUX;
2371
2372 msg = tg3_set_function_status(tp, msg);
2373
2374 if (msg & TG3_GPIO_MSG_ALL_DRVR_PRES_MASK)
2375 goto done;
2319 2376
2377 if (msg & TG3_GPIO_MSG_ALL_NEED_VAUX_MASK)
2378 tg3_pwrsrc_switch_to_vaux(tp);
2379 else
2380 tg3_pwrsrc_die_with_vmain(tp);
2381
2382done:
2320 tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO); 2383 tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
2321} 2384}
2322 2385
@@ -2326,15 +2389,17 @@ static void tg3_frob_aux_power(struct tg3 *tp)
2326 2389
2327 /* The GPIOs do something completely different on 57765. */ 2390 /* The GPIOs do something completely different on 57765. */
2328 if (!tg3_flag(tp, IS_NIC) || 2391 if (!tg3_flag(tp, IS_NIC) ||
2329 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
2330 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) 2392 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
2331 return; 2393 return;
2332 2394
2333 if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || 2395 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
2334 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 || 2396 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
2335 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || 2397 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
2336 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) && 2398 tg3_frob_aux_power_5717(tp);
2337 tp->pdev_peer != tp->pdev) { 2399 return;
2400 }
2401
2402 if (tp->pdev_peer && tp->pdev_peer != tp->pdev) {
2338 struct net_device *dev_peer; 2403 struct net_device *dev_peer;
2339 2404
2340 dev_peer = pci_get_drvdata(tp->pdev_peer); 2405 dev_peer = pci_get_drvdata(tp->pdev_peer);
@@ -13692,9 +13757,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
13692 } 13757 }
13693 13758
13694 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || 13759 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
13695 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 || 13760 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)
13696 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
13697 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
13698 tp->pdev_peer = tg3_find_peer(tp); 13761 tp->pdev_peer = tg3_find_peer(tp);
13699 13762
13700 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || 13763 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||