aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-09-06 15:45:02 -0400
committerJeff Garzik <jeff@garzik.org>2006-09-13 13:27:44 -0400
commitf65b138ca94326bbffe06ddc28e65606a249e58e (patch)
tree8fb69b76b32fe10d07678e3721a68638841061ca
parentb89165f2b75ba0a79eb5ed60924835cf3c54c51a (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.c43
-rw-r--r--drivers/net/sky2.h19
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 */
1797struct sky2_tx_le { 1795struct 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;