linux/drivers/net/ethernet/freescale/fman/fman_tgec.c
<<
>>
Prefs
   1/*
   2 * Copyright 2008-2015 Freescale Semiconductor Inc.
   3 *
   4 * Redistribution and use in source and binary forms, with or without
   5 * modification, are permitted provided that the following conditions are met:
   6 *     * Redistributions of source code must retain the above copyright
   7 *       notice, this list of conditions and the following disclaimer.
   8 *     * Redistributions in binary form must reproduce the above copyright
   9 *       notice, this list of conditions and the following disclaimer in the
  10 *       documentation and/or other materials provided with the distribution.
  11 *     * Neither the name of Freescale Semiconductor nor the
  12 *       names of its contributors may be used to endorse or promote products
  13 *       derived from this software without specific prior written permission.
  14 *
  15 *
  16 * ALTERNATIVELY, this software may be distributed under the terms of the
  17 * GNU General Public License ("GPL") as published by the Free Software
  18 * Foundation, either version 2 of that License or (at your option) any
  19 * later version.
  20 *
  21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
  22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
  25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31 */
  32
  33#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  34
  35#include "fman_tgec.h"
  36#include "fman.h"
  37
  38#include <linux/slab.h>
  39#include <linux/bitrev.h>
  40#include <linux/io.h>
  41#include <linux/crc32.h>
  42
  43/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
  44#define TGEC_TX_IPG_LENGTH_MASK 0x000003ff
  45
  46/* Command and Configuration Register (COMMAND_CONFIG) */
  47#define CMD_CFG_NO_LEN_CHK              0x00020000
  48#define CMD_CFG_PAUSE_IGNORE            0x00000100
  49#define CMF_CFG_CRC_FWD                 0x00000040
  50#define CMD_CFG_PROMIS_EN               0x00000010
  51#define CMD_CFG_RX_EN                   0x00000002
  52#define CMD_CFG_TX_EN                   0x00000001
  53
  54/* Interrupt Mask Register (IMASK) */
  55#define TGEC_IMASK_MDIO_SCAN_EVENT      0x00010000
  56#define TGEC_IMASK_MDIO_CMD_CMPL        0x00008000
  57#define TGEC_IMASK_REM_FAULT            0x00004000
  58#define TGEC_IMASK_LOC_FAULT            0x00002000
  59#define TGEC_IMASK_TX_ECC_ER            0x00001000
  60#define TGEC_IMASK_TX_FIFO_UNFL 0x00000800
  61#define TGEC_IMASK_TX_FIFO_OVFL 0x00000400
  62#define TGEC_IMASK_TX_ER                0x00000200
  63#define TGEC_IMASK_RX_FIFO_OVFL 0x00000100
  64#define TGEC_IMASK_RX_ECC_ER            0x00000080
  65#define TGEC_IMASK_RX_JAB_FRM           0x00000040
  66#define TGEC_IMASK_RX_OVRSZ_FRM 0x00000020
  67#define TGEC_IMASK_RX_RUNT_FRM          0x00000010
  68#define TGEC_IMASK_RX_FRAG_FRM          0x00000008
  69#define TGEC_IMASK_RX_LEN_ER            0x00000004
  70#define TGEC_IMASK_RX_CRC_ER            0x00000002
  71#define TGEC_IMASK_RX_ALIGN_ER          0x00000001
  72
  73/* Hashtable Control Register (HASHTABLE_CTRL) */
  74#define TGEC_HASH_MCAST_SHIFT           23
  75#define TGEC_HASH_MCAST_EN              0x00000200
  76#define TGEC_HASH_ADR_MSK               0x000001ff
  77
  78#define DEFAULT_TX_IPG_LENGTH                   12
  79#define DEFAULT_MAX_FRAME_LENGTH                0x600
  80#define DEFAULT_PAUSE_QUANT                     0xf000
  81
  82/* number of pattern match registers (entries) */
  83#define TGEC_NUM_OF_PADDRS          1
  84
  85/* Group address bit indication */
  86#define GROUP_ADDRESS               0x0000010000000000LL
  87
  88/* Hash table size (= 32 bits*8 regs) */
  89#define TGEC_HASH_TABLE_SIZE             512
  90
  91/* tGEC memory map */
  92struct tgec_regs {
  93        u32 tgec_id;            /* 0x000 Controller ID */
  94        u32 reserved001[1];     /* 0x004 */
  95        u32 command_config;     /* 0x008 Control and configuration */
  96        u32 mac_addr_0;         /* 0x00c Lower 32 bits of the MAC adr */
  97        u32 mac_addr_1;         /* 0x010 Upper 16 bits of the MAC adr */
  98        u32 maxfrm;             /* 0x014 Maximum frame length */
  99        u32 pause_quant;        /* 0x018 Pause quanta */
 100        u32 rx_fifo_sections;   /* 0x01c  */
 101        u32 tx_fifo_sections;   /* 0x020  */
 102        u32 rx_fifo_almost_f_e; /* 0x024  */
 103        u32 tx_fifo_almost_f_e; /* 0x028  */
 104        u32 hashtable_ctrl;     /* 0x02c Hash table control */
 105        u32 mdio_cfg_status;    /* 0x030  */
 106        u32 mdio_command;       /* 0x034  */
 107        u32 mdio_data;          /* 0x038  */
 108        u32 mdio_regaddr;       /* 0x03c  */
 109        u32 status;             /* 0x040  */
 110        u32 tx_ipg_len;         /* 0x044 Transmitter inter-packet-gap */
 111        u32 mac_addr_2;         /* 0x048 Lower 32 bits of 2nd MAC adr */
 112        u32 mac_addr_3;         /* 0x04c Upper 16 bits of 2nd MAC adr */
 113        u32 rx_fifo_ptr_rd;     /* 0x050  */
 114        u32 rx_fifo_ptr_wr;     /* 0x054  */
 115        u32 tx_fifo_ptr_rd;     /* 0x058  */
 116        u32 tx_fifo_ptr_wr;     /* 0x05c  */
 117        u32 imask;              /* 0x060 Interrupt mask */
 118        u32 ievent;             /* 0x064 Interrupt event */
 119        u32 udp_port;           /* 0x068 Defines a UDP Port number */
 120        u32 type_1588v2;        /* 0x06c Type field for 1588v2 */
 121        u32 reserved070[4];     /* 0x070 */
 122        /* 10Ge Statistics Counter */
 123        u32 tfrm_u;             /* 80 aFramesTransmittedOK */
 124        u32 tfrm_l;             /* 84 aFramesTransmittedOK */
 125        u32 rfrm_u;             /* 88 aFramesReceivedOK */
 126        u32 rfrm_l;             /* 8c aFramesReceivedOK */
 127        u32 rfcs_u;             /* 90 aFrameCheckSequenceErrors */
 128        u32 rfcs_l;             /* 94 aFrameCheckSequenceErrors */
 129        u32 raln_u;             /* 98 aAlignmentErrors */
 130        u32 raln_l;             /* 9c aAlignmentErrors */
 131        u32 txpf_u;             /* A0 aPAUSEMACCtrlFramesTransmitted */
 132        u32 txpf_l;             /* A4 aPAUSEMACCtrlFramesTransmitted */
 133        u32 rxpf_u;             /* A8 aPAUSEMACCtrlFramesReceived */
 134        u32 rxpf_l;             /* Ac aPAUSEMACCtrlFramesReceived */
 135        u32 rlong_u;            /* B0 aFrameTooLongErrors */
 136        u32 rlong_l;            /* B4 aFrameTooLongErrors */
 137        u32 rflr_u;             /* B8 aInRangeLengthErrors */
 138        u32 rflr_l;             /* Bc aInRangeLengthErrors */
 139        u32 tvlan_u;            /* C0 VLANTransmittedOK */
 140        u32 tvlan_l;            /* C4 VLANTransmittedOK */
 141        u32 rvlan_u;            /* C8 VLANReceivedOK */
 142        u32 rvlan_l;            /* Cc VLANReceivedOK */
 143        u32 toct_u;             /* D0 if_out_octets */
 144        u32 toct_l;             /* D4 if_out_octets */
 145        u32 roct_u;             /* D8 if_in_octets */
 146        u32 roct_l;             /* Dc if_in_octets */
 147        u32 ruca_u;             /* E0 if_in_ucast_pkts */
 148        u32 ruca_l;             /* E4 if_in_ucast_pkts */
 149        u32 rmca_u;             /* E8 ifInMulticastPkts */
 150        u32 rmca_l;             /* Ec ifInMulticastPkts */
 151        u32 rbca_u;             /* F0 ifInBroadcastPkts */
 152        u32 rbca_l;             /* F4 ifInBroadcastPkts */
 153        u32 terr_u;             /* F8 if_out_errors */
 154        u32 terr_l;             /* Fc if_out_errors */
 155        u32 reserved100[2];     /* 100-108 */
 156        u32 tuca_u;             /* 108 if_out_ucast_pkts */
 157        u32 tuca_l;             /* 10c if_out_ucast_pkts */
 158        u32 tmca_u;             /* 110 ifOutMulticastPkts */
 159        u32 tmca_l;             /* 114 ifOutMulticastPkts */
 160        u32 tbca_u;             /* 118 ifOutBroadcastPkts */
 161        u32 tbca_l;             /* 11c ifOutBroadcastPkts */
 162        u32 rdrp_u;             /* 120 etherStatsDropEvents */
 163        u32 rdrp_l;             /* 124 etherStatsDropEvents */
 164        u32 reoct_u;            /* 128 etherStatsOctets */
 165        u32 reoct_l;            /* 12c etherStatsOctets */
 166        u32 rpkt_u;             /* 130 etherStatsPkts */
 167        u32 rpkt_l;             /* 134 etherStatsPkts */
 168        u32 trund_u;            /* 138 etherStatsUndersizePkts */
 169        u32 trund_l;            /* 13c etherStatsUndersizePkts */
 170        u32 r64_u;              /* 140 etherStatsPkts64Octets */
 171        u32 r64_l;              /* 144 etherStatsPkts64Octets */
 172        u32 r127_u;             /* 148 etherStatsPkts65to127Octets */
 173        u32 r127_l;             /* 14c etherStatsPkts65to127Octets */
 174        u32 r255_u;             /* 150 etherStatsPkts128to255Octets */
 175        u32 r255_l;             /* 154 etherStatsPkts128to255Octets */
 176        u32 r511_u;             /* 158 etherStatsPkts256to511Octets */
 177        u32 r511_l;             /* 15c etherStatsPkts256to511Octets */
 178        u32 r1023_u;            /* 160 etherStatsPkts512to1023Octets */
 179        u32 r1023_l;            /* 164 etherStatsPkts512to1023Octets */
 180        u32 r1518_u;            /* 168 etherStatsPkts1024to1518Octets */
 181        u32 r1518_l;            /* 16c etherStatsPkts1024to1518Octets */
 182        u32 r1519x_u;           /* 170 etherStatsPkts1519toX */
 183        u32 r1519x_l;           /* 174 etherStatsPkts1519toX */
 184        u32 trovr_u;            /* 178 etherStatsOversizePkts */
 185        u32 trovr_l;            /* 17c etherStatsOversizePkts */
 186        u32 trjbr_u;            /* 180 etherStatsJabbers */
 187        u32 trjbr_l;            /* 184 etherStatsJabbers */
 188        u32 trfrg_u;            /* 188 etherStatsFragments */
 189        u32 trfrg_l;            /* 18C etherStatsFragments */
 190        u32 rerr_u;             /* 190 if_in_errors */
 191        u32 rerr_l;             /* 194 if_in_errors */
 192};
 193
 194struct tgec_cfg {
 195        bool pause_ignore;
 196        bool promiscuous_mode_enable;
 197        u16 max_frame_length;
 198        u16 pause_quant;
 199        u32 tx_ipg_length;
 200};
 201
 202struct fman_mac {
 203        /* Pointer to the memory mapped registers. */
 204        struct tgec_regs __iomem *regs;
 205        /* MAC address of device; */
 206        u64 addr;
 207        u16 max_speed;
 208        void *dev_id; /* device cookie used by the exception cbs */
 209        fman_mac_exception_cb *exception_cb;
 210        fman_mac_exception_cb *event_cb;
 211        /* pointer to driver's global address hash table  */
 212        struct eth_hash_t *multicast_addr_hash;
 213        /* pointer to driver's individual address hash table  */
 214        struct eth_hash_t *unicast_addr_hash;
 215        u8 mac_id;
 216        u32 exceptions;
 217        struct tgec_cfg *cfg;
 218        void *fm;
 219        struct fman_rev_info fm_rev_info;
 220        bool allmulti_enabled;
 221};
 222
 223static void set_mac_address(struct tgec_regs __iomem *regs, u8 *adr)
 224{
 225        u32 tmp0, tmp1;
 226
 227        tmp0 = (u32)(adr[0] | adr[1] << 8 | adr[2] << 16 | adr[3] << 24);
 228        tmp1 = (u32)(adr[4] | adr[5] << 8);
 229        iowrite32be(tmp0, &regs->mac_addr_0);
 230        iowrite32be(tmp1, &regs->mac_addr_1);
 231}
 232
 233static void set_dflts(struct tgec_cfg *cfg)
 234{
 235        cfg->promiscuous_mode_enable = false;
 236        cfg->pause_ignore = false;
 237        cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
 238        cfg->max_frame_length = DEFAULT_MAX_FRAME_LENGTH;
 239        cfg->pause_quant = DEFAULT_PAUSE_QUANT;
 240}
 241
 242static int init(struct tgec_regs __iomem *regs, struct tgec_cfg *cfg,
 243                u32 exception_mask)
 244{
 245        u32 tmp;
 246
 247        /* Config */
 248        tmp = CMF_CFG_CRC_FWD;
 249        if (cfg->promiscuous_mode_enable)
 250                tmp |= CMD_CFG_PROMIS_EN;
 251        if (cfg->pause_ignore)
 252                tmp |= CMD_CFG_PAUSE_IGNORE;
 253        /* Payload length check disable */
 254        tmp |= CMD_CFG_NO_LEN_CHK;
 255        iowrite32be(tmp, &regs->command_config);
 256
 257        /* Max Frame Length */
 258        iowrite32be((u32)cfg->max_frame_length, &regs->maxfrm);
 259        /* Pause Time */
 260        iowrite32be(cfg->pause_quant, &regs->pause_quant);
 261
 262        /* clear all pending events and set-up interrupts */
 263        iowrite32be(0xffffffff, &regs->ievent);
 264        iowrite32be(ioread32be(&regs->imask) | exception_mask, &regs->imask);
 265
 266        return 0;
 267}
 268
 269static int check_init_parameters(struct fman_mac *tgec)
 270{
 271        if (tgec->max_speed < SPEED_10000) {
 272                pr_err("10G MAC driver only support 10G speed\n");
 273                return -EINVAL;
 274        }
 275        if (tgec->addr == 0) {
 276                pr_err("Ethernet 10G MAC Must have valid MAC Address\n");
 277                return -EINVAL;
 278        }
 279        if (!tgec->exception_cb) {
 280                pr_err("uninitialized exception_cb\n");
 281                return -EINVAL;
 282        }
 283        if (!tgec->event_cb) {
 284                pr_err("uninitialized event_cb\n");
 285                return -EINVAL;
 286        }
 287
 288        return 0;
 289}
 290
 291static int get_exception_flag(enum fman_mac_exceptions exception)
 292{
 293        u32 bit_mask;
 294
 295        switch (exception) {
 296        case FM_MAC_EX_10G_MDIO_SCAN_EVENT:
 297                bit_mask = TGEC_IMASK_MDIO_SCAN_EVENT;
 298                break;
 299        case FM_MAC_EX_10G_MDIO_CMD_CMPL:
 300                bit_mask = TGEC_IMASK_MDIO_CMD_CMPL;
 301                break;
 302        case FM_MAC_EX_10G_REM_FAULT:
 303                bit_mask = TGEC_IMASK_REM_FAULT;
 304                break;
 305        case FM_MAC_EX_10G_LOC_FAULT:
 306                bit_mask = TGEC_IMASK_LOC_FAULT;
 307                break;
 308        case FM_MAC_EX_10G_TX_ECC_ER:
 309                bit_mask = TGEC_IMASK_TX_ECC_ER;
 310                break;
 311        case FM_MAC_EX_10G_TX_FIFO_UNFL:
 312                bit_mask = TGEC_IMASK_TX_FIFO_UNFL;
 313                break;
 314        case FM_MAC_EX_10G_TX_FIFO_OVFL:
 315                bit_mask = TGEC_IMASK_TX_FIFO_OVFL;
 316                break;
 317        case FM_MAC_EX_10G_TX_ER:
 318                bit_mask = TGEC_IMASK_TX_ER;
 319                break;
 320        case FM_MAC_EX_10G_RX_FIFO_OVFL:
 321                bit_mask = TGEC_IMASK_RX_FIFO_OVFL;
 322                break;
 323        case FM_MAC_EX_10G_RX_ECC_ER:
 324                bit_mask = TGEC_IMASK_RX_ECC_ER;
 325                break;
 326        case FM_MAC_EX_10G_RX_JAB_FRM:
 327                bit_mask = TGEC_IMASK_RX_JAB_FRM;
 328                break;
 329        case FM_MAC_EX_10G_RX_OVRSZ_FRM:
 330                bit_mask = TGEC_IMASK_RX_OVRSZ_FRM;
 331                break;
 332        case FM_MAC_EX_10G_RX_RUNT_FRM:
 333                bit_mask = TGEC_IMASK_RX_RUNT_FRM;
 334                break;
 335        case FM_MAC_EX_10G_RX_FRAG_FRM:
 336                bit_mask = TGEC_IMASK_RX_FRAG_FRM;
 337                break;
 338        case FM_MAC_EX_10G_RX_LEN_ER:
 339                bit_mask = TGEC_IMASK_RX_LEN_ER;
 340                break;
 341        case FM_MAC_EX_10G_RX_CRC_ER:
 342                bit_mask = TGEC_IMASK_RX_CRC_ER;
 343                break;
 344        case FM_MAC_EX_10G_RX_ALIGN_ER:
 345                bit_mask = TGEC_IMASK_RX_ALIGN_ER;
 346                break;
 347        default:
 348                bit_mask = 0;
 349                break;
 350        }
 351
 352        return bit_mask;
 353}
 354
 355static void tgec_err_exception(void *handle)
 356{
 357        struct fman_mac *tgec = (struct fman_mac *)handle;
 358        struct tgec_regs __iomem *regs = tgec->regs;
 359        u32 event;
 360
 361        /* do not handle MDIO events */
 362        event = ioread32be(&regs->ievent) &
 363                           ~(TGEC_IMASK_MDIO_SCAN_EVENT |
 364                           TGEC_IMASK_MDIO_CMD_CMPL);
 365
 366        event &= ioread32be(&regs->imask);
 367
 368        iowrite32be(event, &regs->ievent);
 369
 370        if (event & TGEC_IMASK_REM_FAULT)
 371                tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_REM_FAULT);
 372        if (event & TGEC_IMASK_LOC_FAULT)
 373                tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_LOC_FAULT);
 374        if (event & TGEC_IMASK_TX_ECC_ER)
 375                tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_TX_ECC_ER);
 376        if (event & TGEC_IMASK_TX_FIFO_UNFL)
 377                tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_TX_FIFO_UNFL);
 378        if (event & TGEC_IMASK_TX_FIFO_OVFL)
 379                tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_TX_FIFO_OVFL);
 380        if (event & TGEC_IMASK_TX_ER)
 381                tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_TX_ER);
 382        if (event & TGEC_IMASK_RX_FIFO_OVFL)
 383                tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_FIFO_OVFL);
 384        if (event & TGEC_IMASK_RX_ECC_ER)
 385                tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_ECC_ER);
 386        if (event & TGEC_IMASK_RX_JAB_FRM)
 387                tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_JAB_FRM);
 388        if (event & TGEC_IMASK_RX_OVRSZ_FRM)
 389                tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_OVRSZ_FRM);
 390        if (event & TGEC_IMASK_RX_RUNT_FRM)
 391                tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_RUNT_FRM);
 392        if (event & TGEC_IMASK_RX_FRAG_FRM)
 393                tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_FRAG_FRM);
 394        if (event & TGEC_IMASK_RX_LEN_ER)
 395                tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_LEN_ER);
 396        if (event & TGEC_IMASK_RX_CRC_ER)
 397                tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_CRC_ER);
 398        if (event & TGEC_IMASK_RX_ALIGN_ER)
 399                tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_ALIGN_ER);
 400}
 401
 402static void free_init_resources(struct fman_mac *tgec)
 403{
 404        fman_unregister_intr(tgec->fm, FMAN_MOD_MAC, tgec->mac_id,
 405                             FMAN_INTR_TYPE_ERR);
 406
 407        /* release the driver's group hash table */
 408        free_hash_table(tgec->multicast_addr_hash);
 409        tgec->multicast_addr_hash = NULL;
 410
 411        /* release the driver's individual hash table */
 412        free_hash_table(tgec->unicast_addr_hash);
 413        tgec->unicast_addr_hash = NULL;
 414}
 415
 416static bool is_init_done(struct tgec_cfg *cfg)
 417{
 418        /* Checks if tGEC driver parameters were initialized */
 419        if (!cfg)
 420                return true;
 421
 422        return false;
 423}
 424
 425int tgec_enable(struct fman_mac *tgec, enum comm_mode mode)
 426{
 427        struct tgec_regs __iomem *regs = tgec->regs;
 428        u32 tmp;
 429
 430        if (!is_init_done(tgec->cfg))
 431                return -EINVAL;
 432
 433        tmp = ioread32be(&regs->command_config);
 434        if (mode & COMM_MODE_RX)
 435                tmp |= CMD_CFG_RX_EN;
 436        if (mode & COMM_MODE_TX)
 437                tmp |= CMD_CFG_TX_EN;
 438        iowrite32be(tmp, &regs->command_config);
 439
 440        return 0;
 441}
 442
 443int tgec_disable(struct fman_mac *tgec, enum comm_mode mode)
 444{
 445        struct tgec_regs __iomem *regs = tgec->regs;
 446        u32 tmp;
 447
 448        if (!is_init_done(tgec->cfg))
 449                return -EINVAL;
 450
 451        tmp = ioread32be(&regs->command_config);
 452        if (mode & COMM_MODE_RX)
 453                tmp &= ~CMD_CFG_RX_EN;
 454        if (mode & COMM_MODE_TX)
 455                tmp &= ~CMD_CFG_TX_EN;
 456        iowrite32be(tmp, &regs->command_config);
 457
 458        return 0;
 459}
 460
 461int tgec_set_promiscuous(struct fman_mac *tgec, bool new_val)
 462{
 463        struct tgec_regs __iomem *regs = tgec->regs;
 464        u32 tmp;
 465
 466        if (!is_init_done(tgec->cfg))
 467                return -EINVAL;
 468
 469        tmp = ioread32be(&regs->command_config);
 470        if (new_val)
 471                tmp |= CMD_CFG_PROMIS_EN;
 472        else
 473                tmp &= ~CMD_CFG_PROMIS_EN;
 474        iowrite32be(tmp, &regs->command_config);
 475
 476        return 0;
 477}
 478
 479int tgec_cfg_max_frame_len(struct fman_mac *tgec, u16 new_val)
 480{
 481        if (is_init_done(tgec->cfg))
 482                return -EINVAL;
 483
 484        tgec->cfg->max_frame_length = new_val;
 485
 486        return 0;
 487}
 488
 489int tgec_set_tx_pause_frames(struct fman_mac *tgec, u8 __maybe_unused priority,
 490                             u16 pause_time, u16 __maybe_unused thresh_time)
 491{
 492        struct tgec_regs __iomem *regs = tgec->regs;
 493
 494        if (!is_init_done(tgec->cfg))
 495                return -EINVAL;
 496
 497        iowrite32be((u32)pause_time, &regs->pause_quant);
 498
 499        return 0;
 500}
 501
 502int tgec_accept_rx_pause_frames(struct fman_mac *tgec, bool en)
 503{
 504        struct tgec_regs __iomem *regs = tgec->regs;
 505        u32 tmp;
 506
 507        if (!is_init_done(tgec->cfg))
 508                return -EINVAL;
 509
 510        tmp = ioread32be(&regs->command_config);
 511        if (!en)
 512                tmp |= CMD_CFG_PAUSE_IGNORE;
 513        else
 514                tmp &= ~CMD_CFG_PAUSE_IGNORE;
 515        iowrite32be(tmp, &regs->command_config);
 516
 517        return 0;
 518}
 519
 520int tgec_modify_mac_address(struct fman_mac *tgec, enet_addr_t *p_enet_addr)
 521{
 522        if (!is_init_done(tgec->cfg))
 523                return -EINVAL;
 524
 525        tgec->addr = ENET_ADDR_TO_UINT64(*p_enet_addr);
 526        set_mac_address(tgec->regs, (u8 *)(*p_enet_addr));
 527
 528        return 0;
 529}
 530
 531int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
 532{
 533        struct tgec_regs __iomem *regs = tgec->regs;
 534        struct eth_hash_entry *hash_entry;
 535        u32 crc = 0xFFFFFFFF, hash;
 536        u64 addr;
 537
 538        if (!is_init_done(tgec->cfg))
 539                return -EINVAL;
 540
 541        addr = ENET_ADDR_TO_UINT64(*eth_addr);
 542
 543        if (!(addr & GROUP_ADDRESS)) {
 544                /* Unicast addresses not supported in hash */
 545                pr_err("Unicast Address\n");
 546                return -EINVAL;
 547        }
 548        /* CRC calculation */
 549        crc = crc32_le(crc, (u8 *)eth_addr, ETH_ALEN);
 550        crc = bitrev32(crc);
 551        /* Take 9 MSB bits */
 552        hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK;
 553
 554        /* Create element to be added to the driver hash table */
 555        hash_entry = kmalloc(sizeof(*hash_entry), GFP_KERNEL);
 556        if (!hash_entry)
 557                return -ENOMEM;
 558        hash_entry->addr = addr;
 559        INIT_LIST_HEAD(&hash_entry->node);
 560
 561        list_add_tail(&hash_entry->node,
 562                      &tgec->multicast_addr_hash->lsts[hash]);
 563        iowrite32be((hash | TGEC_HASH_MCAST_EN), &regs->hashtable_ctrl);
 564
 565        return 0;
 566}
 567
 568int tgec_set_allmulti(struct fman_mac *tgec, bool enable)
 569{
 570        u32 entry;
 571        struct tgec_regs __iomem *regs = tgec->regs;
 572
 573        if (!is_init_done(tgec->cfg))
 574                return -EINVAL;
 575
 576        if (enable) {
 577                for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++)
 578                        iowrite32be(entry | TGEC_HASH_MCAST_EN,
 579                                    &regs->hashtable_ctrl);
 580        } else {
 581                for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++)
 582                        iowrite32be(entry & ~TGEC_HASH_MCAST_EN,
 583                                    &regs->hashtable_ctrl);
 584        }
 585
 586        tgec->allmulti_enabled = enable;
 587
 588        return 0;
 589}
 590
 591int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
 592{
 593        struct tgec_regs __iomem *regs = tgec->regs;
 594        struct eth_hash_entry *hash_entry = NULL;
 595        struct list_head *pos;
 596        u32 crc = 0xFFFFFFFF, hash;
 597        u64 addr;
 598
 599        if (!is_init_done(tgec->cfg))
 600                return -EINVAL;
 601
 602        addr = ((*(u64 *)eth_addr) >> 16);
 603
 604        /* CRC calculation */
 605        crc = crc32_le(crc, (u8 *)eth_addr, ETH_ALEN);
 606        crc = bitrev32(crc);
 607        /* Take 9 MSB bits */
 608        hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK;
 609
 610        list_for_each(pos, &tgec->multicast_addr_hash->lsts[hash]) {
 611                hash_entry = ETH_HASH_ENTRY_OBJ(pos);
 612                if (hash_entry->addr == addr) {
 613                        list_del_init(&hash_entry->node);
 614                        kfree(hash_entry);
 615                        break;
 616                }
 617        }
 618
 619        if (!tgec->allmulti_enabled) {
 620                if (list_empty(&tgec->multicast_addr_hash->lsts[hash]))
 621                        iowrite32be((hash & ~TGEC_HASH_MCAST_EN),
 622                                    &regs->hashtable_ctrl);
 623        }
 624
 625        return 0;
 626}
 627
 628int tgec_get_version(struct fman_mac *tgec, u32 *mac_version)
 629{
 630        struct tgec_regs __iomem *regs = tgec->regs;
 631
 632        if (!is_init_done(tgec->cfg))
 633                return -EINVAL;
 634
 635        *mac_version = ioread32be(&regs->tgec_id);
 636
 637        return 0;
 638}
 639
 640int tgec_set_exception(struct fman_mac *tgec,
 641                       enum fman_mac_exceptions exception, bool enable)
 642{
 643        struct tgec_regs __iomem *regs = tgec->regs;
 644        u32 bit_mask = 0;
 645
 646        if (!is_init_done(tgec->cfg))
 647                return -EINVAL;
 648
 649        bit_mask = get_exception_flag(exception);
 650        if (bit_mask) {
 651                if (enable)
 652                        tgec->exceptions |= bit_mask;
 653                else
 654                        tgec->exceptions &= ~bit_mask;
 655        } else {
 656                pr_err("Undefined exception\n");
 657                return -EINVAL;
 658        }
 659        if (enable)
 660                iowrite32be(ioread32be(&regs->imask) | bit_mask, &regs->imask);
 661        else
 662                iowrite32be(ioread32be(&regs->imask) & ~bit_mask, &regs->imask);
 663
 664        return 0;
 665}
 666
 667int tgec_init(struct fman_mac *tgec)
 668{
 669        struct tgec_cfg *cfg;
 670        enet_addr_t eth_addr;
 671        int err;
 672
 673        if (is_init_done(tgec->cfg))
 674                return -EINVAL;
 675
 676        if (DEFAULT_RESET_ON_INIT &&
 677            (fman_reset_mac(tgec->fm, tgec->mac_id) != 0)) {
 678                pr_err("Can't reset MAC!\n");
 679                return -EINVAL;
 680        }
 681
 682        err = check_init_parameters(tgec);
 683        if (err)
 684                return err;
 685
 686        cfg = tgec->cfg;
 687
 688        MAKE_ENET_ADDR_FROM_UINT64(tgec->addr, eth_addr);
 689        set_mac_address(tgec->regs, (u8 *)eth_addr);
 690
 691        /* interrupts */
 692        /* FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 Errata workaround */
 693        if (tgec->fm_rev_info.major <= 2)
 694                tgec->exceptions &= ~(TGEC_IMASK_REM_FAULT |
 695                                      TGEC_IMASK_LOC_FAULT);
 696
 697        err = init(tgec->regs, cfg, tgec->exceptions);
 698        if (err) {
 699                free_init_resources(tgec);
 700                pr_err("TGEC version doesn't support this i/f mode\n");
 701                return err;
 702        }
 703
 704        /* Max Frame Length */
 705        err = fman_set_mac_max_frame(tgec->fm, tgec->mac_id,
 706                                     cfg->max_frame_length);
 707        if (err) {
 708                pr_err("Setting max frame length FAILED\n");
 709                free_init_resources(tgec);
 710                return -EINVAL;
 711        }
 712
 713        /* FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 Errata workaround */
 714        if (tgec->fm_rev_info.major == 2) {
 715                struct tgec_regs __iomem *regs = tgec->regs;
 716                u32 tmp;
 717
 718                /* restore the default tx ipg Length */
 719                tmp = (ioread32be(&regs->tx_ipg_len) &
 720                       ~TGEC_TX_IPG_LENGTH_MASK) | 12;
 721
 722                iowrite32be(tmp, &regs->tx_ipg_len);
 723        }
 724
 725        tgec->multicast_addr_hash = alloc_hash_table(TGEC_HASH_TABLE_SIZE);
 726        if (!tgec->multicast_addr_hash) {
 727                free_init_resources(tgec);
 728                pr_err("allocation hash table is FAILED\n");
 729                return -ENOMEM;
 730        }
 731
 732        tgec->unicast_addr_hash = alloc_hash_table(TGEC_HASH_TABLE_SIZE);
 733        if (!tgec->unicast_addr_hash) {
 734                free_init_resources(tgec);
 735                pr_err("allocation hash table is FAILED\n");
 736                return -ENOMEM;
 737        }
 738
 739        fman_register_intr(tgec->fm, FMAN_MOD_MAC, tgec->mac_id,
 740                           FMAN_INTR_TYPE_ERR, tgec_err_exception, tgec);
 741
 742        kfree(cfg);
 743        tgec->cfg = NULL;
 744
 745        return 0;
 746}
 747
 748int tgec_free(struct fman_mac *tgec)
 749{
 750        free_init_resources(tgec);
 751
 752        kfree(tgec->cfg);
 753        kfree(tgec);
 754
 755        return 0;
 756}
 757
 758struct fman_mac *tgec_config(struct fman_mac_params *params)
 759{
 760        struct fman_mac *tgec;
 761        struct tgec_cfg *cfg;
 762        void __iomem *base_addr;
 763
 764        base_addr = params->base_addr;
 765        /* allocate memory for the UCC GETH data structure. */
 766        tgec = kzalloc(sizeof(*tgec), GFP_KERNEL);
 767        if (!tgec)
 768                return NULL;
 769
 770        /* allocate memory for the 10G MAC driver parameters data structure. */
 771        cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
 772        if (!cfg) {
 773                tgec_free(tgec);
 774                return NULL;
 775        }
 776
 777        /* Plant parameter structure pointer */
 778        tgec->cfg = cfg;
 779
 780        set_dflts(cfg);
 781
 782        tgec->regs = base_addr;
 783        tgec->addr = ENET_ADDR_TO_UINT64(params->addr);
 784        tgec->max_speed = params->max_speed;
 785        tgec->mac_id = params->mac_id;
 786        tgec->exceptions = (TGEC_IMASK_MDIO_SCAN_EVENT  |
 787                            TGEC_IMASK_REM_FAULT        |
 788                            TGEC_IMASK_LOC_FAULT        |
 789                            TGEC_IMASK_TX_ECC_ER        |
 790                            TGEC_IMASK_TX_FIFO_UNFL     |
 791                            TGEC_IMASK_TX_FIFO_OVFL     |
 792                            TGEC_IMASK_TX_ER            |
 793                            TGEC_IMASK_RX_FIFO_OVFL     |
 794                            TGEC_IMASK_RX_ECC_ER        |
 795                            TGEC_IMASK_RX_JAB_FRM       |
 796                            TGEC_IMASK_RX_OVRSZ_FRM     |
 797                            TGEC_IMASK_RX_RUNT_FRM      |
 798                            TGEC_IMASK_RX_FRAG_FRM      |
 799                            TGEC_IMASK_RX_CRC_ER        |
 800                            TGEC_IMASK_RX_ALIGN_ER);
 801        tgec->exception_cb = params->exception_cb;
 802        tgec->event_cb = params->event_cb;
 803        tgec->dev_id = params->dev_id;
 804        tgec->fm = params->fm;
 805
 806        /* Save FMan revision */
 807        fman_get_revision(tgec->fm, &tgec->fm_rev_info);
 808
 809        return tgec;
 810}
 811