diff options
author | Sucheta Chakraborty <sucheta.chakraborty@qlogic.com> | 2010-10-04 00:20:13 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-05 01:46:50 -0400 |
commit | 7e56cac4b68805470849ba373dd313ba0e7cdb81 (patch) | |
tree | ac25d1e2bd40838b37e9e51a2c6ab8afc321b982 /drivers/net/qlcnic | |
parent | b501595cbb8afeaa9aaa870b3d29ef051403511a (diff) |
qlcnic: fix vlan TSO on big endian machine
o desc->vlan_tci is in __le16 format. Doing htons and
cpu_to_le64 again on vlan_tci, result in invalid value on ppc.
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/qlcnic')
-rw-r--r-- | drivers/net/qlcnic/qlcnic.h | 7 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_hw.c | 6 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 15 |
3 files changed, 20 insertions, 8 deletions
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 7af3c6ce0b6..9d80171a1fb 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h | |||
@@ -898,6 +898,11 @@ struct qlcnic_mac_req { | |||
898 | u8 mac_addr[6]; | 898 | u8 mac_addr[6]; |
899 | }; | 899 | }; |
900 | 900 | ||
901 | struct qlcnic_vlan_req { | ||
902 | __le16 vlan_id; | ||
903 | __le16 rsvd[3]; | ||
904 | }; | ||
905 | |||
901 | struct qlcnic_ipaddr { | 906 | struct qlcnic_ipaddr { |
902 | __be32 ipv4; | 907 | __be32 ipv4; |
903 | __be32 ipv6[4]; | 908 | __be32 ipv6[4]; |
@@ -940,7 +945,7 @@ struct qlcnic_ipaddr { | |||
940 | struct qlcnic_filter { | 945 | struct qlcnic_filter { |
941 | struct hlist_node fnode; | 946 | struct hlist_node fnode; |
942 | u8 faddr[ETH_ALEN]; | 947 | u8 faddr[ETH_ALEN]; |
943 | u16 vlan_id; | 948 | __le16 vlan_id; |
944 | unsigned long ftime; | 949 | unsigned long ftime; |
945 | }; | 950 | }; |
946 | 951 | ||
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 68d56939a8d..712cfabc282 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c | |||
@@ -375,10 +375,11 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter, | |||
375 | 375 | ||
376 | static int | 376 | static int |
377 | qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, | 377 | qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, |
378 | u16 vlan_id, unsigned op) | 378 | __le16 vlan_id, unsigned op) |
379 | { | 379 | { |
380 | struct qlcnic_nic_req req; | 380 | struct qlcnic_nic_req req; |
381 | struct qlcnic_mac_req *mac_req; | 381 | struct qlcnic_mac_req *mac_req; |
382 | struct qlcnic_vlan_req *vlan_req; | ||
382 | u64 word; | 383 | u64 word; |
383 | 384 | ||
384 | memset(&req, 0, sizeof(struct qlcnic_nic_req)); | 385 | memset(&req, 0, sizeof(struct qlcnic_nic_req)); |
@@ -391,7 +392,8 @@ qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, | |||
391 | mac_req->op = op; | 392 | mac_req->op = op; |
392 | memcpy(mac_req->mac_addr, addr, 6); | 393 | memcpy(mac_req->mac_addr, addr, 6); |
393 | 394 | ||
394 | req.words[1] = cpu_to_le64(vlan_id); | 395 | vlan_req = (struct qlcnic_vlan_req *)&req.words[1]; |
396 | vlan_req->vlan_id = vlan_id; | ||
395 | 397 | ||
396 | return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); | 398 | return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); |
397 | } | 399 | } |
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index a3d7705a2dd..6001f41a70a 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include "qlcnic.h" | 29 | #include "qlcnic.h" |
30 | 30 | ||
31 | #include <linux/swab.h> | ||
31 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
32 | #include <linux/if_vlan.h> | 33 | #include <linux/if_vlan.h> |
33 | #include <net/ip.h> | 34 | #include <net/ip.h> |
@@ -1834,11 +1835,12 @@ static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter) | |||
1834 | } | 1835 | } |
1835 | 1836 | ||
1836 | static void qlcnic_change_filter(struct qlcnic_adapter *adapter, | 1837 | static void qlcnic_change_filter(struct qlcnic_adapter *adapter, |
1837 | u64 uaddr, u16 vlan_id, struct qlcnic_host_tx_ring *tx_ring) | 1838 | u64 uaddr, __le16 vlan_id, struct qlcnic_host_tx_ring *tx_ring) |
1838 | { | 1839 | { |
1839 | struct cmd_desc_type0 *hwdesc; | 1840 | struct cmd_desc_type0 *hwdesc; |
1840 | struct qlcnic_nic_req *req; | 1841 | struct qlcnic_nic_req *req; |
1841 | struct qlcnic_mac_req *mac_req; | 1842 | struct qlcnic_mac_req *mac_req; |
1843 | struct qlcnic_vlan_req *vlan_req; | ||
1842 | u32 producer; | 1844 | u32 producer; |
1843 | u64 word; | 1845 | u64 word; |
1844 | 1846 | ||
@@ -1856,7 +1858,8 @@ static void qlcnic_change_filter(struct qlcnic_adapter *adapter, | |||
1856 | mac_req->op = vlan_id ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_ADD; | 1858 | mac_req->op = vlan_id ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_ADD; |
1857 | memcpy(mac_req->mac_addr, &uaddr, ETH_ALEN); | 1859 | memcpy(mac_req->mac_addr, &uaddr, ETH_ALEN); |
1858 | 1860 | ||
1859 | req->words[1] = cpu_to_le64(vlan_id); | 1861 | vlan_req = (struct qlcnic_vlan_req *)&req->words[1]; |
1862 | vlan_req->vlan_id = vlan_id; | ||
1860 | 1863 | ||
1861 | tx_ring->producer = get_next_index(producer, tx_ring->num_desc); | 1864 | tx_ring->producer = get_next_index(producer, tx_ring->num_desc); |
1862 | } | 1865 | } |
@@ -1875,7 +1878,7 @@ qlcnic_send_filter(struct qlcnic_adapter *adapter, | |||
1875 | struct hlist_node *tmp_hnode, *n; | 1878 | struct hlist_node *tmp_hnode, *n; |
1876 | struct hlist_head *head; | 1879 | struct hlist_head *head; |
1877 | u64 src_addr = 0; | 1880 | u64 src_addr = 0; |
1878 | u16 vlan_id = 0; | 1881 | __le16 vlan_id = 0; |
1879 | u8 hindex; | 1882 | u8 hindex; |
1880 | 1883 | ||
1881 | if (!compare_ether_addr(phdr->h_source, adapter->mac_addr)) | 1884 | if (!compare_ether_addr(phdr->h_source, adapter->mac_addr)) |
@@ -1928,7 +1931,8 @@ qlcnic_tso_check(struct net_device *netdev, | |||
1928 | struct vlan_ethhdr *vh; | 1931 | struct vlan_ethhdr *vh; |
1929 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 1932 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1930 | u32 producer = tx_ring->producer; | 1933 | u32 producer = tx_ring->producer; |
1931 | int vlan_oob = first_desc->flags_opcode & cpu_to_le16(FLAGS_VLAN_OOB); | 1934 | __le16 vlan_oob = first_desc->flags_opcode & |
1935 | cpu_to_le16(FLAGS_VLAN_OOB); | ||
1932 | 1936 | ||
1933 | if (*(skb->data) & BIT_0) { | 1937 | if (*(skb->data) & BIT_0) { |
1934 | flags |= BIT_0; | 1938 | flags |= BIT_0; |
@@ -1999,7 +2003,8 @@ qlcnic_tso_check(struct net_device *netdev, | |||
1999 | vh = (struct vlan_ethhdr *)((char *)hwdesc + 2); | 2003 | vh = (struct vlan_ethhdr *)((char *)hwdesc + 2); |
2000 | skb_copy_from_linear_data(skb, vh, 12); | 2004 | skb_copy_from_linear_data(skb, vh, 12); |
2001 | vh->h_vlan_proto = htons(ETH_P_8021Q); | 2005 | vh->h_vlan_proto = htons(ETH_P_8021Q); |
2002 | vh->h_vlan_TCI = htons(first_desc->vlan_TCI); | 2006 | vh->h_vlan_TCI = (__be16)swab16((u16)first_desc->vlan_TCI); |
2007 | |||
2003 | skb_copy_from_linear_data_offset(skb, 12, | 2008 | skb_copy_from_linear_data_offset(skb, 12, |
2004 | (char *)vh + 16, copy_len - 16); | 2009 | (char *)vh + 16, copy_len - 16); |
2005 | 2010 | ||