Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[cascardo/linux.git] / drivers / net / ethernet / freescale / fman / fman_mac.h
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
45 /* Ethernet Address */
46 typedef 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  */
81 enum 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 */
89 enum 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
166 struct eth_hash_entry {
167         u64 addr;               /* Ethernet Address  */
168         struct list_head node;
169 };
170
171 typedef void (fman_mac_exception_cb)(void *dev_id,
172                                     enum fman_mac_exceptions exceptions);
173
174 /* FMan MAC config input */
175 struct 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
195          * MACs; MUST be set to 0 for MACs that don't have
196          * 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
211 struct eth_hash_t {
212         u16 size;
213         struct list_head *lsts;
214 };
215
216 static 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
228 static 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
253 static 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 */