projects
/
openwrt.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
[mcs814x] nuport-mac: disable MAC RX and TX during interface close
[openwrt.git]
/
target
/
linux
/
mcs814x
/
files-3.3
/
drivers
/
net
/
ethernet
/
mcs8140
/
nuport_mac.c
diff --git
a/target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/nuport_mac.c
b/target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/nuport_mac.c
index
8254026
..
4a42086
100644
(file)
--- a/
target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/nuport_mac.c
+++ b/
target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/nuport_mac.c
@@
-145,6
+145,7
@@
struct nuport_mac_priv {
/* Transmit buffers */
struct sk_buff *tx_skb[TX_RING_SIZE];
/* Transmit buffers */
struct sk_buff *tx_skb[TX_RING_SIZE];
+ dma_addr_t tx_addr;
unsigned int valid_txskb[TX_RING_SIZE];
unsigned int cur_tx;
unsigned int dma_tx;
unsigned int valid_txskb[TX_RING_SIZE];
unsigned int cur_tx;
unsigned int dma_tx;
@@
-152,6
+153,7
@@
struct nuport_mac_priv {
/* Receive buffers */
struct sk_buff *rx_skb[RX_RING_SIZE];
/* Receive buffers */
struct sk_buff *rx_skb[RX_RING_SIZE];
+ dma_addr_t rx_addr;
unsigned int irq_rxskb[RX_RING_SIZE];
int pkt_len[RX_RING_SIZE];
unsigned int cur_rx;
unsigned int irq_rxskb[RX_RING_SIZE];
int pkt_len[RX_RING_SIZE];
unsigned int cur_rx;
@@
-237,7
+239,6
@@
static int nuport_mac_mii_reset(struct mii_bus *bus)
static int nuport_mac_start_tx_dma(struct nuport_mac_priv *priv,
struct sk_buff *skb)
{
static int nuport_mac_start_tx_dma(struct nuport_mac_priv *priv,
struct sk_buff *skb)
{
- dma_addr_t p;
u32 reg;
unsigned int timeout = 2048;
u32 reg;
unsigned int timeout = 2048;
@@
-253,12
+254,14
@@
static int nuport_mac_start_tx_dma(struct nuport_mac_priv *priv,
if (!timeout)
return -EBUSY;
if (!timeout)
return -EBUSY;
- p = dma_map_single(&priv->pdev->dev, skb->data,
+ p
riv->tx_addr
= dma_map_single(&priv->pdev->dev, skb->data,
skb->len, DMA_TO_DEVICE);
skb->len, DMA_TO_DEVICE);
+ if (dma_mapping_error(&priv->pdev->dev, priv->tx_addr))
+ return -ENOMEM;
/* enable enhanced mode */
nuport_mac_writel(TX_DMA_ENH_ENABLE, TX_DMA_ENH);
/* enable enhanced mode */
nuport_mac_writel(TX_DMA_ENH_ENABLE, TX_DMA_ENH);
- nuport_mac_writel(p, TX_BUFFER_ADDR);
+ nuport_mac_writel(p
riv->tx_addr
, TX_BUFFER_ADDR);
nuport_mac_writel((skb->len) - 1, TX_PKT_BYTES);
wmb();
reg = TX_DMA_ENABLE | TX_DMA_START_FRAME | TX_DMA_END_FRAME;
nuport_mac_writel((skb->len) - 1, TX_PKT_BYTES);
wmb();
reg = TX_DMA_ENABLE | TX_DMA_START_FRAME | TX_DMA_END_FRAME;
@@
-279,7
+282,6
@@
static void nuport_mac_reset_tx_dma(struct nuport_mac_priv *priv)
static int nuport_mac_start_rx_dma(struct nuport_mac_priv *priv,
struct sk_buff *skb)
{
static int nuport_mac_start_rx_dma(struct nuport_mac_priv *priv,
struct sk_buff *skb)
{
- dma_addr_t p;
u32 reg;
unsigned int timeout = 2048;
u32 reg;
unsigned int timeout = 2048;
@@
-295,10
+297,12
@@
static int nuport_mac_start_rx_dma(struct nuport_mac_priv *priv,
if (!timeout)
return -EBUSY;
if (!timeout)
return -EBUSY;
- p = dma_map_single(&priv->pdev->dev, skb->data,
+ p
riv->rx_addr
= dma_map_single(&priv->pdev->dev, skb->data,
RX_ALLOC_SIZE, DMA_FROM_DEVICE);
RX_ALLOC_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(&priv->pdev->dev, priv->rx_addr))
+ return -ENOMEM;
- nuport_mac_writel(p, RX_BUFFER_ADDR);
+ nuport_mac_writel(p
riv->rx_addr
, RX_BUFFER_ADDR);
wmb();
nuport_mac_writel(RX_DMA_ENABLE, RX_START_DMA);
wmb();
nuport_mac_writel(RX_DMA_ENABLE, RX_START_DMA);
@@
-422,19
+426,25
@@
static irqreturn_t nuport_mac_link_interrupt(int irq, void *dev_id)
struct nuport_mac_priv *priv = netdev_priv(dev);
u32 reg;
u8 phy_addr;
struct nuport_mac_priv *priv = netdev_priv(dev);
u32 reg;
u8 phy_addr;
+ unsigned long flags;
+ irqreturn_t ret = IRQ_HANDLED;
+ spin_lock_irqsave(&priv->lock, flags);
reg = nuport_mac_readl(LINK_INT_CSR);
phy_addr = (reg >> LINK_PHY_ADDR_SHIFT) & (PHY_MAX_ADDR - 1);
if (phy_addr != priv->phydev->addr) {
netdev_err(dev, "spurious PHY irq (phy: %d)\n", phy_addr);
reg = nuport_mac_readl(LINK_INT_CSR);
phy_addr = (reg >> LINK_PHY_ADDR_SHIFT) & (PHY_MAX_ADDR - 1);
if (phy_addr != priv->phydev->addr) {
netdev_err(dev, "spurious PHY irq (phy: %d)\n", phy_addr);
- return IRQ_NONE;
+ ret = IRQ_NONE;
+ goto out;
}
priv->phydev->link = (reg & LINK_UP);
nuport_mac_adjust_link(dev);
}
priv->phydev->link = (reg & LINK_UP);
nuport_mac_adjust_link(dev);
- return IRQ_HANDLED;
+out:
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return ret;
}
static irqreturn_t nuport_mac_tx_interrupt(int irq, void *dev_id)
}
static irqreturn_t nuport_mac_tx_interrupt(int irq, void *dev_id)
@@
-461,6
+471,8
@@
static irqreturn_t nuport_mac_tx_interrupt(int irq, void *dev_id)
skb = priv->tx_skb[priv->dma_tx];
priv->tx_skb[priv->dma_tx] = NULL;
priv->valid_txskb[priv->dma_tx] = 0;
skb = priv->tx_skb[priv->dma_tx];
priv->tx_skb[priv->dma_tx] = NULL;
priv->valid_txskb[priv->dma_tx] = 0;
+ dma_unmap_single(&priv->pdev->dev, priv->rx_addr, skb->len,
+ DMA_TO_DEVICE);
dev_kfree_skb_irq(skb);
priv->dma_tx++;
dev_kfree_skb_irq(skb);
priv->dma_tx++;
@@
-554,6
+566,9
@@
static int nuport_mac_rx(struct net_device *dev, int limit)
status = get_unaligned((u32 *) (skb->data + len));
skb->dev = dev;
status = get_unaligned((u32 *) (skb->data + len));
skb->dev = dev;
+ dma_unmap_single(&priv->pdev->dev, priv->rx_addr, skb->len,
+ DMA_FROM_DEVICE);
+
/* packet filter failed */
if (!(status & (1 << 30))) {
dev_kfree_skb_irq(skb);
/* packet filter failed */
if (!(status & (1 << 30))) {
dev_kfree_skb_irq(skb);
@@
-673,6
+688,10
@@
static void nuport_mac_free_rx_ring(struct nuport_mac_priv *priv)
dev_kfree_skb(priv->rx_skb[i]);
priv->rx_skb[i] = NULL;
}
dev_kfree_skb(priv->rx_skb[i]);
priv->rx_skb[i] = NULL;
}
+
+ if (priv->rx_addr)
+ dma_unmap_single(&priv->pdev->dev, priv->rx_addr, RX_ALLOC_SIZE,
+ DMA_TO_DEVICE);
}
static void nuport_mac_read_mac_address(struct net_device *dev)
}
static void nuport_mac_read_mac_address(struct net_device *dev)
@@
-746,7
+765,12
@@
static int nuport_mac_open(struct net_device *dev)
goto out_emac_clk;
}
goto out_emac_clk;
}
- phy_start(priv->phydev);
+ ret = request_irq(priv->tx_irq, &nuport_mac_tx_interrupt,
+ 0, dev->name, dev);
+ if (ret) {
+ netdev_err(dev, "unable to request rx interrupt\n");
+ goto out_link_irq;
+ }
/* Enable link interrupt monitoring for our PHY address */
reg = LINK_INT_EN | (priv->phydev->addr << LINK_PHY_ADDR_SHIFT);
/* Enable link interrupt monitoring for our PHY address */
reg = LINK_INT_EN | (priv->phydev->addr << LINK_PHY_ADDR_SHIFT);
@@
-760,14
+784,7
@@
static int nuport_mac_open(struct net_device *dev)
nuport_mac_writel(LINK_POLL_MASK, LINK_INT_POLL_TIME);
spin_unlock_irqrestore(&priv->lock, flags);
nuport_mac_writel(LINK_POLL_MASK, LINK_INT_POLL_TIME);
spin_unlock_irqrestore(&priv->lock, flags);
- ret = request_irq(priv->tx_irq, &nuport_mac_tx_interrupt,
- 0, dev->name, dev);
- if (ret) {
- netdev_err(dev, "unable to request rx interrupt\n");
- goto out_link_irq;
- }
-
- napi_enable(&priv->napi);
+ phy_start(priv->phydev);
ret = request_irq(priv->rx_irq, &nuport_mac_rx_interrupt,
0, dev->name, dev);
ret = request_irq(priv->rx_irq, &nuport_mac_rx_interrupt,
0, dev->name, dev);
@@
-790,7
+807,13
@@
static int nuport_mac_open(struct net_device *dev)
nuport_mac_reset_rx_dma(priv);
/* Start RX DMA */
nuport_mac_reset_rx_dma(priv);
/* Start RX DMA */
- return nuport_mac_start_rx_dma(priv, priv->rx_skb[0]);
+ spin_lock_irqsave(&priv->lock, flags);
+ ret = nuport_mac_start_rx_dma(priv, priv->rx_skb[0]);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ napi_enable(&priv->napi);
+
+ return ret;
out_rx_skb:
nuport_mac_free_rx_ring(priv);
out_rx_skb:
nuport_mac_free_rx_ring(priv);
@@
-806,9
+829,14
@@
out_emac_clk:
static int nuport_mac_close(struct net_device *dev)
{
static int nuport_mac_close(struct net_device *dev)
{
+ u32 reg;
struct nuport_mac_priv *priv = netdev_priv(dev);
spin_lock_irq(&priv->lock);
struct nuport_mac_priv *priv = netdev_priv(dev);
spin_lock_irq(&priv->lock);
+ reg = nuport_mac_readl(CTRL_REG);
+ reg &= ~(RX_ENABLE | TX_ENABLE);
+ nuport_mac_writel(reg, CTRL_REG);
+
napi_disable(&priv->napi);
netif_stop_queue(dev);
napi_disable(&priv->napi);
netif_stop_queue(dev);
@@
-880,8
+908,8
@@
static int nuport_mac_mii_probe(struct net_device *dev)
phydev->supported &= PHY_BASIC_FEATURES;
phydev->advertising = phydev->supported;
priv->phydev = phydev;
phydev->supported &= PHY_BASIC_FEATURES;
phydev->advertising = phydev->supported;
priv->phydev = phydev;
- priv->old_link =
0
;
- priv->old_duplex =
-1
;
+ priv->old_link =
1
;
+ priv->old_duplex =
DUPLEX_FULL
;
dev_info(&priv->pdev->dev, "attached PHY driver [%s] "
"(mii_bus:phy_addr=%d)\n",
dev_info(&priv->pdev->dev, "attached PHY driver [%s] "
"(mii_bus:phy_addr=%d)\n",