diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-09-06 15:45:02 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-09-13 13:27:44 -0400 |
commit | f65b138ca94326bbffe06ddc28e65606a249e58e (patch) | |
tree | 8fb69b76b32fe10d07678e3721a68638841061ca | |
parent | b89165f2b75ba0a79eb5ed60924835cf3c54c51a (diff) |
[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>
-rw-r--r-- | drivers/net/sky2.c | 43 | ||||
-rw-r--r-- | drivers/net/sky2.h | 19 |
2 files changed, 25 insertions, 37 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 2b9272c0955a..9429859be54f 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -827,7 +827,7 @@ static void rx_set_checksum(struct sky2_port *sky2) | |||
827 | struct sky2_rx_le *le; | 827 | struct sky2_rx_le *le; |
828 | 828 | ||
829 | le = sky2_next_rx(sky2); | 829 | le = sky2_next_rx(sky2); |
830 | le->addr = (ETH_HLEN << 16) | ETH_HLEN; | 830 | le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN); |
831 | le->ctrl = 0; | 831 | le->ctrl = 0; |
832 | le->opcode = OP_TCPSTART | HW_OWNER; | 832 | le->opcode = OP_TCPSTART | HW_OWNER; |
833 | 833 | ||
@@ -1245,7 +1245,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1245 | /* Send high bits if changed or crosses boundary */ | 1245 | /* Send high bits if changed or crosses boundary */ |
1246 | if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) { | 1246 | if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) { |
1247 | le = get_tx_le(sky2); | 1247 | le = get_tx_le(sky2); |
1248 | le->tx.addr = cpu_to_le32(addr64); | 1248 | le->addr = cpu_to_le32(addr64); |
1249 | le->ctrl = 0; | 1249 | le->ctrl = 0; |
1250 | le->opcode = OP_ADDR64 | HW_OWNER; | 1250 | le->opcode = OP_ADDR64 | HW_OWNER; |
1251 | sky2->tx_addr64 = high32(mapping + len); | 1251 | sky2->tx_addr64 = high32(mapping + len); |
@@ -1260,8 +1260,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1260 | 1260 | ||
1261 | if (mss != sky2->tx_last_mss) { | 1261 | if (mss != sky2->tx_last_mss) { |
1262 | le = get_tx_le(sky2); | 1262 | le = get_tx_le(sky2); |
1263 | le->tx.tso.size = cpu_to_le16(mss); | 1263 | le->addr = cpu_to_le32(mss); |
1264 | le->tx.tso.rsvd = 0; | ||
1265 | le->opcode = OP_LRGLEN | HW_OWNER; | 1264 | le->opcode = OP_LRGLEN | HW_OWNER; |
1266 | le->ctrl = 0; | 1265 | le->ctrl = 0; |
1267 | sky2->tx_last_mss = mss; | 1266 | sky2->tx_last_mss = mss; |
@@ -1274,7 +1273,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1274 | if (sky2->vlgrp && vlan_tx_tag_present(skb)) { | 1273 | if (sky2->vlgrp && vlan_tx_tag_present(skb)) { |
1275 | if (!le) { | 1274 | if (!le) { |
1276 | le = get_tx_le(sky2); | 1275 | le = get_tx_le(sky2); |
1277 | le->tx.addr = 0; | 1276 | le->addr = 0; |
1278 | le->opcode = OP_VLAN|HW_OWNER; | 1277 | le->opcode = OP_VLAN|HW_OWNER; |
1279 | le->ctrl = 0; | 1278 | le->ctrl = 0; |
1280 | } else | 1279 | } else |
@@ -1286,20 +1285,21 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1286 | 1285 | ||
1287 | /* Handle TCP checksum offload */ | 1286 | /* Handle TCP checksum offload */ |
1288 | if (skb->ip_summed == CHECKSUM_HW) { | 1287 | if (skb->ip_summed == CHECKSUM_HW) { |
1289 | u16 hdr = skb->h.raw - skb->data; | 1288 | unsigned offset = skb->h.raw - skb->data; |
1290 | u16 offset = hdr + skb->csum; | 1289 | u32 tcpsum; |
1290 | |||
1291 | tcpsum = offset << 16; /* sum start */ | ||
1292 | tcpsum |= offset + skb->csum; /* sum write */ | ||
1291 | 1293 | ||
1292 | ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; | 1294 | ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; |
1293 | if (skb->nh.iph->protocol == IPPROTO_UDP) | 1295 | if (skb->nh.iph->protocol == IPPROTO_UDP) |
1294 | ctrl |= UDPTCP; | 1296 | ctrl |= UDPTCP; |
1295 | 1297 | ||
1296 | if (hdr != sky2->tx_csum_start || offset != sky2->tx_csum_offset) { | 1298 | if (tcpsum != sky2->tx_tcpsum) { |
1297 | sky2->tx_csum_start = hdr; | 1299 | sky2->tx_tcpsum = tcpsum; |
1298 | sky2->tx_csum_offset = offset; | ||
1299 | 1300 | ||
1300 | le = get_tx_le(sky2); | 1301 | le = get_tx_le(sky2); |
1301 | le->tx.csum.start = cpu_to_le16(hdr); | 1302 | le->addr = cpu_to_le32(tcpsum); |
1302 | le->tx.csum.offset = cpu_to_le16(offset); | ||
1303 | le->length = 0; /* initial checksum value */ | 1303 | le->length = 0; /* initial checksum value */ |
1304 | le->ctrl = 1; /* one packet */ | 1304 | le->ctrl = 1; /* one packet */ |
1305 | le->opcode = OP_TCPLISW | HW_OWNER; | 1305 | le->opcode = OP_TCPLISW | HW_OWNER; |
@@ -1307,7 +1307,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1307 | } | 1307 | } |
1308 | 1308 | ||
1309 | le = get_tx_le(sky2); | 1309 | le = get_tx_le(sky2); |
1310 | le->tx.addr = cpu_to_le32((u32) mapping); | 1310 | le->addr = cpu_to_le32((u32) mapping); |
1311 | le->length = cpu_to_le16(len); | 1311 | le->length = cpu_to_le16(len); |
1312 | le->ctrl = ctrl; | 1312 | le->ctrl = ctrl; |
1313 | le->opcode = mss ? (OP_LARGESEND | HW_OWNER) : (OP_PACKET | HW_OWNER); | 1313 | 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) | |||
1325 | addr64 = high32(mapping); | 1325 | addr64 = high32(mapping); |
1326 | if (addr64 != sky2->tx_addr64) { | 1326 | if (addr64 != sky2->tx_addr64) { |
1327 | le = get_tx_le(sky2); | 1327 | le = get_tx_le(sky2); |
1328 | le->tx.addr = cpu_to_le32(addr64); | 1328 | le->addr = cpu_to_le32(addr64); |
1329 | le->ctrl = 0; | 1329 | le->ctrl = 0; |
1330 | le->opcode = OP_ADDR64 | HW_OWNER; | 1330 | le->opcode = OP_ADDR64 | HW_OWNER; |
1331 | sky2->tx_addr64 = addr64; | 1331 | sky2->tx_addr64 = addr64; |
1332 | } | 1332 | } |
1333 | 1333 | ||
1334 | le = get_tx_le(sky2); | 1334 | le = get_tx_le(sky2); |
1335 | le->tx.addr = cpu_to_le32((u32) mapping); | 1335 | le->addr = cpu_to_le32((u32) mapping); |
1336 | le->length = cpu_to_le16(frag->size); | 1336 | le->length = cpu_to_le16(frag->size); |
1337 | le->ctrl = ctrl; | 1337 | le->ctrl = ctrl; |
1338 | le->opcode = OP_BUFFER | HW_OWNER; | 1338 | le->opcode = OP_BUFFER | HW_OWNER; |
@@ -1938,8 +1938,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
1938 | dev = hw->dev[le->link]; | 1938 | dev = hw->dev[le->link]; |
1939 | 1939 | ||
1940 | sky2 = netdev_priv(dev); | 1940 | sky2 = netdev_priv(dev); |
1941 | length = le->length; | 1941 | length = le16_to_cpu(le->length); |
1942 | status = le->status; | 1942 | status = le32_to_cpu(le->status); |
1943 | 1943 | ||
1944 | switch (le->opcode & ~HW_OWNER) { | 1944 | switch (le->opcode & ~HW_OWNER) { |
1945 | case OP_RXSTAT: | 1945 | case OP_RXSTAT: |
@@ -1983,7 +1983,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
1983 | case OP_RXCHKS: | 1983 | case OP_RXCHKS: |
1984 | skb = sky2->rx_ring[sky2->rx_next].skb; | 1984 | skb = sky2->rx_ring[sky2->rx_next].skb; |
1985 | skb->ip_summed = CHECKSUM_HW; | 1985 | skb->ip_summed = CHECKSUM_HW; |
1986 | skb->csum = le16_to_cpu(status); | 1986 | skb->csum = status & 0xffff; |
1987 | break; | 1987 | break; |
1988 | 1988 | ||
1989 | case OP_TXINDEXLE: | 1989 | case OP_TXINDEXLE: |
@@ -3286,12 +3286,13 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
3286 | hw->pm_cap = pm_cap; | 3286 | hw->pm_cap = pm_cap; |
3287 | 3287 | ||
3288 | #ifdef __BIG_ENDIAN | 3288 | #ifdef __BIG_ENDIAN |
3289 | /* byte swap descriptors in hardware */ | 3289 | /* The sk98lin vendor driver uses hardware byte swapping but |
3290 | * this driver uses software swapping. | ||
3291 | */ | ||
3290 | { | 3292 | { |
3291 | u32 reg; | 3293 | u32 reg; |
3292 | |||
3293 | reg = sky2_pci_read32(hw, PCI_DEV_REG2); | 3294 | reg = sky2_pci_read32(hw, PCI_DEV_REG2); |
3294 | reg |= PCI_REV_DESC; | 3295 | reg &= ~PCI_REV_DESC; |
3295 | sky2_pci_write32(hw, PCI_DEV_REG2, reg); | 3296 | sky2_pci_write32(hw, PCI_DEV_REG2, reg); |
3296 | } | 3297 | } |
3297 | #endif | 3298 | #endif |
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index be464636f07a..4c13c371bc21 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
@@ -1791,21 +1791,9 @@ enum { | |||
1791 | OP_TXINDEXLE = 0x68, | 1791 | OP_TXINDEXLE = 0x68, |
1792 | }; | 1792 | }; |
1793 | 1793 | ||
1794 | /* Yukon 2 hardware interface | 1794 | /* Yukon 2 hardware interface */ |
1795 | * Not tested on big endian | ||
1796 | */ | ||
1797 | struct sky2_tx_le { | 1795 | struct sky2_tx_le { |
1798 | union { | 1796 | __le32 addr; |
1799 | __le32 addr; | ||
1800 | struct { | ||
1801 | __le16 offset; | ||
1802 | __le16 start; | ||
1803 | } csum __attribute((packed)); | ||
1804 | struct { | ||
1805 | __le16 size; | ||
1806 | __le16 rsvd; | ||
1807 | } tso __attribute((packed)); | ||
1808 | } tx; | ||
1809 | __le16 length; /* also vlan tag or checksum start */ | 1797 | __le16 length; /* also vlan tag or checksum start */ |
1810 | u8 ctrl; | 1798 | u8 ctrl; |
1811 | u8 opcode; | 1799 | u8 opcode; |
@@ -1851,8 +1839,7 @@ struct sky2_port { | |||
1851 | u32 tx_addr64; | 1839 | u32 tx_addr64; |
1852 | u16 tx_pending; | 1840 | u16 tx_pending; |
1853 | u16 tx_last_mss; | 1841 | u16 tx_last_mss; |
1854 | u16 tx_csum_start; | 1842 | u32 tx_tcpsum; |
1855 | u16 tx_csum_offset; | ||
1856 | 1843 | ||
1857 | struct ring_info *rx_ring ____cacheline_aligned_in_smp; | 1844 | struct ring_info *rx_ring ____cacheline_aligned_in_smp; |
1858 | struct sky2_rx_le *rx_le; | 1845 | struct sky2_rx_le *rx_le; |