From: John Feeney <jfeeney@redhat.com> Date: Thu, 30 Sep 2010 21:36:04 -0400 Subject: [net] tg3: display FW version, handle FW events correctly Message-id: <4CA502C4.5050704@redhat.com> Patchwork-id: 28530 O-Subject: [RHEL5.6 PATCH] tg3: Display FW version and handle FW events correctly Bugzilla: 634325 RH-Acked-by: Stanislaw Gruszka <sgruszka@redhat.com> RH-Acked-by: David S. Miller <davem@redhat.com> bz634325 https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=634325 tg3: Incorrect FW version displayed and FW handshake update Description of problem: This actually is two related problems, the firmware version displayed is incorrectly for NCSI tg3 devices (i.e. 5718) and NCSI does not support firmware events. Solution: Basically, the fixes involve checking for NCSI and acting accordingly. Upstream commits: tg3: Detect APE firmware types commit: ecc796486f0a7f4958f8dc7550267570dcacb608 tg3: Don't send APE events for NCSI firmware commit: dc6d074457f1551f9357f773a4eda09a3d5ef150 Brew: Successfully built in Brew for all architectures (task_2785135). Testing: Sanity tested with Connectathon but we don't have a 5718 so could not explicitly check NCSI NIC. Did test a non-NCSI NIC successfully, just in case. Broadcom verified the patched RHEL-5 kernel works properly. Acks would be appreciated. Thanks. Signed-off-by: Jarod Wilson <jarod@redhat.com> diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 65084f0..66bf556 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -6082,6 +6082,10 @@ static void tg3_ape_send_event(struct tg3 *tp, u32 event) int i; u32 apedata; + /* NCSI does not support APE events */ + if (tp->tg3_flags3 & TG3_FLG3_APE_HAS_NCSI) + return; + apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG); if (apedata != APE_SEG_SIG_MAGIC) return; @@ -6133,6 +6137,8 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind) APE_HOST_DRIVER_ID_MAGIC); tg3_ape_write32(tp, TG3_APE_HOST_BEHAVIOR, APE_HOST_BEHAV_NO_PHYLOCK); + tg3_ape_write32(tp, TG3_APE_HOST_DRVR_STATE, + TG3_APE_HOST_DRVR_STATE_START); event = APE_EVENT_STATUS_STATE_START; break; @@ -6144,6 +6150,16 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind) */ tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, 0x0); + if (device_may_wakeup(&tp->pdev->dev) && + (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) { + tg3_ape_write32(tp, TG3_APE_HOST_WOL_SPEED, + TG3_APE_HOST_WOL_SPEED_AUTO); + apedata = TG3_APE_HOST_DRVR_STATE_WOL; + } else + apedata = TG3_APE_HOST_DRVR_STATE_UNLOAD; + + tg3_ape_write32(tp, TG3_APE_HOST_DRVR_STATE, apedata); + event = APE_EVENT_STATUS_STATE_UNLOAD; break; case RESET_KIND_SUSPEND: @@ -12991,6 +13007,7 @@ static void __devinit tg3_read_dash_ver(struct tg3 *tp) { int vlen; u32 apedata; + char *fwtype; if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) || !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) @@ -13006,9 +13023,17 @@ static void __devinit tg3_read_dash_ver(struct tg3 *tp) apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION); + if (tg3_ape_read32(tp, TG3_APE_FW_FEATURES) & TG3_APE_FW_FEATURE_NCSI) { + tp->tg3_flags3 |= TG3_FLG3_APE_HAS_NCSI; + fwtype = "NCSI"; + } else { + fwtype = "DASH"; + } + vlen = strlen(tp->fw_ver); - snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " DASH v%d.%d.%d.%d", + snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " %s v%d.%d.%d.%d", + fwtype, (apedata & APE_FW_VERSION_MAJMSK) >> APE_FW_VERSION_MAJSFT, (apedata & APE_FW_VERSION_MINMSK) >> APE_FW_VERSION_MINSFT, (apedata & APE_FW_VERSION_REVMSK) >> APE_FW_VERSION_REVSFT, diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 2feb72d..a464406 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2229,6 +2229,8 @@ /* APE shared memory. Accessible through BAR1 */ #define TG3_APE_FW_STATUS 0x400c #define APE_FW_STATUS_READY 0x00000100 +#define TG3_APE_FW_FEATURES 0x4010 +#define TG3_APE_FW_FEATURE_NCSI 0x00000002 #define TG3_APE_FW_VERSION 0x4018 #define APE_FW_VERSION_MAJMSK 0xff000000 #define APE_FW_VERSION_MAJSFT 24 @@ -2240,7 +2242,7 @@ #define TG3_APE_HOST_SEG_SIG 0x4200 #define APE_HOST_SEG_SIG_MAGIC 0x484f5354 #define TG3_APE_HOST_SEG_LEN 0x4204 -#define APE_HOST_SEG_LEN_MAGIC 0x0000001c +#define APE_HOST_SEG_LEN_MAGIC 0x00000020 #define TG3_APE_HOST_INIT_COUNT 0x4208 #define TG3_APE_HOST_DRIVER_ID 0x420c #define APE_HOST_DRIVER_ID_MAGIC 0xf0035100 @@ -2250,6 +2252,12 @@ #define APE_HOST_HEARTBEAT_INT_DISABLE 0 #define APE_HOST_HEARTBEAT_INT_5SEC 5000 #define TG3_APE_HOST_HEARTBEAT_COUNT 0x4218 +#define TG3_APE_HOST_DRVR_STATE 0x421c +#define TG3_APE_HOST_DRVR_STATE_START 0x00000001 +#define TG3_APE_HOST_DRVR_STATE_UNLOAD 0x00000002 +#define TG3_APE_HOST_DRVR_STATE_WOL 0x00000003 +#define TG3_APE_HOST_WOL_SPEED 0x4224 +#define TG3_APE_HOST_WOL_SPEED_AUTO 0x00008000 #define TG3_APE_EVENT_STATUS 0x4300 @@ -2966,6 +2974,7 @@ struct tg3 { #define TG3_FLG3_SHORT_DMA_BUG 0x00200000 #define TG3_FLG3_USE_JUMBO_BDFLAG 0x00400000 #define TG3_FLG3_L1PLLPD_EN 0x00800000 +#define TG3_FLG3_APE_HAS_NCSI 0x02000000 struct timer_list timer; u16 timer_counter;