aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/jme.c
diff options
context:
space:
mode:
authorGuo-Fu Tseng <cooldavid@cooldavid.org>2011-02-13 13:27:39 -0500
committerDavid S. Miller <davem@davemloft.net>2011-02-13 23:43:22 -0500
commit854a2e7c331a36244169626ba8e11e15d134cb5f (patch)
treee06c5ec5967eee5d078181b0e3b8958192dfe80f /drivers/net/jme.c
parent3903c023570446303a10f152cfc120dcbf9a4ccf (diff)
jme: Safer MAC processor reset sequence
Adding control to clk_rx, and makes the control of clk_{rx|tx|tcp} with safer sequence. This sequence is provided by JMicron. Signed-off-by: Guo-Fu Tseng <cooldavid@cooldavid.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/jme.c')
-rw-r--r--drivers/net/jme.c152
1 files changed, 117 insertions, 35 deletions
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index 6996d04e1de4..dd4132443b7b 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -161,6 +161,67 @@ jme_setup_wakeup_frame(struct jme_adapter *jme,
161} 161}
162 162
163static inline void 163static inline void
164jme_mac_rxclk_off(struct jme_adapter *jme)
165{
166 jme->reg_gpreg1 |= GPREG1_RXCLKOFF;
167 jwrite32f(jme, JME_GPREG1, jme->reg_gpreg1);
168}
169
170static inline void
171jme_mac_rxclk_on(struct jme_adapter *jme)
172{
173 jme->reg_gpreg1 &= ~GPREG1_RXCLKOFF;
174 jwrite32f(jme, JME_GPREG1, jme->reg_gpreg1);
175}
176
177static inline void
178jme_mac_txclk_off(struct jme_adapter *jme)
179{
180 jme->reg_ghc &= ~(GHC_TO_CLK_SRC | GHC_TXMAC_CLK_SRC);
181 jwrite32f(jme, JME_GHC, jme->reg_ghc);
182}
183
184static inline void
185jme_mac_txclk_on(struct jme_adapter *jme)
186{
187 u32 speed = jme->reg_ghc & GHC_SPEED;
188 if (speed == GHC_SPEED_1000M)
189 jme->reg_ghc |= GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY;
190 else
191 jme->reg_ghc |= GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE;
192 jwrite32f(jme, JME_GHC, jme->reg_ghc);
193}
194
195static inline void
196jme_reset_ghc_speed(struct jme_adapter *jme)
197{
198 jme->reg_ghc &= ~(GHC_SPEED | GHC_DPX);
199 jwrite32f(jme, JME_GHC, jme->reg_ghc);
200}
201
202static inline void
203jme_reset_250A2_workaround(struct jme_adapter *jme)
204{
205 jme->reg_gpreg1 &= ~(GPREG1_HALFMODEPATCH |
206 GPREG1_RSSPATCH);
207 jwrite32(jme, JME_GPREG1, jme->reg_gpreg1);
208}
209
210static inline void
211jme_assert_ghc_reset(struct jme_adapter *jme)
212{
213 jme->reg_ghc |= GHC_SWRST;
214 jwrite32f(jme, JME_GHC, jme->reg_ghc);
215}
216
217static inline void
218jme_clear_ghc_reset(struct jme_adapter *jme)
219{
220 jme->reg_ghc &= ~GHC_SWRST;
221 jwrite32f(jme, JME_GHC, jme->reg_ghc);
222}
223
224static inline void
164jme_reset_mac_processor(struct jme_adapter *jme) 225jme_reset_mac_processor(struct jme_adapter *jme)
165{ 226{
166 static const u32 mask[WAKEUP_FRAME_MASK_DWNR] = {0, 0, 0, 0}; 227 static const u32 mask[WAKEUP_FRAME_MASK_DWNR] = {0, 0, 0, 0};
@@ -168,9 +229,24 @@ jme_reset_mac_processor(struct jme_adapter *jme)
168 u32 gpreg0; 229 u32 gpreg0;
169 int i; 230 int i;
170 231
171 jwrite32(jme, JME_GHC, jme->reg_ghc | GHC_SWRST); 232 jme_reset_ghc_speed(jme);
172 udelay(2); 233 jme_reset_250A2_workaround(jme);
173 jwrite32(jme, JME_GHC, jme->reg_ghc); 234
235 jme_mac_rxclk_on(jme);
236 jme_mac_txclk_on(jme);
237 udelay(1);
238 jme_assert_ghc_reset(jme);
239 udelay(1);
240 jme_mac_rxclk_off(jme);
241 jme_mac_txclk_off(jme);
242 udelay(1);
243 jme_clear_ghc_reset(jme);
244 udelay(1);
245 jme_mac_rxclk_on(jme);
246 jme_mac_txclk_on(jme);
247 udelay(1);
248 jme_mac_rxclk_off(jme);
249 jme_mac_txclk_off(jme);
174 250
175 jwrite32(jme, JME_RXDBA_LO, 0x00000000); 251 jwrite32(jme, JME_RXDBA_LO, 0x00000000);
176 jwrite32(jme, JME_RXDBA_HI, 0x00000000); 252 jwrite32(jme, JME_RXDBA_HI, 0x00000000);
@@ -190,14 +266,6 @@ jme_reset_mac_processor(struct jme_adapter *jme)
190 else 266 else
191 gpreg0 = GPREG0_DEFAULT; 267 gpreg0 = GPREG0_DEFAULT;
192 jwrite32(jme, JME_GPREG0, gpreg0); 268 jwrite32(jme, JME_GPREG0, gpreg0);
193 jwrite32(jme, JME_GPREG1, GPREG1_DEFAULT);
194}
195
196static inline void
197jme_reset_ghc_speed(struct jme_adapter *jme)
198{
199 jme->reg_ghc &= ~(GHC_SPEED_1000M | GHC_DPX);
200 jwrite32(jme, JME_GHC, jme->reg_ghc);
201} 269}
202 270
203static inline void 271static inline void
@@ -351,7 +419,7 @@ static int
351jme_check_link(struct net_device *netdev, int testonly) 419jme_check_link(struct net_device *netdev, int testonly)
352{ 420{
353 struct jme_adapter *jme = netdev_priv(netdev); 421 struct jme_adapter *jme = netdev_priv(netdev);
354 u32 phylink, ghc, cnt = JME_SPDRSV_TIMEOUT, bmcr, gpreg1; 422 u32 phylink, cnt = JME_SPDRSV_TIMEOUT, bmcr;
355 char linkmsg[64]; 423 char linkmsg[64];
356 int rc = 0; 424 int rc = 0;
357 425
@@ -414,23 +482,21 @@ jme_check_link(struct net_device *netdev, int testonly)
414 482
415 jme->phylink = phylink; 483 jme->phylink = phylink;
416 484
417 ghc = jme->reg_ghc & ~(GHC_SPEED | GHC_DPX | 485 /*
418 GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE | 486 * The speed/duplex setting of jme->reg_ghc already cleared
419 GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY); 487 * by jme_reset_mac_processor()
488 */
420 switch (phylink & PHY_LINK_SPEED_MASK) { 489 switch (phylink & PHY_LINK_SPEED_MASK) {
421 case PHY_LINK_SPEED_10M: 490 case PHY_LINK_SPEED_10M:
422 ghc |= GHC_SPEED_10M | 491 jme->reg_ghc |= GHC_SPEED_10M;
423 GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE;
424 strcat(linkmsg, "10 Mbps, "); 492 strcat(linkmsg, "10 Mbps, ");
425 break; 493 break;
426 case PHY_LINK_SPEED_100M: 494 case PHY_LINK_SPEED_100M:
427 ghc |= GHC_SPEED_100M | 495 jme->reg_ghc |= GHC_SPEED_100M;
428 GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE;
429 strcat(linkmsg, "100 Mbps, "); 496 strcat(linkmsg, "100 Mbps, ");
430 break; 497 break;
431 case PHY_LINK_SPEED_1000M: 498 case PHY_LINK_SPEED_1000M:
432 ghc |= GHC_SPEED_1000M | 499 jme->reg_ghc |= GHC_SPEED_1000M;
433 GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY;
434 strcat(linkmsg, "1000 Mbps, "); 500 strcat(linkmsg, "1000 Mbps, ");
435 break; 501 break;
436 default: 502 default:
@@ -440,7 +506,7 @@ jme_check_link(struct net_device *netdev, int testonly)
440 if (phylink & PHY_LINK_DUPLEX) { 506 if (phylink & PHY_LINK_DUPLEX) {
441 jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT); 507 jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT);
442 jwrite32(jme, JME_TXTRHD, TXTRHD_FULLDUPLEX); 508 jwrite32(jme, JME_TXTRHD, TXTRHD_FULLDUPLEX);
443 ghc |= GHC_DPX; 509 jme->reg_ghc |= GHC_DPX;
444 } else { 510 } else {
445 jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT | 511 jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT |
446 TXMCS_BACKOFF | 512 TXMCS_BACKOFF |
@@ -449,18 +515,21 @@ jme_check_link(struct net_device *netdev, int testonly)
449 jwrite32(jme, JME_TXTRHD, TXTRHD_HALFDUPLEX); 515 jwrite32(jme, JME_TXTRHD, TXTRHD_HALFDUPLEX);
450 } 516 }
451 517
452 gpreg1 = GPREG1_DEFAULT; 518 jwrite32(jme, JME_GHC, jme->reg_ghc);
519
453 if (is_buggy250(jme->pdev->device, jme->chiprev)) { 520 if (is_buggy250(jme->pdev->device, jme->chiprev)) {
521 jme->reg_gpreg1 &= ~(GPREG1_HALFMODEPATCH |
522 GPREG1_RSSPATCH);
454 if (!(phylink & PHY_LINK_DUPLEX)) 523 if (!(phylink & PHY_LINK_DUPLEX))
455 gpreg1 |= GPREG1_HALFMODEPATCH; 524 jme->reg_gpreg1 |= GPREG1_HALFMODEPATCH;
456 switch (phylink & PHY_LINK_SPEED_MASK) { 525 switch (phylink & PHY_LINK_SPEED_MASK) {
457 case PHY_LINK_SPEED_10M: 526 case PHY_LINK_SPEED_10M:
458 jme_set_phyfifo_8level(jme); 527 jme_set_phyfifo_8level(jme);
459 gpreg1 |= GPREG1_RSSPATCH; 528 jme->reg_gpreg1 |= GPREG1_RSSPATCH;
460 break; 529 break;
461 case PHY_LINK_SPEED_100M: 530 case PHY_LINK_SPEED_100M:
462 jme_set_phyfifo_5level(jme); 531 jme_set_phyfifo_5level(jme);
463 gpreg1 |= GPREG1_RSSPATCH; 532 jme->reg_gpreg1 |= GPREG1_RSSPATCH;
464 break; 533 break;
465 case PHY_LINK_SPEED_1000M: 534 case PHY_LINK_SPEED_1000M:
466 jme_set_phyfifo_8level(jme); 535 jme_set_phyfifo_8level(jme);
@@ -469,10 +538,7 @@ jme_check_link(struct net_device *netdev, int testonly)
469 break; 538 break;
470 } 539 }
471 } 540 }
472 541 jwrite32(jme, JME_GPREG1, jme->reg_gpreg1);
473 jwrite32(jme, JME_GPREG1, gpreg1);
474 jwrite32(jme, JME_GHC, ghc);
475 jme->reg_ghc = ghc;
476 542
477 strcat(linkmsg, (phylink & PHY_LINK_DUPLEX) ? 543 strcat(linkmsg, (phylink & PHY_LINK_DUPLEX) ?
478 "Full-Duplex, " : 544 "Full-Duplex, " :
@@ -611,10 +677,14 @@ jme_enable_tx_engine(struct jme_adapter *jme)
611 * Enable TX Engine 677 * Enable TX Engine
612 */ 678 */
613 wmb(); 679 wmb();
614 jwrite32(jme, JME_TXCS, jme->reg_txcs | 680 jwrite32f(jme, JME_TXCS, jme->reg_txcs |
615 TXCS_SELECT_QUEUE0 | 681 TXCS_SELECT_QUEUE0 |
616 TXCS_ENABLE); 682 TXCS_ENABLE);
617 683
684 /*
685 * Start clock for TX MAC Processor
686 */
687 jme_mac_txclk_on(jme);
618} 688}
619 689
620static inline void 690static inline void
@@ -649,6 +719,11 @@ jme_disable_tx_engine(struct jme_adapter *jme)
649 719
650 if (!i) 720 if (!i)
651 pr_err("Disable TX engine timeout\n"); 721 pr_err("Disable TX engine timeout\n");
722
723 /*
724 * Stop clock for TX MAC Processor
725 */
726 jme_mac_txclk_off(jme);
652} 727}
653 728
654static void 729static void
@@ -829,10 +904,15 @@ jme_enable_rx_engine(struct jme_adapter *jme)
829 * Enable RX Engine 904 * Enable RX Engine
830 */ 905 */
831 wmb(); 906 wmb();
832 jwrite32(jme, JME_RXCS, jme->reg_rxcs | 907 jwrite32f(jme, JME_RXCS, jme->reg_rxcs |
833 RXCS_QUEUESEL_Q0 | 908 RXCS_QUEUESEL_Q0 |
834 RXCS_ENABLE | 909 RXCS_ENABLE |
835 RXCS_QST); 910 RXCS_QST);
911
912 /*
913 * Start clock for RX MAC Processor
914 */
915 jme_mac_rxclk_on(jme);
836} 916}
837 917
838static inline void 918static inline void
@@ -869,6 +949,10 @@ jme_disable_rx_engine(struct jme_adapter *jme)
869 if (!i) 949 if (!i)
870 pr_err("Disable RX engine timeout\n"); 950 pr_err("Disable RX engine timeout\n");
871 951
952 /*
953 * Stop clock for RX MAC Processor
954 */
955 jme_mac_rxclk_off(jme);
872} 956}
873 957
874static int 958static int
@@ -1205,7 +1289,6 @@ jme_link_change_tasklet(unsigned long arg)
1205 tasklet_disable(&jme->rxempty_task); 1289 tasklet_disable(&jme->rxempty_task);
1206 1290
1207 if (netif_carrier_ok(netdev)) { 1291 if (netif_carrier_ok(netdev)) {
1208 jme_reset_ghc_speed(jme);
1209 jme_disable_rx_engine(jme); 1292 jme_disable_rx_engine(jme);
1210 jme_disable_tx_engine(jme); 1293 jme_disable_tx_engine(jme);
1211 jme_reset_mac_processor(jme); 1294 jme_reset_mac_processor(jme);
@@ -1735,7 +1818,6 @@ jme_close(struct net_device *netdev)
1735 tasklet_disable(&jme->rxclean_task); 1818 tasklet_disable(&jme->rxclean_task);
1736 tasklet_disable(&jme->rxempty_task); 1819 tasklet_disable(&jme->rxempty_task);
1737 1820
1738 jme_reset_ghc_speed(jme);
1739 jme_disable_rx_engine(jme); 1821 jme_disable_rx_engine(jme);
1740 jme_disable_tx_engine(jme); 1822 jme_disable_tx_engine(jme);
1741 jme_reset_mac_processor(jme); 1823 jme_reset_mac_processor(jme);
@@ -2921,6 +3003,7 @@ jme_init_one(struct pci_dev *pdev,
2921 jme->reg_rxmcs = RXMCS_DEFAULT; 3003 jme->reg_rxmcs = RXMCS_DEFAULT;
2922 jme->reg_txpfc = 0; 3004 jme->reg_txpfc = 0;
2923 jme->reg_pmcs = PMCS_MFEN; 3005 jme->reg_pmcs = PMCS_MFEN;
3006 jme->reg_gpreg1 = GPREG1_DEFAULT;
2924 set_bit(JME_FLAG_TXCSUM, &jme->flags); 3007 set_bit(JME_FLAG_TXCSUM, &jme->flags);
2925 set_bit(JME_FLAG_TSO, &jme->flags); 3008 set_bit(JME_FLAG_TSO, &jme->flags);
2926 3009
@@ -3076,7 +3159,6 @@ jme_suspend(struct pci_dev *pdev, pm_message_t state)
3076 jme_polling_mode(jme); 3159 jme_polling_mode(jme);
3077 3160
3078 jme_stop_pcc_timer(jme); 3161 jme_stop_pcc_timer(jme);
3079 jme_reset_ghc_speed(jme);
3080 jme_disable_rx_engine(jme); 3162 jme_disable_rx_engine(jme);
3081 jme_disable_tx_engine(jme); 3163 jme_disable_tx_engine(jme);
3082 jme_reset_mac_processor(jme); 3164 jme_reset_mac_processor(jme);