linux/drivers/net/tulip/media.c
<<
>>
Prefs
   1/*
   2        drivers/net/tulip/media.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 refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
  11        for more information on this driver.
  12
  13        Please submit bugs to http://bugzilla.kernel.org/ .
  14*/
  15
  16#include <linux/kernel.h>
  17#include <linux/mii.h>
  18#include <linux/init.h>
  19#include <linux/delay.h>
  20#include <linux/pci.h>
  21#include "tulip.h"
  22
  23
  24/* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
  25   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
  26   "overclocking" issues or future 66Mhz PCI. */
  27#define mdio_delay() ioread32(mdio_addr)
  28
  29/* Read and write the MII registers using software-generated serial
  30   MDIO protocol.  It is just different enough from the EEPROM protocol
  31   to not share code.  The maxium data clock rate is 2.5 Mhz. */
  32#define MDIO_SHIFT_CLK          0x10000
  33#define MDIO_DATA_WRITE0        0x00000
  34#define MDIO_DATA_WRITE1        0x20000
  35#define MDIO_ENB                0x00000 /* Ignore the 0x02000 databook setting. */
  36#define MDIO_ENB_IN             0x40000
  37#define MDIO_DATA_READ          0x80000
  38
  39static const unsigned char comet_miireg2offset[32] = {
  40        0xB4, 0xB8, 0xBC, 0xC0,  0xC4, 0xC8, 0xCC, 0,  0,0,0,0,  0,0,0,0,
  41        0,0xD0,0,0,  0,0,0,0,  0,0,0,0, 0, 0xD4, 0xD8, 0xDC, };
  42
  43
  44/* MII transceiver control section.
  45   Read and write the MII registers using software-generated serial
  46   MDIO protocol.
  47   See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management functions")
  48   or DP83840A data sheet for more details.
  49   */
  50
  51int tulip_mdio_read(struct net_device *dev, int phy_id, int location)
  52{
  53        struct tulip_private *tp = netdev_priv(dev);
  54        int i;
  55        int read_cmd = (0xf6 << 10) | ((phy_id & 0x1f) << 5) | location;
  56        int retval = 0;
  57        void __iomem *ioaddr = tp->base_addr;
  58        void __iomem *mdio_addr = ioaddr + CSR9;
  59        unsigned long flags;
  60
  61        if (location & ~0x1f)
  62                return 0xffff;
  63
  64        if (tp->chip_id == COMET  &&  phy_id == 30) {
  65                if (comet_miireg2offset[location])
  66                        return ioread32(ioaddr + comet_miireg2offset[location]);
  67                return 0xffff;
  68        }
  69
  70        spin_lock_irqsave(&tp->mii_lock, flags);
  71        if (tp->chip_id == LC82C168) {
  72                iowrite32(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
  73                ioread32(ioaddr + 0xA0);
  74                ioread32(ioaddr + 0xA0);
  75                for (i = 1000; i >= 0; --i) {
  76                        barrier();
  77                        if ( ! ((retval = ioread32(ioaddr + 0xA0)) & 0x80000000))
  78                                break;
  79                }
  80                spin_unlock_irqrestore(&tp->mii_lock, flags);
  81                return retval & 0xffff;
  82        }
  83
  84        /* Establish sync by sending at least 32 logic ones. */
  85        for (i = 32; i >= 0; i--) {
  86                iowrite32(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
  87                mdio_delay();
  88                iowrite32(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
  89                mdio_delay();
  90        }
  91        /* Shift the read command bits out. */
  92        for (i = 15; i >= 0; i--) {
  93                int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
  94
  95                iowrite32(MDIO_ENB | dataval, mdio_addr);
  96                mdio_delay();
  97                iowrite32(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
  98                mdio_delay();
  99        }
 100        /* Read the two transition, 16 data, and wire-idle bits. */
 101        for (i = 19; i > 0; i--) {
 102                iowrite32(MDIO_ENB_IN, mdio_addr);
 103                mdio_delay();
 104                retval = (retval << 1) | ((ioread32(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
 105                iowrite32(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
 106                mdio_delay();
 107        }
 108
 109        spin_unlock_irqrestore(&tp->mii_lock, flags);
 110        return (retval>>1) & 0xffff;
 111}
 112
 113void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int val)
 114{
 115        struct tulip_private *tp = netdev_priv(dev);
 116        int i;
 117        int cmd = (0x5002 << 16) | ((phy_id & 0x1f) << 23) | (location<<18) | (val & 0xffff);
 118        void __iomem *ioaddr = tp->base_addr;
 119        void __iomem *mdio_addr = ioaddr + CSR9;
 120        unsigned long flags;
 121
 122        if (location & ~0x1f)
 123                return;
 124
 125        if (tp->chip_id == COMET && phy_id == 30) {
 126                if (comet_miireg2offset[location])
 127                        iowrite32(val, ioaddr + comet_miireg2offset[location]);
 128                return;
 129        }
 130
 131        spin_lock_irqsave(&tp->mii_lock, flags);
 132        if (tp->chip_id == LC82C168) {
 133                iowrite32(cmd, ioaddr + 0xA0);
 134                for (i = 1000; i >= 0; --i) {
 135                        barrier();
 136                        if ( ! (ioread32(ioaddr + 0xA0) & 0x80000000))
 137                                break;
 138                }
 139                spin_unlock_irqrestore(&tp->mii_lock, flags);
 140                return;
 141        }
 142
 143        /* Establish sync by sending 32 logic ones. */
 144        for (i = 32; i >= 0; i--) {
 145                iowrite32(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
 146                mdio_delay();
 147                iowrite32(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
 148                mdio_delay();
 149        }
 150        /* Shift the command bits out. */
 151        for (i = 31; i >= 0; i--) {
 152                int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
 153                iowrite32(MDIO_ENB | dataval, mdio_addr);
 154                mdio_delay();
 155                iowrite32(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
 156                mdio_delay();
 157        }
 158        /* Clear out extra bits. */
 159        for (i = 2; i > 0; i--) {
 160                iowrite32(MDIO_ENB_IN, mdio_addr);
 161                mdio_delay();
 162                iowrite32(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
 163                mdio_delay();
 164        }
 165
 166        spin_unlock_irqrestore(&tp->mii_lock, flags);
 167}
 168
 169
 170/* Set up the transceiver control registers for the selected media type. */
 171void tulip_select_media(struct net_device *dev, int startup)
 172{
 173        struct tulip_private *tp = netdev_priv(dev);
 174        void __iomem *ioaddr = tp->base_addr;
 175        struct mediatable *mtable = tp->mtable;
 176        u32 new_csr6;
 177        int i;
 178
 179        if (mtable) {
 180                struct medialeaf *mleaf = &mtable->mleaf[tp->cur_index];
 181                unsigned char *p = mleaf->leafdata;
 182                switch (mleaf->type) {
 183                case 0:                                 /* 21140 non-MII xcvr. */
 184                        if (tulip_debug > 1)
 185                                printk(KERN_DEBUG "%s: Using a 21140 non-MII transceiver"
 186                                           " with control setting %2.2x.\n",
 187                                           dev->name, p[1]);
 188                        dev->if_port = p[0];
 189                        if (startup)
 190                                iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12);
 191                        iowrite32(p[1], ioaddr + CSR12);
 192                        new_csr6 = 0x02000000 | ((p[2] & 0x71) << 18);
 193                        break;
 194                case 2: case 4: {
 195                        u16 setup[5];
 196                        u32 csr13val, csr14val, csr15dir, csr15val;
 197                        for (i = 0; i < 5; i++)
 198                                setup[i] = get_u16(&p[i*2 + 1]);
 199
 200                        dev->if_port = p[0] & MEDIA_MASK;
 201                        if (tulip_media_cap[dev->if_port] & MediaAlwaysFD)
 202                                tp->full_duplex = 1;
 203
 204                        if (startup && mtable->has_reset) {
 205                                struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
 206                                unsigned char *rst = rleaf->leafdata;
 207                                if (tulip_debug > 1)
 208                                        printk(KERN_DEBUG "%s: Resetting the transceiver.\n",
 209                                                   dev->name);
 210                                for (i = 0; i < rst[0]; i++)
 211                                        iowrite32(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
 212                        }
 213                        if (tulip_debug > 1)
 214                                printk(KERN_DEBUG "%s: 21143 non-MII %s transceiver control "
 215                                           "%4.4x/%4.4x.\n",
 216                                           dev->name, medianame[dev->if_port], setup[0], setup[1]);
 217                        if (p[0] & 0x40) {      /* SIA (CSR13-15) setup values are provided. */
 218                                csr13val = setup[0];
 219                                csr14val = setup[1];
 220                                csr15dir = (setup[3]<<16) | setup[2];
 221                                csr15val = (setup[4]<<16) | setup[2];
 222                                iowrite32(0, ioaddr + CSR13);
 223                                iowrite32(csr14val, ioaddr + CSR14);
 224                                iowrite32(csr15dir, ioaddr + CSR15);    /* Direction */
 225                                iowrite32(csr15val, ioaddr + CSR15);    /* Data */
 226                                iowrite32(csr13val, ioaddr + CSR13);
 227                        } else {
 228                                csr13val = 1;
 229                                csr14val = 0;
 230                                csr15dir = (setup[0]<<16) | 0x0008;
 231                                csr15val = (setup[1]<<16) | 0x0008;
 232                                if (dev->if_port <= 4)
 233                                        csr14val = t21142_csr14[dev->if_port];
 234                                if (startup) {
 235                                        iowrite32(0, ioaddr + CSR13);
 236                                        iowrite32(csr14val, ioaddr + CSR14);
 237                                }
 238                                iowrite32(csr15dir, ioaddr + CSR15);    /* Direction */
 239                                iowrite32(csr15val, ioaddr + CSR15);    /* Data */
 240                                if (startup) iowrite32(csr13val, ioaddr + CSR13);
 241                        }
 242                        if (tulip_debug > 1)
 243                                printk(KERN_DEBUG "%s:  Setting CSR15 to %8.8x/%8.8x.\n",
 244                                           dev->name, csr15dir, csr15val);
 245                        if (mleaf->type == 4)
 246                                new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18);
 247                        else
 248                                new_csr6 = 0x82420000;
 249                        break;
 250                }
 251                case 1: case 3: {
 252                        int phy_num = p[0];
 253                        int init_length = p[1];
 254                        u16 *misc_info, tmp_info;
 255
 256                        dev->if_port = 11;
 257                        new_csr6 = 0x020E0000;
 258                        if (mleaf->type == 3) { /* 21142 */
 259                                u16 *init_sequence = (u16*)(p+2);
 260                                u16 *reset_sequence = &((u16*)(p+3))[init_length];
 261                                int reset_length = p[2 + init_length*2];
 262                                misc_info = reset_sequence + reset_length;
 263                                if (startup) {
 264                                        int timeout = 10;       /* max 1 ms */
 265                                        for (i = 0; i < reset_length; i++)
 266                                                iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);
 267
 268                                        /* flush posted writes */
 269                                        ioread32(ioaddr + CSR15);
 270
 271                                        /* Sect 3.10.3 in DP83840A.pdf (p39) */
 272                                        udelay(500);
 273
 274                                        /* Section 4.2 in DP83840A.pdf (p43) */
 275                                        /* and IEEE 802.3 "22.2.4.1.1 Reset" */
 276                                        while (timeout-- &&
 277                                                (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
 278                                                udelay(100);
 279                                }
 280                                for (i = 0; i < init_length; i++)
 281                                        iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15);
 282
 283                                ioread32(ioaddr + CSR15);       /* flush posted writes */
 284                        } else {
 285                                u8 *init_sequence = p + 2;
 286                                u8 *reset_sequence = p + 3 + init_length;
 287                                int reset_length = p[2 + init_length];
 288                                misc_info = (u16*)(reset_sequence + reset_length);
 289                                if (startup) {
 290                                        int timeout = 10;       /* max 1 ms */
 291                                        iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12);
 292                                        for (i = 0; i < reset_length; i++)
 293                                                iowrite32(reset_sequence[i], ioaddr + CSR12);
 294
 295                                        /* flush posted writes */
 296                                        ioread32(ioaddr + CSR12);
 297
 298                                        /* Sect 3.10.3 in DP83840A.pdf (p39) */
 299                                        udelay(500);
 300
 301                                        /* Section 4.2 in DP83840A.pdf (p43) */
 302                                        /* and IEEE 802.3 "22.2.4.1.1 Reset" */
 303                                        while (timeout-- &&
 304                                                (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
 305                                                udelay(100);
 306                                }
 307                                for (i = 0; i < init_length; i++)
 308                                        iowrite32(init_sequence[i], ioaddr + CSR12);
 309
 310                                ioread32(ioaddr + CSR12);       /* flush posted writes */
 311                        }
 312
 313                        tmp_info = get_u16(&misc_info[1]);
 314                        if (tmp_info)
 315                                tp->advertising[phy_num] = tmp_info | 1;
 316                        if (tmp_info && startup < 2) {
 317                                if (tp->mii_advertise == 0)
 318                                        tp->mii_advertise = tp->advertising[phy_num];
 319                                if (tulip_debug > 1)
 320                                        printk(KERN_DEBUG "%s:  Advertising %4.4x on MII %d.\n",
 321                                               dev->name, tp->mii_advertise, tp->phys[phy_num]);
 322                                tulip_mdio_write(dev, tp->phys[phy_num], 4, tp->mii_advertise);
 323                        }
 324                        break;
 325                }
 326                case 5: case 6: {
 327                        u16 setup[5];
 328
 329                        new_csr6 = 0; /* FIXME */
 330
 331                        for (i = 0; i < 5; i++)
 332                                setup[i] = get_u16(&p[i*2 + 1]);
 333
 334                        if (startup && mtable->has_reset) {
 335                                struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
 336                                unsigned char *rst = rleaf->leafdata;
 337                                if (tulip_debug > 1)
 338                                        printk(KERN_DEBUG "%s: Resetting the transceiver.\n",
 339                                                   dev->name);
 340                                for (i = 0; i < rst[0]; i++)
 341                                        iowrite32(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
 342                        }
 343
 344                        break;
 345                }
 346                default:
 347                        printk(KERN_DEBUG "%s:  Invalid media table selection %d.\n",
 348                                           dev->name, mleaf->type);
 349                        new_csr6 = 0x020E0000;
 350                }
 351                if (tulip_debug > 1)
 352                        printk(KERN_DEBUG "%s: Using media type %s, CSR12 is %2.2x.\n",
 353                                   dev->name, medianame[dev->if_port],
 354                                   ioread32(ioaddr + CSR12) & 0xff);
 355        } else if (tp->chip_id == LC82C168) {
 356                if (startup && ! tp->medialock)
 357                        dev->if_port = tp->mii_cnt ? 11 : 0;
 358                if (tulip_debug > 1)
 359                        printk(KERN_DEBUG "%s: PNIC PHY status is %3.3x, media %s.\n",
 360                                   dev->name, ioread32(ioaddr + 0xB8), medianame[dev->if_port]);
 361                if (tp->mii_cnt) {
 362                        new_csr6 = 0x810C0000;
 363                        iowrite32(0x0001, ioaddr + CSR15);
 364                        iowrite32(0x0201B07A, ioaddr + 0xB8);
 365                } else if (startup) {
 366                        /* Start with 10mbps to do autonegotiation. */
 367                        iowrite32(0x32, ioaddr + CSR12);
 368                        new_csr6 = 0x00420000;
 369                        iowrite32(0x0001B078, ioaddr + 0xB8);
 370                        iowrite32(0x0201B078, ioaddr + 0xB8);
 371                } else if (dev->if_port == 3  ||  dev->if_port == 5) {
 372                        iowrite32(0x33, ioaddr + CSR12);
 373                        new_csr6 = 0x01860000;
 374                        /* Trigger autonegotiation. */
 375                        iowrite32(startup ? 0x0201F868 : 0x0001F868, ioaddr + 0xB8);
 376                } else {
 377                        iowrite32(0x32, ioaddr + CSR12);
 378                        new_csr6 = 0x00420000;
 379                        iowrite32(0x1F078, ioaddr + 0xB8);
 380                }
 381        } else {                                        /* Unknown chip type with no media table. */
 382                if (tp->default_port == 0)
 383                        dev->if_port = tp->mii_cnt ? 11 : 3;
 384                if (tulip_media_cap[dev->if_port] & MediaIsMII) {
 385                        new_csr6 = 0x020E0000;
 386                } else if (tulip_media_cap[dev->if_port] & MediaIsFx) {
 387                        new_csr6 = 0x02860000;
 388                } else
 389                        new_csr6 = 0x03860000;
 390                if (tulip_debug > 1)
 391                        printk(KERN_DEBUG "%s: No media description table, assuming "
 392                                   "%s transceiver, CSR12 %2.2x.\n",
 393                                   dev->name, medianame[dev->if_port],
 394                                   ioread32(ioaddr + CSR12));
 395        }
 396
 397        tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0);
 398
 399        mdelay(1);
 400
 401        return;
 402}
 403
 404/*
 405  Check the MII negotiated duplex and change the CSR6 setting if
 406  required.
 407  Return 0 if everything is OK.
 408  Return < 0 if the transceiver is missing or has no link beat.
 409  */
 410int tulip_check_duplex(struct net_device *dev)
 411{
 412        struct tulip_private *tp = netdev_priv(dev);
 413        unsigned int bmsr, lpa, negotiated, new_csr6;
 414
 415        bmsr = tulip_mdio_read(dev, tp->phys[0], MII_BMSR);
 416        lpa = tulip_mdio_read(dev, tp->phys[0], MII_LPA);
 417        if (tulip_debug > 1)
 418                printk(KERN_INFO "%s: MII status %4.4x, Link partner report "
 419                           "%4.4x.\n", dev->name, bmsr, lpa);
 420        if (bmsr == 0xffff)
 421                return -2;
 422        if ((bmsr & BMSR_LSTATUS) == 0) {
 423                int new_bmsr = tulip_mdio_read(dev, tp->phys[0], MII_BMSR);
 424                if ((new_bmsr & BMSR_LSTATUS) == 0) {
 425                        if (tulip_debug  > 1)
 426                                printk(KERN_INFO "%s: No link beat on the MII interface,"
 427                                           " status %4.4x.\n", dev->name, new_bmsr);
 428                        return -1;
 429                }
 430        }
 431        negotiated = lpa & tp->advertising[0];
 432        tp->full_duplex = mii_duplex(tp->full_duplex_lock, negotiated);
 433
 434        new_csr6 = tp->csr6;
 435
 436        if (negotiated & LPA_100) new_csr6 &= ~TxThreshold;
 437        else                      new_csr6 |= TxThreshold;
 438        if (tp->full_duplex) new_csr6 |= FullDuplex;
 439        else                 new_csr6 &= ~FullDuplex;
 440
 441        if (new_csr6 != tp->csr6) {
 442                tp->csr6 = new_csr6;
 443                tulip_restart_rxtx(tp);
 444
 445                if (tulip_debug > 0)
 446                        printk(KERN_INFO "%s: Setting %s-duplex based on MII"
 447                                   "#%d link partner capability of %4.4x.\n",
 448                                   dev->name, tp->full_duplex ? "full" : "half",
 449                                   tp->phys[0], lpa);
 450                return 1;
 451        }
 452
 453        return 0;
 454}
 455
 456void __devinit tulip_find_mii (struct net_device *dev, int board_idx)
 457{
 458        struct tulip_private *tp = netdev_priv(dev);
 459        int phyn, phy_idx = 0;
 460        int mii_reg0;
 461        int mii_advert;
 462        unsigned int to_advert, new_bmcr, ane_switch;
 463
 464        /* Find the connected MII xcvrs.
 465           Doing this in open() would allow detecting external xcvrs later,
 466           but takes much time. */
 467        for (phyn = 1; phyn <= 32 && phy_idx < sizeof (tp->phys); phyn++) {
 468                int phy = phyn & 0x1f;
 469                int mii_status = tulip_mdio_read (dev, phy, MII_BMSR);
 470                if ((mii_status & 0x8301) == 0x8001 ||
 471                    ((mii_status & BMSR_100BASE4) == 0
 472                     && (mii_status & 0x7800) != 0)) {
 473                        /* preserve Becker logic, gain indentation level */
 474                } else {
 475                        continue;
 476                }
 477
 478                mii_reg0 = tulip_mdio_read (dev, phy, MII_BMCR);
 479                mii_advert = tulip_mdio_read (dev, phy, MII_ADVERTISE);
 480                ane_switch = 0;
 481
 482                /* if not advertising at all, gen an
 483                 * advertising value from the capability
 484                 * bits in BMSR
 485                 */
 486                if ((mii_advert & ADVERTISE_ALL) == 0) {
 487                        unsigned int tmpadv = tulip_mdio_read (dev, phy, MII_BMSR);
 488                        mii_advert = ((tmpadv >> 6) & 0x3e0) | 1;
 489                }
 490
 491                if (tp->mii_advertise) {
 492                        tp->advertising[phy_idx] =
 493                        to_advert = tp->mii_advertise;
 494                } else if (tp->advertising[phy_idx]) {
 495                        to_advert = tp->advertising[phy_idx];
 496                } else {
 497                        tp->advertising[phy_idx] =
 498                        tp->mii_advertise =
 499                        to_advert = mii_advert;
 500                }
 501
 502                tp->phys[phy_idx++] = phy;
 503
 504                printk (KERN_INFO "tulip%d:  MII transceiver #%d "
 505                        "config %4.4x status %4.4x advertising %4.4x.\n",
 506                        board_idx, phy, mii_reg0, mii_status, mii_advert);
 507
 508                /* Fixup for DLink with miswired PHY. */
 509                if (mii_advert != to_advert) {
 510                        printk (KERN_DEBUG "tulip%d:  Advertising %4.4x on PHY %d,"
 511                                " previously advertising %4.4x.\n",
 512                                board_idx, to_advert, phy, mii_advert);
 513                        tulip_mdio_write (dev, phy, 4, to_advert);
 514                }
 515
 516                /* Enable autonegotiation: some boards default to off. */
 517                if (tp->default_port == 0) {
 518                        new_bmcr = mii_reg0 | BMCR_ANENABLE;
 519                        if (new_bmcr != mii_reg0) {
 520                                new_bmcr |= BMCR_ANRESTART;
 521                                ane_switch = 1;
 522                        }
 523                }
 524                /* ...or disable nway, if forcing media */
 525                else {
 526                        new_bmcr = mii_reg0 & ~BMCR_ANENABLE;
 527                        if (new_bmcr != mii_reg0)
 528                                ane_switch = 1;
 529                }
 530
 531                /* clear out bits we never want at this point */
 532                new_bmcr &= ~(BMCR_CTST | BMCR_FULLDPLX | BMCR_ISOLATE |
 533                              BMCR_PDOWN | BMCR_SPEED100 | BMCR_LOOPBACK |
 534                              BMCR_RESET);
 535
 536                if (tp->full_duplex)
 537                        new_bmcr |= BMCR_FULLDPLX;
 538                if (tulip_media_cap[tp->default_port] & MediaIs100)
 539                        new_bmcr |= BMCR_SPEED100;
 540
 541                if (new_bmcr != mii_reg0) {
 542                        /* some phys need the ANE switch to
 543                         * happen before forced media settings
 544                         * will "take."  However, we write the
 545                         * same value twice in order not to
 546                         * confuse the sane phys.
 547                         */
 548                        if (ane_switch) {
 549                                tulip_mdio_write (dev, phy, MII_BMCR, new_bmcr);
 550                                udelay (10);
 551                        }
 552                        tulip_mdio_write (dev, phy, MII_BMCR, new_bmcr);
 553                }
 554        }
 555        tp->mii_cnt = phy_idx;
 556        if (tp->mtable && tp->mtable->has_mii && phy_idx == 0) {
 557                printk (KERN_INFO "tulip%d: ***WARNING***: No MII transceiver found!\n",
 558                        board_idx);
 559                tp->phys[0] = 1;
 560        }
 561}
 562
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.