1 /* $Id: xemacps_control.c,v 1.1.2.1 2011/01/20 03:39:02 sadanan Exp $ */
2 /******************************************************************************
4 * Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * Use of the Software is limited solely to applications:
17 * (a) running on a Xilinx device, or
18 * (b) that interact with a Xilinx device through a bus or interconnect.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
25 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 * Except as contained in this notice, the name of the Xilinx shall not be used
29 * in advertising or otherwise to promote the sale, use or other dealings in
30 * this Software without prior written authorization from Xilinx.
32 ******************************************************************************/
33 /*****************************************************************************/
36 * @file xemacps_control.c
37 * @addtogroup emacps_v2_0
40 * Functions in this file implement general purpose command and control related
41 * functionality. See xemacps.h for a detailed description of the driver.
44 * MODIFICATION HISTORY:
46 * Ver Who Date Changes
47 * ----- ---- -------- -------------------------------------------------------
48 * 1.00a wsy 01/10/10 First release
49 * 1.02a asa 11/05/12 Added a new API for deleting an entry from the HASH
50 * register. Added a new API for setting the BURST length
53 *****************************************************************************/
55 /***************************** Include Files *********************************/
59 /************************** Constant Definitions *****************************/
62 /**************************** Type Definitions *******************************/
65 /***************** Macros (Inline Functions) Definitions *********************/
68 /************************** Function Prototypes ******************************/
71 /************************** Variable Definitions *****************************/
74 /*****************************************************************************/
76 * Set the MAC address for this driver/device. The address is a 48-bit value.
77 * The device must be stopped before calling this function.
79 * @param InstancePtr is a pointer to the instance to be worked on.
80 * @param AddressPtr is a pointer to a 6-byte MAC address.
81 * @param Index is a index to which MAC (1-4) address.
84 * - XST_SUCCESS if the MAC address was set successfully
85 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
87 *****************************************************************************/
88 int XEmacPs_SetMacAddress(XEmacPs *InstancePtr, void *AddressPtr, u8 Index)
91 u8 *Aptr = (u8 *) AddressPtr;
93 Xil_AssertNonvoid(InstancePtr != NULL);
94 Xil_AssertNonvoid(AddressPtr != NULL);
95 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
96 Xil_AssertNonvoid((Index <= XEMACPS_MAX_MAC_ADDR) && (Index > 0));
98 /* Be sure device has been stopped */
99 if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
100 return (XST_DEVICE_IS_STARTED);
103 /* Index ranges 1 to 4, for offset calculation is 0 to 3. */
106 /* Set the MAC bits [31:0] in BOT */
108 MacAddr |= Aptr[1] << 8;
109 MacAddr |= Aptr[2] << 16;
110 MacAddr |= Aptr[3] << 24;
111 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
112 (XEMACPS_LADDR1L_OFFSET + Index * 8), MacAddr);
114 /* There are reserved bits in TOP so don't affect them */
115 MacAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
116 (XEMACPS_LADDR1H_OFFSET + (Index * 8)));
118 MacAddr &= ~XEMACPS_LADDR_MACH_MASK;
120 /* Set MAC bits [47:32] in TOP */
122 MacAddr |= Aptr[5] << 8;
124 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
125 (XEMACPS_LADDR1H_OFFSET + (Index * 8)), MacAddr);
127 return (XST_SUCCESS);
131 /*****************************************************************************/
133 * Get the MAC address for this driver/device.
135 * @param InstancePtr is a pointer to the instance to be worked on.
136 * @param AddressPtr is an output parameter, and is a pointer to a buffer into
137 * which the current MAC address will be copied.
138 * @param Index is a index to which MAC (1-4) address.
140 *****************************************************************************/
141 void XEmacPs_GetMacAddress(XEmacPs *InstancePtr, void *AddressPtr, u8 Index)
144 u8 *Aptr = (u8 *) AddressPtr;
146 Xil_AssertVoid(InstancePtr != NULL);
147 Xil_AssertVoid(AddressPtr != NULL);
148 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
149 Xil_AssertVoid((Index <= XEMACPS_MAX_MAC_ADDR) && (Index > 0));
151 /* Index ranges 1 to 4, for offset calculation is 0 to 3. */
154 MacAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
155 (XEMACPS_LADDR1L_OFFSET + (Index * 8)));
156 Aptr[0] = (u8) MacAddr;
157 Aptr[1] = (u8) (MacAddr >> 8);
158 Aptr[2] = (u8) (MacAddr >> 16);
159 Aptr[3] = (u8) (MacAddr >> 24);
161 /* Read MAC bits [47:32] in TOP */
162 MacAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
163 (XEMACPS_LADDR1H_OFFSET + (Index * 8)));
164 Aptr[4] = (u8) MacAddr;
165 Aptr[5] = (u8) (MacAddr >> 8);
169 /*****************************************************************************/
171 * Set 48-bit MAC addresses in hash table.
172 * The device must be stopped before calling this function.
174 * The hash address register is 64 bits long and takes up two locations in
175 * the memory map. The least significant bits are stored in hash register
176 * bottom and the most significant bits in hash register top.
178 * The unicast hash enable and the multicast hash enable bits in the network
179 * configuration register enable the reception of hash matched frames. The
180 * destination address is reduced to a 6 bit index into the 64 bit hash
181 * register using the following hash function. The hash function is an XOR
182 * of every sixth bit of the destination address.
185 * hash_index[05] = da[05]^da[11]^da[17]^da[23]^da[29]^da[35]^da[41]^da[47]
186 * hash_index[04] = da[04]^da[10]^da[16]^da[22]^da[28]^da[34]^da[40]^da[46]
187 * hash_index[03] = da[03]^da[09]^da[15]^da[21]^da[27]^da[33]^da[39]^da[45]
188 * hash_index[02] = da[02]^da[08]^da[14]^da[20]^da[26]^da[32]^da[38]^da[44]
189 * hash_index[01] = da[01]^da[07]^da[13]^da[19]^da[25]^da[31]^da[37]^da[43]
190 * hash_index[00] = da[00]^da[06]^da[12]^da[18]^da[24]^da[30]^da[36]^da[42]
193 * da[0] represents the least significant bit of the first byte received,
194 * that is, the multicast/unicast indicator, and da[47] represents the most
195 * significant bit of the last byte received.
197 * If the hash index points to a bit that is set in the hash register then
198 * the frame will be matched according to whether the frame is multicast
201 * A multicast match will be signaled if the multicast hash enable bit is
202 * set, da[0] is logic 1 and the hash index points to a bit set in the hash
205 * A unicast match will be signaled if the unicast hash enable bit is set,
206 * da[0] is logic 0 and the hash index points to a bit set in the hash
209 * To receive all multicast frames, the hash register should be set with
210 * all ones and the multicast hash enable bit should be set in the network
211 * configuration register.
214 * @param InstancePtr is a pointer to the instance to be worked on.
215 * @param AddressPtr is a pointer to a 6-byte MAC address.
218 * - XST_SUCCESS if the HASH MAC address was set successfully
219 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
220 * - XST_INVALID_PARAM if the HASH MAC address passed in does not meet
221 * requirement after calculation
224 * Having Aptr be unsigned type prevents the following operations from sign
226 *****************************************************************************/
227 int XEmacPs_SetHash(XEmacPs *InstancePtr, void *AddressPtr)
230 u8 *Aptr = (u8 *) AddressPtr;
231 u8 Temp1, Temp2, Temp3, Temp4, Temp5, Temp6, Temp7, Temp8;
234 Xil_AssertNonvoid(InstancePtr != NULL);
235 Xil_AssertNonvoid(AddressPtr != NULL);
236 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
238 /* Be sure device has been stopped */
239 if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
240 return (XST_DEVICE_IS_STARTED);
242 Temp1 = Aptr[0] & 0x3F;
243 Temp2 = ((Aptr[0] >> 6) & 0x3) | ((Aptr[1] & 0xF) << 2);
244 Temp3 = ((Aptr[1] >> 4) & 0xF) | ((Aptr[2] & 0x3) << 4);
245 Temp4 = ((Aptr[2] >> 2) & 0x3F);
246 Temp5 = Aptr[3] & 0x3F;
247 Temp6 = ((Aptr[3] >> 6) & 0x3) | ((Aptr[4] & 0xF) << 2);
248 Temp7 = ((Aptr[4] >> 4) & 0xF) | ((Aptr[5] & 0x3) << 4);
249 Temp8 = ((Aptr[5] >> 2) & 0x3F);
251 Result = Temp1 ^ Temp2 ^ Temp3 ^ Temp4 ^ Temp5 ^ Temp6 ^ Temp7 ^ Temp8;
253 if (Result >= XEMACPS_MAX_HASH_BITS) {
254 return (XST_INVALID_PARAM);
258 HashAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
259 XEMACPS_HASHL_OFFSET);
260 HashAddr |= (1 << Result);
261 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
262 XEMACPS_HASHL_OFFSET, HashAddr);
264 HashAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
265 XEMACPS_HASHH_OFFSET);
266 HashAddr |= (1 << (Result - 32));
267 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
268 XEMACPS_HASHH_OFFSET, HashAddr);
271 return (XST_SUCCESS);
274 /*****************************************************************************/
276 * Delete 48-bit MAC addresses in hash table.
277 * The device must be stopped before calling this function.
279 * @param InstancePtr is a pointer to the instance to be worked on.
280 * @param AddressPtr is a pointer to a 6-byte MAC address.
283 * - XST_SUCCESS if the HASH MAC address was deleted successfully
284 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
285 * - XST_INVALID_PARAM if the HASH MAC address passed in does not meet
286 * requirement after calculation
289 * Having Aptr be unsigned type prevents the following operations from sign
291 *****************************************************************************/
292 int XEmacPs_DeleteHash(XEmacPs *InstancePtr, void *AddressPtr)
295 u8 *Aptr = (u8 *) AddressPtr;
296 u8 Temp1, Temp2, Temp3, Temp4, Temp5, Temp6, Temp7, Temp8;
299 Xil_AssertNonvoid(InstancePtr != NULL);
300 Xil_AssertNonvoid(AddressPtr != NULL);
301 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
303 /* Be sure device has been stopped */
304 if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
305 return (XST_DEVICE_IS_STARTED);
307 Temp1 = Aptr[0] & 0x3F;
308 Temp2 = ((Aptr[0] >> 6) & 0x3) | ((Aptr[1] & 0xF) << 2);
309 Temp3 = ((Aptr[1] >> 4) & 0xF) | ((Aptr[2] & 0x3) << 4);
310 Temp4 = ((Aptr[2] >> 2) & 0x3F);
311 Temp5 = Aptr[3] & 0x3F;
312 Temp6 = ((Aptr[3] >> 6) & 0x3) | ((Aptr[4] & 0xF) << 2);
313 Temp7 = ((Aptr[4] >> 4) & 0xF) | ((Aptr[5] & 0x3) << 4);
314 Temp8 = ((Aptr[5] >> 2) & 0x3F);
316 Result = Temp1 ^ Temp2 ^ Temp3 ^ Temp4 ^ Temp5 ^ Temp6 ^ Temp7 ^ Temp8;
318 if (Result >= XEMACPS_MAX_HASH_BITS) {
319 return (XST_INVALID_PARAM);
323 HashAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
324 XEMACPS_HASHL_OFFSET);
325 HashAddr &= (~(1 << Result));
326 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
327 XEMACPS_HASHL_OFFSET, HashAddr);
329 HashAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
330 XEMACPS_HASHH_OFFSET);
331 HashAddr &= (~(1 << (Result - 32)));
332 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
333 XEMACPS_HASHH_OFFSET, HashAddr);
336 return (XST_SUCCESS);
340 /*****************************************************************************/
342 * Clear the Hash registers for the mac address pointed by AddressPtr.
344 * @param InstancePtr is a pointer to the instance to be worked on.
346 *****************************************************************************/
347 void XEmacPs_ClearHash(XEmacPs *InstancePtr)
349 Xil_AssertVoid(InstancePtr != NULL);
350 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
352 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
353 XEMACPS_HASHL_OFFSET, 0x0);
355 /* write bits [63:32] in TOP */
356 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
357 XEMACPS_HASHH_OFFSET, 0x0);
361 /*****************************************************************************/
363 * Get the Hash address for this driver/device.
365 * @param InstancePtr is a pointer to the instance to be worked on.
366 * @param AddressPtr is an output parameter, and is a pointer to a buffer into
367 * which the current HASH MAC address will be copied.
369 *****************************************************************************/
370 void XEmacPs_GetHash(XEmacPs *InstancePtr, void *AddressPtr)
372 u32 *Aptr = (u32 *) AddressPtr;
374 Xil_AssertVoid(InstancePtr != NULL);
375 Xil_AssertVoid(AddressPtr != NULL);
376 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
378 Aptr[0] = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
379 XEMACPS_HASHL_OFFSET);
381 /* Read Hash bits [63:32] in TOP */
382 Aptr[1] = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
383 XEMACPS_HASHH_OFFSET);
387 /*****************************************************************************/
389 * Set the Type ID match for this driver/device. The register is a 32-bit
390 * value. The device must be stopped before calling this function.
392 * @param InstancePtr is a pointer to the instance to be worked on.
393 * @param Id_Check is type ID to be configured.
394 * @param Index is a index to which Type ID (1-4).
397 * - XST_SUCCESS if the MAC address was set successfully
398 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
400 *****************************************************************************/
401 int XEmacPs_SetTypeIdCheck(XEmacPs *InstancePtr, u32 Id_Check, u8 Index)
403 Xil_AssertNonvoid(InstancePtr != NULL);
404 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
405 Xil_AssertNonvoid((Index <= XEMACPS_MAX_TYPE_ID) && (Index > 0));
407 /* Be sure device has been stopped */
408 if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
409 return (XST_DEVICE_IS_STARTED);
412 /* Index ranges 1 to 4, for offset calculation is 0 to 3. */
415 /* Set the ID bits in MATCHx register */
416 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
417 (XEMACPS_MATCH1_OFFSET + (Index * 4)), Id_Check);
419 return (XST_SUCCESS);
422 /*****************************************************************************/
424 * Set options for the driver/device. The driver should be stopped with
425 * XEmacPs_Stop() before changing options.
427 * @param InstancePtr is a pointer to the instance to be worked on.
428 * @param Options are the options to set. Multiple options can be set by OR'ing
429 * XTE_*_OPTIONS constants together. Options not specified are not
433 * - XST_SUCCESS if the options were set successfully
434 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
437 * See xemacps.h for a description of the available options.
439 *****************************************************************************/
440 int XEmacPs_SetOptions(XEmacPs *InstancePtr, u32 Options)
442 u32 Reg; /* Generic register contents */
443 u32 RegNetCfg; /* Reflects original contents of NET_CONFIG */
444 u32 RegNewNetCfg; /* Reflects new contents of NET_CONFIG */
446 Xil_AssertNonvoid(InstancePtr != NULL);
447 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
449 /* Be sure device has been stopped */
450 if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
451 return (XST_DEVICE_IS_STARTED);
454 /* Many of these options will change the NET_CONFIG registers.
455 * To reduce the amount of IO to the device, group these options here
456 * and change them all at once.
459 /* Grab current register contents */
460 RegNetCfg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
461 XEMACPS_NWCFG_OFFSET);
462 RegNewNetCfg = RegNetCfg;
465 * It is configured to max 1536.
467 if (Options & XEMACPS_FRAME1536_OPTION) {
468 RegNewNetCfg |= (XEMACPS_NWCFG_1536RXEN_MASK);
471 /* Turn on VLAN packet only, only VLAN tagged will be accepted */
472 if (Options & XEMACPS_VLAN_OPTION) {
473 RegNewNetCfg |= XEMACPS_NWCFG_NVLANDISC_MASK;
476 /* Turn on FCS stripping on receive packets */
477 if (Options & XEMACPS_FCS_STRIP_OPTION) {
478 RegNewNetCfg |= XEMACPS_NWCFG_FCSREM_MASK;
481 /* Turn on length/type field checking on receive packets */
482 if (Options & XEMACPS_LENTYPE_ERR_OPTION) {
483 RegNewNetCfg |= XEMACPS_NWCFG_LENGTHERRDSCRD_MASK;
486 /* Turn on flow control */
487 if (Options & XEMACPS_FLOW_CONTROL_OPTION) {
488 RegNewNetCfg |= XEMACPS_NWCFG_PAUSEEN_MASK;
491 /* Turn on promiscuous frame filtering (all frames are received) */
492 if (Options & XEMACPS_PROMISC_OPTION) {
493 RegNewNetCfg |= XEMACPS_NWCFG_COPYALLEN_MASK;
496 /* Allow broadcast address reception */
497 if (Options & XEMACPS_BROADCAST_OPTION) {
498 RegNewNetCfg &= ~XEMACPS_NWCFG_BCASTDI_MASK;
501 /* Allow multicast address filtering */
502 if (Options & XEMACPS_MULTICAST_OPTION) {
503 RegNewNetCfg |= XEMACPS_NWCFG_MCASTHASHEN_MASK;
506 /* enable RX checksum offload */
507 if (Options & XEMACPS_RX_CHKSUM_ENABLE_OPTION) {
508 RegNewNetCfg |= XEMACPS_NWCFG_RXCHKSUMEN_MASK;
511 /* Officially change the NET_CONFIG registers if it needs to be
514 if (RegNetCfg != RegNewNetCfg) {
515 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
516 XEMACPS_NWCFG_OFFSET, RegNewNetCfg);
519 /* Enable TX checksum offload */
520 if (Options & XEMACPS_TX_CHKSUM_ENABLE_OPTION) {
521 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
522 XEMACPS_DMACR_OFFSET);
523 Reg |= XEMACPS_DMACR_TCPCKSUM_MASK;
524 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
525 XEMACPS_DMACR_OFFSET, Reg);
528 /* Enable transmitter */
529 if (Options & XEMACPS_TRANSMITTER_ENABLE_OPTION) {
530 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
531 XEMACPS_NWCTRL_OFFSET);
532 Reg |= XEMACPS_NWCTRL_TXEN_MASK;
533 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
534 XEMACPS_NWCTRL_OFFSET, Reg);
537 /* Enable receiver */
538 if (Options & XEMACPS_RECEIVER_ENABLE_OPTION) {
539 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
540 XEMACPS_NWCTRL_OFFSET);
541 Reg |= XEMACPS_NWCTRL_RXEN_MASK;
542 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
543 XEMACPS_NWCTRL_OFFSET, Reg);
546 /* The remaining options not handled here are managed elsewhere in the
547 * driver. No register modifications are needed at this time. Reflecting
548 * the option in InstancePtr->Options is good enough for now.
551 /* Set options word to its new value */
552 InstancePtr->Options |= Options;
554 return (XST_SUCCESS);
558 /*****************************************************************************/
560 * Clear options for the driver/device
562 * @param InstancePtr is a pointer to the instance to be worked on.
563 * @param Options are the options to clear. Multiple options can be cleared by
564 * OR'ing XEMACPS_*_OPTIONS constants together. Options not specified
568 * - XST_SUCCESS if the options were set successfully
569 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
572 * See xemacps.h for a description of the available options.
574 *****************************************************************************/
575 int XEmacPs_ClearOptions(XEmacPs *InstancePtr, u32 Options)
577 u32 Reg; /* Generic */
578 u32 RegNetCfg; /* Reflects original contents of NET_CONFIG */
579 u32 RegNewNetCfg; /* Reflects new contents of NET_CONFIG */
581 Xil_AssertNonvoid(InstancePtr != NULL);
582 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
584 /* Be sure device has been stopped */
585 if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
586 return (XST_DEVICE_IS_STARTED);
589 /* Many of these options will change the NET_CONFIG registers.
590 * To reduce the amount of IO to the device, group these options here
591 * and change them all at once.
594 /* Grab current register contents */
595 RegNetCfg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
596 XEMACPS_NWCFG_OFFSET);
597 RegNewNetCfg = RegNetCfg;
599 /* There is only RX configuration!?
600 * It is configured in two different length, upto 1536 and 10240 bytes
602 if (Options & XEMACPS_FRAME1536_OPTION) {
603 RegNewNetCfg &= ~XEMACPS_NWCFG_1536RXEN_MASK;
606 /* Turn off VLAN packet only */
607 if (Options & XEMACPS_VLAN_OPTION) {
608 RegNewNetCfg &= ~XEMACPS_NWCFG_NVLANDISC_MASK;
611 /* Turn off FCS stripping on receive packets */
612 if (Options & XEMACPS_FCS_STRIP_OPTION) {
613 RegNewNetCfg &= ~XEMACPS_NWCFG_FCSREM_MASK;
616 /* Turn off length/type field checking on receive packets */
617 if (Options & XEMACPS_LENTYPE_ERR_OPTION) {
618 RegNewNetCfg &= ~XEMACPS_NWCFG_LENGTHERRDSCRD_MASK;
621 /* Turn off flow control */
622 if (Options & XEMACPS_FLOW_CONTROL_OPTION) {
623 RegNewNetCfg &= ~XEMACPS_NWCFG_PAUSEEN_MASK;
626 /* Turn off promiscuous frame filtering (all frames are received) */
627 if (Options & XEMACPS_PROMISC_OPTION) {
628 RegNewNetCfg &= ~XEMACPS_NWCFG_COPYALLEN_MASK;
631 /* Disallow broadcast address filtering => broadcast reception */
632 if (Options & XEMACPS_BROADCAST_OPTION) {
633 RegNewNetCfg |= XEMACPS_NWCFG_BCASTDI_MASK;
636 /* Disallow multicast address filtering */
637 if (Options & XEMACPS_MULTICAST_OPTION) {
638 RegNewNetCfg &= ~XEMACPS_NWCFG_MCASTHASHEN_MASK;
641 /* Disable RX checksum offload */
642 if (Options & XEMACPS_RX_CHKSUM_ENABLE_OPTION) {
643 RegNewNetCfg &= ~XEMACPS_NWCFG_RXCHKSUMEN_MASK;
646 /* Officially change the NET_CONFIG registers if it needs to be
649 if (RegNetCfg != RegNewNetCfg) {
650 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
651 XEMACPS_NWCFG_OFFSET, RegNewNetCfg);
654 /* Disable TX checksum offload */
655 if (Options & XEMACPS_TX_CHKSUM_ENABLE_OPTION) {
656 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
657 XEMACPS_DMACR_OFFSET);
658 Reg &= ~XEMACPS_DMACR_TCPCKSUM_MASK;
659 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
660 XEMACPS_DMACR_OFFSET, Reg);
663 /* Disable transmitter */
664 if (Options & XEMACPS_TRANSMITTER_ENABLE_OPTION) {
665 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
666 XEMACPS_NWCTRL_OFFSET);
667 Reg &= ~XEMACPS_NWCTRL_TXEN_MASK;
668 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
669 XEMACPS_NWCTRL_OFFSET, Reg);
672 /* Disable receiver */
673 if (Options & XEMACPS_RECEIVER_ENABLE_OPTION) {
674 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
675 XEMACPS_NWCTRL_OFFSET);
676 Reg &= ~XEMACPS_NWCTRL_RXEN_MASK;
677 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
678 XEMACPS_NWCTRL_OFFSET, Reg);
681 /* The remaining options not handled here are managed elsewhere in the
682 * driver. No register modifications are needed at this time. Reflecting
683 * option in InstancePtr->Options is good enough for now.
686 /* Set options word to its new value */
687 InstancePtr->Options &= ~Options;
689 return (XST_SUCCESS);
693 /*****************************************************************************/
695 * Get current option settings
697 * @param InstancePtr is a pointer to the instance to be worked on.
700 * A bitmask of XTE_*_OPTION constants. Any bit set to 1 is to be interpreted
704 * See xemacps.h for a description of the available options.
706 *****************************************************************************/
707 u32 XEmacPs_GetOptions(XEmacPs *InstancePtr)
709 Xil_AssertNonvoid(InstancePtr != NULL);
710 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
712 return (InstancePtr->Options);
716 /*****************************************************************************/
718 * Send a pause packet
720 * @param InstancePtr is a pointer to the instance to be worked on.
723 * - XST_SUCCESS if pause frame transmission was initiated
724 * - XST_DEVICE_IS_STOPPED if the device has not been started.
726 *****************************************************************************/
727 int XEmacPs_SendPausePacket(XEmacPs *InstancePtr)
731 Xil_AssertNonvoid(InstancePtr != NULL);
732 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
734 /* Make sure device is ready for this operation */
735 if (InstancePtr->IsStarted != XIL_COMPONENT_IS_STARTED) {
736 return (XST_DEVICE_IS_STOPPED);
739 /* Send flow control frame */
740 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
741 XEMACPS_NWCTRL_OFFSET);
742 Reg |= XEMACPS_NWCTRL_PAUSETX_MASK;
743 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
744 XEMACPS_NWCTRL_OFFSET, Reg);
745 return (XST_SUCCESS);
748 /*****************************************************************************/
750 * XEmacPs_GetOperatingSpeed gets the current operating link speed. This may
751 * be the value set by XEmacPs_SetOperatingSpeed() or a hardware default.
753 * @param InstancePtr references the TEMAC channel on which to operate.
755 * @return XEmacPs_GetOperatingSpeed returns the link speed in units of
756 * megabits per second.
760 *****************************************************************************/
761 u16 XEmacPs_GetOperatingSpeed(XEmacPs *InstancePtr)
765 Xil_AssertNonvoid(InstancePtr != NULL);
766 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
768 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
769 XEMACPS_NWCFG_OFFSET);
771 if (Reg & XEMACPS_NWCFG_1000_MASK) {
774 if (Reg & XEMACPS_NWCFG_100_MASK) {
783 /*****************************************************************************/
785 * XEmacPs_SetOperatingSpeed sets the current operating link speed. For any
786 * traffic to be passed, this speed must match the current MII/GMII/SGMII/RGMII
789 * @param InstancePtr references the TEMAC channel on which to operate.
790 * @param Speed is the speed to set in units of Mbps. Valid values are 10, 100,
791 * or 1000. XEmacPs_SetOperatingSpeed ignores invalid values.
795 *****************************************************************************/
796 void XEmacPs_SetOperatingSpeed(XEmacPs *InstancePtr, u16 Speed)
800 Xil_AssertVoid(InstancePtr != NULL);
801 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
802 Xil_AssertVoid((Speed == 10) || (Speed == 100) || (Speed == 1000));
804 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
805 XEMACPS_NWCFG_OFFSET);
806 Reg &= ~(XEMACPS_NWCFG_1000_MASK | XEMACPS_NWCFG_100_MASK);
813 Reg |= XEMACPS_NWCFG_100_MASK;
817 Reg |= XEMACPS_NWCFG_1000_MASK;
824 /* Set register and return */
825 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
826 XEMACPS_NWCFG_OFFSET, Reg);
830 /*****************************************************************************/
832 * Set the MDIO clock divisor.
834 * Calculating the divisor:
838 * f[MDC] = -----------------
842 * where f[HOSTCLK] is the bus clock frequency in MHz, and f[MDC] is the
843 * MDIO clock frequency in MHz to the PHY. Typically, f[MDC] should not
844 * exceed 2.5 MHz. Some PHYs can tolerate faster speeds which means faster
845 * access. Here is the table to show values to generate MDC,
848 * 000 : divide pclk by 8 (pclk up to 20 MHz)
849 * 001 : divide pclk by 16 (pclk up to 40 MHz)
850 * 010 : divide pclk by 32 (pclk up to 80 MHz)
851 * 011 : divide pclk by 48 (pclk up to 120 MHz)
852 * 100 : divide pclk by 64 (pclk up to 160 MHz)
853 * 101 : divide pclk by 96 (pclk up to 240 MHz)
854 * 110 : divide pclk by 128 (pclk up to 320 MHz)
855 * 111 : divide pclk by 224 (pclk up to 540 MHz)
858 * @param InstancePtr is a pointer to the instance to be worked on.
859 * @param Divisor is the divisor to set. Range is 0b000 to 0b111.
861 *****************************************************************************/
862 void XEmacPs_SetMdioDivisor(XEmacPs *InstancePtr, XEmacPs_MdcDiv Divisor)
866 Xil_AssertVoid(InstancePtr != NULL);
867 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
868 Xil_AssertVoid(Divisor <= 0x7); /* only last three bits are valid */
870 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
871 XEMACPS_NWCFG_OFFSET);
872 /* clear these three bits, could be done with mask */
873 Reg &= ~XEMACPS_NWCFG_MDCCLKDIV_MASK;
875 Reg |= (Divisor << XEMACPS_NWCFG_MDC_SHIFT_MASK);
877 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
878 XEMACPS_NWCFG_OFFSET, Reg);
883 /*****************************************************************************/
885 * Read the current value of the PHY register indicated by the PhyAddress and
886 * the RegisterNum parameters. The MAC provides the driver with the ability to
887 * talk to a PHY that adheres to the Media Independent Interface (MII) as
888 * defined in the IEEE 802.3 standard.
890 * Prior to PHY access with this function, the user should have setup the MDIO
891 * clock with XEmacPs_SetMdioDivisor().
893 * @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
894 * @param PhyAddress is the address of the PHY to be read (supports multiple
896 * @param RegisterNum is the register number, 0-31, of the specific PHY register
898 * @param PhyDataPtr is an output parameter, and points to a 16-bit buffer into
899 * which the current value of the register will be copied.
903 * - XST_SUCCESS if the PHY was read from successfully
904 * - XST_EMAC_MII_BUSY if there is another PHY operation in progress
908 * This function is not thread-safe. The user must provide mutually exclusive
909 * access to this function if there are to be multiple threads that can call it.
911 * There is the possibility that this function will not return if the hardware
912 * is broken (i.e., it never sets the status bit indicating that the read is
913 * done). If this is of concern to the user, the user should provide a mechanism
914 * suitable to their needs for recovery.
916 * For the duration of this function, all host interface reads and writes are
917 * blocked to the current XEmacPs instance.
919 ******************************************************************************/
920 int XEmacPs_PhyRead(XEmacPs *InstancePtr, u32 PhyAddress,
921 u32 RegisterNum, u16 *PhyDataPtr)
926 Xil_AssertNonvoid(InstancePtr != NULL);
928 /* Make sure no other PHY operation is currently in progress */
929 if (!(XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
930 XEMACPS_NWSR_OFFSET) &
931 XEMACPS_NWSR_MDIOIDLE_MASK)) {
932 return (XST_EMAC_MII_BUSY);
935 /* Construct Mgtcr mask for the operation */
936 Mgtcr = XEMACPS_PHYMNTNC_OP_MASK | XEMACPS_PHYMNTNC_OP_R_MASK |
937 (PhyAddress << XEMACPS_PHYMNTNC_PHYAD_SHIFT_MASK) |
938 (RegisterNum << XEMACPS_PHYMNTNC_PHREG_SHIFT_MASK);
940 /* Write Mgtcr and wait for completion */
941 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
942 XEMACPS_PHYMNTNC_OFFSET, Mgtcr);
945 Ipisr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
946 XEMACPS_NWSR_OFFSET);
947 } while ((Ipisr & XEMACPS_NWSR_MDIOIDLE_MASK) == 0);
950 *PhyDataPtr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
951 XEMACPS_PHYMNTNC_OFFSET);
953 return (XST_SUCCESS);
957 /*****************************************************************************/
959 * Write data to the specified PHY register. The Ethernet driver does not
960 * require the device to be stopped before writing to the PHY. Although it is
961 * probably a good idea to stop the device, it is the responsibility of the
962 * application to deem this necessary. The MAC provides the driver with the
963 * ability to talk to a PHY that adheres to the Media Independent Interface
964 * (MII) as defined in the IEEE 802.3 standard.
966 * Prior to PHY access with this function, the user should have setup the MDIO
967 * clock with XEmacPs_SetMdioDivisor().
969 * @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
970 * @param PhyAddress is the address of the PHY to be written (supports multiple
972 * @param RegisterNum is the register number, 0-31, of the specific PHY register
974 * @param PhyData is the 16-bit value that will be written to the register
978 * - XST_SUCCESS if the PHY was written to successfully. Since there is no error
979 * status from the MAC on a write, the user should read the PHY to verify the
980 * write was successful.
981 * - XST_EMAC_MII_BUSY if there is another PHY operation in progress
985 * This function is not thread-safe. The user must provide mutually exclusive
986 * access to this function if there are to be multiple threads that can call it.
988 * There is the possibility that this function will not return if the hardware
989 * is broken (i.e., it never sets the status bit indicating that the write is
990 * done). If this is of concern to the user, the user should provide a mechanism
991 * suitable to their needs for recovery.
993 * For the duration of this function, all host interface reads and writes are
994 * blocked to the current XEmacPs instance.
996 ******************************************************************************/
997 int XEmacPs_PhyWrite(XEmacPs *InstancePtr, u32 PhyAddress,
998 u32 RegisterNum, u16 PhyData)
1003 Xil_AssertNonvoid(InstancePtr != NULL);
1005 /* Make sure no other PHY operation is currently in progress */
1006 if (!(XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
1007 XEMACPS_NWSR_OFFSET) &
1008 XEMACPS_NWSR_MDIOIDLE_MASK)) {
1009 return (XST_EMAC_MII_BUSY);
1012 /* Construct Mgtcr mask for the operation */
1013 Mgtcr = XEMACPS_PHYMNTNC_OP_MASK | XEMACPS_PHYMNTNC_OP_W_MASK |
1014 (PhyAddress << XEMACPS_PHYMNTNC_PHYAD_SHIFT_MASK) |
1015 (RegisterNum << XEMACPS_PHYMNTNC_PHREG_SHIFT_MASK) | PhyData;
1017 /* Write Mgtcr and wait for completion */
1018 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
1019 XEMACPS_PHYMNTNC_OFFSET, Mgtcr);
1022 Ipisr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
1023 XEMACPS_NWSR_OFFSET);
1024 } while ((Ipisr & XEMACPS_NWSR_MDIOIDLE_MASK) == 0);
1026 return (XST_SUCCESS);
1029 /*****************************************************************************/
1031 * API to update the Burst length in the DMACR register.
1033 * @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
1034 * @param BLength is the length in bytes for the dma burst.
1038 ******************************************************************************/
1039 void XEmacPs_DMABLengthUpdate(XEmacPs *InstancePtr, int BLength)
1042 u32 RegUpdateVal = 0;
1044 Xil_AssertVoid(InstancePtr != NULL);
1045 Xil_AssertVoid((BLength == XEMACPS_SINGLE_BURST) ||
1046 (BLength == XEMACPS_4BYTE_BURST) ||
1047 (BLength == XEMACPS_8BYTE_BURST) ||
1048 (BLength == XEMACPS_16BYTE_BURST));
1051 case XEMACPS_SINGLE_BURST:
1052 RegUpdateVal = XEMACPS_DMACR_SINGLE_AHB_BURST;
1055 case XEMACPS_4BYTE_BURST:
1056 RegUpdateVal = XEMACPS_DMACR_INCR4_AHB_BURST;
1059 case XEMACPS_8BYTE_BURST:
1060 RegUpdateVal = XEMACPS_DMACR_INCR8_AHB_BURST;
1063 case XEMACPS_16BYTE_BURST:
1064 RegUpdateVal = XEMACPS_DMACR_INCR16_AHB_BURST;
1070 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
1071 XEMACPS_DMACR_OFFSET);
1073 Reg &= (~XEMACPS_DMACR_BLENGTH_MASK);
1074 Reg |= RegUpdateVal;
1075 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_DMACR_OFFSET,