xref: /freebsd/sys/contrib/ncsw/Peripherals/FM/MAC/memac.c (revision c2c014f24c10f90d85126ac5fbd4d8524de32b1c)
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