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