root/drivers/net/ethernet/freescale/fman/fman_tgec.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. set_mac_address
  2. set_dflts
  3. init
  4. check_init_parameters
  5. get_exception_flag
  6. tgec_err_exception
  7. free_init_resources
  8. is_init_done
  9. tgec_enable
  10. tgec_disable
  11. tgec_set_promiscuous
  12. tgec_cfg_max_frame_len
  13. tgec_set_tx_pause_frames
  14. tgec_accept_rx_pause_frames
  15. tgec_modify_mac_address
  16. tgec_add_hash_mac_address
  17. tgec_set_allmulti
  18. tgec_set_tstamp
  19. tgec_del_hash_mac_address
  20. tgec_get_version
  21. tgec_set_exception
  22. tgec_init
  23. tgec_free
  24. tgec_config

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

/* [<][>][^][v][top][bottom][index][help] */