arch/arm/src/sama5/sam_gmac: Prevent txtimeout from always firing and fix txbuffer leak during high-volume sends
This commit is contained in:
parent
8ee6be0780
commit
cdc61a08e0
@ -1,4 +1,4 @@
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* arch/arm/src/sama5/hardware/sam_gmac.h
|
||||
*
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
@ -31,22 +31,23 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_SAMA5_HARDWARE_SAM_GMAC_H
|
||||
#define __ARCH_ARM_SRC_SAMA5_HARDWARE_SAM_GMAC_H
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include "hardware/sam_memorymap.h"
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
/* GMAC Register Offsets ************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/* GMAC Register Offsets ****************************************************/
|
||||
|
||||
#define SAM_GMAC_NCR_OFFSET 0x0000 /* Network Control Register */
|
||||
#define SAM_GMAC_NCFGR_OFFSET 0x0004 /* Network Configuration Register */
|
||||
@ -243,7 +244,7 @@
|
||||
#define SAM_GMAC_IMRPQ5_OFFSET 0x654 /* Interrupt Mask Register Priority Queue 5 */
|
||||
#define SAM_GMAC_IMRPQ6_OFFSET 0x658 /* Interrupt Mask Register Priority Queue 6 */
|
||||
|
||||
/* GMAC Register Addresses *********************************************************/
|
||||
/* GMAC Register Addresses **************************************************/
|
||||
|
||||
#define SAM_GMAC_NCR (SAM_GMAC_VBASE+SAM_GMAC_NCR_OFFSET)
|
||||
#define SAM_GMAC_NCFGR (SAM_GMAC_VBASE+SAM_GMAC_NCFGR_OFFSET)
|
||||
@ -436,7 +437,7 @@
|
||||
#define SAM_GMAC_IMRPQ5 (SAM_GMAC_VBASE+SAM_GMAC_IMRPQ5_OFFSET)
|
||||
#define SAM_GMAC_IMRPQ6 (SAM_GMAC_VBASE+SAM_GMAC_IMRPQ6_OFFSET)
|
||||
|
||||
/* GMAC Register Bit Definitions ***************************************************/
|
||||
/* GMAC Register Bit Definitions ********************************************/
|
||||
|
||||
/* Network Control Register */
|
||||
|
||||
@ -871,13 +872,13 @@
|
||||
*
|
||||
* Use these definitions:
|
||||
*
|
||||
* GMAC_INT_RCOMP Bit 1: Receive Complete
|
||||
* GMAC_INT_RXUBR Bit 2: Receive Used Bit Read
|
||||
* GMAC_INT_RLEX Bit 5: Retry Limit Exceeded or Late Collision
|
||||
* GMAC_INT_TFC Bit 6: Transmit Frame Corruption due to AHB error
|
||||
* GMAC_INT_TCOMP Bit 7: Transmit Complete
|
||||
* GMAC_INT_ROVR Bit 10: Receive Overrun
|
||||
* GMAC_INT_HRESP Bit 11: HRESP not OK
|
||||
* GMAC_INT_RCOMP Bit 1: Receive Complete
|
||||
* GMAC_INT_RXUBR Bit 2: Receive Used Bit Read
|
||||
* GMAC_INT_RLEX Bit 5: Retry Limit Exceeded or Late Collision
|
||||
* GMAC_INT_TFC Bit 6: Transmit Frame Corruption due to AHB error
|
||||
* GMAC_INT_TCOMP Bit 7: Transmit Complete
|
||||
* GMAC_INT_ROVR Bit 10: Receive Overrun
|
||||
* GMAC_INT_HRESP Bit 11: HRESP not OK
|
||||
*/
|
||||
|
||||
/* Transmit Buffer Queue Base Address Priority Queue 0-6 */
|
||||
@ -916,7 +917,7 @@
|
||||
# define GMAC_ST2RPQ0_VLANP(n) ((uint32_t)(n) << GMAC_ST2RPQ0_VLANP_SHIFT)
|
||||
#define GMAC_ST2RPQ0_VLANE (1 << 8) /* Bit 8: VLAN Enable */
|
||||
|
||||
/* Descriptors **********************************************************************/
|
||||
/* Descriptors **************************************************************/
|
||||
|
||||
/* Receive buffer descriptor: Address word */
|
||||
|
||||
@ -992,9 +993,12 @@
|
||||
#define GMACTXD_STA_WRAP (1 << 30) /* Bit 30: Last descriptor in descriptor list */
|
||||
#define GMACTXD_STA_USED (1 << 31) /* Bit 31: Zero for the GMAC to read from buffer */
|
||||
|
||||
/************************************************************************************
|
||||
#define GMAC_STATUS_LENGTH_MASK 0x3fffu
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/* Receive buffer descriptor */
|
||||
|
||||
struct gmac_rxdesc_s
|
||||
|
@ -89,6 +89,7 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* If processing is not done at the interrupt level, then work queue support
|
||||
@ -168,6 +169,7 @@
|
||||
#endif
|
||||
|
||||
/* Timing *******************************************************************/
|
||||
|
||||
/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per
|
||||
* second
|
||||
*/
|
||||
@ -183,6 +185,7 @@
|
||||
#define PHY_RETRY_MAX 300000
|
||||
|
||||
/* Helpers ******************************************************************/
|
||||
|
||||
/* This is a helper pointer for accessing the contents of the GMAC
|
||||
* header
|
||||
*/
|
||||
@ -250,6 +253,7 @@ static uint8_t g_pktbuf[MAX_NETDEV_PKTSIZE + CONFIG_NET_GUARDSIZE];
|
||||
|
||||
#ifdef CONFIG_SAMA5_GMAC_PREALLOCATE
|
||||
/* Preallocated data */
|
||||
|
||||
/* TX descriptors list */
|
||||
|
||||
static struct gmac_txdesc_s g_txdesc[CONFIG_SAMA5_GMAC_NTXBUFFERS]
|
||||
@ -262,9 +266,9 @@ static struct gmac_rxdesc_s g_rxdesc[CONFIG_SAMA5_GMAC_NRXBUFFERS]
|
||||
|
||||
/* Transmit Buffers
|
||||
*
|
||||
* Section 3.6 of AMBA 2.0 spec states that burst should not cross 1K Boundaries.
|
||||
* Receive buffer manager writes are burst of 2 words => 3 lsb bits of the address
|
||||
* shall be set to 0
|
||||
* Section 3.6 of AMBA 2.0 spec states that burst should not cross 1K
|
||||
* Boundaries. Receive buffer manager writes are burst of
|
||||
* 2 words => 3 lsb bits of the address shall be set to 0
|
||||
*/
|
||||
|
||||
static uint8_t g_txbuffer[CONFIG_SAMA5_GMAC_NTXBUFFERS * GMAC_TX_UNITSIZE]
|
||||
@ -279,13 +283,15 @@ static uint8_t g_rxbuffer[CONFIG_SAMA5_GMAC_NRXBUFFERS * GMAC_RX_UNITSIZE]
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Register operations ******************************************************/
|
||||
|
||||
#if defined(CONFIG_SAMA5_GMAC_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES)
|
||||
static bool sam_checkreg(struct sam_gmac_s *priv, bool wr,
|
||||
uint32_t regval, uintptr_t address);
|
||||
static uint32_t sam_getreg(struct sam_gmac_s *priv, uintptr_t addr);
|
||||
static void sam_putreg(struct sam_gmac_s *priv, uintptr_t addr, uint32_t val);
|
||||
static void sam_putreg(struct sam_gmac_s *priv, uintptr_t addr,
|
||||
uint32_t val);
|
||||
#else
|
||||
# define sam_getreg(priv,addr) getreg32(addr)
|
||||
# define sam_putreg(priv,addr,val) putreg32(val,addr)
|
||||
@ -383,6 +389,7 @@ static int sam_gmac_configure(struct sam_gmac_s *priv);
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_checkreg
|
||||
*
|
||||
@ -526,7 +533,7 @@ static uint16_t sam_txfree(struct sam_gmac_s *priv)
|
||||
* the configured size minus 1.
|
||||
*/
|
||||
|
||||
return (CONFIG_SAMA5_GMAC_NTXBUFFERS-1) - sam_txinuse(priv);
|
||||
return (CONFIG_SAMA5_GMAC_NTXBUFFERS - 1) - sam_txinuse(priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -708,7 +715,14 @@ static int sam_transmit(struct sam_gmac_s *priv)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Setup/Copy data to transmission buffer */
|
||||
/* Mark buffer as used temporarily so DMA doesn't operate on it */
|
||||
|
||||
status = GMACTXD_STA_USED | GMACTXD_STA_LAST;
|
||||
txdesc->status = status;
|
||||
up_clean_dcache((uint32_t)txdesc,
|
||||
(uint32_t)txdesc + sizeof(struct gmac_txdesc_s));
|
||||
|
||||
/* Setup/Copy data to transmition buffer */
|
||||
|
||||
if (dev->d_len > 0)
|
||||
{
|
||||
@ -721,8 +735,10 @@ static int sam_transmit(struct sam_gmac_s *priv)
|
||||
|
||||
/* Update TX descriptor status. */
|
||||
|
||||
status = dev->d_len & GMAC_STATUS_LENGTH_MASK;
|
||||
status = dev->d_len | GMACTXD_STA_LAST;
|
||||
if (priv->txhead == CONFIG_SAMA5_GMAC_NTXBUFFERS-1)
|
||||
|
||||
if (priv->txhead == CONFIG_SAMA5_GMAC_NTXBUFFERS - 1)
|
||||
{
|
||||
status |= GMACTXD_STA_WRAP;
|
||||
}
|
||||
@ -777,8 +793,9 @@ static int sam_transmit(struct sam_gmac_s *priv)
|
||||
* Function: sam_txpoll
|
||||
*
|
||||
* Description:
|
||||
* The transmitter is available, check if the network has any outgoing packets ready
|
||||
* to send. This is a callback from devif_poll(). devif_poll() may be called:
|
||||
* The transmitter is available, check if the network has any outgoing
|
||||
* packets ready to send. This is a callback from devif_poll().
|
||||
* devif_poll() may be called:
|
||||
*
|
||||
* 1. When the preceding TX packet send is complete,
|
||||
* 2. When the preceding TX packet send timesout and the interface is reset
|
||||
@ -850,8 +867,8 @@ static int sam_txpoll(struct net_driver_s *dev)
|
||||
}
|
||||
}
|
||||
|
||||
/* If zero is returned, the polling will continue until all connections have
|
||||
* been examined.
|
||||
/* If zero is returned, the polling will continue until all connections
|
||||
* have been examined.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
@ -866,7 +883,8 @@ static int sam_txpoll(struct net_driver_s *dev)
|
||||
*
|
||||
* 1. After completion of a transmission (sam_txdone),
|
||||
* 2. When new TX data is available (sam_txavail), and
|
||||
* 3. After a TX timeout to restart the sending process (sam_txtimeout_expiry).
|
||||
* 3. After a TX timeout to restart the sending process
|
||||
* (sam_txtimeout_expiry).
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
@ -1095,7 +1113,8 @@ static int sam_recvframe(struct sam_gmac_s *priv)
|
||||
|
||||
if (pktlen < dev->d_len)
|
||||
{
|
||||
nerr("ERROR: Buffer size %d; frame size %d\n", dev->d_len, pktlen);
|
||||
nerr("ERROR: Buffer size %d; frame size %d\n",
|
||||
dev->d_len, pktlen);
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
@ -1103,7 +1122,9 @@ static int sam_recvframe(struct sam_gmac_s *priv)
|
||||
}
|
||||
}
|
||||
|
||||
/* We have not encount the SOF yet... discard this fragment and keep looking */
|
||||
/* We have not encount the SOF yet... discard this fragment and keep
|
||||
* looking
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
@ -1181,8 +1202,8 @@ static void sam_receive(struct sam_gmac_s *priv)
|
||||
{
|
||||
sam_dumppacket("Received packet", dev->d_buf, dev->d_len);
|
||||
|
||||
/* Check if the packet is a valid size for the network buffer configuration
|
||||
* (this should not happen)
|
||||
/* Check if the packet is a valid size for the network buffer
|
||||
* configuration (this should not happen)
|
||||
*/
|
||||
|
||||
if (dev->d_len > CONFIG_NET_ETH_PKTSIZE)
|
||||
@ -1192,7 +1213,9 @@ static void sam_receive(struct sam_gmac_s *priv)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_PKT
|
||||
/* When packet sockets are enabled, feed the frame into the packet tap */
|
||||
/* When packet sockets are enabled, feed the frame into the packet
|
||||
* tap
|
||||
*/
|
||||
|
||||
pkt_input(&priv->dev);
|
||||
#endif
|
||||
@ -1212,7 +1235,8 @@ static void sam_receive(struct sam_gmac_s *priv)
|
||||
ipv4_input(&priv->dev);
|
||||
|
||||
/* If the above function invocation resulted in data that should be
|
||||
* sent out on the network, the field d_len will set to a value > 0.
|
||||
* sent out on the network, the field d_len will set to a
|
||||
* value > 0.
|
||||
*/
|
||||
|
||||
if (priv->dev.d_len > 0)
|
||||
@ -1249,7 +1273,8 @@ static void sam_receive(struct sam_gmac_s *priv)
|
||||
ipv6_input(&priv->dev);
|
||||
|
||||
/* If the above function invocation resulted in data that should be
|
||||
* sent out on the network, the field d_len will set to a value > 0.
|
||||
* sent out on the network, the field d_len will set to a
|
||||
* value > 0.
|
||||
*/
|
||||
|
||||
if (priv->dev.d_len > 0)
|
||||
@ -1286,7 +1311,8 @@ static void sam_receive(struct sam_gmac_s *priv)
|
||||
arp_arpin(&priv->dev);
|
||||
|
||||
/* If the above function invocation resulted in data that should be
|
||||
* sent out on the network, the field d_len will set to a value > 0.
|
||||
* sent out on the network, the field d_len will set to a
|
||||
* value > 0.
|
||||
*/
|
||||
|
||||
if (priv->dev.d_len > 0)
|
||||
@ -1323,6 +1349,7 @@ static void sam_receive(struct sam_gmac_s *priv)
|
||||
static void sam_txdone(struct sam_gmac_s *priv)
|
||||
{
|
||||
struct gmac_txdesc_s *txdesc;
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Are there any outstanding transmissions? Loop until either (1) all of
|
||||
* the TX descriptors have been examined, or (2) until we encounter the
|
||||
@ -1337,24 +1364,39 @@ static void sam_txdone(struct sam_gmac_s *priv)
|
||||
up_invalidate_dcache((uintptr_t)txdesc,
|
||||
(uintptr_t)txdesc + sizeof(struct gmac_txdesc_s));
|
||||
|
||||
/* Is this TX descriptor still in use? */
|
||||
/* Is this TX descriptor done transmitting? (SAMA5D36 datasheet,
|
||||
* p. 934)
|
||||
* First TX descriptor in chain has GMACTXD_STA_USED = 1
|
||||
*/
|
||||
|
||||
if ((txdesc->status & GMACTXD_STA_USED) == 0)
|
||||
{
|
||||
/* Yes.. the descriptor is still in use. However, I have seen a
|
||||
* case (only repeatable on start-up) where the USED bit is never
|
||||
* set. Yikes! If we have encountered the first still busy
|
||||
* descriptor, then we should also have TQBD equal to the descriptor
|
||||
* address. If it is not, then treat is as used anyway.
|
||||
* descriptor, then we should also have TQBD equal to the
|
||||
* descriptor address. If it is not, then treat is as used anyway.
|
||||
*/
|
||||
|
||||
#warning REVISIT
|
||||
if (priv->txtail == 0 &&
|
||||
sam_physramaddr((uintptr_t)txdesc) != sam_getreg(priv, SAM_GMAC_TBQB))
|
||||
sam_physramaddr((uintptr_t)txdesc) != sam_getreg(priv,
|
||||
SAM_GMAC_TBQB))
|
||||
{
|
||||
txdesc->status = (uint32_t)GMACTXD_STA_USED;
|
||||
ninfo("TX buffer marked in-use: unusual startup case (%d)\n",
|
||||
priv->txtail);
|
||||
txdesc->status = (uint32_t) dev->d_len | GMACTXD_STA_USED;
|
||||
up_clean_dcache((uintptr_t)txdesc,
|
||||
(uintptr_t)txdesc + sizeof(struct gmac_txdesc_s));
|
||||
(uintptr_t)txdesc +
|
||||
sizeof(struct gmac_txdesc_s));
|
||||
}
|
||||
else if (((txdesc->status & GMACTXD_STA_USED) == 0) &&
|
||||
((txdesc->status & GMACTXD_STA_LAST) != 0))
|
||||
{
|
||||
txdesc->status = (uint32_t) dev->d_len | GMACTXD_STA_USED |
|
||||
GMACTXD_STA_LAST;
|
||||
up_clean_dcache((uintptr_t)txdesc,
|
||||
(uintptr_t)txdesc +
|
||||
sizeof(struct gmac_txdesc_s));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1428,8 +1470,8 @@ static void sam_interrupt_work(FAR void *arg)
|
||||
ninfo("isr: %08x pending: %08x\n", isr, pending);
|
||||
|
||||
/* Check for the completion of a transmission. This should be done before
|
||||
* checking for received data (because receiving can cause another transmission
|
||||
* before we had a chance to handle the last one).
|
||||
* checking for received data (because receiving can cause another
|
||||
* transmission before we had a chance to handle the last one).
|
||||
*
|
||||
* ISR:TCOMP is set when a frame has been transmitted. Cleared on read.
|
||||
* TSR:COMP is set when a frame has been transmitted. Cleared by writing a
|
||||
@ -1579,7 +1621,8 @@ static void sam_interrupt_work(FAR void *arg)
|
||||
#ifdef CONFIG_DEBUG_NET
|
||||
/* Check for PAUSE Frame received (PFRE).
|
||||
*
|
||||
* ISR:PFRE indicates that a pause frame has been received. Cleared on a read.
|
||||
* ISR:PFRE indicates that a pause frame has been received. Cleared on a
|
||||
* read.
|
||||
*/
|
||||
|
||||
if ((pending & GMAC_INT_PFNZ) != 0)
|
||||
@ -1638,15 +1681,15 @@ static int sam_gmac_interrupt(int irq, void *context, FAR void *arg)
|
||||
*
|
||||
* ISR:TCOMP is set when a frame has been transmitted. Cleared on read (so
|
||||
* we cannot read it here).
|
||||
* TSR:TXCOMP is set when a frame has been transmitted. Cleared by writing a
|
||||
* one to this bit.
|
||||
* TSR:TXCOMP is set when a frame has been transmitted. Cleared by writing
|
||||
* a one to this bit.
|
||||
*/
|
||||
|
||||
tsr = sam_getreg(priv, SAM_GMAC_TSR_OFFSET);
|
||||
tsr = sam_getreg(priv, SAM_GMAC_TSR);
|
||||
if ((tsr & GMAC_TSR_TXCOMP) != 0)
|
||||
{
|
||||
/* If a TX transfer just completed, then cancel the TX timeout so
|
||||
* there will be do race condition between any subsequent timeout
|
||||
* there will be no race condition between any subsequent timeout
|
||||
* expiration and the deferred interrupt processing.
|
||||
*/
|
||||
|
||||
@ -2032,7 +2075,8 @@ static unsigned int sam_hashindx(const uint8_t *mac)
|
||||
unsigned int ndx;
|
||||
|
||||
/* Isolate: mac[0]
|
||||
* ... 05 04 03 02 01 00] */
|
||||
* ... 05 04 03 02 01 00]
|
||||
*/
|
||||
|
||||
ndx = mac[0];
|
||||
|
||||
@ -2203,8 +2247,8 @@ static int sam_addmac(struct net_driver_s *dev, const uint8_t *mac)
|
||||
* Function: sam_rmmac
|
||||
*
|
||||
* Description:
|
||||
* NuttX Callback: Remove the specified MAC address from the hardware multicast
|
||||
* address filtering
|
||||
* NuttX Callback: Remove the specified MAC address from the hardware
|
||||
* multicast address filtering
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Reference to the NuttX driver state structure
|
||||
@ -2301,9 +2345,9 @@ static int sam_rmmac(struct net_driver_s *dev, const uint8_t *mac)
|
||||
* specified using the req->reg_no struct field and then write its output
|
||||
* to the req->val_out field.
|
||||
*
|
||||
* When called with SIOCSMIIREG it will write to a register of the PHY that
|
||||
* is specified using the req->reg_no struct field and use req->val_in as
|
||||
* its input.
|
||||
* When called with SIOCSMIIREG it will write to a register of the PHY
|
||||
* that is specified using the req->reg_no struct field and use
|
||||
* req->val_in as its input.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Ethernet device structure
|
||||
@ -2330,7 +2374,8 @@ static int sam_ioctl(struct net_driver_s *dev, int cmd, unsigned long arg)
|
||||
#ifdef CONFIG_ARCH_PHY_INTERRUPT
|
||||
case SIOCMIINOTIFY: /* Set up for PHY event notifications */
|
||||
{
|
||||
struct mii_ioctl_notify_s *req = (struct mii_ioctl_notify_s *)((uintptr_t)arg);
|
||||
struct mii_ioctl_notify_s *req =
|
||||
(struct mii_ioctl_notify_s *)((uintptr_t)arg);
|
||||
|
||||
ret = phy_notify_subscribe(dev->d_ifname, req->pid, &req->event);
|
||||
if (ret == OK)
|
||||
@ -2345,7 +2390,8 @@ static int sam_ioctl(struct net_driver_s *dev, int cmd, unsigned long arg)
|
||||
|
||||
case SIOCGMIIPHY: /* Get MII PHY address */
|
||||
{
|
||||
struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg);
|
||||
struct mii_ioctl_data_s *req =
|
||||
(struct mii_ioctl_data_s *)((uintptr_t)arg);
|
||||
req->phy_id = priv->phyaddr;
|
||||
ret = OK;
|
||||
}
|
||||
@ -2353,7 +2399,8 @@ static int sam_ioctl(struct net_driver_s *dev, int cmd, unsigned long arg)
|
||||
|
||||
case SIOCGMIIREG: /* Get register from MII PHY */
|
||||
{
|
||||
struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg);
|
||||
struct mii_ioctl_data_s *req =
|
||||
(struct mii_ioctl_data_s *)((uintptr_t)arg);
|
||||
|
||||
/* Enable the management port */
|
||||
|
||||
@ -2371,7 +2418,8 @@ static int sam_ioctl(struct net_driver_s *dev, int cmd, unsigned long arg)
|
||||
|
||||
case SIOCSMIIREG: /* Set register in MII PHY */
|
||||
{
|
||||
struct mii_ioctl_data_s *req = (struct mii_ioctl_data_s *)((uintptr_t)arg);
|
||||
struct mii_ioctl_data_s *req =
|
||||
(struct mii_ioctl_data_s *)((uintptr_t)arg);
|
||||
|
||||
/* Enable the management port */
|
||||
|
||||
@ -3119,6 +3167,7 @@ static int sam_autonegotiate(struct sam_gmac_s *priv)
|
||||
sam_putreg(priv, SAM_GMAC_UR, regval);
|
||||
|
||||
errout:
|
||||
|
||||
/* Disable the management port */
|
||||
|
||||
sam_disablemdio(priv);
|
||||
@ -3367,13 +3416,14 @@ static void sam_txreset(struct sam_gmac_s *priv)
|
||||
|
||||
/* Mark the final descriptor in the list */
|
||||
|
||||
txdesc[CONFIG_SAMA5_GMAC_NTXBUFFERS - 1].status = GMACTXD_STA_USED | GMACTXD_STA_WRAP;
|
||||
txdesc[CONFIG_SAMA5_GMAC_NTXBUFFERS - 1].status = GMACTXD_STA_USED |
|
||||
GMACTXD_STA_WRAP;
|
||||
|
||||
/* Flush the entire TX descriptor table to RAM */
|
||||
|
||||
up_clean_dcache((uintptr_t)txdesc,
|
||||
(uintptr_t)txdesc +
|
||||
CONFIG_SAMA5_GMAC_NTXBUFFERS * sizeof(struct gmac_txdesc_s));
|
||||
(uintptr_t)txdesc + CONFIG_SAMA5_GMAC_NTXBUFFERS *
|
||||
sizeof(struct gmac_txdesc_s));
|
||||
|
||||
/* Set the Transmit Buffer Queue Base Register */
|
||||
|
||||
@ -3436,8 +3486,8 @@ static void sam_rxreset(struct sam_gmac_s *priv)
|
||||
/* Flush the entire RX descriptor table to RAM */
|
||||
|
||||
up_clean_dcache((uintptr_t)rxdesc,
|
||||
(uintptr_t)rxdesc +
|
||||
CONFIG_SAMA5_GMAC_NRXBUFFERS * sizeof(struct gmac_rxdesc_s));
|
||||
(uintptr_t)rxdesc + CONFIG_SAMA5_GMAC_NRXBUFFERS *
|
||||
sizeof(struct gmac_rxdesc_s));
|
||||
|
||||
/* Set the Receive Buffer Queue Base Register */
|
||||
|
||||
@ -3526,9 +3576,12 @@ static void sam_macaddress(struct sam_gmac_s *priv)
|
||||
|
||||
ninfo("%s MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
dev->d_ifname,
|
||||
dev->d_mac.ether.ether_addr_octet[0], dev->d_mac.ether.ether_addr_octet[1],
|
||||
dev->d_mac.ether.ether_addr_octet[2], dev->d_mac.ether.ether_addr_octet[3],
|
||||
dev->d_mac.ether.ether_addr_octet[4], dev->d_mac.ether.ether_addr_octet[5]);
|
||||
dev->d_mac.ether.ether_addr_octet[0],
|
||||
dev->d_mac.ether.ether_addr_octet[1],
|
||||
dev->d_mac.ether.ether_addr_octet[2],
|
||||
dev->d_mac.ether.ether_addr_octet[3],
|
||||
dev->d_mac.ether.ether_addr_octet[4],
|
||||
dev->d_mac.ether.ether_addr_octet[5]);
|
||||
|
||||
/* Set the MAC address */
|
||||
|
||||
@ -3717,12 +3770,14 @@ static int sam_gmac_configure(struct sam_gmac_s *priv)
|
||||
|
||||
/* Setup the interrupts for TX events, RX events, and error events */
|
||||
|
||||
regval = GMAC_INT_MFS | GMAC_INT_RCOMP | GMAC_INT_RXUBR | GMAC_INT_TXUBR |
|
||||
GMAC_INT_TUR | GMAC_INT_RLEX | GMAC_INT_TFC | GMAC_INT_TCOMP |
|
||||
GMAC_INT_ROVR | GMAC_INT_HRESP | GMAC_INT_PFNZ | GMAC_INT_PTZ |
|
||||
GMAC_INT_PFTR | GMAC_INT_EXINT | GMAC_INT_DRQFR | GMAC_INT_SFR |
|
||||
GMAC_INT_DRQFT | GMAC_INT_SFT | GMAC_INT_PDRQFR | GMAC_INT_PDRSFR |
|
||||
GMAC_INT_PDRQFT | GMAC_INT_PDRSFT;
|
||||
regval = GMAC_INT_MFS | GMAC_INT_RCOMP | GMAC_INT_RXUBR |
|
||||
GMAC_INT_TXUBR | GMAC_INT_TUR | GMAC_INT_RLEX |
|
||||
GMAC_INT_TFC | GMAC_INT_TCOMP | GMAC_INT_ROVR |
|
||||
GMAC_INT_HRESP | GMAC_INT_PFNZ | GMAC_INT_PTZ |
|
||||
GMAC_INT_PFTR | GMAC_INT_EXINT | GMAC_INT_DRQFR |
|
||||
GMAC_INT_SFR | GMAC_INT_DRQFT | GMAC_INT_SFT |
|
||||
GMAC_INT_PDRQFR | GMAC_INT_PDRSFR | GMAC_INT_PDRQFT |
|
||||
GMAC_INT_PDRSFT;
|
||||
sam_putreg(priv, SAM_GMAC_IER, regval);
|
||||
return OK;
|
||||
}
|
||||
@ -3807,7 +3862,8 @@ int sam_gmac_initialize(void)
|
||||
ret = irq_attach(SAM_IRQ_GMAC, sam_gmac_interrupt, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: Failed to attach the handler to the IRQ%d\n", SAM_IRQ_GMAC);
|
||||
nerr("ERROR: Failed to attach the handler to the IRQ%d\n",
|
||||
SAM_IRQ_GMAC);
|
||||
goto errout_with_buffers;
|
||||
}
|
||||
|
||||
@ -3820,7 +3876,8 @@ int sam_gmac_initialize(void)
|
||||
ret = sam_ifdown(&priv->dev);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: Failed to put the interface in the down state: %d\n", ret);
|
||||
nerr("ERROR: Failed to put the interface in the down state: %d\n",
|
||||
ret);
|
||||
goto errout_with_buffers;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user