aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tg3.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2005-12-19 19:27:04 -0500
committerDavid S. Miller <davem@davemloft.net>2005-12-19 19:27:04 -0500
commitb401e9e2ec44a5fc1d8053546276bff584b7118e (patch)
tree3f554445d377269c941688d2ce23479bd198d8a3 /drivers/net/tg3.c
parentdc56b7d46dd2b303a844166ef931270b882bf08c (diff)
[TG3]: Add tw32_wait_f() for some sensitive registers
The tw32_f() function (register write with immediate read flush) can hang when used on some registers to switch clock frequencies and power. A new tw32_wait_f() is added for such registers with the delay before the read and after the read. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r--drivers/net/tg3.c151
1 files changed, 77 insertions, 74 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index de898f175d73..b0d963c83746 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -341,6 +341,16 @@ static struct {
341 { "interrupt test (offline)" }, 341 { "interrupt test (offline)" },
342}; 342};
343 343
344static void tg3_write32(struct tg3 *tp, u32 off, u32 val)
345{
346 writel(val, tp->regs + off);
347}
348
349static u32 tg3_read32(struct tg3 *tp, u32 off)
350{
351 return (readl(tp->regs + off));
352}
353
344static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) 354static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
345{ 355{
346 unsigned long flags; 356 unsigned long flags;
@@ -411,13 +421,29 @@ static u32 tg3_read_indirect_mbox(struct tg3 *tp, u32 off)
411 return val; 421 return val;
412} 422}
413 423
414static void _tw32_flush(struct tg3 *tp, u32 off, u32 val) 424/* usec_wait specifies the wait time in usec when writing to certain registers
425 * where it is unsafe to read back the register without some delay.
426 * GRC_LOCAL_CTRL is one example if the GPIOs are toggled to switch power.
427 * TG3PCI_CLOCK_CTRL is another example if the clock frequencies are changed.
428 */
429static void _tw32_flush(struct tg3 *tp, u32 off, u32 val, u32 usec_wait)
415{ 430{
416 tp->write32(tp, off, val); 431 if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) ||
417 if (!(tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) && 432 (tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))
418 !(tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) && 433 /* Non-posted methods */
419 !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND)) 434 tp->write32(tp, off, val);
420 tp->read32(tp, off); /* flush */ 435 else {
436 /* Posted method */
437 tg3_write32(tp, off, val);
438 if (usec_wait)
439 udelay(usec_wait);
440 tp->read32(tp, off);
441 }
442 /* Wait again after the read for the posted method to guarantee that
443 * the wait time is met.
444 */
445 if (usec_wait)
446 udelay(usec_wait);
421} 447}
422 448
423static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val) 449static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val)
@@ -438,16 +464,6 @@ static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val)
438 readl(mbox); 464 readl(mbox);
439} 465}
440 466
441static void tg3_write32(struct tg3 *tp, u32 off, u32 val)
442{
443 writel(val, tp->regs + off);
444}
445
446static u32 tg3_read32(struct tg3 *tp, u32 off)
447{
448 return (readl(tp->regs + off));
449}
450
451#define tw32_mailbox(reg, val) tp->write32_mbox(tp, reg, val) 467#define tw32_mailbox(reg, val) tp->write32_mbox(tp, reg, val)
452#define tw32_mailbox_f(reg, val) tw32_mailbox_flush(tp, (reg), (val)) 468#define tw32_mailbox_f(reg, val) tw32_mailbox_flush(tp, (reg), (val))
453#define tw32_rx_mbox(reg, val) tp->write32_rx_mbox(tp, reg, val) 469#define tw32_rx_mbox(reg, val) tp->write32_rx_mbox(tp, reg, val)
@@ -455,7 +471,8 @@ static u32 tg3_read32(struct tg3 *tp, u32 off)
455#define tr32_mailbox(reg) tp->read32_mbox(tp, reg) 471#define tr32_mailbox(reg) tp->read32_mbox(tp, reg)
456 472
457#define tw32(reg,val) tp->write32(tp, reg, val) 473#define tw32(reg,val) tp->write32(tp, reg, val)
458#define tw32_f(reg,val) _tw32_flush(tp,(reg),(val)) 474#define tw32_f(reg,val) _tw32_flush(tp,(reg),(val), 0)
475#define tw32_wait_f(reg,val,us) _tw32_flush(tp,(reg),(val), (us))
459#define tr32(reg) tp->read32(tp, reg) 476#define tr32(reg) tp->read32(tp, reg)
460 477
461static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) 478static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
@@ -595,21 +612,19 @@ static void tg3_switch_clocks(struct tg3 *tp)
595 612
596 if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { 613 if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
597 if (orig_clock_ctrl & CLOCK_CTRL_625_CORE) { 614 if (orig_clock_ctrl & CLOCK_CTRL_625_CORE) {
598 tw32_f(TG3PCI_CLOCK_CTRL, 615 tw32_wait_f(TG3PCI_CLOCK_CTRL,
599 clock_ctrl | CLOCK_CTRL_625_CORE); 616 clock_ctrl | CLOCK_CTRL_625_CORE, 40);
600 udelay(40);
601 } 617 }
602 } else if ((orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE) != 0) { 618 } else if ((orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE) != 0) {
603 tw32_f(TG3PCI_CLOCK_CTRL, 619 tw32_wait_f(TG3PCI_CLOCK_CTRL,
604 clock_ctrl | 620 clock_ctrl |
605 (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK)); 621 (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK),
606 udelay(40); 622 40);
607 tw32_f(TG3PCI_CLOCK_CTRL, 623 tw32_wait_f(TG3PCI_CLOCK_CTRL,
608 clock_ctrl | (CLOCK_CTRL_ALTCLK)); 624 clock_ctrl | (CLOCK_CTRL_ALTCLK),
609 udelay(40); 625 40);
610 } 626 }
611 tw32_f(TG3PCI_CLOCK_CTRL, clock_ctrl); 627 tw32_wait_f(TG3PCI_CLOCK_CTRL, clock_ctrl, 40);
612 udelay(40);
613} 628}
614 629
615#define PHY_BUSY_LOOPS 5000 630#define PHY_BUSY_LOOPS 5000
@@ -1033,13 +1048,13 @@ static void tg3_frob_aux_power(struct tg3 *tp)
1033 (tp_peer->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) { 1048 (tp_peer->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) {
1034 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || 1049 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
1035 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { 1050 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
1036 tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | 1051 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
1037 (GRC_LCLCTRL_GPIO_OE0 | 1052 (GRC_LCLCTRL_GPIO_OE0 |
1038 GRC_LCLCTRL_GPIO_OE1 | 1053 GRC_LCLCTRL_GPIO_OE1 |
1039 GRC_LCLCTRL_GPIO_OE2 | 1054 GRC_LCLCTRL_GPIO_OE2 |
1040 GRC_LCLCTRL_GPIO_OUTPUT0 | 1055 GRC_LCLCTRL_GPIO_OUTPUT0 |
1041 GRC_LCLCTRL_GPIO_OUTPUT1)); 1056 GRC_LCLCTRL_GPIO_OUTPUT1),
1042 udelay(100); 1057 100);
1043 } else { 1058 } else {
1044 u32 no_gpio2; 1059 u32 no_gpio2;
1045 u32 grc_local_ctrl = 0; 1060 u32 grc_local_ctrl = 0;
@@ -1052,9 +1067,8 @@ static void tg3_frob_aux_power(struct tg3 *tp)
1052 if (GET_ASIC_REV(tp->pci_chip_rev_id) == 1067 if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
1053 ASIC_REV_5714) { 1068 ASIC_REV_5714) {
1054 grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3; 1069 grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
1055 tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | 1070 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
1056 grc_local_ctrl); 1071 grc_local_ctrl, 100);
1057 udelay(100);
1058 } 1072 }
1059 1073
1060 /* On 5753 and variants, GPIO2 cannot be used. */ 1074 /* On 5753 and variants, GPIO2 cannot be used. */
@@ -1070,21 +1084,18 @@ static void tg3_frob_aux_power(struct tg3 *tp)
1070 grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 | 1084 grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 |
1071 GRC_LCLCTRL_GPIO_OUTPUT2); 1085 GRC_LCLCTRL_GPIO_OUTPUT2);
1072 } 1086 }
1073 tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | 1087 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
1074 grc_local_ctrl); 1088 grc_local_ctrl, 100);
1075 udelay(100);
1076 1089
1077 grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0; 1090 grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0;
1078 1091
1079 tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | 1092 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
1080 grc_local_ctrl); 1093 grc_local_ctrl, 100);
1081 udelay(100);
1082 1094
1083 if (!no_gpio2) { 1095 if (!no_gpio2) {
1084 grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2; 1096 grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2;
1085 tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | 1097 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
1086 grc_local_ctrl); 1098 grc_local_ctrl, 100);
1087 udelay(100);
1088 } 1099 }
1089 } 1100 }
1090 } else { 1101 } else {
@@ -1094,19 +1105,16 @@ static void tg3_frob_aux_power(struct tg3 *tp)
1094 (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0) 1105 (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0)
1095 return; 1106 return;
1096 1107
1097 tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | 1108 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
1098 (GRC_LCLCTRL_GPIO_OE1 | 1109 (GRC_LCLCTRL_GPIO_OE1 |
1099 GRC_LCLCTRL_GPIO_OUTPUT1)); 1110 GRC_LCLCTRL_GPIO_OUTPUT1), 100);
1100 udelay(100);
1101 1111
1102 tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | 1112 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
1103 (GRC_LCLCTRL_GPIO_OE1)); 1113 GRC_LCLCTRL_GPIO_OE1, 100);
1104 udelay(100);
1105 1114
1106 tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | 1115 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
1107 (GRC_LCLCTRL_GPIO_OE1 | 1116 (GRC_LCLCTRL_GPIO_OE1 |
1108 GRC_LCLCTRL_GPIO_OUTPUT1)); 1117 GRC_LCLCTRL_GPIO_OUTPUT1), 100);
1109 udelay(100);
1110 } 1118 }
1111 } 1119 }
1112} 1120}
@@ -1149,10 +1157,8 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
1149 udelay(100); /* Delay after power state change */ 1157 udelay(100); /* Delay after power state change */
1150 1158
1151 /* Switch out of Vaux if it is not a LOM */ 1159 /* Switch out of Vaux if it is not a LOM */
1152 if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT)) { 1160 if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT))
1153 tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); 1161 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100);
1154 udelay(100);
1155 }
1156 1162
1157 return 0; 1163 return 0;
1158 1164
@@ -1251,10 +1257,8 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
1251 base_val |= (CLOCK_CTRL_RXCLK_DISABLE | 1257 base_val |= (CLOCK_CTRL_RXCLK_DISABLE |
1252 CLOCK_CTRL_TXCLK_DISABLE); 1258 CLOCK_CTRL_TXCLK_DISABLE);
1253 1259
1254 tw32_f(TG3PCI_CLOCK_CTRL, base_val | 1260 tw32_wait_f(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK |
1255 CLOCK_CTRL_ALTCLK | 1261 CLOCK_CTRL_PWRDOWN_PLL133, 40);
1256 CLOCK_CTRL_PWRDOWN_PLL133);
1257 udelay(40);
1258 } else if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { 1262 } else if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
1259 /* do nothing */ 1263 /* do nothing */
1260 } else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && 1264 } else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
@@ -1275,11 +1279,11 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
1275 newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE; 1279 newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE;
1276 } 1280 }
1277 1281
1278 tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits1); 1282 tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits1,
1279 udelay(40); 1283 40);
1280 1284
1281 tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2); 1285 tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2,
1282 udelay(40); 1286 40);
1283 1287
1284 if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { 1288 if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
1285 u32 newbits3; 1289 u32 newbits3;
@@ -1293,9 +1297,8 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
1293 newbits3 = CLOCK_CTRL_44MHZ_CORE; 1297 newbits3 = CLOCK_CTRL_44MHZ_CORE;
1294 } 1298 }
1295 1299
1296 tw32_f(TG3PCI_CLOCK_CTRL, 1300 tw32_wait_f(TG3PCI_CLOCK_CTRL,
1297 tp->pci_clock_ctrl | newbits3); 1301 tp->pci_clock_ctrl | newbits3, 40);
1298 udelay(40);
1299 } 1302 }
1300 } 1303 }
1301 1304