linux/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
<<
>>
Prefs
   1/*******************************************************************************
   2  This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
   3  DWC Ether MAC 10/100/1000 Universal version 3.41a  has been used for
   4  developing this code.
   5
   6  This only implements the mac core functions for this chip.
   7
   8  Copyright (C) 2007-2009  STMicroelectronics Ltd
   9
  10  This program is free software; you can redistribute it and/or modify it
  11  under the terms and conditions of the GNU General Public License,
  12  version 2, as published by the Free Software Foundation.
  13
  14  This program is distributed in the hope it will be useful, but WITHOUT
  15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  16  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  17  more details.
  18
  19  You should have received a copy of the GNU General Public License along with
  20  this program; if not, write to the Free Software Foundation, Inc.,
  21  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  22
  23  The full GNU General Public License is included in this distribution in
  24  the file called "COPYING".
  25
  26  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
  27*******************************************************************************/
  28
  29#include <linux/crc32.h>
  30#include <linux/slab.h>
  31#include <linux/ethtool.h>
  32#include <asm/io.h>
  33#include "dwmac1000.h"
  34
  35static void dwmac1000_core_init(struct mac_device_info *hw, int mtu)
  36{
  37        void __iomem *ioaddr = hw->pcsr;
  38        u32 value = readl(ioaddr + GMAC_CONTROL);
  39        value |= GMAC_CORE_INIT;
  40        if (mtu > 1500)
  41                value |= GMAC_CONTROL_2K;
  42        if (mtu > 2000)
  43                value |= GMAC_CONTROL_JE;
  44
  45        writel(value, ioaddr + GMAC_CONTROL);
  46
  47        /* Mask GMAC interrupts */
  48        writel(0x207, ioaddr + GMAC_INT_MASK);
  49
  50#ifdef STMMAC_VLAN_TAG_USED
  51        /* Tag detection without filtering */
  52        writel(0x0, ioaddr + GMAC_VLAN_TAG);
  53#endif
  54}
  55
  56static int dwmac1000_rx_ipc_enable(struct mac_device_info *hw)
  57{
  58        void __iomem *ioaddr = hw->pcsr;
  59        u32 value = readl(ioaddr + GMAC_CONTROL);
  60
  61        if (hw->rx_csum)
  62                value |= GMAC_CONTROL_IPC;
  63        else
  64                value &= ~GMAC_CONTROL_IPC;
  65
  66        writel(value, ioaddr + GMAC_CONTROL);
  67
  68        value = readl(ioaddr + GMAC_CONTROL);
  69
  70        return !!(value & GMAC_CONTROL_IPC);
  71}
  72
  73static void dwmac1000_dump_regs(struct mac_device_info *hw)
  74{
  75        void __iomem *ioaddr = hw->pcsr;
  76        int i;
  77        pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr);
  78
  79        for (i = 0; i < 55; i++) {
  80                int offset = i * 4;
  81                pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
  82                        offset, readl(ioaddr + offset));
  83        }
  84}
  85
  86static void dwmac1000_set_umac_addr(struct mac_device_info *hw,
  87                                    unsigned char *addr,
  88                                    unsigned int reg_n)
  89{
  90        void __iomem *ioaddr = hw->pcsr;
  91        stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
  92                            GMAC_ADDR_LOW(reg_n));
  93}
  94
  95static void dwmac1000_get_umac_addr(struct mac_device_info *hw,
  96                                    unsigned char *addr,
  97                                    unsigned int reg_n)
  98{
  99        void __iomem *ioaddr = hw->pcsr;
 100        stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
 101                            GMAC_ADDR_LOW(reg_n));
 102}
 103
 104static void dwmac1000_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits,
 105                                 int mcbitslog2)
 106{
 107        int numhashregs, regs;
 108
 109        switch (mcbitslog2) {
 110        case 6:
 111                writel(mcfilterbits[0], ioaddr + GMAC_HASH_LOW);
 112                writel(mcfilterbits[1], ioaddr + GMAC_HASH_HIGH);
 113                return;
 114                break;
 115        case 7:
 116                numhashregs = 4;
 117                break;
 118        case 8:
 119                numhashregs = 8;
 120                break;
 121        default:
 122                pr_debug("STMMAC: err in setting mulitcast filter\n");
 123                return;
 124                break;
 125        }
 126        for (regs = 0; regs < numhashregs; regs++)
 127                writel(mcfilterbits[regs],
 128                       ioaddr + GMAC_EXTHASH_BASE + regs * 4);
 129}
 130
 131static void dwmac1000_set_filter(struct mac_device_info *hw,
 132                                 struct net_device *dev)
 133{
 134        void __iomem *ioaddr = (void __iomem *)dev->base_addr;
 135        unsigned int value = 0;
 136        unsigned int perfect_addr_number = hw->unicast_filter_entries;
 137        u32 mc_filter[8];
 138        int mcbitslog2 = hw->mcast_bits_log2;
 139
 140        pr_debug("%s: # mcasts %d, # unicast %d\n", __func__,
 141                 netdev_mc_count(dev), netdev_uc_count(dev));
 142
 143        memset(mc_filter, 0, sizeof(mc_filter));
 144
 145        if (dev->flags & IFF_PROMISC) {
 146                value = GMAC_FRAME_FILTER_PR;
 147        } else if (dev->flags & IFF_ALLMULTI) {
 148                value = GMAC_FRAME_FILTER_PM;   /* pass all multi */
 149        } else if (!netdev_mc_empty(dev)) {
 150                struct netdev_hw_addr *ha;
 151
 152                /* Hash filter for multicast */
 153                value = GMAC_FRAME_FILTER_HMC;
 154
 155                netdev_for_each_mc_addr(ha, dev) {
 156                        /* The upper n bits of the calculated CRC are used to
 157                         * index the contents of the hash table. The number of
 158                         * bits used depends on the hardware configuration
 159                         * selected at core configuration time.
 160                         */
 161                        int bit_nr = bitrev32(~crc32_le(~0, ha->addr,
 162                                              ETH_ALEN)) >>
 163                                              (32 - mcbitslog2);
 164                        /* The most significant bit determines the register to
 165                         * use (H/L) while the other 5 bits determine the bit
 166                         * within the register.
 167                         */
 168                        mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
 169                }
 170        }
 171
 172        dwmac1000_set_mchash(ioaddr, mc_filter, mcbitslog2);
 173
 174        /* Handle multiple unicast addresses (perfect filtering) */
 175        if (netdev_uc_count(dev) > perfect_addr_number)
 176                /* Switch to promiscuous mode if more than unicast
 177                 * addresses are requested than supported by hardware.
 178                 */
 179                value |= GMAC_FRAME_FILTER_PR;
 180        else {
 181                int reg = 1;
 182                struct netdev_hw_addr *ha;
 183
 184                netdev_for_each_uc_addr(ha, dev) {
 185                        stmmac_set_mac_addr(ioaddr, ha->addr,
 186                                            GMAC_ADDR_HIGH(reg),
 187                                            GMAC_ADDR_LOW(reg));
 188                        reg++;
 189                }
 190        }
 191
 192#ifdef FRAME_FILTER_DEBUG
 193        /* Enable Receive all mode (to debug filtering_fail errors) */
 194        value |= GMAC_FRAME_FILTER_RA;
 195#endif
 196        writel(value, ioaddr + GMAC_FRAME_FILTER);
 197}
 198
 199
 200static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
 201                                unsigned int fc, unsigned int pause_time)
 202{
 203        void __iomem *ioaddr = hw->pcsr;
 204        /* Set flow such that DZPQ in Mac Register 6 is 0,
 205         * and unicast pause detect is enabled.
 206         */
 207        unsigned int flow = GMAC_FLOW_CTRL_UP;
 208
 209        pr_debug("GMAC Flow-Control:\n");
 210        if (fc & FLOW_RX) {
 211                pr_debug("\tReceive Flow-Control ON\n");
 212                flow |= GMAC_FLOW_CTRL_RFE;
 213        }
 214        if (fc & FLOW_TX) {
 215                pr_debug("\tTransmit Flow-Control ON\n");
 216                flow |= GMAC_FLOW_CTRL_TFE;
 217        }
 218
 219        if (duplex) {
 220                pr_debug("\tduplex mode: PAUSE %d\n", pause_time);
 221                flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
 222        }
 223
 224        writel(flow, ioaddr + GMAC_FLOW_CTRL);
 225}
 226
 227static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode)
 228{
 229        void __iomem *ioaddr = hw->pcsr;
 230        unsigned int pmt = 0;
 231
 232        if (mode & WAKE_MAGIC) {
 233                pr_debug("GMAC: WOL Magic frame\n");
 234                pmt |= power_down | magic_pkt_en;
 235        }
 236        if (mode & WAKE_UCAST) {
 237                pr_debug("GMAC: WOL on global unicast\n");
 238                pmt |= global_unicast;
 239        }
 240
 241        writel(pmt, ioaddr + GMAC_PMT);
 242}
 243
 244static int dwmac1000_irq_status(struct mac_device_info *hw,
 245                                struct stmmac_extra_stats *x)
 246{
 247        void __iomem *ioaddr = hw->pcsr;
 248        u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
 249        int ret = 0;
 250
 251        /* Not used events (e.g. MMC interrupts) are not handled. */
 252        if ((intr_status & mmc_tx_irq))
 253                x->mmc_tx_irq_n++;
 254        if (unlikely(intr_status & mmc_rx_irq))
 255                x->mmc_rx_irq_n++;
 256        if (unlikely(intr_status & mmc_rx_csum_offload_irq))
 257                x->mmc_rx_csum_offload_irq_n++;
 258        if (unlikely(intr_status & pmt_irq)) {
 259                /* clear the PMT bits 5 and 6 by reading the PMT status reg */
 260                readl(ioaddr + GMAC_PMT);
 261                x->irq_receive_pmt_irq_n++;
 262        }
 263        /* MAC trx/rx EEE LPI entry/exit interrupts */
 264        if (intr_status & lpiis_irq) {
 265                /* Clean LPI interrupt by reading the Reg 12 */
 266                ret = readl(ioaddr + LPI_CTRL_STATUS);
 267
 268                if (ret & LPI_CTRL_STATUS_TLPIEN)
 269                        x->irq_tx_path_in_lpi_mode_n++;
 270                if (ret & LPI_CTRL_STATUS_TLPIEX)
 271                        x->irq_tx_path_exit_lpi_mode_n++;
 272                if (ret & LPI_CTRL_STATUS_RLPIEN)
 273                        x->irq_rx_path_in_lpi_mode_n++;
 274                if (ret & LPI_CTRL_STATUS_RLPIEX)
 275                        x->irq_rx_path_exit_lpi_mode_n++;
 276        }
 277
 278        if ((intr_status & pcs_ane_irq) || (intr_status & pcs_link_irq)) {
 279                readl(ioaddr + GMAC_AN_STATUS);
 280                x->irq_pcs_ane_n++;
 281        }
 282        if (intr_status & rgmii_irq) {
 283                u32 status = readl(ioaddr + GMAC_S_R_GMII);
 284                x->irq_rgmii_n++;
 285
 286                /* Save and dump the link status. */
 287                if (status & GMAC_S_R_GMII_LINK) {
 288                        int speed_value = (status & GMAC_S_R_GMII_SPEED) >>
 289                            GMAC_S_R_GMII_SPEED_SHIFT;
 290                        x->pcs_duplex = (status & GMAC_S_R_GMII_MODE);
 291
 292                        if (speed_value == GMAC_S_R_GMII_SPEED_125)
 293                                x->pcs_speed = SPEED_1000;
 294                        else if (speed_value == GMAC_S_R_GMII_SPEED_25)
 295                                x->pcs_speed = SPEED_100;
 296                        else
 297                                x->pcs_speed = SPEED_10;
 298
 299                        x->pcs_link = 1;
 300                        pr_debug("%s: Link is Up - %d/%s\n", __func__,
 301                                 (int)x->pcs_speed,
 302                                 x->pcs_duplex ? "Full" : "Half");
 303                } else {
 304                        x->pcs_link = 0;
 305                        pr_debug("%s: Link is Down\n", __func__);
 306                }
 307        }
 308
 309        return ret;
 310}
 311
 312static void dwmac1000_set_eee_mode(struct mac_device_info *hw)
 313{
 314        void __iomem *ioaddr = hw->pcsr;
 315        u32 value;
 316
 317        /* Enable the link status receive on RGMII, SGMII ore SMII
 318         * receive path and instruct the transmit to enter in LPI
 319         * state.
 320         */
 321        value = readl(ioaddr + LPI_CTRL_STATUS);
 322        value |= LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA;
 323        writel(value, ioaddr + LPI_CTRL_STATUS);
 324}
 325
 326static void dwmac1000_reset_eee_mode(struct mac_device_info *hw)
 327{
 328        void __iomem *ioaddr = hw->pcsr;
 329        u32 value;
 330
 331        value = readl(ioaddr + LPI_CTRL_STATUS);
 332        value &= ~(LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA);
 333        writel(value, ioaddr + LPI_CTRL_STATUS);
 334}
 335
 336static void dwmac1000_set_eee_pls(struct mac_device_info *hw, int link)
 337{
 338        void __iomem *ioaddr = hw->pcsr;
 339        u32 value;
 340
 341        value = readl(ioaddr + LPI_CTRL_STATUS);
 342
 343        if (link)
 344                value |= LPI_CTRL_STATUS_PLS;
 345        else
 346                value &= ~LPI_CTRL_STATUS_PLS;
 347
 348        writel(value, ioaddr + LPI_CTRL_STATUS);
 349}
 350
 351static void dwmac1000_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
 352{
 353        void __iomem *ioaddr = hw->pcsr;
 354        int value = ((tw & 0xffff)) | ((ls & 0x7ff) << 16);
 355
 356        /* Program the timers in the LPI timer control register:
 357         * LS: minimum time (ms) for which the link
 358         *  status from PHY should be ok before transmitting
 359         *  the LPI pattern.
 360         * TW: minimum time (us) for which the core waits
 361         *  after it has stopped transmitting the LPI pattern.
 362         */
 363        writel(value, ioaddr + LPI_TIMER_CTRL);
 364}
 365
 366static void dwmac1000_ctrl_ane(struct mac_device_info *hw, bool restart)
 367{
 368        void __iomem *ioaddr = hw->pcsr;
 369        /* auto negotiation enable and External Loopback enable */
 370        u32 value = GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_ELE;
 371
 372        if (restart)
 373                value |= GMAC_AN_CTRL_RAN;
 374
 375        writel(value, ioaddr + GMAC_AN_CTRL);
 376}
 377
 378static void dwmac1000_get_adv(struct mac_device_info *hw, struct rgmii_adv *adv)
 379{
 380        void __iomem *ioaddr = hw->pcsr;
 381        u32 value = readl(ioaddr + GMAC_ANE_ADV);
 382
 383        if (value & GMAC_ANE_FD)
 384                adv->duplex = DUPLEX_FULL;
 385        if (value & GMAC_ANE_HD)
 386                adv->duplex |= DUPLEX_HALF;
 387
 388        adv->pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
 389
 390        value = readl(ioaddr + GMAC_ANE_LPA);
 391
 392        if (value & GMAC_ANE_FD)
 393                adv->lp_duplex = DUPLEX_FULL;
 394        if (value & GMAC_ANE_HD)
 395                adv->lp_duplex = DUPLEX_HALF;
 396
 397        adv->lp_pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
 398}
 399
 400static const struct stmmac_ops dwmac1000_ops = {
 401        .core_init = dwmac1000_core_init,
 402        .rx_ipc = dwmac1000_rx_ipc_enable,
 403        .dump_regs = dwmac1000_dump_regs,
 404        .host_irq_status = dwmac1000_irq_status,
 405        .set_filter = dwmac1000_set_filter,
 406        .flow_ctrl = dwmac1000_flow_ctrl,
 407        .pmt = dwmac1000_pmt,
 408        .set_umac_addr = dwmac1000_set_umac_addr,
 409        .get_umac_addr = dwmac1000_get_umac_addr,
 410        .set_eee_mode = dwmac1000_set_eee_mode,
 411        .reset_eee_mode = dwmac1000_reset_eee_mode,
 412        .set_eee_timer = dwmac1000_set_eee_timer,
 413        .set_eee_pls = dwmac1000_set_eee_pls,
 414        .ctrl_ane = dwmac1000_ctrl_ane,
 415        .get_adv = dwmac1000_get_adv,
 416};
 417
 418struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
 419                                        int perfect_uc_entries)
 420{
 421        struct mac_device_info *mac;
 422        u32 hwid = readl(ioaddr + GMAC_VERSION);
 423
 424        mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
 425        if (!mac)
 426                return NULL;
 427
 428        mac->pcsr = ioaddr;
 429        mac->multicast_filter_bins = mcbins;
 430        mac->unicast_filter_entries = perfect_uc_entries;
 431        mac->mcast_bits_log2 = 0;
 432
 433        if (mac->multicast_filter_bins)
 434                mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
 435
 436        mac->mac = &dwmac1000_ops;
 437        mac->dma = &dwmac1000_dma_ops;
 438
 439        mac->link.port = GMAC_CONTROL_PS;
 440        mac->link.duplex = GMAC_CONTROL_DM;
 441        mac->link.speed = GMAC_CONTROL_FES;
 442        mac->mii.addr = GMAC_MII_ADDR;
 443        mac->mii.data = GMAC_MII_DATA;
 444        mac->synopsys_uid = hwid;
 445
 446        return mac;
 447}
 448