mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-12 08:48:48 +00:00
[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: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
b89165f2b7
commit
f65b138ca9
@ -827,7 +827,7 @@ static void rx_set_checksum(struct sky2_port *sky2)
|
|||||||
struct sky2_rx_le *le;
|
struct sky2_rx_le *le;
|
||||||
|
|
||||||
le = sky2_next_rx(sky2);
|
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->ctrl = 0;
|
||||||
le->opcode = OP_TCPSTART | HW_OWNER;
|
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 */
|
/* Send high bits if changed or crosses boundary */
|
||||||
if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) {
|
if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) {
|
||||||
le = get_tx_le(sky2);
|
le = get_tx_le(sky2);
|
||||||
le->tx.addr = cpu_to_le32(addr64);
|
le->addr = cpu_to_le32(addr64);
|
||||||
le->ctrl = 0;
|
le->ctrl = 0;
|
||||||
le->opcode = OP_ADDR64 | HW_OWNER;
|
le->opcode = OP_ADDR64 | HW_OWNER;
|
||||||
sky2->tx_addr64 = high32(mapping + len);
|
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) {
|
if (mss != sky2->tx_last_mss) {
|
||||||
le = get_tx_le(sky2);
|
le = get_tx_le(sky2);
|
||||||
le->tx.tso.size = cpu_to_le16(mss);
|
le->addr = cpu_to_le32(mss);
|
||||||
le->tx.tso.rsvd = 0;
|
|
||||||
le->opcode = OP_LRGLEN | HW_OWNER;
|
le->opcode = OP_LRGLEN | HW_OWNER;
|
||||||
le->ctrl = 0;
|
le->ctrl = 0;
|
||||||
sky2->tx_last_mss = mss;
|
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 (sky2->vlgrp && vlan_tx_tag_present(skb)) {
|
||||||
if (!le) {
|
if (!le) {
|
||||||
le = get_tx_le(sky2);
|
le = get_tx_le(sky2);
|
||||||
le->tx.addr = 0;
|
le->addr = 0;
|
||||||
le->opcode = OP_VLAN|HW_OWNER;
|
le->opcode = OP_VLAN|HW_OWNER;
|
||||||
le->ctrl = 0;
|
le->ctrl = 0;
|
||||||
} else
|
} else
|
||||||
@ -1286,20 +1285,21 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
|
|||||||
|
|
||||||
/* Handle TCP checksum offload */
|
/* Handle TCP checksum offload */
|
||||||
if (skb->ip_summed == CHECKSUM_HW) {
|
if (skb->ip_summed == CHECKSUM_HW) {
|
||||||
u16 hdr = skb->h.raw - skb->data;
|
unsigned offset = skb->h.raw - skb->data;
|
||||||
u16 offset = hdr + skb->csum;
|
u32 tcpsum;
|
||||||
|
|
||||||
|
tcpsum = offset << 16; /* sum start */
|
||||||
|
tcpsum |= offset + skb->csum; /* sum write */
|
||||||
|
|
||||||
ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
|
ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
|
||||||
if (skb->nh.iph->protocol == IPPROTO_UDP)
|
if (skb->nh.iph->protocol == IPPROTO_UDP)
|
||||||
ctrl |= UDPTCP;
|
ctrl |= UDPTCP;
|
||||||
|
|
||||||
if (hdr != sky2->tx_csum_start || offset != sky2->tx_csum_offset) {
|
if (tcpsum != sky2->tx_tcpsum) {
|
||||||
sky2->tx_csum_start = hdr;
|
sky2->tx_tcpsum = tcpsum;
|
||||||
sky2->tx_csum_offset = offset;
|
|
||||||
|
|
||||||
le = get_tx_le(sky2);
|
le = get_tx_le(sky2);
|
||||||
le->tx.csum.start = cpu_to_le16(hdr);
|
le->addr = cpu_to_le32(tcpsum);
|
||||||
le->tx.csum.offset = cpu_to_le16(offset);
|
|
||||||
le->length = 0; /* initial checksum value */
|
le->length = 0; /* initial checksum value */
|
||||||
le->ctrl = 1; /* one packet */
|
le->ctrl = 1; /* one packet */
|
||||||
le->opcode = OP_TCPLISW | HW_OWNER;
|
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 = 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->length = cpu_to_le16(len);
|
||||||
le->ctrl = ctrl;
|
le->ctrl = ctrl;
|
||||||
le->opcode = mss ? (OP_LARGESEND | HW_OWNER) : (OP_PACKET | HW_OWNER);
|
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);
|
addr64 = high32(mapping);
|
||||||
if (addr64 != sky2->tx_addr64) {
|
if (addr64 != sky2->tx_addr64) {
|
||||||
le = get_tx_le(sky2);
|
le = get_tx_le(sky2);
|
||||||
le->tx.addr = cpu_to_le32(addr64);
|
le->addr = cpu_to_le32(addr64);
|
||||||
le->ctrl = 0;
|
le->ctrl = 0;
|
||||||
le->opcode = OP_ADDR64 | HW_OWNER;
|
le->opcode = OP_ADDR64 | HW_OWNER;
|
||||||
sky2->tx_addr64 = addr64;
|
sky2->tx_addr64 = addr64;
|
||||||
}
|
}
|
||||||
|
|
||||||
le = get_tx_le(sky2);
|
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->length = cpu_to_le16(frag->size);
|
||||||
le->ctrl = ctrl;
|
le->ctrl = ctrl;
|
||||||
le->opcode = OP_BUFFER | HW_OWNER;
|
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];
|
dev = hw->dev[le->link];
|
||||||
|
|
||||||
sky2 = netdev_priv(dev);
|
sky2 = netdev_priv(dev);
|
||||||
length = le->length;
|
length = le16_to_cpu(le->length);
|
||||||
status = le->status;
|
status = le32_to_cpu(le->status);
|
||||||
|
|
||||||
switch (le->opcode & ~HW_OWNER) {
|
switch (le->opcode & ~HW_OWNER) {
|
||||||
case OP_RXSTAT:
|
case OP_RXSTAT:
|
||||||
@ -1983,7 +1983,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
|
|||||||
case OP_RXCHKS:
|
case OP_RXCHKS:
|
||||||
skb = sky2->rx_ring[sky2->rx_next].skb;
|
skb = sky2->rx_ring[sky2->rx_next].skb;
|
||||||
skb->ip_summed = CHECKSUM_HW;
|
skb->ip_summed = CHECKSUM_HW;
|
||||||
skb->csum = le16_to_cpu(status);
|
skb->csum = status & 0xffff;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_TXINDEXLE:
|
case OP_TXINDEXLE:
|
||||||
@ -3286,12 +3286,13 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
|
|||||||
hw->pm_cap = pm_cap;
|
hw->pm_cap = pm_cap;
|
||||||
|
|
||||||
#ifdef __BIG_ENDIAN
|
#ifdef __BIG_ENDIAN
|
||||||
/* byte swap descriptors in hardware */
|
/* The sk98lin vendor driver uses hardware byte swapping but
|
||||||
|
* this driver uses software swapping.
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
reg = sky2_pci_read32(hw, PCI_DEV_REG2);
|
reg = sky2_pci_read32(hw, PCI_DEV_REG2);
|
||||||
reg |= PCI_REV_DESC;
|
reg &= ~PCI_REV_DESC;
|
||||||
sky2_pci_write32(hw, PCI_DEV_REG2, reg);
|
sky2_pci_write32(hw, PCI_DEV_REG2, reg);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1791,21 +1791,9 @@ enum {
|
|||||||
OP_TXINDEXLE = 0x68,
|
OP_TXINDEXLE = 0x68,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Yukon 2 hardware interface
|
/* Yukon 2 hardware interface */
|
||||||
* Not tested on big endian
|
|
||||||
*/
|
|
||||||
struct sky2_tx_le {
|
struct sky2_tx_le {
|
||||||
union {
|
__le32 addr;
|
||||||
__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 */
|
__le16 length; /* also vlan tag or checksum start */
|
||||||
u8 ctrl;
|
u8 ctrl;
|
||||||
u8 opcode;
|
u8 opcode;
|
||||||
@ -1851,8 +1839,7 @@ struct sky2_port {
|
|||||||
u32 tx_addr64;
|
u32 tx_addr64;
|
||||||
u16 tx_pending;
|
u16 tx_pending;
|
||||||
u16 tx_last_mss;
|
u16 tx_last_mss;
|
||||||
u16 tx_csum_start;
|
u32 tx_tcpsum;
|
||||||
u16 tx_csum_offset;
|
|
||||||
|
|
||||||
struct ring_info *rx_ring ____cacheline_aligned_in_smp;
|
struct ring_info *rx_ring ____cacheline_aligned_in_smp;
|
||||||
struct sky2_rx_le *rx_le;
|
struct sky2_rx_le *rx_le;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user