static void ks8842_rx_frame(struct net_device *netdev,
	struct ks8842_adapter *adapter)
{
	u32 status = ks8842_read32(adapter, 17, REG_QMU_DATA_LO);
	int len = (status >> 16) & 0x7ff;

	status &= 0xffff;

	dev_dbg(&adapter->pdev->dev, "%s - rx_data: status: %x\n",
		__func__, status);

	/* check the status */
	if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) {
		struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, len);

		dev_dbg(&adapter->pdev->dev, "%s, got package, len: %d\n",
			__func__, len);
		if (skb) {
			u32 *data;

			netdev->stats.rx_packets++;
			netdev->stats.rx_bytes += len;
			if (status & RXSR_MULTICAST)
				netdev->stats.multicast++;

			data = (u32 *)skb_put(skb, len);

			ks8842_select_bank(adapter, 17);
			while (len > 0) {
				*data++ = ioread32(adapter->hw_addr +
					REG_QMU_DATA_LO);
				len -= sizeof(u32);
			}

			skb->protocol = eth_type_trans(skb, netdev);
			netif_rx(skb);
		} else
			netdev->stats.rx_dropped++;
	} else {
		dev_dbg(&adapter->pdev->dev, "RX error, status: %x\n", status);
		netdev->stats.rx_errors++;
		if (status & RXSR_TOO_LONG)
			netdev->stats.rx_length_errors++;
		if (status & RXSR_CRC_ERROR)
			netdev->stats.rx_crc_errors++;
		if (status & RXSR_RUNT)
			netdev->stats.rx_frame_errors++;
	}

	/* set high watermark to 3K */
	ks8842_clear_bits(adapter, 0, 1 << 12, REG_QRFCR);

	/* release the frame */
	ks8842_write16(adapter, 17, 0x01, REG_RXQCR);

	/* set high watermark to 2K */
	ks8842_enable_bits(adapter, 0, 1 << 12, REG_QRFCR);
}
Beispiel #2
0
static void ks8842_reset_hw(struct ks8842_adapter *adapter)
{
	/* reset the HW */
	ks8842_reset(adapter);

	/* Enable QMU Transmit flow control / transmit padding / Transmit CRC */
	ks8842_write16(adapter, 16, 0x000E, REG_TXCR);

	/* enable the receiver, uni + multi + broadcast + flow ctrl
		+ crc strip */
	ks8842_write16(adapter, 16, 0x8 | 0x20 | 0x40 | 0x80 | 0x400,
		REG_RXCR);

	/* TX frame pointer autoincrement */
	ks8842_write16(adapter, 17, 0x4000, REG_TXFDPR);

	/* RX frame pointer autoincrement */
	ks8842_write16(adapter, 17, 0x4000, REG_RXFDPR);

	/* RX 2 kb high watermark */
	ks8842_write16(adapter, 0, 0x1000, REG_QRFCR);

	/* aggresive back off in half duplex */
	ks8842_enable_bits(adapter, 32, 1 << 8, REG_SGCR1);

	/* enable no excessive collison drop */
	ks8842_enable_bits(adapter, 32, 1 << 3, REG_SGCR2);

	/* Enable port 1 force flow control / back pressure / transmit / recv */
	ks8842_write16(adapter, 48, 0x1E07, REG_P1CR2);

	/* restart port auto-negotiation */
	ks8842_enable_bits(adapter, 49, 1 << 13, REG_P1CR4);
	/* only advertise 10Mbps */
	ks8842_clear_bits(adapter, 49, 3 << 2, REG_P1CR4);

	/* Enable the transmitter */
	ks8842_enable_tx(adapter);

	/* Enable the receiver */
	ks8842_enable_rx(adapter);

	/* clear all interrupts */
	ks8842_write16(adapter, 18, 0xffff, REG_ISR);

	/* enable interrupts */
	ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);

	/* enable the switch */
	ks8842_write16(adapter, 32, 0x1, REG_SW_ID_AND_ENABLE);
}
Beispiel #3
0
static void ks8842_disable_rx(struct ks8842_adapter *adapter)
{
	ks8842_clear_bits(adapter, 16, 0x01, REG_RXCR);
}