* [PATCH net-next-2.6 2/9] jme: PHY Power control for new chip
2011-02-14 4:27 [PATCH net-next-2.6 1/9] jme: Extract main and sub chip revision Guo-Fu Tseng
@ 2011-02-14 4:27 ` Guo-Fu Tseng
2011-02-14 4:44 ` David Miller
2011-02-14 4:27 ` [PATCH net-next-2.6 3/9] jme: Fix bit typo of JMC250A2 workaround Guo-Fu Tseng
` (7 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Guo-Fu Tseng @ 2011-02-14 4:27 UTC (permalink / raw)
To: David Miller
Cc: Guo-Fu Tseng, linux-netdev, Aries Lee, Devinchiu, Ethan Hsiao
From: Guo-Fu Tseng <cooldavid@cooldavid.org>
After main chip rev 5, the hardware support more power saving
control registers.
Some Non-Linux drivers might turn off the phy power with new
interfaces, this patch makes it possible for Linux to turn it
on again.
Signed-off-by: Guo-Fu Tseng <cooldavid@cooldavid.org>
---
drivers/net/jme.c | 68 ++++++++++++++++++++++++++++++++++++++++++-----------
drivers/net/jme.h | 52 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 106 insertions(+), 14 deletions(-)
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index d44716e..d446fdb 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -1577,6 +1577,38 @@ jme_free_irq(struct jme_adapter *jme)
}
static inline void
+jme_new_phy_on(struct jme_adapter *jme)
+{
+ u32 reg;
+
+ reg = jread32(jme, JME_PHY_PWR);
+ reg &= ~(PHY_PWR_DWN1SEL | PHY_PWR_DWN1SW |
+ PHY_PWR_DWN2 | PHY_PWR_CLKSEL);
+ jwrite32(jme, JME_PHY_PWR, reg);
+
+ pci_read_config_dword(jme->pdev, PCI_PRIV_PE1, ®);
+ reg &= ~PE1_GPREG0_PBG;
+ reg |= PE1_GPREG0_ENBG;
+ pci_write_config_dword(jme->pdev, PCI_PRIV_PE1, reg);
+}
+
+static inline void
+jme_new_phy_off(struct jme_adapter *jme)
+{
+ u32 reg;
+
+ reg = jread32(jme, JME_PHY_PWR);
+ reg |= PHY_PWR_DWN1SEL | PHY_PWR_DWN1SW |
+ PHY_PWR_DWN2 | PHY_PWR_CLKSEL;
+ jwrite32(jme, JME_PHY_PWR, reg);
+
+ pci_read_config_dword(jme->pdev, PCI_PRIV_PE1, ®);
+ reg &= ~PE1_GPREG0_PBG;
+ reg |= PE1_GPREG0_PDD3COLD;
+ pci_write_config_dword(jme->pdev, PCI_PRIV_PE1, reg);
+}
+
+static inline void
jme_phy_on(struct jme_adapter *jme)
{
u32 bmcr;
@@ -1584,6 +1616,22 @@ jme_phy_on(struct jme_adapter *jme)
bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR);
bmcr &= ~BMCR_PDOWN;
jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr);
+
+ if (new_phy_power_ctrl(jme->chip_main_rev))
+ jme_new_phy_on(jme);
+}
+
+static inline void
+jme_phy_off(struct jme_adapter *jme)
+{
+ u32 bmcr;
+
+ bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR);
+ bmcr |= BMCR_PDOWN;
+ jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr);
+
+ if (new_phy_power_ctrl(jme->chip_main_rev))
+ jme_new_phy_off(jme);
}
static int
@@ -1606,12 +1654,11 @@ jme_open(struct net_device *netdev)
jme_start_irq(jme);
- if (test_bit(JME_FLAG_SSET, &jme->flags)) {
- jme_phy_on(jme);
+ jme_phy_on(jme);
+ if (test_bit(JME_FLAG_SSET, &jme->flags))
jme_set_settings(netdev, &jme->old_ecmd);
- } else {
+ else
jme_reset_phy_processor(jme);
- }
jme_reset_link(jme);
@@ -1657,12 +1704,6 @@ jme_wait_link(struct jme_adapter *jme)
}
}
-static inline void
-jme_phy_off(struct jme_adapter *jme)
-{
- jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, BMCR_PDOWN);
-}
-
static void
jme_powersave_phy(struct jme_adapter *jme)
{
@@ -3068,12 +3109,11 @@ jme_resume(struct pci_dev *pdev)
jme_clear_pm(jme);
pci_restore_state(pdev);
- if (test_bit(JME_FLAG_SSET, &jme->flags)) {
- jme_phy_on(jme);
+ jme_phy_on(jme);
+ if (test_bit(JME_FLAG_SSET, &jme->flags))
jme_set_settings(netdev, &jme->old_ecmd);
- } else {
+ else
jme_reset_phy_processor(jme);
- }
jme_start_irq(jme);
netif_device_attach(netdev);
diff --git a/drivers/net/jme.h b/drivers/net/jme.h
index 32b2a9d..c3764fc 100644
--- a/drivers/net/jme.h
+++ b/drivers/net/jme.h
@@ -103,6 +103,37 @@ enum jme_spi_op_bits {
#define HALF_US 500 /* 500 ns */
#define JMESPIIOCTL SIOCDEVPRIVATE
+#define PCI_PRIV_PE1 0xE4
+
+enum pci_priv_pe1_bit_masks {
+ PE1_ASPMSUPRT = 0x00000003, /*
+ * RW:
+ * Aspm_support[1:0]
+ * (R/W Port of 5C[11:10])
+ */
+ PE1_MULTIFUN = 0x00000004, /* RW: Multi_fun_bit */
+ PE1_RDYDMA = 0x00000008, /* RO: ~link.rdy_for_dma */
+ PE1_ASPMOPTL = 0x00000030, /* RW: link.rx10s_option[1:0] */
+ PE1_ASPMOPTH = 0x000000C0, /* RW: 10_req=[3]?HW:[2] */
+ PE1_GPREG0 = 0x0000FF00, /*
+ * SRW:
+ * Cfg_gp_reg0
+ * [7:6] phy_giga BG control
+ * [5] CREQ_N as CREQ_N1 (CPPE# as CREQ#)
+ * [4:0] Reserved
+ */
+ PE1_GPREG0_PBG = 0x0000C000, /* phy_giga BG control */
+ PE1_GPREG1 = 0x00FF0000, /* RW: Cfg_gp_reg1 */
+ PE1_REVID = 0xFF000000, /* RO: Rev ID */
+};
+
+enum pci_priv_pe1_values {
+ PE1_GPREG0_ENBG = 0x00000000, /* en BG */
+ PE1_GPREG0_PDD3COLD = 0x00004000, /* giga_PD + d3cold */
+ PE1_GPREG0_PDPCIESD = 0x00008000, /* giga_PD + pcie_shutdown */
+ PE1_GPREG0_PDPCIEIDDQ = 0x0000C000, /* giga_PD + pcie_iddq */
+};
+
/*
* Dynamic(adaptive)/Static PCC values
*/
@@ -499,6 +530,7 @@ enum jme_iomap_regs {
JME_PMCS = JME_MAC | 0x60, /* Power Management Control/Stat */
+ JME_PHY_PWR = JME_PHY | 0x24, /* New PHY Power Ctrl Register */
JME_PHY_CS = JME_PHY | 0x28, /* PHY Ctrl and Status Register */
JME_PHY_LINK = JME_PHY | 0x30, /* PHY Link Status Register */
JME_SMBCSR = JME_PHY | 0x40, /* SMB Control and Status */
@@ -835,6 +867,21 @@ enum jme_pmcs_bit_masks {
};
/*
+ * New PHY Power Control Register
+ */
+enum jme_phy_pwr_bit_masks {
+ PHY_PWR_DWN1SEL = 0x01000000, /* Phy_giga.p_PWR_DOWN1_SEL */
+ PHY_PWR_DWN1SW = 0x02000000, /* Phy_giga.p_PWR_DOWN1_SW */
+ PHY_PWR_DWN2 = 0x04000000, /* Phy_giga.p_PWR_DOWN2 */
+ PHY_PWR_CLKSEL = 0x08000000, /*
+ * XTL_OUT Clock select
+ * (an internal free-running clock)
+ * 0: xtl_out = phy_giga.A_XTL25_O
+ * 1: xtl_out = phy_giga.PD_OSC
+ */
+};
+
+/*
* Giga PHY Status Registers
*/
enum jme_phy_link_bit_mask {
@@ -1191,6 +1238,11 @@ static inline int is_buggy250(unsigned short device, u8 chiprev)
return device == PCI_DEVICE_ID_JMICRON_JMC250 && chiprev == 0x11;
}
+static inline int new_phy_power_ctrl(u8 chip_main_rev)
+{
+ return chip_main_rev >= 5;
+}
+
/*
* Function prototypes
*/
--
1.7.2.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH net-next-2.6 3/9] jme: Fix bit typo of JMC250A2 workaround
2011-02-14 4:27 [PATCH net-next-2.6 1/9] jme: Extract main and sub chip revision Guo-Fu Tseng
2011-02-14 4:27 ` [PATCH net-next-2.6 2/9] jme: PHY Power control for new chip Guo-Fu Tseng
@ 2011-02-14 4:27 ` Guo-Fu Tseng
2011-02-14 4:44 ` David Miller
2011-02-14 4:27 ` [PATCH net-next-2.6 4/9] jme: Rename phyfifo function for easier understand Guo-Fu Tseng
` (6 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Guo-Fu Tseng @ 2011-02-14 4:27 UTC (permalink / raw)
To: David Miller
Cc: Guo-Fu Tseng, linux-netdev, Aries Lee, Devinchiu, Ethan Hsiao
From: Guo-Fu Tseng <cooldavid@cooldavid.org>
Signed-off-by: Guo-Fu Tseng <cooldavid@cooldavid.org>
---
drivers/net/jme.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/jme.h b/drivers/net/jme.h
index c3764fc..dc4af57 100644
--- a/drivers/net/jme.h
+++ b/drivers/net/jme.h
@@ -1000,8 +1000,8 @@ enum jme_gpreg1_masks {
};
enum jme_gpreg1_vals {
- GPREG1_RSSPATCH = 0x00000040,
- GPREG1_HALFMODEPATCH = 0x00000020,
+ GPREG1_HALFMODEPATCH = 0x00000040,
+ GPREG1_RSSPATCH = 0x00000020,
GPREG1_INTDLYUNIT_16NS = 0x00000000,
GPREG1_INTDLYUNIT_256NS = 0x00000008,
--
1.7.2.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH net-next-2.6 4/9] jme: Rename phyfifo function for easier understand
2011-02-14 4:27 [PATCH net-next-2.6 1/9] jme: Extract main and sub chip revision Guo-Fu Tseng
2011-02-14 4:27 ` [PATCH net-next-2.6 2/9] jme: PHY Power control for new chip Guo-Fu Tseng
2011-02-14 4:27 ` [PATCH net-next-2.6 3/9] jme: Fix bit typo of JMC250A2 workaround Guo-Fu Tseng
@ 2011-02-14 4:27 ` Guo-Fu Tseng
2011-02-14 4:44 ` David Miller
2011-02-14 4:27 ` [PATCH net-next-2.6 5/9] jme: Fix hardware action of full-duplex Guo-Fu Tseng
` (5 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Guo-Fu Tseng @ 2011-02-14 4:27 UTC (permalink / raw)
To: David Miller
Cc: Guo-Fu Tseng, linux-netdev, Aries Lee, Devinchiu, Ethan Hsiao
From: Guo-Fu Tseng <cooldavid@cooldavid.org>
Signed-off-by: Guo-Fu Tseng <cooldavid@cooldavid.org>
---
drivers/net/jme.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index d446fdb..490bc0f 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -336,13 +336,13 @@ jme_linkstat_from_phy(struct jme_adapter *jme)
}
static inline void
-jme_set_phyfifoa(struct jme_adapter *jme)
+jme_set_phyfifo_5level(struct jme_adapter *jme)
{
jme_mdio_write(jme->dev, jme->mii_if.phy_id, 27, 0x0004);
}
static inline void
-jme_set_phyfifob(struct jme_adapter *jme)
+jme_set_phyfifo_8level(struct jme_adapter *jme)
{
jme_mdio_write(jme->dev, jme->mii_if.phy_id, 27, 0x0000);
}
@@ -457,15 +457,15 @@ jme_check_link(struct net_device *netdev, int testonly)
gpreg1 |= GPREG1_HALFMODEPATCH;
switch (phylink & PHY_LINK_SPEED_MASK) {
case PHY_LINK_SPEED_10M:
- jme_set_phyfifoa(jme);
+ jme_set_phyfifo_8level(jme);
gpreg1 |= GPREG1_RSSPATCH;
break;
case PHY_LINK_SPEED_100M:
- jme_set_phyfifob(jme);
+ jme_set_phyfifo_5level(jme);
gpreg1 |= GPREG1_RSSPATCH;
break;
case PHY_LINK_SPEED_1000M:
- jme_set_phyfifoa(jme);
+ jme_set_phyfifo_8level(jme);
break;
default:
break;
@@ -2979,7 +2979,7 @@ jme_init_one(struct pci_dev *pdev,
jme->mii_if.mdio_write = jme_mdio_write;
jme_clear_pm(jme);
- jme_set_phyfifoa(jme);
+ jme_set_phyfifo_5level(jme);
pci_read_config_byte(pdev, PCI_REVISION_ID, &jme->pcirev);
if (!jme->fpgaver)
jme_phy_init(jme);
--
1.7.2.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH net-next-2.6 5/9] jme: Fix hardware action of full-duplex
2011-02-14 4:27 [PATCH net-next-2.6 1/9] jme: Extract main and sub chip revision Guo-Fu Tseng
` (2 preceding siblings ...)
2011-02-14 4:27 ` [PATCH net-next-2.6 4/9] jme: Rename phyfifo function for easier understand Guo-Fu Tseng
@ 2011-02-14 4:27 ` Guo-Fu Tseng
2011-02-14 4:44 ` David Miller
2011-02-14 4:27 ` [PATCH net-next-2.6 6/9] jme: Safer MAC processor reset sequence Guo-Fu Tseng
` (4 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Guo-Fu Tseng @ 2011-02-14 4:27 UTC (permalink / raw)
To: David Miller
Cc: Guo-Fu Tseng, linux-netdev, Aries Lee, Devinchiu, Ethan Hsiao
From: Guo-Fu Tseng <cooldavid@cooldavid.org>
Clear Transmit Timer/Retry setting while full-duplex.
Signed-off-by: Guo-Fu Tseng <cooldavid@cooldavid.org>
---
drivers/net/jme.c | 6 ++----
drivers/net/jme.h | 8 ++++++++
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index 490bc0f..6996d04 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -439,16 +439,14 @@ jme_check_link(struct net_device *netdev, int testonly)
if (phylink & PHY_LINK_DUPLEX) {
jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT);
+ jwrite32(jme, JME_TXTRHD, TXTRHD_FULLDUPLEX);
ghc |= GHC_DPX;
} else {
jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT |
TXMCS_BACKOFF |
TXMCS_CARRIERSENSE |
TXMCS_COLLISION);
- jwrite32(jme, JME_TXTRHD, TXTRHD_TXPEN |
- ((0x2000 << TXTRHD_TXP_SHIFT) & TXTRHD_TXP) |
- TXTRHD_TXREN |
- ((8 << TXTRHD_TXRL_SHIFT) & TXTRHD_TXRL));
+ jwrite32(jme, JME_TXTRHD, TXTRHD_HALFDUPLEX);
}
gpreg1 = GPREG1_DEFAULT;
diff --git a/drivers/net/jme.h b/drivers/net/jme.h
index dc4af57..b33bc5b 100644
--- a/drivers/net/jme.h
+++ b/drivers/net/jme.h
@@ -658,6 +658,14 @@ enum jme_txtrhd_shifts {
TXTRHD_TXRL_SHIFT = 0,
};
+enum jme_txtrhd_values {
+ TXTRHD_FULLDUPLEX = 0x00000000,
+ TXTRHD_HALFDUPLEX = TXTRHD_TXPEN |
+ ((0x2000 << TXTRHD_TXP_SHIFT) & TXTRHD_TXP) |
+ TXTRHD_TXREN |
+ ((8 << TXTRHD_TXRL_SHIFT) & TXTRHD_TXRL),
+};
+
/*
* RX Control/Status Bits
*/
--
1.7.2.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH net-next-2.6 6/9] jme: Safer MAC processor reset sequence
2011-02-14 4:27 [PATCH net-next-2.6 1/9] jme: Extract main and sub chip revision Guo-Fu Tseng
` (3 preceding siblings ...)
2011-02-14 4:27 ` [PATCH net-next-2.6 5/9] jme: Fix hardware action of full-duplex Guo-Fu Tseng
@ 2011-02-14 4:27 ` Guo-Fu Tseng
2011-02-14 4:44 ` David Miller
2011-02-14 4:27 ` [PATCH net-next-2.6 7/9] jme: Refill receive unicase MAC addr after resume Guo-Fu Tseng
` (3 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Guo-Fu Tseng @ 2011-02-14 4:27 UTC (permalink / raw)
To: David Miller
Cc: Guo-Fu Tseng, linux-netdev, Aries Lee, Devinchiu, Ethan Hsiao
From: Guo-Fu Tseng <cooldavid@cooldavid.org>
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>
---
drivers/net/jme.c | 152 ++++++++++++++++++++++++++++++++++++++++------------
drivers/net/jme.h | 16 +++---
2 files changed, 126 insertions(+), 42 deletions(-)
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index 6996d04..dd41324 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -161,6 +161,67 @@ jme_setup_wakeup_frame(struct jme_adapter *jme,
}
static inline void
+jme_mac_rxclk_off(struct jme_adapter *jme)
+{
+ jme->reg_gpreg1 |= GPREG1_RXCLKOFF;
+ jwrite32f(jme, JME_GPREG1, jme->reg_gpreg1);
+}
+
+static inline void
+jme_mac_rxclk_on(struct jme_adapter *jme)
+{
+ jme->reg_gpreg1 &= ~GPREG1_RXCLKOFF;
+ jwrite32f(jme, JME_GPREG1, jme->reg_gpreg1);
+}
+
+static inline void
+jme_mac_txclk_off(struct jme_adapter *jme)
+{
+ jme->reg_ghc &= ~(GHC_TO_CLK_SRC | GHC_TXMAC_CLK_SRC);
+ jwrite32f(jme, JME_GHC, jme->reg_ghc);
+}
+
+static inline void
+jme_mac_txclk_on(struct jme_adapter *jme)
+{
+ u32 speed = jme->reg_ghc & GHC_SPEED;
+ if (speed == GHC_SPEED_1000M)
+ jme->reg_ghc |= GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY;
+ else
+ jme->reg_ghc |= GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE;
+ jwrite32f(jme, JME_GHC, jme->reg_ghc);
+}
+
+static inline void
+jme_reset_ghc_speed(struct jme_adapter *jme)
+{
+ jme->reg_ghc &= ~(GHC_SPEED | GHC_DPX);
+ jwrite32f(jme, JME_GHC, jme->reg_ghc);
+}
+
+static inline void
+jme_reset_250A2_workaround(struct jme_adapter *jme)
+{
+ jme->reg_gpreg1 &= ~(GPREG1_HALFMODEPATCH |
+ GPREG1_RSSPATCH);
+ jwrite32(jme, JME_GPREG1, jme->reg_gpreg1);
+}
+
+static inline void
+jme_assert_ghc_reset(struct jme_adapter *jme)
+{
+ jme->reg_ghc |= GHC_SWRST;
+ jwrite32f(jme, JME_GHC, jme->reg_ghc);
+}
+
+static inline void
+jme_clear_ghc_reset(struct jme_adapter *jme)
+{
+ jme->reg_ghc &= ~GHC_SWRST;
+ jwrite32f(jme, JME_GHC, jme->reg_ghc);
+}
+
+static inline void
jme_reset_mac_processor(struct jme_adapter *jme)
{
static const u32 mask[WAKEUP_FRAME_MASK_DWNR] = {0, 0, 0, 0};
@@ -168,9 +229,24 @@ jme_reset_mac_processor(struct jme_adapter *jme)
u32 gpreg0;
int i;
- jwrite32(jme, JME_GHC, jme->reg_ghc | GHC_SWRST);
- udelay(2);
- jwrite32(jme, JME_GHC, jme->reg_ghc);
+ jme_reset_ghc_speed(jme);
+ jme_reset_250A2_workaround(jme);
+
+ jme_mac_rxclk_on(jme);
+ jme_mac_txclk_on(jme);
+ udelay(1);
+ jme_assert_ghc_reset(jme);
+ udelay(1);
+ jme_mac_rxclk_off(jme);
+ jme_mac_txclk_off(jme);
+ udelay(1);
+ jme_clear_ghc_reset(jme);
+ udelay(1);
+ jme_mac_rxclk_on(jme);
+ jme_mac_txclk_on(jme);
+ udelay(1);
+ jme_mac_rxclk_off(jme);
+ jme_mac_txclk_off(jme);
jwrite32(jme, JME_RXDBA_LO, 0x00000000);
jwrite32(jme, JME_RXDBA_HI, 0x00000000);
@@ -190,14 +266,6 @@ jme_reset_mac_processor(struct jme_adapter *jme)
else
gpreg0 = GPREG0_DEFAULT;
jwrite32(jme, JME_GPREG0, gpreg0);
- jwrite32(jme, JME_GPREG1, GPREG1_DEFAULT);
-}
-
-static inline void
-jme_reset_ghc_speed(struct jme_adapter *jme)
-{
- jme->reg_ghc &= ~(GHC_SPEED_1000M | GHC_DPX);
- jwrite32(jme, JME_GHC, jme->reg_ghc);
}
static inline void
@@ -351,7 +419,7 @@ static int
jme_check_link(struct net_device *netdev, int testonly)
{
struct jme_adapter *jme = netdev_priv(netdev);
- u32 phylink, ghc, cnt = JME_SPDRSV_TIMEOUT, bmcr, gpreg1;
+ u32 phylink, cnt = JME_SPDRSV_TIMEOUT, bmcr;
char linkmsg[64];
int rc = 0;
@@ -414,23 +482,21 @@ jme_check_link(struct net_device *netdev, int testonly)
jme->phylink = phylink;
- ghc = jme->reg_ghc & ~(GHC_SPEED | GHC_DPX |
- GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE |
- GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY);
+ /*
+ * The speed/duplex setting of jme->reg_ghc already cleared
+ * by jme_reset_mac_processor()
+ */
switch (phylink & PHY_LINK_SPEED_MASK) {
case PHY_LINK_SPEED_10M:
- ghc |= GHC_SPEED_10M |
- GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE;
+ jme->reg_ghc |= GHC_SPEED_10M;
strcat(linkmsg, "10 Mbps, ");
break;
case PHY_LINK_SPEED_100M:
- ghc |= GHC_SPEED_100M |
- GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE;
+ jme->reg_ghc |= GHC_SPEED_100M;
strcat(linkmsg, "100 Mbps, ");
break;
case PHY_LINK_SPEED_1000M:
- ghc |= GHC_SPEED_1000M |
- GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY;
+ jme->reg_ghc |= GHC_SPEED_1000M;
strcat(linkmsg, "1000 Mbps, ");
break;
default:
@@ -440,7 +506,7 @@ jme_check_link(struct net_device *netdev, int testonly)
if (phylink & PHY_LINK_DUPLEX) {
jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT);
jwrite32(jme, JME_TXTRHD, TXTRHD_FULLDUPLEX);
- ghc |= GHC_DPX;
+ jme->reg_ghc |= GHC_DPX;
} else {
jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT |
TXMCS_BACKOFF |
@@ -449,18 +515,21 @@ jme_check_link(struct net_device *netdev, int testonly)
jwrite32(jme, JME_TXTRHD, TXTRHD_HALFDUPLEX);
}
- gpreg1 = GPREG1_DEFAULT;
+ jwrite32(jme, JME_GHC, jme->reg_ghc);
+
if (is_buggy250(jme->pdev->device, jme->chiprev)) {
+ jme->reg_gpreg1 &= ~(GPREG1_HALFMODEPATCH |
+ GPREG1_RSSPATCH);
if (!(phylink & PHY_LINK_DUPLEX))
- gpreg1 |= GPREG1_HALFMODEPATCH;
+ jme->reg_gpreg1 |= GPREG1_HALFMODEPATCH;
switch (phylink & PHY_LINK_SPEED_MASK) {
case PHY_LINK_SPEED_10M:
jme_set_phyfifo_8level(jme);
- gpreg1 |= GPREG1_RSSPATCH;
+ jme->reg_gpreg1 |= GPREG1_RSSPATCH;
break;
case PHY_LINK_SPEED_100M:
jme_set_phyfifo_5level(jme);
- gpreg1 |= GPREG1_RSSPATCH;
+ jme->reg_gpreg1 |= GPREG1_RSSPATCH;
break;
case PHY_LINK_SPEED_1000M:
jme_set_phyfifo_8level(jme);
@@ -469,10 +538,7 @@ jme_check_link(struct net_device *netdev, int testonly)
break;
}
}
-
- jwrite32(jme, JME_GPREG1, gpreg1);
- jwrite32(jme, JME_GHC, ghc);
- jme->reg_ghc = ghc;
+ jwrite32(jme, JME_GPREG1, jme->reg_gpreg1);
strcat(linkmsg, (phylink & PHY_LINK_DUPLEX) ?
"Full-Duplex, " :
@@ -611,10 +677,14 @@ jme_enable_tx_engine(struct jme_adapter *jme)
* Enable TX Engine
*/
wmb();
- jwrite32(jme, JME_TXCS, jme->reg_txcs |
+ jwrite32f(jme, JME_TXCS, jme->reg_txcs |
TXCS_SELECT_QUEUE0 |
TXCS_ENABLE);
+ /*
+ * Start clock for TX MAC Processor
+ */
+ jme_mac_txclk_on(jme);
}
static inline void
@@ -649,6 +719,11 @@ jme_disable_tx_engine(struct jme_adapter *jme)
if (!i)
pr_err("Disable TX engine timeout\n");
+
+ /*
+ * Stop clock for TX MAC Processor
+ */
+ jme_mac_txclk_off(jme);
}
static void
@@ -829,10 +904,15 @@ jme_enable_rx_engine(struct jme_adapter *jme)
* Enable RX Engine
*/
wmb();
- jwrite32(jme, JME_RXCS, jme->reg_rxcs |
+ jwrite32f(jme, JME_RXCS, jme->reg_rxcs |
RXCS_QUEUESEL_Q0 |
RXCS_ENABLE |
RXCS_QST);
+
+ /*
+ * Start clock for RX MAC Processor
+ */
+ jme_mac_rxclk_on(jme);
}
static inline void
@@ -869,6 +949,10 @@ jme_disable_rx_engine(struct jme_adapter *jme)
if (!i)
pr_err("Disable RX engine timeout\n");
+ /*
+ * Stop clock for RX MAC Processor
+ */
+ jme_mac_rxclk_off(jme);
}
static int
@@ -1205,7 +1289,6 @@ jme_link_change_tasklet(unsigned long arg)
tasklet_disable(&jme->rxempty_task);
if (netif_carrier_ok(netdev)) {
- jme_reset_ghc_speed(jme);
jme_disable_rx_engine(jme);
jme_disable_tx_engine(jme);
jme_reset_mac_processor(jme);
@@ -1735,7 +1818,6 @@ jme_close(struct net_device *netdev)
tasklet_disable(&jme->rxclean_task);
tasklet_disable(&jme->rxempty_task);
- jme_reset_ghc_speed(jme);
jme_disable_rx_engine(jme);
jme_disable_tx_engine(jme);
jme_reset_mac_processor(jme);
@@ -2921,6 +3003,7 @@ jme_init_one(struct pci_dev *pdev,
jme->reg_rxmcs = RXMCS_DEFAULT;
jme->reg_txpfc = 0;
jme->reg_pmcs = PMCS_MFEN;
+ jme->reg_gpreg1 = GPREG1_DEFAULT;
set_bit(JME_FLAG_TXCSUM, &jme->flags);
set_bit(JME_FLAG_TSO, &jme->flags);
@@ -3076,7 +3159,6 @@ jme_suspend(struct pci_dev *pdev, pm_message_t state)
jme_polling_mode(jme);
jme_stop_pcc_timer(jme);
- jme_reset_ghc_speed(jme);
jme_disable_rx_engine(jme);
jme_disable_tx_engine(jme);
jme_reset_mac_processor(jme);
diff --git a/drivers/net/jme.h b/drivers/net/jme.h
index b33bc5b..668958c 100644
--- a/drivers/net/jme.h
+++ b/drivers/net/jme.h
@@ -434,6 +434,7 @@ struct jme_adapter {
u32 reg_rxmcs;
u32 reg_ghc;
u32 reg_pmcs;
+ u32 reg_gpreg1;
u32 phylink;
u32 tx_ring_size;
u32 tx_ring_mask;
@@ -821,6 +822,8 @@ static inline u32 smi_phy_addr(int x)
*/
enum jme_ghc_bit_mask {
GHC_SWRST = 0x40000000,
+ GHC_TO_CLK_SRC = 0x00C00000,
+ GHC_TXMAC_CLK_SRC = 0x00300000,
GHC_DPX = 0x00000040,
GHC_SPEED = 0x00000030,
GHC_LINK_POLL = 0x00000001,
@@ -999,18 +1002,17 @@ enum jme_gpreg0_vals {
/*
* General Purpose REG-1
- * Note: All theses bits defined here are for
- * Chip mode revision 0x11 only
*/
-enum jme_gpreg1_masks {
+enum jme_gpreg1_bit_masks {
+ GPREG1_RXCLKOFF = 0x04000000,
+ GPREG1_PCREQN = 0x00020000,
+ GPREG1_HALFMODEPATCH = 0x00000040, /* For Chip revision 0x11 only */
+ GPREG1_RSSPATCH = 0x00000020, /* For Chip revision 0x11 only */
GPREG1_INTRDELAYUNIT = 0x00000018,
GPREG1_INTRDELAYENABLE = 0x00000007,
};
enum jme_gpreg1_vals {
- GPREG1_HALFMODEPATCH = 0x00000040,
- GPREG1_RSSPATCH = 0x00000020,
-
GPREG1_INTDLYUNIT_16NS = 0x00000000,
GPREG1_INTDLYUNIT_256NS = 0x00000008,
GPREG1_INTDLYUNIT_1US = 0x00000010,
@@ -1024,7 +1026,7 @@ enum jme_gpreg1_vals {
GPREG1_INTDLYEN_6U = 0x00000006,
GPREG1_INTDLYEN_7U = 0x00000007,
- GPREG1_DEFAULT = 0x00000000,
+ GPREG1_DEFAULT = GPREG1_PCREQN,
};
/*
--
1.7.2.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH net-next-2.6 7/9] jme: Refill receive unicase MAC addr after resume
2011-02-14 4:27 [PATCH net-next-2.6 1/9] jme: Extract main and sub chip revision Guo-Fu Tseng
` (4 preceding siblings ...)
2011-02-14 4:27 ` [PATCH net-next-2.6 6/9] jme: Safer MAC processor reset sequence Guo-Fu Tseng
@ 2011-02-14 4:27 ` Guo-Fu Tseng
2011-02-14 4:44 ` David Miller
2011-02-14 4:27 ` [PATCH net-next-2.6 8/9] jme: Don't show UDP Checksum error if HW misjudged Guo-Fu Tseng
` (2 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Guo-Fu Tseng @ 2011-02-14 4:27 UTC (permalink / raw)
To: David Miller
Cc: Guo-Fu Tseng, linux-netdev, Aries Lee, Devinchiu, Ethan Hsiao
From: Guo-Fu Tseng <cooldavid@cooldavid.org>
The value of the register which holds receive Unicast MAC Address
sometimes get messed-up after resume.
This patch refill it before enabling the hardware filter.
Signed-off-by: Guo-Fu Tseng <cooldavid@cooldavid.org>
---
drivers/net/jme.c | 28 ++++++++++++++++++----------
drivers/net/jme.h | 1 +
2 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index dd41324..ed35e17 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -898,6 +898,7 @@ jme_enable_rx_engine(struct jme_adapter *jme)
/*
* Setup Unicast Filter
*/
+ jme_set_unicastaddr(jme->dev);
jme_set_multi(jme->dev);
/*
@@ -2114,27 +2115,34 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
}
+static void
+jme_set_unicastaddr(struct net_device *netdev)
+{
+ struct jme_adapter *jme = netdev_priv(netdev);
+ u32 val;
+
+ val = (netdev->dev_addr[3] & 0xff) << 24 |
+ (netdev->dev_addr[2] & 0xff) << 16 |
+ (netdev->dev_addr[1] & 0xff) << 8 |
+ (netdev->dev_addr[0] & 0xff);
+ jwrite32(jme, JME_RXUMA_LO, val);
+ val = (netdev->dev_addr[5] & 0xff) << 8 |
+ (netdev->dev_addr[4] & 0xff);
+ jwrite32(jme, JME_RXUMA_HI, val);
+}
+
static int
jme_set_macaddr(struct net_device *netdev, void *p)
{
struct jme_adapter *jme = netdev_priv(netdev);
struct sockaddr *addr = p;
- u32 val;
if (netif_running(netdev))
return -EBUSY;
spin_lock_bh(&jme->macaddr_lock);
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-
- val = (addr->sa_data[3] & 0xff) << 24 |
- (addr->sa_data[2] & 0xff) << 16 |
- (addr->sa_data[1] & 0xff) << 8 |
- (addr->sa_data[0] & 0xff);
- jwrite32(jme, JME_RXUMA_LO, val);
- val = (addr->sa_data[5] & 0xff) << 8 |
- (addr->sa_data[4] & 0xff);
- jwrite32(jme, JME_RXUMA_HI, val);
+ jme_set_unicastaddr(netdev);
spin_unlock_bh(&jme->macaddr_lock);
return 0;
diff --git a/drivers/net/jme.h b/drivers/net/jme.h
index 668958c..b7ae0c7 100644
--- a/drivers/net/jme.h
+++ b/drivers/net/jme.h
@@ -1258,6 +1258,7 @@ static inline int new_phy_power_ctrl(u8 chip_main_rev)
*/
static int jme_set_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd);
+static void jme_set_unicastaddr(struct net_device *netdev);
static void jme_set_multi(struct net_device *netdev);
#endif
--
1.7.2.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH net-next-2.6 8/9] jme: Don't show UDP Checksum error if HW misjudged
2011-02-14 4:27 [PATCH net-next-2.6 1/9] jme: Extract main and sub chip revision Guo-Fu Tseng
` (5 preceding siblings ...)
2011-02-14 4:27 ` [PATCH net-next-2.6 7/9] jme: Refill receive unicase MAC addr after resume Guo-Fu Tseng
@ 2011-02-14 4:27 ` Guo-Fu Tseng
2011-02-14 4:43 ` David Miller
2011-02-14 4:27 ` [PATCH net-next-2.6 9/9] jme: Advance driver version Guo-Fu Tseng
2011-02-14 4:44 ` [PATCH net-next-2.6 1/9] jme: Extract main and sub chip revision David Miller
8 siblings, 1 reply; 18+ messages in thread
From: Guo-Fu Tseng @ 2011-02-14 4:27 UTC (permalink / raw)
To: David Miller
Cc: Guo-Fu Tseng, linux-netdev, Aries Lee, Devinchiu, Ethan Hsiao
From: Guo-Fu Tseng <cooldavid@cooldavid.org>
Some JMicron Chip treat 0 as error checksum for UDP packets.
Which should be "No checksum needed".
Reported-by: Adam Swift <Adam.Swift@omnitude.net>
Confirmed-by: "Aries Lee" <arieslee@jmicron.com>
Signed-off-by: Guo-Fu Tseng <cooldavid@cooldavid.org>
---
drivers/net/jme.c | 25 ++++++++++++++++++++++---
1 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index ed35e17..5ced990 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -956,8 +956,27 @@ jme_disable_rx_engine(struct jme_adapter *jme)
jme_mac_rxclk_off(jme);
}
+static u16
+jme_udpsum(struct sk_buff *skb)
+{
+ u16 csum = 0xFFFFu;
+
+ if (skb->protocol != htons(ETH_P_IP))
+ return csum;
+ skb_set_network_header(skb, ETH_HLEN);
+ if (ip_hdr(skb)->protocol != IPPROTO_UDP)
+ return csum;
+ skb_set_transport_header(skb,
+ ETH_HLEN + (ip_hdr(skb)->ihl << 2));
+ csum = udp_hdr(skb)->check;
+ skb_reset_transport_header(skb);
+ skb_reset_network_header(skb);
+
+ return csum;
+}
+
static int
-jme_rxsum_ok(struct jme_adapter *jme, u16 flags)
+jme_rxsum_ok(struct jme_adapter *jme, u16 flags, struct sk_buff *skb)
{
if (!(flags & (RXWBFLAG_TCPON | RXWBFLAG_UDPON | RXWBFLAG_IPV4)))
return false;
@@ -970,7 +989,7 @@ jme_rxsum_ok(struct jme_adapter *jme, u16 flags)
}
if (unlikely((flags & (RXWBFLAG_MF | RXWBFLAG_UDPON | RXWBFLAG_UDPCS))
- == RXWBFLAG_UDPON)) {
+ == RXWBFLAG_UDPON) && jme_udpsum(skb)) {
if (flags & RXWBFLAG_IPV4)
netif_err(jme, rx_err, jme->dev, "UDP Checksum error\n");
return false;
@@ -1018,7 +1037,7 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx)
skb_put(skb, framesize);
skb->protocol = eth_type_trans(skb, jme->dev);
- if (jme_rxsum_ok(jme, le16_to_cpu(rxdesc->descwb.flags)))
+ if (jme_rxsum_ok(jme, le16_to_cpu(rxdesc->descwb.flags), skb))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
skb_checksum_none_assert(skb);
--
1.7.2.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH net-next-2.6 8/9] jme: Don't show UDP Checksum error if HW misjudged
2011-02-14 4:27 ` [PATCH net-next-2.6 8/9] jme: Don't show UDP Checksum error if HW misjudged Guo-Fu Tseng
@ 2011-02-14 4:43 ` David Miller
2011-02-14 5:13 ` Guo-Fu Tseng
0 siblings, 1 reply; 18+ messages in thread
From: David Miller @ 2011-02-14 4:43 UTC (permalink / raw)
To: cooldavid; +Cc: netdev, arieslee, devinchiu, ethanhsiao
From: "Guo-Fu Tseng" <cooldavid@cooldavid.org>
Date: Mon, 14 Feb 2011 12:27:41 +0800
> @@ -956,8 +956,27 @@ jme_disable_rx_engine(struct jme_adapter *jme)
> jme_mac_rxclk_off(jme);
> }
>
> +static u16
> +jme_udpsum(struct sk_buff *skb)
> +{
> + u16 csum = 0xFFFFu;
> +
> + if (skb->protocol != htons(ETH_P_IP))
> + return csum;
> + skb_set_network_header(skb, ETH_HLEN);
> + if (ip_hdr(skb)->protocol != IPPROTO_UDP)
> + return csum;
> + skb_set_transport_header(skb,
> + ETH_HLEN + (ip_hdr(skb)->ihl << 2));
> + csum = udp_hdr(skb)->check;
> + skb_reset_transport_header(skb);
> + skb_reset_network_header(skb);
> +
> + return csum;
> +}
You need to validate the packet length in all of these packet header
accesses, otherwise you're potentially looking at garbage.
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH net-next-2.6 8/9] jme: Don't show UDP Checksum error if HW misjudged
2011-02-14 4:43 ` David Miller
@ 2011-02-14 5:13 ` Guo-Fu Tseng
0 siblings, 0 replies; 18+ messages in thread
From: Guo-Fu Tseng @ 2011-02-14 5:13 UTC (permalink / raw)
To: David Miller; +Cc: netdev, arieslee, devinchiu, ethanhsiao
On Sun, 13 Feb 2011 20:43:00 -0800 (PST), David Miller wrote
> From: "Guo-Fu Tseng" <cooldavid@cooldavid.org>
> Date: Mon, 14 Feb 2011 12:27:41 +0800
>
> > @@ -956,8 +956,27 @@ jme_disable_rx_engine(struct jme_adapter *jme)
> > jme_mac_rxclk_off(jme);
> > }
> >
> > +static u16
> > +jme_udpsum(struct sk_buff *skb)
> > +{
> > + u16 csum = 0xFFFFu;
> > +
> > + if (skb->protocol != htons(ETH_P_IP))
> > + return csum;
> > + skb_set_network_header(skb, ETH_HLEN);
> > + if (ip_hdr(skb)->protocol != IPPROTO_UDP)
> > + return csum;
> > + skb_set_transport_header(skb,
> > + ETH_HLEN + (ip_hdr(skb)->ihl << 2));
> > + csum = udp_hdr(skb)->check;
> > + skb_reset_transport_header(skb);
> > + skb_reset_network_header(skb);
> > +
> > + return csum;
> > +}
>
> You need to validate the packet length in all of these packet header
> accesses, otherwise you're potentially looking at garbage.
Thank you!
Redoing this path, I'll send it later. :)
Guo-Fu Tseng
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH net-next-2.6 9/9] jme: Advance driver version
2011-02-14 4:27 [PATCH net-next-2.6 1/9] jme: Extract main and sub chip revision Guo-Fu Tseng
` (6 preceding siblings ...)
2011-02-14 4:27 ` [PATCH net-next-2.6 8/9] jme: Don't show UDP Checksum error if HW misjudged Guo-Fu Tseng
@ 2011-02-14 4:27 ` Guo-Fu Tseng
2011-02-14 4:44 ` [PATCH net-next-2.6 1/9] jme: Extract main and sub chip revision David Miller
8 siblings, 0 replies; 18+ messages in thread
From: Guo-Fu Tseng @ 2011-02-14 4:27 UTC (permalink / raw)
To: David Miller
Cc: Guo-Fu Tseng, linux-netdev, Aries Lee, Devinchiu, Ethan Hsiao
From: Guo-Fu Tseng <cooldavid@cooldavid.org>
Signed-off-by: Guo-Fu Tseng <cooldavid@cooldavid.org>
---
drivers/net/jme.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/jme.h b/drivers/net/jme.h
index b7ae0c7..8bf3045 100644
--- a/drivers/net/jme.h
+++ b/drivers/net/jme.h
@@ -26,7 +26,7 @@
#define __JME_H_INCLUDED__
#define DRV_NAME "jme"
-#define DRV_VERSION "1.0.7"
+#define DRV_VERSION "1.0.8"
#define PFX DRV_NAME ": "
#define PCI_DEVICE_ID_JMICRON_JMC250 0x0250
--
1.7.2.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH net-next-2.6 1/9] jme: Extract main and sub chip revision
2011-02-14 4:27 [PATCH net-next-2.6 1/9] jme: Extract main and sub chip revision Guo-Fu Tseng
` (7 preceding siblings ...)
2011-02-14 4:27 ` [PATCH net-next-2.6 9/9] jme: Advance driver version Guo-Fu Tseng
@ 2011-02-14 4:44 ` David Miller
8 siblings, 0 replies; 18+ messages in thread
From: David Miller @ 2011-02-14 4:44 UTC (permalink / raw)
To: cooldavid; +Cc: netdev, arieslee, devinchiu, ethanhsiao
From: "Guo-Fu Tseng" <cooldavid@cooldavid.org>
Date: Mon, 14 Feb 2011 12:27:34 +0800
> From: Guo-Fu Tseng <cooldavid@cooldavid.org>
>
> Get the main and sub chip revision for later workaround use.
>
> Signed-off-by: Guo-Fu Tseng <cooldavid@cooldavid.org>
Applied.
^ permalink raw reply [flat|nested] 18+ messages in thread