aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/enic
diff options
context:
space:
mode:
authorVasanthy Kolluri <vkolluri@cisco.com>2010-06-24 06:49:51 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-25 23:45:22 -0400
commitf8cac14acff870203ea7f61f1a92c5486d1774fa (patch)
tree4caa5145dca79a98bb5a19b9fd2658fe8fe3933c /drivers/net/enic
parent88132f55d74fdd97a7d459007b2bbb59e850f8c0 (diff)
enic: Bug Fix: Change hardware ingress vlan rewrite mode
The current ingress vlan rewrite mode setting lets the hardware strip off the tag control information of a packet received on native vlan. As a result, the priority bits are also lost. The fix is to change the ingress vlan rewrite mode setting such that the complete tag control information is retained for packets that belong to native vlan. Signed-off-by: Scott Feldman <scofeldm@cisco.com> Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com> Signed-off-by: Roopa Prabhu <roprabhu@cisco.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/enic')
-rw-r--r--drivers/net/enic/cq_enet_desc.h16
-rw-r--r--drivers/net/enic/enic_main.c31
-rw-r--r--drivers/net/enic/vnic_dev.c14
-rw-r--r--drivers/net/enic/vnic_dev.h2
-rw-r--r--drivers/net/enic/vnic_devcmd.h12
5 files changed, 68 insertions, 7 deletions
diff --git a/drivers/net/enic/cq_enet_desc.h b/drivers/net/enic/cq_enet_desc.h
index 337d1943af46..f2d98bbf05aa 100644
--- a/drivers/net/enic/cq_enet_desc.h
+++ b/drivers/net/enic/cq_enet_desc.h
@@ -73,6 +73,15 @@ struct cq_enet_rq_desc {
73#define CQ_ENET_RQ_DESC_FLAGS_TRUNCATED (0x1 << 14) 73#define CQ_ENET_RQ_DESC_FLAGS_TRUNCATED (0x1 << 14)
74#define CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED (0x1 << 15) 74#define CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED (0x1 << 15)
75 75
76#define CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_BITS 12
77#define CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_MASK \
78 ((1 << CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_BITS) - 1)
79#define CQ_ENET_RQ_DESC_VLAN_TCI_CFI_MASK (0x1 << 12)
80#define CQ_ENET_RQ_DESC_VLAN_TCI_USER_PRIO_BITS 3
81#define CQ_ENET_RQ_DESC_VLAN_TCI_USER_PRIO_MASK \
82 ((1 << CQ_ENET_RQ_DESC_VLAN_TCI_USER_PRIO_BITS) - 1)
83#define CQ_ENET_RQ_DESC_VLAN_TCI_USER_PRIO_SHIFT 13
84
76#define CQ_ENET_RQ_DESC_FCOE_SOF_BITS 4 85#define CQ_ENET_RQ_DESC_FCOE_SOF_BITS 4
77#define CQ_ENET_RQ_DESC_FCOE_SOF_MASK \ 86#define CQ_ENET_RQ_DESC_FCOE_SOF_MASK \
78 ((1 << CQ_ENET_RQ_DESC_FCOE_SOF_BITS) - 1) 87 ((1 << CQ_ENET_RQ_DESC_FCOE_SOF_BITS) - 1)
@@ -96,7 +105,7 @@ static inline void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc,
96 u8 *type, u8 *color, u16 *q_number, u16 *completed_index, 105 u8 *type, u8 *color, u16 *q_number, u16 *completed_index,
97 u8 *ingress_port, u8 *fcoe, u8 *eop, u8 *sop, u8 *rss_type, 106 u8 *ingress_port, u8 *fcoe, u8 *eop, u8 *sop, u8 *rss_type,
98 u8 *csum_not_calc, u32 *rss_hash, u16 *bytes_written, u8 *packet_error, 107 u8 *csum_not_calc, u32 *rss_hash, u16 *bytes_written, u8 *packet_error,
99 u8 *vlan_stripped, u16 *vlan, u16 *checksum, u8 *fcoe_sof, 108 u8 *vlan_stripped, u16 *vlan_tci, u16 *checksum, u8 *fcoe_sof,
100 u8 *fcoe_fc_crc_ok, u8 *fcoe_enc_error, u8 *fcoe_eof, 109 u8 *fcoe_fc_crc_ok, u8 *fcoe_enc_error, u8 *fcoe_eof,
101 u8 *tcp_udp_csum_ok, u8 *udp, u8 *tcp, u8 *ipv4_csum_ok, 110 u8 *tcp_udp_csum_ok, u8 *udp, u8 *tcp, u8 *ipv4_csum_ok,
102 u8 *ipv6, u8 *ipv4, u8 *ipv4_fragment, u8 *fcs_ok) 111 u8 *ipv6, u8 *ipv4, u8 *ipv4_fragment, u8 *fcs_ok)
@@ -136,7 +145,10 @@ static inline void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc,
136 *vlan_stripped = (bytes_written_flags & 145 *vlan_stripped = (bytes_written_flags &
137 CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED) ? 1 : 0; 146 CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED) ? 1 : 0;
138 147
139 *vlan = le16_to_cpu(desc->vlan); 148 /*
149 * Tag Control Information(16) = user_priority(3) + cfi(1) + vlan(12)
150 */
151 *vlan_tci = le16_to_cpu(desc->vlan);
140 152
141 if (*fcoe) { 153 if (*fcoe) {
142 *fcoe_sof = (u8)(le16_to_cpu(desc->checksum_fcoe) & 154 *fcoe_sof = (u8)(le16_to_cpu(desc->checksum_fcoe) &
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index c2b848f58c29..7f98af1eb1ea 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1300,7 +1300,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
1300 u8 tcp_udp_csum_ok, udp, tcp, ipv4_csum_ok; 1300 u8 tcp_udp_csum_ok, udp, tcp, ipv4_csum_ok;
1301 u8 ipv6, ipv4, ipv4_fragment, fcs_ok, rss_type, csum_not_calc; 1301 u8 ipv6, ipv4, ipv4_fragment, fcs_ok, rss_type, csum_not_calc;
1302 u8 packet_error; 1302 u8 packet_error;
1303 u16 q_number, completed_index, bytes_written, vlan, checksum; 1303 u16 q_number, completed_index, bytes_written, vlan_tci, checksum;
1304 u32 rss_hash; 1304 u32 rss_hash;
1305 1305
1306 if (skipped) 1306 if (skipped)
@@ -1315,7 +1315,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
1315 &type, &color, &q_number, &completed_index, 1315 &type, &color, &q_number, &completed_index,
1316 &ingress_port, &fcoe, &eop, &sop, &rss_type, 1316 &ingress_port, &fcoe, &eop, &sop, &rss_type,
1317 &csum_not_calc, &rss_hash, &bytes_written, 1317 &csum_not_calc, &rss_hash, &bytes_written,
1318 &packet_error, &vlan_stripped, &vlan, &checksum, 1318 &packet_error, &vlan_stripped, &vlan_tci, &checksum,
1319 &fcoe_sof, &fcoe_fc_crc_ok, &fcoe_enc_error, 1319 &fcoe_sof, &fcoe_fc_crc_ok, &fcoe_enc_error,
1320 &fcoe_eof, &tcp_udp_csum_ok, &udp, &tcp, 1320 &fcoe_eof, &tcp_udp_csum_ok, &udp, &tcp,
1321 &ipv4_csum_ok, &ipv6, &ipv4, &ipv4_fragment, 1321 &ipv4_csum_ok, &ipv6, &ipv4, &ipv4_fragment,
@@ -1350,14 +1350,15 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
1350 1350
1351 skb->dev = netdev; 1351 skb->dev = netdev;
1352 1352
1353 if (enic->vlan_group && vlan_stripped) { 1353 if (enic->vlan_group && vlan_stripped &&
1354 (vlan_tci & CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_MASK)) {
1354 1355
1355 if (netdev->features & NETIF_F_GRO) 1356 if (netdev->features & NETIF_F_GRO)
1356 vlan_gro_receive(&enic->napi, enic->vlan_group, 1357 vlan_gro_receive(&enic->napi, enic->vlan_group,
1357 vlan, skb); 1358 vlan_tci, skb);
1358 else 1359 else
1359 vlan_hwaccel_receive_skb(skb, 1360 vlan_hwaccel_receive_skb(skb,
1360 enic->vlan_group, vlan); 1361 enic->vlan_group, vlan_tci);
1361 1362
1362 } else { 1363 } else {
1363 1364
@@ -1879,6 +1880,18 @@ static int enic_set_niccfg(struct enic *enic)
1879 ig_vlan_strip_en); 1880 ig_vlan_strip_en);
1880} 1881}
1881 1882
1883int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic)
1884{
1885 int err;
1886
1887 spin_lock(&enic->devcmd_lock);
1888 err = vnic_dev_set_ig_vlan_rewrite_mode(enic->vdev,
1889 IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN);
1890 spin_unlock(&enic->devcmd_lock);
1891
1892 return err;
1893}
1894
1882static void enic_reset(struct work_struct *work) 1895static void enic_reset(struct work_struct *work)
1883{ 1896{
1884 struct enic *enic = container_of(work, struct enic, reset); 1897 struct enic *enic = container_of(work, struct enic, reset);
@@ -1898,6 +1911,7 @@ static void enic_reset(struct work_struct *work)
1898 enic_reset_mcaddrs(enic); 1911 enic_reset_mcaddrs(enic);
1899 enic_init_vnic_resources(enic); 1912 enic_init_vnic_resources(enic);
1900 enic_set_niccfg(enic); 1913 enic_set_niccfg(enic);
1914 enic_dev_set_ig_vlan_rewrite_mode(enic);
1901 enic_open(enic->netdev); 1915 enic_open(enic->netdev);
1902 1916
1903 rtnl_unlock(); 1917 rtnl_unlock();
@@ -2110,6 +2124,13 @@ int enic_dev_init(struct enic *enic)
2110 goto err_out_free_vnic_resources; 2124 goto err_out_free_vnic_resources;
2111 } 2125 }
2112 2126
2127 err = enic_dev_set_ig_vlan_rewrite_mode(enic);
2128 if (err) {
2129 printk(KERN_ERR PFX
2130 "Failed to set ingress vlan rewrite mode, aborting.\n");
2131 goto err_out_free_vnic_resources;
2132 }
2133
2113 switch (vnic_dev_get_intr_mode(enic->vdev)) { 2134 switch (vnic_dev_get_intr_mode(enic->vdev)) {
2114 default: 2135 default:
2115 netif_napi_add(netdev, &enic->napi, enic_poll, 64); 2136 netif_napi_add(netdev, &enic->napi, enic_poll, 64);
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index e0d33281ec98..e3742faa06fe 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -564,6 +564,20 @@ int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
564 return err; 564 return err;
565} 565}
566 566
567int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev,
568 u8 ig_vlan_rewrite_mode)
569{
570 u64 a0 = ig_vlan_rewrite_mode, a1 = 0;
571 int wait = 1000;
572 int err;
573
574 err = vnic_dev_cmd(vdev, CMD_IG_VLAN_REWRITE_MODE, &a0, &a1, wait);
575 if (err == ERR_ECMDUNKNOWN)
576 return 0;
577
578 return err;
579}
580
567int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr) 581int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr)
568{ 582{
569 u64 a0 = intr, a1 = 0; 583 u64 a0 = intr, a1 = 0;
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index caccce36957b..780c3cd73292 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -133,6 +133,8 @@ void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
133 enum vnic_dev_intr_mode intr_mode); 133 enum vnic_dev_intr_mode intr_mode);
134enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev); 134enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev);
135void vnic_dev_unregister(struct vnic_dev *vdev); 135void vnic_dev_unregister(struct vnic_dev *vdev);
136int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev,
137 u8 ig_vlan_rewrite_mode);
136struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, 138struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
137 void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar, 139 void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar,
138 unsigned int num_bars); 140 unsigned int num_bars);
diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h
index d78bbcc1fdf9..c5ff4ff2ed26 100644
--- a/drivers/net/enic/vnic_devcmd.h
+++ b/drivers/net/enic/vnic_devcmd.h
@@ -211,6 +211,12 @@ enum vnic_devcmd_cmd {
211 * in: (u16)a0=interrupt number to assert 211 * in: (u16)a0=interrupt number to assert
212 */ 212 */
213 CMD_IAR = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 38), 213 CMD_IAR = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 38),
214
215 /*
216 * Set hw ingress packet vlan rewrite mode:
217 * in: (u32)a0=new vlan rewrite mode
218 * out: (u32)a0=old vlan rewrite mode */
219 CMD_IG_VLAN_REWRITE_MODE = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ENET, 41),
214}; 220};
215 221
216/* flags for CMD_OPEN */ 222/* flags for CMD_OPEN */
@@ -226,6 +232,12 @@ enum vnic_devcmd_cmd {
226#define CMD_PFILTER_PROMISCUOUS 0x08 232#define CMD_PFILTER_PROMISCUOUS 0x08
227#define CMD_PFILTER_ALL_MULTICAST 0x10 233#define CMD_PFILTER_ALL_MULTICAST 0x10
228 234
235/* rewrite modes for CMD_IG_VLAN_REWRITE_MODE */
236#define IG_VLAN_REWRITE_MODE_DEFAULT_TRUNK 0
237#define IG_VLAN_REWRITE_MODE_UNTAG_DEFAULT_VLAN 1
238#define IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN 2
239#define IG_VLAN_REWRITE_MODE_PASS_THRU 3
240
229enum vnic_devcmd_status { 241enum vnic_devcmd_status {
230 STAT_NONE = 0, 242 STAT_NONE = 0,
231 STAT_BUSY = 1 << 0, /* cmd in progress */ 243 STAT_BUSY = 1 << 0, /* cmd in progress */