GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / net / ethernet / dec / tulip / eeprom.c
1 /*
2         drivers/net/ethernet/dec/tulip/eeprom.c
3
4         Copyright 2000,2001  The Linux Kernel Team
5         Written/copyright 1994-2001 by Donald Becker.
6
7         This software may be used and distributed according to the terms
8         of the GNU General Public License, incorporated herein by reference.
9
10         Please submit bug reports to http://bugzilla.kernel.org/.
11 */
12
13 #include <linux/pci.h>
14 #include <linux/slab.h>
15 #include "tulip.h"
16 #include <asm/unaligned.h>
17
18
19
20 /* Serial EEPROM section. */
21 /* The main routine to parse the very complicated SROM structure.
22    Search www.digital.com for "21X4 SROM" to get details.
23    This code is very complex, and will require changes to support
24    additional cards, so I'll be verbose about what is going on.
25    */
26
27 /* Known cards that have old-style EEPROMs. */
28 static struct eeprom_fixup eeprom_fixups[] = {
29   {"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c,
30                           0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }},
31   {"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x041f,
32                            0x0000, 0x009E, /* 10baseT */
33                            0x0004, 0x009E, /* 10baseT-FD */
34                            0x0903, 0x006D, /* 100baseTx */
35                            0x0905, 0x006D, /* 100baseTx-FD */ }},
36   {"Cogent EM100", 0, 0, 0x92, { 0x1e00, 0x0000, 0x0800, 0x063f,
37                                  0x0107, 0x8021, /* 100baseFx */
38                                  0x0108, 0x8021, /* 100baseFx-FD */
39                                  0x0100, 0x009E, /* 10baseT */
40                                  0x0104, 0x009E, /* 10baseT-FD */
41                                  0x0103, 0x006D, /* 100baseTx */
42                                  0x0105, 0x006D, /* 100baseTx-FD */ }},
43   {"Maxtech NX-110", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x0513,
44                                    0x1001, 0x009E, /* 10base2, CSR12 0x10*/
45                                    0x0000, 0x009E, /* 10baseT */
46                                    0x0004, 0x009E, /* 10baseT-FD */
47                                    0x0303, 0x006D, /* 100baseTx, CSR12 0x03 */
48                                    0x0305, 0x006D, /* 100baseTx-FD CSR12 0x03 */}},
49   {"Accton EN1207", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x051F,
50                                   0x1B01, 0x0000, /* 10base2,   CSR12 0x1B */
51                                   0x0B00, 0x009E, /* 10baseT,   CSR12 0x0B */
52                                   0x0B04, 0x009E, /* 10baseT-FD,CSR12 0x0B */
53                                   0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */
54                                   0x1B05, 0x006D, /* 100baseTx-FD CSR12 0x1B */
55    }},
56   {"NetWinder", 0x00, 0x10, 0x57,
57         /* Default media = MII
58          * MII block, reset sequence (3) = 0x0821 0x0000 0x0001, capabilities 0x01e1
59          */
60         { 0x1e00, 0x0000, 0x000b, 0x8f01, 0x0103, 0x0300, 0x0821, 0x000, 0x0001, 0x0000, 0x01e1 }
61   },
62   {"Cobalt Microserver", 0, 0x10, 0xE0, {0x1e00, /* 0 == controller #, 1e == offset     */
63                                          0x0000, /* 0 == high offset, 0 == gap          */
64                                          0x0800, /* Default Autoselect                  */
65                                          0x8001, /* 1 leaf, extended type, bogus len    */
66                                          0x0003, /* Type 3 (MII), PHY #0                */
67                                          0x0400, /* 0 init instr, 4 reset instr         */
68                                          0x0801, /* Set control mode, GP0 output        */
69                                          0x0000, /* Drive GP0 Low (RST is active low)   */
70                                          0x0800, /* control mode, GP0 input (undriven)  */
71                                          0x0000, /* clear control mode                  */
72                                          0x7800, /* 100TX FDX + HDX, 10bT FDX + HDX     */
73                                          0x01e0, /* Advertise all above                 */
74                                          0x5000, /* FDX all above                       */
75                                          0x1800, /* Set fast TTM in 100bt modes         */
76                                          0x0000, /* PHY cannot be unplugged             */
77   }},
78   {NULL}};
79
80
81 static const char *const block_name[] = {
82         "21140 non-MII",
83         "21140 MII PHY",
84         "21142 Serial PHY",
85         "21142 MII PHY",
86         "21143 SYM PHY",
87         "21143 reset method"
88 };
89
90
91 /**
92  * tulip_build_fake_mediatable - Build a fake mediatable entry.
93  * @tp: Ptr to the tulip private data.
94  *
95  * Some cards like the 3x5 HSC cards (J3514A) do not have a standard
96  * srom and can not be handled under the fixup routine.  These cards
97  * still need a valid mediatable entry for correct csr12 setup and
98  * mii handling.
99  *
100  * Since this is currently a parisc-linux specific function, the
101  * #ifdef __hppa__ should completely optimize this function away for
102  * non-parisc hardware.
103  */
104 static void tulip_build_fake_mediatable(struct tulip_private *tp)
105 {
106 #ifdef CONFIG_GSC
107         if (tp->flags & NEEDS_FAKE_MEDIA_TABLE) {
108                 static unsigned char leafdata[] =
109                         { 0x01,       /* phy number */
110                           0x02,       /* gpr setup sequence length */
111                           0x02, 0x00, /* gpr setup sequence */
112                           0x02,       /* phy reset sequence length */
113                           0x01, 0x00, /* phy reset sequence */
114                           0x00, 0x78, /* media capabilities */
115                           0x00, 0xe0, /* nway advertisement */
116                           0x00, 0x05, /* fdx bit map */
117                           0x00, 0x06  /* ttm bit map */
118                         };
119
120                 tp->mtable = devm_kmalloc(&tp->pdev->dev, sizeof(struct mediatable) +
121                                           sizeof(struct medialeaf), GFP_KERNEL);
122
123                 if (tp->mtable == NULL)
124                         return; /* Horrible, impossible failure. */
125
126                 tp->mtable->defaultmedia = 0x800;
127                 tp->mtable->leafcount = 1;
128                 tp->mtable->csr12dir = 0x3f; /* inputs on bit7 for hsc-pci, bit6 for pci-fx */
129                 tp->mtable->has_nonmii = 0;
130                 tp->mtable->has_reset = 0;
131                 tp->mtable->has_mii = 1;
132                 tp->mtable->csr15dir = tp->mtable->csr15val = 0;
133                 tp->mtable->mleaf[0].type = 1;
134                 tp->mtable->mleaf[0].media = 11;
135                 tp->mtable->mleaf[0].leafdata = &leafdata[0];
136                 tp->flags |= HAS_PHY_IRQ;
137                 tp->csr12_shadow = -1;
138         }
139 #endif
140 }
141
142 void tulip_parse_eeprom(struct net_device *dev)
143 {
144         /*
145           dev is not registered at this point, so logging messages can't
146           use dev_<level> or netdev_<level> but dev->name is good via a
147           hack in the caller
148         */
149
150         /* The last media info list parsed, for multiport boards.  */
151         static struct mediatable *last_mediatable;
152         static unsigned char *last_ee_data;
153         static int controller_index;
154         struct tulip_private *tp = netdev_priv(dev);
155         unsigned char *ee_data = tp->eeprom;
156         int i;
157
158         tp->mtable = NULL;
159         /* Detect an old-style (SA only) EEPROM layout:
160            memcmp(eedata, eedata+16, 8). */
161         for (i = 0; i < 8; i ++)
162                 if (ee_data[i] != ee_data[16+i])
163                         break;
164         if (i >= 8) {
165                 if (ee_data[0] == 0xff) {
166                         if (last_mediatable) {
167                                 controller_index++;
168                                 pr_info("%s: Controller %d of multiport board\n",
169                                         dev->name, controller_index);
170                                 tp->mtable = last_mediatable;
171                                 ee_data = last_ee_data;
172                                 goto subsequent_board;
173                         } else
174                                 pr_info("%s: Missing EEPROM, this interface may not work correctly!\n",
175                                         dev->name);
176                         return;
177                 }
178           /* Do a fix-up based on the vendor half of the station address prefix. */
179           for (i = 0; eeprom_fixups[i].name; i++) {
180                   if (dev->dev_addr[0] == eeprom_fixups[i].addr0 &&
181                       dev->dev_addr[1] == eeprom_fixups[i].addr1 &&
182                       dev->dev_addr[2] == eeprom_fixups[i].addr2) {
183                   if (dev->dev_addr[2] == 0xE8 && ee_data[0x1a] == 0x55)
184                           i++;                  /* An Accton EN1207, not an outlaw Maxtech. */
185                   memcpy(ee_data + 26, eeprom_fixups[i].newtable,
186                                  sizeof(eeprom_fixups[i].newtable));
187                   pr_info("%s: Old format EEPROM on '%s' board.  Using substitute media control info\n",
188                           dev->name, eeprom_fixups[i].name);
189                   break;
190                 }
191           }
192           if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
193                   pr_info("%s: Old style EEPROM with no media selection information\n",
194                           dev->name);
195                 return;
196           }
197         }
198
199         controller_index = 0;
200         if (ee_data[19] > 1) {          /* Multiport board. */
201                 last_ee_data = ee_data;
202         }
203 subsequent_board:
204
205         if (ee_data[27] == 0) {         /* No valid media table. */
206                 tulip_build_fake_mediatable(tp);
207         } else {
208                 unsigned char *p = (void *)ee_data + ee_data[27];
209                 unsigned char csr12dir = 0;
210                 int count, new_advertise = 0;
211                 struct mediatable *mtable;
212                 u16 media = get_u16(p);
213
214                 p += 2;
215                 if (tp->flags & CSR12_IN_SROM)
216                         csr12dir = *p++;
217                 count = *p++;
218
219                 /* there is no phy information, don't even try to build mtable */
220                 if (count == 0) {
221                         if (tulip_debug > 0)
222                                 pr_warn("%s: no phy info, aborting mtable build\n",
223                                         dev->name);
224                         return;
225                 }
226
227                 mtable = devm_kmalloc(&tp->pdev->dev, struct_size(mtable, mleaf, count),
228                                       GFP_KERNEL);
229                 if (mtable == NULL)
230                         return;                         /* Horrible, impossible failure. */
231                 last_mediatable = tp->mtable = mtable;
232                 mtable->defaultmedia = media;
233                 mtable->leafcount = count;
234                 mtable->csr12dir = csr12dir;
235                 mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
236                 mtable->csr15dir = mtable->csr15val = 0;
237
238                 pr_info("%s: EEPROM default media type %s\n",
239                         dev->name,
240                         media & 0x0800 ? "Autosense"
241                                        : medianame[media & MEDIA_MASK]);
242                 for (i = 0; i < count; i++) {
243                         struct medialeaf *leaf = &mtable->mleaf[i];
244
245                         if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */
246                                 leaf->type = 0;
247                                 leaf->media = p[0] & 0x3f;
248                                 leaf->leafdata = p;
249                                 if ((p[2] & 0x61) == 0x01)      /* Bogus, but Znyx boards do it. */
250                                         mtable->has_mii = 1;
251                                 p += 4;
252                         } else {
253                                 leaf->type = p[1];
254                                 if (p[1] == 0x05) {
255                                         mtable->has_reset = i;
256                                         leaf->media = p[2] & 0x0f;
257                                 } else if (tp->chip_id == DM910X && p[1] == 0x80) {
258                                         /* Hack to ignore Davicom delay period block */
259                                         mtable->leafcount--;
260                                         count--;
261                                         i--;
262                                         leaf->leafdata = p + 2;
263                                         p += (p[0] & 0x3f) + 1;
264                                         continue;
265                                 } else if (p[1] & 1) {
266                                         int gpr_len, reset_len;
267
268                                         mtable->has_mii = 1;
269                                         leaf->media = 11;
270                                         gpr_len=p[3]*2;
271                                         reset_len=p[4+gpr_len]*2;
272                                         new_advertise |= get_u16(&p[7+gpr_len+reset_len]);
273                                 } else {
274                                         mtable->has_nonmii = 1;
275                                         leaf->media = p[2] & MEDIA_MASK;
276                                         /* Davicom's media number for 100BaseTX is strange */
277                                         if (tp->chip_id == DM910X && leaf->media == 1)
278                                                 leaf->media = 3;
279                                         switch (leaf->media) {
280                                         case 0: new_advertise |= 0x0020; break;
281                                         case 4: new_advertise |= 0x0040; break;
282                                         case 3: new_advertise |= 0x0080; break;
283                                         case 5: new_advertise |= 0x0100; break;
284                                         case 6: new_advertise |= 0x0200; break;
285                                         }
286                                         if (p[1] == 2  &&  leaf->media == 0) {
287                                                 if (p[2] & 0x40) {
288                                                         u32 base15 = get_unaligned((u16*)&p[7]);
289                                                         mtable->csr15dir =
290                                                                 (get_unaligned((u16*)&p[9])<<16) + base15;
291                                                         mtable->csr15val =
292                                                                 (get_unaligned((u16*)&p[11])<<16) + base15;
293                                                 } else {
294                                                         mtable->csr15dir = get_unaligned((u16*)&p[3])<<16;
295                                                         mtable->csr15val = get_unaligned((u16*)&p[5])<<16;
296                                                 }
297                                         }
298                                 }
299                                 leaf->leafdata = p + 2;
300                                 p += (p[0] & 0x3f) + 1;
301                         }
302                         if (tulip_debug > 1  &&  leaf->media == 11) {
303                                 unsigned char *bp = leaf->leafdata;
304                                 pr_info("%s: MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %02x %02x\n",
305                                         dev->name,
306                                         bp[0], bp[1], bp[2 + bp[1]*2],
307                                         bp[5 + bp[2 + bp[1]*2]*2],
308                                         bp[4 + bp[2 + bp[1]*2]*2]);
309                         }
310                         pr_info("%s: Index #%d - Media %s (#%d) described by a %s (%d) block\n",
311                                 dev->name,
312                                 i, medianame[leaf->media & 15], leaf->media,
313                                 leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>",
314                                 leaf->type);
315                 }
316                 if (new_advertise)
317                         tp->sym_advertise = new_advertise;
318         }
319 }
320 /* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/
321
322 /*  EEPROM_Ctrl bits. */
323 #define EE_SHIFT_CLK    0x02    /* EEPROM shift clock. */
324 #define EE_CS           0x01    /* EEPROM chip select. */
325 #define EE_DATA_WRITE   0x04    /* Data from the Tulip to EEPROM. */
326 #define EE_WRITE_0      0x01
327 #define EE_WRITE_1      0x05
328 #define EE_DATA_READ    0x08    /* Data from the EEPROM chip. */
329 #define EE_ENB          (0x4800 | EE_CS)
330
331 /* Delay between EEPROM clock transitions.
332    Even at 33Mhz current PCI implementations don't overrun the EEPROM clock.
333    We add a bus turn-around to insure that this remains true. */
334 #define eeprom_delay()  ioread32(ee_addr)
335
336 /* The EEPROM commands include the alway-set leading bit. */
337 #define EE_READ_CMD             (6)
338
339 /* Note: this routine returns extra data bits for size detection. */
340 int tulip_read_eeprom(struct net_device *dev, int location, int addr_len)
341 {
342         int i;
343         unsigned retval = 0;
344         struct tulip_private *tp = netdev_priv(dev);
345         void __iomem *ee_addr = tp->base_addr + CSR9;
346         int read_cmd = location | (EE_READ_CMD << addr_len);
347
348         /* If location is past the end of what we can address, don't
349          * read some other location (ie truncate). Just return zero.
350          */
351         if (location > (1 << addr_len) - 1)
352                 return 0;
353
354         iowrite32(EE_ENB & ~EE_CS, ee_addr);
355         iowrite32(EE_ENB, ee_addr);
356
357         /* Shift the read command bits out. */
358         for (i = 4 + addr_len; i >= 0; i--) {
359                 short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
360                 iowrite32(EE_ENB | dataval, ee_addr);
361                 eeprom_delay();
362                 iowrite32(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
363                 eeprom_delay();
364                 retval = (retval << 1) | ((ioread32(ee_addr) & EE_DATA_READ) ? 1 : 0);
365         }
366         iowrite32(EE_ENB, ee_addr);
367         eeprom_delay();
368
369         for (i = 16; i > 0; i--) {
370                 iowrite32(EE_ENB | EE_SHIFT_CLK, ee_addr);
371                 eeprom_delay();
372                 retval = (retval << 1) | ((ioread32(ee_addr) & EE_DATA_READ) ? 1 : 0);
373                 iowrite32(EE_ENB, ee_addr);
374                 eeprom_delay();
375         }
376
377         /* Terminate the EEPROM access. */
378         iowrite32(EE_ENB & ~EE_CS, ee_addr);
379         return (tp->flags & HAS_SWAPPED_SEEPROM) ? swab16(retval) : retval;
380 }
381