diff options
Diffstat (limited to 'drivers/net/cxgb3')
-rw-r--r-- | drivers/net/cxgb3/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/cxgb3/adapter.h | 8 | ||||
-rw-r--r-- | drivers/net/cxgb3/ael1002.c | 958 | ||||
-rw-r--r-- | drivers/net/cxgb3/aq100x.c | 355 | ||||
-rw-r--r-- | drivers/net/cxgb3/common.h | 67 | ||||
-rw-r--r-- | drivers/net/cxgb3/cxgb3_main.c | 160 | ||||
-rw-r--r-- | drivers/net/cxgb3/cxgb3_offload.c | 27 | ||||
-rw-r--r-- | drivers/net/cxgb3/cxgb3_offload.h | 3 | ||||
-rw-r--r-- | drivers/net/cxgb3/sge.c | 82 | ||||
-rw-r--r-- | drivers/net/cxgb3/t3_hw.c | 96 | ||||
-rw-r--r-- | drivers/net/cxgb3/version.h | 4 | ||||
-rw-r--r-- | drivers/net/cxgb3/vsc8211.c | 70 |
12 files changed, 1482 insertions, 350 deletions
diff --git a/drivers/net/cxgb3/Makefile b/drivers/net/cxgb3/Makefile index 343467985321..29aff78c7820 100644 --- a/drivers/net/cxgb3/Makefile +++ b/drivers/net/cxgb3/Makefile | |||
@@ -5,4 +5,4 @@ | |||
5 | obj-$(CONFIG_CHELSIO_T3) += cxgb3.o | 5 | obj-$(CONFIG_CHELSIO_T3) += cxgb3.o |
6 | 6 | ||
7 | cxgb3-objs := cxgb3_main.o ael1002.o vsc8211.o t3_hw.o mc5.o \ | 7 | cxgb3-objs := cxgb3_main.o ael1002.o vsc8211.o t3_hw.o mc5.o \ |
8 | xgmac.o sge.o l2t.o cxgb3_offload.o | 8 | xgmac.o sge.o l2t.o cxgb3_offload.o aq100x.o |
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index 714df2b675e6..1694fad38720 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h | |||
@@ -85,8 +85,8 @@ struct fl_pg_chunk { | |||
85 | struct page *page; | 85 | struct page *page; |
86 | void *va; | 86 | void *va; |
87 | unsigned int offset; | 87 | unsigned int offset; |
88 | u64 *p_cnt; | 88 | unsigned long *p_cnt; |
89 | DECLARE_PCI_UNMAP_ADDR(mapping); | 89 | dma_addr_t mapping; |
90 | }; | 90 | }; |
91 | 91 | ||
92 | struct rx_desc; | 92 | struct rx_desc; |
@@ -195,7 +195,7 @@ struct sge_qset { /* an SGE queue set */ | |||
195 | struct sge_rspq rspq; | 195 | struct sge_rspq rspq; |
196 | struct sge_fl fl[SGE_RXQ_PER_SET]; | 196 | struct sge_fl fl[SGE_RXQ_PER_SET]; |
197 | struct sge_txq txq[SGE_TXQ_PER_SET]; | 197 | struct sge_txq txq[SGE_TXQ_PER_SET]; |
198 | struct napi_gro_fraginfo lro_frag_tbl; | 198 | int nomem; |
199 | int lro_enabled; | 199 | int lro_enabled; |
200 | void *lro_va; | 200 | void *lro_va; |
201 | struct net_device *netdev; | 201 | struct net_device *netdev; |
@@ -253,6 +253,8 @@ struct adapter { | |||
253 | struct mutex mdio_lock; | 253 | struct mutex mdio_lock; |
254 | spinlock_t stats_lock; | 254 | spinlock_t stats_lock; |
255 | spinlock_t work_lock; | 255 | spinlock_t work_lock; |
256 | |||
257 | struct sk_buff *nofail_skb; | ||
256 | }; | 258 | }; |
257 | 259 | ||
258 | static inline u32 t3_read_reg(struct adapter *adapter, u32 reg_addr) | 260 | static inline u32 t3_read_reg(struct adapter *adapter, u32 reg_addr) |
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c index e1b22490ff59..9fe008ec9ba5 100644 --- a/drivers/net/cxgb3/ael1002.c +++ b/drivers/net/cxgb3/ael1002.c | |||
@@ -33,14 +33,6 @@ | |||
33 | #include "regs.h" | 33 | #include "regs.h" |
34 | 34 | ||
35 | enum { | 35 | enum { |
36 | PMD_RSD = 10, /* PMA/PMD receive signal detect register */ | ||
37 | PCS_STAT1_X = 24, /* 10GBASE-X PCS status 1 register */ | ||
38 | PCS_STAT1_R = 32, /* 10GBASE-R PCS status 1 register */ | ||
39 | XS_LN_STAT = 24 /* XS lane status register */ | ||
40 | }; | ||
41 | |||
42 | enum { | ||
43 | AEL100X_TX_DISABLE = 9, | ||
44 | AEL100X_TX_CONFIG1 = 0xc002, | 36 | AEL100X_TX_CONFIG1 = 0xc002, |
45 | AEL1002_PWR_DOWN_HI = 0xc011, | 37 | AEL1002_PWR_DOWN_HI = 0xc011, |
46 | AEL1002_PWR_DOWN_LO = 0xc012, | 38 | AEL1002_PWR_DOWN_LO = 0xc012, |
@@ -52,12 +44,33 @@ enum { | |||
52 | AEL_I2C_STAT = 0xc30c, | 44 | AEL_I2C_STAT = 0xc30c, |
53 | AEL2005_GPIO_CTRL = 0xc214, | 45 | AEL2005_GPIO_CTRL = 0xc214, |
54 | AEL2005_GPIO_STAT = 0xc215, | 46 | AEL2005_GPIO_STAT = 0xc215, |
47 | |||
48 | AEL2020_GPIO_INTR = 0xc103, /* Latch High (LH) */ | ||
49 | AEL2020_GPIO_CTRL = 0xc108, /* Store Clear (SC) */ | ||
50 | AEL2020_GPIO_STAT = 0xc10c, /* Read Only (RO) */ | ||
51 | AEL2020_GPIO_CFG = 0xc110, /* Read Write (RW) */ | ||
52 | |||
53 | AEL2020_GPIO_SDA = 0, /* IN: i2c serial data */ | ||
54 | AEL2020_GPIO_MODDET = 1, /* IN: Module Detect */ | ||
55 | AEL2020_GPIO_0 = 3, /* IN: unassigned */ | ||
56 | AEL2020_GPIO_1 = 2, /* OUT: unassigned */ | ||
57 | AEL2020_GPIO_LSTAT = AEL2020_GPIO_1, /* wired to link status LED */ | ||
55 | }; | 58 | }; |
56 | 59 | ||
57 | enum { edc_none, edc_sr, edc_twinax }; | 60 | enum { edc_none, edc_sr, edc_twinax }; |
58 | 61 | ||
59 | /* PHY module I2C device address */ | 62 | /* PHY module I2C device address */ |
60 | #define MODULE_DEV_ADDR 0xa0 | 63 | enum { |
64 | MODULE_DEV_ADDR = 0xa0, | ||
65 | SFF_DEV_ADDR = 0xa2, | ||
66 | }; | ||
67 | |||
68 | /* PHY transceiver type */ | ||
69 | enum { | ||
70 | phy_transtype_unknown = 0, | ||
71 | phy_transtype_sfp = 3, | ||
72 | phy_transtype_xfp = 6, | ||
73 | }; | ||
61 | 74 | ||
62 | #define AEL2005_MODDET_IRQ 4 | 75 | #define AEL2005_MODDET_IRQ 4 |
63 | 76 | ||
@@ -74,8 +87,8 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv) | |||
74 | 87 | ||
75 | for (err = 0; rv->mmd_addr && !err; rv++) { | 88 | for (err = 0; rv->mmd_addr && !err; rv++) { |
76 | if (rv->clear_bits == 0xffff) | 89 | if (rv->clear_bits == 0xffff) |
77 | err = mdio_write(phy, rv->mmd_addr, rv->reg_addr, | 90 | err = t3_mdio_write(phy, rv->mmd_addr, rv->reg_addr, |
78 | rv->set_bits); | 91 | rv->set_bits); |
79 | else | 92 | else |
80 | err = t3_mdio_change_bits(phy, rv->mmd_addr, | 93 | err = t3_mdio_change_bits(phy, rv->mmd_addr, |
81 | rv->reg_addr, rv->clear_bits, | 94 | rv->reg_addr, rv->clear_bits, |
@@ -86,21 +99,54 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv) | |||
86 | 99 | ||
87 | static void ael100x_txon(struct cphy *phy) | 100 | static void ael100x_txon(struct cphy *phy) |
88 | { | 101 | { |
89 | int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; | 102 | int tx_on_gpio = |
103 | phy->mdio.prtad == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; | ||
90 | 104 | ||
91 | msleep(100); | 105 | msleep(100); |
92 | t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio); | 106 | t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio); |
93 | msleep(30); | 107 | msleep(30); |
94 | } | 108 | } |
95 | 109 | ||
110 | /* | ||
111 | * Read an 8-bit word from a device attached to the PHY's i2c bus. | ||
112 | */ | ||
113 | static int ael_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) | ||
114 | { | ||
115 | int i, err; | ||
116 | unsigned int stat, data; | ||
117 | |||
118 | err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL_I2C_CTRL, | ||
119 | (dev_addr << 8) | (1 << 8) | word_addr); | ||
120 | if (err) | ||
121 | return err; | ||
122 | |||
123 | for (i = 0; i < 200; i++) { | ||
124 | msleep(1); | ||
125 | err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_STAT, &stat); | ||
126 | if (err) | ||
127 | return err; | ||
128 | if ((stat & 3) == 1) { | ||
129 | err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_DATA, | ||
130 | &data); | ||
131 | if (err) | ||
132 | return err; | ||
133 | return data >> 8; | ||
134 | } | ||
135 | } | ||
136 | CH_WARN(phy->adapter, "PHY %u i2c read of dev.addr %#x.%#x timed out\n", | ||
137 | phy->mdio.prtad, dev_addr, word_addr); | ||
138 | return -ETIMEDOUT; | ||
139 | } | ||
140 | |||
96 | static int ael1002_power_down(struct cphy *phy, int enable) | 141 | static int ael1002_power_down(struct cphy *phy, int enable) |
97 | { | 142 | { |
98 | int err; | 143 | int err; |
99 | 144 | ||
100 | err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable); | 145 | err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS, !!enable); |
101 | if (!err) | 146 | if (!err) |
102 | err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, | 147 | err = mdio_set_flag(&phy->mdio, phy->mdio.prtad, |
103 | BMCR_PDOWN, enable ? BMCR_PDOWN : 0); | 148 | MDIO_MMD_PMAPMD, MDIO_CTRL1, |
149 | MDIO_CTRL1_LPOWER, enable); | ||
104 | return err; | 150 | return err; |
105 | } | 151 | } |
106 | 152 | ||
@@ -109,11 +155,11 @@ static int ael1002_reset(struct cphy *phy, int wait) | |||
109 | int err; | 155 | int err; |
110 | 156 | ||
111 | if ((err = ael1002_power_down(phy, 0)) || | 157 | if ((err = ael1002_power_down(phy, 0)) || |
112 | (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) || | 158 | (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL100X_TX_CONFIG1, 1)) || |
113 | (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) || | 159 | (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_HI, 0)) || |
114 | (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) || | 160 | (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_LO, 0)) || |
115 | (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) || | 161 | (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_XFI_EQL, 0x18)) || |
116 | (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN, | 162 | (err = t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL1002_LB_EN, |
117 | 0, 1 << 5))) | 163 | 0, 1 << 5))) |
118 | return err; | 164 | return err; |
119 | return 0; | 165 | return 0; |
@@ -132,12 +178,15 @@ static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed, | |||
132 | { | 178 | { |
133 | if (link_ok) { | 179 | if (link_ok) { |
134 | unsigned int stat0, stat1, stat2; | 180 | unsigned int stat0, stat1, stat2; |
135 | int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); | 181 | int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, |
182 | MDIO_PMA_RXDET, &stat0); | ||
136 | 183 | ||
137 | if (!err) | 184 | if (!err) |
138 | err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1); | 185 | err = t3_mdio_read(phy, MDIO_MMD_PCS, |
186 | MDIO_PCS_10GBRT_STAT1, &stat1); | ||
139 | if (!err) | 187 | if (!err) |
140 | err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); | 188 | err = t3_mdio_read(phy, MDIO_MMD_PHYXS, |
189 | MDIO_PHYXS_LNSTAT, &stat2); | ||
141 | if (err) | 190 | if (err) |
142 | return err; | 191 | return err; |
143 | *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1; | 192 | *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1; |
@@ -157,6 +206,7 @@ static struct cphy_ops ael1002_ops = { | |||
157 | .intr_handler = ael1002_intr_noop, | 206 | .intr_handler = ael1002_intr_noop, |
158 | .get_link_status = get_link_status_r, | 207 | .get_link_status = get_link_status_r, |
159 | .power_down = ael1002_power_down, | 208 | .power_down = ael1002_power_down, |
209 | .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | ||
160 | }; | 210 | }; |
161 | 211 | ||
162 | int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, | 212 | int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, |
@@ -171,13 +221,13 @@ int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, | |||
171 | 221 | ||
172 | static int ael1006_reset(struct cphy *phy, int wait) | 222 | static int ael1006_reset(struct cphy *phy, int wait) |
173 | { | 223 | { |
174 | return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait); | 224 | return t3_phy_reset(phy, MDIO_MMD_PMAPMD, wait); |
175 | } | 225 | } |
176 | 226 | ||
177 | static int ael1006_power_down(struct cphy *phy, int enable) | 227 | static int ael1006_power_down(struct cphy *phy, int enable) |
178 | { | 228 | { |
179 | return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, | 229 | return mdio_set_flag(&phy->mdio, phy->mdio.prtad, MDIO_MMD_PMAPMD, |
180 | BMCR_PDOWN, enable ? BMCR_PDOWN : 0); | 230 | MDIO_CTRL1, MDIO_CTRL1_LPOWER, enable); |
181 | } | 231 | } |
182 | 232 | ||
183 | static struct cphy_ops ael1006_ops = { | 233 | static struct cphy_ops ael1006_ops = { |
@@ -188,6 +238,7 @@ static struct cphy_ops ael1006_ops = { | |||
188 | .intr_handler = t3_phy_lasi_intr_handler, | 238 | .intr_handler = t3_phy_lasi_intr_handler, |
189 | .get_link_status = get_link_status_r, | 239 | .get_link_status = get_link_status_r, |
190 | .power_down = ael1006_power_down, | 240 | .power_down = ael1006_power_down, |
241 | .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | ||
191 | }; | 242 | }; |
192 | 243 | ||
193 | int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, | 244 | int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, |
@@ -200,12 +251,57 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, | |||
200 | return 0; | 251 | return 0; |
201 | } | 252 | } |
202 | 253 | ||
254 | /* | ||
255 | * Decode our module type. | ||
256 | */ | ||
257 | static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms) | ||
258 | { | ||
259 | int v; | ||
260 | |||
261 | if (delay_ms) | ||
262 | msleep(delay_ms); | ||
263 | |||
264 | /* see SFF-8472 for below */ | ||
265 | v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 3); | ||
266 | if (v < 0) | ||
267 | return v; | ||
268 | |||
269 | if (v == 0x10) | ||
270 | return phy_modtype_sr; | ||
271 | if (v == 0x20) | ||
272 | return phy_modtype_lr; | ||
273 | if (v == 0x40) | ||
274 | return phy_modtype_lrm; | ||
275 | |||
276 | v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 6); | ||
277 | if (v < 0) | ||
278 | return v; | ||
279 | if (v != 4) | ||
280 | goto unknown; | ||
281 | |||
282 | v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 10); | ||
283 | if (v < 0) | ||
284 | return v; | ||
285 | |||
286 | if (v & 0x80) { | ||
287 | v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12); | ||
288 | if (v < 0) | ||
289 | return v; | ||
290 | return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax; | ||
291 | } | ||
292 | unknown: | ||
293 | return phy_modtype_unknown; | ||
294 | } | ||
295 | |||
296 | /* | ||
297 | * Code to support the Aeluros/NetLogic 2005 10Gb PHY. | ||
298 | */ | ||
203 | static int ael2005_setup_sr_edc(struct cphy *phy) | 299 | static int ael2005_setup_sr_edc(struct cphy *phy) |
204 | { | 300 | { |
205 | static struct reg_val regs[] = { | 301 | static struct reg_val regs[] = { |
206 | { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 }, | 302 | { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x181 }, |
207 | { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a }, | 303 | { MDIO_MMD_PMAPMD, 0xc010, 0xffff, 0x448a }, |
208 | { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 }, | 304 | { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5200 }, |
209 | { 0, 0, 0, 0 } | 305 | { 0, 0, 0, 0 } |
210 | }; | 306 | }; |
211 | static u16 sr_edc[] = { | 307 | static u16 sr_edc[] = { |
@@ -490,8 +586,8 @@ static int ael2005_setup_sr_edc(struct cphy *phy) | |||
490 | msleep(50); | 586 | msleep(50); |
491 | 587 | ||
492 | for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2) | 588 | for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2) |
493 | err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i], | 589 | err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, sr_edc[i], |
494 | sr_edc[i + 1]); | 590 | sr_edc[i + 1]); |
495 | if (!err) | 591 | if (!err) |
496 | phy->priv = edc_sr; | 592 | phy->priv = edc_sr; |
497 | return err; | 593 | return err; |
@@ -500,12 +596,12 @@ static int ael2005_setup_sr_edc(struct cphy *phy) | |||
500 | static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) | 596 | static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) |
501 | { | 597 | { |
502 | static struct reg_val regs[] = { | 598 | static struct reg_val regs[] = { |
503 | { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 }, | 599 | { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5a00 }, |
504 | { 0, 0, 0, 0 } | 600 | { 0, 0, 0, 0 } |
505 | }; | 601 | }; |
506 | static struct reg_val preemphasis[] = { | 602 | static struct reg_val preemphasis[] = { |
507 | { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 }, | 603 | { MDIO_MMD_PMAPMD, 0xc014, 0xffff, 0xfe16 }, |
508 | { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 }, | 604 | { MDIO_MMD_PMAPMD, 0xc015, 0xffff, 0xa000 }, |
509 | { 0, 0, 0, 0 } | 605 | { 0, 0, 0, 0 } |
510 | }; | 606 | }; |
511 | static u16 twinax_edc[] = { | 607 | static u16 twinax_edc[] = { |
@@ -887,132 +983,73 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) | |||
887 | msleep(50); | 983 | msleep(50); |
888 | 984 | ||
889 | for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) | 985 | for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) |
890 | err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i], | 986 | err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i], |
891 | twinax_edc[i + 1]); | 987 | twinax_edc[i + 1]); |
892 | if (!err) | 988 | if (!err) |
893 | phy->priv = edc_twinax; | 989 | phy->priv = edc_twinax; |
894 | return err; | 990 | return err; |
895 | } | 991 | } |
896 | 992 | ||
897 | static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) | 993 | static int ael2005_get_module_type(struct cphy *phy, int delay_ms) |
898 | { | ||
899 | int i, err; | ||
900 | unsigned int stat, data; | ||
901 | |||
902 | err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL, | ||
903 | (dev_addr << 8) | (1 << 8) | word_addr); | ||
904 | if (err) | ||
905 | return err; | ||
906 | |||
907 | for (i = 0; i < 5; i++) { | ||
908 | msleep(1); | ||
909 | err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat); | ||
910 | if (err) | ||
911 | return err; | ||
912 | if ((stat & 3) == 1) { | ||
913 | err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA, | ||
914 | &data); | ||
915 | if (err) | ||
916 | return err; | ||
917 | return data >> 8; | ||
918 | } | ||
919 | } | ||
920 | CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n", | ||
921 | phy->addr, word_addr); | ||
922 | return -ETIMEDOUT; | ||
923 | } | ||
924 | |||
925 | static int get_module_type(struct cphy *phy, int delay_ms) | ||
926 | { | 994 | { |
927 | int v; | 995 | int v; |
928 | unsigned int stat; | 996 | unsigned int stat; |
929 | 997 | ||
930 | v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat); | 998 | v = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, &stat); |
931 | if (v) | 999 | if (v) |
932 | return v; | 1000 | return v; |
933 | 1001 | ||
934 | if (stat & (1 << 8)) /* module absent */ | 1002 | if (stat & (1 << 8)) /* module absent */ |
935 | return phy_modtype_none; | 1003 | return phy_modtype_none; |
936 | 1004 | ||
937 | if (delay_ms) | 1005 | return ael2xxx_get_module_type(phy, delay_ms); |
938 | msleep(delay_ms); | ||
939 | |||
940 | /* see SFF-8472 for below */ | ||
941 | v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 3); | ||
942 | if (v < 0) | ||
943 | return v; | ||
944 | |||
945 | if (v == 0x10) | ||
946 | return phy_modtype_sr; | ||
947 | if (v == 0x20) | ||
948 | return phy_modtype_lr; | ||
949 | if (v == 0x40) | ||
950 | return phy_modtype_lrm; | ||
951 | |||
952 | v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 6); | ||
953 | if (v < 0) | ||
954 | return v; | ||
955 | if (v != 4) | ||
956 | goto unknown; | ||
957 | |||
958 | v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 10); | ||
959 | if (v < 0) | ||
960 | return v; | ||
961 | |||
962 | if (v & 0x80) { | ||
963 | v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 0x12); | ||
964 | if (v < 0) | ||
965 | return v; | ||
966 | return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax; | ||
967 | } | ||
968 | unknown: | ||
969 | return phy_modtype_unknown; | ||
970 | } | 1006 | } |
971 | 1007 | ||
972 | static int ael2005_intr_enable(struct cphy *phy) | 1008 | static int ael2005_intr_enable(struct cphy *phy) |
973 | { | 1009 | { |
974 | int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200); | 1010 | int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x200); |
975 | return err ? err : t3_phy_lasi_intr_enable(phy); | 1011 | return err ? err : t3_phy_lasi_intr_enable(phy); |
976 | } | 1012 | } |
977 | 1013 | ||
978 | static int ael2005_intr_disable(struct cphy *phy) | 1014 | static int ael2005_intr_disable(struct cphy *phy) |
979 | { | 1015 | { |
980 | int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100); | 1016 | int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x100); |
981 | return err ? err : t3_phy_lasi_intr_disable(phy); | 1017 | return err ? err : t3_phy_lasi_intr_disable(phy); |
982 | } | 1018 | } |
983 | 1019 | ||
984 | static int ael2005_intr_clear(struct cphy *phy) | 1020 | static int ael2005_intr_clear(struct cphy *phy) |
985 | { | 1021 | { |
986 | int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00); | 1022 | int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0xd00); |
987 | return err ? err : t3_phy_lasi_intr_clear(phy); | 1023 | return err ? err : t3_phy_lasi_intr_clear(phy); |
988 | } | 1024 | } |
989 | 1025 | ||
990 | static int ael2005_reset(struct cphy *phy, int wait) | 1026 | static int ael2005_reset(struct cphy *phy, int wait) |
991 | { | 1027 | { |
992 | static struct reg_val regs0[] = { | 1028 | static struct reg_val regs0[] = { |
993 | { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 }, | 1029 | { MDIO_MMD_PMAPMD, 0xc001, 0, 1 << 5 }, |
994 | { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 }, | 1030 | { MDIO_MMD_PMAPMD, 0xc017, 0, 1 << 5 }, |
995 | { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 }, | 1031 | { MDIO_MMD_PMAPMD, 0xc013, 0xffff, 0xf341 }, |
996 | { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, | 1032 | { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 }, |
997 | { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 }, | 1033 | { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8100 }, |
998 | { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, | 1034 | { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 }, |
999 | { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 }, | 1035 | { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0 }, |
1000 | { 0, 0, 0, 0 } | 1036 | { 0, 0, 0, 0 } |
1001 | }; | 1037 | }; |
1002 | static struct reg_val regs1[] = { | 1038 | static struct reg_val regs1[] = { |
1003 | { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 }, | 1039 | { MDIO_MMD_PMAPMD, 0xca00, 0xffff, 0x0080 }, |
1004 | { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 }, | 1040 | { MDIO_MMD_PMAPMD, 0xca12, 0xffff, 0 }, |
1005 | { 0, 0, 0, 0 } | 1041 | { 0, 0, 0, 0 } |
1006 | }; | 1042 | }; |
1007 | 1043 | ||
1008 | int err; | 1044 | int err; |
1009 | unsigned int lasi_ctrl; | 1045 | unsigned int lasi_ctrl; |
1010 | 1046 | ||
1011 | err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl); | 1047 | err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, |
1048 | &lasi_ctrl); | ||
1012 | if (err) | 1049 | if (err) |
1013 | return err; | 1050 | return err; |
1014 | 1051 | ||
1015 | err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0); | 1052 | err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 0); |
1016 | if (err) | 1053 | if (err) |
1017 | return err; | 1054 | return err; |
1018 | 1055 | ||
@@ -1024,7 +1061,7 @@ static int ael2005_reset(struct cphy *phy, int wait) | |||
1024 | 1061 | ||
1025 | msleep(50); | 1062 | msleep(50); |
1026 | 1063 | ||
1027 | err = get_module_type(phy, 0); | 1064 | err = ael2005_get_module_type(phy, 0); |
1028 | if (err < 0) | 1065 | if (err < 0) |
1029 | return err; | 1066 | return err; |
1030 | phy->modtype = err; | 1067 | phy->modtype = err; |
@@ -1051,18 +1088,18 @@ static int ael2005_intr_handler(struct cphy *phy) | |||
1051 | unsigned int stat; | 1088 | unsigned int stat; |
1052 | int ret, edc_needed, cause = 0; | 1089 | int ret, edc_needed, cause = 0; |
1053 | 1090 | ||
1054 | ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat); | 1091 | ret = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_STAT, &stat); |
1055 | if (ret) | 1092 | if (ret) |
1056 | return ret; | 1093 | return ret; |
1057 | 1094 | ||
1058 | if (stat & AEL2005_MODDET_IRQ) { | 1095 | if (stat & AEL2005_MODDET_IRQ) { |
1059 | ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, | 1096 | ret = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, |
1060 | 0xd00); | 1097 | 0xd00); |
1061 | if (ret) | 1098 | if (ret) |
1062 | return ret; | 1099 | return ret; |
1063 | 1100 | ||
1064 | /* modules have max 300 ms init time after hot plug */ | 1101 | /* modules have max 300 ms init time after hot plug */ |
1065 | ret = get_module_type(phy, 300); | 1102 | ret = ael2005_get_module_type(phy, 300); |
1066 | if (ret < 0) | 1103 | if (ret < 0) |
1067 | return ret; | 1104 | return ret; |
1068 | 1105 | ||
@@ -1098,6 +1135,7 @@ static struct cphy_ops ael2005_ops = { | |||
1098 | .intr_handler = ael2005_intr_handler, | 1135 | .intr_handler = ael2005_intr_handler, |
1099 | .get_link_status = get_link_status_r, | 1136 | .get_link_status = get_link_status_r, |
1100 | .power_down = ael1002_power_down, | 1137 | .power_down = ael1002_power_down, |
1138 | .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | ||
1101 | }; | 1139 | }; |
1102 | 1140 | ||
1103 | int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, | 1141 | int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, |
@@ -1107,11 +1145,667 @@ int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, | |||
1107 | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | | 1145 | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | |
1108 | SUPPORTED_IRQ, "10GBASE-R"); | 1146 | SUPPORTED_IRQ, "10GBASE-R"); |
1109 | msleep(125); | 1147 | msleep(125); |
1110 | return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0, | 1148 | return t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS, 0, |
1111 | 1 << 5); | 1149 | 1 << 5); |
1112 | } | 1150 | } |
1113 | 1151 | ||
1114 | /* | 1152 | /* |
1153 | * Setup EDC and other parameters for operation with an optical module. | ||
1154 | */ | ||
1155 | static int ael2020_setup_sr_edc(struct cphy *phy) | ||
1156 | { | ||
1157 | static struct reg_val regs[] = { | ||
1158 | /* set CDR offset to 10 */ | ||
1159 | { MDIO_MMD_PMAPMD, 0xcc01, 0xffff, 0x488a }, | ||
1160 | |||
1161 | /* adjust 10G RX bias current */ | ||
1162 | { MDIO_MMD_PMAPMD, 0xcb1b, 0xffff, 0x0200 }, | ||
1163 | { MDIO_MMD_PMAPMD, 0xcb1c, 0xffff, 0x00f0 }, | ||
1164 | { MDIO_MMD_PMAPMD, 0xcc06, 0xffff, 0x00e0 }, | ||
1165 | |||
1166 | /* end */ | ||
1167 | { 0, 0, 0, 0 } | ||
1168 | }; | ||
1169 | int err; | ||
1170 | |||
1171 | err = set_phy_regs(phy, regs); | ||
1172 | msleep(50); | ||
1173 | if (err) | ||
1174 | return err; | ||
1175 | |||
1176 | phy->priv = edc_sr; | ||
1177 | return 0; | ||
1178 | } | ||
1179 | |||
1180 | /* | ||
1181 | * Setup EDC and other parameters for operation with an TWINAX module. | ||
1182 | */ | ||
1183 | static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype) | ||
1184 | { | ||
1185 | /* set uC to 40MHz */ | ||
1186 | static struct reg_val uCclock40MHz[] = { | ||
1187 | { MDIO_MMD_PMAPMD, 0xff28, 0xffff, 0x4001 }, | ||
1188 | { MDIO_MMD_PMAPMD, 0xff2a, 0xffff, 0x0002 }, | ||
1189 | { 0, 0, 0, 0 } | ||
1190 | }; | ||
1191 | |||
1192 | /* activate uC clock */ | ||
1193 | static struct reg_val uCclockActivate[] = { | ||
1194 | { MDIO_MMD_PMAPMD, 0xd000, 0xffff, 0x5200 }, | ||
1195 | { 0, 0, 0, 0 } | ||
1196 | }; | ||
1197 | |||
1198 | /* set PC to start of SRAM and activate uC */ | ||
1199 | static struct reg_val uCactivate[] = { | ||
1200 | { MDIO_MMD_PMAPMD, 0xd080, 0xffff, 0x0100 }, | ||
1201 | { MDIO_MMD_PMAPMD, 0xd092, 0xffff, 0x0000 }, | ||
1202 | { 0, 0, 0, 0 } | ||
1203 | }; | ||
1204 | |||
1205 | /* TWINAX EDC firmware */ | ||
1206 | static u16 twinax_edc[] = { | ||
1207 | 0xd800, 0x4009, | ||
1208 | 0xd801, 0x2fff, | ||
1209 | 0xd802, 0x300f, | ||
1210 | 0xd803, 0x40aa, | ||
1211 | 0xd804, 0x401c, | ||
1212 | 0xd805, 0x401e, | ||
1213 | 0xd806, 0x2ff4, | ||
1214 | 0xd807, 0x3dc4, | ||
1215 | 0xd808, 0x2035, | ||
1216 | 0xd809, 0x3035, | ||
1217 | 0xd80a, 0x6524, | ||
1218 | 0xd80b, 0x2cb2, | ||
1219 | 0xd80c, 0x3012, | ||
1220 | 0xd80d, 0x1002, | ||
1221 | 0xd80e, 0x26e2, | ||
1222 | 0xd80f, 0x3022, | ||
1223 | 0xd810, 0x1002, | ||
1224 | 0xd811, 0x27d2, | ||
1225 | 0xd812, 0x3022, | ||
1226 | 0xd813, 0x1002, | ||
1227 | 0xd814, 0x2822, | ||
1228 | 0xd815, 0x3012, | ||
1229 | 0xd816, 0x1002, | ||
1230 | 0xd817, 0x2492, | ||
1231 | 0xd818, 0x3022, | ||
1232 | 0xd819, 0x1002, | ||
1233 | 0xd81a, 0x2772, | ||
1234 | 0xd81b, 0x3012, | ||
1235 | 0xd81c, 0x1002, | ||
1236 | 0xd81d, 0x23d2, | ||
1237 | 0xd81e, 0x3022, | ||
1238 | 0xd81f, 0x1002, | ||
1239 | 0xd820, 0x22cd, | ||
1240 | 0xd821, 0x301d, | ||
1241 | 0xd822, 0x27f2, | ||
1242 | 0xd823, 0x3022, | ||
1243 | 0xd824, 0x1002, | ||
1244 | 0xd825, 0x5553, | ||
1245 | 0xd826, 0x0307, | ||
1246 | 0xd827, 0x2522, | ||
1247 | 0xd828, 0x3022, | ||
1248 | 0xd829, 0x1002, | ||
1249 | 0xd82a, 0x2142, | ||
1250 | 0xd82b, 0x3012, | ||
1251 | 0xd82c, 0x1002, | ||
1252 | 0xd82d, 0x4016, | ||
1253 | 0xd82e, 0x5e63, | ||
1254 | 0xd82f, 0x0344, | ||
1255 | 0xd830, 0x2142, | ||
1256 | 0xd831, 0x3012, | ||
1257 | 0xd832, 0x1002, | ||
1258 | 0xd833, 0x400e, | ||
1259 | 0xd834, 0x2522, | ||
1260 | 0xd835, 0x3022, | ||
1261 | 0xd836, 0x1002, | ||
1262 | 0xd837, 0x2b52, | ||
1263 | 0xd838, 0x3012, | ||
1264 | 0xd839, 0x1002, | ||
1265 | 0xd83a, 0x2742, | ||
1266 | 0xd83b, 0x3022, | ||
1267 | 0xd83c, 0x1002, | ||
1268 | 0xd83d, 0x25e2, | ||
1269 | 0xd83e, 0x3022, | ||
1270 | 0xd83f, 0x1002, | ||
1271 | 0xd840, 0x2fa4, | ||
1272 | 0xd841, 0x3dc4, | ||
1273 | 0xd842, 0x6624, | ||
1274 | 0xd843, 0x414b, | ||
1275 | 0xd844, 0x56b3, | ||
1276 | 0xd845, 0x03c6, | ||
1277 | 0xd846, 0x866b, | ||
1278 | 0xd847, 0x400c, | ||
1279 | 0xd848, 0x2712, | ||
1280 | 0xd849, 0x3012, | ||
1281 | 0xd84a, 0x1002, | ||
1282 | 0xd84b, 0x2c4b, | ||
1283 | 0xd84c, 0x309b, | ||
1284 | 0xd84d, 0x56b3, | ||
1285 | 0xd84e, 0x03c3, | ||
1286 | 0xd84f, 0x866b, | ||
1287 | 0xd850, 0x400c, | ||
1288 | 0xd851, 0x2272, | ||
1289 | 0xd852, 0x3022, | ||
1290 | 0xd853, 0x1002, | ||
1291 | 0xd854, 0x2742, | ||
1292 | 0xd855, 0x3022, | ||
1293 | 0xd856, 0x1002, | ||
1294 | 0xd857, 0x25e2, | ||
1295 | 0xd858, 0x3022, | ||
1296 | 0xd859, 0x1002, | ||
1297 | 0xd85a, 0x2fb4, | ||
1298 | 0xd85b, 0x3dc4, | ||
1299 | 0xd85c, 0x6624, | ||
1300 | 0xd85d, 0x56b3, | ||
1301 | 0xd85e, 0x03c3, | ||
1302 | 0xd85f, 0x866b, | ||
1303 | 0xd860, 0x401c, | ||
1304 | 0xd861, 0x2c45, | ||
1305 | 0xd862, 0x3095, | ||
1306 | 0xd863, 0x5b53, | ||
1307 | 0xd864, 0x2372, | ||
1308 | 0xd865, 0x3012, | ||
1309 | 0xd866, 0x13c2, | ||
1310 | 0xd867, 0x5cc3, | ||
1311 | 0xd868, 0x2712, | ||
1312 | 0xd869, 0x3012, | ||
1313 | 0xd86a, 0x1312, | ||
1314 | 0xd86b, 0x2b52, | ||
1315 | 0xd86c, 0x3012, | ||
1316 | 0xd86d, 0x1002, | ||
1317 | 0xd86e, 0x2742, | ||
1318 | 0xd86f, 0x3022, | ||
1319 | 0xd870, 0x1002, | ||
1320 | 0xd871, 0x2582, | ||
1321 | 0xd872, 0x3022, | ||
1322 | 0xd873, 0x1002, | ||
1323 | 0xd874, 0x2142, | ||
1324 | 0xd875, 0x3012, | ||
1325 | 0xd876, 0x1002, | ||
1326 | 0xd877, 0x628f, | ||
1327 | 0xd878, 0x2985, | ||
1328 | 0xd879, 0x33a5, | ||
1329 | 0xd87a, 0x25e2, | ||
1330 | 0xd87b, 0x3022, | ||
1331 | 0xd87c, 0x1002, | ||
1332 | 0xd87d, 0x5653, | ||
1333 | 0xd87e, 0x03d2, | ||
1334 | 0xd87f, 0x401e, | ||
1335 | 0xd880, 0x6f72, | ||
1336 | 0xd881, 0x1002, | ||
1337 | 0xd882, 0x628f, | ||
1338 | 0xd883, 0x2304, | ||
1339 | 0xd884, 0x3c84, | ||
1340 | 0xd885, 0x6436, | ||
1341 | 0xd886, 0xdff4, | ||
1342 | 0xd887, 0x6436, | ||
1343 | 0xd888, 0x2ff5, | ||
1344 | 0xd889, 0x3005, | ||
1345 | 0xd88a, 0x8656, | ||
1346 | 0xd88b, 0xdfba, | ||
1347 | 0xd88c, 0x56a3, | ||
1348 | 0xd88d, 0xd05a, | ||
1349 | 0xd88e, 0x2972, | ||
1350 | 0xd88f, 0x3012, | ||
1351 | 0xd890, 0x1392, | ||
1352 | 0xd891, 0xd05a, | ||
1353 | 0xd892, 0x56a3, | ||
1354 | 0xd893, 0xdfba, | ||
1355 | 0xd894, 0x0383, | ||
1356 | 0xd895, 0x6f72, | ||
1357 | 0xd896, 0x1002, | ||
1358 | 0xd897, 0x2b45, | ||
1359 | 0xd898, 0x3005, | ||
1360 | 0xd899, 0x4178, | ||
1361 | 0xd89a, 0x5653, | ||
1362 | 0xd89b, 0x0384, | ||
1363 | 0xd89c, 0x2a62, | ||
1364 | 0xd89d, 0x3012, | ||
1365 | 0xd89e, 0x1002, | ||
1366 | 0xd89f, 0x2f05, | ||
1367 | 0xd8a0, 0x3005, | ||
1368 | 0xd8a1, 0x41c8, | ||
1369 | 0xd8a2, 0x5653, | ||
1370 | 0xd8a3, 0x0382, | ||
1371 | 0xd8a4, 0x0002, | ||
1372 | 0xd8a5, 0x4218, | ||
1373 | 0xd8a6, 0x2474, | ||
1374 | 0xd8a7, 0x3c84, | ||
1375 | 0xd8a8, 0x6437, | ||
1376 | 0xd8a9, 0xdff4, | ||
1377 | 0xd8aa, 0x6437, | ||
1378 | 0xd8ab, 0x2ff5, | ||
1379 | 0xd8ac, 0x3c05, | ||
1380 | 0xd8ad, 0x8757, | ||
1381 | 0xd8ae, 0xb888, | ||
1382 | 0xd8af, 0x9787, | ||
1383 | 0xd8b0, 0xdff4, | ||
1384 | 0xd8b1, 0x6724, | ||
1385 | 0xd8b2, 0x866a, | ||
1386 | 0xd8b3, 0x6f72, | ||
1387 | 0xd8b4, 0x1002, | ||
1388 | 0xd8b5, 0x2641, | ||
1389 | 0xd8b6, 0x3021, | ||
1390 | 0xd8b7, 0x1001, | ||
1391 | 0xd8b8, 0xc620, | ||
1392 | 0xd8b9, 0x0000, | ||
1393 | 0xd8ba, 0xc621, | ||
1394 | 0xd8bb, 0x0000, | ||
1395 | 0xd8bc, 0xc622, | ||
1396 | 0xd8bd, 0x00ce, | ||
1397 | 0xd8be, 0xc623, | ||
1398 | 0xd8bf, 0x007f, | ||
1399 | 0xd8c0, 0xc624, | ||
1400 | 0xd8c1, 0x0032, | ||
1401 | 0xd8c2, 0xc625, | ||
1402 | 0xd8c3, 0x0000, | ||
1403 | 0xd8c4, 0xc627, | ||
1404 | 0xd8c5, 0x0000, | ||
1405 | 0xd8c6, 0xc628, | ||
1406 | 0xd8c7, 0x0000, | ||
1407 | 0xd8c8, 0xc62c, | ||
1408 | 0xd8c9, 0x0000, | ||
1409 | 0xd8ca, 0x0000, | ||
1410 | 0xd8cb, 0x2641, | ||
1411 | 0xd8cc, 0x3021, | ||
1412 | 0xd8cd, 0x1001, | ||
1413 | 0xd8ce, 0xc502, | ||
1414 | 0xd8cf, 0x53ac, | ||
1415 | 0xd8d0, 0xc503, | ||
1416 | 0xd8d1, 0x2cd3, | ||
1417 | 0xd8d2, 0xc600, | ||
1418 | 0xd8d3, 0x2a6e, | ||
1419 | 0xd8d4, 0xc601, | ||
1420 | 0xd8d5, 0x2a2c, | ||
1421 | 0xd8d6, 0xc605, | ||
1422 | 0xd8d7, 0x5557, | ||
1423 | 0xd8d8, 0xc60c, | ||
1424 | 0xd8d9, 0x5400, | ||
1425 | 0xd8da, 0xc710, | ||
1426 | 0xd8db, 0x0700, | ||
1427 | 0xd8dc, 0xc711, | ||
1428 | 0xd8dd, 0x0f06, | ||
1429 | 0xd8de, 0xc718, | ||
1430 | 0xd8df, 0x0700, | ||
1431 | 0xd8e0, 0xc719, | ||
1432 | 0xd8e1, 0x0f06, | ||
1433 | 0xd8e2, 0xc720, | ||
1434 | 0xd8e3, 0x4700, | ||
1435 | 0xd8e4, 0xc721, | ||
1436 | 0xd8e5, 0x0f06, | ||
1437 | 0xd8e6, 0xc728, | ||
1438 | 0xd8e7, 0x0700, | ||
1439 | 0xd8e8, 0xc729, | ||
1440 | 0xd8e9, 0x1207, | ||
1441 | 0xd8ea, 0xc801, | ||
1442 | 0xd8eb, 0x7f50, | ||
1443 | 0xd8ec, 0xc802, | ||
1444 | 0xd8ed, 0x7760, | ||
1445 | 0xd8ee, 0xc803, | ||
1446 | 0xd8ef, 0x7fce, | ||
1447 | 0xd8f0, 0xc804, | ||
1448 | 0xd8f1, 0x520e, | ||
1449 | 0xd8f2, 0xc805, | ||
1450 | 0xd8f3, 0x5c11, | ||
1451 | 0xd8f4, 0xc806, | ||
1452 | 0xd8f5, 0x3c51, | ||
1453 | 0xd8f6, 0xc807, | ||
1454 | 0xd8f7, 0x4061, | ||
1455 | 0xd8f8, 0xc808, | ||
1456 | 0xd8f9, 0x49c1, | ||
1457 | 0xd8fa, 0xc809, | ||
1458 | 0xd8fb, 0x3840, | ||
1459 | 0xd8fc, 0xc80a, | ||
1460 | 0xd8fd, 0x0000, | ||
1461 | 0xd8fe, 0xc821, | ||
1462 | 0xd8ff, 0x0002, | ||
1463 | 0xd900, 0xc822, | ||
1464 | 0xd901, 0x0046, | ||
1465 | 0xd902, 0xc844, | ||
1466 | 0xd903, 0x182f, | ||
1467 | 0xd904, 0xc013, | ||
1468 | 0xd905, 0xf341, | ||
1469 | 0xd906, 0xc084, | ||
1470 | 0xd907, 0x0030, | ||
1471 | 0xd908, 0xc904, | ||
1472 | 0xd909, 0x1401, | ||
1473 | 0xd90a, 0xcb0c, | ||
1474 | 0xd90b, 0x0004, | ||
1475 | 0xd90c, 0xcb0e, | ||
1476 | 0xd90d, 0xa00a, | ||
1477 | 0xd90e, 0xcb0f, | ||
1478 | 0xd90f, 0xc0c0, | ||
1479 | 0xd910, 0xcb10, | ||
1480 | 0xd911, 0xc0c0, | ||
1481 | 0xd912, 0xcb11, | ||
1482 | 0xd913, 0x00a0, | ||
1483 | 0xd914, 0xcb12, | ||
1484 | 0xd915, 0x0007, | ||
1485 | 0xd916, 0xc241, | ||
1486 | 0xd917, 0xa000, | ||
1487 | 0xd918, 0xc243, | ||
1488 | 0xd919, 0x7fe0, | ||
1489 | 0xd91a, 0xc604, | ||
1490 | 0xd91b, 0x000e, | ||
1491 | 0xd91c, 0xc609, | ||
1492 | 0xd91d, 0x00f5, | ||
1493 | 0xd91e, 0xc611, | ||
1494 | 0xd91f, 0x000e, | ||
1495 | 0xd920, 0xc660, | ||
1496 | 0xd921, 0x9600, | ||
1497 | 0xd922, 0xc687, | ||
1498 | 0xd923, 0x0004, | ||
1499 | 0xd924, 0xc60a, | ||
1500 | 0xd925, 0x04f5, | ||
1501 | 0xd926, 0x0000, | ||
1502 | 0xd927, 0x2641, | ||
1503 | 0xd928, 0x3021, | ||
1504 | 0xd929, 0x1001, | ||
1505 | 0xd92a, 0xc620, | ||
1506 | 0xd92b, 0x14e5, | ||
1507 | 0xd92c, 0xc621, | ||
1508 | 0xd92d, 0xc53d, | ||
1509 | 0xd92e, 0xc622, | ||
1510 | 0xd92f, 0x3cbe, | ||
1511 | 0xd930, 0xc623, | ||
1512 | 0xd931, 0x4452, | ||
1513 | 0xd932, 0xc624, | ||
1514 | 0xd933, 0xc5c5, | ||
1515 | 0xd934, 0xc625, | ||
1516 | 0xd935, 0xe01e, | ||
1517 | 0xd936, 0xc627, | ||
1518 | 0xd937, 0x0000, | ||
1519 | 0xd938, 0xc628, | ||
1520 | 0xd939, 0x0000, | ||
1521 | 0xd93a, 0xc62c, | ||
1522 | 0xd93b, 0x0000, | ||
1523 | 0xd93c, 0x0000, | ||
1524 | 0xd93d, 0x2b84, | ||
1525 | 0xd93e, 0x3c74, | ||
1526 | 0xd93f, 0x6435, | ||
1527 | 0xd940, 0xdff4, | ||
1528 | 0xd941, 0x6435, | ||
1529 | 0xd942, 0x2806, | ||
1530 | 0xd943, 0x3006, | ||
1531 | 0xd944, 0x8565, | ||
1532 | 0xd945, 0x2b24, | ||
1533 | 0xd946, 0x3c24, | ||
1534 | 0xd947, 0x6436, | ||
1535 | 0xd948, 0x1002, | ||
1536 | 0xd949, 0x2b24, | ||
1537 | 0xd94a, 0x3c24, | ||
1538 | 0xd94b, 0x6436, | ||
1539 | 0xd94c, 0x4045, | ||
1540 | 0xd94d, 0x8656, | ||
1541 | 0xd94e, 0x5663, | ||
1542 | 0xd94f, 0x0302, | ||
1543 | 0xd950, 0x401e, | ||
1544 | 0xd951, 0x1002, | ||
1545 | 0xd952, 0x2807, | ||
1546 | 0xd953, 0x31a7, | ||
1547 | 0xd954, 0x20c4, | ||
1548 | 0xd955, 0x3c24, | ||
1549 | 0xd956, 0x6724, | ||
1550 | 0xd957, 0x1002, | ||
1551 | 0xd958, 0x2807, | ||
1552 | 0xd959, 0x3187, | ||
1553 | 0xd95a, 0x20c4, | ||
1554 | 0xd95b, 0x3c24, | ||
1555 | 0xd95c, 0x6724, | ||
1556 | 0xd95d, 0x1002, | ||
1557 | 0xd95e, 0x24f4, | ||
1558 | 0xd95f, 0x3c64, | ||
1559 | 0xd960, 0x6436, | ||
1560 | 0xd961, 0xdff4, | ||
1561 | 0xd962, 0x6436, | ||
1562 | 0xd963, 0x1002, | ||
1563 | 0xd964, 0x2006, | ||
1564 | 0xd965, 0x3d76, | ||
1565 | 0xd966, 0xc161, | ||
1566 | 0xd967, 0x6134, | ||
1567 | 0xd968, 0x6135, | ||
1568 | 0xd969, 0x5443, | ||
1569 | 0xd96a, 0x0303, | ||
1570 | 0xd96b, 0x6524, | ||
1571 | 0xd96c, 0x00fb, | ||
1572 | 0xd96d, 0x1002, | ||
1573 | 0xd96e, 0x20d4, | ||
1574 | 0xd96f, 0x3c24, | ||
1575 | 0xd970, 0x2025, | ||
1576 | 0xd971, 0x3005, | ||
1577 | 0xd972, 0x6524, | ||
1578 | 0xd973, 0x1002, | ||
1579 | 0xd974, 0xd019, | ||
1580 | 0xd975, 0x2104, | ||
1581 | 0xd976, 0x3c24, | ||
1582 | 0xd977, 0x2105, | ||
1583 | 0xd978, 0x3805, | ||
1584 | 0xd979, 0x6524, | ||
1585 | 0xd97a, 0xdff4, | ||
1586 | 0xd97b, 0x4005, | ||
1587 | 0xd97c, 0x6524, | ||
1588 | 0xd97d, 0x2e8d, | ||
1589 | 0xd97e, 0x303d, | ||
1590 | 0xd97f, 0x2408, | ||
1591 | 0xd980, 0x35d8, | ||
1592 | 0xd981, 0x5dd3, | ||
1593 | 0xd982, 0x0307, | ||
1594 | 0xd983, 0x8887, | ||
1595 | 0xd984, 0x63a7, | ||
1596 | 0xd985, 0x8887, | ||
1597 | 0xd986, 0x63a7, | ||
1598 | 0xd987, 0xdffd, | ||
1599 | 0xd988, 0x00f9, | ||
1600 | 0xd989, 0x1002, | ||
1601 | 0xd98a, 0x0000, | ||
1602 | }; | ||
1603 | int i, err; | ||
1604 | |||
1605 | /* set uC clock and activate it */ | ||
1606 | err = set_phy_regs(phy, uCclock40MHz); | ||
1607 | msleep(500); | ||
1608 | if (err) | ||
1609 | return err; | ||
1610 | err = set_phy_regs(phy, uCclockActivate); | ||
1611 | msleep(500); | ||
1612 | if (err) | ||
1613 | return err; | ||
1614 | |||
1615 | /* write TWINAX EDC firmware into PHY */ | ||
1616 | for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) | ||
1617 | err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i], | ||
1618 | twinax_edc[i + 1]); | ||
1619 | /* activate uC */ | ||
1620 | err = set_phy_regs(phy, uCactivate); | ||
1621 | if (!err) | ||
1622 | phy->priv = edc_twinax; | ||
1623 | return err; | ||
1624 | } | ||
1625 | |||
1626 | /* | ||
1627 | * Return Module Type. | ||
1628 | */ | ||
1629 | static int ael2020_get_module_type(struct cphy *phy, int delay_ms) | ||
1630 | { | ||
1631 | int v; | ||
1632 | unsigned int stat; | ||
1633 | |||
1634 | v = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_STAT, &stat); | ||
1635 | if (v) | ||
1636 | return v; | ||
1637 | |||
1638 | if (stat & (0x1 << (AEL2020_GPIO_MODDET*4))) { | ||
1639 | /* module absent */ | ||
1640 | return phy_modtype_none; | ||
1641 | } | ||
1642 | |||
1643 | return ael2xxx_get_module_type(phy, delay_ms); | ||
1644 | } | ||
1645 | |||
1646 | /* | ||
1647 | * Enable PHY interrupts. We enable "Module Detection" interrupts (on any | ||
1648 | * state transition) and then generic Link Alarm Status Interrupt (LASI). | ||
1649 | */ | ||
1650 | static int ael2020_intr_enable(struct cphy *phy) | ||
1651 | { | ||
1652 | int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL, | ||
1653 | 0x2 << (AEL2020_GPIO_MODDET*4)); | ||
1654 | return err ? err : t3_phy_lasi_intr_enable(phy); | ||
1655 | } | ||
1656 | |||
1657 | /* | ||
1658 | * Disable PHY interrupts. The mirror of the above ... | ||
1659 | */ | ||
1660 | static int ael2020_intr_disable(struct cphy *phy) | ||
1661 | { | ||
1662 | int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL, | ||
1663 | 0x1 << (AEL2020_GPIO_MODDET*4)); | ||
1664 | return err ? err : t3_phy_lasi_intr_disable(phy); | ||
1665 | } | ||
1666 | |||
1667 | /* | ||
1668 | * Clear PHY interrupt state. | ||
1669 | */ | ||
1670 | static int ael2020_intr_clear(struct cphy *phy) | ||
1671 | { | ||
1672 | /* | ||
1673 | * The GPIO Interrupt register on the AEL2020 is a "Latching High" | ||
1674 | * (LH) register which is cleared to the current state when it's read. | ||
1675 | * Thus, we simply read the register and discard the result. | ||
1676 | */ | ||
1677 | unsigned int stat; | ||
1678 | int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_INTR, &stat); | ||
1679 | return err ? err : t3_phy_lasi_intr_clear(phy); | ||
1680 | } | ||
1681 | |||
1682 | /* | ||
1683 | * Reset the PHY and put it into a canonical operating state. | ||
1684 | */ | ||
1685 | static int ael2020_reset(struct cphy *phy, int wait) | ||
1686 | { | ||
1687 | static struct reg_val regs0[] = { | ||
1688 | /* Erratum #2: CDRLOL asserted, causing PMA link down status */ | ||
1689 | { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x3101 }, | ||
1690 | |||
1691 | /* force XAUI to send LF when RX_LOS is asserted */ | ||
1692 | { MDIO_MMD_PMAPMD, 0xcd40, 0xffff, 0x0001 }, | ||
1693 | |||
1694 | /* RX_LOS pin is active high */ | ||
1695 | { MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS, | ||
1696 | 0x0020, 0x0020 }, | ||
1697 | |||
1698 | /* output Module's Loss Of Signal (LOS) to LED */ | ||
1699 | { MDIO_MMD_PMAPMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT, | ||
1700 | 0xffff, 0x0004 }, | ||
1701 | { MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL, | ||
1702 | 0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) }, | ||
1703 | |||
1704 | /* end */ | ||
1705 | { 0, 0, 0, 0 } | ||
1706 | }; | ||
1707 | int err; | ||
1708 | unsigned int lasi_ctrl; | ||
1709 | |||
1710 | /* grab current interrupt state */ | ||
1711 | err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, | ||
1712 | &lasi_ctrl); | ||
1713 | if (err) | ||
1714 | return err; | ||
1715 | |||
1716 | err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 125); | ||
1717 | if (err) | ||
1718 | return err; | ||
1719 | msleep(100); | ||
1720 | |||
1721 | /* basic initialization for all module types */ | ||
1722 | phy->priv = edc_none; | ||
1723 | err = set_phy_regs(phy, regs0); | ||
1724 | if (err) | ||
1725 | return err; | ||
1726 | |||
1727 | /* determine module type and perform appropriate initialization */ | ||
1728 | err = ael2020_get_module_type(phy, 0); | ||
1729 | if (err < 0) | ||
1730 | return err; | ||
1731 | phy->modtype = (u8)err; | ||
1732 | if (err == phy_modtype_twinax || err == phy_modtype_twinax_long) | ||
1733 | err = ael2020_setup_twinax_edc(phy, err); | ||
1734 | else | ||
1735 | err = ael2020_setup_sr_edc(phy); | ||
1736 | if (err) | ||
1737 | return err; | ||
1738 | |||
1739 | /* reset wipes out interrupts, reenable them if they were on */ | ||
1740 | if (lasi_ctrl & 1) | ||
1741 | err = ael2005_intr_enable(phy); | ||
1742 | return err; | ||
1743 | } | ||
1744 | |||
1745 | /* | ||
1746 | * Handle a PHY interrupt. | ||
1747 | */ | ||
1748 | static int ael2020_intr_handler(struct cphy *phy) | ||
1749 | { | ||
1750 | unsigned int stat; | ||
1751 | int ret, edc_needed, cause = 0; | ||
1752 | |||
1753 | ret = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_INTR, &stat); | ||
1754 | if (ret) | ||
1755 | return ret; | ||
1756 | |||
1757 | if (stat & (0x1 << AEL2020_GPIO_MODDET)) { | ||
1758 | /* modules have max 300 ms init time after hot plug */ | ||
1759 | ret = ael2020_get_module_type(phy, 300); | ||
1760 | if (ret < 0) | ||
1761 | return ret; | ||
1762 | |||
1763 | phy->modtype = (u8)ret; | ||
1764 | if (ret == phy_modtype_none) | ||
1765 | edc_needed = phy->priv; /* on unplug retain EDC */ | ||
1766 | else if (ret == phy_modtype_twinax || | ||
1767 | ret == phy_modtype_twinax_long) | ||
1768 | edc_needed = edc_twinax; | ||
1769 | else | ||
1770 | edc_needed = edc_sr; | ||
1771 | |||
1772 | if (edc_needed != phy->priv) { | ||
1773 | ret = ael2020_reset(phy, 0); | ||
1774 | return ret ? ret : cphy_cause_module_change; | ||
1775 | } | ||
1776 | cause = cphy_cause_module_change; | ||
1777 | } | ||
1778 | |||
1779 | ret = t3_phy_lasi_intr_handler(phy); | ||
1780 | if (ret < 0) | ||
1781 | return ret; | ||
1782 | |||
1783 | ret |= cause; | ||
1784 | return ret ? ret : cphy_cause_link_change; | ||
1785 | } | ||
1786 | |||
1787 | static struct cphy_ops ael2020_ops = { | ||
1788 | .reset = ael2020_reset, | ||
1789 | .intr_enable = ael2020_intr_enable, | ||
1790 | .intr_disable = ael2020_intr_disable, | ||
1791 | .intr_clear = ael2020_intr_clear, | ||
1792 | .intr_handler = ael2020_intr_handler, | ||
1793 | .get_link_status = get_link_status_r, | ||
1794 | .power_down = ael1002_power_down, | ||
1795 | .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | ||
1796 | }; | ||
1797 | |||
1798 | int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, | ||
1799 | const struct mdio_ops *mdio_ops) | ||
1800 | { | ||
1801 | cphy_init(phy, adapter, phy_addr, &ael2020_ops, mdio_ops, | ||
1802 | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | | ||
1803 | SUPPORTED_IRQ, "10GBASE-R"); | ||
1804 | msleep(125); | ||
1805 | return 0; | ||
1806 | } | ||
1807 | |||
1808 | /* | ||
1115 | * Get link status for a 10GBASE-X device. | 1809 | * Get link status for a 10GBASE-X device. |
1116 | */ | 1810 | */ |
1117 | static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed, | 1811 | static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed, |
@@ -1119,12 +1813,15 @@ static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed, | |||
1119 | { | 1813 | { |
1120 | if (link_ok) { | 1814 | if (link_ok) { |
1121 | unsigned int stat0, stat1, stat2; | 1815 | unsigned int stat0, stat1, stat2; |
1122 | int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); | 1816 | int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, |
1817 | MDIO_PMA_RXDET, &stat0); | ||
1123 | 1818 | ||
1124 | if (!err) | 1819 | if (!err) |
1125 | err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1); | 1820 | err = t3_mdio_read(phy, MDIO_MMD_PCS, |
1821 | MDIO_PCS_10GBX_STAT1, &stat1); | ||
1126 | if (!err) | 1822 | if (!err) |
1127 | err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); | 1823 | err = t3_mdio_read(phy, MDIO_MMD_PHYXS, |
1824 | MDIO_PHYXS_LNSTAT, &stat2); | ||
1128 | if (err) | 1825 | if (err) |
1129 | return err; | 1826 | return err; |
1130 | *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1; | 1827 | *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1; |
@@ -1144,6 +1841,7 @@ static struct cphy_ops qt2045_ops = { | |||
1144 | .intr_handler = t3_phy_lasi_intr_handler, | 1841 | .intr_handler = t3_phy_lasi_intr_handler, |
1145 | .get_link_status = get_link_status_x, | 1842 | .get_link_status = get_link_status_x, |
1146 | .power_down = ael1006_power_down, | 1843 | .power_down = ael1006_power_down, |
1844 | .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | ||
1147 | }; | 1845 | }; |
1148 | 1846 | ||
1149 | int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, | 1847 | int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, |
@@ -1159,9 +1857,10 @@ int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, | |||
1159 | * Some cards where the PHY is supposed to be at address 0 actually | 1857 | * Some cards where the PHY is supposed to be at address 0 actually |
1160 | * have it at 1. | 1858 | * have it at 1. |
1161 | */ | 1859 | */ |
1162 | if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) && | 1860 | if (!phy_addr && |
1861 | !t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &stat) && | ||
1163 | stat == 0xffff) | 1862 | stat == 0xffff) |
1164 | phy->addr = 1; | 1863 | phy->mdio.prtad = 1; |
1165 | return 0; | 1864 | return 0; |
1166 | } | 1865 | } |
1167 | 1866 | ||
@@ -1175,15 +1874,16 @@ static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok, | |||
1175 | { | 1874 | { |
1176 | if (link_ok) { | 1875 | if (link_ok) { |
1177 | unsigned int status; | 1876 | unsigned int status; |
1877 | int prtad = phy->mdio.prtad; | ||
1178 | 1878 | ||
1179 | status = t3_read_reg(phy->adapter, | 1879 | status = t3_read_reg(phy->adapter, |
1180 | XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) | | 1880 | XGM_REG(A_XGM_SERDES_STAT0, prtad)) | |
1181 | t3_read_reg(phy->adapter, | 1881 | t3_read_reg(phy->adapter, |
1182 | XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) | | 1882 | XGM_REG(A_XGM_SERDES_STAT1, prtad)) | |
1183 | t3_read_reg(phy->adapter, | 1883 | t3_read_reg(phy->adapter, |
1184 | XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) | | 1884 | XGM_REG(A_XGM_SERDES_STAT2, prtad)) | |
1185 | t3_read_reg(phy->adapter, | 1885 | t3_read_reg(phy->adapter, |
1186 | XGM_REG(A_XGM_SERDES_STAT3, phy->addr)); | 1886 | XGM_REG(A_XGM_SERDES_STAT3, prtad)); |
1187 | *link_ok = !(status & F_LOWSIG0); | 1887 | *link_ok = !(status & F_LOWSIG0); |
1188 | } | 1888 | } |
1189 | if (speed) | 1889 | if (speed) |
@@ -1211,7 +1911,7 @@ static struct cphy_ops xaui_direct_ops = { | |||
1211 | int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, | 1911 | int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, |
1212 | int phy_addr, const struct mdio_ops *mdio_ops) | 1912 | int phy_addr, const struct mdio_ops *mdio_ops) |
1213 | { | 1913 | { |
1214 | cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops, | 1914 | cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops, |
1215 | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, | 1915 | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, |
1216 | "10GBASE-CX4"); | 1916 | "10GBASE-CX4"); |
1217 | return 0; | 1917 | return 0; |
diff --git a/drivers/net/cxgb3/aq100x.c b/drivers/net/cxgb3/aq100x.c new file mode 100644 index 000000000000..b1fd5bf836e4 --- /dev/null +++ b/drivers/net/cxgb3/aq100x.c | |||
@@ -0,0 +1,355 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved. | ||
3 | * | ||
4 | * This software is available to you under a choice of one of two | ||
5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
6 | * General Public License (GPL) Version 2, available from the file | ||
7 | * COPYING in the main directory of this source tree, or the | ||
8 | * OpenIB.org BSD license below: | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or | ||
11 | * without modification, are permitted provided that the following | ||
12 | * conditions are met: | ||
13 | * | ||
14 | * - Redistributions of source code must retain the above | ||
15 | * copyright notice, this list of conditions and the following | ||
16 | * disclaimer. | ||
17 | * | ||
18 | * - Redistributions in binary form must reproduce the above | ||
19 | * copyright notice, this list of conditions and the following | ||
20 | * disclaimer in the documentation and/or other materials | ||
21 | * provided with the distribution. | ||
22 | * | ||
23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
30 | * SOFTWARE. | ||
31 | */ | ||
32 | |||
33 | #include "common.h" | ||
34 | #include "regs.h" | ||
35 | |||
36 | enum { | ||
37 | /* MDIO_DEV_PMA_PMD registers */ | ||
38 | AQ_LINK_STAT = 0xe800, | ||
39 | AQ_IMASK_PMA = 0xf000, | ||
40 | |||
41 | /* MDIO_DEV_XGXS registers */ | ||
42 | AQ_XAUI_RX_CFG = 0xc400, | ||
43 | AQ_XAUI_TX_CFG = 0xe400, | ||
44 | |||
45 | /* MDIO_DEV_ANEG registers */ | ||
46 | AQ_1G_CTRL = 0xc400, | ||
47 | AQ_ANEG_STAT = 0xc800, | ||
48 | |||
49 | /* MDIO_DEV_VEND1 registers */ | ||
50 | AQ_FW_VERSION = 0x0020, | ||
51 | AQ_IFLAG_GLOBAL = 0xfc00, | ||
52 | AQ_IMASK_GLOBAL = 0xff00, | ||
53 | }; | ||
54 | |||
55 | enum { | ||
56 | IMASK_PMA = 1 << 2, | ||
57 | IMASK_GLOBAL = 1 << 15, | ||
58 | ADV_1G_FULL = 1 << 15, | ||
59 | ADV_1G_HALF = 1 << 14, | ||
60 | ADV_10G_FULL = 1 << 12, | ||
61 | AQ_RESET = (1 << 14) | (1 << 15), | ||
62 | AQ_LOWPOWER = 1 << 12, | ||
63 | }; | ||
64 | |||
65 | static int aq100x_reset(struct cphy *phy, int wait) | ||
66 | { | ||
67 | /* | ||
68 | * Ignore the caller specified wait time; always wait for the reset to | ||
69 | * complete. Can take up to 3s. | ||
70 | */ | ||
71 | int err = t3_phy_reset(phy, MDIO_MMD_VEND1, 3000); | ||
72 | |||
73 | if (err) | ||
74 | CH_WARN(phy->adapter, "PHY%d: reset failed (0x%x).\n", | ||
75 | phy->mdio.prtad, err); | ||
76 | |||
77 | return err; | ||
78 | } | ||
79 | |||
80 | static int aq100x_intr_enable(struct cphy *phy) | ||
81 | { | ||
82 | int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AQ_IMASK_PMA, IMASK_PMA); | ||
83 | if (err) | ||
84 | return err; | ||
85 | |||
86 | err = t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, IMASK_GLOBAL); | ||
87 | return err; | ||
88 | } | ||
89 | |||
90 | static int aq100x_intr_disable(struct cphy *phy) | ||
91 | { | ||
92 | return t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, 0); | ||
93 | } | ||
94 | |||
95 | static int aq100x_intr_clear(struct cphy *phy) | ||
96 | { | ||
97 | unsigned int v; | ||
98 | |||
99 | t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &v); | ||
100 | t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v); | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static int aq100x_intr_handler(struct cphy *phy) | ||
106 | { | ||
107 | int err; | ||
108 | unsigned int cause, v; | ||
109 | |||
110 | err = t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &cause); | ||
111 | if (err) | ||
112 | return err; | ||
113 | |||
114 | /* Read (and reset) the latching version of the status */ | ||
115 | t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v); | ||
116 | |||
117 | return cphy_cause_link_change; | ||
118 | } | ||
119 | |||
120 | static int aq100x_power_down(struct cphy *phy, int off) | ||
121 | { | ||
122 | return mdio_set_flag(&phy->mdio, phy->mdio.prtad, | ||
123 | MDIO_MMD_PMAPMD, MDIO_CTRL1, | ||
124 | MDIO_CTRL1_LPOWER, off); | ||
125 | } | ||
126 | |||
127 | static int aq100x_autoneg_enable(struct cphy *phy) | ||
128 | { | ||
129 | int err; | ||
130 | |||
131 | err = aq100x_power_down(phy, 0); | ||
132 | if (!err) | ||
133 | err = mdio_set_flag(&phy->mdio, phy->mdio.prtad, | ||
134 | MDIO_MMD_AN, MDIO_CTRL1, | ||
135 | BMCR_ANENABLE | BMCR_ANRESTART, 1); | ||
136 | |||
137 | return err; | ||
138 | } | ||
139 | |||
140 | static int aq100x_autoneg_restart(struct cphy *phy) | ||
141 | { | ||
142 | int err; | ||
143 | |||
144 | err = aq100x_power_down(phy, 0); | ||
145 | if (!err) | ||
146 | err = mdio_set_flag(&phy->mdio, phy->mdio.prtad, | ||
147 | MDIO_MMD_AN, MDIO_CTRL1, | ||
148 | BMCR_ANENABLE | BMCR_ANRESTART, 1); | ||
149 | |||
150 | return err; | ||
151 | } | ||
152 | |||
153 | static int aq100x_advertise(struct cphy *phy, unsigned int advertise_map) | ||
154 | { | ||
155 | unsigned int adv; | ||
156 | int err; | ||
157 | |||
158 | /* 10G advertisement */ | ||
159 | adv = 0; | ||
160 | if (advertise_map & ADVERTISED_10000baseT_Full) | ||
161 | adv |= ADV_10G_FULL; | ||
162 | err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, | ||
163 | ADV_10G_FULL, adv); | ||
164 | if (err) | ||
165 | return err; | ||
166 | |||
167 | /* 1G advertisement */ | ||
168 | adv = 0; | ||
169 | if (advertise_map & ADVERTISED_1000baseT_Full) | ||
170 | adv |= ADV_1G_FULL; | ||
171 | if (advertise_map & ADVERTISED_1000baseT_Half) | ||
172 | adv |= ADV_1G_HALF; | ||
173 | err = t3_mdio_change_bits(phy, MDIO_MMD_AN, AQ_1G_CTRL, | ||
174 | ADV_1G_FULL | ADV_1G_HALF, adv); | ||
175 | if (err) | ||
176 | return err; | ||
177 | |||
178 | /* 100M, pause advertisement */ | ||
179 | adv = 0; | ||
180 | if (advertise_map & ADVERTISED_100baseT_Half) | ||
181 | adv |= ADVERTISE_100HALF; | ||
182 | if (advertise_map & ADVERTISED_100baseT_Full) | ||
183 | adv |= ADVERTISE_100FULL; | ||
184 | if (advertise_map & ADVERTISED_Pause) | ||
185 | adv |= ADVERTISE_PAUSE_CAP; | ||
186 | if (advertise_map & ADVERTISED_Asym_Pause) | ||
187 | adv |= ADVERTISE_PAUSE_ASYM; | ||
188 | err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_ADVERTISE, | ||
189 | 0xfe0, adv); | ||
190 | |||
191 | return err; | ||
192 | } | ||
193 | |||
194 | static int aq100x_set_loopback(struct cphy *phy, int mmd, int dir, int enable) | ||
195 | { | ||
196 | return mdio_set_flag(&phy->mdio, phy->mdio.prtad, | ||
197 | MDIO_MMD_PMAPMD, MDIO_CTRL1, | ||
198 | BMCR_LOOPBACK, enable); | ||
199 | } | ||
200 | |||
201 | static int aq100x_set_speed_duplex(struct cphy *phy, int speed, int duplex) | ||
202 | { | ||
203 | /* no can do */ | ||
204 | return -1; | ||
205 | } | ||
206 | |||
207 | static int aq100x_get_link_status(struct cphy *phy, int *link_ok, | ||
208 | int *speed, int *duplex, int *fc) | ||
209 | { | ||
210 | int err; | ||
211 | unsigned int v; | ||
212 | |||
213 | if (link_ok) { | ||
214 | err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AQ_LINK_STAT, &v); | ||
215 | if (err) | ||
216 | return err; | ||
217 | |||
218 | *link_ok = v & 1; | ||
219 | if (!*link_ok) | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | err = t3_mdio_read(phy, MDIO_MMD_AN, AQ_ANEG_STAT, &v); | ||
224 | if (err) | ||
225 | return err; | ||
226 | |||
227 | if (speed) { | ||
228 | switch (v & 0x6) { | ||
229 | case 0x6: | ||
230 | *speed = SPEED_10000; | ||
231 | break; | ||
232 | case 0x4: | ||
233 | *speed = SPEED_1000; | ||
234 | break; | ||
235 | case 0x2: | ||
236 | *speed = SPEED_100; | ||
237 | break; | ||
238 | case 0x0: | ||
239 | *speed = SPEED_10; | ||
240 | break; | ||
241 | } | ||
242 | } | ||
243 | |||
244 | if (duplex) | ||
245 | *duplex = v & 1 ? DUPLEX_FULL : DUPLEX_HALF; | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static struct cphy_ops aq100x_ops = { | ||
251 | .reset = aq100x_reset, | ||
252 | .intr_enable = aq100x_intr_enable, | ||
253 | .intr_disable = aq100x_intr_disable, | ||
254 | .intr_clear = aq100x_intr_clear, | ||
255 | .intr_handler = aq100x_intr_handler, | ||
256 | .autoneg_enable = aq100x_autoneg_enable, | ||
257 | .autoneg_restart = aq100x_autoneg_restart, | ||
258 | .advertise = aq100x_advertise, | ||
259 | .set_loopback = aq100x_set_loopback, | ||
260 | .set_speed_duplex = aq100x_set_speed_duplex, | ||
261 | .get_link_status = aq100x_get_link_status, | ||
262 | .power_down = aq100x_power_down, | ||
263 | .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | ||
264 | }; | ||
265 | |||
266 | int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, | ||
267 | const struct mdio_ops *mdio_ops) | ||
268 | { | ||
269 | unsigned int v, v2, gpio, wait; | ||
270 | int err; | ||
271 | |||
272 | cphy_init(phy, adapter, phy_addr, &aq100x_ops, mdio_ops, | ||
273 | SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full | | ||
274 | SUPPORTED_Autoneg | SUPPORTED_AUI, "1000/10GBASE-T"); | ||
275 | |||
276 | /* | ||
277 | * The PHY has been out of reset ever since the system powered up. So | ||
278 | * we do a hard reset over here. | ||
279 | */ | ||
280 | gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL; | ||
281 | t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0); | ||
282 | msleep(1); | ||
283 | t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio); | ||
284 | |||
285 | /* | ||
286 | * Give it enough time to load the firmware and get ready for mdio. | ||
287 | */ | ||
288 | msleep(1000); | ||
289 | wait = 500; /* in 10ms increments */ | ||
290 | do { | ||
291 | err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v); | ||
292 | if (err || v == 0xffff) { | ||
293 | |||
294 | /* Allow prep_adapter to succeed when ffff is read */ | ||
295 | |||
296 | CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n", | ||
297 | phy_addr, err, v); | ||
298 | goto done; | ||
299 | } | ||
300 | |||
301 | v &= AQ_RESET; | ||
302 | if (v) | ||
303 | msleep(10); | ||
304 | } while (v && --wait); | ||
305 | if (v) { | ||
306 | CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n", | ||
307 | phy_addr, v); | ||
308 | |||
309 | goto done; /* let prep_adapter succeed */ | ||
310 | } | ||
311 | |||
312 | /* Datasheet says 3s max but this has been observed */ | ||
313 | wait = (500 - wait) * 10 + 1000; | ||
314 | if (wait > 3000) | ||
315 | CH_WARN(adapter, "PHY%d: reset took %ums\n", phy_addr, wait); | ||
316 | |||
317 | /* Firmware version check. */ | ||
318 | t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_FW_VERSION, &v); | ||
319 | if (v != 30) { | ||
320 | CH_WARN(adapter, "PHY%d: unsupported firmware %d\n", | ||
321 | phy_addr, v); | ||
322 | return 0; /* allow t3_prep_adapter to succeed */ | ||
323 | } | ||
324 | |||
325 | /* | ||
326 | * The PHY should start in really-low-power mode. Prepare it for normal | ||
327 | * operations. | ||
328 | */ | ||
329 | err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v); | ||
330 | if (err) | ||
331 | return err; | ||
332 | if (v & AQ_LOWPOWER) { | ||
333 | err = t3_mdio_change_bits(phy, MDIO_MMD_VEND1, MDIO_CTRL1, | ||
334 | AQ_LOWPOWER, 0); | ||
335 | if (err) | ||
336 | return err; | ||
337 | msleep(10); | ||
338 | } else | ||
339 | CH_WARN(adapter, "PHY%d does not start in low power mode.\n", | ||
340 | phy_addr); | ||
341 | |||
342 | /* | ||
343 | * Verify XAUI settings, but let prep succeed no matter what. | ||
344 | */ | ||
345 | v = v2 = 0; | ||
346 | t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_RX_CFG, &v); | ||
347 | t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_TX_CFG, &v2); | ||
348 | if (v != 0x1b || v2 != 0x1b) | ||
349 | CH_WARN(adapter, | ||
350 | "PHY%d: incorrect XAUI settings (0x%x, 0x%x).\n", | ||
351 | phy_addr, v, v2); | ||
352 | |||
353 | done: | ||
354 | return err; | ||
355 | } | ||
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h index e508dc32f3ec..d21b705501a9 100644 --- a/drivers/net/cxgb3/common.h +++ b/drivers/net/cxgb3/common.h | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <linux/init.h> | 39 | #include <linux/init.h> |
40 | #include <linux/netdevice.h> | 40 | #include <linux/netdevice.h> |
41 | #include <linux/ethtool.h> | 41 | #include <linux/ethtool.h> |
42 | #include <linux/mii.h> | 42 | #include <linux/mdio.h> |
43 | #include "version.h" | 43 | #include "version.h" |
44 | 44 | ||
45 | #define CH_ERR(adap, fmt, ...) dev_err(&adap->pdev->dev, fmt, ## __VA_ARGS__) | 45 | #define CH_ERR(adap, fmt, ...) dev_err(&adap->pdev->dev, fmt, ## __VA_ARGS__) |
@@ -184,10 +184,11 @@ struct cphy; | |||
184 | struct adapter; | 184 | struct adapter; |
185 | 185 | ||
186 | struct mdio_ops { | 186 | struct mdio_ops { |
187 | int (*read)(struct adapter *adapter, int phy_addr, int mmd_addr, | 187 | int (*read)(struct net_device *dev, int phy_addr, int mmd_addr, |
188 | int reg_addr, unsigned int *val); | 188 | u16 reg_addr); |
189 | int (*write)(struct adapter *adapter, int phy_addr, int mmd_addr, | 189 | int (*write)(struct net_device *dev, int phy_addr, int mmd_addr, |
190 | int reg_addr, unsigned int val); | 190 | u16 reg_addr, u16 val); |
191 | unsigned mode_support; | ||
191 | }; | 192 | }; |
192 | 193 | ||
193 | struct adapter_info { | 194 | struct adapter_info { |
@@ -520,27 +521,6 @@ enum { | |||
520 | MAC_RXFIFO_SIZE = 32768 | 521 | MAC_RXFIFO_SIZE = 32768 |
521 | }; | 522 | }; |
522 | 523 | ||
523 | /* IEEE 802.3 specified MDIO devices */ | ||
524 | enum { | ||
525 | MDIO_DEV_PMA_PMD = 1, | ||
526 | MDIO_DEV_WIS = 2, | ||
527 | MDIO_DEV_PCS = 3, | ||
528 | MDIO_DEV_XGXS = 4, | ||
529 | MDIO_DEV_ANEG = 7, | ||
530 | MDIO_DEV_VEND1 = 30, | ||
531 | MDIO_DEV_VEND2 = 31 | ||
532 | }; | ||
533 | |||
534 | /* LASI control and status registers */ | ||
535 | enum { | ||
536 | RX_ALARM_CTRL = 0x9000, | ||
537 | TX_ALARM_CTRL = 0x9001, | ||
538 | LASI_CTRL = 0x9002, | ||
539 | RX_ALARM_STAT = 0x9003, | ||
540 | TX_ALARM_STAT = 0x9004, | ||
541 | LASI_STAT = 0x9005 | ||
542 | }; | ||
543 | |||
544 | /* PHY loopback direction */ | 524 | /* PHY loopback direction */ |
545 | enum { | 525 | enum { |
546 | PHY_LOOPBACK_TX = 1, | 526 | PHY_LOOPBACK_TX = 1, |
@@ -583,11 +563,12 @@ struct cphy_ops { | |||
583 | int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed, | 563 | int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed, |
584 | int *duplex, int *fc); | 564 | int *duplex, int *fc); |
585 | int (*power_down)(struct cphy *phy, int enable); | 565 | int (*power_down)(struct cphy *phy, int enable); |
566 | |||
567 | u32 mmds; | ||
586 | }; | 568 | }; |
587 | 569 | ||
588 | /* A PHY instance */ | 570 | /* A PHY instance */ |
589 | struct cphy { | 571 | struct cphy { |
590 | u8 addr; /* PHY address */ | ||
591 | u8 modtype; /* PHY module type */ | 572 | u8 modtype; /* PHY module type */ |
592 | short priv; /* scratch pad */ | 573 | short priv; /* scratch pad */ |
593 | unsigned int caps; /* PHY capabilities */ | 574 | unsigned int caps; /* PHY capabilities */ |
@@ -595,23 +576,23 @@ struct cphy { | |||
595 | const char *desc; /* PHY description */ | 576 | const char *desc; /* PHY description */ |
596 | unsigned long fifo_errors; /* FIFO over/under-flows */ | 577 | unsigned long fifo_errors; /* FIFO over/under-flows */ |
597 | const struct cphy_ops *ops; /* PHY operations */ | 578 | const struct cphy_ops *ops; /* PHY operations */ |
598 | int (*mdio_read)(struct adapter *adapter, int phy_addr, int mmd_addr, | 579 | struct mdio_if_info mdio; |
599 | int reg_addr, unsigned int *val); | ||
600 | int (*mdio_write)(struct adapter *adapter, int phy_addr, int mmd_addr, | ||
601 | int reg_addr, unsigned int val); | ||
602 | }; | 580 | }; |
603 | 581 | ||
604 | /* Convenience MDIO read/write wrappers */ | 582 | /* Convenience MDIO read/write wrappers */ |
605 | static inline int mdio_read(struct cphy *phy, int mmd, int reg, | 583 | static inline int t3_mdio_read(struct cphy *phy, int mmd, int reg, |
606 | unsigned int *valp) | 584 | unsigned int *valp) |
607 | { | 585 | { |
608 | return phy->mdio_read(phy->adapter, phy->addr, mmd, reg, valp); | 586 | int rc = phy->mdio.mdio_read(phy->mdio.dev, phy->mdio.prtad, mmd, reg); |
587 | *valp = (rc >= 0) ? rc : -1; | ||
588 | return (rc >= 0) ? 0 : rc; | ||
609 | } | 589 | } |
610 | 590 | ||
611 | static inline int mdio_write(struct cphy *phy, int mmd, int reg, | 591 | static inline int t3_mdio_write(struct cphy *phy, int mmd, int reg, |
612 | unsigned int val) | 592 | unsigned int val) |
613 | { | 593 | { |
614 | return phy->mdio_write(phy->adapter, phy->addr, mmd, reg, val); | 594 | return phy->mdio.mdio_write(phy->mdio.dev, phy->mdio.prtad, mmd, |
595 | reg, val); | ||
615 | } | 596 | } |
616 | 597 | ||
617 | /* Convenience initializer */ | 598 | /* Convenience initializer */ |
@@ -620,14 +601,16 @@ static inline void cphy_init(struct cphy *phy, struct adapter *adapter, | |||
620 | const struct mdio_ops *mdio_ops, | 601 | const struct mdio_ops *mdio_ops, |
621 | unsigned int caps, const char *desc) | 602 | unsigned int caps, const char *desc) |
622 | { | 603 | { |
623 | phy->addr = phy_addr; | ||
624 | phy->caps = caps; | 604 | phy->caps = caps; |
625 | phy->adapter = adapter; | 605 | phy->adapter = adapter; |
626 | phy->desc = desc; | 606 | phy->desc = desc; |
627 | phy->ops = phy_ops; | 607 | phy->ops = phy_ops; |
628 | if (mdio_ops) { | 608 | if (mdio_ops) { |
629 | phy->mdio_read = mdio_ops->read; | 609 | phy->mdio.prtad = phy_addr; |
630 | phy->mdio_write = mdio_ops->write; | 610 | phy->mdio.mmds = phy_ops->mmds; |
611 | phy->mdio.mode_support = mdio_ops->mode_support; | ||
612 | phy->mdio.mdio_read = mdio_ops->read; | ||
613 | phy->mdio.mdio_write = mdio_ops->write; | ||
631 | } | 614 | } |
632 | } | 615 | } |
633 | 616 | ||
@@ -819,8 +802,12 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, | |||
819 | int phy_addr, const struct mdio_ops *mdio_ops); | 802 | int phy_addr, const struct mdio_ops *mdio_ops); |
820 | int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, | 803 | int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, |
821 | int phy_addr, const struct mdio_ops *mdio_ops); | 804 | int phy_addr, const struct mdio_ops *mdio_ops); |
805 | int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter, | ||
806 | int phy_addr, const struct mdio_ops *mdio_ops); | ||
822 | int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, | 807 | int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, |
823 | const struct mdio_ops *mdio_ops); | 808 | const struct mdio_ops *mdio_ops); |
824 | int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, | 809 | int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, |
825 | int phy_addr, const struct mdio_ops *mdio_ops); | 810 | int phy_addr, const struct mdio_ops *mdio_ops); |
811 | int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, | ||
812 | int phy_addr, const struct mdio_ops *mdio_ops); | ||
826 | #endif /* __CHELSIO_COMMON_H */ | 813 | #endif /* __CHELSIO_COMMON_H */ |
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 7ea48414c6cb..538dda4422dc 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/netdevice.h> | 37 | #include <linux/netdevice.h> |
38 | #include <linux/etherdevice.h> | 38 | #include <linux/etherdevice.h> |
39 | #include <linux/if_vlan.h> | 39 | #include <linux/if_vlan.h> |
40 | #include <linux/mii.h> | 40 | #include <linux/mdio.h> |
41 | #include <linux/sockios.h> | 41 | #include <linux/sockios.h> |
42 | #include <linux/workqueue.h> | 42 | #include <linux/workqueue.h> |
43 | #include <linux/proc_fs.h> | 43 | #include <linux/proc_fs.h> |
@@ -91,6 +91,8 @@ static const struct pci_device_id cxgb3_pci_tbl[] = { | |||
91 | CH_DEVICE(0x31, 3), /* T3B20 */ | 91 | CH_DEVICE(0x31, 3), /* T3B20 */ |
92 | CH_DEVICE(0x32, 1), /* T3B02 */ | 92 | CH_DEVICE(0x32, 1), /* T3B02 */ |
93 | CH_DEVICE(0x35, 6), /* T3C20-derived T3C10 */ | 93 | CH_DEVICE(0x35, 6), /* T3C20-derived T3C10 */ |
94 | CH_DEVICE(0x36, 3), /* S320E-CR */ | ||
95 | CH_DEVICE(0x37, 7), /* N320E-G2 */ | ||
94 | {0,} | 96 | {0,} |
95 | }; | 97 | }; |
96 | 98 | ||
@@ -431,40 +433,78 @@ static int init_tp_parity(struct adapter *adap) | |||
431 | for (i = 0; i < 16; i++) { | 433 | for (i = 0; i < 16; i++) { |
432 | struct cpl_smt_write_req *req; | 434 | struct cpl_smt_write_req *req; |
433 | 435 | ||
434 | skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); | 436 | skb = alloc_skb(sizeof(*req), GFP_KERNEL); |
437 | if (!skb) | ||
438 | skb = adap->nofail_skb; | ||
439 | if (!skb) | ||
440 | goto alloc_skb_fail; | ||
441 | |||
435 | req = (struct cpl_smt_write_req *)__skb_put(skb, sizeof(*req)); | 442 | req = (struct cpl_smt_write_req *)__skb_put(skb, sizeof(*req)); |
436 | memset(req, 0, sizeof(*req)); | 443 | memset(req, 0, sizeof(*req)); |
437 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | 444 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); |
438 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i)); | 445 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i)); |
439 | req->iff = i; | 446 | req->iff = i; |
440 | t3_mgmt_tx(adap, skb); | 447 | t3_mgmt_tx(adap, skb); |
448 | if (skb == adap->nofail_skb) { | ||
449 | await_mgmt_replies(adap, cnt, i + 1); | ||
450 | adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); | ||
451 | if (!adap->nofail_skb) | ||
452 | goto alloc_skb_fail; | ||
453 | } | ||
441 | } | 454 | } |
442 | 455 | ||
443 | for (i = 0; i < 2048; i++) { | 456 | for (i = 0; i < 2048; i++) { |
444 | struct cpl_l2t_write_req *req; | 457 | struct cpl_l2t_write_req *req; |
445 | 458 | ||
446 | skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); | 459 | skb = alloc_skb(sizeof(*req), GFP_KERNEL); |
460 | if (!skb) | ||
461 | skb = adap->nofail_skb; | ||
462 | if (!skb) | ||
463 | goto alloc_skb_fail; | ||
464 | |||
447 | req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req)); | 465 | req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req)); |
448 | memset(req, 0, sizeof(*req)); | 466 | memset(req, 0, sizeof(*req)); |
449 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | 467 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); |
450 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, i)); | 468 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, i)); |
451 | req->params = htonl(V_L2T_W_IDX(i)); | 469 | req->params = htonl(V_L2T_W_IDX(i)); |
452 | t3_mgmt_tx(adap, skb); | 470 | t3_mgmt_tx(adap, skb); |
471 | if (skb == adap->nofail_skb) { | ||
472 | await_mgmt_replies(adap, cnt, 16 + i + 1); | ||
473 | adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); | ||
474 | if (!adap->nofail_skb) | ||
475 | goto alloc_skb_fail; | ||
476 | } | ||
453 | } | 477 | } |
454 | 478 | ||
455 | for (i = 0; i < 2048; i++) { | 479 | for (i = 0; i < 2048; i++) { |
456 | struct cpl_rte_write_req *req; | 480 | struct cpl_rte_write_req *req; |
457 | 481 | ||
458 | skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); | 482 | skb = alloc_skb(sizeof(*req), GFP_KERNEL); |
483 | if (!skb) | ||
484 | skb = adap->nofail_skb; | ||
485 | if (!skb) | ||
486 | goto alloc_skb_fail; | ||
487 | |||
459 | req = (struct cpl_rte_write_req *)__skb_put(skb, sizeof(*req)); | 488 | req = (struct cpl_rte_write_req *)__skb_put(skb, sizeof(*req)); |
460 | memset(req, 0, sizeof(*req)); | 489 | memset(req, 0, sizeof(*req)); |
461 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | 490 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); |
462 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RTE_WRITE_REQ, i)); | 491 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RTE_WRITE_REQ, i)); |
463 | req->l2t_idx = htonl(V_L2T_W_IDX(i)); | 492 | req->l2t_idx = htonl(V_L2T_W_IDX(i)); |
464 | t3_mgmt_tx(adap, skb); | 493 | t3_mgmt_tx(adap, skb); |
494 | if (skb == adap->nofail_skb) { | ||
495 | await_mgmt_replies(adap, cnt, 16 + 2048 + i + 1); | ||
496 | adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); | ||
497 | if (!adap->nofail_skb) | ||
498 | goto alloc_skb_fail; | ||
499 | } | ||
465 | } | 500 | } |
466 | 501 | ||
467 | skb = alloc_skb(sizeof(*greq), GFP_KERNEL | __GFP_NOFAIL); | 502 | skb = alloc_skb(sizeof(*greq), GFP_KERNEL); |
503 | if (!skb) | ||
504 | skb = adap->nofail_skb; | ||
505 | if (!skb) | ||
506 | goto alloc_skb_fail; | ||
507 | |||
468 | greq = (struct cpl_set_tcb_field *)__skb_put(skb, sizeof(*greq)); | 508 | greq = (struct cpl_set_tcb_field *)__skb_put(skb, sizeof(*greq)); |
469 | memset(greq, 0, sizeof(*greq)); | 509 | memset(greq, 0, sizeof(*greq)); |
470 | greq->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | 510 | greq->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); |
@@ -473,8 +513,17 @@ static int init_tp_parity(struct adapter *adap) | |||
473 | t3_mgmt_tx(adap, skb); | 513 | t3_mgmt_tx(adap, skb); |
474 | 514 | ||
475 | i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1); | 515 | i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1); |
516 | if (skb == adap->nofail_skb) { | ||
517 | i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1); | ||
518 | adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); | ||
519 | } | ||
520 | |||
476 | t3_tp_set_offload_mode(adap, 0); | 521 | t3_tp_set_offload_mode(adap, 0); |
477 | return i; | 522 | return i; |
523 | |||
524 | alloc_skb_fail: | ||
525 | t3_tp_set_offload_mode(adap, 0); | ||
526 | return -ENOMEM; | ||
478 | } | 527 | } |
479 | 528 | ||
480 | /** | 529 | /** |
@@ -869,7 +918,12 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo, | |||
869 | struct mngt_pktsched_wr *req; | 918 | struct mngt_pktsched_wr *req; |
870 | int ret; | 919 | int ret; |
871 | 920 | ||
872 | skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); | 921 | skb = alloc_skb(sizeof(*req), GFP_KERNEL); |
922 | if (!skb) | ||
923 | skb = adap->nofail_skb; | ||
924 | if (!skb) | ||
925 | return -ENOMEM; | ||
926 | |||
873 | req = (struct mngt_pktsched_wr *)skb_put(skb, sizeof(*req)); | 927 | req = (struct mngt_pktsched_wr *)skb_put(skb, sizeof(*req)); |
874 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT)); | 928 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT)); |
875 | req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET; | 929 | req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET; |
@@ -879,6 +933,12 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo, | |||
879 | req->max = hi; | 933 | req->max = hi; |
880 | req->binding = port; | 934 | req->binding = port; |
881 | ret = t3_mgmt_tx(adap, skb); | 935 | ret = t3_mgmt_tx(adap, skb); |
936 | if (skb == adap->nofail_skb) { | ||
937 | adap->nofail_skb = alloc_skb(sizeof(struct cpl_set_tcb_field), | ||
938 | GFP_KERNEL); | ||
939 | if (!adap->nofail_skb) | ||
940 | ret = -ENOMEM; | ||
941 | } | ||
882 | 942 | ||
883 | return ret; | 943 | return ret; |
884 | } | 944 | } |
@@ -1593,7 +1653,7 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
1593 | } | 1653 | } |
1594 | 1654 | ||
1595 | cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; | 1655 | cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; |
1596 | cmd->phy_address = p->phy.addr; | 1656 | cmd->phy_address = p->phy.mdio.prtad; |
1597 | cmd->transceiver = XCVR_EXTERNAL; | 1657 | cmd->transceiver = XCVR_EXTERNAL; |
1598 | cmd->autoneg = p->link_config.autoneg; | 1658 | cmd->autoneg = p->link_config.autoneg; |
1599 | cmd->maxtxpkt = 0; | 1659 | cmd->maxtxpkt = 0; |
@@ -2308,70 +2368,25 @@ static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd) | |||
2308 | struct mii_ioctl_data *data = if_mii(req); | 2368 | struct mii_ioctl_data *data = if_mii(req); |
2309 | struct port_info *pi = netdev_priv(dev); | 2369 | struct port_info *pi = netdev_priv(dev); |
2310 | struct adapter *adapter = pi->adapter; | 2370 | struct adapter *adapter = pi->adapter; |
2311 | int ret, mmd; | ||
2312 | 2371 | ||
2313 | switch (cmd) { | 2372 | switch (cmd) { |
2314 | case SIOCGMIIPHY: | 2373 | case SIOCGMIIREG: |
2315 | data->phy_id = pi->phy.addr; | 2374 | case SIOCSMIIREG: |
2375 | /* Convert phy_id from older PRTAD/DEVAD format */ | ||
2376 | if (is_10G(adapter) && | ||
2377 | !mdio_phy_id_is_c45(data->phy_id) && | ||
2378 | (data->phy_id & 0x1f00) && | ||
2379 | !(data->phy_id & 0xe0e0)) | ||
2380 | data->phy_id = mdio_phy_id_c45(data->phy_id >> 8, | ||
2381 | data->phy_id & 0x1f); | ||
2316 | /* FALLTHRU */ | 2382 | /* FALLTHRU */ |
2317 | case SIOCGMIIREG:{ | 2383 | case SIOCGMIIPHY: |
2318 | u32 val; | 2384 | return mdio_mii_ioctl(&pi->phy.mdio, data, cmd); |
2319 | struct cphy *phy = &pi->phy; | ||
2320 | |||
2321 | if (!phy->mdio_read) | ||
2322 | return -EOPNOTSUPP; | ||
2323 | if (is_10G(adapter)) { | ||
2324 | mmd = data->phy_id >> 8; | ||
2325 | if (!mmd) | ||
2326 | mmd = MDIO_DEV_PCS; | ||
2327 | else if (mmd > MDIO_DEV_VEND2) | ||
2328 | return -EINVAL; | ||
2329 | |||
2330 | ret = | ||
2331 | phy->mdio_read(adapter, data->phy_id & 0x1f, | ||
2332 | mmd, data->reg_num, &val); | ||
2333 | } else | ||
2334 | ret = | ||
2335 | phy->mdio_read(adapter, data->phy_id & 0x1f, | ||
2336 | 0, data->reg_num & 0x1f, | ||
2337 | &val); | ||
2338 | if (!ret) | ||
2339 | data->val_out = val; | ||
2340 | break; | ||
2341 | } | ||
2342 | case SIOCSMIIREG:{ | ||
2343 | struct cphy *phy = &pi->phy; | ||
2344 | |||
2345 | if (!capable(CAP_NET_ADMIN)) | ||
2346 | return -EPERM; | ||
2347 | if (!phy->mdio_write) | ||
2348 | return -EOPNOTSUPP; | ||
2349 | if (is_10G(adapter)) { | ||
2350 | mmd = data->phy_id >> 8; | ||
2351 | if (!mmd) | ||
2352 | mmd = MDIO_DEV_PCS; | ||
2353 | else if (mmd > MDIO_DEV_VEND2) | ||
2354 | return -EINVAL; | ||
2355 | |||
2356 | ret = | ||
2357 | phy->mdio_write(adapter, | ||
2358 | data->phy_id & 0x1f, mmd, | ||
2359 | data->reg_num, | ||
2360 | data->val_in); | ||
2361 | } else | ||
2362 | ret = | ||
2363 | phy->mdio_write(adapter, | ||
2364 | data->phy_id & 0x1f, 0, | ||
2365 | data->reg_num & 0x1f, | ||
2366 | data->val_in); | ||
2367 | break; | ||
2368 | } | ||
2369 | case SIOCCHIOCTL: | 2385 | case SIOCCHIOCTL: |
2370 | return cxgb_extension_ioctl(dev, req->ifr_data); | 2386 | return cxgb_extension_ioctl(dev, req->ifr_data); |
2371 | default: | 2387 | default: |
2372 | return -EOPNOTSUPP; | 2388 | return -EOPNOTSUPP; |
2373 | } | 2389 | } |
2374 | return ret; | ||
2375 | } | 2390 | } |
2376 | 2391 | ||
2377 | static int cxgb_change_mtu(struct net_device *dev, int new_mtu) | 2392 | static int cxgb_change_mtu(struct net_device *dev, int new_mtu) |
@@ -2496,14 +2511,16 @@ static void check_link_status(struct adapter *adapter) | |||
2496 | for_each_port(adapter, i) { | 2511 | for_each_port(adapter, i) { |
2497 | struct net_device *dev = adapter->port[i]; | 2512 | struct net_device *dev = adapter->port[i]; |
2498 | struct port_info *p = netdev_priv(dev); | 2513 | struct port_info *p = netdev_priv(dev); |
2514 | int link_fault; | ||
2499 | 2515 | ||
2500 | spin_lock_irq(&adapter->work_lock); | 2516 | spin_lock_irq(&adapter->work_lock); |
2501 | if (p->link_fault) { | 2517 | link_fault = p->link_fault; |
2518 | spin_unlock_irq(&adapter->work_lock); | ||
2519 | |||
2520 | if (link_fault) { | ||
2502 | t3_link_fault(adapter, i); | 2521 | t3_link_fault(adapter, i); |
2503 | spin_unlock_irq(&adapter->work_lock); | ||
2504 | continue; | 2522 | continue; |
2505 | } | 2523 | } |
2506 | spin_unlock_irq(&adapter->work_lock); | ||
2507 | 2524 | ||
2508 | if (!(p->phy.caps & SUPPORTED_IRQ) && netif_running(dev)) { | 2525 | if (!(p->phy.caps & SUPPORTED_IRQ) && netif_running(dev)) { |
2509 | t3_xgm_intr_disable(adapter, i); | 2526 | t3_xgm_intr_disable(adapter, i); |
@@ -3061,6 +3078,14 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
3061 | goto out_disable_device; | 3078 | goto out_disable_device; |
3062 | } | 3079 | } |
3063 | 3080 | ||
3081 | adapter->nofail_skb = | ||
3082 | alloc_skb(sizeof(struct cpl_set_tcb_field), GFP_KERNEL); | ||
3083 | if (!adapter->nofail_skb) { | ||
3084 | dev_err(&pdev->dev, "cannot allocate nofail buffer\n"); | ||
3085 | err = -ENOMEM; | ||
3086 | goto out_free_adapter; | ||
3087 | } | ||
3088 | |||
3064 | adapter->regs = ioremap_nocache(mmio_start, mmio_len); | 3089 | adapter->regs = ioremap_nocache(mmio_start, mmio_len); |
3065 | if (!adapter->regs) { | 3090 | if (!adapter->regs) { |
3066 | dev_err(&pdev->dev, "cannot map device registers\n"); | 3091 | dev_err(&pdev->dev, "cannot map device registers\n"); |
@@ -3104,7 +3129,6 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
3104 | netdev->mem_start = mmio_start; | 3129 | netdev->mem_start = mmio_start; |
3105 | netdev->mem_end = mmio_start + mmio_len - 1; | 3130 | netdev->mem_end = mmio_start + mmio_len - 1; |
3106 | netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; | 3131 | netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; |
3107 | netdev->features |= NETIF_F_LLTX; | ||
3108 | netdev->features |= NETIF_F_GRO; | 3132 | netdev->features |= NETIF_F_GRO; |
3109 | if (pci_using_dac) | 3133 | if (pci_using_dac) |
3110 | netdev->features |= NETIF_F_HIGHDMA; | 3134 | netdev->features |= NETIF_F_HIGHDMA; |
@@ -3218,6 +3242,8 @@ static void __devexit remove_one(struct pci_dev *pdev) | |||
3218 | free_netdev(adapter->port[i]); | 3242 | free_netdev(adapter->port[i]); |
3219 | 3243 | ||
3220 | iounmap(adapter->regs); | 3244 | iounmap(adapter->regs); |
3245 | if (adapter->nofail_skb) | ||
3246 | kfree_skb(adapter->nofail_skb); | ||
3221 | kfree(adapter); | 3247 | kfree(adapter); |
3222 | pci_release_regions(pdev); | 3248 | pci_release_regions(pdev); |
3223 | pci_disable_device(pdev); | 3249 | pci_disable_device(pdev); |
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index 620d80be6aac..f9f54b57b28c 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c | |||
@@ -566,13 +566,31 @@ static void t3_process_tid_release_list(struct work_struct *work) | |||
566 | spin_unlock_bh(&td->tid_release_lock); | 566 | spin_unlock_bh(&td->tid_release_lock); |
567 | 567 | ||
568 | skb = alloc_skb(sizeof(struct cpl_tid_release), | 568 | skb = alloc_skb(sizeof(struct cpl_tid_release), |
569 | GFP_KERNEL | __GFP_NOFAIL); | 569 | GFP_KERNEL); |
570 | if (!skb) | ||
571 | skb = td->nofail_skb; | ||
572 | if (!skb) { | ||
573 | spin_lock_bh(&td->tid_release_lock); | ||
574 | p->ctx = (void *)td->tid_release_list; | ||
575 | td->tid_release_list = (struct t3c_tid_entry *)p; | ||
576 | break; | ||
577 | } | ||
570 | mk_tid_release(skb, p - td->tid_maps.tid_tab); | 578 | mk_tid_release(skb, p - td->tid_maps.tid_tab); |
571 | cxgb3_ofld_send(tdev, skb); | 579 | cxgb3_ofld_send(tdev, skb); |
572 | p->ctx = NULL; | 580 | p->ctx = NULL; |
581 | if (skb == td->nofail_skb) | ||
582 | td->nofail_skb = | ||
583 | alloc_skb(sizeof(struct cpl_tid_release), | ||
584 | GFP_KERNEL); | ||
573 | spin_lock_bh(&td->tid_release_lock); | 585 | spin_lock_bh(&td->tid_release_lock); |
574 | } | 586 | } |
587 | td->release_list_incomplete = (td->tid_release_list == NULL) ? 0 : 1; | ||
575 | spin_unlock_bh(&td->tid_release_lock); | 588 | spin_unlock_bh(&td->tid_release_lock); |
589 | |||
590 | if (!td->nofail_skb) | ||
591 | td->nofail_skb = | ||
592 | alloc_skb(sizeof(struct cpl_tid_release), | ||
593 | GFP_KERNEL); | ||
576 | } | 594 | } |
577 | 595 | ||
578 | /* use ctx as a next pointer in the tid release list */ | 596 | /* use ctx as a next pointer in the tid release list */ |
@@ -585,7 +603,7 @@ void cxgb3_queue_tid_release(struct t3cdev *tdev, unsigned int tid) | |||
585 | p->ctx = (void *)td->tid_release_list; | 603 | p->ctx = (void *)td->tid_release_list; |
586 | p->client = NULL; | 604 | p->client = NULL; |
587 | td->tid_release_list = p; | 605 | td->tid_release_list = p; |
588 | if (!p->ctx) | 606 | if (!p->ctx || td->release_list_incomplete) |
589 | schedule_work(&td->tid_release_task); | 607 | schedule_work(&td->tid_release_task); |
590 | spin_unlock_bh(&td->tid_release_lock); | 608 | spin_unlock_bh(&td->tid_release_lock); |
591 | } | 609 | } |
@@ -1274,6 +1292,9 @@ int cxgb3_offload_activate(struct adapter *adapter) | |||
1274 | if (list_empty(&adapter_list)) | 1292 | if (list_empty(&adapter_list)) |
1275 | register_netevent_notifier(&nb); | 1293 | register_netevent_notifier(&nb); |
1276 | 1294 | ||
1295 | t->nofail_skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_KERNEL); | ||
1296 | t->release_list_incomplete = 0; | ||
1297 | |||
1277 | add_adapter(adapter); | 1298 | add_adapter(adapter); |
1278 | return 0; | 1299 | return 0; |
1279 | 1300 | ||
@@ -1298,6 +1319,8 @@ void cxgb3_offload_deactivate(struct adapter *adapter) | |||
1298 | T3C_DATA(tdev) = NULL; | 1319 | T3C_DATA(tdev) = NULL; |
1299 | t3_free_l2t(L2DATA(tdev)); | 1320 | t3_free_l2t(L2DATA(tdev)); |
1300 | L2DATA(tdev) = NULL; | 1321 | L2DATA(tdev) = NULL; |
1322 | if (t->nofail_skb) | ||
1323 | kfree_skb(t->nofail_skb); | ||
1301 | kfree(t); | 1324 | kfree(t); |
1302 | } | 1325 | } |
1303 | 1326 | ||
diff --git a/drivers/net/cxgb3/cxgb3_offload.h b/drivers/net/cxgb3/cxgb3_offload.h index a8e8e5fcdf84..55945f422aec 100644 --- a/drivers/net/cxgb3/cxgb3_offload.h +++ b/drivers/net/cxgb3/cxgb3_offload.h | |||
@@ -191,6 +191,9 @@ struct t3c_data { | |||
191 | struct t3c_tid_entry *tid_release_list; | 191 | struct t3c_tid_entry *tid_release_list; |
192 | spinlock_t tid_release_lock; | 192 | spinlock_t tid_release_lock; |
193 | struct work_struct tid_release_task; | 193 | struct work_struct tid_release_task; |
194 | |||
195 | struct sk_buff *nofail_skb; | ||
196 | unsigned int release_list_incomplete; | ||
194 | }; | 197 | }; |
195 | 198 | ||
196 | /* | 199 | /* |
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 26d3587f3399..29c79eb43beb 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c | |||
@@ -355,7 +355,7 @@ static void clear_rx_desc(struct pci_dev *pdev, const struct sge_fl *q, | |||
355 | (*d->pg_chunk.p_cnt)--; | 355 | (*d->pg_chunk.p_cnt)--; |
356 | if (!*d->pg_chunk.p_cnt) | 356 | if (!*d->pg_chunk.p_cnt) |
357 | pci_unmap_page(pdev, | 357 | pci_unmap_page(pdev, |
358 | pci_unmap_addr(&d->pg_chunk, mapping), | 358 | d->pg_chunk.mapping, |
359 | q->alloc_size, PCI_DMA_FROMDEVICE); | 359 | q->alloc_size, PCI_DMA_FROMDEVICE); |
360 | 360 | ||
361 | put_page(d->pg_chunk.page); | 361 | put_page(d->pg_chunk.page); |
@@ -454,7 +454,7 @@ static int alloc_pg_chunk(struct adapter *adapter, struct sge_fl *q, | |||
454 | q->pg_chunk.offset = 0; | 454 | q->pg_chunk.offset = 0; |
455 | mapping = pci_map_page(adapter->pdev, q->pg_chunk.page, | 455 | mapping = pci_map_page(adapter->pdev, q->pg_chunk.page, |
456 | 0, q->alloc_size, PCI_DMA_FROMDEVICE); | 456 | 0, q->alloc_size, PCI_DMA_FROMDEVICE); |
457 | pci_unmap_addr_set(&q->pg_chunk, mapping, mapping); | 457 | q->pg_chunk.mapping = mapping; |
458 | } | 458 | } |
459 | sd->pg_chunk = q->pg_chunk; | 459 | sd->pg_chunk = q->pg_chunk; |
460 | 460 | ||
@@ -511,8 +511,7 @@ static int refill_fl(struct adapter *adap, struct sge_fl *q, int n, gfp_t gfp) | |||
511 | nomem: q->alloc_failed++; | 511 | nomem: q->alloc_failed++; |
512 | break; | 512 | break; |
513 | } | 513 | } |
514 | mapping = pci_unmap_addr(&sd->pg_chunk, mapping) + | 514 | mapping = sd->pg_chunk.mapping + sd->pg_chunk.offset; |
515 | sd->pg_chunk.offset; | ||
516 | pci_unmap_addr_set(sd, dma_addr, mapping); | 515 | pci_unmap_addr_set(sd, dma_addr, mapping); |
517 | 516 | ||
518 | add_one_rx_chunk(mapping, d, q->gen); | 517 | add_one_rx_chunk(mapping, d, q->gen); |
@@ -654,7 +653,8 @@ static void t3_reset_qset(struct sge_qset *q) | |||
654 | q->txq_stopped = 0; | 653 | q->txq_stopped = 0; |
655 | q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */ | 654 | q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */ |
656 | q->rx_reclaim_timer.function = NULL; | 655 | q->rx_reclaim_timer.function = NULL; |
657 | q->lro_frag_tbl.nr_frags = q->lro_frag_tbl.len = 0; | 656 | q->nomem = 0; |
657 | napi_free_frags(&q->napi); | ||
658 | } | 658 | } |
659 | 659 | ||
660 | 660 | ||
@@ -881,7 +881,7 @@ recycle: | |||
881 | (*sd->pg_chunk.p_cnt)--; | 881 | (*sd->pg_chunk.p_cnt)--; |
882 | if (!*sd->pg_chunk.p_cnt) | 882 | if (!*sd->pg_chunk.p_cnt) |
883 | pci_unmap_page(adap->pdev, | 883 | pci_unmap_page(adap->pdev, |
884 | pci_unmap_addr(&sd->pg_chunk, mapping), | 884 | sd->pg_chunk.mapping, |
885 | fl->alloc_size, | 885 | fl->alloc_size, |
886 | PCI_DMA_FROMDEVICE); | 886 | PCI_DMA_FROMDEVICE); |
887 | if (!skb) { | 887 | if (!skb) { |
@@ -1240,7 +1240,6 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1240 | q = &qs->txq[TXQ_ETH]; | 1240 | q = &qs->txq[TXQ_ETH]; |
1241 | txq = netdev_get_tx_queue(dev, qidx); | 1241 | txq = netdev_get_tx_queue(dev, qidx); |
1242 | 1242 | ||
1243 | spin_lock(&q->lock); | ||
1244 | reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK); | 1243 | reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK); |
1245 | 1244 | ||
1246 | credits = q->size - q->in_use; | 1245 | credits = q->size - q->in_use; |
@@ -1251,7 +1250,6 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1251 | dev_err(&adap->pdev->dev, | 1250 | dev_err(&adap->pdev->dev, |
1252 | "%s: Tx ring %u full while queue awake!\n", | 1251 | "%s: Tx ring %u full while queue awake!\n", |
1253 | dev->name, q->cntxt_id & 7); | 1252 | dev->name, q->cntxt_id & 7); |
1254 | spin_unlock(&q->lock); | ||
1255 | return NETDEV_TX_BUSY; | 1253 | return NETDEV_TX_BUSY; |
1256 | } | 1254 | } |
1257 | 1255 | ||
@@ -1285,9 +1283,6 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1285 | if (vlan_tx_tag_present(skb) && pi->vlan_grp) | 1283 | if (vlan_tx_tag_present(skb) && pi->vlan_grp) |
1286 | qs->port_stats[SGE_PSTAT_VLANINS]++; | 1284 | qs->port_stats[SGE_PSTAT_VLANINS]++; |
1287 | 1285 | ||
1288 | dev->trans_start = jiffies; | ||
1289 | spin_unlock(&q->lock); | ||
1290 | |||
1291 | /* | 1286 | /* |
1292 | * We do not use Tx completion interrupts to free DMAd Tx packets. | 1287 | * We do not use Tx completion interrupts to free DMAd Tx packets. |
1293 | * This is good for performamce but means that we rely on new Tx | 1288 | * This is good for performamce but means that we rely on new Tx |
@@ -2074,20 +2069,19 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, | |||
2074 | struct sge_fl *fl, int len, int complete) | 2069 | struct sge_fl *fl, int len, int complete) |
2075 | { | 2070 | { |
2076 | struct rx_sw_desc *sd = &fl->sdesc[fl->cidx]; | 2071 | struct rx_sw_desc *sd = &fl->sdesc[fl->cidx]; |
2072 | struct sk_buff *skb = NULL; | ||
2077 | struct cpl_rx_pkt *cpl; | 2073 | struct cpl_rx_pkt *cpl; |
2078 | struct skb_frag_struct *rx_frag = qs->lro_frag_tbl.frags; | 2074 | struct skb_frag_struct *rx_frag; |
2079 | int nr_frags = qs->lro_frag_tbl.nr_frags; | 2075 | int nr_frags; |
2080 | int frag_len = qs->lro_frag_tbl.len; | ||
2081 | int offset = 0; | 2076 | int offset = 0; |
2082 | 2077 | ||
2083 | if (!nr_frags) { | 2078 | if (!qs->nomem) { |
2084 | offset = 2 + sizeof(struct cpl_rx_pkt); | 2079 | skb = napi_get_frags(&qs->napi); |
2085 | qs->lro_va = cpl = sd->pg_chunk.va + 2; | 2080 | qs->nomem = !skb; |
2086 | } | 2081 | } |
2087 | 2082 | ||
2088 | fl->credits--; | 2083 | fl->credits--; |
2089 | 2084 | ||
2090 | len -= offset; | ||
2091 | pci_dma_sync_single_for_cpu(adap->pdev, | 2085 | pci_dma_sync_single_for_cpu(adap->pdev, |
2092 | pci_unmap_addr(sd, dma_addr), | 2086 | pci_unmap_addr(sd, dma_addr), |
2093 | fl->buf_size - SGE_PG_RSVD, | 2087 | fl->buf_size - SGE_PG_RSVD, |
@@ -2096,25 +2090,42 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, | |||
2096 | (*sd->pg_chunk.p_cnt)--; | 2090 | (*sd->pg_chunk.p_cnt)--; |
2097 | if (!*sd->pg_chunk.p_cnt) | 2091 | if (!*sd->pg_chunk.p_cnt) |
2098 | pci_unmap_page(adap->pdev, | 2092 | pci_unmap_page(adap->pdev, |
2099 | pci_unmap_addr(&sd->pg_chunk, mapping), | 2093 | sd->pg_chunk.mapping, |
2100 | fl->alloc_size, | 2094 | fl->alloc_size, |
2101 | PCI_DMA_FROMDEVICE); | 2095 | PCI_DMA_FROMDEVICE); |
2102 | 2096 | ||
2097 | if (!skb) { | ||
2098 | put_page(sd->pg_chunk.page); | ||
2099 | if (complete) | ||
2100 | qs->nomem = 0; | ||
2101 | return; | ||
2102 | } | ||
2103 | |||
2104 | rx_frag = skb_shinfo(skb)->frags; | ||
2105 | nr_frags = skb_shinfo(skb)->nr_frags; | ||
2106 | |||
2107 | if (!nr_frags) { | ||
2108 | offset = 2 + sizeof(struct cpl_rx_pkt); | ||
2109 | qs->lro_va = sd->pg_chunk.va + 2; | ||
2110 | } | ||
2111 | len -= offset; | ||
2112 | |||
2103 | prefetch(qs->lro_va); | 2113 | prefetch(qs->lro_va); |
2104 | 2114 | ||
2105 | rx_frag += nr_frags; | 2115 | rx_frag += nr_frags; |
2106 | rx_frag->page = sd->pg_chunk.page; | 2116 | rx_frag->page = sd->pg_chunk.page; |
2107 | rx_frag->page_offset = sd->pg_chunk.offset + offset; | 2117 | rx_frag->page_offset = sd->pg_chunk.offset + offset; |
2108 | rx_frag->size = len; | 2118 | rx_frag->size = len; |
2109 | frag_len += len; | ||
2110 | qs->lro_frag_tbl.nr_frags++; | ||
2111 | qs->lro_frag_tbl.len = frag_len; | ||
2112 | 2119 | ||
2120 | skb->len += len; | ||
2121 | skb->data_len += len; | ||
2122 | skb->truesize += len; | ||
2123 | skb_shinfo(skb)->nr_frags++; | ||
2113 | 2124 | ||
2114 | if (!complete) | 2125 | if (!complete) |
2115 | return; | 2126 | return; |
2116 | 2127 | ||
2117 | qs->lro_frag_tbl.ip_summed = CHECKSUM_UNNECESSARY; | 2128 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
2118 | cpl = qs->lro_va; | 2129 | cpl = qs->lro_va; |
2119 | 2130 | ||
2120 | if (unlikely(cpl->vlan_valid)) { | 2131 | if (unlikely(cpl->vlan_valid)) { |
@@ -2123,15 +2134,11 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, | |||
2123 | struct vlan_group *grp = pi->vlan_grp; | 2134 | struct vlan_group *grp = pi->vlan_grp; |
2124 | 2135 | ||
2125 | if (likely(grp != NULL)) { | 2136 | if (likely(grp != NULL)) { |
2126 | vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan), | 2137 | vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan)); |
2127 | &qs->lro_frag_tbl); | 2138 | return; |
2128 | goto out; | ||
2129 | } | 2139 | } |
2130 | } | 2140 | } |
2131 | napi_gro_frags(&qs->napi, &qs->lro_frag_tbl); | 2141 | napi_gro_frags(&qs->napi); |
2132 | |||
2133 | out: | ||
2134 | qs->lro_frag_tbl.nr_frags = qs->lro_frag_tbl.len = 0; | ||
2135 | } | 2142 | } |
2136 | 2143 | ||
2137 | /** | 2144 | /** |
@@ -2300,8 +2307,6 @@ no_mem: | |||
2300 | if (fl->use_pages) { | 2307 | if (fl->use_pages) { |
2301 | void *addr = fl->sdesc[fl->cidx].pg_chunk.va; | 2308 | void *addr = fl->sdesc[fl->cidx].pg_chunk.va; |
2302 | 2309 | ||
2303 | prefetch(&qs->lro_frag_tbl); | ||
2304 | |||
2305 | prefetch(addr); | 2310 | prefetch(addr); |
2306 | #if L1_CACHE_BYTES < 128 | 2311 | #if L1_CACHE_BYTES < 128 |
2307 | prefetch(addr + L1_CACHE_BYTES); | 2312 | prefetch(addr + L1_CACHE_BYTES); |
@@ -2847,11 +2852,12 @@ static void sge_timer_tx(unsigned long data) | |||
2847 | unsigned int tbd[SGE_TXQ_PER_SET] = {0, 0}; | 2852 | unsigned int tbd[SGE_TXQ_PER_SET] = {0, 0}; |
2848 | unsigned long next_period; | 2853 | unsigned long next_period; |
2849 | 2854 | ||
2850 | if (spin_trylock(&qs->txq[TXQ_ETH].lock)) { | 2855 | if (__netif_tx_trylock(qs->tx_q)) { |
2851 | tbd[TXQ_ETH] = reclaim_completed_tx(adap, &qs->txq[TXQ_ETH], | 2856 | tbd[TXQ_ETH] = reclaim_completed_tx(adap, &qs->txq[TXQ_ETH], |
2852 | TX_RECLAIM_TIMER_CHUNK); | 2857 | TX_RECLAIM_TIMER_CHUNK); |
2853 | spin_unlock(&qs->txq[TXQ_ETH].lock); | 2858 | __netif_tx_unlock(qs->tx_q); |
2854 | } | 2859 | } |
2860 | |||
2855 | if (spin_trylock(&qs->txq[TXQ_OFLD].lock)) { | 2861 | if (spin_trylock(&qs->txq[TXQ_OFLD].lock)) { |
2856 | tbd[TXQ_OFLD] = reclaim_completed_tx(adap, &qs->txq[TXQ_OFLD], | 2862 | tbd[TXQ_OFLD] = reclaim_completed_tx(adap, &qs->txq[TXQ_OFLD], |
2857 | TX_RECLAIM_TIMER_CHUNK); | 2863 | TX_RECLAIM_TIMER_CHUNK); |
@@ -2859,8 +2865,8 @@ static void sge_timer_tx(unsigned long data) | |||
2859 | } | 2865 | } |
2860 | 2866 | ||
2861 | next_period = TX_RECLAIM_PERIOD >> | 2867 | next_period = TX_RECLAIM_PERIOD >> |
2862 | (max(tbd[TXQ_ETH], tbd[TXQ_OFLD]) / | 2868 | (max(tbd[TXQ_ETH], tbd[TXQ_OFLD]) / |
2863 | TX_RECLAIM_TIMER_CHUNK); | 2869 | TX_RECLAIM_TIMER_CHUNK); |
2864 | mod_timer(&qs->tx_reclaim_timer, jiffies + next_period); | 2870 | mod_timer(&qs->tx_reclaim_timer, jiffies + next_period); |
2865 | } | 2871 | } |
2866 | 2872 | ||
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index e1bd690ff831..870d44992c70 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c | |||
@@ -204,35 +204,33 @@ static void mi1_init(struct adapter *adap, const struct adapter_info *ai) | |||
204 | /* | 204 | /* |
205 | * MI1 read/write operations for clause 22 PHYs. | 205 | * MI1 read/write operations for clause 22 PHYs. |
206 | */ | 206 | */ |
207 | static int t3_mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr, | 207 | static int t3_mi1_read(struct net_device *dev, int phy_addr, int mmd_addr, |
208 | int reg_addr, unsigned int *valp) | 208 | u16 reg_addr) |
209 | { | 209 | { |
210 | struct port_info *pi = netdev_priv(dev); | ||
211 | struct adapter *adapter = pi->adapter; | ||
210 | int ret; | 212 | int ret; |
211 | u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr); | 213 | u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr); |
212 | 214 | ||
213 | if (mmd_addr) | ||
214 | return -EINVAL; | ||
215 | |||
216 | mutex_lock(&adapter->mdio_lock); | 215 | mutex_lock(&adapter->mdio_lock); |
217 | t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1)); | 216 | t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1)); |
218 | t3_write_reg(adapter, A_MI1_ADDR, addr); | 217 | t3_write_reg(adapter, A_MI1_ADDR, addr); |
219 | t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2)); | 218 | t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2)); |
220 | ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10); | 219 | ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10); |
221 | if (!ret) | 220 | if (!ret) |
222 | *valp = t3_read_reg(adapter, A_MI1_DATA); | 221 | ret = t3_read_reg(adapter, A_MI1_DATA); |
223 | mutex_unlock(&adapter->mdio_lock); | 222 | mutex_unlock(&adapter->mdio_lock); |
224 | return ret; | 223 | return ret; |
225 | } | 224 | } |
226 | 225 | ||
227 | static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr, | 226 | static int t3_mi1_write(struct net_device *dev, int phy_addr, int mmd_addr, |
228 | int reg_addr, unsigned int val) | 227 | u16 reg_addr, u16 val) |
229 | { | 228 | { |
229 | struct port_info *pi = netdev_priv(dev); | ||
230 | struct adapter *adapter = pi->adapter; | ||
230 | int ret; | 231 | int ret; |
231 | u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr); | 232 | u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr); |
232 | 233 | ||
233 | if (mmd_addr) | ||
234 | return -EINVAL; | ||
235 | |||
236 | mutex_lock(&adapter->mdio_lock); | 234 | mutex_lock(&adapter->mdio_lock); |
237 | t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1)); | 235 | t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1)); |
238 | t3_write_reg(adapter, A_MI1_ADDR, addr); | 236 | t3_write_reg(adapter, A_MI1_ADDR, addr); |
@@ -244,8 +242,9 @@ static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr, | |||
244 | } | 242 | } |
245 | 243 | ||
246 | static const struct mdio_ops mi1_mdio_ops = { | 244 | static const struct mdio_ops mi1_mdio_ops = { |
247 | t3_mi1_read, | 245 | .read = t3_mi1_read, |
248 | t3_mi1_write | 246 | .write = t3_mi1_write, |
247 | .mode_support = MDIO_SUPPORTS_C22 | ||
249 | }; | 248 | }; |
250 | 249 | ||
251 | /* | 250 | /* |
@@ -268,9 +267,11 @@ static int mi1_wr_addr(struct adapter *adapter, int phy_addr, int mmd_addr, | |||
268 | /* | 267 | /* |
269 | * MI1 read/write operations for indirect-addressed PHYs. | 268 | * MI1 read/write operations for indirect-addressed PHYs. |
270 | */ | 269 | */ |
271 | static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr, | 270 | static int mi1_ext_read(struct net_device *dev, int phy_addr, int mmd_addr, |
272 | int reg_addr, unsigned int *valp) | 271 | u16 reg_addr) |
273 | { | 272 | { |
273 | struct port_info *pi = netdev_priv(dev); | ||
274 | struct adapter *adapter = pi->adapter; | ||
274 | int ret; | 275 | int ret; |
275 | 276 | ||
276 | mutex_lock(&adapter->mdio_lock); | 277 | mutex_lock(&adapter->mdio_lock); |
@@ -280,15 +281,17 @@ static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr, | |||
280 | ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, | 281 | ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, |
281 | MDIO_ATTEMPTS, 10); | 282 | MDIO_ATTEMPTS, 10); |
282 | if (!ret) | 283 | if (!ret) |
283 | *valp = t3_read_reg(adapter, A_MI1_DATA); | 284 | ret = t3_read_reg(adapter, A_MI1_DATA); |
284 | } | 285 | } |
285 | mutex_unlock(&adapter->mdio_lock); | 286 | mutex_unlock(&adapter->mdio_lock); |
286 | return ret; | 287 | return ret; |
287 | } | 288 | } |
288 | 289 | ||
289 | static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr, | 290 | static int mi1_ext_write(struct net_device *dev, int phy_addr, int mmd_addr, |
290 | int reg_addr, unsigned int val) | 291 | u16 reg_addr, u16 val) |
291 | { | 292 | { |
293 | struct port_info *pi = netdev_priv(dev); | ||
294 | struct adapter *adapter = pi->adapter; | ||
292 | int ret; | 295 | int ret; |
293 | 296 | ||
294 | mutex_lock(&adapter->mdio_lock); | 297 | mutex_lock(&adapter->mdio_lock); |
@@ -304,8 +307,9 @@ static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr, | |||
304 | } | 307 | } |
305 | 308 | ||
306 | static const struct mdio_ops mi1_mdio_ext_ops = { | 309 | static const struct mdio_ops mi1_mdio_ext_ops = { |
307 | mi1_ext_read, | 310 | .read = mi1_ext_read, |
308 | mi1_ext_write | 311 | .write = mi1_ext_write, |
312 | .mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22 | ||
309 | }; | 313 | }; |
310 | 314 | ||
311 | /** | 315 | /** |
@@ -325,10 +329,10 @@ int t3_mdio_change_bits(struct cphy *phy, int mmd, int reg, unsigned int clear, | |||
325 | int ret; | 329 | int ret; |
326 | unsigned int val; | 330 | unsigned int val; |
327 | 331 | ||
328 | ret = mdio_read(phy, mmd, reg, &val); | 332 | ret = t3_mdio_read(phy, mmd, reg, &val); |
329 | if (!ret) { | 333 | if (!ret) { |
330 | val &= ~clear; | 334 | val &= ~clear; |
331 | ret = mdio_write(phy, mmd, reg, val | set); | 335 | ret = t3_mdio_write(phy, mmd, reg, val | set); |
332 | } | 336 | } |
333 | return ret; | 337 | return ret; |
334 | } | 338 | } |
@@ -348,15 +352,16 @@ int t3_phy_reset(struct cphy *phy, int mmd, int wait) | |||
348 | int err; | 352 | int err; |
349 | unsigned int ctl; | 353 | unsigned int ctl; |
350 | 354 | ||
351 | err = t3_mdio_change_bits(phy, mmd, MII_BMCR, BMCR_PDOWN, BMCR_RESET); | 355 | err = t3_mdio_change_bits(phy, mmd, MDIO_CTRL1, MDIO_CTRL1_LPOWER, |
356 | MDIO_CTRL1_RESET); | ||
352 | if (err || !wait) | 357 | if (err || !wait) |
353 | return err; | 358 | return err; |
354 | 359 | ||
355 | do { | 360 | do { |
356 | err = mdio_read(phy, mmd, MII_BMCR, &ctl); | 361 | err = t3_mdio_read(phy, mmd, MDIO_CTRL1, &ctl); |
357 | if (err) | 362 | if (err) |
358 | return err; | 363 | return err; |
359 | ctl &= BMCR_RESET; | 364 | ctl &= MDIO_CTRL1_RESET; |
360 | if (ctl) | 365 | if (ctl) |
361 | msleep(1); | 366 | msleep(1); |
362 | } while (ctl && --wait); | 367 | } while (ctl && --wait); |
@@ -377,7 +382,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert) | |||
377 | int err; | 382 | int err; |
378 | unsigned int val = 0; | 383 | unsigned int val = 0; |
379 | 384 | ||
380 | err = mdio_read(phy, 0, MII_CTRL1000, &val); | 385 | err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_CTRL1000, &val); |
381 | if (err) | 386 | if (err) |
382 | return err; | 387 | return err; |
383 | 388 | ||
@@ -387,7 +392,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert) | |||
387 | if (advert & ADVERTISED_1000baseT_Full) | 392 | if (advert & ADVERTISED_1000baseT_Full) |
388 | val |= ADVERTISE_1000FULL; | 393 | val |= ADVERTISE_1000FULL; |
389 | 394 | ||
390 | err = mdio_write(phy, 0, MII_CTRL1000, val); | 395 | err = t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_CTRL1000, val); |
391 | if (err) | 396 | if (err) |
392 | return err; | 397 | return err; |
393 | 398 | ||
@@ -404,7 +409,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert) | |||
404 | val |= ADVERTISE_PAUSE_CAP; | 409 | val |= ADVERTISE_PAUSE_CAP; |
405 | if (advert & ADVERTISED_Asym_Pause) | 410 | if (advert & ADVERTISED_Asym_Pause) |
406 | val |= ADVERTISE_PAUSE_ASYM; | 411 | val |= ADVERTISE_PAUSE_ASYM; |
407 | return mdio_write(phy, 0, MII_ADVERTISE, val); | 412 | return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val); |
408 | } | 413 | } |
409 | 414 | ||
410 | /** | 415 | /** |
@@ -427,7 +432,7 @@ int t3_phy_advertise_fiber(struct cphy *phy, unsigned int advert) | |||
427 | val |= ADVERTISE_1000XPAUSE; | 432 | val |= ADVERTISE_1000XPAUSE; |
428 | if (advert & ADVERTISED_Asym_Pause) | 433 | if (advert & ADVERTISED_Asym_Pause) |
429 | val |= ADVERTISE_1000XPSE_ASYM; | 434 | val |= ADVERTISE_1000XPSE_ASYM; |
430 | return mdio_write(phy, 0, MII_ADVERTISE, val); | 435 | return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val); |
431 | } | 436 | } |
432 | 437 | ||
433 | /** | 438 | /** |
@@ -444,7 +449,7 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex) | |||
444 | int err; | 449 | int err; |
445 | unsigned int ctl; | 450 | unsigned int ctl; |
446 | 451 | ||
447 | err = mdio_read(phy, 0, MII_BMCR, &ctl); | 452 | err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_BMCR, &ctl); |
448 | if (err) | 453 | if (err) |
449 | return err; | 454 | return err; |
450 | 455 | ||
@@ -462,34 +467,36 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex) | |||
462 | } | 467 | } |
463 | if (ctl & BMCR_SPEED1000) /* auto-negotiation required for GigE */ | 468 | if (ctl & BMCR_SPEED1000) /* auto-negotiation required for GigE */ |
464 | ctl |= BMCR_ANENABLE; | 469 | ctl |= BMCR_ANENABLE; |
465 | return mdio_write(phy, 0, MII_BMCR, ctl); | 470 | return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_BMCR, ctl); |
466 | } | 471 | } |
467 | 472 | ||
468 | int t3_phy_lasi_intr_enable(struct cphy *phy) | 473 | int t3_phy_lasi_intr_enable(struct cphy *phy) |
469 | { | 474 | { |
470 | return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 1); | 475 | return t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, |
476 | MDIO_PMA_LASI_LSALARM); | ||
471 | } | 477 | } |
472 | 478 | ||
473 | int t3_phy_lasi_intr_disable(struct cphy *phy) | 479 | int t3_phy_lasi_intr_disable(struct cphy *phy) |
474 | { | 480 | { |
475 | return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 0); | 481 | return t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, 0); |
476 | } | 482 | } |
477 | 483 | ||
478 | int t3_phy_lasi_intr_clear(struct cphy *phy) | 484 | int t3_phy_lasi_intr_clear(struct cphy *phy) |
479 | { | 485 | { |
480 | u32 val; | 486 | u32 val; |
481 | 487 | ||
482 | return mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &val); | 488 | return t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT, &val); |
483 | } | 489 | } |
484 | 490 | ||
485 | int t3_phy_lasi_intr_handler(struct cphy *phy) | 491 | int t3_phy_lasi_intr_handler(struct cphy *phy) |
486 | { | 492 | { |
487 | unsigned int status; | 493 | unsigned int status; |
488 | int err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &status); | 494 | int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT, |
495 | &status); | ||
489 | 496 | ||
490 | if (err) | 497 | if (err) |
491 | return err; | 498 | return err; |
492 | return (status & 1) ? cphy_cause_link_change : 0; | 499 | return (status & MDIO_PMA_LASI_LSALARM) ? cphy_cause_link_change : 0; |
493 | } | 500 | } |
494 | 501 | ||
495 | static const struct adapter_info t3_adap_info[] = { | 502 | static const struct adapter_info t3_adap_info[] = { |
@@ -519,6 +526,11 @@ static const struct adapter_info t3_adap_info[] = { | |||
519 | F_GPIO10_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, | 526 | F_GPIO10_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, |
520 | { S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, | 527 | { S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, |
521 | &mi1_mdio_ext_ops, "Chelsio T310" }, | 528 | &mi1_mdio_ext_ops, "Chelsio T310" }, |
529 | {1, 0, 0, | ||
530 | F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | | ||
531 | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL, | ||
532 | { S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, | ||
533 | &mi1_mdio_ext_ops, "Chelsio N320E-G2" }, | ||
522 | }; | 534 | }; |
523 | 535 | ||
524 | /* | 536 | /* |
@@ -545,6 +557,8 @@ static const struct port_type_info port_types[] = { | |||
545 | { t3_qt2045_phy_prep }, | 557 | { t3_qt2045_phy_prep }, |
546 | { t3_ael1006_phy_prep }, | 558 | { t3_ael1006_phy_prep }, |
547 | { NULL }, | 559 | { NULL }, |
560 | { t3_aq100x_phy_prep }, | ||
561 | { t3_ael2020_phy_prep }, | ||
548 | }; | 562 | }; |
549 | 563 | ||
550 | #define VPD_ENTRY(name, len) \ | 564 | #define VPD_ENTRY(name, len) \ |
@@ -1274,6 +1288,11 @@ void t3_link_fault(struct adapter *adapter, int port_id) | |||
1274 | A_XGM_INT_STATUS + mac->offset); | 1288 | A_XGM_INT_STATUS + mac->offset); |
1275 | link_fault &= F_LINKFAULTCHANGE; | 1289 | link_fault &= F_LINKFAULTCHANGE; |
1276 | 1290 | ||
1291 | link_ok = lc->link_ok; | ||
1292 | speed = lc->speed; | ||
1293 | duplex = lc->duplex; | ||
1294 | fc = lc->fc; | ||
1295 | |||
1277 | phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); | 1296 | phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); |
1278 | 1297 | ||
1279 | if (link_fault) { | 1298 | if (link_fault) { |
@@ -3779,7 +3798,7 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, | |||
3779 | 3798 | ||
3780 | adapter->params.info = ai; | 3799 | adapter->params.info = ai; |
3781 | adapter->params.nports = ai->nports0 + ai->nports1; | 3800 | adapter->params.nports = ai->nports0 + ai->nports1; |
3782 | adapter->params.chan_map = !!ai->nports0 | (!!ai->nports1 << 1); | 3801 | adapter->params.chan_map = (!!ai->nports0) | (!!ai->nports1 << 1); |
3783 | adapter->params.rev = t3_read_reg(adapter, A_PL_REV); | 3802 | adapter->params.rev = t3_read_reg(adapter, A_PL_REV); |
3784 | /* | 3803 | /* |
3785 | * We used to only run the "adapter check task" once a second if | 3804 | * We used to only run the "adapter check task" once a second if |
@@ -3859,6 +3878,7 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, | |||
3859 | return -EINVAL; | 3878 | return -EINVAL; |
3860 | } | 3879 | } |
3861 | 3880 | ||
3881 | p->phy.mdio.dev = adapter->port[i]; | ||
3862 | ret = pti->phy_prep(&p->phy, adapter, ai->phy_base_addr + j, | 3882 | ret = pti->phy_prep(&p->phy, adapter, ai->phy_base_addr + j, |
3863 | ai->mdio_ops); | 3883 | ai->mdio_ops); |
3864 | if (ret) | 3884 | if (ret) |
@@ -3918,7 +3938,7 @@ int t3_replay_prep_adapter(struct adapter *adapter) | |||
3918 | ; | 3938 | ; |
3919 | 3939 | ||
3920 | pti = &port_types[adapter->params.vpd.port_type[j]]; | 3940 | pti = &port_types[adapter->params.vpd.port_type[j]]; |
3921 | ret = pti->phy_prep(&p->phy, adapter, p->phy.addr, NULL); | 3941 | ret = pti->phy_prep(&p->phy, adapter, p->phy.mdio.prtad, NULL); |
3922 | if (ret) | 3942 | if (ret) |
3923 | return ret; | 3943 | return ret; |
3924 | p->phy.ops->power_down(&p->phy, 1); | 3944 | p->phy.ops->power_down(&p->phy, 1); |
diff --git a/drivers/net/cxgb3/version.h b/drivers/net/cxgb3/version.h index 7bf963ec5548..9d0bd9dd9ab1 100644 --- a/drivers/net/cxgb3/version.h +++ b/drivers/net/cxgb3/version.h | |||
@@ -35,10 +35,10 @@ | |||
35 | #define DRV_DESC "Chelsio T3 Network Driver" | 35 | #define DRV_DESC "Chelsio T3 Network Driver" |
36 | #define DRV_NAME "cxgb3" | 36 | #define DRV_NAME "cxgb3" |
37 | /* Driver version */ | 37 | /* Driver version */ |
38 | #define DRV_VERSION "1.1.2-ko" | 38 | #define DRV_VERSION "1.1.3-ko" |
39 | 39 | ||
40 | /* Firmware version */ | 40 | /* Firmware version */ |
41 | #define FW_VERSION_MAJOR 7 | 41 | #define FW_VERSION_MAJOR 7 |
42 | #define FW_VERSION_MINOR 1 | 42 | #define FW_VERSION_MINOR 4 |
43 | #define FW_VERSION_MICRO 0 | 43 | #define FW_VERSION_MICRO 0 |
44 | #endif /* __CHELSIO_VERSION_H */ | 44 | #endif /* __CHELSIO_VERSION_H */ |
diff --git a/drivers/net/cxgb3/vsc8211.c b/drivers/net/cxgb3/vsc8211.c index d07130971b8f..4f9a1c2724f4 100644 --- a/drivers/net/cxgb3/vsc8211.c +++ b/drivers/net/cxgb3/vsc8211.c | |||
@@ -91,17 +91,18 @@ enum { | |||
91 | */ | 91 | */ |
92 | static int vsc8211_reset(struct cphy *cphy, int wait) | 92 | static int vsc8211_reset(struct cphy *cphy, int wait) |
93 | { | 93 | { |
94 | return t3_phy_reset(cphy, 0, 0); | 94 | return t3_phy_reset(cphy, MDIO_DEVAD_NONE, 0); |
95 | } | 95 | } |
96 | 96 | ||
97 | static int vsc8211_intr_enable(struct cphy *cphy) | 97 | static int vsc8211_intr_enable(struct cphy *cphy) |
98 | { | 98 | { |
99 | return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, INTR_MASK); | 99 | return t3_mdio_write(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_ENABLE, |
100 | INTR_MASK); | ||
100 | } | 101 | } |
101 | 102 | ||
102 | static int vsc8211_intr_disable(struct cphy *cphy) | 103 | static int vsc8211_intr_disable(struct cphy *cphy) |
103 | { | 104 | { |
104 | return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, 0); | 105 | return t3_mdio_write(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_ENABLE, 0); |
105 | } | 106 | } |
106 | 107 | ||
107 | static int vsc8211_intr_clear(struct cphy *cphy) | 108 | static int vsc8211_intr_clear(struct cphy *cphy) |
@@ -109,18 +110,20 @@ static int vsc8211_intr_clear(struct cphy *cphy) | |||
109 | u32 val; | 110 | u32 val; |
110 | 111 | ||
111 | /* Clear PHY interrupts by reading the register. */ | 112 | /* Clear PHY interrupts by reading the register. */ |
112 | return mdio_read(cphy, 0, VSC8211_INTR_STATUS, &val); | 113 | return t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_STATUS, &val); |
113 | } | 114 | } |
114 | 115 | ||
115 | static int vsc8211_autoneg_enable(struct cphy *cphy) | 116 | static int vsc8211_autoneg_enable(struct cphy *cphy) |
116 | { | 117 | { |
117 | return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, | 118 | return t3_mdio_change_bits(cphy, MDIO_DEVAD_NONE, MII_BMCR, |
119 | BMCR_PDOWN | BMCR_ISOLATE, | ||
118 | BMCR_ANENABLE | BMCR_ANRESTART); | 120 | BMCR_ANENABLE | BMCR_ANRESTART); |
119 | } | 121 | } |
120 | 122 | ||
121 | static int vsc8211_autoneg_restart(struct cphy *cphy) | 123 | static int vsc8211_autoneg_restart(struct cphy *cphy) |
122 | { | 124 | { |
123 | return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, | 125 | return t3_mdio_change_bits(cphy, MDIO_DEVAD_NONE, MII_BMCR, |
126 | BMCR_PDOWN | BMCR_ISOLATE, | ||
124 | BMCR_ANRESTART); | 127 | BMCR_ANRESTART); |
125 | } | 128 | } |
126 | 129 | ||
@@ -130,9 +133,9 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok, | |||
130 | unsigned int bmcr, status, lpa, adv; | 133 | unsigned int bmcr, status, lpa, adv; |
131 | int err, sp = -1, dplx = -1, pause = 0; | 134 | int err, sp = -1, dplx = -1, pause = 0; |
132 | 135 | ||
133 | err = mdio_read(cphy, 0, MII_BMCR, &bmcr); | 136 | err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMCR, &bmcr); |
134 | if (!err) | 137 | if (!err) |
135 | err = mdio_read(cphy, 0, MII_BMSR, &status); | 138 | err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, &status); |
136 | if (err) | 139 | if (err) |
137 | return err; | 140 | return err; |
138 | 141 | ||
@@ -142,7 +145,8 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok, | |||
142 | * once more to get the current link state. | 145 | * once more to get the current link state. |
143 | */ | 146 | */ |
144 | if (!(status & BMSR_LSTATUS)) | 147 | if (!(status & BMSR_LSTATUS)) |
145 | err = mdio_read(cphy, 0, MII_BMSR, &status); | 148 | err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, |
149 | &status); | ||
146 | if (err) | 150 | if (err) |
147 | return err; | 151 | return err; |
148 | *link_ok = (status & BMSR_LSTATUS) != 0; | 152 | *link_ok = (status & BMSR_LSTATUS) != 0; |
@@ -156,7 +160,8 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok, | |||
156 | else | 160 | else |
157 | sp = SPEED_10; | 161 | sp = SPEED_10; |
158 | } else if (status & BMSR_ANEGCOMPLETE) { | 162 | } else if (status & BMSR_ANEGCOMPLETE) { |
159 | err = mdio_read(cphy, 0, VSC8211_AUX_CTRL_STAT, &status); | 163 | err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_AUX_CTRL_STAT, |
164 | &status); | ||
160 | if (err) | 165 | if (err) |
161 | return err; | 166 | return err; |
162 | 167 | ||
@@ -170,9 +175,11 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok, | |||
170 | sp = SPEED_1000; | 175 | sp = SPEED_1000; |
171 | 176 | ||
172 | if (fc && dplx == DUPLEX_FULL) { | 177 | if (fc && dplx == DUPLEX_FULL) { |
173 | err = mdio_read(cphy, 0, MII_LPA, &lpa); | 178 | err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_LPA, |
179 | &lpa); | ||
174 | if (!err) | 180 | if (!err) |
175 | err = mdio_read(cphy, 0, MII_ADVERTISE, &adv); | 181 | err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, |
182 | MII_ADVERTISE, &adv); | ||
176 | if (err) | 183 | if (err) |
177 | return err; | 184 | return err; |
178 | 185 | ||
@@ -202,9 +209,9 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok, | |||
202 | unsigned int bmcr, status, lpa, adv; | 209 | unsigned int bmcr, status, lpa, adv; |
203 | int err, sp = -1, dplx = -1, pause = 0; | 210 | int err, sp = -1, dplx = -1, pause = 0; |
204 | 211 | ||
205 | err = mdio_read(cphy, 0, MII_BMCR, &bmcr); | 212 | err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMCR, &bmcr); |
206 | if (!err) | 213 | if (!err) |
207 | err = mdio_read(cphy, 0, MII_BMSR, &status); | 214 | err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, &status); |
208 | if (err) | 215 | if (err) |
209 | return err; | 216 | return err; |
210 | 217 | ||
@@ -214,7 +221,8 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok, | |||
214 | * once more to get the current link state. | 221 | * once more to get the current link state. |
215 | */ | 222 | */ |
216 | if (!(status & BMSR_LSTATUS)) | 223 | if (!(status & BMSR_LSTATUS)) |
217 | err = mdio_read(cphy, 0, MII_BMSR, &status); | 224 | err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, |
225 | &status); | ||
218 | if (err) | 226 | if (err) |
219 | return err; | 227 | return err; |
220 | *link_ok = (status & BMSR_LSTATUS) != 0; | 228 | *link_ok = (status & BMSR_LSTATUS) != 0; |
@@ -228,9 +236,10 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok, | |||
228 | else | 236 | else |
229 | sp = SPEED_10; | 237 | sp = SPEED_10; |
230 | } else if (status & BMSR_ANEGCOMPLETE) { | 238 | } else if (status & BMSR_ANEGCOMPLETE) { |
231 | err = mdio_read(cphy, 0, MII_LPA, &lpa); | 239 | err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_LPA, &lpa); |
232 | if (!err) | 240 | if (!err) |
233 | err = mdio_read(cphy, 0, MII_ADVERTISE, &adv); | 241 | err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_ADVERTISE, |
242 | &adv); | ||
234 | if (err) | 243 | if (err) |
235 | return err; | 244 | return err; |
236 | 245 | ||
@@ -270,23 +279,23 @@ static int vsc8211_set_automdi(struct cphy *phy, int enable) | |||
270 | { | 279 | { |
271 | int err; | 280 | int err; |
272 | 281 | ||
273 | err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0x52b5); | 282 | err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0x52b5); |
274 | if (err) | 283 | if (err) |
275 | return err; | 284 | return err; |
276 | 285 | ||
277 | err = mdio_write(phy, 0, 18, 0x12); | 286 | err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 18, 0x12); |
278 | if (err) | 287 | if (err) |
279 | return err; | 288 | return err; |
280 | 289 | ||
281 | err = mdio_write(phy, 0, 17, enable ? 0x2803 : 0x3003); | 290 | err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 17, enable ? 0x2803 : 0x3003); |
282 | if (err) | 291 | if (err) |
283 | return err; | 292 | return err; |
284 | 293 | ||
285 | err = mdio_write(phy, 0, 16, 0x87fa); | 294 | err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 16, 0x87fa); |
286 | if (err) | 295 | if (err) |
287 | return err; | 296 | return err; |
288 | 297 | ||
289 | err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0); | 298 | err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0); |
290 | if (err) | 299 | if (err) |
291 | return err; | 300 | return err; |
292 | 301 | ||
@@ -315,7 +324,7 @@ static int vsc8211_intr_handler(struct cphy *cphy) | |||
315 | unsigned int cause; | 324 | unsigned int cause; |
316 | int err, cphy_cause = 0; | 325 | int err, cphy_cause = 0; |
317 | 326 | ||
318 | err = mdio_read(cphy, 0, VSC8211_INTR_STATUS, &cause); | 327 | err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_STATUS, &cause); |
319 | if (err) | 328 | if (err) |
320 | return err; | 329 | return err; |
321 | 330 | ||
@@ -367,12 +376,13 @@ int t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter, | |||
367 | SUPPORTED_TP | SUPPORTED_IRQ, "10/100/1000BASE-T"); | 376 | SUPPORTED_TP | SUPPORTED_IRQ, "10/100/1000BASE-T"); |
368 | msleep(20); /* PHY needs ~10ms to start responding to MDIO */ | 377 | msleep(20); /* PHY needs ~10ms to start responding to MDIO */ |
369 | 378 | ||
370 | err = mdio_read(phy, 0, VSC8211_EXT_CTRL, &val); | 379 | err = t3_mdio_read(phy, MDIO_DEVAD_NONE, VSC8211_EXT_CTRL, &val); |
371 | if (err) | 380 | if (err) |
372 | return err; | 381 | return err; |
373 | if (val & VSC_CTRL_MEDIA_MODE_HI) { | 382 | if (val & VSC_CTRL_MEDIA_MODE_HI) { |
374 | /* copper interface, just need to configure the LEDs */ | 383 | /* copper interface, just need to configure the LEDs */ |
375 | return mdio_write(phy, 0, VSC8211_LED_CTRL, 0x100); | 384 | return t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_LED_CTRL, |
385 | 0x100); | ||
376 | } | 386 | } |
377 | 387 | ||
378 | phy->caps = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | | 388 | phy->caps = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | |
@@ -380,20 +390,20 @@ int t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter, | |||
380 | phy->desc = "1000BASE-X"; | 390 | phy->desc = "1000BASE-X"; |
381 | phy->ops = &vsc8211_fiber_ops; | 391 | phy->ops = &vsc8211_fiber_ops; |
382 | 392 | ||
383 | err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 1); | 393 | err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 1); |
384 | if (err) | 394 | if (err) |
385 | return err; | 395 | return err; |
386 | 396 | ||
387 | err = mdio_write(phy, 0, VSC8211_SIGDET_CTRL, 1); | 397 | err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_SIGDET_CTRL, 1); |
388 | if (err) | 398 | if (err) |
389 | return err; | 399 | return err; |
390 | 400 | ||
391 | err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0); | 401 | err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0); |
392 | if (err) | 402 | if (err) |
393 | return err; | 403 | return err; |
394 | 404 | ||
395 | err = mdio_write(phy, 0, VSC8211_EXT_CTRL, | 405 | err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_CTRL, |
396 | val | VSC_CTRL_CLAUSE37_VIEW); | 406 | val | VSC_CTRL_CLAUSE37_VIEW); |
397 | if (err) | 407 | if (err) |
398 | return err; | 408 | return err; |
399 | 409 | ||