Skip to content

Commit

Permalink
drivers/net: ks8851_mll ethernet network driver -resubmit
Browse files Browse the repository at this point in the history
Summary of Changes:

	-Fix to receive multicast packets by setting the corresponding hardware
	 bit during initialization.
	-Fix to re-enable the interface [by interface up command(ifup)] while the
	 interface is down.
	-Fix to be able to down the interface by passing the last parameter
	 correctly to request_irq().
	-Remove to read 4 extra bytes from the receiving queue after reading a
	 packet, even though it does not cause a predictable issue now.
	-Remove occurrences of transmission done interrupt in order to tx
	 throughput enhancement.
	-Enable IP checksum for packet receiving by setting the corresponding
	 hardware bit during initialization.
	-Relocate ks_enable_int()/ks_disable_int() in order not to declare those
	 functions at the beginning of the file.
	-Rename ks_enable()/_disable() to ks_enable_qmu()/ks_disable_qmu() in
	 order to give more meaningful names and relocate them not declaire
	 those functions at the beginning of the file.

Signed-off-by: David J. Choi <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davidchoi-micrel authored and davem330 committed Nov 20, 2009
1 parent 0ebe74e commit 4a91ca4
Showing 1 changed file with 68 additions and 74 deletions.
142 changes: 68 additions & 74 deletions drivers/net/ks8851_mll.c
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,16 @@ static inline void ks_outblk(struct ks_net *ks, u16 *wptr, u32 len)
iowrite16(*wptr++, ks->hw_addr);
}

static void ks_disable_int(struct ks_net *ks)
{
ks_wrreg16(ks, KS_IER, 0x0000);
} /* ks_disable_int */

static void ks_enable_int(struct ks_net *ks)
{
ks_wrreg16(ks, KS_IER, ks->rc_ier);
} /* ks_enable_int */

/**
* ks_tx_fifo_space - return the available hardware buffer size.
* @ks: The chip information
Expand Down Expand Up @@ -681,6 +691,47 @@ static void ks_soft_reset(struct ks_net *ks, unsigned op)
}


void ks_enable_qmu(struct ks_net *ks)
{
u16 w;

w = ks_rdreg16(ks, KS_TXCR);
/* Enables QMU Transmit (TXCR). */
ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE);

/*
* RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame
* Enable
*/

w = ks_rdreg16(ks, KS_RXQCR);
ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE);

/* Enables QMU Receive (RXCR1). */
w = ks_rdreg16(ks, KS_RXCR1);
ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE);
ks->enabled = true;
} /* ks_enable_qmu */

static void ks_disable_qmu(struct ks_net *ks)
{
u16 w;

w = ks_rdreg16(ks, KS_TXCR);

/* Disables QMU Transmit (TXCR). */
w &= ~TXCR_TXE;
ks_wrreg16(ks, KS_TXCR, w);

/* Disables QMU Receive (RXCR1). */
w = ks_rdreg16(ks, KS_RXCR1);
w &= ~RXCR1_RXE ;
ks_wrreg16(ks, KS_RXCR1, w);

ks->enabled = false;

} /* ks_disable_qmu */

/**
* ks_read_qmu - read 1 pkt data from the QMU.
* @ks: The chip information
Expand Down Expand Up @@ -752,7 +803,7 @@ static void ks_rcv(struct ks_net *ks, struct net_device *netdev)
(frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) {
skb_reserve(skb, 2);
/* read data block including CRC 4 bytes */
ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len + 4);
ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len);
skb_put(skb, frame_hdr->len);
skb->dev = netdev;
skb->protocol = eth_type_trans(skb, netdev);
Expand Down Expand Up @@ -861,14 +912,23 @@ static int ks_net_open(struct net_device *netdev)
ks_dbg(ks, "%s - entry\n", __func__);

/* reset the HW */
err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, ks);
err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, netdev);

if (err) {
printk(KERN_ERR "Failed to request IRQ: %d: %d\n",
ks->irq, err);
return err;
}

/* wake up powermode to normal mode */
ks_set_powermode(ks, PMECR_PM_NORMAL);
mdelay(1); /* wait for normal mode to take effect */

ks_wrreg16(ks, KS_ISR, 0xffff);
ks_enable_int(ks);
ks_enable_qmu(ks);
netif_start_queue(ks->netdev);

if (netif_msg_ifup(ks))
ks_dbg(ks, "network device %s up\n", netdev->name);

Expand All @@ -892,19 +952,14 @@ static int ks_net_stop(struct net_device *netdev)

netif_stop_queue(netdev);

kfree(ks->frame_head_info);

