]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.drivers/cxgb3-Support-for-Aeluros-2005-PHY
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / cxgb3-Support-for-Aeluros-2005-PHY
diff --git a/src/patches/suse-2.6.27.31/patches.drivers/cxgb3-Support-for-Aeluros-2005-PHY b/src/patches/suse-2.6.27.31/patches.drivers/cxgb3-Support-for-Aeluros-2005-PHY
new file mode 100644 (file)
index 0000000..e962fc4
--- /dev/null
@@ -0,0 +1,1183 @@
+Commit-Id: 1e8820256f9921370cd7423396871e2d850e0323
+From: Divy Le Ray <divy@chelsio.com>
+Date: Wed, 8 Oct 2008 17:40:07 -0700
+Acked-by: Karsten Keil <kkeil@novell.com>
+Subject: [PATCH] cxgb3: Support for Aeluros 2005 PHY
+Reference: bnc#446739
+
+
+Add support for SR PHY.
+Auto-detect phy module type, and report type changes.
+
+Signed-off-by: Divy Le Ray <divy@chelsio.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+
+Index: linux-2.6.27/drivers/net/cxgb3/ael1002.c
+===================================================================
+--- linux-2.6.27.orig/drivers/net/cxgb3/ael1002.c
++++ linux-2.6.27/drivers/net/cxgb3/ael1002.c
+@@ -33,14 +33,57 @@
+ #include "regs.h"
+ enum {
++      PMD_RSD     = 10,   /* PMA/PMD receive signal detect register */
++      PCS_STAT1_X = 24,   /* 10GBASE-X PCS status 1 register */
++      PCS_STAT1_R = 32,   /* 10GBASE-R PCS status 1 register */
++      XS_LN_STAT  = 24    /* XS lane status register */
++};
++
++enum {
+       AEL100X_TX_DISABLE = 9,
+       AEL100X_TX_CONFIG1 = 0xc002,
+       AEL1002_PWR_DOWN_HI = 0xc011,
+       AEL1002_PWR_DOWN_LO = 0xc012,
+       AEL1002_XFI_EQL = 0xc015,
+       AEL1002_LB_EN = 0xc017,
++      AEL_OPT_SETTINGS = 0xc017,
++      AEL_I2C_CTRL = 0xc30a,
++      AEL_I2C_DATA = 0xc30b,
++      AEL_I2C_STAT = 0xc30c,
++      AEL2005_GPIO_CTRL = 0xc214,
++      AEL2005_GPIO_STAT = 0xc215,
+ };
++enum { edc_none, edc_sr, edc_twinax };
++
++/* PHY module I2C device address */
++#define MODULE_DEV_ADDR 0xa0
++
++#define AEL2005_MODDET_IRQ 4
++
++struct reg_val {
++      unsigned short mmd_addr;
++      unsigned short reg_addr;
++      unsigned short clear_bits;
++      unsigned short set_bits;
++};
++
++static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
++{
++      int err;
++
++      for (err = 0; rv->mmd_addr && !err; rv++) {
++              if (rv->clear_bits == 0xffff)
++                      err = mdio_write(phy, rv->mmd_addr, rv->reg_addr,
++                                       rv->set_bits);
++              else
++                      err = t3_mdio_change_bits(phy, rv->mmd_addr,
++                                                rv->reg_addr, rv->clear_bits,
++                                                rv->set_bits);
++      }
++      return err;
++}
++
+ static void ael100x_txon(struct cphy *phy)
+ {
+       int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
+@@ -81,23 +124,23 @@ static int ael1002_intr_noop(struct cphy
+       return 0;
+ }
+-static int ael100x_get_link_status(struct cphy *phy, int *link_ok,
+-                                 int *speed, int *duplex, int *fc)
++/*
++ * Get link status for a 10GBASE-R device.
++ */
++static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed,
++                           int *duplex, int *fc)
+ {
+       if (link_ok) {
+-              unsigned int status;
+-              int err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &status);
++              unsigned int stat0, stat1, stat2;
++              int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
+-              /*
+-               * BMSR_LSTATUS is latch-low, so if it is 0 we need to read it
+-               * once more to get the current link state.
+-               */
+-              if (!err && !(status & BMSR_LSTATUS))
+-                      err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR,
+-                                      &status);
++              if (!err)
++                      err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1);
++              if (!err)
++                      err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
+               if (err)
+                       return err;
+-              *link_ok = !!(status & BMSR_LSTATUS);
++              *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1;
+       }
+       if (speed)
+               *speed = SPEED_10000;
+@@ -112,7 +155,7 @@ static struct cphy_ops ael1002_ops = {
+       .intr_disable = ael1002_intr_noop,
+       .intr_clear = ael1002_intr_noop,
+       .intr_handler = ael1002_intr_noop,
+-      .get_link_status = ael100x_get_link_status,
++      .get_link_status = get_link_status_r,
+       .power_down = ael1002_power_down,
+ };
+@@ -143,7 +186,7 @@ static struct cphy_ops ael1006_ops = {
+       .intr_disable = t3_phy_lasi_intr_disable,
+       .intr_clear = t3_phy_lasi_intr_clear,
+       .intr_handler = t3_phy_lasi_intr_handler,
+-      .get_link_status = ael100x_get_link_status,
++      .get_link_status = get_link_status_r,
+       .power_down = ael1006_power_down,
+ };
+@@ -157,13 +200,948 @@ int t3_ael1006_phy_prep(struct cphy *phy
+       return 0;
+ }
++static int ael2005_setup_sr_edc(struct cphy *phy)
++{
++      static struct reg_val regs[] = {
++              { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 },
++              { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a },
++              { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 },
++              { 0, 0, 0, 0 }
++      };
++      static u16 sr_edc[] = {
++              0xcc00, 0x2ff4,
++              0xcc01, 0x3cd4,
++              0xcc02, 0x2015,
++              0xcc03, 0x3105,
++              0xcc04, 0x6524,
++              0xcc05, 0x27ff,
++              0xcc06, 0x300f,
++              0xcc07, 0x2c8b,
++              0xcc08, 0x300b,
++              0xcc09, 0x4009,
++              0xcc0a, 0x400e,
++              0xcc0b, 0x2f72,
++              0xcc0c, 0x3002,
++              0xcc0d, 0x1002,
++              0xcc0e, 0x2172,
++              0xcc0f, 0x3012,
++              0xcc10, 0x1002,
++              0xcc11, 0x25d2,
++              0xcc12, 0x3012,
++              0xcc13, 0x1002,
++              0xcc14, 0xd01e,
++              0xcc15, 0x27d2,
++              0xcc16, 0x3012,
++              0xcc17, 0x1002,
++              0xcc18, 0x2004,
++              0xcc19, 0x3c84,
++              0xcc1a, 0x6436,
++              0xcc1b, 0x2007,
++              0xcc1c, 0x3f87,
++              0xcc1d, 0x8676,
++              0xcc1e, 0x40b7,
++              0xcc1f, 0xa746,
++              0xcc20, 0x4047,
++              0xcc21, 0x5673,
++              0xcc22, 0x2982,
++              0xcc23, 0x3002,
++              0xcc24, 0x13d2,
++              0xcc25, 0x8bbd,
++              0xcc26, 0x2862,
++              0xcc27, 0x3012,
++              0xcc28, 0x1002,
++              0xcc29, 0x2092,
++              0xcc2a, 0x3012,
++              0xcc2b, 0x1002,
++              0xcc2c, 0x5cc3,
++              0xcc2d, 0x314,
++              0xcc2e, 0x2942,
++              0xcc2f, 0x3002,
++              0xcc30, 0x1002,
++              0xcc31, 0xd019,
++              0xcc32, 0x2032,
++              0xcc33, 0x3012,
++              0xcc34, 0x1002,
++              0xcc35, 0x2a04,
++              0xcc36, 0x3c74,
++              0xcc37, 0x6435,
++              0xcc38, 0x2fa4,
++              0xcc39, 0x3cd4,
++              0xcc3a, 0x6624,
++              0xcc3b, 0x5563,
++              0xcc3c, 0x2d42,
++              0xcc3d, 0x3002,
++              0xcc3e, 0x13d2,
++              0xcc3f, 0x464d,
++              0xcc40, 0x2862,
++              0xcc41, 0x3012,
++              0xcc42, 0x1002,
++              0xcc43, 0x2032,
++              0xcc44, 0x3012,
++              0xcc45, 0x1002,
++              0xcc46, 0x2fb4,
++              0xcc47, 0x3cd4,
++              0xcc48, 0x6624,
++              0xcc49, 0x5563,
++              0xcc4a, 0x2d42,
++              0xcc4b, 0x3002,
++              0xcc4c, 0x13d2,
++              0xcc4d, 0x2ed2,
++              0xcc4e, 0x3002,
++              0xcc4f, 0x1002,
++              0xcc50, 0x2fd2,
++              0xcc51, 0x3002,
++              0xcc52, 0x1002,
++              0xcc53, 0x004,
++              0xcc54, 0x2942,
++              0xcc55, 0x3002,
++              0xcc56, 0x1002,
++              0xcc57, 0x2092,
++              0xcc58, 0x3012,
++              0xcc59, 0x1002,
++              0xcc5a, 0x5cc3,
++              0xcc5b, 0x317,
++              0xcc5c, 0x2f72,
++              0xcc5d, 0x3002,
++              0xcc5e, 0x1002,
++              0xcc5f, 0x2942,
++              0xcc60, 0x3002,
++              0xcc61, 0x1002,
++              0xcc62, 0x22cd,
++              0xcc63, 0x301d,
++              0xcc64, 0x2862,
++              0xcc65, 0x3012,
++              0xcc66, 0x1002,
++              0xcc67, 0x2ed2,
++              0xcc68, 0x3002,
++              0xcc69, 0x1002,
++              0xcc6a, 0x2d72,
++              0xcc6b, 0x3002,
++              0xcc6c, 0x1002,
++              0xcc6d, 0x628f,
++              0xcc6e, 0x2112,
++              0xcc6f, 0x3012,
++              0xcc70, 0x1002,
++              0xcc71, 0x5aa3,
++              0xcc72, 0x2dc2,
++              0xcc73, 0x3002,
++              0xcc74, 0x1312,
++              0xcc75, 0x6f72,
++              0xcc76, 0x1002,
++              0xcc77, 0x2807,
++              0xcc78, 0x31a7,
++              0xcc79, 0x20c4,
++              0xcc7a, 0x3c24,
++              0xcc7b, 0x6724,
++              0xcc7c, 0x1002,
++              0xcc7d, 0x2807,
++              0xcc7e, 0x3187,
++              0xcc7f, 0x20c4,
++              0xcc80, 0x3c24,
++              0xcc81, 0x6724,
++              0xcc82, 0x1002,
++              0xcc83, 0x2514,
++              0xcc84, 0x3c64,
++              0xcc85, 0x6436,
++              0xcc86, 0xdff4,
++              0xcc87, 0x6436,
++              0xcc88, 0x1002,
++              0xcc89, 0x40a4,
++              0xcc8a, 0x643c,
++              0xcc8b, 0x4016,
++              0xcc8c, 0x8c6c,
++              0xcc8d, 0x2b24,
++              0xcc8e, 0x3c24,
++              0xcc8f, 0x6435,
++              0xcc90, 0x1002,
++              0xcc91, 0x2b24,
++              0xcc92, 0x3c24,
++              0xcc93, 0x643a,
++              0xcc94, 0x4025,
++              0xcc95, 0x8a5a,
++              0xcc96, 0x1002,
++              0xcc97, 0x2731,
++              0xcc98, 0x3011,
++              0xcc99, 0x1001,
++              0xcc9a, 0xc7a0,
++              0xcc9b, 0x100,
++              0xcc9c, 0xc502,
++              0xcc9d, 0x53ac,
++              0xcc9e, 0xc503,
++              0xcc9f, 0xd5d5,
++              0xcca0, 0xc600,
++              0xcca1, 0x2a6d,
++              0xcca2, 0xc601,
++              0xcca3, 0x2a4c,
++              0xcca4, 0xc602,
++              0xcca5, 0x111,
++              0xcca6, 0xc60c,
++              0xcca7, 0x5900,
++              0xcca8, 0xc710,
++              0xcca9, 0x700,
++              0xccaa, 0xc718,
++              0xccab, 0x700,
++              0xccac, 0xc720,
++              0xccad, 0x4700,
++              0xccae, 0xc801,
++              0xccaf, 0x7f50,
++              0xccb0, 0xc802,
++              0xccb1, 0x7760,
++              0xccb2, 0xc803,
++              0xccb3, 0x7fce,
++              0xccb4, 0xc804,
++              0xccb5, 0x5700,
++              0xccb6, 0xc805,
++              0xccb7, 0x5f11,
++              0xccb8, 0xc806,
++              0xccb9, 0x4751,
++              0xccba, 0xc807,
++              0xccbb, 0x57e1,
++              0xccbc, 0xc808,
++              0xccbd, 0x2700,
++              0xccbe, 0xc809,
++              0xccbf, 0x000,
++              0xccc0, 0xc821,
++              0xccc1, 0x002,
++              0xccc2, 0xc822,
++              0xccc3, 0x014,
++              0xccc4, 0xc832,
++              0xccc5, 0x1186,
++              0xccc6, 0xc847,
++              0xccc7, 0x1e02,
++              0xccc8, 0xc013,
++              0xccc9, 0xf341,
++              0xccca, 0xc01a,
++              0xcccb, 0x446,
++              0xcccc, 0xc024,
++              0xcccd, 0x1000,
++              0xccce, 0xc025,
++              0xcccf, 0xa00,
++              0xccd0, 0xc026,
++              0xccd1, 0xc0c,
++              0xccd2, 0xc027,
++              0xccd3, 0xc0c,
++              0xccd4, 0xc029,
++              0xccd5, 0x0a0,
++              0xccd6, 0xc030,
++              0xccd7, 0xa00,
++              0xccd8, 0xc03c,
++              0xccd9, 0x01c,
++              0xccda, 0xc005,
++              0xccdb, 0x7a06,
++              0xccdc, 0x000,
++              0xccdd, 0x2731,
++              0xccde, 0x3011,
++              0xccdf, 0x1001,
++              0xcce0, 0xc620,
++              0xcce1, 0x000,
++              0xcce2, 0xc621,
++              0xcce3, 0x03f,
++              0xcce4, 0xc622,
++              0xcce5, 0x000,
++              0xcce6, 0xc623,
++              0xcce7, 0x000,
++              0xcce8, 0xc624,
++              0xcce9, 0x000,
++              0xccea, 0xc625,
++              0xcceb, 0x000,
++              0xccec, 0xc627,
++              0xcced, 0x000,
++              0xccee, 0xc628,
++              0xccef, 0x000,
++              0xccf0, 0xc62c,
++              0xccf1, 0x000,
++              0xccf2, 0x000,
++              0xccf3, 0x2806,
++              0xccf4, 0x3cb6,
++              0xccf5, 0xc161,
++              0xccf6, 0x6134,
++              0xccf7, 0x6135,
++              0xccf8, 0x5443,
++              0xccf9, 0x303,
++              0xccfa, 0x6524,
++              0xccfb, 0x00b,
++              0xccfc, 0x1002,
++              0xccfd, 0x2104,
++              0xccfe, 0x3c24,
++              0xccff, 0x2105,
++              0xcd00, 0x3805,
++              0xcd01, 0x6524,
++              0xcd02, 0xdff4,
++              0xcd03, 0x4005,
++              0xcd04, 0x6524,
++              0xcd05, 0x1002,
++              0xcd06, 0x5dd3,
++              0xcd07, 0x306,
++              0xcd08, 0x2ff7,
++              0xcd09, 0x38f7,
++              0xcd0a, 0x60b7,
++              0xcd0b, 0xdffd,
++              0xcd0c, 0x00a,
++              0xcd0d, 0x1002,
++              0xcd0e, 0
++      };
++      int i, err;
++
++      err = set_phy_regs(phy, regs);
++      if (err)
++              return err;
++
++      msleep(50);
++
++      for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2)
++              err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i],
++                               sr_edc[i + 1]);
++      if (!err)
++              phy->priv = edc_sr;
++      return err;
++}
++
++static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
++{
++      static struct reg_val regs[] = {
++              { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 },
++              { 0, 0, 0, 0 }
++      };
++      static struct reg_val preemphasis[] = {
++              { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 },
++              { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 },
++              { 0, 0, 0, 0 }
++      };
++      static u16 twinax_edc[] = {
++              0xcc00, 0x4009,
++              0xcc01, 0x27ff,
++              0xcc02, 0x300f,
++              0xcc03, 0x40aa,
++              0xcc04, 0x401c,
++              0xcc05, 0x401e,
++              0xcc06, 0x2ff4,
++              0xcc07, 0x3cd4,
++              0xcc08, 0x2035,
++              0xcc09, 0x3145,
++              0xcc0a, 0x6524,
++              0xcc0b, 0x26a2,
++              0xcc0c, 0x3012,
++              0xcc0d, 0x1002,
++              0xcc0e, 0x29c2,
++              0xcc0f, 0x3002,
++              0xcc10, 0x1002,
++              0xcc11, 0x2072,
++              0xcc12, 0x3012,
++              0xcc13, 0x1002,
++              0xcc14, 0x22cd,
++              0xcc15, 0x301d,
++              0xcc16, 0x2e52,
++              0xcc17, 0x3012,
++              0xcc18, 0x1002,
++              0xcc19, 0x28e2,
++              0xcc1a, 0x3002,
++              0xcc1b, 0x1002,
++              0xcc1c, 0x628f,
++              0xcc1d, 0x2ac2,
++              0xcc1e, 0x3012,
++              0xcc1f, 0x1002,
++              0xcc20, 0x5553,
++              0xcc21, 0x2ae2,
++              0xcc22, 0x3002,
++              0xcc23, 0x1302,
++              0xcc24, 0x401e,
++              0xcc25, 0x2be2,
++              0xcc26, 0x3012,
++              0xcc27, 0x1002,
++              0xcc28, 0x2da2,
++              0xcc29, 0x3012,
++              0xcc2a, 0x1002,
++              0xcc2b, 0x2ba2,
++              0xcc2c, 0x3002,
++              0xcc2d, 0x1002,
++              0xcc2e, 0x5ee3,
++              0xcc2f, 0x305,
++              0xcc30, 0x400e,
++              0xcc31, 0x2bc2,
++              0xcc32, 0x3002,
++              0xcc33, 0x1002,
++              0xcc34, 0x2b82,
++              0xcc35, 0x3012,
++              0xcc36, 0x1002,
++              0xcc37, 0x5663,
++              0xcc38, 0x302,
++              0xcc39, 0x401e,
++              0xcc3a, 0x6f72,
++              0xcc3b, 0x1002,
++              0xcc3c, 0x628f,
++              0xcc3d, 0x2be2,
++              0xcc3e, 0x3012,
++              0xcc3f, 0x1002,
++              0xcc40, 0x22cd,
++              0xcc41, 0x301d,
++              0xcc42, 0x2e52,
++              0xcc43, 0x3012,
++              0xcc44, 0x1002,
++              0xcc45, 0x2522,
++              0xcc46, 0x3012,
++              0xcc47, 0x1002,
++              0xcc48, 0x2da2,
++              0xcc49, 0x3012,
++              0xcc4a, 0x1002,
++              0xcc4b, 0x2ca2,
++              0xcc4c, 0x3012,
++              0xcc4d, 0x1002,
++              0xcc4e, 0x2fa4,
++              0xcc4f, 0x3cd4,
++              0xcc50, 0x6624,
++              0xcc51, 0x410b,
++              0xcc52, 0x56b3,
++              0xcc53, 0x3c4,
++              0xcc54, 0x2fb2,
++              0xcc55, 0x3002,
++              0xcc56, 0x1002,
++              0xcc57, 0x220b,
++              0xcc58, 0x303b,
++              0xcc59, 0x56b3,
++              0xcc5a, 0x3c3,
++              0xcc5b, 0x866b,
++              0xcc5c, 0x400c,
++              0xcc5d, 0x23a2,
++              0xcc5e, 0x3012,
++              0xcc5f, 0x1002,
++              0xcc60, 0x2da2,
++              0xcc61, 0x3012,
++              0xcc62, 0x1002,
++              0xcc63, 0x2ca2,
++              0xcc64, 0x3012,
++              0xcc65, 0x1002,
++              0xcc66, 0x2fb4,
++              0xcc67, 0x3cd4,
++              0xcc68, 0x6624,
++              0xcc69, 0x56b3,
++              0xcc6a, 0x3c3,
++              0xcc6b, 0x866b,
++              0xcc6c, 0x401c,
++              0xcc6d, 0x2205,
++              0xcc6e, 0x3035,
++              0xcc6f, 0x5b53,
++              0xcc70, 0x2c52,
++              0xcc71, 0x3002,
++              0xcc72, 0x13c2,
++              0xcc73, 0x5cc3,
++              0xcc74, 0x317,
++              0xcc75, 0x2522,
++              0xcc76, 0x3012,
++              0xcc77, 0x1002,
++              0xcc78, 0x2da2,
++              0xcc79, 0x3012,
++              0xcc7a, 0x1002,
++              0xcc7b, 0x2b82,
++              0xcc7c, 0x3012,
++              0xcc7d, 0x1002,
++              0xcc7e, 0x5663,
++              0xcc7f, 0x303,
++              0xcc80, 0x401e,
++              0xcc81, 0x004,
++              0xcc82, 0x2c42,
++              0xcc83, 0x3012,
++              0xcc84, 0x1002,
++              0xcc85, 0x6f72,
++              0xcc86, 0x1002,
++              0xcc87, 0x628f,
++              0xcc88, 0x2304,
++              0xcc89, 0x3c84,
++              0xcc8a, 0x6436,
++              0xcc8b, 0xdff4,
++              0xcc8c, 0x6436,
++              0xcc8d, 0x2ff5,
++              0xcc8e, 0x3005,
++              0xcc8f, 0x8656,
++              0xcc90, 0xdfba,
++              0xcc91, 0x56a3,
++              0xcc92, 0xd05a,
++              0xcc93, 0x21c2,
++              0xcc94, 0x3012,
++              0xcc95, 0x1392,
++              0xcc96, 0xd05a,
++              0xcc97, 0x56a3,
++              0xcc98, 0xdfba,
++              0xcc99, 0x383,
++              0xcc9a, 0x6f72,
++              0xcc9b, 0x1002,
++              0xcc9c, 0x28c5,
++              0xcc9d, 0x3005,
++              0xcc9e, 0x4178,
++              0xcc9f, 0x5653,
++              0xcca0, 0x384,
++              0xcca1, 0x22b2,
++              0xcca2, 0x3012,
++              0xcca3, 0x1002,
++              0xcca4, 0x2be5,
++              0xcca5, 0x3005,
++              0xcca6, 0x41e8,
++              0xcca7, 0x5653,
++              0xcca8, 0x382,
++              0xcca9, 0x002,
++              0xccaa, 0x4258,
++              0xccab, 0x2474,
++              0xccac, 0x3c84,
++              0xccad, 0x6437,
++              0xccae, 0xdff4,
++              0xccaf, 0x6437,
++              0xccb0, 0x2ff5,
++              0xccb1, 0x3c05,
++              0xccb2, 0x8757,
++              0xccb3, 0xb888,
++              0xccb4, 0x9787,
++              0xccb5, 0xdff4,
++              0xccb6, 0x6724,
++              0xccb7, 0x866a,
++              0xccb8, 0x6f72,
++              0xccb9, 0x1002,
++              0xccba, 0x2d01,
++              0xccbb, 0x3011,
++              0xccbc, 0x1001,
++              0xccbd, 0xc620,
++              0xccbe, 0x14e5,
++              0xccbf, 0xc621,
++              0xccc0, 0xc53d,
++              0xccc1, 0xc622,
++              0xccc2, 0x3cbe,
++              0xccc3, 0xc623,
++              0xccc4, 0x4452,
++              0xccc5, 0xc624,
++              0xccc6, 0xc5c5,
++              0xccc7, 0xc625,
++              0xccc8, 0xe01e,
++              0xccc9, 0xc627,
++              0xccca, 0x000,
++              0xcccb, 0xc628,
++              0xcccc, 0x000,
++              0xcccd, 0xc62b,
++              0xccce, 0x000,
++              0xcccf, 0xc62c,
++              0xccd0, 0x000,
++              0xccd1, 0x000,
++              0xccd2, 0x2d01,
++              0xccd3, 0x3011,
++              0xccd4, 0x1001,
++              0xccd5, 0xc620,
++              0xccd6, 0x000,
++              0xccd7, 0xc621,
++              0xccd8, 0x000,
++              0xccd9, 0xc622,
++              0xccda, 0x0ce,
++              0xccdb, 0xc623,
++              0xccdc, 0x07f,
++              0xccdd, 0xc624,
++              0xccde, 0x032,
++              0xccdf, 0xc625,
++              0xcce0, 0x000,
++              0xcce1, 0xc627,
++              0xcce2, 0x000,
++              0xcce3, 0xc628,
++              0xcce4, 0x000,
++              0xcce5, 0xc62b,
++              0xcce6, 0x000,
++              0xcce7, 0xc62c,
++              0xcce8, 0x000,
++              0xcce9, 0x000,
++              0xccea, 0x2d01,
++              0xcceb, 0x3011,
++              0xccec, 0x1001,
++              0xcced, 0xc502,
++              0xccee, 0x609f,
++              0xccef, 0xc600,
++              0xccf0, 0x2a6e,
++              0xccf1, 0xc601,
++              0xccf2, 0x2a2c,
++              0xccf3, 0xc60c,
++              0xccf4, 0x5400,
++              0xccf5, 0xc710,
++              0xccf6, 0x700,
++              0xccf7, 0xc718,
++              0xccf8, 0x700,
++              0xccf9, 0xc720,
++              0xccfa, 0x4700,
++              0xccfb, 0xc728,
++              0xccfc, 0x700,
++              0xccfd, 0xc729,
++              0xccfe, 0x1207,
++              0xccff, 0xc801,
++              0xcd00, 0x7f50,
++              0xcd01, 0xc802,
++              0xcd02, 0x7760,
++              0xcd03, 0xc803,
++              0xcd04, 0x7fce,
++              0xcd05, 0xc804,
++              0xcd06, 0x520e,
++              0xcd07, 0xc805,
++              0xcd08, 0x5c11,
++              0xcd09, 0xc806,
++              0xcd0a, 0x3c51,
++              0xcd0b, 0xc807,
++              0xcd0c, 0x4061,
++              0xcd0d, 0xc808,
++              0xcd0e, 0x49c1,
++              0xcd0f, 0xc809,
++              0xcd10, 0x3840,
++              0xcd11, 0xc80a,
++              0xcd12, 0x000,
++              0xcd13, 0xc821,
++              0xcd14, 0x002,
++              0xcd15, 0xc822,
++              0xcd16, 0x046,
++              0xcd17, 0xc844,
++              0xcd18, 0x182f,
++              0xcd19, 0xc013,
++              0xcd1a, 0xf341,
++              0xcd1b, 0xc01a,
++              0xcd1c, 0x446,
++              0xcd1d, 0xc024,
++              0xcd1e, 0x1000,
++              0xcd1f, 0xc025,
++              0xcd20, 0xa00,
++              0xcd21, 0xc026,
++              0xcd22, 0xc0c,
++              0xcd23, 0xc027,
++              0xcd24, 0xc0c,
++              0xcd25, 0xc029,
++              0xcd26, 0x0a0,
++              0xcd27, 0xc030,
++              0xcd28, 0xa00,
++              0xcd29, 0xc03c,
++              0xcd2a, 0x01c,
++              0xcd2b, 0x000,
++              0xcd2c, 0x2b84,
++              0xcd2d, 0x3c74,
++              0xcd2e, 0x6435,
++              0xcd2f, 0xdff4,
++              0xcd30, 0x6435,
++              0xcd31, 0x2806,
++              0xcd32, 0x3006,
++              0xcd33, 0x8565,
++              0xcd34, 0x2b24,
++              0xcd35, 0x3c24,
++              0xcd36, 0x6436,
++              0xcd37, 0x1002,
++              0xcd38, 0x2b24,
++              0xcd39, 0x3c24,
++              0xcd3a, 0x6436,
++              0xcd3b, 0x4045,
++              0xcd3c, 0x8656,
++              0xcd3d, 0x1002,
++              0xcd3e, 0x2807,
++              0xcd3f, 0x31a7,
++              0xcd40, 0x20c4,
++              0xcd41, 0x3c24,
++              0xcd42, 0x6724,
++              0xcd43, 0x1002,
++              0xcd44, 0x2807,
++              0xcd45, 0x3187,
++              0xcd46, 0x20c4,
++              0xcd47, 0x3c24,
++              0xcd48, 0x6724,
++              0xcd49, 0x1002,
++              0xcd4a, 0x2514,
++              0xcd4b, 0x3c64,
++              0xcd4c, 0x6436,
++              0xcd4d, 0xdff4,
++              0xcd4e, 0x6436,
++              0xcd4f, 0x1002,
++              0xcd50, 0x2806,
++              0xcd51, 0x3cb6,
++              0xcd52, 0xc161,
++              0xcd53, 0x6134,
++              0xcd54, 0x6135,
++              0xcd55, 0x5443,
++              0xcd56, 0x303,
++              0xcd57, 0x6524,
++              0xcd58, 0x00b,
++              0xcd59, 0x1002,
++              0xcd5a, 0xd019,
++              0xcd5b, 0x2104,
++              0xcd5c, 0x3c24,
++              0xcd5d, 0x2105,
++              0xcd5e, 0x3805,
++              0xcd5f, 0x6524,
++              0xcd60, 0xdff4,
++              0xcd61, 0x4005,
++              0xcd62, 0x6524,
++              0xcd63, 0x2e8d,
++              0xcd64, 0x303d,
++              0xcd65, 0x5dd3,
++              0xcd66, 0x306,
++              0xcd67, 0x2ff7,
++              0xcd68, 0x38f7,
++              0xcd69, 0x60b7,
++              0xcd6a, 0xdffd,
++              0xcd6b, 0x00a,
++              0xcd6c, 0x1002,
++              0xcd6d, 0
++      };
++      int i, err;
++
++      err = set_phy_regs(phy, regs);
++      if (!err && modtype == phy_modtype_twinax_long)
++              err = set_phy_regs(phy, preemphasis);
++      if (err)
++              return err;
++
++      msleep(50);
++
++      for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
++              err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i],
++                               twinax_edc[i + 1]);
++      if (!err)
++              phy->priv = edc_twinax;
++      return err;
++}
++
++static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
++{
++      int i, err;
++      unsigned int stat, data;
++
++      err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
++                       (dev_addr << 8) | (1 << 8) | word_addr);
++      if (err)
++              return err;
++
++      for (i = 0; i < 5; i++) {
++              msleep(1);
++              err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
++              if (err)
++                      return err;
++              if ((stat & 3) == 1) {
++                      err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA,
++                                      &data);
++                      if (err)
++                              return err;
++                      return data >> 8;
++              }
++      }
++      CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n",
++              phy->addr, word_addr);
++      return -ETIMEDOUT;
++}
++
++static int get_module_type(struct cphy *phy, int delay_ms)
++{
++      int v;
++      unsigned int stat;
++
++      v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat);
++      if (v)
++              return v;
++
++      if (stat & (1 << 8))                    /* module absent */
++              return phy_modtype_none;
++
++      if (delay_ms)
++              msleep(delay_ms);
++
++      /* see SFF-8472 for below */
++      v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 3);
++      if (v < 0)
++              return v;
++
++      if (v == 0x10)
++              return phy_modtype_sr;
++      if (v == 0x20)
++              return phy_modtype_lr;
++      if (v == 0x40)
++              return phy_modtype_lrm;
++
++      v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 6);
++      if (v < 0)
++              return v;
++      if (v != 4)
++              goto unknown;
++
++      v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 10);
++      if (v < 0)
++              return v;
++
++      if (v & 0x80) {
++              v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
++              if (v < 0)
++                      return v;
++              return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax;
++      }
++unknown:
++      return phy_modtype_unknown;
++}
++
++static int ael2005_intr_enable(struct cphy *phy)
++{
++      int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200);
++      return err ? err : t3_phy_lasi_intr_enable(phy);
++}
++
++static int ael2005_intr_disable(struct cphy *phy)
++{
++      int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100);
++      return err ? err : t3_phy_lasi_intr_disable(phy);
++}
++
++static int ael2005_intr_clear(struct cphy *phy)
++{
++      int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00);
++      return err ? err : t3_phy_lasi_intr_clear(phy);
++}
++
++static int ael2005_reset(struct cphy *phy, int wait)
++{
++      static struct reg_val regs0[] = {
++              { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 },
++              { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 },
++              { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 },
++              { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
++              { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 },
++              { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
++              { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 },
++              { 0, 0, 0, 0 }
++      };
++      static struct reg_val regs1[] = {
++              { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 },
++              { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 },
++              { 0, 0, 0, 0 }
++      };
++
++      int err, lasi_ctrl;
++
++      err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
++      if (err)
++              return err;
++
++      err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0);
++      if (err)
++              return err;
++
++      msleep(125);
++      phy->priv = edc_none;
++      err = set_phy_regs(phy, regs0);
++      if (err)
++              return err;
++
++      msleep(50);
++
++      err = get_module_type(phy, 0);
++      if (err < 0)
++              return err;
++      phy->modtype = err;
++
++      if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
++              err = ael2005_setup_twinax_edc(phy, err);
++      else
++              err = ael2005_setup_sr_edc(phy);
++      if (err)
++              return err;
++
++      err = set_phy_regs(phy, regs1);
++      if (err)
++              return err;
++
++      /* reset wipes out interrupts, reenable them if they were on */
++      if (lasi_ctrl & 1)
++              err = ael2005_intr_enable(phy);
++      return err;
++}
++
++static int ael2005_intr_handler(struct cphy *phy)
++{
++      unsigned int stat;
++      int ret, edc_needed, cause = 0;
++
++      ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat);
++      if (ret)
++              return ret;
++
++      if (stat & AEL2005_MODDET_IRQ) {
++              ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL,
++                               0xd00);
++              if (ret)
++                      return ret;
++
++              /* modules have max 300 ms init time after hot plug */
++              ret = get_module_type(phy, 300);
++              if (ret < 0)
++                      return ret;
++
++              phy->modtype = ret;
++              if (ret == phy_modtype_none)
++                      edc_needed = phy->priv;       /* on unplug retain EDC */
++              else if (ret == phy_modtype_twinax ||
++                       ret == phy_modtype_twinax_long)
++                      edc_needed = edc_twinax;
++              else
++                      edc_needed = edc_sr;
++
++              if (edc_needed != phy->priv) {
++                      ret = ael2005_reset(phy, 0);
++                      return ret ? ret : cphy_cause_module_change;
++              }
++              cause = cphy_cause_module_change;
++      }
++
++      ret = t3_phy_lasi_intr_handler(phy);
++      if (ret < 0)
++              return ret;
++
++      ret |= cause;
++      return ret ? ret : cphy_cause_link_change;
++}
++
++static struct cphy_ops ael2005_ops = {
++      .reset           = ael2005_reset,
++      .intr_enable     = ael2005_intr_enable,
++      .intr_disable    = ael2005_intr_disable,
++      .intr_clear      = ael2005_intr_clear,
++      .intr_handler    = ael2005_intr_handler,
++      .get_link_status = get_link_status_r,
++      .power_down      = ael1002_power_down,
++};
++
++int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
++                      int phy_addr, const struct mdio_ops *mdio_ops)
++{
++      cphy_init(phy, adapter, phy_addr, &ael2005_ops, mdio_ops,
++                SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
++                SUPPORTED_IRQ, "10GBASE-R");
++      msleep(125);
++      return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0,
++                                 1 << 5);
++}
++
++/*
++ * Get link status for a 10GBASE-X device.
++ */
++static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed,
++                           int *duplex, int *fc)
++{
++      if (link_ok) {
++              unsigned int stat0, stat1, stat2;
++              int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
++
++              if (!err)
++                      err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1);
++              if (!err)
++                      err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
++              if (err)
++                      return err;
++              *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1;
++      }
++      if (speed)
++              *speed = SPEED_10000;
++      if (duplex)
++              *duplex = DUPLEX_FULL;
++      return 0;
++}
++
+ static struct cphy_ops qt2045_ops = {
+       .reset = ael1006_reset,
+       .intr_enable = t3_phy_lasi_intr_enable,
+       .intr_disable = t3_phy_lasi_intr_disable,
+       .intr_clear = t3_phy_lasi_intr_clear,
+       .intr_handler = t3_phy_lasi_intr_handler,
+-      .get_link_status = ael100x_get_link_status,
++      .get_link_status = get_link_status_x,
+       .power_down = ael1006_power_down,
+ };
+Index: linux-2.6.27/drivers/net/cxgb3/common.h
+===================================================================
+--- linux-2.6.27.orig/drivers/net/cxgb3/common.h
++++ linux-2.6.27/drivers/net/cxgb3/common.h
+@@ -547,7 +547,19 @@ enum {
+ /* PHY interrupt types */
+ enum {
+       cphy_cause_link_change = 1,
+-      cphy_cause_fifo_error = 2
++      cphy_cause_fifo_error = 2,
++      cphy_cause_module_change = 4,
++};
++
++/* PHY module types */
++enum {
++      phy_modtype_none,
++      phy_modtype_sr,
++      phy_modtype_lr,
++      phy_modtype_lrm,
++      phy_modtype_twinax,
++      phy_modtype_twinax_long,
++      phy_modtype_unknown
+ };
+ /* PHY operations */
+@@ -572,7 +584,9 @@ struct cphy_ops {
+ /* A PHY instance */
+ struct cphy {
+-      int addr;                       /* PHY address */
++      u8 addr;                        /* PHY address */
++      u8 modtype;                     /* PHY module type */
++      short priv;                     /* scratch pad */
+       unsigned int caps;              /* PHY capabilities */
+       struct adapter *adapter;        /* associated adapter */
+       const char *desc;               /* PHY description */
+@@ -793,6 +807,8 @@ int t3_ael1002_phy_prep(struct cphy *phy
+                       int phy_addr, const struct mdio_ops *mdio_ops);
+ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
+                       int phy_addr, const struct mdio_ops *mdio_ops);
++int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
++                      int phy_addr, const struct mdio_ops *mdio_ops);
+ int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
+                      const struct mdio_ops *mdio_ops);
+ int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
+Index: linux-2.6.27/drivers/net/cxgb3/cxgb3_main.c
+===================================================================
+--- linux-2.6.27.orig/drivers/net/cxgb3/cxgb3_main.c
++++ linux-2.6.27/drivers/net/cxgb3/cxgb3_main.c
+@@ -209,6 +209,31 @@ void t3_os_link_changed(struct adapter *
+       }
+ }
++/**
++ *    t3_os_phymod_changed - handle PHY module changes
++ *    @phy: the PHY reporting the module change
++ *    @mod_type: new module type
++ *
++ *    This is the OS-dependent handler for PHY module changes.  It is
++ *    invoked when a PHY module is removed or inserted for any OS-specific
++ *    processing.
++ */
++void t3_os_phymod_changed(struct adapter *adap, int port_id)
++{
++      static const char *mod_str[] = {
++              NULL, "SR", "LR", "LRM", "TWINAX", "TWINAX", "unknown"
++      };
++
++      const struct net_device *dev = adap->port[port_id];
++      const struct port_info *pi = netdev_priv(dev);
++
++      if (pi->phy.modtype == phy_modtype_none)
++              printk(KERN_INFO "%s: PHY module unplugged\n", dev->name);
++      else
++              printk(KERN_INFO "%s: %s PHY module inserted\n", dev->name,
++                     mod_str[pi->phy.modtype]);
++}
++
+ static void cxgb_set_rxmode(struct net_device *dev)
+ {
+       struct t3_rx_mode rm;
+Index: linux-2.6.27/drivers/net/cxgb3/t3_hw.c
+===================================================================
+--- linux-2.6.27.orig/drivers/net/cxgb3/t3_hw.c
++++ linux-2.6.27/drivers/net/cxgb3/t3_hw.c
+@@ -511,7 +511,7 @@ static const struct port_type_info port_
+       { t3_vsc8211_phy_prep },
+       { NULL},
+       { t3_xaui_direct_phy_prep },
+-      { NULL },
++      { t3_ael2005_phy_prep },
+       { t3_qt2045_phy_prep },
+       { t3_ael1006_phy_prep },
+       { NULL },
+@@ -1728,6 +1728,8 @@ int t3_phy_intr_handler(struct adapter *
+                               t3_link_changed(adapter, i);
+                       if (phy_cause & cphy_cause_fifo_error)
+                               p->phy.fifo_errors++;
++                      if (phy_cause & cphy_cause_module_change)
++                              t3_os_phymod_changed(adapter, i);
+               }
+       }