can: sja1000: fix use after free in ems_pcmcia_add_card()
[linux-2.6-microblaze.git] / drivers / net / phy / microchip_t1.c
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2018 Microchip Technology
3
4 #include <linux/kernel.h>
5 #include <linux/module.h>
6 #include <linux/delay.h>
7 #include <linux/mii.h>
8 #include <linux/phy.h>
9 #include <linux/ethtool.h>
10 #include <linux/ethtool_netlink.h>
11
12 /* External Register Control Register */
13 #define LAN87XX_EXT_REG_CTL                     (0x14)
14 #define LAN87XX_EXT_REG_CTL_RD_CTL              (0x1000)
15 #define LAN87XX_EXT_REG_CTL_WR_CTL              (0x0800)
16
17 /* External Register Read Data Register */
18 #define LAN87XX_EXT_REG_RD_DATA                 (0x15)
19
20 /* External Register Write Data Register */
21 #define LAN87XX_EXT_REG_WR_DATA                 (0x16)
22
23 /* Interrupt Source Register */
24 #define LAN87XX_INTERRUPT_SOURCE                (0x18)
25
26 /* Interrupt Mask Register */
27 #define LAN87XX_INTERRUPT_MASK                  (0x19)
28 #define LAN87XX_MASK_LINK_UP                    (0x0004)
29 #define LAN87XX_MASK_LINK_DOWN                  (0x0002)
30
31 /* MISC Control 1 Register */
32 #define LAN87XX_CTRL_1                          (0x11)
33 #define LAN87XX_MASK_RGMII_TXC_DLY_EN           (0x4000)
34 #define LAN87XX_MASK_RGMII_RXC_DLY_EN           (0x2000)
35
36 /* phyaccess nested types */
37 #define PHYACC_ATTR_MODE_READ           0
38 #define PHYACC_ATTR_MODE_WRITE          1
39 #define PHYACC_ATTR_MODE_MODIFY         2
40
41 #define PHYACC_ATTR_BANK_SMI            0
42 #define PHYACC_ATTR_BANK_MISC           1
43 #define PHYACC_ATTR_BANK_PCS            2
44 #define PHYACC_ATTR_BANK_AFE            3
45 #define PHYACC_ATTR_BANK_DSP            4
46 #define PHYACC_ATTR_BANK_MAX            7
47
48 /* measurement defines */
49 #define LAN87XX_CABLE_TEST_OK           0
50 #define LAN87XX_CABLE_TEST_OPEN 1
51 #define LAN87XX_CABLE_TEST_SAME_SHORT   2
52
53 #define DRIVER_AUTHOR   "Nisar Sayed <nisar.sayed@microchip.com>"
54 #define DRIVER_DESC     "Microchip LAN87XX T1 PHY driver"
55
56 struct access_ereg_val {
57         u8  mode;
58         u8  bank;
59         u8  offset;
60         u16 val;
61         u16 mask;
62 };
63
64 static int access_ereg(struct phy_device *phydev, u8 mode, u8 bank,
65                        u8 offset, u16 val)
66 {
67         u16 ereg = 0;
68         int rc = 0;
69
70         if (mode > PHYACC_ATTR_MODE_WRITE || bank > PHYACC_ATTR_BANK_MAX)
71                 return -EINVAL;
72
73         if (bank == PHYACC_ATTR_BANK_SMI) {
74                 if (mode == PHYACC_ATTR_MODE_WRITE)
75                         rc = phy_write(phydev, offset, val);
76                 else
77                         rc = phy_read(phydev, offset);
78                 return rc;
79         }
80
81         if (mode == PHYACC_ATTR_MODE_WRITE) {
82                 ereg = LAN87XX_EXT_REG_CTL_WR_CTL;
83                 rc = phy_write(phydev, LAN87XX_EXT_REG_WR_DATA, val);
84                 if (rc < 0)
85                         return rc;
86         } else {
87                 ereg = LAN87XX_EXT_REG_CTL_RD_CTL;
88         }
89
90         ereg |= (bank << 8) | offset;
91
92         rc = phy_write(phydev, LAN87XX_EXT_REG_CTL, ereg);
93         if (rc < 0)
94                 return rc;
95
96         if (mode == PHYACC_ATTR_MODE_READ)
97                 rc = phy_read(phydev, LAN87XX_EXT_REG_RD_DATA);
98
99         return rc;
100 }
101
102 static int access_ereg_modify_changed(struct phy_device *phydev,
103                                       u8 bank, u8 offset, u16 val, u16 mask)
104 {
105         int new = 0, rc = 0;
106
107         if (bank > PHYACC_ATTR_BANK_MAX)
108                 return -EINVAL;
109
110         rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, bank, offset, val);
111         if (rc < 0)
112                 return rc;
113
114         new = val | (rc & (mask ^ 0xFFFF));
115         rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE, bank, offset, new);
116
117         return rc;
118 }
119
120 static int lan87xx_config_rgmii_delay(struct phy_device *phydev)
121 {
122         int rc;
123
124         if (!phy_interface_is_rgmii(phydev))
125                 return 0;
126
127         rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
128                          PHYACC_ATTR_BANK_MISC, LAN87XX_CTRL_1, 0);
129         if (rc < 0)
130                 return rc;
131
132         switch (phydev->interface) {
133         case PHY_INTERFACE_MODE_RGMII:
134                 rc &= ~LAN87XX_MASK_RGMII_TXC_DLY_EN;
135                 rc &= ~LAN87XX_MASK_RGMII_RXC_DLY_EN;
136                 break;
137         case PHY_INTERFACE_MODE_RGMII_ID:
138                 rc |= LAN87XX_MASK_RGMII_TXC_DLY_EN;
139                 rc |= LAN87XX_MASK_RGMII_RXC_DLY_EN;
140                 break;
141         case PHY_INTERFACE_MODE_RGMII_RXID:
142                 rc &= ~LAN87XX_MASK_RGMII_TXC_DLY_EN;
143                 rc |= LAN87XX_MASK_RGMII_RXC_DLY_EN;
144                 break;
145         case PHY_INTERFACE_MODE_RGMII_TXID:
146                 rc |= LAN87XX_MASK_RGMII_TXC_DLY_EN;
147                 rc &= ~LAN87XX_MASK_RGMII_RXC_DLY_EN;
148                 break;
149         default:
150                 return 0;
151         }
152
153         return access_ereg(phydev, PHYACC_ATTR_MODE_WRITE,
154                            PHYACC_ATTR_BANK_MISC, LAN87XX_CTRL_1, rc);
155 }
156
157 static int lan87xx_phy_init(struct phy_device *phydev)
158 {
159         static const struct access_ereg_val init[] = {
160                 /* TX Amplitude = 5 */
161                 {PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_AFE, 0x0B,
162                  0x000A, 0x001E},
163                 /* Clear SMI interrupts */
164                 {PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_SMI, 0x18,
165                  0, 0},
166                 /* Clear MISC interrupts */
167                 {PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_MISC, 0x08,
168                  0, 0},
169                 /* Turn on TC10 Ring Oscillator (ROSC) */
170                 {PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_MISC, 0x20,
171                  0x0020, 0x0020},
172                 /* WUR Detect Length to 1.2uS, LPC Detect Length to 1.09uS */
173                 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_PCS, 0x20,
174                  0x283C, 0},
175                 /* Wake_In Debounce Length to 39uS, Wake_Out Length to 79uS */
176                 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_MISC, 0x21,
177                  0x274F, 0},
178                 /* Enable Auto Wake Forward to Wake_Out, ROSC on, Sleep,
179                  * and Wake_In to wake PHY
180                  */
181                 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_MISC, 0x20,
182                  0x80A7, 0},
183                 /* Enable WUP Auto Fwd, Enable Wake on MDI, Wakeup Debouncer
184                  * to 128 uS
185                  */
186                 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_MISC, 0x24,
187                  0xF110, 0},
188                 /* Enable HW Init */
189                 {PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_SMI, 0x1A,
190                  0x0100, 0x0100},
191         };
192         int rc, i;
193
194         /* Start manual initialization procedures in Managed Mode */
195         rc = access_ereg_modify_changed(phydev, PHYACC_ATTR_BANK_SMI,
196                                         0x1a, 0x0000, 0x0100);
197         if (rc < 0)
198                 return rc;
199
200         /* Soft Reset the SMI block */
201         rc = access_ereg_modify_changed(phydev, PHYACC_ATTR_BANK_SMI,
202                                         0x00, 0x8000, 0x8000);
203         if (rc < 0)
204                 return rc;
205
206         /* Check to see if the self-clearing bit is cleared */
207         usleep_range(1000, 2000);
208         rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
209                          PHYACC_ATTR_BANK_SMI, 0x00, 0);
210         if (rc < 0)
211                 return rc;
212         if ((rc & 0x8000) != 0)
213                 return -ETIMEDOUT;
214
215         /* PHY Initialization */
216         for (i = 0; i < ARRAY_SIZE(init); i++) {
217                 if (init[i].mode == PHYACC_ATTR_MODE_MODIFY) {
218                         rc = access_ereg_modify_changed(phydev, init[i].bank,
219                                                         init[i].offset,
220                                                         init[i].val,
221                                                         init[i].mask);
222                 } else {
223                         rc = access_ereg(phydev, init[i].mode, init[i].bank,
224                                          init[i].offset, init[i].val);
225                 }
226                 if (rc < 0)
227                         return rc;
228         }
229
230         return lan87xx_config_rgmii_delay(phydev);
231 }
232
233 static int lan87xx_phy_config_intr(struct phy_device *phydev)
234 {
235         int rc, val = 0;
236
237         if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
238                 /* unmask all source and clear them before enable */
239                 rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, 0x7FFF);
240                 rc = phy_read(phydev, LAN87XX_INTERRUPT_SOURCE);
241                 val = LAN87XX_MASK_LINK_UP | LAN87XX_MASK_LINK_DOWN;
242                 rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, val);
243         } else {
244                 rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, val);
245                 if (rc)
246                         return rc;
247
248                 rc = phy_read(phydev, LAN87XX_INTERRUPT_SOURCE);
249         }
250
251         return rc < 0 ? rc : 0;
252 }
253
254 static irqreturn_t lan87xx_handle_interrupt(struct phy_device *phydev)
255 {
256         int irq_status;
257
258         irq_status = phy_read(phydev, LAN87XX_INTERRUPT_SOURCE);
259         if (irq_status < 0) {
260                 phy_error(phydev);
261                 return IRQ_NONE;
262         }
263
264         if (irq_status == 0)
265                 return IRQ_NONE;
266
267         phy_trigger_machine(phydev);
268
269         return IRQ_HANDLED;
270 }
271
272 static int lan87xx_config_init(struct phy_device *phydev)
273 {
274         int rc = lan87xx_phy_init(phydev);
275
276         return rc < 0 ? rc : 0;
277 }
278
279 static int microchip_cable_test_start_common(struct phy_device *phydev)
280 {
281         int bmcr, bmsr, ret;
282
283         /* If auto-negotiation is enabled, but not complete, the cable
284          * test never completes. So disable auto-neg.
285          */
286         bmcr = phy_read(phydev, MII_BMCR);
287         if (bmcr < 0)
288                 return bmcr;
289
290         bmsr = phy_read(phydev, MII_BMSR);
291
292         if (bmsr < 0)
293                 return bmsr;
294
295         if (bmcr & BMCR_ANENABLE) {
296                 ret =  phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0);
297                 if (ret < 0)
298                         return ret;
299                 ret = genphy_soft_reset(phydev);
300                 if (ret < 0)
301                         return ret;
302         }
303
304         /* If the link is up, allow it some time to go down */
305         if (bmsr & BMSR_LSTATUS)
306                 msleep(1500);
307
308         return 0;
309 }
310
311 static int lan87xx_cable_test_start(struct phy_device *phydev)
312 {
313         static const struct access_ereg_val cable_test[] = {
314                 /* min wait */
315                 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 93,
316                  0, 0},
317                 /* max wait */
318                 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 94,
319                  10, 0},
320                 /* pulse cycle */
321                 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 95,
322                  90, 0},
323                 /* cable diag thresh */
324                 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 92,
325                  60, 0},
326                 /* max gain */
327                 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 79,
328                  31, 0},
329                 /* clock align for each iteration */
330                 {PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_DSP, 55,
331                  0, 0x0038},
332                 /* max cycle wait config */
333                 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 94,
334                  70, 0},
335                 /* start cable diag*/
336                 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 90,
337                  1, 0},
338         };
339         int rc, i;
340
341         rc = microchip_cable_test_start_common(phydev);
342         if (rc < 0)
343                 return rc;
344
345         /* start cable diag */
346         /* check if part is alive - if not, return diagnostic error */
347         rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_SMI,
348                          0x00, 0);
349         if (rc < 0)
350                 return rc;
351
352         /* master/slave specific configs */
353         rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_SMI,
354                          0x0A, 0);
355         if (rc < 0)
356                 return rc;
357
358         if ((rc & 0x4000) != 0x4000) {
359                 /* DUT is Slave */
360                 rc = access_ereg_modify_changed(phydev, PHYACC_ATTR_BANK_AFE,
361                                                 0x0E, 0x5, 0x7);
362                 if (rc < 0)
363                         return rc;
364                 rc = access_ereg_modify_changed(phydev, PHYACC_ATTR_BANK_SMI,
365                                                 0x1A, 0x8, 0x8);
366                 if (rc < 0)
367                         return rc;
368         } else {
369                 /* DUT is Master */
370                 rc = access_ereg_modify_changed(phydev, PHYACC_ATTR_BANK_SMI,
371                                                 0x10, 0x8, 0x40);
372                 if (rc < 0)
373                         return rc;
374         }
375
376         for (i = 0; i < ARRAY_SIZE(cable_test); i++) {
377                 if (cable_test[i].mode == PHYACC_ATTR_MODE_MODIFY) {
378                         rc = access_ereg_modify_changed(phydev,
379                                                         cable_test[i].bank,
380                                                         cable_test[i].offset,
381                                                         cable_test[i].val,
382                                                         cable_test[i].mask);
383                         /* wait 50ms */
384                         msleep(50);
385                 } else {
386                         rc = access_ereg(phydev, cable_test[i].mode,
387                                          cable_test[i].bank,
388                                          cable_test[i].offset,
389                                          cable_test[i].val);
390                 }
391                 if (rc < 0)
392                         return rc;
393         }
394         /* cable diag started */
395
396         return 0;
397 }
398
399 static int lan87xx_cable_test_report_trans(u32 result)
400 {
401         switch (result) {
402         case LAN87XX_CABLE_TEST_OK:
403                 return ETHTOOL_A_CABLE_RESULT_CODE_OK;
404         case LAN87XX_CABLE_TEST_OPEN:
405                 return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
406         case LAN87XX_CABLE_TEST_SAME_SHORT:
407                 return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
408         default:
409                 /* DIAGNOSTIC_ERROR */
410                 return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
411         }
412 }
413
414 static int lan87xx_cable_test_report(struct phy_device *phydev)
415 {
416         int pos_peak_cycle = 0, pos_peak_in_phases = 0, pos_peak_phase = 0;
417         int neg_peak_cycle = 0, neg_peak_in_phases = 0, neg_peak_phase = 0;
418         int noise_margin = 20, time_margin = 89, jitter_var = 30;
419         int min_time_diff = 96, max_time_diff = 96 + time_margin;
420         bool fault = false, check_a = false, check_b = false;
421         int gain_idx = 0, pos_peak = 0, neg_peak = 0;
422         int pos_peak_time = 0, neg_peak_time = 0;
423         int pos_peak_in_phases_hybrid = 0;
424         int detect = -1;
425
426         gain_idx = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
427                                PHYACC_ATTR_BANK_DSP, 151, 0);
428         /* read non-hybrid results */
429         pos_peak = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
430                                PHYACC_ATTR_BANK_DSP, 153, 0);
431         neg_peak = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
432                                PHYACC_ATTR_BANK_DSP, 154, 0);
433         pos_peak_time = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
434                                     PHYACC_ATTR_BANK_DSP, 156, 0);
435         neg_peak_time = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
436                                     PHYACC_ATTR_BANK_DSP, 157, 0);
437
438         pos_peak_cycle = (pos_peak_time >> 7) & 0x7F;
439         /* calculate non-hybrid values */
440         pos_peak_phase = pos_peak_time & 0x7F;
441         pos_peak_in_phases = (pos_peak_cycle * 96) + pos_peak_phase;
442         neg_peak_cycle = (neg_peak_time >> 7) & 0x7F;
443         neg_peak_phase = neg_peak_time & 0x7F;
444         neg_peak_in_phases = (neg_peak_cycle * 96) + neg_peak_phase;
445
446         /* process values */
447         check_a =
448                 ((pos_peak_in_phases - neg_peak_in_phases) >= min_time_diff) &&
449                 ((pos_peak_in_phases - neg_peak_in_phases) < max_time_diff) &&
450                 pos_peak_in_phases_hybrid < pos_peak_in_phases &&
451                 (pos_peak_in_phases_hybrid < (neg_peak_in_phases + jitter_var));
452         check_b =
453                 ((neg_peak_in_phases - pos_peak_in_phases) >= min_time_diff) &&
454                 ((neg_peak_in_phases - pos_peak_in_phases) < max_time_diff) &&
455                 pos_peak_in_phases_hybrid < neg_peak_in_phases &&
456                 (pos_peak_in_phases_hybrid < (pos_peak_in_phases + jitter_var));
457
458         if (pos_peak_in_phases > neg_peak_in_phases && check_a)
459                 detect = 2;
460         else if ((neg_peak_in_phases > pos_peak_in_phases) && check_b)
461                 detect = 1;
462
463         if (pos_peak > noise_margin && neg_peak > noise_margin &&
464             gain_idx >= 0) {
465                 if (detect == 1 || detect == 2)
466                         fault = true;
467         }
468
469         if (!fault)
470                 detect = 0;
471
472         ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
473                                 lan87xx_cable_test_report_trans(detect));
474
475         return 0;
476 }
477
478 static int lan87xx_cable_test_get_status(struct phy_device *phydev,
479                                          bool *finished)
480 {
481         int rc = 0;
482
483         *finished = false;
484
485         /* check if cable diag was finished */
486         rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_DSP,
487                          90, 0);
488         if (rc < 0)
489                 return rc;
490
491         if ((rc & 2) == 2) {
492                 /* stop cable diag*/
493                 rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE,
494                                  PHYACC_ATTR_BANK_DSP,
495                                  90, 0);
496                 if (rc < 0)
497                         return rc;
498
499                 *finished = true;
500
501                 return lan87xx_cable_test_report(phydev);
502         }
503
504         return 0;
505 }
506
507 static struct phy_driver microchip_t1_phy_driver[] = {
508         {
509                 .phy_id         = 0x0007c150,
510                 .phy_id_mask    = 0xfffffff0,
511                 .name           = "Microchip LAN87xx T1",
512                 .flags          = PHY_POLL_CABLE_TEST,
513
514                 .features       = PHY_BASIC_T1_FEATURES,
515
516                 .config_init    = lan87xx_config_init,
517
518                 .config_intr    = lan87xx_phy_config_intr,
519                 .handle_interrupt = lan87xx_handle_interrupt,
520
521                 .suspend        = genphy_suspend,
522                 .resume         = genphy_resume,
523                 .cable_test_start = lan87xx_cable_test_start,
524                 .cable_test_get_status = lan87xx_cable_test_get_status,
525         }
526 };
527
528 module_phy_driver(microchip_t1_phy_driver);
529
530 static struct mdio_device_id __maybe_unused microchip_t1_tbl[] = {
531         { 0x0007c150, 0xfffffff0 },
532         { }
533 };
534
535 MODULE_DEVICE_TABLE(mdio, microchip_t1_tbl);
536
537 MODULE_AUTHOR(DRIVER_AUTHOR);
538 MODULE_DESCRIPTION(DRIVER_DESC);
539 MODULE_LICENSE("GPL");