diff options
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 53 |
1 files changed, 37 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. */ |
1023 | static 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. */ | ||
1023 | static void tg3_wait_for_event_ack(struct tg3 *tp) | 1037 | static 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 | ||
1085 | static void tg3_link_report(struct tg3 *tp) | 1111 | static 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 | } |