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 /* FM MAC ... */ 34 #ifndef __FM_MAC_H 35 #define __FM_MAC_H 36 37 #include "fman.h" 38 39 #include <linux/slab.h> 40 #include <linux/phy.h> 41 #include <linux/if_ether.h> 42 43 struct fman_mac; 44 struct mac_device; 45 46 /* Ethernet Address */ 47 typedef u8 enet_addr_t[ETH_ALEN]; 48 49 #define ENET_ADDR_TO_UINT64(_enet_addr) \ 50 (u64)(((u64)(_enet_addr)[0] << 40) | \ 51 ((u64)(_enet_addr)[1] << 32) | \ 52 ((u64)(_enet_addr)[2] << 24) | \ 53 ((u64)(_enet_addr)[3] << 16) | \ 54 ((u64)(_enet_addr)[4] << 8) | \ 55 ((u64)(_enet_addr)[5])) 56 57 #define MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enet_addr) \ 58 do { \ 59 int i; \ 60 for (i = 0; i < ETH_ALEN; i++) \ 61 (_enet_addr)[i] = \ 62 (u8)((_addr64) >> ((5 - i) * 8)); \ 63 } while (0) 64 65 /* defaults */ 66 #define DEFAULT_RESET_ON_INIT false 67 68 /* PFC defines */ 69 #define FSL_FM_PAUSE_TIME_ENABLE 0xf000 70 #define FSL_FM_PAUSE_TIME_DISABLE 0 71 #define FSL_FM_PAUSE_THRESH_DEFAULT 0 72 73 #define FM_MAC_NO_PFC 0xff 74 75 /* HASH defines */ 76 #define ETH_HASH_ENTRY_OBJ(ptr) \ 77 hlist_entry_safe(ptr, struct eth_hash_entry, node) 78 79 /* FM MAC Exceptions */ 80 enum fman_mac_exceptions { 81 FM_MAC_EX_10G_MDIO_SCAN_EVENT = 0 82 /* 10GEC MDIO scan event interrupt */ 83 , FM_MAC_EX_10G_MDIO_CMD_CMPL 84 /* 10GEC MDIO command completion interrupt */ 85 , FM_MAC_EX_10G_REM_FAULT 86 /* 10GEC, mEMAC Remote fault interrupt */ 87 , FM_MAC_EX_10G_LOC_FAULT 88 /* 10GEC, mEMAC Local fault interrupt */ 89 , FM_MAC_EX_10G_TX_ECC_ER 90 /* 10GEC, mEMAC Transmit frame ECC error interrupt */ 91 , FM_MAC_EX_10G_TX_FIFO_UNFL 92 /* 10GEC, mEMAC Transmit FIFO underflow interrupt */ 93 , FM_MAC_EX_10G_TX_FIFO_OVFL 94 /* 10GEC, mEMAC Transmit FIFO overflow interrupt */ 95 , FM_MAC_EX_10G_TX_ER 96 /* 10GEC Transmit frame error interrupt */ 97 , FM_MAC_EX_10G_RX_FIFO_OVFL 98 /* 10GEC, mEMAC Receive FIFO overflow interrupt */ 99 , FM_MAC_EX_10G_RX_ECC_ER 100 /* 10GEC, mEMAC Receive frame ECC error interrupt */ 101 , FM_MAC_EX_10G_RX_JAB_FRM 102 /* 10GEC Receive jabber frame interrupt */ 103 , FM_MAC_EX_10G_RX_OVRSZ_FRM 104 /* 10GEC Receive oversized frame interrupt */ 105 , FM_MAC_EX_10G_RX_RUNT_FRM 106 /* 10GEC Receive runt frame interrupt */ 107 , FM_MAC_EX_10G_RX_FRAG_FRM 108 /* 10GEC Receive fragment frame interrupt */ 109 , FM_MAC_EX_10G_RX_LEN_ER 110 /* 10GEC Receive payload length error interrupt */ 111 , FM_MAC_EX_10G_RX_CRC_ER 112 /* 10GEC Receive CRC error interrupt */ 113 , FM_MAC_EX_10G_RX_ALIGN_ER 114 /* 10GEC Receive alignment error interrupt */ 115 , FM_MAC_EX_1G_BAB_RX 116 /* dTSEC Babbling receive error */ 117 , FM_MAC_EX_1G_RX_CTL 118 /* dTSEC Receive control (pause frame) interrupt */ 119 , FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET 120 /* dTSEC Graceful transmit stop complete */ 121 , FM_MAC_EX_1G_BAB_TX 122 /* dTSEC Babbling transmit error */ 123 , FM_MAC_EX_1G_TX_CTL 124 /* dTSEC Transmit control (pause frame) interrupt */ 125 , FM_MAC_EX_1G_TX_ERR 126 /* dTSEC Transmit error */ 127 , FM_MAC_EX_1G_LATE_COL 128 /* dTSEC Late collision */ 129 , FM_MAC_EX_1G_COL_RET_LMT 130 /* dTSEC Collision retry limit */ 131 , FM_MAC_EX_1G_TX_FIFO_UNDRN 132 /* dTSEC Transmit FIFO underrun */ 133 , FM_MAC_EX_1G_MAG_PCKT 134 /* dTSEC Magic Packet detection */ 135 , FM_MAC_EX_1G_MII_MNG_RD_COMPLET 136 /* dTSEC MII management read completion */ 137 , FM_MAC_EX_1G_MII_MNG_WR_COMPLET 138 /* dTSEC MII management write completion */ 139 , FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET 140 /* dTSEC Graceful receive stop complete */ 141 , FM_MAC_EX_1G_DATA_ERR 142 /* dTSEC Internal data error on transmit */ 143 , FM_MAC_1G_RX_DATA_ERR 144 /* dTSEC Internal data error on receive */ 145 , FM_MAC_EX_1G_1588_TS_RX_ERR 146 /* dTSEC Time-Stamp Receive Error */ 147 , FM_MAC_EX_1G_RX_MIB_CNT_OVFL 148 /* dTSEC MIB counter overflow */ 149 , FM_MAC_EX_TS_FIFO_ECC_ERR 150 /* mEMAC Time-stamp FIFO ECC error interrupt; 151 * not supported on T4240/B4860 rev1 chips 152 */ 153 , FM_MAC_EX_MAGIC_PACKET_INDICATION = FM_MAC_EX_1G_MAG_PCKT 154 /* mEMAC Magic Packet Indication Interrupt */ 155 }; 156 157 struct eth_hash_entry { 158 u64 addr; /* Ethernet Address */ 159 struct list_head node; 160 }; 161 162 typedef void (fman_mac_exception_cb)(struct mac_device *dev_id, 163 enum fman_mac_exceptions exceptions); 164 165 /* FMan MAC config input */ 166 struct fman_mac_params { 167 /* MAC ID; numbering of dTSEC and 1G-mEMAC: 168 * 0 - FM_MAX_NUM_OF_1G_MACS; 169 * numbering of 10G-MAC (TGEC) and 10G-mEMAC: 170 * 0 - FM_MAX_NUM_OF_10G_MACS 171 */ 172 u8 mac_id; 173 /* Note that the speed should indicate the maximum rate that 174 * this MAC should support rather than the actual speed; 175 */ 176 u16 max_speed; 177 /* A handle to the FM object this port related to */ 178 void *fm; 179 fman_mac_exception_cb *event_cb; /* MDIO Events Callback Routine */ 180 fman_mac_exception_cb *exception_cb;/* Exception Callback Routine */ 181 /* SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC 182 * and phy or backplane; Note: 1000BaseX auto-negotiation relates only 183 * to interface between MAC and phy/backplane, SGMII phy can still 184 * synchronize with far-end phy at 10Mbps, 100Mbps or 1000Mbps 185 */ 186 bool basex_if; 187 }; 188 189 struct eth_hash_t { 190 u16 size; 191 struct list_head *lsts; 192 }; 193 194 static inline struct eth_hash_entry 195 *dequeue_addr_from_hash_entry(struct list_head *addr_lst) 196 { 197 struct eth_hash_entry *hash_entry = NULL; 198 199 if (!list_empty(addr_lst)) { 200 hash_entry = ETH_HASH_ENTRY_OBJ(addr_lst->next); 201 list_del_init(&hash_entry->node); 202 } 203 return hash_entry; 204 } 205 206 static inline void free_hash_table(struct eth_hash_t *hash) 207 { 208 struct eth_hash_entry *hash_entry; 209 int i = 0; 210 211 if (hash) { 212 if (hash->lsts) { 213 for (i = 0; i < hash->size; i++) { 214 hash_entry = 215 dequeue_addr_from_hash_entry(&hash->lsts[i]); 216 while (hash_entry) { 217 kfree(hash_entry); 218 hash_entry = 219 dequeue_addr_from_hash_entry(&hash-> 220 lsts[i]); 221 } 222 } 223 224 kfree(hash->lsts); 225 } 226 227 kfree(hash); 228 } 229 } 230 231 static inline struct eth_hash_t *alloc_hash_table(u16 size) 232 { 233 u32 i; 234 struct eth_hash_t *hash; 235 236 /* Allocate address hash table */ 237 hash = kmalloc(sizeof(*hash), GFP_KERNEL); 238 if (!hash) 239 return NULL; 240 241 hash->size = size; 242 243 hash->lsts = kmalloc_array(hash->size, sizeof(struct list_head), 244 GFP_KERNEL); 245 if (!hash->lsts) { 246 kfree(hash); 247 return NULL; 248 } 249 250 for (i = 0; i < hash->size; i++) 251 INIT_LIST_HEAD(&hash->lsts[i]); 252 253 return hash; 254 } 255 256 #endif /* __FM_MAC_H */ 257