Skip to content

Commit

Permalink
[PATCH] sky2: big endian
Browse files Browse the repository at this point in the history
Fix support for big endian platforms like PPC.
Still not sure about VLAN acceleration (does it need swapping)?

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
  • Loading branch information
Stephen Hemminger authored and Jeff Garzik committed Sep 13, 2006
1 parent b89165f commit f65b138
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 37 deletions.
43 changes: 22 additions & 21 deletions drivers/net/sky2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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
Expand All @@ -1286,28 +1285,29 @@ 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;
}
}

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);
Expand All @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
19 changes: 3 additions & 16 deletions drivers/net/sky2.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
__le32 addr;
__le16 length; /* also vlan tag or checksum start */
u8 ctrl;
u8 opcode;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit f65b138

Please sign in to comment.