aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen
diff options
context:
space:
mode:
authorDhananjay Phadke <dhananjay@netxen.com>2009-07-26 16:07:45 -0400
committerDavid S. Miller <davem@davemloft.net>2009-07-27 14:15:31 -0400
commit028afe719855a157e32450c36b7a12e1f9e85abe (patch)
tree5aac51f5fd2def91942bf7b9b46040aeb7d4b503 /drivers/net/netxen
parent9b08beba2d1bf7e4598deba2800a9ea5e5c3a282 (diff)
netxen: add vlan tx acceleration support
Enable vlan tx acceleration for NX3031 if firmware advertises capability. Signed-off-by: Amit Kumar Salecha <amit@netxen.com> Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r--drivers/net/netxen/netxen_nic.h11
-rw-r--r--drivers/net/netxen/netxen_nic_main.c52
2 files changed, 57 insertions, 6 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index e7702f603346..d01cc092450e 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -304,6 +304,10 @@ struct netxen_ring_ctx {
304#define FLAGS_IPSEC_SA_ADD 0x04 304#define FLAGS_IPSEC_SA_ADD 0x04
305#define FLAGS_IPSEC_SA_DELETE 0x08 305#define FLAGS_IPSEC_SA_DELETE 0x08
306#define FLAGS_VLAN_TAGGED 0x10 306#define FLAGS_VLAN_TAGGED 0x10
307#define FLAGS_VLAN_OOB 0x40
308
309#define netxen_set_tx_vlan_tci(cmd_desc, v) \
310 (cmd_desc)->vlan_TCI = cpu_to_le16(v);
307 311
308#define netxen_set_cmd_desc_port(cmd_desc, var) \ 312#define netxen_set_cmd_desc_port(cmd_desc, var) \
309 ((cmd_desc)->port_ctxid |= ((var) & 0x0F)) 313 ((cmd_desc)->port_ctxid |= ((var) & 0x0F))
@@ -342,7 +346,9 @@ struct cmd_desc_type0 {
342 346
343 __le64 addr_buffer4; 347 __le64 addr_buffer4;
344 348
345 __le64 unused; 349 __le16 vlan_TCI;
350 __le16 reserved;
351 __le32 reserved2;
346 352
347} __attribute__ ((aligned(64))); 353} __attribute__ ((aligned(64)));
348 354
@@ -1111,6 +1117,9 @@ typedef struct {
1111 1117
1112#define NX_FW_CAPABILITY_LINK_NOTIFICATION (1 << 5) 1118#define NX_FW_CAPABILITY_LINK_NOTIFICATION (1 << 5)
1113#define NX_FW_CAPABILITY_SWITCHING (1 << 6) 1119#define NX_FW_CAPABILITY_SWITCHING (1 << 6)
1120#define NX_FW_CAPABILITY_PEXQ (1 << 7)
1121#define NX_FW_CAPABILITY_BDG (1 << 8)
1122#define NX_FW_CAPABILITY_FVLANTX (1 << 9)
1114 1123
1115/* module types */ 1124/* module types */
1116#define LINKEVENT_MODULE_NOT_PRESENT 1 1125#define LINKEVENT_MODULE_NOT_PRESENT 1
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 43a99f6a23df..ff7ee9c43ef5 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -1016,6 +1016,9 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
1016 netdev->vlan_features |= NETIF_F_HIGHDMA; 1016 netdev->vlan_features |= NETIF_F_HIGHDMA;
1017 } 1017 }
1018 1018
1019 if (adapter->capabilities & NX_FW_CAPABILITY_FVLANTX)
1020 netdev->features |= (NETIF_F_HW_VLAN_TX);
1021
1019 netdev->irq = adapter->msix_entries[0].vector; 1022 netdev->irq = adapter->msix_entries[0].vector;
1020 1023
1021 err = netxen_napi_add(adapter, netdev); 1024 err = netxen_napi_add(adapter, netdev);
@@ -1333,15 +1336,24 @@ netxen_tso_check(struct net_device *netdev,
1333{ 1336{
1334 u8 opcode = TX_ETHER_PKT; 1337 u8 opcode = TX_ETHER_PKT;
1335 __be16 protocol = skb->protocol; 1338 __be16 protocol = skb->protocol;
1336 u16 flags = 0; 1339 u16 flags = 0, vid = 0;
1337 u32 producer; 1340 u32 producer;
1338 int copied, offset, copy_len, hdr_len = 0, tso = 0; 1341 int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0;
1339 struct cmd_desc_type0 *hwdesc; 1342 struct cmd_desc_type0 *hwdesc;
1343 struct vlan_ethhdr *vh;
1340 1344
1341 if (protocol == cpu_to_be16(ETH_P_8021Q)) { 1345 if (protocol == cpu_to_be16(ETH_P_8021Q)) {
1342 struct vlan_ethhdr *vh = (struct vlan_ethhdr *)skb->data; 1346
1347 vh = (struct vlan_ethhdr *)skb->data;
1343 protocol = vh->h_vlan_encapsulated_proto; 1348 protocol = vh->h_vlan_encapsulated_proto;
1344 flags = FLAGS_VLAN_TAGGED; 1349 flags = FLAGS_VLAN_TAGGED;
1350
1351 } else if (vlan_tx_tag_present(skb)) {
1352
1353 flags = FLAGS_VLAN_OOB;
1354 vid = vlan_tx_tag_get(skb);
1355 netxen_set_tx_vlan_tci(first_desc, vid);
1356 vlan_oob = 1;
1345 } 1357 }
1346 1358
1347 if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && 1359 if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
@@ -1351,6 +1363,13 @@ netxen_tso_check(struct net_device *netdev,
1351 1363
1352 first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); 1364 first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
1353 first_desc->total_hdr_length = hdr_len; 1365 first_desc->total_hdr_length = hdr_len;
1366 if (vlan_oob) {
1367 first_desc->total_hdr_length += VLAN_HLEN;
1368 first_desc->tcp_hdr_offset = VLAN_HLEN;
1369 first_desc->ip_hdr_offset = VLAN_HLEN;
1370 /* Only in case of TSO on vlan device */
1371 flags |= FLAGS_VLAN_TAGGED;
1372 }
1354 1373
1355 opcode = (protocol == cpu_to_be16(ETH_P_IPV6)) ? 1374 opcode = (protocol == cpu_to_be16(ETH_P_IPV6)) ?
1356 TX_TCP_LSO6 : TX_TCP_LSO; 1375 TX_TCP_LSO6 : TX_TCP_LSO;
@@ -1375,8 +1394,9 @@ netxen_tso_check(struct net_device *netdev,
1375 opcode = TX_UDPV6_PKT; 1394 opcode = TX_UDPV6_PKT;
1376 } 1395 }
1377 } 1396 }
1378 first_desc->tcp_hdr_offset = skb_transport_offset(skb); 1397
1379 first_desc->ip_hdr_offset = skb_network_offset(skb); 1398 first_desc->tcp_hdr_offset += skb_transport_offset(skb);
1399 first_desc->ip_hdr_offset += skb_network_offset(skb);
1380 netxen_set_tx_flags_opcode(first_desc, flags, opcode); 1400 netxen_set_tx_flags_opcode(first_desc, flags, opcode);
1381 1401
1382 if (!tso) 1402 if (!tso)
@@ -1389,6 +1409,28 @@ netxen_tso_check(struct net_device *netdev,
1389 copied = 0; 1409 copied = 0;
1390 offset = 2; 1410 offset = 2;
1391 1411
1412 if (vlan_oob) {
1413 /* Create a TSO vlan header template for firmware */
1414
1415 hwdesc = &tx_ring->desc_head[producer];
1416 tx_ring->cmd_buf_arr[producer].skb = NULL;
1417
1418 copy_len = min((int)sizeof(struct cmd_desc_type0) - offset,
1419 hdr_len + VLAN_HLEN);
1420
1421 vh = (struct vlan_ethhdr *)((char *)hwdesc + 2);
1422 skb_copy_from_linear_data(skb, vh, 12);
1423 vh->h_vlan_proto = htons(ETH_P_8021Q);
1424 vh->h_vlan_TCI = htons(vid);
1425 skb_copy_from_linear_data_offset(skb, 12,
1426 (char *)vh + 16, copy_len - 16);
1427
1428 copied = copy_len;
1429 offset = 0;
1430
1431 producer = get_next_index(producer, tx_ring->num_desc);
1432 }
1433
1392 while (copied < hdr_len) { 1434 while (copied < hdr_len) {
1393 1435
1394 copy_len = min((int)sizeof(struct cmd_desc_type0) - offset, 1436 copy_len = min((int)sizeof(struct cmd_desc_type0) - offset,