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
43struct fman_mac;
44struct mac_device;
45
46/* Ethernet Address */
47typedef 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 */
80enum 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
157struct eth_hash_entry {
158	u64 addr;		/* Ethernet Address  */
159	struct list_head node;
160};
161
162typedef void (fman_mac_exception_cb)(struct mac_device *dev_id,
163				     enum fman_mac_exceptions exceptions);
164
165/* FMan MAC config input */
166struct 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	/* A handle to the FM object this port related to */
174	void *fm;
175	fman_mac_exception_cb *event_cb;    /* MDIO Events Callback Routine */
176	fman_mac_exception_cb *exception_cb;/* Exception Callback Routine */
177};
178
179struct eth_hash_t {
180	u16 size;
181	struct list_head *lsts;
182};
183
184static inline struct eth_hash_entry
185*dequeue_addr_from_hash_entry(struct list_head *addr_lst)
186{
187	struct eth_hash_entry *hash_entry = NULL;
188
189	if (!list_empty(addr_lst)) {
190		hash_entry = ETH_HASH_ENTRY_OBJ(addr_lst->next);
191		list_del_init(&hash_entry->node);
192	}
193	return hash_entry;
194}
195
196static inline void free_hash_table(struct eth_hash_t *hash)
197{
198	struct eth_hash_entry *hash_entry;
199	int i = 0;
200
201	if (hash) {
202		if (hash->lsts) {
203			for (i = 0; i < hash->size; i++) {
204				hash_entry =
205				dequeue_addr_from_hash_entry(&hash->lsts[i]);
206				while (hash_entry) {
207					kfree(hash_entry);
208					hash_entry =
209					dequeue_addr_from_hash_entry(&hash->
210								     lsts[i]);
211				}
212			}
213
214			kfree(hash->lsts);
215		}
216
217		kfree(hash);
218	}
219}
220
221static inline struct eth_hash_t *alloc_hash_table(u16 size)
222{
223	u32 i;
224	struct eth_hash_t *hash;
225
226	/* Allocate address hash table */
227	hash = kmalloc(sizeof(*hash), GFP_KERNEL);
228	if (!hash)
229		return NULL;
230
231	hash->size = size;
232
233	hash->lsts = kmalloc_array(hash->size, sizeof(struct list_head),
234				   GFP_KERNEL);
235	if (!hash->lsts) {
236		kfree(hash);
237		return NULL;
238	}
239
240	for (i = 0; i < hash->size; i++)
241		INIT_LIST_HEAD(&hash->lsts[i]);
242
243	return hash;
244}
245
246#endif /* __FM_MAC_H */
247