Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f65b138c authored by Stephen Hemminger's avatar Stephen Hemminger Committed by Jeff Garzik
Browse files

[PATCH] sky2: big endian



Fix support for big endian platforms like PPC.
Still not sure about VLAN acceleration (does it need swapping)?

Signed-off-by: default avatarStephen Hemminger <shemminger@osdl.org>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent b89165f2
Loading
Loading
Loading
Loading
+22 −21
Original line number Diff line number Diff line
@@ -827,7 +827,7 @@ static void rx_set_checksum(struct sky2_port *sky2)
	struct sky2_rx_le *le;

	le = sky2_next_rx(sky2);
	le->addr = (ETH_HLEN << 16) | ETH_HLEN;
	le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN);
	le->ctrl = 0;
	le->opcode = OP_TCPSTART | HW_OWNER;

@@ -1245,7 +1245,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
	/* Send high bits if changed or crosses boundary */
	if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) {
		le = get_tx_le(sky2);
		le->tx.addr = cpu_to_le32(addr64);
		le->addr = cpu_to_le32(addr64);
		le->ctrl = 0;
		le->opcode = OP_ADDR64 | HW_OWNER;
		sky2->tx_addr64 = high32(mapping + len);
@@ -1260,8 +1260,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)

		if (mss != sky2->tx_last_mss) {
			le = get_tx_le(sky2);
			le->tx.tso.size = cpu_to_le16(mss);
			le->tx.tso.rsvd = 0;
			le->addr = cpu_to_le32(mss);
			le->opcode = OP_LRGLEN | HW_OWNER;
			le->ctrl = 0;
			sky2->tx_last_mss = mss;
@@ -1274,7 +1273,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
	if (sky2->vlgrp && vlan_tx_tag_present(skb)) {
		if (!le) {
			le = get_tx_le(sky2);
			le->tx.addr = 0;
			le->addr = 0;
			le->opcode = OP_VLAN|HW_OWNER;
			le->ctrl = 0;
		} else
@@ -1286,20 +1285,21 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)

	/* Handle TCP checksum offload */
	if (skb->ip_summed == CHECKSUM_HW) {
		u16 hdr = skb->h.raw - skb->data;
		u16 offset = hdr + skb->csum;
		unsigned offset = skb->h.raw - skb->data;
		u32 tcpsum;

		tcpsum = offset << 16;		/* sum start */
		tcpsum |= offset + skb->csum;	/* sum write */

		ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
		if (skb->nh.iph->protocol == IPPROTO_UDP)
			ctrl |= UDPTCP;

		if (hdr != sky2->tx_csum_start || offset != sky2->tx_csum_offset) {
			sky2->tx_csum_start = hdr;
			sky2->tx_csum_offset = offset;
		if (tcpsum != sky2->tx_tcpsum) {
			sky2->tx_tcpsum = tcpsum;

			le = get_tx_le(sky2);
			le->tx.csum.start = cpu_to_le16(hdr);
			le->tx.csum.offset = cpu_to_le16(offset);
			le->addr = cpu_to_le32(tcpsum);
			le->length = 0;	/* initial checksum value */
			le->ctrl = 1;	/* one packet */
			le->opcode = OP_TCPLISW | HW_OWNER;
@@ -1307,7 +1307,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
	}

	le = get_tx_le(sky2);
	le->tx.addr = cpu_to_le32((u32) mapping);
	le->addr = cpu_to_le32((u32) mapping);
	le->length = cpu_to_le16(len);
	le->ctrl = ctrl;
	le->opcode = mss ? (OP_LARGESEND | HW_OWNER) : (OP_PACKET | HW_OWNER);
@@ -1325,14 +1325,14 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
		addr64 = high32(mapping);
		if (addr64 != sky2->tx_addr64) {
			le = get_tx_le(sky2);
			le->tx.addr = cpu_to_le32(addr64);
			le->addr = cpu_to_le32(addr64);
			le->ctrl = 0;
			le->opcode = OP_ADDR64 | HW_OWNER;
			sky2->tx_addr64 = addr64;
		}

		le = get_tx_le(sky2);
		le->tx.addr = cpu_to_le32((u32) mapping);
		le->addr = cpu_to_le32((u32) mapping);
		le->length = cpu_to_le16(frag->size);
		le->ctrl = ctrl;
		le->opcode = OP_BUFFER | HW_OWNER;
@@ -1938,8 +1938,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
		dev = hw->dev[le->link];

		sky2 = netdev_priv(dev);
		length = le->length;
		status = le->status;
		length = le16_to_cpu(le->length);
		status = le32_to_cpu(le->status);

		switch (le->opcode & ~HW_OWNER) {
		case OP_RXSTAT:
@@ -1983,7 +1983,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
		case OP_RXCHKS:
			skb = sky2->rx_ring[sky2->rx_next].skb;
			skb->ip_summed = CHECKSUM_HW;
			skb->csum = le16_to_cpu(status);
			skb->csum = status & 0xffff;
			break;

		case OP_TXINDEXLE:
@@ -3286,12 +3286,13 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
	hw->pm_cap = pm_cap;

#ifdef __BIG_ENDIAN
	/* byte swap descriptors in hardware */
	/* The sk98lin vendor driver uses hardware byte swapping but
	 * this driver uses software swapping.
	 */
	{
		u32 reg;

		reg = sky2_pci_read32(hw, PCI_DEV_REG2);
		reg |= PCI_REV_DESC;
		reg &= ~PCI_REV_DESC;
		sky2_pci_write32(hw, PCI_DEV_REG2, reg);
	}
#endif
+3 −16
Original line number Diff line number Diff line
@@ -1791,21 +1791,9 @@ enum {
	OP_TXINDEXLE	= 0x68,
};

/* Yukon 2 hardware interface
 * Not tested on big endian
 */
/* Yukon 2 hardware interface */
struct sky2_tx_le {
	union {
	__le32	addr;
		struct {
			__le16	offset;
			__le16	start;
		} csum  __attribute((packed));
		struct {
			__le16	size;
			__le16	rsvd;
		} tso  __attribute((packed));
	} tx;
	__le16	length;	/* also vlan tag or checksum start */
	u8	ctrl;
	u8	opcode;
@@ -1851,8 +1839,7 @@ struct sky2_port {
	u32		     tx_addr64;
	u16		     tx_pending;
	u16		     tx_last_mss;
	u16		     tx_csum_start;
	u16		     tx_csum_offset;
	u32		     tx_tcpsum;

	struct ring_info     *rx_ring ____cacheline_aligned_in_smp;
	struct sky2_rx_le    *rx_le;