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); }
static inline void ks8842_clear_bits(struct ks8842_adapter *adapter, u16 bank, u16 bits, int offset) { u16 reg; ks8842_select_bank(adapter, bank); reg = ioread16(adapter->hw_addr + offset); reg &= ~bits; iowrite16(reg, adapter->hw_addr + offset); }
static inline u32 ks8842_read32(struct ks8842_adapter *adapter, u16 bank, int offset) { ks8842_select_bank(adapter, bank); return ioread32(adapter->hw_addr + offset); }
static inline void ks8842_write32(struct ks8842_adapter *adapter, u16 bank, u32 value, int offset) { ks8842_select_bank(adapter, bank); iowrite32(value, adapter->hw_addr + offset); }