]> Git Repo - linux.git/blob - drivers/net/phy/vitesse.c
crypto: akcipher - Drop sign/verify operations
[linux.git] / drivers / net / phy / vitesse.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Driver for Vitesse PHYs
4  *
5  * Author: Kriston Carson
6  */
7
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/mii.h>
11 #include <linux/ethtool.h>
12 #include <linux/phy.h>
13 #include <linux/bitfield.h>
14
15 /* Vitesse Extended Page Magic Register(s) */
16 #define MII_VSC73XX_EXT_PAGE_1E         0x01
17 #define MII_VSC82X4_EXT_PAGE_16E        0x10
18 #define MII_VSC82X4_EXT_PAGE_17E        0x11
19 #define MII_VSC82X4_EXT_PAGE_18E        0x12
20
21 /* Vitesse Extended Control Register 1 */
22 #define MII_VSC8244_EXT_CON1           0x17
23 #define MII_VSC8244_EXTCON1_INIT       0x0000
24 #define MII_VSC8244_EXTCON1_TX_SKEW_MASK        0x0c00
25 #define MII_VSC8244_EXTCON1_RX_SKEW_MASK        0x0300
26 #define MII_VSC8244_EXTCON1_TX_SKEW     0x0800
27 #define MII_VSC8244_EXTCON1_RX_SKEW     0x0200
28
29 /* Vitesse Interrupt Mask Register */
30 #define MII_VSC8244_IMASK               0x19
31 #define MII_VSC8244_IMASK_IEN           0x8000
32 #define MII_VSC8244_IMASK_SPEED         0x4000
33 #define MII_VSC8244_IMASK_LINK          0x2000
34 #define MII_VSC8244_IMASK_DUPLEX        0x1000
35 #define MII_VSC8244_IMASK_MASK          0xf000
36
37 #define MII_VSC8221_IMASK_MASK          0xa000
38
39 /* Vitesse Interrupt Status Register */
40 #define MII_VSC8244_ISTAT               0x1a
41 #define MII_VSC8244_ISTAT_STATUS        0x8000
42 #define MII_VSC8244_ISTAT_SPEED         0x4000
43 #define MII_VSC8244_ISTAT_LINK          0x2000
44 #define MII_VSC8244_ISTAT_DUPLEX        0x1000
45 #define MII_VSC8244_ISTAT_MASK          (MII_VSC8244_ISTAT_SPEED | \
46                                          MII_VSC8244_ISTAT_LINK | \
47                                          MII_VSC8244_ISTAT_DUPLEX)
48
49 #define MII_VSC8221_ISTAT_MASK          MII_VSC8244_ISTAT_LINK
50
51 /* Vitesse Auxiliary Control/Status Register */
52 #define MII_VSC8244_AUX_CONSTAT         0x1c
53 #define MII_VSC8244_AUXCONSTAT_INIT     0x0000
54 #define MII_VSC8244_AUXCONSTAT_DUPLEX   0x0020
55 #define MII_VSC8244_AUXCONSTAT_SPEED    0x0018
56 #define MII_VSC8244_AUXCONSTAT_GBIT     0x0010
57 #define MII_VSC8244_AUXCONSTAT_100      0x0008
58
59 #define MII_VSC8221_AUXCONSTAT_INIT     0x0004 /* need to set this bit? */
60 #define MII_VSC8221_AUXCONSTAT_RESERVED 0x0004
61
62 /* Vitesse Extended Page Access Register */
63 #define MII_VSC82X4_EXT_PAGE_ACCESS     0x1f
64
65 /* Vitesse VSC73XX Extended Control Register */
66 #define MII_VSC73XX_PHY_CTRL_EXT3               0x14
67
68 #define MII_VSC73XX_PHY_CTRL_EXT3_DOWNSHIFT_EN  BIT(4)
69 #define MII_VSC73XX_PHY_CTRL_EXT3_DOWNSHIFT_CNT GENMASK(3, 2)
70 #define MII_VSC73XX_PHY_CTRL_EXT3_DOWNSHIFT_STA BIT(1)
71 #define MII_VSC73XX_DOWNSHIFT_MAX               5
72 #define MII_VSC73XX_DOWNSHIFT_INVAL             1
73
74 /* VSC73XX PHY_BYPASS_CTRL register*/
75 #define MII_VSC73XX_PHY_BYPASS_CTRL             MII_DCOUNTER
76 #define MII_VSC73XX_PBC_TX_DIS                  BIT(15)
77 #define MII_VSC73XX_PBC_FOR_SPD_AUTO_MDIX_DIS   BIT(7)
78 #define MII_VSC73XX_PBC_PAIR_SWAP_DIS           BIT(5)
79 #define MII_VSC73XX_PBC_POL_INV_DIS             BIT(4)
80 #define MII_VSC73XX_PBC_PARALLEL_DET_DIS        BIT(3)
81 #define MII_VSC73XX_PBC_AUTO_NP_EXCHANGE_DIS    BIT(1)
82
83 /* VSC73XX PHY_AUX_CTRL_STAT register */
84 #define MII_VSC73XX_PHY_AUX_CTRL_STAT   MII_NCONFIG
85 #define MII_VSC73XX_PACS_NO_MDI_X_IND   BIT(13)
86
87 /* Vitesse VSC8601 Extended PHY Control Register 1 */
88 #define MII_VSC8601_EPHY_CTL            0x17
89 #define MII_VSC8601_EPHY_CTL_RGMII_SKEW (1 << 8)
90
91 #define PHY_ID_VSC8234                  0x000fc620
92 #define PHY_ID_VSC8244                  0x000fc6c0
93 #define PHY_ID_VSC8572                  0x000704d0
94 #define PHY_ID_VSC8601                  0x00070420
95 #define PHY_ID_VSC7385                  0x00070450
96 #define PHY_ID_VSC7388                  0x00070480
97 #define PHY_ID_VSC7395                  0x00070550
98 #define PHY_ID_VSC7398                  0x00070580
99 #define PHY_ID_VSC8662                  0x00070660
100 #define PHY_ID_VSC8221                  0x000fc550
101 #define PHY_ID_VSC8211                  0x000fc4b0
102
103 MODULE_DESCRIPTION("Vitesse PHY driver");
104 MODULE_AUTHOR("Kriston Carson");
105 MODULE_LICENSE("GPL");
106
107 static int vsc824x_add_skew(struct phy_device *phydev)
108 {
109         int err;
110         int extcon;
111
112         extcon = phy_read(phydev, MII_VSC8244_EXT_CON1);
113
114         if (extcon < 0)
115                 return extcon;
116
117         extcon &= ~(MII_VSC8244_EXTCON1_TX_SKEW_MASK |
118                         MII_VSC8244_EXTCON1_RX_SKEW_MASK);
119
120         extcon |= (MII_VSC8244_EXTCON1_TX_SKEW |
121                         MII_VSC8244_EXTCON1_RX_SKEW);
122
123         err = phy_write(phydev, MII_VSC8244_EXT_CON1, extcon);
124
125         return err;
126 }
127
128 static int vsc824x_config_init(struct phy_device *phydev)
129 {
130         int err;
131
132         err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT,
133                         MII_VSC8244_AUXCONSTAT_INIT);
134         if (err < 0)
135                 return err;
136
137         if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
138                 err = vsc824x_add_skew(phydev);
139
140         return err;
141 }
142
143 #define VSC73XX_EXT_PAGE_ACCESS 0x1f
144
145 static int vsc73xx_read_page(struct phy_device *phydev)
146 {
147         return __phy_read(phydev, VSC73XX_EXT_PAGE_ACCESS);
148 }
149
150 static int vsc73xx_write_page(struct phy_device *phydev, int page)
151 {
152         return __phy_write(phydev, VSC73XX_EXT_PAGE_ACCESS, page);
153 }
154
155 static int vsc73xx_get_downshift(struct phy_device *phydev, u8 *data)
156 {
157         int val, enable, cnt;
158
159         val = phy_read_paged(phydev, MII_VSC73XX_EXT_PAGE_1E,
160                              MII_VSC73XX_PHY_CTRL_EXT3);
161         if (val < 0)
162                 return val;
163
164         enable = FIELD_GET(MII_VSC73XX_PHY_CTRL_EXT3_DOWNSHIFT_EN, val);
165         cnt = FIELD_GET(MII_VSC73XX_PHY_CTRL_EXT3_DOWNSHIFT_CNT, val) + 2;
166
167         *data = enable ? cnt : DOWNSHIFT_DEV_DISABLE;
168
169         return 0;
170 }
171
172 static int vsc73xx_set_downshift(struct phy_device *phydev, u8 cnt)
173 {
174         u16 mask, val;
175         int ret;
176
177         if (cnt > MII_VSC73XX_DOWNSHIFT_MAX)
178                 return -E2BIG;
179         else if (cnt == MII_VSC73XX_DOWNSHIFT_INVAL)
180                 return -EINVAL;
181
182         mask = MII_VSC73XX_PHY_CTRL_EXT3_DOWNSHIFT_EN;
183
184         if (!cnt) {
185                 val = 0;
186         } else {
187                 mask |= MII_VSC73XX_PHY_CTRL_EXT3_DOWNSHIFT_CNT;
188                 val = MII_VSC73XX_PHY_CTRL_EXT3_DOWNSHIFT_EN |
189                       FIELD_PREP(MII_VSC73XX_PHY_CTRL_EXT3_DOWNSHIFT_CNT,
190                                  cnt - 2);
191         }
192
193         ret = phy_modify_paged(phydev, MII_VSC73XX_EXT_PAGE_1E,
194                                MII_VSC73XX_PHY_CTRL_EXT3, mask, val);
195         if (ret < 0)
196                 return ret;
197
198         return genphy_soft_reset(phydev);
199 }
200
201 static int vsc73xx_get_tunable(struct phy_device *phydev,
202                                struct ethtool_tunable *tuna, void *data)
203 {
204         switch (tuna->id) {
205         case ETHTOOL_PHY_DOWNSHIFT:
206                 return vsc73xx_get_downshift(phydev, data);
207         default:
208                 return -EOPNOTSUPP;
209         }
210 }
211
212 static int vsc73xx_set_tunable(struct phy_device *phydev,
213                                struct ethtool_tunable *tuna, const void *data)
214 {
215         switch (tuna->id) {
216         case ETHTOOL_PHY_DOWNSHIFT:
217                 return vsc73xx_set_downshift(phydev, *(const u8 *)data);
218         default:
219                 return -EOPNOTSUPP;
220         }
221 }
222
223 static void vsc73xx_config_init(struct phy_device *phydev)
224 {
225         /* Receiver init */
226         phy_write(phydev, 0x1f, 0x2a30);
227         phy_modify(phydev, 0x0c, 0x0300, 0x0200);
228         phy_write(phydev, 0x1f, 0x0000);
229
230         /* Config LEDs 0x61 */
231         phy_modify(phydev, MII_TPISTATUS, 0xff00, 0x0061);
232
233         /* Enable downshift by default */
234         vsc73xx_set_downshift(phydev, MII_VSC73XX_DOWNSHIFT_MAX);
235
236         /* Set Auto MDI-X by default */
237         phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
238 }
239
240 static int vsc738x_config_init(struct phy_device *phydev)
241 {
242         u16 rev;
243         /* This magic sequence appear in the application note
244          * "VSC7385/7388 PHY Configuration".
245          *
246          * Maybe one day we will get to know what it all means.
247          */
248         phy_write(phydev, 0x1f, 0x2a30);
249         phy_modify(phydev, 0x08, 0x0200, 0x0200);
250         phy_write(phydev, 0x1f, 0x52b5);
251         phy_write(phydev, 0x10, 0xb68a);
252         phy_modify(phydev, 0x12, 0xff07, 0x0003);
253         phy_modify(phydev, 0x11, 0x00ff, 0x00a2);
254         phy_write(phydev, 0x10, 0x968a);
255         phy_write(phydev, 0x1f, 0x2a30);
256         phy_modify(phydev, 0x08, 0x0200, 0x0000);
257         phy_write(phydev, 0x1f, 0x0000);
258
259         /* Read revision */
260         rev = phy_read(phydev, MII_PHYSID2);
261         rev &= 0x0f;
262
263         /* Special quirk for revision 0 */
264         if (rev == 0) {
265                 phy_write(phydev, 0x1f, 0x2a30);
266                 phy_modify(phydev, 0x08, 0x0200, 0x0200);
267                 phy_write(phydev, 0x1f, 0x52b5);
268                 phy_write(phydev, 0x12, 0x0000);
269                 phy_write(phydev, 0x11, 0x0689);
270                 phy_write(phydev, 0x10, 0x8f92);
271                 phy_write(phydev, 0x1f, 0x52b5);
272                 phy_write(phydev, 0x12, 0x0000);
273                 phy_write(phydev, 0x11, 0x0e35);
274                 phy_write(phydev, 0x10, 0x9786);
275                 phy_write(phydev, 0x1f, 0x2a30);
276                 phy_modify(phydev, 0x08, 0x0200, 0x0000);
277                 phy_write(phydev, 0x17, 0xff80);
278                 phy_write(phydev, 0x17, 0x0000);
279         }
280
281         phy_write(phydev, 0x1f, 0x0000);
282         phy_write(phydev, 0x12, 0x0048);
283
284         if (rev == 0) {
285                 phy_write(phydev, 0x1f, 0x2a30);
286                 phy_write(phydev, 0x14, 0x6600);
287                 phy_write(phydev, 0x1f, 0x0000);
288                 phy_write(phydev, 0x18, 0xa24e);
289         } else {
290                 phy_write(phydev, 0x1f, 0x2a30);
291                 phy_modify(phydev, 0x16, 0x0fc0, 0x0240);
292                 phy_modify(phydev, 0x14, 0x6000, 0x4000);
293                 /* bits 14-15 in extended register 0x14 controls DACG amplitude
294                  * 6 = -8%, 2 is hardware default
295                  */
296                 phy_write(phydev, 0x1f, 0x0001);
297                 phy_modify(phydev, 0x14, 0xe000, 0x6000);
298                 phy_write(phydev, 0x1f, 0x0000);
299         }
300
301         vsc73xx_config_init(phydev);
302
303         return 0;
304 }
305
306 static int vsc739x_config_init(struct phy_device *phydev)
307 {
308         /* This magic sequence appears in the VSC7395 SparX-G5e application
309          * note "VSC7395/VSC7398 PHY Configuration"
310          *
311          * Maybe one day we will get to know what it all means.
312          */
313         phy_write(phydev, 0x1f, 0x2a30);
314         phy_modify(phydev, 0x08, 0x0200, 0x0200);
315         phy_write(phydev, 0x1f, 0x52b5);
316         phy_write(phydev, 0x10, 0xb68a);
317         phy_modify(phydev, 0x12, 0xff07, 0x0003);
318         phy_modify(phydev, 0x11, 0x00ff, 0x00a2);
319         phy_write(phydev, 0x10, 0x968a);
320         phy_write(phydev, 0x1f, 0x2a30);
321         phy_modify(phydev, 0x08, 0x0200, 0x0000);
322         phy_write(phydev, 0x1f, 0x0000);
323
324         phy_write(phydev, 0x1f, 0x0000);
325         phy_write(phydev, 0x12, 0x0048);
326         phy_write(phydev, 0x1f, 0x2a30);
327         phy_modify(phydev, 0x16, 0x0fc0, 0x0240);
328         phy_modify(phydev, 0x14, 0x6000, 0x4000);
329         phy_write(phydev, 0x1f, 0x0001);
330         phy_modify(phydev, 0x14, 0xe000, 0x6000);
331         phy_write(phydev, 0x1f, 0x0000);
332
333         vsc73xx_config_init(phydev);
334
335         return 0;
336 }
337
338 static int vsc73xx_mdix_set(struct phy_device *phydev, u8 mdix)
339 {
340         int ret;
341         u16 val;
342
343         val = phy_read(phydev, MII_VSC73XX_PHY_BYPASS_CTRL);
344
345         switch (mdix) {
346         case ETH_TP_MDI:
347                 val |= MII_VSC73XX_PBC_FOR_SPD_AUTO_MDIX_DIS |
348                        MII_VSC73XX_PBC_PAIR_SWAP_DIS |
349                        MII_VSC73XX_PBC_POL_INV_DIS;
350                 break;
351         case ETH_TP_MDI_X:
352                 /* When MDI-X auto configuration is disabled, is possible
353                  * to force only MDI mode. Let's use autoconfig for forced
354                  * MDIX mode.
355                  */
356         case ETH_TP_MDI_AUTO:
357                 val &= ~(MII_VSC73XX_PBC_FOR_SPD_AUTO_MDIX_DIS |
358                          MII_VSC73XX_PBC_PAIR_SWAP_DIS |
359                          MII_VSC73XX_PBC_POL_INV_DIS);
360                 break;
361         default:
362                 return -EINVAL;
363         }
364
365         ret = phy_write(phydev, MII_VSC73XX_PHY_BYPASS_CTRL, val);
366         if (ret)
367                 return ret;
368
369         return genphy_restart_aneg(phydev);
370 }
371
372 static int vsc73xx_config_aneg(struct phy_device *phydev)
373 {
374         int ret;
375
376         ret = vsc73xx_mdix_set(phydev, phydev->mdix_ctrl);
377         if (ret)
378                 return ret;
379
380         return genphy_config_aneg(phydev);
381 }
382
383 static int vsc73xx_mdix_get(struct phy_device *phydev, u8 *mdix)
384 {
385         u16 reg_val;
386
387         reg_val = phy_read(phydev, MII_VSC73XX_PHY_AUX_CTRL_STAT);
388         if (reg_val & MII_VSC73XX_PACS_NO_MDI_X_IND)
389                 *mdix = ETH_TP_MDI;
390         else
391                 *mdix = ETH_TP_MDI_X;
392
393         return 0;
394 }
395
396 static int vsc73xx_read_status(struct phy_device *phydev)
397 {
398         int ret;
399
400         ret = vsc73xx_mdix_get(phydev, &phydev->mdix);
401         if (ret < 0)
402                 return ret;
403
404         return genphy_read_status(phydev);
405 }
406
407 /* This adds a skew for both TX and RX clocks, so the skew should only be
408  * applied to "rgmii-id" interfaces. It may not work as expected
409  * on "rgmii-txid", "rgmii-rxid" or "rgmii" interfaces.
410  */
411 static int vsc8601_add_skew(struct phy_device *phydev)
412 {
413         int ret;
414
415         ret = phy_read(phydev, MII_VSC8601_EPHY_CTL);
416         if (ret < 0)
417                 return ret;
418
419         ret |= MII_VSC8601_EPHY_CTL_RGMII_SKEW;
420         return phy_write(phydev, MII_VSC8601_EPHY_CTL, ret);
421 }
422
423 static int vsc8601_config_init(struct phy_device *phydev)
424 {
425         int ret = 0;
426
427         if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
428                 ret = vsc8601_add_skew(phydev);
429
430         if (ret < 0)
431                 return ret;
432
433         return 0;
434 }
435
436 static int vsc82xx_config_intr(struct phy_device *phydev)
437 {
438         int err;
439
440         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
441                 /* Don't bother to ACK the interrupts since the 824x cannot
442                  * clear the interrupts if they are disabled.
443                  */
444                 err = phy_write(phydev, MII_VSC8244_IMASK,
445                         (phydev->drv->phy_id == PHY_ID_VSC8234 ||
446                          phydev->drv->phy_id == PHY_ID_VSC8244 ||
447                          phydev->drv->phy_id == PHY_ID_VSC8572 ||
448                          phydev->drv->phy_id == PHY_ID_VSC8601) ?
449                                 MII_VSC8244_IMASK_MASK :
450                                 MII_VSC8221_IMASK_MASK);
451         else {
452                 /* The Vitesse PHY cannot clear the interrupt
453                  * once it has disabled them, so we clear them first
454                  */
455                 err = phy_read(phydev, MII_VSC8244_ISTAT);
456
457                 if (err < 0)
458                         return err;
459
460                 err = phy_write(phydev, MII_VSC8244_IMASK, 0);
461         }
462
463         return err;
464 }
465
466 static irqreturn_t vsc82xx_handle_interrupt(struct phy_device *phydev)
467 {
468         int irq_status, irq_mask;
469
470         if (phydev->drv->phy_id == PHY_ID_VSC8244 ||
471             phydev->drv->phy_id == PHY_ID_VSC8572 ||
472             phydev->drv->phy_id == PHY_ID_VSC8601)
473                 irq_mask = MII_VSC8244_ISTAT_MASK;
474         else
475                 irq_mask = MII_VSC8221_ISTAT_MASK;
476
477         irq_status = phy_read(phydev, MII_VSC8244_ISTAT);
478         if (irq_status < 0) {
479                 phy_error(phydev);
480                 return IRQ_NONE;
481         }
482
483         if (!(irq_status & irq_mask))
484                 return IRQ_NONE;
485
486         phy_trigger_machine(phydev);
487
488         return IRQ_HANDLED;
489 }
490
491 static int vsc8221_config_init(struct phy_device *phydev)
492 {
493         int err;
494
495         err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT,
496                         MII_VSC8221_AUXCONSTAT_INIT);
497         return err;
498
499         /* Perhaps we should set EXT_CON1 based on the interface?
500          * Options are 802.3Z SerDes or SGMII
501          */
502 }
503
504 /* vsc82x4_config_autocross_enable - Enable auto MDI/MDI-X for forced links
505  * @phydev: target phy_device struct
506  *
507  * Enable auto MDI/MDI-X when in 10/100 forced link speeds by writing
508  * special values in the VSC8234/VSC8244 extended reserved registers
509  */
510 static int vsc82x4_config_autocross_enable(struct phy_device *phydev)
511 {
512         int ret;
513
514         if (phydev->autoneg == AUTONEG_ENABLE || phydev->speed > SPEED_100)
515                 return 0;
516
517         /* map extended registers set 0x10 - 0x1e */
518         ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_ACCESS, 0x52b5);
519         if (ret >= 0)
520                 ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_18E, 0x0012);
521         if (ret >= 0)
522                 ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_17E, 0x2803);
523         if (ret >= 0)
524                 ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_16E, 0x87fa);
525         /* map standard registers set 0x10 - 0x1e */
526         if (ret >= 0)
527                 ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_ACCESS, 0x0000);
528         else
529                 phy_write(phydev, MII_VSC82X4_EXT_PAGE_ACCESS, 0x0000);
530
531         return ret;
532 }
533
534 /* vsc82x4_config_aneg - restart auto-negotiation or write BMCR
535  * @phydev: target phy_device struct
536  *
537  * Description: If auto-negotiation is enabled, we configure the
538  *   advertising, and then restart auto-negotiation.  If it is not
539  *   enabled, then we write the BMCR and also start the auto
540  *   MDI/MDI-X feature
541  */
542 static int vsc82x4_config_aneg(struct phy_device *phydev)
543 {
544         int ret;
545
546         /* Enable auto MDI/MDI-X when in 10/100 forced link speeds by
547          * writing special values in the VSC8234 extended reserved registers
548          */
549         if (phydev->autoneg != AUTONEG_ENABLE && phydev->speed <= SPEED_100) {
550                 ret = genphy_setup_forced(phydev);
551
552                 if (ret < 0) /* error */
553                         return ret;
554
555                 return vsc82x4_config_autocross_enable(phydev);
556         }
557
558         return genphy_config_aneg(phydev);
559 }
560
561 /* Vitesse 82xx */
562 static struct phy_driver vsc82xx_driver[] = {
563 {
564         .phy_id         = PHY_ID_VSC8234,
565         .name           = "Vitesse VSC8234",
566         .phy_id_mask    = 0x000ffff0,
567         /* PHY_GBIT_FEATURES */
568         .config_init    = &vsc824x_config_init,
569         .config_aneg    = &vsc82x4_config_aneg,
570         .config_intr    = &vsc82xx_config_intr,
571         .handle_interrupt = &vsc82xx_handle_interrupt,
572 }, {
573         .phy_id         = PHY_ID_VSC8244,
574         .name           = "Vitesse VSC8244",
575         .phy_id_mask    = 0x000fffc0,
576         /* PHY_GBIT_FEATURES */
577         .config_init    = &vsc824x_config_init,
578         .config_aneg    = &vsc82x4_config_aneg,
579         .config_intr    = &vsc82xx_config_intr,
580         .handle_interrupt = &vsc82xx_handle_interrupt,
581 }, {
582         .phy_id         = PHY_ID_VSC8572,
583         .name           = "Vitesse VSC8572",
584         .phy_id_mask    = 0x000ffff0,
585         /* PHY_GBIT_FEATURES */
586         .config_init    = &vsc824x_config_init,
587         .config_aneg    = &vsc82x4_config_aneg,
588         .config_intr    = &vsc82xx_config_intr,
589         .handle_interrupt = &vsc82xx_handle_interrupt,
590 }, {
591         .phy_id         = PHY_ID_VSC8601,
592         .name           = "Vitesse VSC8601",
593         .phy_id_mask    = 0x000ffff0,
594         /* PHY_GBIT_FEATURES */
595         .config_init    = &vsc8601_config_init,
596         .config_intr    = &vsc82xx_config_intr,
597         .handle_interrupt = &vsc82xx_handle_interrupt,
598 }, {
599         .phy_id         = PHY_ID_VSC7385,
600         .name           = "Vitesse VSC7385",
601         .phy_id_mask    = 0x000ffff0,
602         /* PHY_GBIT_FEATURES */
603         .config_init    = vsc738x_config_init,
604         .config_aneg    = vsc73xx_config_aneg,
605         .read_status    = vsc73xx_read_status,
606         .read_page      = vsc73xx_read_page,
607         .write_page     = vsc73xx_write_page,
608         .get_tunable    = vsc73xx_get_tunable,
609         .set_tunable    = vsc73xx_set_tunable,
610 }, {
611         .phy_id         = PHY_ID_VSC7388,
612         .name           = "Vitesse VSC7388",
613         .phy_id_mask    = 0x000ffff0,
614         /* PHY_GBIT_FEATURES */
615         .config_init    = vsc738x_config_init,
616         .config_aneg    = vsc73xx_config_aneg,
617         .read_status    = vsc73xx_read_status,
618         .read_page      = vsc73xx_read_page,
619         .write_page     = vsc73xx_write_page,
620         .get_tunable    = vsc73xx_get_tunable,
621         .set_tunable    = vsc73xx_set_tunable,
622 }, {
623         .phy_id         = PHY_ID_VSC7395,
624         .name           = "Vitesse VSC7395",
625         .phy_id_mask    = 0x000ffff0,
626         /* PHY_GBIT_FEATURES */
627         .config_init    = vsc739x_config_init,
628         .config_aneg    = vsc73xx_config_aneg,
629         .read_status    = vsc73xx_read_status,
630         .read_page      = vsc73xx_read_page,
631         .write_page     = vsc73xx_write_page,
632         .get_tunable    = vsc73xx_get_tunable,
633         .set_tunable    = vsc73xx_set_tunable,
634 }, {
635         .phy_id         = PHY_ID_VSC7398,
636         .name           = "Vitesse VSC7398",
637         .phy_id_mask    = 0x000ffff0,
638         /* PHY_GBIT_FEATURES */
639         .config_init    = vsc739x_config_init,
640         .config_aneg    = vsc73xx_config_aneg,
641         .read_status    = vsc73xx_read_status,
642         .read_page      = vsc73xx_read_page,
643         .write_page     = vsc73xx_write_page,
644         .get_tunable    = vsc73xx_get_tunable,
645         .set_tunable    = vsc73xx_set_tunable,
646 }, {
647         .phy_id         = PHY_ID_VSC8662,
648         .name           = "Vitesse VSC8662",
649         .phy_id_mask    = 0x000ffff0,
650         /* PHY_GBIT_FEATURES */
651         .config_init    = &vsc824x_config_init,
652         .config_aneg    = &vsc82x4_config_aneg,
653         .config_intr    = &vsc82xx_config_intr,
654         .handle_interrupt = &vsc82xx_handle_interrupt,
655 }, {
656         /* Vitesse 8221 */
657         .phy_id         = PHY_ID_VSC8221,
658         .phy_id_mask    = 0x000ffff0,
659         .name           = "Vitesse VSC8221",
660         /* PHY_GBIT_FEATURES */
661         .config_init    = &vsc8221_config_init,
662         .config_intr    = &vsc82xx_config_intr,
663         .handle_interrupt = &vsc82xx_handle_interrupt,
664 }, {
665         /* Vitesse 8211 */
666         .phy_id         = PHY_ID_VSC8211,
667         .phy_id_mask    = 0x000ffff0,
668         .name           = "Vitesse VSC8211",
669         /* PHY_GBIT_FEATURES */
670         .config_init    = &vsc8221_config_init,
671         .config_intr    = &vsc82xx_config_intr,
672         .handle_interrupt = &vsc82xx_handle_interrupt,
673 } };
674
675 module_phy_driver(vsc82xx_driver);
676
677 static struct mdio_device_id __maybe_unused vitesse_tbl[] = {
678         { PHY_ID_VSC8234, 0x000ffff0 },
679         { PHY_ID_VSC8244, 0x000fffc0 },
680         { PHY_ID_VSC8572, 0x000ffff0 },
681         { PHY_ID_VSC7385, 0x000ffff0 },
682         { PHY_ID_VSC7388, 0x000ffff0 },
683         { PHY_ID_VSC7395, 0x000ffff0 },
684         { PHY_ID_VSC7398, 0x000ffff0 },
685         { PHY_ID_VSC8662, 0x000ffff0 },
686         { PHY_ID_VSC8221, 0x000ffff0 },
687         { PHY_ID_VSC8211, 0x000ffff0 },
688         { }
689 };
690
691 MODULE_DEVICE_TABLE(mdio, vitesse_tbl);
This page took 0.069521 seconds and 4 git commands to generate.