diff --git a/debian/changelog b/debian/changelog index d708c69c8..0bf3d8428 100644 --- a/debian/changelog +++ b/debian/changelog @@ -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 diff --git a/debian/patches/debian/dfsg/drivers-net-cxgb3-disable.patch b/debian/patches/debian/dfsg/drivers-net-cxgb3-disable.patch new file mode 100644 index 000000000..84ee3d520 --- /dev/null +++ b/debian/patches/debian/dfsg/drivers-net-cxgb3-disable.patch @@ -0,0 +1,77 @@ +From 6eb780fe50039fc81af6aaf8f91a38488a3cdae9 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +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 + diff --git a/debian/patches/debian/dfsg/drivers-net-cxgb3.patch b/debian/patches/debian/dfsg/drivers-net-cxgb3.patch deleted file mode 100644 index b832fdbf7..000000000 --- a/debian/patches/debian/dfsg/drivers-net-cxgb3.patch +++ /dev/null @@ -1,117 +0,0 @@ -From c8a3b4da329c53ccaa8075344d9fe3bda0a9ae2e Mon Sep 17 00:00:00 2001 -From: Ben Hutchings -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 - diff --git a/debian/patches/features/all/drivers-net-cxgb3-request_firmware.patch b/debian/patches/features/all/drivers-net-cxgb3-request_firmware.patch new file mode 100644 index 000000000..34202fdcc --- /dev/null +++ b/debian/patches/features/all/drivers-net-cxgb3-request_firmware.patch @@ -0,0 +1,213 @@ +From 70824840b09935e8df8cc9123f1c09400e00b7b5 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +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 . +--- + 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 + diff --git a/debian/patches/series/base b/debian/patches/series/base index 103ed2e30..a63e43908 100644 --- a/debian/patches/series/base +++ b/debian/patches/series/base @@ -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 diff --git a/debian/patches/series/orig-0 b/debian/patches/series/orig-0 index 6cc58cbac..2fb03bf9c 100644 --- a/debian/patches/series/orig-0 +++ b/debian/patches/series/orig-0 @@ -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