1*852ba100SJustin Hibbits /*
2*852ba100SJustin Hibbits * Copyright 2008-2012 Freescale Semiconductor Inc.
3*852ba100SJustin Hibbits *
4*852ba100SJustin Hibbits * Redistribution and use in source and binary forms, with or without
5*852ba100SJustin Hibbits * modification, are permitted provided that the following conditions are met:
6*852ba100SJustin Hibbits * * Redistributions of source code must retain the above copyright
7*852ba100SJustin Hibbits * notice, this list of conditions and the following disclaimer.
8*852ba100SJustin Hibbits * * Redistributions in binary form must reproduce the above copyright
9*852ba100SJustin Hibbits * notice, this list of conditions and the following disclaimer in the
10*852ba100SJustin Hibbits * documentation and/or other materials provided with the distribution.
11*852ba100SJustin Hibbits * * Neither the name of Freescale Semiconductor nor the
12*852ba100SJustin Hibbits * names of its contributors may be used to endorse or promote products
13*852ba100SJustin Hibbits * derived from this software without specific prior written permission.
14*852ba100SJustin Hibbits *
15*852ba100SJustin Hibbits *
16*852ba100SJustin Hibbits * ALTERNATIVELY, this software may be distributed under the terms of the
17*852ba100SJustin Hibbits * GNU General Public License ("GPL") as published by the Free Software
18*852ba100SJustin Hibbits * Foundation, either version 2 of that License or (at your option) any
19*852ba100SJustin Hibbits * later version.
20*852ba100SJustin Hibbits *
21*852ba100SJustin Hibbits * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22*852ba100SJustin Hibbits * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23*852ba100SJustin Hibbits * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24*852ba100SJustin Hibbits * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25*852ba100SJustin Hibbits * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26*852ba100SJustin Hibbits * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27*852ba100SJustin Hibbits * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28*852ba100SJustin Hibbits * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29*852ba100SJustin Hibbits * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30*852ba100SJustin Hibbits * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*852ba100SJustin Hibbits */
32*852ba100SJustin Hibbits
33*852ba100SJustin Hibbits
34*852ba100SJustin Hibbits /******************************************************************************
35*852ba100SJustin Hibbits @File memac.c
36*852ba100SJustin Hibbits
37*852ba100SJustin Hibbits @Description FM mEMAC driver
38*852ba100SJustin Hibbits *//***************************************************************************/
39*852ba100SJustin Hibbits
40*852ba100SJustin Hibbits #include "std_ext.h"
41*852ba100SJustin Hibbits #include "string_ext.h"
42*852ba100SJustin Hibbits #include "error_ext.h"
43*852ba100SJustin Hibbits #include "xx_ext.h"
44*852ba100SJustin Hibbits #include "endian_ext.h"
45*852ba100SJustin Hibbits #include "debug_ext.h"
46*852ba100SJustin Hibbits
47*852ba100SJustin Hibbits #include "fm_common.h"
48*852ba100SJustin Hibbits #include "memac.h"
49*852ba100SJustin Hibbits
50*852ba100SJustin Hibbits
51*852ba100SJustin Hibbits /*****************************************************************************/
52*852ba100SJustin Hibbits /* Internal routines */
53*852ba100SJustin Hibbits /*****************************************************************************/
54*852ba100SJustin Hibbits
55*852ba100SJustin Hibbits /* ......................................................................... */
56*852ba100SJustin Hibbits
GetMacAddrHashCode(uint64_t ethAddr)57*852ba100SJustin Hibbits static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
58*852ba100SJustin Hibbits {
59*852ba100SJustin Hibbits uint64_t mask1, mask2;
60*852ba100SJustin Hibbits uint32_t xorVal = 0;
61*852ba100SJustin Hibbits uint8_t i, j;
62*852ba100SJustin Hibbits
63*852ba100SJustin Hibbits for (i=0; i<6; i++)
64*852ba100SJustin Hibbits {
65*852ba100SJustin Hibbits mask1 = ethAddr & (uint64_t)0x01;
66*852ba100SJustin Hibbits ethAddr >>= 1;
67*852ba100SJustin Hibbits
68*852ba100SJustin Hibbits for (j=0; j<7; j++)
69*852ba100SJustin Hibbits {
70*852ba100SJustin Hibbits mask2 = ethAddr & (uint64_t)0x01;
71*852ba100SJustin Hibbits mask1 ^= mask2;
72*852ba100SJustin Hibbits ethAddr >>= 1;
73*852ba100SJustin Hibbits }
74*852ba100SJustin Hibbits
75*852ba100SJustin Hibbits xorVal |= (mask1 << (5-i));
76*852ba100SJustin Hibbits }
77*852ba100SJustin Hibbits
78*852ba100SJustin Hibbits return xorVal;
79*852ba100SJustin Hibbits }
80*852ba100SJustin Hibbits
81*852ba100SJustin Hibbits /* ......................................................................... */
82*852ba100SJustin Hibbits
SetupSgmiiInternalPhy(t_Memac * p_Memac,uint8_t phyAddr)83*852ba100SJustin Hibbits static void SetupSgmiiInternalPhy(t_Memac *p_Memac, uint8_t phyAddr)
84*852ba100SJustin Hibbits {
85*852ba100SJustin Hibbits uint16_t tmpReg16;
86*852ba100SJustin Hibbits e_EnetMode enetMode;
87*852ba100SJustin Hibbits
88*852ba100SJustin Hibbits /* In case the higher MACs are used (i.e. the MACs that should support 10G),
89*852ba100SJustin Hibbits speed=10000 is provided for SGMII ports. Temporary modify enet mode
90*852ba100SJustin Hibbits to 1G one, so MII functions can work correctly. */
91*852ba100SJustin Hibbits enetMode = p_Memac->enetMode;
92*852ba100SJustin Hibbits
93*852ba100SJustin Hibbits /* SGMII mode + AN enable */
94*852ba100SJustin Hibbits tmpReg16 = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII;
95*852ba100SJustin Hibbits if ((p_Memac->enetMode) == e_ENET_MODE_SGMII_2500)
96*852ba100SJustin Hibbits tmpReg16 = PHY_SGMII_CR_PHY_RESET | PHY_SGMII_IF_SPEED_GIGABIT | PHY_SGMII_IF_MODE_SGMII;
97*852ba100SJustin Hibbits
98*852ba100SJustin Hibbits p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
99*852ba100SJustin Hibbits MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
100*852ba100SJustin Hibbits
101*852ba100SJustin Hibbits /* Device ability according to SGMII specification */
102*852ba100SJustin Hibbits tmpReg16 = PHY_SGMII_DEV_ABILITY_SGMII;
103*852ba100SJustin Hibbits MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
104*852ba100SJustin Hibbits
105*852ba100SJustin Hibbits /* Adjust link timer for SGMII -
106*852ba100SJustin Hibbits According to Cisco SGMII specification the timer should be 1.6 ms.
107*852ba100SJustin Hibbits The link_timer register is configured in units of the clock.
108*852ba100SJustin Hibbits - When running as 1G SGMII, Serdes clock is 125 MHz, so
109*852ba100SJustin Hibbits unit = 1 / (125*10^6 Hz) = 8 ns.
110*852ba100SJustin Hibbits 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2 * 10^5 = 0x30d40
111*852ba100SJustin Hibbits - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
112*852ba100SJustin Hibbits unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
113*852ba100SJustin Hibbits 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5 * 10^5 = 0x7a120.
114*852ba100SJustin Hibbits Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
115*852ba100SJustin Hibbits we always set up here a value of 2.5 SGMII. */
116*852ba100SJustin Hibbits MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x0007);
117*852ba100SJustin Hibbits MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xa120);
118*852ba100SJustin Hibbits
119*852ba100SJustin Hibbits /* Restart AN */
120*852ba100SJustin Hibbits tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
121*852ba100SJustin Hibbits MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
122*852ba100SJustin Hibbits
123*852ba100SJustin Hibbits /* Restore original enet mode */
124*852ba100SJustin Hibbits p_Memac->enetMode = enetMode;
125*852ba100SJustin Hibbits }
126*852ba100SJustin Hibbits
127*852ba100SJustin Hibbits /* ......................................................................... */
128*852ba100SJustin Hibbits
SetupSgmiiInternalPhyBaseX(t_Memac * p_Memac,uint8_t phyAddr)129*852ba100SJustin Hibbits static void SetupSgmiiInternalPhyBaseX(t_Memac *p_Memac, uint8_t phyAddr)
130*852ba100SJustin Hibbits {
131*852ba100SJustin Hibbits uint16_t tmpReg16;
132*852ba100SJustin Hibbits e_EnetMode enetMode;
133*852ba100SJustin Hibbits
134*852ba100SJustin Hibbits /* In case the higher MACs are used (i.e. the MACs that should support 10G),
135*852ba100SJustin Hibbits speed=10000 is provided for SGMII ports. Temporary modify enet mode
136*852ba100SJustin Hibbits to 1G one, so MII functions can work correctly. */
137*852ba100SJustin Hibbits enetMode = p_Memac->enetMode;
138*852ba100SJustin Hibbits p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
139*852ba100SJustin Hibbits
140*852ba100SJustin Hibbits /* 1000BaseX mode */
141*852ba100SJustin Hibbits tmpReg16 = PHY_SGMII_IF_MODE_1000X;
142*852ba100SJustin Hibbits MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
143*852ba100SJustin Hibbits
144*852ba100SJustin Hibbits /* AN Device capability */
145*852ba100SJustin Hibbits tmpReg16 = PHY_SGMII_DEV_ABILITY_1000X;
146*852ba100SJustin Hibbits MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
147*852ba100SJustin Hibbits
148*852ba100SJustin Hibbits /* Adjust link timer for SGMII -
149*852ba100SJustin Hibbits For Serdes 1000BaseX auto-negotiation the timer should be 10 ms.
150*852ba100SJustin Hibbits The link_timer register is configured in units of the clock.
151*852ba100SJustin Hibbits - When running as 1G SGMII, Serdes clock is 125 MHz, so
152*852ba100SJustin Hibbits unit = 1 / (125*10^6 Hz) = 8 ns.
153*852ba100SJustin Hibbits 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0
154*852ba100SJustin Hibbits - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
155*852ba100SJustin Hibbits unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
156*852ba100SJustin Hibbits 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08.
157*852ba100SJustin Hibbits Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
158*852ba100SJustin Hibbits we always set up here a value of 2.5 SGMII. */
159*852ba100SJustin Hibbits MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x002f);
160*852ba100SJustin Hibbits MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xaf08);
161*852ba100SJustin Hibbits
162*852ba100SJustin Hibbits /* Restart AN */
163*852ba100SJustin Hibbits tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
164*852ba100SJustin Hibbits MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
165*852ba100SJustin Hibbits
166*852ba100SJustin Hibbits /* Restore original enet mode */
167*852ba100SJustin Hibbits p_Memac->enetMode = enetMode;
168*852ba100SJustin Hibbits }
169*852ba100SJustin Hibbits
170*852ba100SJustin Hibbits /* ......................................................................... */
171*852ba100SJustin Hibbits
CheckInitParameters(t_Memac * p_Memac)172*852ba100SJustin Hibbits static t_Error CheckInitParameters(t_Memac *p_Memac)
173*852ba100SJustin Hibbits {
174*852ba100SJustin Hibbits e_FmMacType portType;
175*852ba100SJustin Hibbits
176*852ba100SJustin Hibbits portType = ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
177*852ba100SJustin Hibbits
178*852ba100SJustin Hibbits #if (FM_MAX_NUM_OF_10G_MACS > 0)
179*852ba100SJustin Hibbits if ((portType == e_FM_MAC_10G) && (p_Memac->macId >= FM_MAX_NUM_OF_10G_MACS))
180*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("10G MAC ID must be less than %d", FM_MAX_NUM_OF_10G_MACS));
181*852ba100SJustin Hibbits #endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
182*852ba100SJustin Hibbits
183*852ba100SJustin Hibbits if ((portType == e_FM_MAC_1G) && (p_Memac->macId >= FM_MAX_NUM_OF_1G_MACS))
184*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("1G MAC ID must be less than %d", FM_MAX_NUM_OF_1G_MACS));
185*852ba100SJustin Hibbits if (p_Memac->addr == 0)
186*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC must have a valid MAC address"));
187*852ba100SJustin Hibbits if (!p_Memac->f_Exception)
188*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Exception"));
189*852ba100SJustin Hibbits if (!p_Memac->f_Event)
190*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Event"));
191*852ba100SJustin Hibbits #ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
192*852ba100SJustin Hibbits if (!p_Memac->p_MemacDriverParam->no_length_check_enable)
193*852ba100SJustin Hibbits RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
194*852ba100SJustin Hibbits #endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
195*852ba100SJustin Hibbits
196*852ba100SJustin Hibbits return E_OK;
197*852ba100SJustin Hibbits }
198*852ba100SJustin Hibbits
199*852ba100SJustin Hibbits /* ........................................................................... */
200*852ba100SJustin Hibbits
MemacErrException(t_Handle h_Memac)201*852ba100SJustin Hibbits static void MemacErrException(t_Handle h_Memac)
202*852ba100SJustin Hibbits {
203*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
204*852ba100SJustin Hibbits uint32_t event, imask;
205*852ba100SJustin Hibbits
206*852ba100SJustin Hibbits event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
207*852ba100SJustin Hibbits imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
208*852ba100SJustin Hibbits
209*852ba100SJustin Hibbits /* Imask include both error and notification/event bits.
210*852ba100SJustin Hibbits Leaving only error bits enabled by imask.
211*852ba100SJustin Hibbits The imask error bits are shifted by 16 bits offset from
212*852ba100SJustin Hibbits their corresponding location in the ievent - hence the >> 16 */
213*852ba100SJustin Hibbits event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
214*852ba100SJustin Hibbits
215*852ba100SJustin Hibbits fman_memac_ack_event(p_Memac->p_MemMap, event);
216*852ba100SJustin Hibbits
217*852ba100SJustin Hibbits if (event & MEMAC_IEVNT_TS_ECC_ER)
218*852ba100SJustin Hibbits p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_TS_FIFO_ECC_ERR);
219*852ba100SJustin Hibbits if (event & MEMAC_IEVNT_TX_ECC_ER)
220*852ba100SJustin Hibbits p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
221*852ba100SJustin Hibbits if (event & MEMAC_IEVNT_RX_ECC_ER)
222*852ba100SJustin Hibbits p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
223*852ba100SJustin Hibbits }
224*852ba100SJustin Hibbits
MemacException(t_Handle h_Memac)225*852ba100SJustin Hibbits static void MemacException(t_Handle h_Memac)
226*852ba100SJustin Hibbits {
227*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
228*852ba100SJustin Hibbits uint32_t event, imask;
229*852ba100SJustin Hibbits
230*852ba100SJustin Hibbits event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
231*852ba100SJustin Hibbits imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
232*852ba100SJustin Hibbits
233*852ba100SJustin Hibbits /* Imask include both error and notification/event bits.
234*852ba100SJustin Hibbits Leaving only error bits enabled by imask.
235*852ba100SJustin Hibbits The imask error bits are shifted by 16 bits offset from
236*852ba100SJustin Hibbits their corresponding location in the ievent - hence the >> 16 */
237*852ba100SJustin Hibbits event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
238*852ba100SJustin Hibbits
239*852ba100SJustin Hibbits fman_memac_ack_event(p_Memac->p_MemMap, event);
240*852ba100SJustin Hibbits
241*852ba100SJustin Hibbits if (event & MEMAC_IEVNT_MGI)
242*852ba100SJustin Hibbits p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_MAGIC_PACKET_INDICATION);
243*852ba100SJustin Hibbits }
244*852ba100SJustin Hibbits
245*852ba100SJustin Hibbits /* ......................................................................... */
246*852ba100SJustin Hibbits
FreeInitResources(t_Memac * p_Memac)247*852ba100SJustin Hibbits static void FreeInitResources(t_Memac *p_Memac)
248*852ba100SJustin Hibbits {
249*852ba100SJustin Hibbits e_FmMacType portType;
250*852ba100SJustin Hibbits
251*852ba100SJustin Hibbits portType =
252*852ba100SJustin Hibbits ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
253*852ba100SJustin Hibbits
254*852ba100SJustin Hibbits if (portType == e_FM_MAC_10G)
255*852ba100SJustin Hibbits FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
256*852ba100SJustin Hibbits else
257*852ba100SJustin Hibbits FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
258*852ba100SJustin Hibbits
259*852ba100SJustin Hibbits /* release the driver's group hash table */
260*852ba100SJustin Hibbits FreeHashTable(p_Memac->p_MulticastAddrHash);
261*852ba100SJustin Hibbits p_Memac->p_MulticastAddrHash = NULL;
262*852ba100SJustin Hibbits
263*852ba100SJustin Hibbits /* release the driver's individual hash table */
264*852ba100SJustin Hibbits FreeHashTable(p_Memac->p_UnicastAddrHash);
265*852ba100SJustin Hibbits p_Memac->p_UnicastAddrHash = NULL;
266*852ba100SJustin Hibbits }
267*852ba100SJustin Hibbits
268*852ba100SJustin Hibbits
269*852ba100SJustin Hibbits /*****************************************************************************/
270*852ba100SJustin Hibbits /* mEMAC API routines */
271*852ba100SJustin Hibbits /*****************************************************************************/
272*852ba100SJustin Hibbits
273*852ba100SJustin Hibbits /* ......................................................................... */
274*852ba100SJustin Hibbits
MemacEnable(t_Handle h_Memac,e_CommMode mode)275*852ba100SJustin Hibbits static t_Error MemacEnable(t_Handle h_Memac, e_CommMode mode)
276*852ba100SJustin Hibbits {
277*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
278*852ba100SJustin Hibbits
279*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
280*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
281*852ba100SJustin Hibbits
282*852ba100SJustin Hibbits fman_memac_enable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
283*852ba100SJustin Hibbits
284*852ba100SJustin Hibbits return E_OK;
285*852ba100SJustin Hibbits }
286*852ba100SJustin Hibbits
287*852ba100SJustin Hibbits /* ......................................................................... */
288*852ba100SJustin Hibbits
MemacDisable(t_Handle h_Memac,e_CommMode mode)289*852ba100SJustin Hibbits static t_Error MemacDisable (t_Handle h_Memac, e_CommMode mode)
290*852ba100SJustin Hibbits {
291*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
292*852ba100SJustin Hibbits
293*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
294*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
295*852ba100SJustin Hibbits
296*852ba100SJustin Hibbits fman_memac_disable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
297*852ba100SJustin Hibbits
298*852ba100SJustin Hibbits return E_OK;
299*852ba100SJustin Hibbits }
300*852ba100SJustin Hibbits
301*852ba100SJustin Hibbits /* ......................................................................... */
302*852ba100SJustin Hibbits
MemacSetPromiscuous(t_Handle h_Memac,bool newVal)303*852ba100SJustin Hibbits static t_Error MemacSetPromiscuous(t_Handle h_Memac, bool newVal)
304*852ba100SJustin Hibbits {
305*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
306*852ba100SJustin Hibbits
307*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
308*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
309*852ba100SJustin Hibbits
310*852ba100SJustin Hibbits fman_memac_set_promiscuous(p_Memac->p_MemMap, newVal);
311*852ba100SJustin Hibbits
312*852ba100SJustin Hibbits return E_OK;
313*852ba100SJustin Hibbits }
314*852ba100SJustin Hibbits
315*852ba100SJustin Hibbits /* .............................................................................. */
316*852ba100SJustin Hibbits
MemacAdjustLink(t_Handle h_Memac,e_EnetSpeed speed,bool fullDuplex)317*852ba100SJustin Hibbits static t_Error MemacAdjustLink(t_Handle h_Memac, e_EnetSpeed speed, bool fullDuplex)
318*852ba100SJustin Hibbits {
319*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
320*852ba100SJustin Hibbits
321*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
322*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
323*852ba100SJustin Hibbits
324*852ba100SJustin Hibbits if ((speed >= e_ENET_SPEED_1000) && (!fullDuplex))
325*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_CONFLICT,
326*852ba100SJustin Hibbits ("Ethernet MAC 1G or 10G does not support half-duplex"));
327*852ba100SJustin Hibbits
328*852ba100SJustin Hibbits fman_memac_adjust_link(p_Memac->p_MemMap,
329*852ba100SJustin Hibbits (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Memac->enetMode),
330*852ba100SJustin Hibbits (enum enet_speed)speed,
331*852ba100SJustin Hibbits fullDuplex);
332*852ba100SJustin Hibbits return E_OK;
333*852ba100SJustin Hibbits }
334*852ba100SJustin Hibbits
335*852ba100SJustin Hibbits
336*852ba100SJustin Hibbits /*****************************************************************************/
337*852ba100SJustin Hibbits /* Memac Configs modification functions */
338*852ba100SJustin Hibbits /*****************************************************************************/
339*852ba100SJustin Hibbits
340*852ba100SJustin Hibbits /* ......................................................................... */
341*852ba100SJustin Hibbits
MemacConfigLoopback(t_Handle h_Memac,bool newVal)342*852ba100SJustin Hibbits static t_Error MemacConfigLoopback(t_Handle h_Memac, bool newVal)
343*852ba100SJustin Hibbits {
344*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
345*852ba100SJustin Hibbits
346*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
347*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
348*852ba100SJustin Hibbits
349*852ba100SJustin Hibbits p_Memac->p_MemacDriverParam->loopback_enable = newVal;
350*852ba100SJustin Hibbits
351*852ba100SJustin Hibbits return E_OK;
352*852ba100SJustin Hibbits }
353*852ba100SJustin Hibbits
354*852ba100SJustin Hibbits /* ......................................................................... */
355*852ba100SJustin Hibbits
MemacConfigWan(t_Handle h_Memac,bool newVal)356*852ba100SJustin Hibbits static t_Error MemacConfigWan(t_Handle h_Memac, bool newVal)
357*852ba100SJustin Hibbits {
358*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
359*852ba100SJustin Hibbits
360*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
361*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
362*852ba100SJustin Hibbits
363*852ba100SJustin Hibbits p_Memac->p_MemacDriverParam->wan_mode_enable = newVal;
364*852ba100SJustin Hibbits
365*852ba100SJustin Hibbits return E_OK;
366*852ba100SJustin Hibbits }
367*852ba100SJustin Hibbits
368*852ba100SJustin Hibbits /* ......................................................................... */
369*852ba100SJustin Hibbits
MemacConfigMaxFrameLength(t_Handle h_Memac,uint16_t newVal)370*852ba100SJustin Hibbits static t_Error MemacConfigMaxFrameLength(t_Handle h_Memac, uint16_t newVal)
371*852ba100SJustin Hibbits {
372*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
373*852ba100SJustin Hibbits
374*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
375*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
376*852ba100SJustin Hibbits
377*852ba100SJustin Hibbits p_Memac->p_MemacDriverParam->max_frame_length = newVal;
378*852ba100SJustin Hibbits
379*852ba100SJustin Hibbits return E_OK;
380*852ba100SJustin Hibbits }
381*852ba100SJustin Hibbits
382*852ba100SJustin Hibbits /* ......................................................................... */
383*852ba100SJustin Hibbits
MemacConfigPad(t_Handle h_Memac,bool newVal)384*852ba100SJustin Hibbits static t_Error MemacConfigPad(t_Handle h_Memac, bool newVal)
385*852ba100SJustin Hibbits {
386*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
387*852ba100SJustin Hibbits
388*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
389*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
390*852ba100SJustin Hibbits
391*852ba100SJustin Hibbits p_Memac->p_MemacDriverParam->pad_enable = newVal;
392*852ba100SJustin Hibbits
393*852ba100SJustin Hibbits return E_OK;
394*852ba100SJustin Hibbits }
395*852ba100SJustin Hibbits
396*852ba100SJustin Hibbits /* ......................................................................... */
397*852ba100SJustin Hibbits
MemacConfigLengthCheck(t_Handle h_Memac,bool newVal)398*852ba100SJustin Hibbits static t_Error MemacConfigLengthCheck(t_Handle h_Memac, bool newVal)
399*852ba100SJustin Hibbits {
400*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
401*852ba100SJustin Hibbits
402*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
403*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
404*852ba100SJustin Hibbits
405*852ba100SJustin Hibbits p_Memac->p_MemacDriverParam->no_length_check_enable = !newVal;
406*852ba100SJustin Hibbits
407*852ba100SJustin Hibbits return E_OK;
408*852ba100SJustin Hibbits }
409*852ba100SJustin Hibbits
410*852ba100SJustin Hibbits /* ......................................................................... */
411*852ba100SJustin Hibbits
MemacConfigException(t_Handle h_Memac,e_FmMacExceptions exception,bool enable)412*852ba100SJustin Hibbits static t_Error MemacConfigException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
413*852ba100SJustin Hibbits {
414*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
415*852ba100SJustin Hibbits uint32_t bitMask = 0;
416*852ba100SJustin Hibbits
417*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
418*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
419*852ba100SJustin Hibbits
420*852ba100SJustin Hibbits GET_EXCEPTION_FLAG(bitMask, exception);
421*852ba100SJustin Hibbits if (bitMask)
422*852ba100SJustin Hibbits {
423*852ba100SJustin Hibbits if (enable)
424*852ba100SJustin Hibbits p_Memac->exceptions |= bitMask;
425*852ba100SJustin Hibbits else
426*852ba100SJustin Hibbits p_Memac->exceptions &= ~bitMask;
427*852ba100SJustin Hibbits }
428*852ba100SJustin Hibbits else
429*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
430*852ba100SJustin Hibbits
431*852ba100SJustin Hibbits return E_OK;
432*852ba100SJustin Hibbits }
433*852ba100SJustin Hibbits
434*852ba100SJustin Hibbits /* ......................................................................... */
435*852ba100SJustin Hibbits
MemacConfigResetOnInit(t_Handle h_Memac,bool enable)436*852ba100SJustin Hibbits static t_Error MemacConfigResetOnInit(t_Handle h_Memac, bool enable)
437*852ba100SJustin Hibbits {
438*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
439*852ba100SJustin Hibbits
440*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
441*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
442*852ba100SJustin Hibbits
443*852ba100SJustin Hibbits p_Memac->p_MemacDriverParam->reset_on_init = enable;
444*852ba100SJustin Hibbits
445*852ba100SJustin Hibbits return E_OK;
446*852ba100SJustin Hibbits }
447*852ba100SJustin Hibbits
448*852ba100SJustin Hibbits
449*852ba100SJustin Hibbits /*****************************************************************************/
450*852ba100SJustin Hibbits /* Memac Run Time API functions */
451*852ba100SJustin Hibbits /*****************************************************************************/
452*852ba100SJustin Hibbits
453*852ba100SJustin Hibbits /* ......................................................................... */
454*852ba100SJustin Hibbits
MemacSetTxPauseFrames(t_Handle h_Memac,uint8_t priority,uint16_t pauseTime,uint16_t threshTime)455*852ba100SJustin Hibbits static t_Error MemacSetTxPauseFrames(t_Handle h_Memac,
456*852ba100SJustin Hibbits uint8_t priority,
457*852ba100SJustin Hibbits uint16_t pauseTime,
458*852ba100SJustin Hibbits uint16_t threshTime)
459*852ba100SJustin Hibbits {
460*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
461*852ba100SJustin Hibbits
462*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
463*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
464*852ba100SJustin Hibbits
465*852ba100SJustin Hibbits if (priority != 0xFF)
466*852ba100SJustin Hibbits {
467*852ba100SJustin Hibbits bool PortConfigured, PreFetchEnabled;
468*852ba100SJustin Hibbits
469*852ba100SJustin Hibbits if (FmGetTnumAgingPeriod(p_Memac->fmMacControllerDriver.h_Fm) == 0)
470*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_CONFLICT, ("For PFC operation, TNUM aging must be enabled"));
471*852ba100SJustin Hibbits
472*852ba100SJustin Hibbits FmGetPortPreFetchConfiguration(p_Memac->fmMacControllerDriver.h_Fm,
473*852ba100SJustin Hibbits p_Memac->fmMacControllerDriver.macId,
474*852ba100SJustin Hibbits &PortConfigured,
475*852ba100SJustin Hibbits &PreFetchEnabled);
476*852ba100SJustin Hibbits
477*852ba100SJustin Hibbits if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && !PortConfigured)
478*852ba100SJustin Hibbits DBG(INFO, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
479*852ba100SJustin Hibbits
480*852ba100SJustin Hibbits if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && PortConfigured && !PreFetchEnabled)
481*852ba100SJustin Hibbits DBG(WARNING, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
482*852ba100SJustin Hibbits }
483*852ba100SJustin Hibbits
484*852ba100SJustin Hibbits fman_memac_set_tx_pause_frames(p_Memac->p_MemMap, priority, pauseTime, threshTime);
485*852ba100SJustin Hibbits
486*852ba100SJustin Hibbits return E_OK;
487*852ba100SJustin Hibbits }
488*852ba100SJustin Hibbits
489*852ba100SJustin Hibbits /* ......................................................................... */
490*852ba100SJustin Hibbits
MemacSetTxAutoPauseFrames(t_Handle h_Memac,uint16_t pauseTime)491*852ba100SJustin Hibbits static t_Error MemacSetTxAutoPauseFrames(t_Handle h_Memac,
492*852ba100SJustin Hibbits uint16_t pauseTime)
493*852ba100SJustin Hibbits {
494*852ba100SJustin Hibbits return MemacSetTxPauseFrames(h_Memac, FM_MAC_NO_PFC, pauseTime, 0);
495*852ba100SJustin Hibbits }
496*852ba100SJustin Hibbits
497*852ba100SJustin Hibbits /* ......................................................................... */
498*852ba100SJustin Hibbits
MemacSetRxIgnorePauseFrames(t_Handle h_Memac,bool en)499*852ba100SJustin Hibbits static t_Error MemacSetRxIgnorePauseFrames(t_Handle h_Memac, bool en)
500*852ba100SJustin Hibbits {
501*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
502*852ba100SJustin Hibbits
503*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
504*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
505*852ba100SJustin Hibbits
506*852ba100SJustin Hibbits fman_memac_set_rx_ignore_pause_frames(p_Memac->p_MemMap, en);
507*852ba100SJustin Hibbits
508*852ba100SJustin Hibbits return E_OK;
509*852ba100SJustin Hibbits }
510*852ba100SJustin Hibbits
511*852ba100SJustin Hibbits /* ......................................................................... */
512*852ba100SJustin Hibbits
MemacSetWakeOnLan(t_Handle h_Memac,bool en)513*852ba100SJustin Hibbits static t_Error MemacSetWakeOnLan(t_Handle h_Memac, bool en)
514*852ba100SJustin Hibbits {
515*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
516*852ba100SJustin Hibbits
517*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
518*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
519*852ba100SJustin Hibbits
520*852ba100SJustin Hibbits fman_memac_set_wol(p_Memac->p_MemMap, en);
521*852ba100SJustin Hibbits
522*852ba100SJustin Hibbits return E_OK;
523*852ba100SJustin Hibbits }
524*852ba100SJustin Hibbits
525*852ba100SJustin Hibbits /* .............................................................................. */
526*852ba100SJustin Hibbits
MemacEnable1588TimeStamp(t_Handle h_Memac)527*852ba100SJustin Hibbits static t_Error MemacEnable1588TimeStamp(t_Handle h_Memac)
528*852ba100SJustin Hibbits {
529*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
530*852ba100SJustin Hibbits
531*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
532*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
533*852ba100SJustin Hibbits UNUSED(p_Memac);
534*852ba100SJustin Hibbits DBG(WARNING, ("mEMAC has 1588 always enabled!"));
535*852ba100SJustin Hibbits
536*852ba100SJustin Hibbits return E_OK;
537*852ba100SJustin Hibbits }
538*852ba100SJustin Hibbits
539*852ba100SJustin Hibbits /* Counters handling */
540*852ba100SJustin Hibbits /* ......................................................................... */
541*852ba100SJustin Hibbits
MemacGetStatistics(t_Handle h_Memac,t_FmMacStatistics * p_Statistics)542*852ba100SJustin Hibbits static t_Error MemacGetStatistics(t_Handle h_Memac, t_FmMacStatistics *p_Statistics)
543*852ba100SJustin Hibbits {
544*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
545*852ba100SJustin Hibbits
546*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
547*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
548*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
549*852ba100SJustin Hibbits
550*852ba100SJustin Hibbits p_Statistics->eStatPkts64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64);
551*852ba100SJustin Hibbits p_Statistics->eStatPkts65to127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127);
552*852ba100SJustin Hibbits p_Statistics->eStatPkts128to255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255);
553*852ba100SJustin Hibbits p_Statistics->eStatPkts256to511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511);
554*852ba100SJustin Hibbits p_Statistics->eStatPkts512to1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023);
555*852ba100SJustin Hibbits p_Statistics->eStatPkts1024to1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518);
556*852ba100SJustin Hibbits p_Statistics->eStatPkts1519to1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X);
557*852ba100SJustin Hibbits /* */
558*852ba100SJustin Hibbits p_Statistics->eStatFragments = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RFRG);
559*852ba100SJustin Hibbits p_Statistics->eStatJabbers = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RJBR);
560*852ba100SJustin Hibbits
561*852ba100SJustin Hibbits p_Statistics->eStatsDropEvents = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RDRP);
562*852ba100SJustin Hibbits p_Statistics->eStatCRCAlignErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RALN);
563*852ba100SJustin Hibbits
564*852ba100SJustin Hibbits p_Statistics->eStatUndersizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUND);
565*852ba100SJustin Hibbits p_Statistics->eStatOversizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROVR);
566*852ba100SJustin Hibbits /* Pause */
567*852ba100SJustin Hibbits p_Statistics->reStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RXPF);
568*852ba100SJustin Hibbits p_Statistics->teStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TXPF);
569*852ba100SJustin Hibbits
570*852ba100SJustin Hibbits /* MIB II */
571*852ba100SJustin Hibbits p_Statistics->ifInOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROCT);
572*852ba100SJustin Hibbits p_Statistics->ifInUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RUCA);
573*852ba100SJustin Hibbits p_Statistics->ifInMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RMCA);
574*852ba100SJustin Hibbits p_Statistics->ifInBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RBCA);
575*852ba100SJustin Hibbits p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
576*852ba100SJustin Hibbits + p_Statistics->ifInMcastPkts
577*852ba100SJustin Hibbits + p_Statistics->ifInBcastPkts;
578*852ba100SJustin Hibbits p_Statistics->ifInDiscards = 0;
579*852ba100SJustin Hibbits p_Statistics->ifInErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RERR);
580*852ba100SJustin Hibbits
581*852ba100SJustin Hibbits p_Statistics->ifOutOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TOCT);
582*852ba100SJustin Hibbits p_Statistics->ifOutUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUCA);
583*852ba100SJustin Hibbits p_Statistics->ifOutMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TMCA);
584*852ba100SJustin Hibbits p_Statistics->ifOutBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TBCA);
585*852ba100SJustin Hibbits p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
586*852ba100SJustin Hibbits + p_Statistics->ifOutMcastPkts
587*852ba100SJustin Hibbits + p_Statistics->ifOutBcastPkts;
588*852ba100SJustin Hibbits p_Statistics->ifOutDiscards = 0;
589*852ba100SJustin Hibbits p_Statistics->ifOutErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TERR);
590*852ba100SJustin Hibbits
591*852ba100SJustin Hibbits return E_OK;
592*852ba100SJustin Hibbits }
593*852ba100SJustin Hibbits
594*852ba100SJustin Hibbits /* ......................................................................... */
595*852ba100SJustin Hibbits
MemacModifyMacAddress(t_Handle h_Memac,t_EnetAddr * p_EnetAddr)596*852ba100SJustin Hibbits static t_Error MemacModifyMacAddress (t_Handle h_Memac, t_EnetAddr *p_EnetAddr)
597*852ba100SJustin Hibbits {
598*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
599*852ba100SJustin Hibbits
600*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
601*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
602*852ba100SJustin Hibbits
603*852ba100SJustin Hibbits fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t *)(*p_EnetAddr), 0);
604*852ba100SJustin Hibbits
605*852ba100SJustin Hibbits return E_OK;
606*852ba100SJustin Hibbits }
607*852ba100SJustin Hibbits
608*852ba100SJustin Hibbits /* ......................................................................... */
609*852ba100SJustin Hibbits
MemacResetCounters(t_Handle h_Memac)610*852ba100SJustin Hibbits static t_Error MemacResetCounters (t_Handle h_Memac)
611*852ba100SJustin Hibbits {
612*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
613*852ba100SJustin Hibbits
614*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
615*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
616*852ba100SJustin Hibbits
617*852ba100SJustin Hibbits fman_memac_reset_stat(p_Memac->p_MemMap);
618*852ba100SJustin Hibbits
619*852ba100SJustin Hibbits return E_OK;
620*852ba100SJustin Hibbits }
621*852ba100SJustin Hibbits
622*852ba100SJustin Hibbits /* ......................................................................... */
623*852ba100SJustin Hibbits
MemacAddExactMatchMacAddress(t_Handle h_Memac,t_EnetAddr * p_EthAddr)624*852ba100SJustin Hibbits static t_Error MemacAddExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
625*852ba100SJustin Hibbits {
626*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *) h_Memac;
627*852ba100SJustin Hibbits uint64_t ethAddr;
628*852ba100SJustin Hibbits uint8_t paddrNum;
629*852ba100SJustin Hibbits
630*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
631*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
632*852ba100SJustin Hibbits
633*852ba100SJustin Hibbits ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
634*852ba100SJustin Hibbits
635*852ba100SJustin Hibbits if (ethAddr & GROUP_ADDRESS)
636*852ba100SJustin Hibbits /* Multicast address has no effect in PADDR */
637*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
638*852ba100SJustin Hibbits
639*852ba100SJustin Hibbits /* Make sure no PADDR contains this address */
640*852ba100SJustin Hibbits for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
641*852ba100SJustin Hibbits if (p_Memac->indAddrRegUsed[paddrNum])
642*852ba100SJustin Hibbits if (p_Memac->paddr[paddrNum] == ethAddr)
643*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
644*852ba100SJustin Hibbits
645*852ba100SJustin Hibbits /* Find first unused PADDR */
646*852ba100SJustin Hibbits for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
647*852ba100SJustin Hibbits if (!(p_Memac->indAddrRegUsed[paddrNum]))
648*852ba100SJustin Hibbits {
649*852ba100SJustin Hibbits /* mark this PADDR as used */
650*852ba100SJustin Hibbits p_Memac->indAddrRegUsed[paddrNum] = TRUE;
651*852ba100SJustin Hibbits /* store address */
652*852ba100SJustin Hibbits p_Memac->paddr[paddrNum] = ethAddr;
653*852ba100SJustin Hibbits
654*852ba100SJustin Hibbits /* put in hardware */
655*852ba100SJustin Hibbits fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)(*p_EthAddr), paddrNum);
656*852ba100SJustin Hibbits p_Memac->numOfIndAddrInRegs++;
657*852ba100SJustin Hibbits
658*852ba100SJustin Hibbits return E_OK;
659*852ba100SJustin Hibbits }
660*852ba100SJustin Hibbits
661*852ba100SJustin Hibbits /* No free PADDR */
662*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
663*852ba100SJustin Hibbits }
664*852ba100SJustin Hibbits
665*852ba100SJustin Hibbits /* ......................................................................... */
666*852ba100SJustin Hibbits
MemacDelExactMatchMacAddress(t_Handle h_Memac,t_EnetAddr * p_EthAddr)667*852ba100SJustin Hibbits static t_Error MemacDelExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
668*852ba100SJustin Hibbits {
669*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *) h_Memac;
670*852ba100SJustin Hibbits uint64_t ethAddr;
671*852ba100SJustin Hibbits uint8_t paddrNum;
672*852ba100SJustin Hibbits
673*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
674*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
675*852ba100SJustin Hibbits
676*852ba100SJustin Hibbits ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
677*852ba100SJustin Hibbits
678*852ba100SJustin Hibbits /* Find used PADDR containing this address */
679*852ba100SJustin Hibbits for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
680*852ba100SJustin Hibbits {
681*852ba100SJustin Hibbits if ((p_Memac->indAddrRegUsed[paddrNum]) &&
682*852ba100SJustin Hibbits (p_Memac->paddr[paddrNum] == ethAddr))
683*852ba100SJustin Hibbits {
684*852ba100SJustin Hibbits /* mark this PADDR as not used */
685*852ba100SJustin Hibbits p_Memac->indAddrRegUsed[paddrNum] = FALSE;
686*852ba100SJustin Hibbits /* clear in hardware */
687*852ba100SJustin Hibbits fman_memac_clear_addr_in_paddr(p_Memac->p_MemMap, paddrNum);
688*852ba100SJustin Hibbits p_Memac->numOfIndAddrInRegs--;
689*852ba100SJustin Hibbits
690*852ba100SJustin Hibbits return E_OK;
691*852ba100SJustin Hibbits }
692*852ba100SJustin Hibbits }
693*852ba100SJustin Hibbits
694*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
695*852ba100SJustin Hibbits }
696*852ba100SJustin Hibbits
697*852ba100SJustin Hibbits /* ......................................................................... */
698*852ba100SJustin Hibbits
MemacGetId(t_Handle h_Memac,uint32_t * macId)699*852ba100SJustin Hibbits static t_Error MemacGetId(t_Handle h_Memac, uint32_t *macId)
700*852ba100SJustin Hibbits {
701*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
702*852ba100SJustin Hibbits
703*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
704*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
705*852ba100SJustin Hibbits
706*852ba100SJustin Hibbits *macId = p_Memac->macId;
707*852ba100SJustin Hibbits
708*852ba100SJustin Hibbits return E_OK;
709*852ba100SJustin Hibbits }
710*852ba100SJustin Hibbits
711*852ba100SJustin Hibbits /* ......................................................................... */
712*852ba100SJustin Hibbits
713*852ba100SJustin Hibbits
MemacAddHashMacAddress(t_Handle h_Memac,t_EnetAddr * p_EthAddr)714*852ba100SJustin Hibbits static t_Error MemacAddHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
715*852ba100SJustin Hibbits {
716*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
717*852ba100SJustin Hibbits t_EthHashEntry *p_HashEntry;
718*852ba100SJustin Hibbits uint32_t hash;
719*852ba100SJustin Hibbits uint64_t ethAddr;
720*852ba100SJustin Hibbits
721*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
722*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
723*852ba100SJustin Hibbits
724*852ba100SJustin Hibbits ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
725*852ba100SJustin Hibbits
726*852ba100SJustin Hibbits if (!(ethAddr & GROUP_ADDRESS))
727*852ba100SJustin Hibbits /* Unicast addresses not supported in hash */
728*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
729*852ba100SJustin Hibbits
730*852ba100SJustin Hibbits hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
731*852ba100SJustin Hibbits
732*852ba100SJustin Hibbits /* Create element to be added to the driver hash table */
733*852ba100SJustin Hibbits p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
734*852ba100SJustin Hibbits p_HashEntry->addr = ethAddr;
735*852ba100SJustin Hibbits INIT_LIST(&p_HashEntry->node);
736*852ba100SJustin Hibbits
737*852ba100SJustin Hibbits LIST_AddToTail(&(p_HashEntry->node), &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]));
738*852ba100SJustin Hibbits fman_memac_set_hash_table(p_Memac->p_MemMap, (hash | HASH_CTRL_MCAST_EN));
739*852ba100SJustin Hibbits
740*852ba100SJustin Hibbits return E_OK;
741*852ba100SJustin Hibbits }
742*852ba100SJustin Hibbits
743*852ba100SJustin Hibbits /* ......................................................................... */
744*852ba100SJustin Hibbits
MemacDelHashMacAddress(t_Handle h_Memac,t_EnetAddr * p_EthAddr)745*852ba100SJustin Hibbits static t_Error MemacDelHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
746*852ba100SJustin Hibbits {
747*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
748*852ba100SJustin Hibbits t_EthHashEntry *p_HashEntry = NULL;
749*852ba100SJustin Hibbits t_List *p_Pos;
750*852ba100SJustin Hibbits uint32_t hash;
751*852ba100SJustin Hibbits uint64_t ethAddr;
752*852ba100SJustin Hibbits
753*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
754*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
755*852ba100SJustin Hibbits
756*852ba100SJustin Hibbits ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
757*852ba100SJustin Hibbits
758*852ba100SJustin Hibbits hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
759*852ba100SJustin Hibbits
760*852ba100SJustin Hibbits LIST_FOR_EACH(p_Pos, &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
761*852ba100SJustin Hibbits {
762*852ba100SJustin Hibbits p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
763*852ba100SJustin Hibbits if (p_HashEntry->addr == ethAddr)
764*852ba100SJustin Hibbits {
765*852ba100SJustin Hibbits LIST_DelAndInit(&p_HashEntry->node);
766*852ba100SJustin Hibbits XX_Free(p_HashEntry);
767*852ba100SJustin Hibbits break;
768*852ba100SJustin Hibbits }
769*852ba100SJustin Hibbits }
770*852ba100SJustin Hibbits if (LIST_IsEmpty(&p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
771*852ba100SJustin Hibbits fman_memac_set_hash_table(p_Memac->p_MemMap, (hash & ~HASH_CTRL_MCAST_EN));
772*852ba100SJustin Hibbits
773*852ba100SJustin Hibbits return E_OK;
774*852ba100SJustin Hibbits }
775*852ba100SJustin Hibbits
776*852ba100SJustin Hibbits
777*852ba100SJustin Hibbits /* ......................................................................... */
778*852ba100SJustin Hibbits
MemacSetException(t_Handle h_Memac,e_FmMacExceptions exception,bool enable)779*852ba100SJustin Hibbits static t_Error MemacSetException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
780*852ba100SJustin Hibbits {
781*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
782*852ba100SJustin Hibbits uint32_t bitMask = 0;
783*852ba100SJustin Hibbits
784*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
785*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
786*852ba100SJustin Hibbits
787*852ba100SJustin Hibbits GET_EXCEPTION_FLAG(bitMask, exception);
788*852ba100SJustin Hibbits if (bitMask)
789*852ba100SJustin Hibbits {
790*852ba100SJustin Hibbits if (enable)
791*852ba100SJustin Hibbits p_Memac->exceptions |= bitMask;
792*852ba100SJustin Hibbits else
793*852ba100SJustin Hibbits p_Memac->exceptions &= ~bitMask;
794*852ba100SJustin Hibbits }
795*852ba100SJustin Hibbits else
796*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
797*852ba100SJustin Hibbits
798*852ba100SJustin Hibbits fman_memac_set_exception(p_Memac->p_MemMap, bitMask, enable);
799*852ba100SJustin Hibbits
800*852ba100SJustin Hibbits return E_OK;
801*852ba100SJustin Hibbits }
802*852ba100SJustin Hibbits
803*852ba100SJustin Hibbits /* ......................................................................... */
804*852ba100SJustin Hibbits
MemacGetMaxFrameLength(t_Handle h_Memac)805*852ba100SJustin Hibbits static uint16_t MemacGetMaxFrameLength(t_Handle h_Memac)
806*852ba100SJustin Hibbits {
807*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
808*852ba100SJustin Hibbits
809*852ba100SJustin Hibbits SANITY_CHECK_RETURN_VALUE(p_Memac, E_INVALID_HANDLE, 0);
810*852ba100SJustin Hibbits SANITY_CHECK_RETURN_VALUE(!p_Memac->p_MemacDriverParam, E_INVALID_STATE, 0);
811*852ba100SJustin Hibbits
812*852ba100SJustin Hibbits return fman_memac_get_max_frame_len(p_Memac->p_MemMap);
813*852ba100SJustin Hibbits }
814*852ba100SJustin Hibbits
MemacInitInternalPhy(t_Handle h_Memac)815*852ba100SJustin Hibbits static t_Error MemacInitInternalPhy(t_Handle h_Memac)
816*852ba100SJustin Hibbits {
817*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
818*852ba100SJustin Hibbits uint8_t i, phyAddr;
819*852ba100SJustin Hibbits
820*852ba100SJustin Hibbits if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_SGMII)
821*852ba100SJustin Hibbits {
822*852ba100SJustin Hibbits /* Configure internal SGMII PHY */
823*852ba100SJustin Hibbits if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
824*852ba100SJustin Hibbits SetupSgmiiInternalPhyBaseX(p_Memac, PHY_MDIO_ADDR);
825*852ba100SJustin Hibbits else
826*852ba100SJustin Hibbits SetupSgmiiInternalPhy(p_Memac, PHY_MDIO_ADDR);
827*852ba100SJustin Hibbits }
828*852ba100SJustin Hibbits else if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_QSGMII)
829*852ba100SJustin Hibbits {
830*852ba100SJustin Hibbits /* Configure 4 internal SGMII PHYs */
831*852ba100SJustin Hibbits for (i = 0; i < 4; i++)
832*852ba100SJustin Hibbits {
833*852ba100SJustin Hibbits /* QSGMII PHY address occupies 3 upper bits of 5-bit
834*852ba100SJustin Hibbits phyAddress; the lower 2 bits are used to extend
835*852ba100SJustin Hibbits register address space and access each one of 4
836*852ba100SJustin Hibbits ports inside QSGMII. */
837*852ba100SJustin Hibbits phyAddr = (uint8_t)((PHY_MDIO_ADDR << 2) | i);
838*852ba100SJustin Hibbits if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
839*852ba100SJustin Hibbits SetupSgmiiInternalPhyBaseX(p_Memac, phyAddr);
840*852ba100SJustin Hibbits else
841*852ba100SJustin Hibbits SetupSgmiiInternalPhy(p_Memac, phyAddr);
842*852ba100SJustin Hibbits }
843*852ba100SJustin Hibbits }
844*852ba100SJustin Hibbits return E_OK;
845*852ba100SJustin Hibbits }
846*852ba100SJustin Hibbits
847*852ba100SJustin Hibbits /*****************************************************************************/
848*852ba100SJustin Hibbits /* mEMAC Init & Free API */
849*852ba100SJustin Hibbits /*****************************************************************************/
850*852ba100SJustin Hibbits
851*852ba100SJustin Hibbits /* ......................................................................... */
852*852ba100SJustin Hibbits void *g_MemacRegs;
MemacInit(t_Handle h_Memac)853*852ba100SJustin Hibbits static t_Error MemacInit(t_Handle h_Memac)
854*852ba100SJustin Hibbits {
855*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
856*852ba100SJustin Hibbits struct memac_cfg *p_MemacDriverParam;
857*852ba100SJustin Hibbits enum enet_interface enet_interface;
858*852ba100SJustin Hibbits enum enet_speed enet_speed;
859*852ba100SJustin Hibbits t_EnetAddr ethAddr;
860*852ba100SJustin Hibbits e_FmMacType portType;
861*852ba100SJustin Hibbits t_Error err;
862*852ba100SJustin Hibbits bool slow_10g_if = FALSE;
863*852ba100SJustin Hibbits if (p_Memac->macId == 3) /* This is a quick WA */
864*852ba100SJustin Hibbits g_MemacRegs = p_Memac->p_MemMap;
865*852ba100SJustin Hibbits
866*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
867*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
868*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
869*852ba100SJustin Hibbits
870*852ba100SJustin Hibbits FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
871*852ba100SJustin Hibbits if (p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6 &&
872*852ba100SJustin Hibbits p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 4)
873*852ba100SJustin Hibbits slow_10g_if = TRUE;
874*852ba100SJustin Hibbits
875*852ba100SJustin Hibbits CHECK_INIT_PARAMETERS(p_Memac, CheckInitParameters);
876*852ba100SJustin Hibbits
877*852ba100SJustin Hibbits p_MemacDriverParam = p_Memac->p_MemacDriverParam;
878*852ba100SJustin Hibbits
879*852ba100SJustin Hibbits portType =
880*852ba100SJustin Hibbits ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
881*852ba100SJustin Hibbits
882*852ba100SJustin Hibbits /* First, reset the MAC if desired. */
883*852ba100SJustin Hibbits if (p_MemacDriverParam->reset_on_init)
884*852ba100SJustin Hibbits fman_memac_reset(p_Memac->p_MemMap);
885*852ba100SJustin Hibbits
886*852ba100SJustin Hibbits /* MAC Address */
887*852ba100SJustin Hibbits MAKE_ENET_ADDR_FROM_UINT64(p_Memac->addr, ethAddr);
888*852ba100SJustin Hibbits fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)ethAddr, 0);
889*852ba100SJustin Hibbits
890*852ba100SJustin Hibbits enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Memac->enetMode);
891*852ba100SJustin Hibbits enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Memac->enetMode);
892*852ba100SJustin Hibbits
893*852ba100SJustin Hibbits fman_memac_init(p_Memac->p_MemMap,
894*852ba100SJustin Hibbits p_Memac->p_MemacDriverParam,
895*852ba100SJustin Hibbits enet_interface,
896*852ba100SJustin Hibbits enet_speed,
897*852ba100SJustin Hibbits slow_10g_if,
898*852ba100SJustin Hibbits p_Memac->exceptions);
899*852ba100SJustin Hibbits
900*852ba100SJustin Hibbits #ifdef FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
901*852ba100SJustin Hibbits {
902*852ba100SJustin Hibbits uint32_t tmpReg = 0;
903*852ba100SJustin Hibbits
904*852ba100SJustin Hibbits FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
905*852ba100SJustin Hibbits /* check the FMAN version - the bug exists only in rev1 */
906*852ba100SJustin Hibbits if ((p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6) &&
907*852ba100SJustin Hibbits (p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 0))
908*852ba100SJustin Hibbits {
909*852ba100SJustin Hibbits /* MAC strips CRC from received frames - this workaround should
910*852ba100SJustin Hibbits decrease the likelihood of bug appearance
911*852ba100SJustin Hibbits */
912*852ba100SJustin Hibbits tmpReg = GET_UINT32(p_Memac->p_MemMap->command_config);
913*852ba100SJustin Hibbits tmpReg &= ~CMD_CFG_CRC_FWD;
914*852ba100SJustin Hibbits WRITE_UINT32(p_Memac->p_MemMap->command_config, tmpReg);
915*852ba100SJustin Hibbits /* DBG(WARNING, ("mEMAC strips CRC from received frames as part of A006320 errata workaround"));*/
916*852ba100SJustin Hibbits }
917*852ba100SJustin Hibbits }
918*852ba100SJustin Hibbits #endif /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 */
919*852ba100SJustin Hibbits
920*852ba100SJustin Hibbits MemacInitInternalPhy(h_Memac);
921*852ba100SJustin Hibbits
922*852ba100SJustin Hibbits /* Max Frame Length */
923*852ba100SJustin Hibbits err = FmSetMacMaxFrame(p_Memac->fmMacControllerDriver.h_Fm,
924*852ba100SJustin Hibbits portType,
925*852ba100SJustin Hibbits p_Memac->fmMacControllerDriver.macId,
926*852ba100SJustin Hibbits p_MemacDriverParam->max_frame_length);
927*852ba100SJustin Hibbits if (err)
928*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, err, ("settings Mac max frame length is FAILED"));
929*852ba100SJustin Hibbits
930*852ba100SJustin Hibbits p_Memac->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
931*852ba100SJustin Hibbits if (!p_Memac->p_MulticastAddrHash)
932*852ba100SJustin Hibbits {
933*852ba100SJustin Hibbits FreeInitResources(p_Memac);
934*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
935*852ba100SJustin Hibbits }
936*852ba100SJustin Hibbits
937*852ba100SJustin Hibbits p_Memac->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
938*852ba100SJustin Hibbits if (!p_Memac->p_UnicastAddrHash)
939*852ba100SJustin Hibbits {
940*852ba100SJustin Hibbits FreeInitResources(p_Memac);
941*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
942*852ba100SJustin Hibbits }
943*852ba100SJustin Hibbits
944*852ba100SJustin Hibbits FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
945*852ba100SJustin Hibbits (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
946*852ba100SJustin Hibbits p_Memac->macId,
947*852ba100SJustin Hibbits e_FM_INTR_TYPE_ERR,
948*852ba100SJustin Hibbits MemacErrException,
949*852ba100SJustin Hibbits p_Memac);
950*852ba100SJustin Hibbits
951*852ba100SJustin Hibbits FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
952*852ba100SJustin Hibbits (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
953*852ba100SJustin Hibbits p_Memac->macId,
954*852ba100SJustin Hibbits e_FM_INTR_TYPE_NORMAL,
955*852ba100SJustin Hibbits MemacException,
956*852ba100SJustin Hibbits p_Memac);
957*852ba100SJustin Hibbits
958*852ba100SJustin Hibbits XX_Free(p_MemacDriverParam);
959*852ba100SJustin Hibbits p_Memac->p_MemacDriverParam = NULL;
960*852ba100SJustin Hibbits
961*852ba100SJustin Hibbits return E_OK;
962*852ba100SJustin Hibbits }
963*852ba100SJustin Hibbits
964*852ba100SJustin Hibbits /* ......................................................................... */
965*852ba100SJustin Hibbits
MemacFree(t_Handle h_Memac)966*852ba100SJustin Hibbits static t_Error MemacFree(t_Handle h_Memac)
967*852ba100SJustin Hibbits {
968*852ba100SJustin Hibbits t_Memac *p_Memac = (t_Memac *)h_Memac;
969*852ba100SJustin Hibbits
970*852ba100SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
971*852ba100SJustin Hibbits
972*852ba100SJustin Hibbits if (p_Memac->p_MemacDriverParam)
973*852ba100SJustin Hibbits {
974*852ba100SJustin Hibbits /* Called after config */
975*852ba100SJustin Hibbits XX_Free(p_Memac->p_MemacDriverParam);
976*852ba100SJustin Hibbits p_Memac->p_MemacDriverParam = NULL;
977*852ba100SJustin Hibbits }
978*852ba100SJustin Hibbits else
979*852ba100SJustin Hibbits /* Called after init */
980*852ba100SJustin Hibbits FreeInitResources(p_Memac);
981*852ba100SJustin Hibbits
982*852ba100SJustin Hibbits XX_Free(p_Memac);
983*852ba100SJustin Hibbits
984*852ba100SJustin Hibbits return E_OK;
985*852ba100SJustin Hibbits }
986*852ba100SJustin Hibbits
987*852ba100SJustin Hibbits /* ......................................................................... */
988*852ba100SJustin Hibbits
InitFmMacControllerDriver(t_FmMacControllerDriver * p_FmMacControllerDriver)989*852ba100SJustin Hibbits static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
990*852ba100SJustin Hibbits {
991*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_Init = MemacInit;
992*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_Free = MemacFree;
993*852ba100SJustin Hibbits
994*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
995*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = MemacConfigLoopback;
996*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = MemacConfigMaxFrameLength;
997*852ba100SJustin Hibbits
998*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_ConfigWan = MemacConfigWan;
999*852ba100SJustin Hibbits
1000*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = MemacConfigPad;
1001*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is detected automatically */
1002*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = MemacConfigLengthCheck;
1003*852ba100SJustin Hibbits
1004*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_ConfigException = MemacConfigException;
1005*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = MemacConfigResetOnInit;
1006*852ba100SJustin Hibbits
1007*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_SetException = MemacSetException;
1008*852ba100SJustin Hibbits
1009*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = MemacEnable1588TimeStamp; /* always enabled */
1010*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = NULL;
1011*852ba100SJustin Hibbits
1012*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = MemacSetPromiscuous;
1013*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_AdjustLink = MemacAdjustLink;
1014*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
1015*852ba100SJustin Hibbits
1016*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_Enable = MemacEnable;
1017*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_Disable = MemacDisable;
1018*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_Resume = MemacInitInternalPhy;
1019*852ba100SJustin Hibbits
1020*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = MemacSetTxAutoPauseFrames;
1021*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = MemacSetTxPauseFrames;
1022*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = MemacSetRxIgnorePauseFrames;
1023*852ba100SJustin Hibbits
1024*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = MemacSetWakeOnLan;
1025*852ba100SJustin Hibbits
1026*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_ResetCounters = MemacResetCounters;
1027*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_GetStatistics = MemacGetStatistics;
1028*852ba100SJustin Hibbits
1029*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = MemacModifyMacAddress;
1030*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = MemacAddHashMacAddress;
1031*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = MemacDelHashMacAddress;
1032*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = MemacAddExactMatchMacAddress;
1033*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = MemacDelExactMatchMacAddress;
1034*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_GetId = MemacGetId;
1035*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_GetVersion = NULL;
1036*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = MemacGetMaxFrameLength;
1037*852ba100SJustin Hibbits
1038*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = MEMAC_MII_WritePhyReg;
1039*852ba100SJustin Hibbits p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = MEMAC_MII_ReadPhyReg;
1040*852ba100SJustin Hibbits }
1041*852ba100SJustin Hibbits
1042*852ba100SJustin Hibbits
1043*852ba100SJustin Hibbits /*****************************************************************************/
1044*852ba100SJustin Hibbits /* mEMAC Config Main Entry */
1045*852ba100SJustin Hibbits /*****************************************************************************/
1046*852ba100SJustin Hibbits
1047*852ba100SJustin Hibbits /* ......................................................................... */
1048*852ba100SJustin Hibbits
MEMAC_Config(t_FmMacParams * p_FmMacParam)1049*852ba100SJustin Hibbits t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam)
1050*852ba100SJustin Hibbits {
1051*852ba100SJustin Hibbits t_Memac *p_Memac;
1052*852ba100SJustin Hibbits struct memac_cfg *p_MemacDriverParam;
1053*852ba100SJustin Hibbits uintptr_t baseAddr;
1054*852ba100SJustin Hibbits
1055*852ba100SJustin Hibbits SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
1056*852ba100SJustin Hibbits
1057*852ba100SJustin Hibbits baseAddr = p_FmMacParam->baseAddr;
1058*852ba100SJustin Hibbits /* Allocate memory for the mEMAC data structure */
1059*852ba100SJustin Hibbits p_Memac = (t_Memac *)XX_Malloc(sizeof(t_Memac));
1060*852ba100SJustin Hibbits if (!p_Memac)
1061*852ba100SJustin Hibbits {
1062*852ba100SJustin Hibbits REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver structure"));
1063*852ba100SJustin Hibbits return NULL;
1064*852ba100SJustin Hibbits }
1065*852ba100SJustin Hibbits memset(p_Memac, 0, sizeof(t_Memac));
1066*852ba100SJustin Hibbits InitFmMacControllerDriver(&p_Memac->fmMacControllerDriver);
1067*852ba100SJustin Hibbits
1068*852ba100SJustin Hibbits /* Allocate memory for the mEMAC driver parameters data structure */
1069*852ba100SJustin Hibbits p_MemacDriverParam = (struct memac_cfg *)XX_Malloc(sizeof(struct memac_cfg));
1070*852ba100SJustin Hibbits if (!p_MemacDriverParam)
1071*852ba100SJustin Hibbits {
1072*852ba100SJustin Hibbits REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver parameters"));
1073*852ba100SJustin Hibbits XX_Free(p_Memac);
1074*852ba100SJustin Hibbits return NULL;
1075*852ba100SJustin Hibbits }
1076*852ba100SJustin Hibbits memset(p_MemacDriverParam, 0, sizeof(struct memac_cfg));
1077*852ba100SJustin Hibbits
1078*852ba100SJustin Hibbits /* Plant parameter structure pointer */
1079*852ba100SJustin Hibbits p_Memac->p_MemacDriverParam = p_MemacDriverParam;
1080*852ba100SJustin Hibbits
1081*852ba100SJustin Hibbits fman_memac_defconfig(p_MemacDriverParam);
1082*852ba100SJustin Hibbits
1083*852ba100SJustin Hibbits p_Memac->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
1084*852ba100SJustin Hibbits
1085*852ba100SJustin Hibbits p_Memac->p_MemMap = (struct memac_regs *)UINT_TO_PTR(baseAddr);
1086*852ba100SJustin Hibbits p_Memac->p_MiiMemMap = (struct memac_mii_access_mem_map*)UINT_TO_PTR(baseAddr + MEMAC_TO_MII_OFFSET);
1087*852ba100SJustin Hibbits
1088*852ba100SJustin Hibbits p_Memac->enetMode = p_FmMacParam->enetMode;
1089*852ba100SJustin Hibbits p_Memac->macId = p_FmMacParam->macId;
1090*852ba100SJustin Hibbits p_Memac->exceptions = MEMAC_default_exceptions;
1091*852ba100SJustin Hibbits p_Memac->f_Exception = p_FmMacParam->f_Exception;
1092*852ba100SJustin Hibbits p_Memac->f_Event = p_FmMacParam->f_Event;
1093*852ba100SJustin Hibbits p_Memac->h_App = p_FmMacParam->h_App;
1094*852ba100SJustin Hibbits
1095*852ba100SJustin Hibbits return p_Memac;
1096*852ba100SJustin Hibbits }
1097