Merge branch 'fs_enet-opt'
Christophe Leroy says: ==================== Optimisation of fs_enet ethernet driver This set optimises the freescale fs_enet ethernet driver: 1/ Merge of RX and TX NAPI functions in order to limit the amount of interrupts 2/ Do not unmap DMA when packets len is below copybreak, otherwise there is no benefit in copying the skb instead of allocating a new one 3/ Make copybreak value configurable as the optimised value is not the same on all targets ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
34c1b089d9
|
@ -60,6 +60,9 @@ module_param(fs_enet_debug, int, 0);
|
||||||
MODULE_PARM_DESC(fs_enet_debug,
|
MODULE_PARM_DESC(fs_enet_debug,
|
||||||
"Freescale bitmapped debugging message enable value");
|
"Freescale bitmapped debugging message enable value");
|
||||||
|
|
||||||
|
#define RX_RING_SIZE 32
|
||||||
|
#define TX_RING_SIZE 64
|
||||||
|
|
||||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||||
static void fs_enet_netpoll(struct net_device *dev);
|
static void fs_enet_netpoll(struct net_device *dev);
|
||||||
#endif
|
#endif
|
||||||
|
@ -79,8 +82,8 @@ static void skb_align(struct sk_buff *skb, int align)
|
||||||
skb_reserve(skb, align - off);
|
skb_reserve(skb, align - off);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NAPI receive function */
|
/* NAPI function */
|
||||||
static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
|
static int fs_enet_napi(struct napi_struct *napi, int budget)
|
||||||
{
|
{
|
||||||
struct fs_enet_private *fep = container_of(napi, struct fs_enet_private, napi);
|
struct fs_enet_private *fep = container_of(napi, struct fs_enet_private, napi);
|
||||||
struct net_device *dev = fep->ndev;
|
struct net_device *dev = fep->ndev;
|
||||||
|
@ -90,147 +93,17 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
|
||||||
int received = 0;
|
int received = 0;
|
||||||
u16 pkt_len, sc;
|
u16 pkt_len, sc;
|
||||||
int curidx;
|
int curidx;
|
||||||
|
|
||||||
if (budget <= 0)
|
|
||||||
return received;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* First, grab all of the stats for the incoming packet.
|
|
||||||
* These get messed up if we get called due to a busy condition.
|
|
||||||
*/
|
|
||||||
bdp = fep->cur_rx;
|
|
||||||
|
|
||||||
/* clear RX status bits for napi*/
|
|
||||||
(*fep->ops->napi_clear_rx_event)(dev);
|
|
||||||
|
|
||||||
while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) {
|
|
||||||
curidx = bdp - fep->rx_bd_base;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Since we have allocated space to hold a complete frame,
|
|
||||||
* the last indicator should be set.
|
|
||||||
*/
|
|
||||||
if ((sc & BD_ENET_RX_LAST) == 0)
|
|
||||||
dev_warn(fep->dev, "rcv is not +last\n");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check for errors.
|
|
||||||
*/
|
|
||||||
if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL |
|
|
||||||
BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) {
|
|
||||||
fep->stats.rx_errors++;
|
|
||||||
/* Frame too long or too short. */
|
|
||||||
if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH))
|
|
||||||
fep->stats.rx_length_errors++;
|
|
||||||
/* Frame alignment */
|
|
||||||
if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL))
|
|
||||||
fep->stats.rx_frame_errors++;
|
|
||||||
/* CRC Error */
|
|
||||||
if (sc & BD_ENET_RX_CR)
|
|
||||||
fep->stats.rx_crc_errors++;
|
|
||||||
/* FIFO overrun */
|
|
||||||
if (sc & BD_ENET_RX_OV)
|
|
||||||
fep->stats.rx_crc_errors++;
|
|
||||||
|
|
||||||
skb = fep->rx_skbuff[curidx];
|
|
||||||
|
|
||||||
dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
|
|
||||||
L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
|
|
||||||
DMA_FROM_DEVICE);
|
|
||||||
|
|
||||||
skbn = skb;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
skb = fep->rx_skbuff[curidx];
|
|
||||||
|
|
||||||
dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
|
|
||||||
L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
|
|
||||||
DMA_FROM_DEVICE);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Process the incoming frame.
|
|
||||||
*/
|
|
||||||
fep->stats.rx_packets++;
|
|
||||||
pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */
|
|
||||||
fep->stats.rx_bytes += pkt_len + 4;
|
|
||||||
|
|
||||||
if (pkt_len <= fpi->rx_copybreak) {
|
|
||||||
/* +2 to make IP header L1 cache aligned */
|
|
||||||
skbn = netdev_alloc_skb(dev, pkt_len + 2);
|
|
||||||
if (skbn != NULL) {
|
|
||||||
skb_reserve(skbn, 2); /* align IP header */
|
|
||||||
skb_copy_from_linear_data(skb,
|
|
||||||
skbn->data, pkt_len);
|
|
||||||
swap(skb, skbn);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
skbn = netdev_alloc_skb(dev, ENET_RX_FRSIZE);
|
|
||||||
|
|
||||||
if (skbn)
|
|
||||||
skb_align(skbn, ENET_RX_ALIGN);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skbn != NULL) {
|
|
||||||
skb_put(skb, pkt_len); /* Make room */
|
|
||||||
skb->protocol = eth_type_trans(skb, dev);
|
|
||||||
received++;
|
|
||||||
netif_receive_skb(skb);
|
|
||||||
} else {
|
|
||||||
fep->stats.rx_dropped++;
|
|
||||||
skbn = skb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fep->rx_skbuff[curidx] = skbn;
|
|
||||||
CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data,
|
|
||||||
L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
|
|
||||||
DMA_FROM_DEVICE));
|
|
||||||
CBDW_DATLEN(bdp, 0);
|
|
||||||
CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update BD pointer to next entry.
|
|
||||||
*/
|
|
||||||
if ((sc & BD_ENET_RX_WRAP) == 0)
|
|
||||||
bdp++;
|
|
||||||
else
|
|
||||||
bdp = fep->rx_bd_base;
|
|
||||||
|
|
||||||
(*fep->ops->rx_bd_done)(dev);
|
|
||||||
|
|
||||||
if (received >= budget)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fep->cur_rx = bdp;
|
|
||||||
|
|
||||||
if (received < budget) {
|
|
||||||
/* done */
|
|
||||||
napi_complete(napi);
|
|
||||||
(*fep->ops->napi_enable_rx)(dev);
|
|
||||||
}
|
|
||||||
return received;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fs_enet_tx_napi(struct napi_struct *napi, int budget)
|
|
||||||
{
|
|
||||||
struct fs_enet_private *fep = container_of(napi, struct fs_enet_private,
|
|
||||||
napi_tx);
|
|
||||||
struct net_device *dev = fep->ndev;
|
|
||||||
cbd_t __iomem *bdp;
|
|
||||||
struct sk_buff *skb;
|
|
||||||
int dirtyidx, do_wake, do_restart;
|
int dirtyidx, do_wake, do_restart;
|
||||||
u16 sc;
|
int tx_left = TX_RING_SIZE;
|
||||||
int has_tx_work = 0;
|
|
||||||
|
|
||||||
spin_lock(&fep->tx_lock);
|
spin_lock(&fep->tx_lock);
|
||||||
bdp = fep->dirty_tx;
|
bdp = fep->dirty_tx;
|
||||||
|
|
||||||
/* clear TX status bits for napi*/
|
/* clear status bits for napi*/
|
||||||
(*fep->ops->napi_clear_tx_event)(dev);
|
(*fep->ops->napi_clear_event)(dev);
|
||||||
|
|
||||||
do_wake = do_restart = 0;
|
do_wake = do_restart = 0;
|
||||||
while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) {
|
while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0 && tx_left) {
|
||||||
dirtyidx = bdp - fep->tx_bd_base;
|
dirtyidx = bdp - fep->tx_bd_base;
|
||||||
|
|
||||||
if (fep->tx_free == fep->tx_ring)
|
if (fep->tx_free == fep->tx_ring)
|
||||||
|
@ -302,9 +175,9 @@ static int fs_enet_tx_napi(struct napi_struct *napi, int budget)
|
||||||
* Since we have freed up a buffer, the ring is no longer
|
* Since we have freed up a buffer, the ring is no longer
|
||||||
* full.
|
* full.
|
||||||
*/
|
*/
|
||||||
if (++fep->tx_free >= MAX_SKB_FRAGS)
|
if (++fep->tx_free == MAX_SKB_FRAGS)
|
||||||
do_wake = 1;
|
do_wake = 1;
|
||||||
has_tx_work = 1;
|
tx_left--;
|
||||||
}
|
}
|
||||||
|
|
||||||
fep->dirty_tx = bdp;
|
fep->dirty_tx = bdp;
|
||||||
|
@ -312,19 +185,129 @@ static int fs_enet_tx_napi(struct napi_struct *napi, int budget)
|
||||||
if (do_restart)
|
if (do_restart)
|
||||||
(*fep->ops->tx_restart)(dev);
|
(*fep->ops->tx_restart)(dev);
|
||||||
|
|
||||||
if (!has_tx_work) {
|
|
||||||
napi_complete(napi);
|
|
||||||
(*fep->ops->napi_enable_tx)(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock(&fep->tx_lock);
|
spin_unlock(&fep->tx_lock);
|
||||||
|
|
||||||
if (do_wake)
|
if (do_wake)
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
|
|
||||||
if (has_tx_work)
|
/*
|
||||||
return budget;
|
* First, grab all of the stats for the incoming packet.
|
||||||
return 0;
|
* These get messed up if we get called due to a busy condition.
|
||||||
|
*/
|
||||||
|
bdp = fep->cur_rx;
|
||||||
|
|
||||||
|
while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0 &&
|
||||||
|
received < budget) {
|
||||||
|
curidx = bdp - fep->rx_bd_base;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since we have allocated space to hold a complete frame,
|
||||||
|
* the last indicator should be set.
|
||||||
|
*/
|
||||||
|
if ((sc & BD_ENET_RX_LAST) == 0)
|
||||||
|
dev_warn(fep->dev, "rcv is not +last\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for errors.
|
||||||
|
*/
|
||||||
|
if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL |
|
||||||
|
BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) {
|
||||||
|
fep->stats.rx_errors++;
|
||||||
|
/* Frame too long or too short. */
|
||||||
|
if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH))
|
||||||
|
fep->stats.rx_length_errors++;
|
||||||
|
/* Frame alignment */
|
||||||
|
if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL))
|
||||||
|
fep->stats.rx_frame_errors++;
|
||||||
|
/* CRC Error */
|
||||||
|
if (sc & BD_ENET_RX_CR)
|
||||||
|
fep->stats.rx_crc_errors++;
|
||||||
|
/* FIFO overrun */
|
||||||
|
if (sc & BD_ENET_RX_OV)
|
||||||
|
fep->stats.rx_crc_errors++;
|
||||||
|
|
||||||
|
skbn = fep->rx_skbuff[curidx];
|
||||||
|
} else {
|
||||||
|
skb = fep->rx_skbuff[curidx];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process the incoming frame.
|
||||||
|
*/
|
||||||
|
fep->stats.rx_packets++;
|
||||||
|
pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */
|
||||||
|
fep->stats.rx_bytes += pkt_len + 4;
|
||||||
|
|
||||||
|
if (pkt_len <= fpi->rx_copybreak) {
|
||||||
|
/* +2 to make IP header L1 cache aligned */
|
||||||
|
skbn = netdev_alloc_skb(dev, pkt_len + 2);
|
||||||
|
if (skbn != NULL) {
|
||||||
|
skb_reserve(skbn, 2); /* align IP header */
|
||||||
|
skb_copy_from_linear_data(skb,
|
||||||
|
skbn->data, pkt_len);
|
||||||
|
swap(skb, skbn);
|
||||||
|
dma_sync_single_for_cpu(fep->dev,
|
||||||
|
CBDR_BUFADDR(bdp),
|
||||||
|
L1_CACHE_ALIGN(pkt_len),
|
||||||
|
DMA_FROM_DEVICE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
skbn = netdev_alloc_skb(dev, ENET_RX_FRSIZE);
|
||||||
|
|
||||||
|
if (skbn) {
|
||||||
|
dma_addr_t dma;
|
||||||
|
|
||||||
|
skb_align(skbn, ENET_RX_ALIGN);
|
||||||
|
|
||||||
|
dma_unmap_single(fep->dev,
|
||||||
|
CBDR_BUFADDR(bdp),
|
||||||
|
L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
|
||||||
|
DMA_FROM_DEVICE);
|
||||||
|
|
||||||
|
dma = dma_map_single(fep->dev,
|
||||||
|
skbn->data,
|
||||||
|
L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
|
||||||
|
DMA_FROM_DEVICE);
|
||||||
|
CBDW_BUFADDR(bdp, dma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skbn != NULL) {
|
||||||
|
skb_put(skb, pkt_len); /* Make room */
|
||||||
|
skb->protocol = eth_type_trans(skb, dev);
|
||||||
|
received++;
|
||||||
|
netif_receive_skb(skb);
|
||||||
|
} else {
|
||||||
|
fep->stats.rx_dropped++;
|
||||||
|
skbn = skb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fep->rx_skbuff[curidx] = skbn;
|
||||||
|
CBDW_DATLEN(bdp, 0);
|
||||||
|
CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update BD pointer to next entry.
|
||||||
|
*/
|
||||||
|
if ((sc & BD_ENET_RX_WRAP) == 0)
|
||||||
|
bdp++;
|
||||||
|
else
|
||||||
|
bdp = fep->rx_bd_base;
|
||||||
|
|
||||||
|
(*fep->ops->rx_bd_done)(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
fep->cur_rx = bdp;
|
||||||
|
|
||||||
|
if (received < budget && tx_left) {
|
||||||
|
/* done */
|
||||||
|
napi_complete(napi);
|
||||||
|
(*fep->ops->napi_enable)(dev);
|
||||||
|
|
||||||
|
return received;
|
||||||
|
}
|
||||||
|
|
||||||
|
return budget;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -350,18 +333,18 @@ fs_enet_interrupt(int irq, void *dev_id)
|
||||||
nr++;
|
nr++;
|
||||||
|
|
||||||
int_clr_events = int_events;
|
int_clr_events = int_events;
|
||||||
int_clr_events &= ~fep->ev_napi_rx;
|
int_clr_events &= ~fep->ev_napi;
|
||||||
|
|
||||||
(*fep->ops->clear_int_events)(dev, int_clr_events);
|
(*fep->ops->clear_int_events)(dev, int_clr_events);
|
||||||
|
|
||||||
if (int_events & fep->ev_err)
|
if (int_events & fep->ev_err)
|
||||||
(*fep->ops->ev_error)(dev, int_events);
|
(*fep->ops->ev_error)(dev, int_events);
|
||||||
|
|
||||||
if (int_events & fep->ev_rx) {
|
if (int_events & fep->ev) {
|
||||||
napi_ok = napi_schedule_prep(&fep->napi);
|
napi_ok = napi_schedule_prep(&fep->napi);
|
||||||
|
|
||||||
(*fep->ops->napi_disable_rx)(dev);
|
(*fep->ops->napi_disable)(dev);
|
||||||
(*fep->ops->clear_int_events)(dev, fep->ev_napi_rx);
|
(*fep->ops->clear_int_events)(dev, fep->ev_napi);
|
||||||
|
|
||||||
/* NOTE: it is possible for FCCs in NAPI mode */
|
/* NOTE: it is possible for FCCs in NAPI mode */
|
||||||
/* to submit a spurious interrupt while in poll */
|
/* to submit a spurious interrupt while in poll */
|
||||||
|
@ -369,17 +352,6 @@ fs_enet_interrupt(int irq, void *dev_id)
|
||||||
__napi_schedule(&fep->napi);
|
__napi_schedule(&fep->napi);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (int_events & fep->ev_tx) {
|
|
||||||
napi_ok = napi_schedule_prep(&fep->napi_tx);
|
|
||||||
|
|
||||||
(*fep->ops->napi_disable_tx)(dev);
|
|
||||||
(*fep->ops->clear_int_events)(dev, fep->ev_napi_tx);
|
|
||||||
|
|
||||||
/* NOTE: it is possible for FCCs in NAPI mode */
|
|
||||||
/* to submit a spurious interrupt while in poll */
|
|
||||||
if (napi_ok)
|
|
||||||
__napi_schedule(&fep->napi_tx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handled = nr > 0;
|
handled = nr > 0;
|
||||||
|
@ -659,7 +631,8 @@ static void fs_timeout(struct net_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
phy_start(dev->phydev);
|
phy_start(dev->phydev);
|
||||||
wake = fep->tx_free && !(CBDR_SC(fep->cur_tx) & BD_ENET_TX_READY);
|
wake = fep->tx_free >= MAX_SKB_FRAGS &&
|
||||||
|
!(CBDR_SC(fep->cur_tx) & BD_ENET_TX_READY);
|
||||||
spin_unlock_irqrestore(&fep->lock, flags);
|
spin_unlock_irqrestore(&fep->lock, flags);
|
||||||
|
|
||||||
if (wake)
|
if (wake)
|
||||||
|
@ -751,11 +724,10 @@ static int fs_enet_open(struct net_device *dev)
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* to initialize the fep->cur_rx,... */
|
/* to initialize the fep->cur_rx,... */
|
||||||
/* not doing this, will cause a crash in fs_enet_rx_napi */
|
/* not doing this, will cause a crash in fs_enet_napi */
|
||||||
fs_init_bds(fep->ndev);
|
fs_init_bds(fep->ndev);
|
||||||
|
|
||||||
napi_enable(&fep->napi);
|
napi_enable(&fep->napi);
|
||||||
napi_enable(&fep->napi_tx);
|
|
||||||
|
|
||||||
/* Install our interrupt handler. */
|
/* Install our interrupt handler. */
|
||||||
r = request_irq(fep->interrupt, fs_enet_interrupt, IRQF_SHARED,
|
r = request_irq(fep->interrupt, fs_enet_interrupt, IRQF_SHARED,
|
||||||
|
@ -763,7 +735,6 @@ static int fs_enet_open(struct net_device *dev)
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
dev_err(fep->dev, "Could not allocate FS_ENET IRQ!");
|
dev_err(fep->dev, "Could not allocate FS_ENET IRQ!");
|
||||||
napi_disable(&fep->napi);
|
napi_disable(&fep->napi);
|
||||||
napi_disable(&fep->napi_tx);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -771,7 +742,6 @@ static int fs_enet_open(struct net_device *dev)
|
||||||
if (err) {
|
if (err) {
|
||||||
free_irq(fep->interrupt, dev);
|
free_irq(fep->interrupt, dev);
|
||||||
napi_disable(&fep->napi);
|
napi_disable(&fep->napi);
|
||||||
napi_disable(&fep->napi_tx);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
phy_start(dev->phydev);
|
phy_start(dev->phydev);
|
||||||
|
@ -789,7 +759,6 @@ static int fs_enet_close(struct net_device *dev)
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
netif_carrier_off(dev);
|
netif_carrier_off(dev);
|
||||||
napi_disable(&fep->napi);
|
napi_disable(&fep->napi);
|
||||||
napi_disable(&fep->napi_tx);
|
|
||||||
phy_stop(dev->phydev);
|
phy_stop(dev->phydev);
|
||||||
|
|
||||||
spin_lock_irqsave(&fep->lock, flags);
|
spin_lock_irqsave(&fep->lock, flags);
|
||||||
|
@ -861,6 +830,44 @@ static void fs_set_msglevel(struct net_device *dev, u32 value)
|
||||||
fep->msg_enable = value;
|
fep->msg_enable = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fs_get_tunable(struct net_device *dev,
|
||||||
|
const struct ethtool_tunable *tuna, void *data)
|
||||||
|
{
|
||||||
|
struct fs_enet_private *fep = netdev_priv(dev);
|
||||||
|
struct fs_platform_info *fpi = fep->fpi;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
switch (tuna->id) {
|
||||||
|
case ETHTOOL_RX_COPYBREAK:
|
||||||
|
*(u32 *)data = fpi->rx_copybreak;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fs_set_tunable(struct net_device *dev,
|
||||||
|
const struct ethtool_tunable *tuna, const void *data)
|
||||||
|
{
|
||||||
|
struct fs_enet_private *fep = netdev_priv(dev);
|
||||||
|
struct fs_platform_info *fpi = fep->fpi;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
switch (tuna->id) {
|
||||||
|
case ETHTOOL_RX_COPYBREAK:
|
||||||
|
fpi->rx_copybreak = *(u32 *)data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct ethtool_ops fs_ethtool_ops = {
|
static const struct ethtool_ops fs_ethtool_ops = {
|
||||||
.get_drvinfo = fs_get_drvinfo,
|
.get_drvinfo = fs_get_drvinfo,
|
||||||
.get_regs_len = fs_get_regs_len,
|
.get_regs_len = fs_get_regs_len,
|
||||||
|
@ -872,6 +879,8 @@ static const struct ethtool_ops fs_ethtool_ops = {
|
||||||
.get_ts_info = ethtool_op_get_ts_info,
|
.get_ts_info = ethtool_op_get_ts_info,
|
||||||
.get_link_ksettings = phy_ethtool_get_link_ksettings,
|
.get_link_ksettings = phy_ethtool_get_link_ksettings,
|
||||||
.set_link_ksettings = phy_ethtool_set_link_ksettings,
|
.set_link_ksettings = phy_ethtool_set_link_ksettings,
|
||||||
|
.get_tunable = fs_get_tunable,
|
||||||
|
.set_tunable = fs_set_tunable,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||||
|
@ -939,8 +948,8 @@ static int fs_enet_probe(struct platform_device *ofdev)
|
||||||
fpi->cp_command = *data;
|
fpi->cp_command = *data;
|
||||||
}
|
}
|
||||||
|
|
||||||
fpi->rx_ring = 32;
|
fpi->rx_ring = RX_RING_SIZE;
|
||||||
fpi->tx_ring = 64;
|
fpi->tx_ring = TX_RING_SIZE;
|
||||||
fpi->rx_copybreak = 240;
|
fpi->rx_copybreak = 240;
|
||||||
fpi->napi_weight = 17;
|
fpi->napi_weight = 17;
|
||||||
fpi->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0);
|
fpi->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0);
|
||||||
|
@ -1024,8 +1033,7 @@ static int fs_enet_probe(struct platform_device *ofdev)
|
||||||
|
|
||||||
ndev->netdev_ops = &fs_enet_netdev_ops;
|
ndev->netdev_ops = &fs_enet_netdev_ops;
|
||||||
ndev->watchdog_timeo = 2 * HZ;
|
ndev->watchdog_timeo = 2 * HZ;
|
||||||
netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi, fpi->napi_weight);
|
netif_napi_add(ndev, &fep->napi, fs_enet_napi, fpi->napi_weight);
|
||||||
netif_tx_napi_add(ndev, &fep->napi_tx, fs_enet_tx_napi, 2);
|
|
||||||
|
|
||||||
ndev->ethtool_ops = &fs_ethtool_ops;
|
ndev->ethtool_ops = &fs_ethtool_ops;
|
||||||
|
|
||||||
|
|
|
@ -81,12 +81,9 @@ struct fs_ops {
|
||||||
void (*adjust_link)(struct net_device *dev);
|
void (*adjust_link)(struct net_device *dev);
|
||||||
void (*restart)(struct net_device *dev);
|
void (*restart)(struct net_device *dev);
|
||||||
void (*stop)(struct net_device *dev);
|
void (*stop)(struct net_device *dev);
|
||||||
void (*napi_clear_rx_event)(struct net_device *dev);
|
void (*napi_clear_event)(struct net_device *dev);
|
||||||
void (*napi_enable_rx)(struct net_device *dev);
|
void (*napi_enable)(struct net_device *dev);
|
||||||
void (*napi_disable_rx)(struct net_device *dev);
|
void (*napi_disable)(struct net_device *dev);
|
||||||
void (*napi_clear_tx_event)(struct net_device *dev);
|
|
||||||
void (*napi_enable_tx)(struct net_device *dev);
|
|
||||||
void (*napi_disable_tx)(struct net_device *dev);
|
|
||||||
void (*rx_bd_done)(struct net_device *dev);
|
void (*rx_bd_done)(struct net_device *dev);
|
||||||
void (*tx_kickstart)(struct net_device *dev);
|
void (*tx_kickstart)(struct net_device *dev);
|
||||||
u32 (*get_int_events)(struct net_device *dev);
|
u32 (*get_int_events)(struct net_device *dev);
|
||||||
|
@ -122,7 +119,6 @@ struct phy_info {
|
||||||
|
|
||||||
struct fs_enet_private {
|
struct fs_enet_private {
|
||||||
struct napi_struct napi;
|
struct napi_struct napi;
|
||||||
struct napi_struct napi_tx;
|
|
||||||
struct device *dev; /* pointer back to the device (must be initialized first) */
|
struct device *dev; /* pointer back to the device (must be initialized first) */
|
||||||
struct net_device *ndev;
|
struct net_device *ndev;
|
||||||
spinlock_t lock; /* during all ops except TX pckt processing */
|
spinlock_t lock; /* during all ops except TX pckt processing */
|
||||||
|
@ -152,10 +148,8 @@ struct fs_enet_private {
|
||||||
int oldduplex, oldspeed, oldlink; /* current settings */
|
int oldduplex, oldspeed, oldlink; /* current settings */
|
||||||
|
|
||||||
/* event masks */
|
/* event masks */
|
||||||
u32 ev_napi_rx; /* mask of NAPI rx events */
|
u32 ev_napi; /* mask of NAPI events */
|
||||||
u32 ev_napi_tx; /* mask of NAPI rx events */
|
u32 ev; /* event mask */
|
||||||
u32 ev_rx; /* rx event mask */
|
|
||||||
u32 ev_tx; /* tx event mask */
|
|
||||||
u32 ev_err; /* error event mask */
|
u32 ev_err; /* error event mask */
|
||||||
|
|
||||||
u16 bd_rx_empty; /* mask of BD rx empty */
|
u16 bd_rx_empty; /* mask of BD rx empty */
|
||||||
|
|
|
@ -124,10 +124,8 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB)
|
#define FCC_NAPI_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB | FCC_ENET_TXB)
|
||||||
#define FCC_NAPI_TX_EVENT_MSK (FCC_ENET_TXB)
|
#define FCC_EVENT (FCC_ENET_RXF | FCC_ENET_TXB)
|
||||||
#define FCC_RX_EVENT (FCC_ENET_RXF)
|
|
||||||
#define FCC_TX_EVENT (FCC_ENET_TXB)
|
|
||||||
#define FCC_ERR_EVENT_MSK (FCC_ENET_TXE)
|
#define FCC_ERR_EVENT_MSK (FCC_ENET_TXE)
|
||||||
|
|
||||||
static int setup_data(struct net_device *dev)
|
static int setup_data(struct net_device *dev)
|
||||||
|
@ -137,10 +135,8 @@ static int setup_data(struct net_device *dev)
|
||||||
if (do_pd_setup(fep) != 0)
|
if (do_pd_setup(fep) != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
fep->ev_napi_rx = FCC_NAPI_RX_EVENT_MSK;
|
fep->ev_napi = FCC_NAPI_EVENT_MSK;
|
||||||
fep->ev_napi_tx = FCC_NAPI_TX_EVENT_MSK;
|
fep->ev = FCC_EVENT;
|
||||||
fep->ev_rx = FCC_RX_EVENT;
|
|
||||||
fep->ev_tx = FCC_TX_EVENT;
|
|
||||||
fep->ev_err = FCC_ERR_EVENT_MSK;
|
fep->ev_err = FCC_ERR_EVENT_MSK;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -424,52 +420,28 @@ static void stop(struct net_device *dev)
|
||||||
fs_cleanup_bds(dev);
|
fs_cleanup_bds(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void napi_clear_rx_event(struct net_device *dev)
|
static void napi_clear_event_fs(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
struct fs_enet_private *fep = netdev_priv(dev);
|
||||||
fcc_t __iomem *fccp = fep->fcc.fccp;
|
fcc_t __iomem *fccp = fep->fcc.fccp;
|
||||||
|
|
||||||
W16(fccp, fcc_fcce, FCC_NAPI_RX_EVENT_MSK);
|
W16(fccp, fcc_fcce, FCC_NAPI_EVENT_MSK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void napi_enable_rx(struct net_device *dev)
|
static void napi_enable_fs(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
struct fs_enet_private *fep = netdev_priv(dev);
|
||||||
fcc_t __iomem *fccp = fep->fcc.fccp;
|
fcc_t __iomem *fccp = fep->fcc.fccp;
|
||||||
|
|
||||||
S16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK);
|
S16(fccp, fcc_fccm, FCC_NAPI_EVENT_MSK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void napi_disable_rx(struct net_device *dev)
|
static void napi_disable_fs(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
struct fs_enet_private *fep = netdev_priv(dev);
|
||||||
fcc_t __iomem *fccp = fep->fcc.fccp;
|
fcc_t __iomem *fccp = fep->fcc.fccp;
|
||||||
|
|
||||||
C16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK);
|
C16(fccp, fcc_fccm, FCC_NAPI_EVENT_MSK);
|
||||||
}
|
|
||||||
|
|
||||||
static void napi_clear_tx_event(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
|
||||||
fcc_t __iomem *fccp = fep->fcc.fccp;
|
|
||||||
|
|
||||||
W16(fccp, fcc_fcce, FCC_NAPI_TX_EVENT_MSK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void napi_enable_tx(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
|
||||||
fcc_t __iomem *fccp = fep->fcc.fccp;
|
|
||||||
|
|
||||||
S16(fccp, fcc_fccm, FCC_NAPI_TX_EVENT_MSK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void napi_disable_tx(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
|
||||||
fcc_t __iomem *fccp = fep->fcc.fccp;
|
|
||||||
|
|
||||||
C16(fccp, fcc_fccm, FCC_NAPI_TX_EVENT_MSK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rx_bd_done(struct net_device *dev)
|
static void rx_bd_done(struct net_device *dev)
|
||||||
|
@ -595,12 +567,9 @@ const struct fs_ops fs_fcc_ops = {
|
||||||
.set_multicast_list = set_multicast_list,
|
.set_multicast_list = set_multicast_list,
|
||||||
.restart = restart,
|
.restart = restart,
|
||||||
.stop = stop,
|
.stop = stop,
|
||||||
.napi_clear_rx_event = napi_clear_rx_event,
|
.napi_clear_event = napi_clear_event_fs,
|
||||||
.napi_enable_rx = napi_enable_rx,
|
.napi_enable = napi_enable_fs,
|
||||||
.napi_disable_rx = napi_disable_rx,
|
.napi_disable = napi_disable_fs,
|
||||||
.napi_clear_tx_event = napi_clear_tx_event,
|
|
||||||
.napi_enable_tx = napi_enable_tx,
|
|
||||||
.napi_disable_tx = napi_disable_tx,
|
|
||||||
.rx_bd_done = rx_bd_done,
|
.rx_bd_done = rx_bd_done,
|
||||||
.tx_kickstart = tx_kickstart,
|
.tx_kickstart = tx_kickstart,
|
||||||
.get_int_events = get_int_events,
|
.get_int_events = get_int_events,
|
||||||
|
|
|
@ -109,10 +109,8 @@ static int do_pd_setup(struct fs_enet_private *fep)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FEC_NAPI_RX_EVENT_MSK (FEC_ENET_RXF | FEC_ENET_RXB)
|
#define FEC_NAPI_EVENT_MSK (FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_TXF)
|
||||||
#define FEC_NAPI_TX_EVENT_MSK (FEC_ENET_TXF)
|
#define FEC_EVENT (FEC_ENET_RXF | FEC_ENET_TXF)
|
||||||
#define FEC_RX_EVENT (FEC_ENET_RXF)
|
|
||||||
#define FEC_TX_EVENT (FEC_ENET_TXF)
|
|
||||||
#define FEC_ERR_EVENT_MSK (FEC_ENET_HBERR | FEC_ENET_BABR | \
|
#define FEC_ERR_EVENT_MSK (FEC_ENET_HBERR | FEC_ENET_BABR | \
|
||||||
FEC_ENET_BABT | FEC_ENET_EBERR)
|
FEC_ENET_BABT | FEC_ENET_EBERR)
|
||||||
|
|
||||||
|
@ -126,10 +124,8 @@ static int setup_data(struct net_device *dev)
|
||||||
fep->fec.hthi = 0;
|
fep->fec.hthi = 0;
|
||||||
fep->fec.htlo = 0;
|
fep->fec.htlo = 0;
|
||||||
|
|
||||||
fep->ev_napi_rx = FEC_NAPI_RX_EVENT_MSK;
|
fep->ev_napi = FEC_NAPI_EVENT_MSK;
|
||||||
fep->ev_napi_tx = FEC_NAPI_TX_EVENT_MSK;
|
fep->ev = FEC_EVENT;
|
||||||
fep->ev_rx = FEC_RX_EVENT;
|
|
||||||
fep->ev_tx = FEC_TX_EVENT;
|
|
||||||
fep->ev_err = FEC_ERR_EVENT_MSK;
|
fep->ev_err = FEC_ERR_EVENT_MSK;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -396,52 +392,28 @@ static void stop(struct net_device *dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void napi_clear_rx_event(struct net_device *dev)
|
static void napi_clear_event_fs(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
struct fs_enet_private *fep = netdev_priv(dev);
|
||||||
struct fec __iomem *fecp = fep->fec.fecp;
|
struct fec __iomem *fecp = fep->fec.fecp;
|
||||||
|
|
||||||
FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK);
|
FW(fecp, ievent, FEC_NAPI_EVENT_MSK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void napi_enable_rx(struct net_device *dev)
|
static void napi_enable_fs(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
struct fs_enet_private *fep = netdev_priv(dev);
|
||||||
struct fec __iomem *fecp = fep->fec.fecp;
|
struct fec __iomem *fecp = fep->fec.fecp;
|
||||||
|
|
||||||
FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
|
FS(fecp, imask, FEC_NAPI_EVENT_MSK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void napi_disable_rx(struct net_device *dev)
|
static void napi_disable_fs(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
struct fs_enet_private *fep = netdev_priv(dev);
|
||||||
struct fec __iomem *fecp = fep->fec.fecp;
|
struct fec __iomem *fecp = fep->fec.fecp;
|
||||||
|
|
||||||
FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
|
FC(fecp, imask, FEC_NAPI_EVENT_MSK);
|
||||||
}
|
|
||||||
|
|
||||||
static void napi_clear_tx_event(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
|
||||||
struct fec __iomem *fecp = fep->fec.fecp;
|
|
||||||
|
|
||||||
FW(fecp, ievent, FEC_NAPI_TX_EVENT_MSK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void napi_enable_tx(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
|
||||||
struct fec __iomem *fecp = fep->fec.fecp;
|
|
||||||
|
|
||||||
FS(fecp, imask, FEC_NAPI_TX_EVENT_MSK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void napi_disable_tx(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
|
||||||
struct fec __iomem *fecp = fep->fec.fecp;
|
|
||||||
|
|
||||||
FC(fecp, imask, FEC_NAPI_TX_EVENT_MSK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rx_bd_done(struct net_device *dev)
|
static void rx_bd_done(struct net_device *dev)
|
||||||
|
@ -513,12 +485,9 @@ const struct fs_ops fs_fec_ops = {
|
||||||
.set_multicast_list = set_multicast_list,
|
.set_multicast_list = set_multicast_list,
|
||||||
.restart = restart,
|
.restart = restart,
|
||||||
.stop = stop,
|
.stop = stop,
|
||||||
.napi_clear_rx_event = napi_clear_rx_event,
|
.napi_clear_event = napi_clear_event_fs,
|
||||||
.napi_enable_rx = napi_enable_rx,
|
.napi_enable = napi_enable_fs,
|
||||||
.napi_disable_rx = napi_disable_rx,
|
.napi_disable = napi_disable_fs,
|
||||||
.napi_clear_tx_event = napi_clear_tx_event,
|
|
||||||
.napi_enable_tx = napi_enable_tx,
|
|
||||||
.napi_disable_tx = napi_disable_tx,
|
|
||||||
.rx_bd_done = rx_bd_done,
|
.rx_bd_done = rx_bd_done,
|
||||||
.tx_kickstart = tx_kickstart,
|
.tx_kickstart = tx_kickstart,
|
||||||
.get_int_events = get_int_events,
|
.get_int_events = get_int_events,
|
||||||
|
|
|
@ -115,10 +115,8 @@ static int do_pd_setup(struct fs_enet_private *fep)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SCC_NAPI_RX_EVENT_MSK (SCCE_ENET_RXF | SCCE_ENET_RXB)
|
#define SCC_NAPI_EVENT_MSK (SCCE_ENET_RXF | SCCE_ENET_RXB | SCCE_ENET_TXB)
|
||||||
#define SCC_NAPI_TX_EVENT_MSK (SCCE_ENET_TXB)
|
#define SCC_EVENT (SCCE_ENET_RXF | SCCE_ENET_TXB)
|
||||||
#define SCC_RX_EVENT (SCCE_ENET_RXF)
|
|
||||||
#define SCC_TX_EVENT (SCCE_ENET_TXB)
|
|
||||||
#define SCC_ERR_EVENT_MSK (SCCE_ENET_TXE | SCCE_ENET_BSY)
|
#define SCC_ERR_EVENT_MSK (SCCE_ENET_TXE | SCCE_ENET_BSY)
|
||||||
|
|
||||||
static int setup_data(struct net_device *dev)
|
static int setup_data(struct net_device *dev)
|
||||||
|
@ -130,10 +128,8 @@ static int setup_data(struct net_device *dev)
|
||||||
fep->scc.hthi = 0;
|
fep->scc.hthi = 0;
|
||||||
fep->scc.htlo = 0;
|
fep->scc.htlo = 0;
|
||||||
|
|
||||||
fep->ev_napi_rx = SCC_NAPI_RX_EVENT_MSK;
|
fep->ev_napi = SCC_NAPI_EVENT_MSK;
|
||||||
fep->ev_napi_tx = SCC_NAPI_TX_EVENT_MSK;
|
fep->ev = SCC_EVENT | SCCE_ENET_TXE;
|
||||||
fep->ev_rx = SCC_RX_EVENT;
|
|
||||||
fep->ev_tx = SCC_TX_EVENT | SCCE_ENET_TXE;
|
|
||||||
fep->ev_err = SCC_ERR_EVENT_MSK;
|
fep->ev_err = SCC_ERR_EVENT_MSK;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -379,52 +375,28 @@ static void stop(struct net_device *dev)
|
||||||
fs_cleanup_bds(dev);
|
fs_cleanup_bds(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void napi_clear_rx_event(struct net_device *dev)
|
static void napi_clear_event_fs(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
struct fs_enet_private *fep = netdev_priv(dev);
|
||||||
scc_t __iomem *sccp = fep->scc.sccp;
|
scc_t __iomem *sccp = fep->scc.sccp;
|
||||||
|
|
||||||
W16(sccp, scc_scce, SCC_NAPI_RX_EVENT_MSK);
|
W16(sccp, scc_scce, SCC_NAPI_EVENT_MSK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void napi_enable_rx(struct net_device *dev)
|
static void napi_enable_fs(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
struct fs_enet_private *fep = netdev_priv(dev);
|
||||||
scc_t __iomem *sccp = fep->scc.sccp;
|
scc_t __iomem *sccp = fep->scc.sccp;
|
||||||
|
|
||||||
S16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
|
S16(sccp, scc_sccm, SCC_NAPI_EVENT_MSK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void napi_disable_rx(struct net_device *dev)
|
static void napi_disable_fs(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
struct fs_enet_private *fep = netdev_priv(dev);
|
||||||
scc_t __iomem *sccp = fep->scc.sccp;
|
scc_t __iomem *sccp = fep->scc.sccp;
|
||||||
|
|
||||||
C16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
|
C16(sccp, scc_sccm, SCC_NAPI_EVENT_MSK);
|
||||||
}
|
|
||||||
|
|
||||||
static void napi_clear_tx_event(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
|
||||||
scc_t __iomem *sccp = fep->scc.sccp;
|
|
||||||
|
|
||||||
W16(sccp, scc_scce, SCC_NAPI_TX_EVENT_MSK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void napi_enable_tx(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
|
||||||
scc_t __iomem *sccp = fep->scc.sccp;
|
|
||||||
|
|
||||||
S16(sccp, scc_sccm, SCC_NAPI_TX_EVENT_MSK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void napi_disable_tx(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct fs_enet_private *fep = netdev_priv(dev);
|
|
||||||
scc_t __iomem *sccp = fep->scc.sccp;
|
|
||||||
|
|
||||||
C16(sccp, scc_sccm, SCC_NAPI_TX_EVENT_MSK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rx_bd_done(struct net_device *dev)
|
static void rx_bd_done(struct net_device *dev)
|
||||||
|
@ -497,12 +469,9 @@ const struct fs_ops fs_scc_ops = {
|
||||||
.set_multicast_list = set_multicast_list,
|
.set_multicast_list = set_multicast_list,
|
||||||
.restart = restart,
|
.restart = restart,
|
||||||
.stop = stop,
|
.stop = stop,
|
||||||
.napi_clear_rx_event = napi_clear_rx_event,
|
.napi_clear_event = napi_clear_event_fs,
|
||||||
.napi_enable_rx = napi_enable_rx,
|
.napi_enable = napi_enable_fs,
|
||||||
.napi_disable_rx = napi_disable_rx,
|
.napi_disable = napi_disable_fs,
|
||||||
.napi_clear_tx_event = napi_clear_tx_event,
|
|
||||||
.napi_enable_tx = napi_enable_tx,
|
|
||||||
.napi_disable_tx = napi_disable_tx,
|
|
||||||
.rx_bd_done = rx_bd_done,
|
.rx_bd_done = rx_bd_done,
|
||||||
.tx_kickstart = tx_kickstart,
|
.tx_kickstart = tx_kickstart,
|
||||||
.get_int_events = get_int_events,
|
.get_int_events = get_int_events,
|
||||||
|
|
Loading…
Reference in New Issue