18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright 2008-2015 Freescale Semiconductor Inc. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 58c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions are met: 68c2ecf20Sopenharmony_ci * * Redistributions of source code must retain the above copyright 78c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 88c2ecf20Sopenharmony_ci * * Redistributions in binary form must reproduce the above copyright 98c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer in the 108c2ecf20Sopenharmony_ci * documentation and/or other materials provided with the distribution. 118c2ecf20Sopenharmony_ci * * Neither the name of Freescale Semiconductor nor the 128c2ecf20Sopenharmony_ci * names of its contributors may be used to endorse or promote products 138c2ecf20Sopenharmony_ci * derived from this software without specific prior written permission. 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * ALTERNATIVELY, this software may be distributed under the terms of the 178c2ecf20Sopenharmony_ci * GNU General Public License ("GPL") as published by the Free Software 188c2ecf20Sopenharmony_ci * Foundation, either version 2 of that License or (at your option) any 198c2ecf20Sopenharmony_ci * later version. 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 228c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 238c2ecf20Sopenharmony_ci * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 248c2ecf20Sopenharmony_ci * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 258c2ecf20Sopenharmony_ci * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 268c2ecf20Sopenharmony_ci * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 278c2ecf20Sopenharmony_ci * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 288c2ecf20Sopenharmony_ci * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 298c2ecf20Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 308c2ecf20Sopenharmony_ci * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 318c2ecf20Sopenharmony_ci */ 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci/* FM MAC ... */ 348c2ecf20Sopenharmony_ci#ifndef __FM_MAC_H 358c2ecf20Sopenharmony_ci#define __FM_MAC_H 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#include "fman.h" 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#include <linux/slab.h> 408c2ecf20Sopenharmony_ci#include <linux/phy.h> 418c2ecf20Sopenharmony_ci#include <linux/if_ether.h> 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistruct fman_mac; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci/* Ethernet Address */ 468c2ecf20Sopenharmony_citypedef u8 enet_addr_t[ETH_ALEN]; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci#define ENET_ADDR_TO_UINT64(_enet_addr) \ 498c2ecf20Sopenharmony_ci (u64)(((u64)(_enet_addr)[0] << 40) | \ 508c2ecf20Sopenharmony_ci ((u64)(_enet_addr)[1] << 32) | \ 518c2ecf20Sopenharmony_ci ((u64)(_enet_addr)[2] << 24) | \ 528c2ecf20Sopenharmony_ci ((u64)(_enet_addr)[3] << 16) | \ 538c2ecf20Sopenharmony_ci ((u64)(_enet_addr)[4] << 8) | \ 548c2ecf20Sopenharmony_ci ((u64)(_enet_addr)[5])) 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci#define MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enet_addr) \ 578c2ecf20Sopenharmony_ci do { \ 588c2ecf20Sopenharmony_ci int i; \ 598c2ecf20Sopenharmony_ci for (i = 0; i < ETH_ALEN; i++) \ 608c2ecf20Sopenharmony_ci (_enet_addr)[i] = \ 618c2ecf20Sopenharmony_ci (u8)((_addr64) >> ((5 - i) * 8)); \ 628c2ecf20Sopenharmony_ci } while (0) 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci/* defaults */ 658c2ecf20Sopenharmony_ci#define DEFAULT_RESET_ON_INIT false 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci/* PFC defines */ 688c2ecf20Sopenharmony_ci#define FSL_FM_PAUSE_TIME_ENABLE 0xf000 698c2ecf20Sopenharmony_ci#define FSL_FM_PAUSE_TIME_DISABLE 0 708c2ecf20Sopenharmony_ci#define FSL_FM_PAUSE_THRESH_DEFAULT 0 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci#define FM_MAC_NO_PFC 0xff 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci/* HASH defines */ 758c2ecf20Sopenharmony_ci#define ETH_HASH_ENTRY_OBJ(ptr) \ 768c2ecf20Sopenharmony_ci hlist_entry_safe(ptr, struct eth_hash_entry, node) 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci/* Enumeration (bit flags) of communication modes (Transmit, 798c2ecf20Sopenharmony_ci * receive or both). 808c2ecf20Sopenharmony_ci */ 818c2ecf20Sopenharmony_cienum comm_mode { 828c2ecf20Sopenharmony_ci COMM_MODE_NONE = 0, /* No transmit/receive communication */ 838c2ecf20Sopenharmony_ci COMM_MODE_RX = 1, /* Only receive communication */ 848c2ecf20Sopenharmony_ci COMM_MODE_TX = 2, /* Only transmit communication */ 858c2ecf20Sopenharmony_ci COMM_MODE_RX_AND_TX = 3 /* Both transmit and receive communication */ 868c2ecf20Sopenharmony_ci}; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci/* FM MAC Exceptions */ 898c2ecf20Sopenharmony_cienum fman_mac_exceptions { 908c2ecf20Sopenharmony_ci FM_MAC_EX_10G_MDIO_SCAN_EVENT = 0 918c2ecf20Sopenharmony_ci /* 10GEC MDIO scan event interrupt */ 928c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_MDIO_CMD_CMPL 938c2ecf20Sopenharmony_ci /* 10GEC MDIO command completion interrupt */ 948c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_REM_FAULT 958c2ecf20Sopenharmony_ci /* 10GEC, mEMAC Remote fault interrupt */ 968c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_LOC_FAULT 978c2ecf20Sopenharmony_ci /* 10GEC, mEMAC Local fault interrupt */ 988c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_TX_ECC_ER 998c2ecf20Sopenharmony_ci /* 10GEC, mEMAC Transmit frame ECC error interrupt */ 1008c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_TX_FIFO_UNFL 1018c2ecf20Sopenharmony_ci /* 10GEC, mEMAC Transmit FIFO underflow interrupt */ 1028c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_TX_FIFO_OVFL 1038c2ecf20Sopenharmony_ci /* 10GEC, mEMAC Transmit FIFO overflow interrupt */ 1048c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_TX_ER 1058c2ecf20Sopenharmony_ci /* 10GEC Transmit frame error interrupt */ 1068c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_RX_FIFO_OVFL 1078c2ecf20Sopenharmony_ci /* 10GEC, mEMAC Receive FIFO overflow interrupt */ 1088c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_RX_ECC_ER 1098c2ecf20Sopenharmony_ci /* 10GEC, mEMAC Receive frame ECC error interrupt */ 1108c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_RX_JAB_FRM 1118c2ecf20Sopenharmony_ci /* 10GEC Receive jabber frame interrupt */ 1128c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_RX_OVRSZ_FRM 1138c2ecf20Sopenharmony_ci /* 10GEC Receive oversized frame interrupt */ 1148c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_RX_RUNT_FRM 1158c2ecf20Sopenharmony_ci /* 10GEC Receive runt frame interrupt */ 1168c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_RX_FRAG_FRM 1178c2ecf20Sopenharmony_ci /* 10GEC Receive fragment frame interrupt */ 1188c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_RX_LEN_ER 1198c2ecf20Sopenharmony_ci /* 10GEC Receive payload length error interrupt */ 1208c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_RX_CRC_ER 1218c2ecf20Sopenharmony_ci /* 10GEC Receive CRC error interrupt */ 1228c2ecf20Sopenharmony_ci , FM_MAC_EX_10G_RX_ALIGN_ER 1238c2ecf20Sopenharmony_ci /* 10GEC Receive alignment error interrupt */ 1248c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_BAB_RX 1258c2ecf20Sopenharmony_ci /* dTSEC Babbling receive error */ 1268c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_RX_CTL 1278c2ecf20Sopenharmony_ci /* dTSEC Receive control (pause frame) interrupt */ 1288c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET 1298c2ecf20Sopenharmony_ci /* dTSEC Graceful transmit stop complete */ 1308c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_BAB_TX 1318c2ecf20Sopenharmony_ci /* dTSEC Babbling transmit error */ 1328c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_TX_CTL 1338c2ecf20Sopenharmony_ci /* dTSEC Transmit control (pause frame) interrupt */ 1348c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_TX_ERR 1358c2ecf20Sopenharmony_ci /* dTSEC Transmit error */ 1368c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_LATE_COL 1378c2ecf20Sopenharmony_ci /* dTSEC Late collision */ 1388c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_COL_RET_LMT 1398c2ecf20Sopenharmony_ci /* dTSEC Collision retry limit */ 1408c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_TX_FIFO_UNDRN 1418c2ecf20Sopenharmony_ci /* dTSEC Transmit FIFO underrun */ 1428c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_MAG_PCKT 1438c2ecf20Sopenharmony_ci /* dTSEC Magic Packet detection */ 1448c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_MII_MNG_RD_COMPLET 1458c2ecf20Sopenharmony_ci /* dTSEC MII management read completion */ 1468c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_MII_MNG_WR_COMPLET 1478c2ecf20Sopenharmony_ci /* dTSEC MII management write completion */ 1488c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET 1498c2ecf20Sopenharmony_ci /* dTSEC Graceful receive stop complete */ 1508c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_DATA_ERR 1518c2ecf20Sopenharmony_ci /* dTSEC Internal data error on transmit */ 1528c2ecf20Sopenharmony_ci , FM_MAC_1G_RX_DATA_ERR 1538c2ecf20Sopenharmony_ci /* dTSEC Internal data error on receive */ 1548c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_1588_TS_RX_ERR 1558c2ecf20Sopenharmony_ci /* dTSEC Time-Stamp Receive Error */ 1568c2ecf20Sopenharmony_ci , FM_MAC_EX_1G_RX_MIB_CNT_OVFL 1578c2ecf20Sopenharmony_ci /* dTSEC MIB counter overflow */ 1588c2ecf20Sopenharmony_ci , FM_MAC_EX_TS_FIFO_ECC_ERR 1598c2ecf20Sopenharmony_ci /* mEMAC Time-stamp FIFO ECC error interrupt; 1608c2ecf20Sopenharmony_ci * not supported on T4240/B4860 rev1 chips 1618c2ecf20Sopenharmony_ci */ 1628c2ecf20Sopenharmony_ci , FM_MAC_EX_MAGIC_PACKET_INDICATION = FM_MAC_EX_1G_MAG_PCKT 1638c2ecf20Sopenharmony_ci /* mEMAC Magic Packet Indication Interrupt */ 1648c2ecf20Sopenharmony_ci}; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_cistruct eth_hash_entry { 1678c2ecf20Sopenharmony_ci u64 addr; /* Ethernet Address */ 1688c2ecf20Sopenharmony_ci struct list_head node; 1698c2ecf20Sopenharmony_ci}; 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_citypedef void (fman_mac_exception_cb)(void *dev_id, 1728c2ecf20Sopenharmony_ci enum fman_mac_exceptions exceptions); 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci/* FMan MAC config input */ 1758c2ecf20Sopenharmony_cistruct fman_mac_params { 1768c2ecf20Sopenharmony_ci /* Base of memory mapped FM MAC registers */ 1778c2ecf20Sopenharmony_ci void __iomem *base_addr; 1788c2ecf20Sopenharmony_ci /* MAC address of device; First octet is sent first */ 1798c2ecf20Sopenharmony_ci enet_addr_t addr; 1808c2ecf20Sopenharmony_ci /* MAC ID; numbering of dTSEC and 1G-mEMAC: 1818c2ecf20Sopenharmony_ci * 0 - FM_MAX_NUM_OF_1G_MACS; 1828c2ecf20Sopenharmony_ci * numbering of 10G-MAC (TGEC) and 10G-mEMAC: 1838c2ecf20Sopenharmony_ci * 0 - FM_MAX_NUM_OF_10G_MACS 1848c2ecf20Sopenharmony_ci */ 1858c2ecf20Sopenharmony_ci u8 mac_id; 1868c2ecf20Sopenharmony_ci /* PHY interface */ 1878c2ecf20Sopenharmony_ci phy_interface_t phy_if; 1888c2ecf20Sopenharmony_ci /* Note that the speed should indicate the maximum rate that 1898c2ecf20Sopenharmony_ci * this MAC should support rather than the actual speed; 1908c2ecf20Sopenharmony_ci */ 1918c2ecf20Sopenharmony_ci u16 max_speed; 1928c2ecf20Sopenharmony_ci /* A handle to the FM object this port related to */ 1938c2ecf20Sopenharmony_ci void *fm; 1948c2ecf20Sopenharmony_ci void *dev_id; /* device cookie used by the exception cbs */ 1958c2ecf20Sopenharmony_ci fman_mac_exception_cb *event_cb; /* MDIO Events Callback Routine */ 1968c2ecf20Sopenharmony_ci fman_mac_exception_cb *exception_cb;/* Exception Callback Routine */ 1978c2ecf20Sopenharmony_ci /* SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC 1988c2ecf20Sopenharmony_ci * and phy or backplane; Note: 1000BaseX auto-negotiation relates only 1998c2ecf20Sopenharmony_ci * to interface between MAC and phy/backplane, SGMII phy can still 2008c2ecf20Sopenharmony_ci * synchronize with far-end phy at 10Mbps, 100Mbps or 1000Mbps 2018c2ecf20Sopenharmony_ci */ 2028c2ecf20Sopenharmony_ci bool basex_if; 2038c2ecf20Sopenharmony_ci /* Pointer to TBI/PCS PHY node, used for TBI/PCS PHY access */ 2048c2ecf20Sopenharmony_ci struct device_node *internal_phy_node; 2058c2ecf20Sopenharmony_ci}; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_cistruct eth_hash_t { 2088c2ecf20Sopenharmony_ci u16 size; 2098c2ecf20Sopenharmony_ci struct list_head *lsts; 2108c2ecf20Sopenharmony_ci}; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_cistatic inline struct eth_hash_entry 2138c2ecf20Sopenharmony_ci*dequeue_addr_from_hash_entry(struct list_head *addr_lst) 2148c2ecf20Sopenharmony_ci{ 2158c2ecf20Sopenharmony_ci struct eth_hash_entry *hash_entry = NULL; 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci if (!list_empty(addr_lst)) { 2188c2ecf20Sopenharmony_ci hash_entry = ETH_HASH_ENTRY_OBJ(addr_lst->next); 2198c2ecf20Sopenharmony_ci list_del_init(&hash_entry->node); 2208c2ecf20Sopenharmony_ci } 2218c2ecf20Sopenharmony_ci return hash_entry; 2228c2ecf20Sopenharmony_ci} 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_cistatic inline void free_hash_table(struct eth_hash_t *hash) 2258c2ecf20Sopenharmony_ci{ 2268c2ecf20Sopenharmony_ci struct eth_hash_entry *hash_entry; 2278c2ecf20Sopenharmony_ci int i = 0; 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci if (hash) { 2308c2ecf20Sopenharmony_ci if (hash->lsts) { 2318c2ecf20Sopenharmony_ci for (i = 0; i < hash->size; i++) { 2328c2ecf20Sopenharmony_ci hash_entry = 2338c2ecf20Sopenharmony_ci dequeue_addr_from_hash_entry(&hash->lsts[i]); 2348c2ecf20Sopenharmony_ci while (hash_entry) { 2358c2ecf20Sopenharmony_ci kfree(hash_entry); 2368c2ecf20Sopenharmony_ci hash_entry = 2378c2ecf20Sopenharmony_ci dequeue_addr_from_hash_entry(&hash-> 2388c2ecf20Sopenharmony_ci lsts[i]); 2398c2ecf20Sopenharmony_ci } 2408c2ecf20Sopenharmony_ci } 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci kfree(hash->lsts); 2438c2ecf20Sopenharmony_ci } 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci kfree(hash); 2468c2ecf20Sopenharmony_ci } 2478c2ecf20Sopenharmony_ci} 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_cistatic inline struct eth_hash_t *alloc_hash_table(u16 size) 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci u32 i; 2528c2ecf20Sopenharmony_ci struct eth_hash_t *hash; 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci /* Allocate address hash table */ 2558c2ecf20Sopenharmony_ci hash = kmalloc(sizeof(*hash), GFP_KERNEL); 2568c2ecf20Sopenharmony_ci if (!hash) 2578c2ecf20Sopenharmony_ci return NULL; 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci hash->size = size; 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci hash->lsts = kmalloc_array(hash->size, sizeof(struct list_head), 2628c2ecf20Sopenharmony_ci GFP_KERNEL); 2638c2ecf20Sopenharmony_ci if (!hash->lsts) { 2648c2ecf20Sopenharmony_ci kfree(hash); 2658c2ecf20Sopenharmony_ci return NULL; 2668c2ecf20Sopenharmony_ci } 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci for (i = 0; i < hash->size; i++) 2698c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&hash->lsts[i]); 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci return hash; 2728c2ecf20Sopenharmony_ci} 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci#endif /* __FM_MAC_H */ 275