Make cxgb3 use request_firmware() for PHY firmware.

Adapt patch by Divy Le Ray <divy@chelsio.com> accepted by David Miller into net-next-2.6.

svn path=/dists/trunk/linux-2.6/; revision=13906
This commit is contained in:
Ben Hutchings 2009-07-08 23:45:44 +00:00
parent 2d897ad123
commit f2fc4fe87b
6 changed files with 293 additions and 119 deletions

2
debian/changelog vendored
View File

@ -14,7 +14,7 @@ linux-2.6 (2.6.31~rc2-1~experimental.1) UNRELEASED; urgency=low
[ Ben Hutchings ]
* mga: remove unnecessary change from firmware-loading patch
* cxgb3: remove PHY firmware
* cxgb3: remove PHY firmware and use request_firmware() to load it
[ Martin Michlmayr ]
* [armel/orion5x, armel/kirkwood] Set GPIO_SYSFS=y since these

View File

@ -0,0 +1,77 @@
From 6eb780fe50039fc81af6aaf8f91a38488a3cdae9 Mon Sep 17 00:00:00 2001
From: Ben Hutchings <ben@decadent.org.uk>
Date: Thu, 9 Jul 2009 00:20:59 +0100
Subject: [PATCH 1/3] cxgb3: Add #ifdef markers around firmware and mark broken
---
drivers/net/Kconfig | 1 +
drivers/net/cxgb3/ael1002.c | 6 ++++++
2 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index c155bd3..183479d 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2511,6 +2511,7 @@ config CHELSIO_T3_DEPENDS
config CHELSIO_T3
tristate "Chelsio Communications T3 10Gb Ethernet support"
+ depends on BROKEN
depends on CHELSIO_T3_DEPENDS
select FW_LOADER
select MDIO
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c
index 9fe008e..d53cec4 100644
--- a/drivers/net/cxgb3/ael1002.c
+++ b/drivers/net/cxgb3/ael1002.c
@@ -304,6 +304,7 @@ static int ael2005_setup_sr_edc(struct cphy *phy)
{ MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5200 },
{ 0, 0, 0, 0 }
};
+#ifdef REMOVE_DFSG
static u16 sr_edc[] = {
0xcc00, 0x2ff4,
0xcc01, 0x3cd4,
@@ -577,6 +578,7 @@ static int ael2005_setup_sr_edc(struct cphy *phy)
0xcd0d, 0x1002,
0xcd0e, 0
};
+#endif /* REMOVE_DFSG */
int i, err;
err = set_phy_regs(phy, regs);
@@ -604,6 +606,7 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
{ MDIO_MMD_PMAPMD, 0xc015, 0xffff, 0xa000 },
{ 0, 0, 0, 0 }
};
+#ifdef REMOVE_DFSG
static u16 twinax_edc[] = {
0xcc00, 0x4009,
0xcc01, 0x27ff,
@@ -972,6 +975,7 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
0xcd6c, 0x1002,
0xcd6d, 0
};
+#endif /* REMOVE_DFSG */
int i, err;
err = set_phy_regs(phy, regs);
@@ -1202,6 +1206,7 @@ static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
{ 0, 0, 0, 0 }
};
+#ifdef REMOVE_DFSG
/* TWINAX EDC firmware */
static u16 twinax_edc[] = {
0xd800, 0x4009,
@@ -1600,6 +1605,7 @@ static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
0xd989, 0x1002,
0xd98a, 0x0000,
};
+#endif /* REMOVE_DFSG */
int i, err;
/* set uC clock and activate it */
--
1.6.3.3

View File