mutex_lock(&ks->lock);

/* turn off the IRQs and ack any outstanding */
ks_wrreg16(ks, KS_IER, 0x0000);
ks_wrreg16(ks, KS_ISR, 0xffff);

/* shutdown RX process */
ks_wrreg16(ks, KS_RXCR1, 0x0000);

/* shutdown TX process */
ks_wrreg16(ks, KS_TXCR, 0x0000);
/* shutdown RX/TX QMU */
ks_disable_qmu(ks);

/* set powermode to soft power down to save power */
ks_set_powermode(ks, PMECR_PM_SOFTDOWN);
Expand All @@ -929,17 +984,8 @@ static int ks_net_stop(struct net_device *netdev)
*/
static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len)
{
unsigned fid = ks->fid;

fid = ks->fid;
ks->fid = (ks->fid + 1) & TXFR_TXFID_MASK;

/* reduce the tx interrupt occurrances. */
if (!fid)
fid |= TXFR_TXIC; /* irq on completion */

/* start header at txb[0] to align txw entries */
ks->txh.txw[0] = cpu_to_le16(fid);
ks->txh.txw[0] = 0;
ks->txh.txw[1] = cpu_to_le16(len);

/* 1. set sudo-DMA mode */
Expand All @@ -957,16 +1003,6 @@ static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len)
;
}

static void ks_disable_int(struct ks_net *ks)
{
ks_wrreg16(ks, KS_IER, 0x0000);
} /* ks_disable_int */

static void ks_enable_int(struct ks_net *ks)
{
ks_wrreg16(ks, KS_IER, ks->rc_ier);
} /* ks_enable_int */

/**
* ks_start_xmit - transmit packet
* @skb : The buffer to transmit
Expand Down Expand Up @@ -1410,25 +1446,6 @@ static int ks_read_selftest(struct ks_net *ks)
return ret;
}

static void ks_disable(struct ks_net *ks)
{
u16 w;

w = ks_rdreg16(ks, KS_TXCR);

/* Disables QMU Transmit (TXCR). */
w &= ~TXCR_TXE;
ks_wrreg16(ks, KS_TXCR, w);

/* Disables QMU Receive (RXCR1). */
w = ks_rdreg16(ks, KS_RXCR1);
w &= ~RXCR1_RXE ;
ks_wrreg16(ks, KS_RXCR1, w);

ks->enabled = false;

} /* ks_disable */

static void ks_setup(struct ks_net *ks)
{
u16 w;
Expand Down Expand Up @@ -1463,7 +1480,7 @@ static void ks_setup(struct ks_net *ks)
w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP;
ks_wrreg16(ks, KS_TXCR, w);

w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE;
w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME | RXCR1_RXIPFCC;

if (ks->promiscuous) /* bPromiscuous */
w |= (RXCR1_RXAE | RXCR1_RXINVF);
Expand All @@ -1486,28 +1503,6 @@ static void ks_setup_int(struct ks_net *ks)
ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI);
} /* ks_setup_int */

void ks_enable(struct ks_net *ks)
{
u16 w;

w = ks_rdreg16(ks, KS_TXCR);
/* Enables QMU Transmit (TXCR). */
ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE);

/*
* RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame
* Enable
*/

w = ks_rdreg16(ks, KS_RXQCR);
ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE);

/* Enables QMU Receive (RXCR1). */
w = ks_rdreg16(ks, KS_RXCR1);
ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE);
ks->enabled = true;
} /* ks_enable */

static int ks_hw_init(struct ks_net *ks)
{
#define MHEADER_SIZE (sizeof(struct type_frame_head) * MAX_RECV_FRAMES)
Expand Down Expand Up @@ -1612,11 +1607,9 @@ static int __devinit ks8851_probe(struct platform_device *pdev)

ks_soft_reset(ks, GRR_GSR);
ks_hw_init(ks);
ks_disable(ks);
ks_disable_qmu(ks);
ks_setup(ks);
ks_setup_int(ks);
ks_enable_int(ks);
ks_enable(ks);
memcpy(netdev->dev_addr, ks->mac_addr, 6);

data = ks_rdreg16(ks, KS_OBCR);
Expand Down Expand Up @@ -1658,6 +1651,7 @@ static int __devexit ks8851_remove(struct platform_device *pdev)
struct ks_net *ks = netdev_priv(netdev);
struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);

kfree(ks->frame_head_info);
unregister_netdev(netdev);
iounmap(ks->hw_addr);
free_netdev(netdev);
Expand Down

0 comments on commit 4a91ca4

Please sign in to comment.