diff options
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_main.c')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 89 |
1 files changed, 69 insertions, 20 deletions
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 5d93b464681a..089212214ad4 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -759,6 +759,21 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) | |||
759 | } | 759 | } |
760 | 760 | ||
761 | static void | 761 | static void |
762 | qlcnic_set_vlan_config(struct qlcnic_adapter *adapter, | ||
763 | struct qlcnic_esw_func_cfg *esw_cfg) | ||
764 | { | ||
765 | if (esw_cfg->discard_tagged) | ||
766 | adapter->flags &= ~QLCNIC_TAGGING_ENABLED; | ||
767 | else | ||
768 | adapter->flags |= QLCNIC_TAGGING_ENABLED; | ||
769 | |||
770 | if (esw_cfg->vlan_id) | ||
771 | adapter->pvid = esw_cfg->vlan_id; | ||
772 | else | ||
773 | adapter->pvid = 0; | ||
774 | } | ||
775 | |||
776 | static void | ||
762 | qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, | 777 | qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, |
763 | struct qlcnic_esw_func_cfg *esw_cfg) | 778 | struct qlcnic_esw_func_cfg *esw_cfg) |
764 | { | 779 | { |
@@ -781,6 +796,7 @@ qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter) | |||
781 | esw_cfg.pci_func = adapter->ahw.pci_func; | 796 | esw_cfg.pci_func = adapter->ahw.pci_func; |
782 | if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg)) | 797 | if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg)) |
783 | return -EIO; | 798 | return -EIO; |
799 | qlcnic_set_vlan_config(adapter, &esw_cfg); | ||
784 | qlcnic_set_eswitch_port_features(adapter, &esw_cfg); | 800 | qlcnic_set_eswitch_port_features(adapter, &esw_cfg); |
785 | 801 | ||
786 | return 0; | 802 | return 0; |
@@ -1728,26 +1744,13 @@ qlcnic_tso_check(struct net_device *netdev, | |||
1728 | { | 1744 | { |
1729 | u8 opcode = TX_ETHER_PKT; | 1745 | u8 opcode = TX_ETHER_PKT; |
1730 | __be16 protocol = skb->protocol; | 1746 | __be16 protocol = skb->protocol; |
1731 | u16 flags = 0, vid = 0; | 1747 | u16 flags = 0; |
1732 | int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0; | 1748 | int copied, offset, copy_len, hdr_len = 0, tso = 0; |
1733 | struct cmd_desc_type0 *hwdesc; | 1749 | struct cmd_desc_type0 *hwdesc; |
1734 | struct vlan_ethhdr *vh; | 1750 | struct vlan_ethhdr *vh; |
1735 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 1751 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1736 | u32 producer = tx_ring->producer; | 1752 | u32 producer = tx_ring->producer; |
1737 | 1753 | int vlan_oob = first_desc->flags_opcode & cpu_to_le16(FLAGS_VLAN_OOB); | |
1738 | if (protocol == cpu_to_be16(ETH_P_8021Q)) { | ||
1739 | |||
1740 | vh = (struct vlan_ethhdr *)skb->data; | ||
1741 | protocol = vh->h_vlan_encapsulated_proto; | ||
1742 | flags = FLAGS_VLAN_TAGGED; | ||
1743 | |||
1744 | } else if (vlan_tx_tag_present(skb)) { | ||
1745 | |||
1746 | flags = FLAGS_VLAN_OOB; | ||
1747 | vid = vlan_tx_tag_get(skb); | ||
1748 | qlcnic_set_tx_vlan_tci(first_desc, vid); | ||
1749 | vlan_oob = 1; | ||
1750 | } | ||
1751 | 1754 | ||
1752 | if (*(skb->data) & BIT_0) { | 1755 | if (*(skb->data) & BIT_0) { |
1753 | flags |= BIT_0; | 1756 | flags |= BIT_0; |
@@ -1818,7 +1821,7 @@ qlcnic_tso_check(struct net_device *netdev, | |||
1818 | vh = (struct vlan_ethhdr *)((char *)hwdesc + 2); | 1821 | vh = (struct vlan_ethhdr *)((char *)hwdesc + 2); |
1819 | skb_copy_from_linear_data(skb, vh, 12); | 1822 | skb_copy_from_linear_data(skb, vh, 12); |
1820 | vh->h_vlan_proto = htons(ETH_P_8021Q); | 1823 | vh->h_vlan_proto = htons(ETH_P_8021Q); |
1821 | vh->h_vlan_TCI = htons(vid); | 1824 | vh->h_vlan_TCI = htons(first_desc->vlan_TCI); |
1822 | skb_copy_from_linear_data_offset(skb, 12, | 1825 | skb_copy_from_linear_data_offset(skb, 12, |
1823 | (char *)vh + 16, copy_len - 16); | 1826 | (char *)vh + 16, copy_len - 16); |
1824 | 1827 | ||
@@ -1898,11 +1901,47 @@ out_err: | |||
1898 | return -ENOMEM; | 1901 | return -ENOMEM; |
1899 | } | 1902 | } |
1900 | 1903 | ||
1904 | static int | ||
1905 | qlcnic_check_tx_tagging(struct qlcnic_adapter *adapter, | ||
1906 | struct sk_buff *skb, | ||
1907 | struct cmd_desc_type0 *first_desc) | ||
1908 | { | ||
1909 | u8 opcode = 0; | ||
1910 | u16 flags = 0; | ||
1911 | __be16 protocol = skb->protocol; | ||
1912 | struct vlan_ethhdr *vh; | ||
1913 | |||
1914 | if (protocol == cpu_to_be16(ETH_P_8021Q)) { | ||
1915 | vh = (struct vlan_ethhdr *)skb->data; | ||
1916 | protocol = vh->h_vlan_encapsulated_proto; | ||
1917 | flags = FLAGS_VLAN_TAGGED; | ||
1918 | qlcnic_set_tx_vlan_tci(first_desc, ntohs(vh->h_vlan_TCI)); | ||
1919 | } else if (vlan_tx_tag_present(skb)) { | ||
1920 | flags = FLAGS_VLAN_OOB; | ||
1921 | qlcnic_set_tx_vlan_tci(first_desc, vlan_tx_tag_get(skb)); | ||
1922 | } | ||
1923 | if (unlikely(adapter->pvid)) { | ||
1924 | if (first_desc->vlan_TCI && | ||
1925 | !(adapter->flags & QLCNIC_TAGGING_ENABLED)) | ||
1926 | return -EIO; | ||
1927 | if (first_desc->vlan_TCI && | ||
1928 | (adapter->flags & QLCNIC_TAGGING_ENABLED)) | ||
1929 | goto set_flags; | ||
1930 | |||
1931 | flags = FLAGS_VLAN_OOB; | ||
1932 | qlcnic_set_tx_vlan_tci(first_desc, adapter->pvid); | ||
1933 | } | ||
1934 | set_flags: | ||
1935 | qlcnic_set_tx_flags_opcode(first_desc, flags, opcode); | ||
1936 | return 0; | ||
1937 | } | ||
1938 | |||
1901 | static inline void | 1939 | static inline void |
1902 | qlcnic_clear_cmddesc(u64 *desc) | 1940 | qlcnic_clear_cmddesc(u64 *desc) |
1903 | { | 1941 | { |
1904 | desc[0] = 0ULL; | 1942 | desc[0] = 0ULL; |
1905 | desc[2] = 0ULL; | 1943 | desc[2] = 0ULL; |
1944 | desc[7] = 0ULL; | ||
1906 | } | 1945 | } |
1907 | 1946 | ||
1908 | netdev_tx_t | 1947 | netdev_tx_t |
@@ -1952,6 +1991,12 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1952 | 1991 | ||
1953 | pdev = adapter->pdev; | 1992 | pdev = adapter->pdev; |
1954 | 1993 | ||
1994 | first_desc = hwdesc = &tx_ring->desc_head[producer]; | ||
1995 | qlcnic_clear_cmddesc((u64 *)hwdesc); | ||
1996 | |||
1997 | if (qlcnic_check_tx_tagging(adapter, skb, first_desc)) | ||
1998 | goto drop_packet; | ||
1999 | |||
1955 | if (qlcnic_map_tx_skb(pdev, skb, pbuf)) { | 2000 | if (qlcnic_map_tx_skb(pdev, skb, pbuf)) { |
1956 | adapter->stats.tx_dma_map_error++; | 2001 | adapter->stats.tx_dma_map_error++; |
1957 | goto drop_packet; | 2002 | goto drop_packet; |
@@ -1960,9 +2005,6 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1960 | pbuf->skb = skb; | 2005 | pbuf->skb = skb; |
1961 | pbuf->frag_count = frag_count; | 2006 | pbuf->frag_count = frag_count; |
1962 | 2007 | ||
1963 | first_desc = hwdesc = &tx_ring->desc_head[producer]; | ||
1964 | qlcnic_clear_cmddesc((u64 *)hwdesc); | ||
1965 | |||
1966 | qlcnic_set_tx_frags_len(first_desc, frag_count, skb->len); | 2008 | qlcnic_set_tx_frags_len(first_desc, frag_count, skb->len); |
1967 | qlcnic_set_tx_port(first_desc, adapter->portnum); | 2009 | qlcnic_set_tx_port(first_desc, adapter->portnum); |
1968 | 2010 | ||
@@ -3349,6 +3391,13 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj, | |||
3349 | case QLCNIC_PORT_DEFAULTS: | 3391 | case QLCNIC_PORT_DEFAULTS: |
3350 | qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]); | 3392 | qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]); |
3351 | break; | 3393 | break; |
3394 | case QLCNIC_ADD_VLAN: | ||
3395 | qlcnic_set_vlan_config(adapter, &esw_cfg[i]); | ||
3396 | break; | ||
3397 | case QLCNIC_DEL_VLAN: | ||
3398 | esw_cfg[i].vlan_id = 0; | ||
3399 | qlcnic_set_vlan_config(adapter, &esw_cfg[i]); | ||
3400 | break; | ||
3352 | } | 3401 | } |
3353 | } | 3402 | } |
3354 | 3403 | ||