@ -1,117 +0,0 @@
From c8a3b4da329c53ccaa8075344d9fe3bda0a9ae2e Mon Sep 17 00:00:00 2001
From: Ben Hutchings <ben@decadent.org.uk>
Date: Thu, 11 Jun 2009 14:25:05 +0100
Subject: [PATCH] cxgb3: Disable AEL20xx firmware and mark it for removal
---
drivers/net/cxgb3/ael1002.c | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c
index 9fe008e..f94f237 100644
--- a/drivers/net/cxgb3/ael1002.c
+++ b/drivers/net/cxgb3/ael1002.c
@@ -298,12 +298,14 @@ unknown:
*/
static int ael2005_setup_sr_edc(struct cphy *phy)
{
+#if 0
static struct reg_val regs[] = {
{ MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x181 },
{ MDIO_MMD_PMAPMD, 0xc010, 0xffff, 0x448a },
{ MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5200 },
{ 0, 0, 0, 0 }
};
+#ifdef REMOVE_DFSG
static u16 sr_edc[] = {
0xcc00, 0x2ff4,
0xcc01, 0x3cd4,
@@ -577,6 +579,7 @@ static int ael2005_setup_sr_edc(struct cphy *phy)
0xcd0d, 0x1002,
0xcd0e, 0
};
+#endif /* REMOVE_DFSG */
int i, err;
err = set_phy_regs(phy, regs);
@@ -591,10 +594,15 @@ static int ael2005_setup_sr_edc(struct cphy *phy)
if (!err)
phy->priv = edc_sr;
return err;
+#else
+ CH_ERR(phy->adapter, "SR EDC firmware not available\n");
+ return -ENODEV;
+#endif
}
static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
{
+#if 0
static struct reg_val regs[] = {
{ MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5a00 },
{ 0, 0, 0, 0 }
@@ -604,6 +612,7 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
{ MDIO_MMD_PMAPMD, 0xc015, 0xffff, 0xa000 },
{ 0, 0, 0, 0 }
};
+#ifdef REMOVE_DFSG
static u16 twinax_edc[] = {
0xcc00, 0x4009,
0xcc01, 0x27ff,
@@ -972,6 +981,7 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
0xcd6c, 0x1002,
0xcd6d, 0
};
+#endif /* REMOVE_DFSG */
int i, err;
err = set_phy_regs(phy, regs);
@@ -988,6 +998,10 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
if (!err)
phy->priv = edc_twinax;
return err;
+#else
+ CH_ERR(phy->adapter, "TWINAX EDC firmware not available\n");
+ return -ENODEV;
+#endif
}
static int ael2005_get_module_type(struct cphy *phy, int delay_ms)
@@ -1182,6 +1196,7 @@ static int ael2020_setup_sr_edc(struct cphy *phy)
*/
static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
{
+#if 0
/* set uC to 40MHz */
static struct reg_val uCclock40MHz[] = {
{ MDIO_MMD_PMAPMD, 0xff28, 0xffff, 0x4001 },
@@ -1202,6 +1217,7 @@ static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
{ 0, 0, 0, 0 }
};
+#ifdef REMOVE_DFSG
/* TWINAX EDC firmware */
static u16 twinax_edc[] = {
0xd800, 0x4009,
@@ -1600,6 +1616,7 @@ static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
0xd989, 0x1002,
0xd98a, 0x0000,
};
+#endif /* REMOVE_DFSG */
int i, err;
/* set uC clock and activate it */
@@ -1621,6 +1638,10 @@ static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
if (!err)
phy->priv = edc_twinax;
return err;
+#else
+ CH_ERR(phy->adapter, "TWINAX EDC firmware not available\n");
+ return -ENODEV;
+#endif
}
/*
--
1.6.3.1

View File

@ -0,0 +1,213 @@
From 70824840b09935e8df8cc9123f1c09400e00b7b5 Mon Sep 17 00:00:00 2001
From: Ben Hutchings <ben@decadent.org.uk>
Date: Thu, 9 Jul 2009 00:25:04 +0100
Subject: [PATCH 3/3] cxgb3: Use request_firmware() for EDC PHY code
Adapted from work by Divy Le Ray <divy@chelsio.com>.
---
drivers/net/Kconfig | 1 -
drivers/net/cxgb3/adapter.h | 2 +
drivers/net/cxgb3/ael1002.c | 40 +++++++++++++++++------
drivers/net/cxgb3/common.h | 10 ++++++
drivers/net/cxgb3/cxgb3_main.c | 69 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 111 insertions(+), 11 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 183479d..c155bd3 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2511,7 +2511,6 @@ config CHELSIO_T3_DEPENDS
config CHELSIO_T3
tristate "Chelsio Communications T3 10Gb Ethernet support"
- depends on BROKEN
depends on CHELSIO_T3_DEPENDS
select FW_LOADER
select MDIO
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 1694fad..9241c88 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -312,4 +312,6 @@ int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx,
unsigned char *data);
irqreturn_t t3_sge_intr_msix(int irq, void *cookie);
+int t3_get_edc_fw(struct cphy *phy, int edc_idx, int size);
+
#endif /* __T3_ADAPTER_H__ */
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c
index 7b0d445..5a4ff80 100644
--- a/drivers/net/cxgb3/ael1002.c
+++ b/drivers/net/cxgb3/ael1002.c
@@ -312,9 +312,16 @@ static int ael2005_setup_sr_edc(struct cphy *phy)
msleep(50);
- for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2)
- err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, sr_edc[i],
- sr_edc[i + 1]);
+ if (phy->priv != edc_sr)
+ err = t3_get_edc_fw(phy, EDC_OPT_AEL2005,
+ EDC_OPT_AEL2005_SIZE);
+ if (err)
+ return err;
+
+ for (i = 0; i < EDC_OPT_AEL2005_SIZE / sizeof(u16) && !err; i += 2)
+ err = t3_mdio_write(phy, MDIO_MMD_PMAPMD,
+ phy->phy_cache[i],
+ phy->phy_cache[i + 1]);
if (!err)
phy->priv = edc_sr;
return err;
@@ -341,9 +348,16 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
msleep(50);
- for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
- err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i],
- twinax_edc[i + 1]);
+ if (phy->priv != edc_twinax)
+ err = t3_get_edc_fw(phy, EDC_TWX_AEL2005,
+ EDC_TWX_AEL2005_SIZE);
+ if (err)
+ return err;
+
+ for (i = 0; i < EDC_TWX_AEL2005_SIZE / sizeof(u16) && !err; i += 2)
+ err = t3_mdio_write(phy, MDIO_MMD_PMAPMD,
+ phy->phy_cache[i],
+ phy->phy_cache[i + 1]);
if (!err)
phy->priv = edc_twinax;
return err;
@@ -573,10 +587,16 @@ static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
if (err)
return err;
- /* write TWINAX EDC firmware into PHY */
- for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
- err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i],
- twinax_edc[i + 1]);
+ if (phy->priv != edc_twinax)
+ err = t3_get_edc_fw(phy, EDC_TWX_AEL2020,
+ EDC_TWX_AEL2020_SIZE);
+ if (err)
+ return err;
+
+ for (i = 0; i < EDC_TWX_AEL2020_SIZE / sizeof(u16) && !err; i += 2)
+ err = t3_mdio_write(phy, MDIO_MMD_PMAPMD,
+ phy->phy_cache[i],
+ phy->phy_cache[i + 1]);
/* activate uC */
err = set_phy_regs(phy, uCactivate);
if (!err)
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index d21b705..1b2c305 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -566,6 +566,15 @@ struct cphy_ops {
u32 mmds;
};
+enum {
+ EDC_OPT_AEL2005 = 0,
+ EDC_OPT_AEL2005_SIZE = 1084,
+ EDC_TWX_AEL2005 = 1,
+ EDC_TWX_AEL2005_SIZE = 1464,
+ EDC_TWX_AEL2020 = 2,
+ EDC_TWX_AEL2020_SIZE = 1628,
+ EDC_MAX_SIZE = EDC_TWX_AEL2020_SIZE, /* Max cache size */
+};
/* A PHY instance */
struct cphy {
@@ -577,6 +586,7 @@ struct cphy {
unsigned long fifo_errors; /* FIFO over/under-flows */
const struct cphy_ops *ops; /* PHY operations */
struct mdio_if_info mdio;
+ u16 phy_cache[EDC_MAX_SIZE]; /* EDC cache */
};
/* Convenience MDIO read/write wrappers */
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 538dda4..27e7ef5 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -964,6 +964,75 @@ static int bind_qsets(struct adapter *adap)
#define FW_FNAME "cxgb3/t3fw-%d.%d.%d.bin"
#define TPSRAM_NAME "cxgb3/t3%c_psram-%d.%d.%d.bin"
+#define AEL2005_OPT_EDC_NAME "cxgb3/ael2005_opt_edc.bin"
+#define AEL2005_TWX_EDC_NAME "cxgb3/ael2005_twx_edc.bin"
+#define AEL2020_TWX_EDC_NAME "cxgb3/ael2005_twx_edc.bin"
+
+static inline const char *get_edc_fw_name(int edc_idx)
+{
+ const char *fw_name = NULL;
+
+ switch (edc_idx) {
+ case EDC_OPT_AEL2005:
+ fw_name = AEL2005_OPT_EDC_NAME;
+ break;
+ case EDC_TWX_AEL2005:
+ fw_name = AEL2005_TWX_EDC_NAME;
+ break;
+ case EDC_TWX_AEL2020:
+ fw_name = AEL2020_TWX_EDC_NAME;
+ break;
+ }
+ return fw_name;
+}
+
+int t3_get_edc_fw(struct cphy *phy, int edc_idx, int size)
+{
+ struct adapter *adapter = phy->adapter;
+ const struct firmware *fw;
+ char buf[64];
+ u32 csum;
+ const __be32 *p;
+ u16 *cache = phy->phy_cache;
+ int i, ret;
+
+ snprintf(buf, sizeof(buf), get_edc_fw_name(edc_idx));
+
+ ret = request_firmware(&fw, buf, &adapter->pdev->dev);
+ if (ret < 0) {
+ dev_err(&adapter->pdev->dev,
+ "could not upgrade firmware: unable to load %s\n",
+ buf);
+ return ret;
+ }
+
+ /* check size, take checksum in account */
+ if (fw->size > size + 4) {
+ CH_ERR(adapter, "firmware image too large %u, expected %d\n",
+ (unsigned int)fw->size, size + 4);
+ ret = -EINVAL;
+ }
+
+ /* compute checksum */
+ p = (const __be32 *)fw->data;
+ for (csum = 0, i = 0; i < fw->size / sizeof(csum); i++)
+ csum += ntohl(p[i]);
+
+ if (csum != 0xffffffff) {
+ CH_ERR(adapter, "corrupted firmware image, checksum %u\n",
+ csum);
+ ret = -EINVAL;
+ }
+
+ for (i = 0; i < size / 4 ; i++) {
+ *cache++ = (be32_to_cpu(p[i]) & 0xffff0000) >> 16;
+ *cache++ = be32_to_cpu(p[i]) & 0xffff;
+ }
+
+ release_firmware(fw);
+
+ return ret;
+}
static int upgrade_fw(struct adapter *adap)
{
--
1.6.3.3

View File

@ -9,6 +9,7 @@
+ features/all/drivers-gpu-drm-mga-request_firmware.patch
+ features/all/drivers-gpu-drm-r128-request_firmware.patch
+ features/all/drivers-gpu-drm-radeon-request_firmware.patch
+ features/all/drivers-net-cxgb3-request_firmware.patch
# rt2860sta and rt2870sta need ITU-T CRC on bit-reversed data
+ features/all/lib-crcitut-bit-reversed.patch
+ features/all/drivers-staging-rt28x0sta-request_firmware.patch

View File

@ -3,7 +3,7 @@
+ debian/dfsg/drivers-gpu-drm-r128-disable.patch
+ debian/dfsg/drivers-gpu-drm-radeon-disable.patch
+ debian/dfsg/drivers-net-appletalk-cops.patch
+ debian/dfsg/drivers-net-cxgb3.patch
+ debian/dfsg/drivers-net-cxgb3-disable.patch
+ debian/dfsg/drivers-staging-me4000-disable.patch
+ debian/dfsg/drivers-staging-otus-disable.patch
+ debian/dfsg/drivers-staging-rt2860-disable.patch