aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/tg3.c53
-rw-r--r--drivers/net/tg3.h3
2 files changed, 40 insertions, 16 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index e952b91ca2ac..c26011eaa2be 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -1020,15 +1020,43 @@ static void tg3_mdio_fini(struct tg3 *tp)
1020} 1020}
1021 1021
1022/* tp->lock is held. */ 1022/* tp->lock is held. */
1023static inline void tg3_generate_fw_event(struct tg3 *tp)
1024{
1025 u32 val;
1026
1027 val = tr32(GRC_RX_CPU_EVENT);
1028 val |= GRC_RX_CPU_DRIVER_EVENT;
1029 tw32_f(GRC_RX_CPU_EVENT, val);
1030
1031 tp->last_event_jiffies = jiffies;
1032}
1033
1034#define TG3_FW_EVENT_TIMEOUT_USEC 2500
1035
1036/* tp->lock is held. */
1023static void tg3_wait_for_event_ack(struct tg3 *tp) 1037static void tg3_wait_for_event_ack(struct tg3 *tp)
1024{ 1038{
1025 int i; 1039 int i;
1040 unsigned int delay_cnt;
1041 long time_remain;
1042
1043 /* If enough time has passed, no wait is necessary. */
1044 time_remain = (long)(tp->last_event_jiffies + 1 +
1045 usecs_to_jiffies(TG3_FW_EVENT_TIMEOUT_USEC)) -
1046 (long)jiffies;
1047 if (time_remain < 0)
1048 return;
1026 1049
1027 /* Wait for up to 2.5 milliseconds */ 1050 /* Check if we can shorten the wait time. */
1028 for (i = 0; i < 250000; i++) { 1051 delay_cnt = jiffies_to_usecs(time_remain);
1052 if (delay_cnt > TG3_FW_EVENT_TIMEOUT_USEC)
1053 delay_cnt = TG3_FW_EVENT_TIMEOUT_USEC;
1054 delay_cnt = (delay_cnt >> 3) + 1;
1055
1056 for (i = 0; i < delay_cnt; i++) {
1029 if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT)) 1057 if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT))
1030 break; 1058 break;
1031 udelay(10); 1059 udelay(8);
1032 } 1060 }
1033} 1061}
1034 1062
@@ -1077,9 +1105,7 @@ static void tg3_ump_link_report(struct tg3 *tp)
1077 val = 0; 1105 val = 0;
1078 tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val); 1106 tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val);
1079 1107
1080 val = tr32(GRC_RX_CPU_EVENT); 1108 tg3_generate_fw_event(tp);
1081 val |= GRC_RX_CPU_DRIVER_EVENT;
1082 tw32_f(GRC_RX_CPU_EVENT, val);
1083} 1109}
1084 1110
1085static void tg3_link_report(struct tg3 *tp) 1111static void tg3_link_report(struct tg3 *tp)
@@ -5953,6 +5979,7 @@ static int tg3_chip_reset(struct tg3 *tp)
5953 tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg); 5979 tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
5954 if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { 5980 if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
5955 tp->tg3_flags |= TG3_FLAG_ENABLE_ASF; 5981 tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
5982 tp->last_event_jiffies = jiffies;
5956 if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) 5983 if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
5957 tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE; 5984 tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE;
5958 } 5985 }
@@ -5966,15 +5993,12 @@ static void tg3_stop_fw(struct tg3 *tp)
5966{ 5993{
5967 if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && 5994 if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
5968 !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) { 5995 !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
5969 u32 val;
5970
5971 /* Wait for RX cpu to ACK the previous event. */ 5996 /* Wait for RX cpu to ACK the previous event. */
5972 tg3_wait_for_event_ack(tp); 5997 tg3_wait_for_event_ack(tp);
5973 5998
5974 tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW); 5999 tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW);
5975 val = tr32(GRC_RX_CPU_EVENT); 6000
5976 val |= GRC_RX_CPU_DRIVER_EVENT; 6001 tg3_generate_fw_event(tp);
5977 tw32(GRC_RX_CPU_EVENT, val);
5978 6002
5979 /* Wait for RX cpu to ACK this event. */ 6003 /* Wait for RX cpu to ACK this event. */
5980 tg3_wait_for_event_ack(tp); 6004 tg3_wait_for_event_ack(tp);
@@ -7864,8 +7888,6 @@ static void tg3_timer(unsigned long __opaque)
7864 if (!--tp->asf_counter) { 7888 if (!--tp->asf_counter) {
7865 if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && 7889 if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
7866 !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) { 7890 !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
7867 u32 val;
7868
7869 tg3_wait_for_event_ack(tp); 7891 tg3_wait_for_event_ack(tp);
7870 7892
7871 tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, 7893 tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
@@ -7873,9 +7895,8 @@ static void tg3_timer(unsigned long __opaque)
7873 tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); 7895 tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
7874 /* 5 seconds timeout */ 7896 /* 5 seconds timeout */
7875 tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); 7897 tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
7876 val = tr32(GRC_RX_CPU_EVENT); 7898
7877 val |= GRC_RX_CPU_DRIVER_EVENT; 7899 tg3_generate_fw_event(tp);
7878 tw32_f(GRC_RX_CPU_EVENT, val);
7879 } 7900 }
7880 tp->asf_counter = tp->asf_multiplier; 7901 tp->asf_counter = tp->asf_multiplier;
7881 } 7902 }
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 377234947e4f..f5b8cab8d4b5 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2432,7 +2432,10 @@ struct tg3 {
2432 struct tg3_ethtool_stats estats; 2432 struct tg3_ethtool_stats estats;
2433 struct tg3_ethtool_stats estats_prev; 2433 struct tg3_ethtool_stats estats_prev;
2434 2434
2435 union {
2435 unsigned long phy_crc_errors; 2436 unsigned long phy_crc_errors;
2437 unsigned long last_event_jiffies;
2438 };
2436 2439
2437 u32 rx_offset; 2440 u32 rx_offset;
2438 u32 tg3_flags; 2441 u32 tg3_flags;