From: Matt Carlson Date: Mon, 16 Jul 2012 16:24:00 +0000 (+0000) Subject: tg3: Add common function tg3_ape_event_lock() X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=b65a372bbc74924b0ce564a3338d9e139367bd3d;p=openwrt%2Fstaging%2Fblogic.git tg3: Add common function tg3_ape_event_lock() by refactoring code in tg3_ape_send_event(). The common function will be used in subsequent patches. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 45dc6f5c52cf..5dda3ced90e1 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -731,44 +731,52 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum) tg3_ape_write32(tp, gnt + 4 * locknum, bit); } -static void tg3_ape_send_event(struct tg3 *tp, u32 event) +static int tg3_ape_event_lock(struct tg3 *tp, u32 timeout_us) { - int i; u32 apedata; - /* NCSI does not support APE events */ - if (tg3_flag(tp, APE_HAS_NCSI)) - return; + while (timeout_us) { + if (tg3_ape_lock(tp, TG3_APE_LOCK_MEM)) + return -EBUSY; + + apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS); + if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING)) + break; + + tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); + + udelay(10); + timeout_us -= (timeout_us > 10) ? 10 : timeout_us; + } + + return timeout_us ? 0 : -EBUSY; +} + +static int tg3_ape_send_event(struct tg3 *tp, u32 event) +{ + int err; + u32 apedata; apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG); if (apedata != APE_SEG_SIG_MAGIC) - return; + return -EAGAIN; apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS); if (!(apedata & APE_FW_STATUS_READY)) - return; + return -EAGAIN; /* Wait for up to 1 millisecond for APE to service previous event. */ - for (i = 0; i < 10; i++) { - if (tg3_ape_lock(tp, TG3_APE_LOCK_MEM)) - return; - - apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS); - - if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING)) - tg3_ape_write32(tp, TG3_APE_EVENT_STATUS, - event | APE_EVENT_STATUS_EVENT_PENDING); + err = tg3_ape_event_lock(tp, 1000); + if (err) + return err; - tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); + tg3_ape_write32(tp, TG3_APE_EVENT_STATUS, + event | APE_EVENT_STATUS_EVENT_PENDING); - if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING)) - break; + tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); + tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1); - udelay(100); - } - - if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING)) - tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1); + return 0; } static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)