aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTatyana Nikolova <Tatyana.E.Nikolova@intel.com>2014-03-26 18:07:57 -0400
committerRoland Dreier <roland@purestorage.com>2014-06-10 13:12:06 -0400
commit5647263cb136a2795b67b9ce46f2debb653e3373 (patch)
tree9649c342a1a897d163b652dffaf8167357f92a6a
parent30dc5e63d6a5ad24894b5512d10b228d73645a44 (diff)
RDMA/nes: Add support for iWARP Port Mapper user space service
Signed-off-by: Tatyana Nikolova <tatyana.e.nikolova@intel.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/hw/nes/nes.c25
-rw-r--r--drivers/infiniband/hw/nes/nes.h3
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c320
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.h12
4 files changed, 296 insertions, 64 deletions
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index 353c7b05a90a..3b2a6dc8ea99 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -68,7 +68,6 @@ MODULE_VERSION(DRV_VERSION);
68int max_mtu = 9000; 68int max_mtu = 9000;
69int interrupt_mod_interval = 0; 69int interrupt_mod_interval = 0;
70 70
71
72/* Interoperability */ 71/* Interoperability */
73int mpa_version = 1; 72int mpa_version = 1;
74module_param(mpa_version, int, 0644); 73module_param(mpa_version, int, 0644);
@@ -112,6 +111,16 @@ static struct pci_device_id nes_pci_table[] = {
112 111
113MODULE_DEVICE_TABLE(pci, nes_pci_table); 112MODULE_DEVICE_TABLE(pci, nes_pci_table);
114 113
114/* registered nes netlink callbacks */
115static struct ibnl_client_cbs nes_nl_cb_table[] = {
116 [RDMA_NL_IWPM_REG_PID] = {.dump = iwpm_register_pid_cb},
117 [RDMA_NL_IWPM_ADD_MAPPING] = {.dump = iwpm_add_mapping_cb},
118 [RDMA_NL_IWPM_QUERY_MAPPING] = {.dump = iwpm_add_and_query_mapping_cb},
119 [RDMA_NL_IWPM_HANDLE_ERR] = {.dump = iwpm_mapping_error_cb},
120 [RDMA_NL_IWPM_MAPINFO] = {.dump = iwpm_mapping_info_cb},
121 [RDMA_NL_IWPM_MAPINFO_NUM] = {.dump = iwpm_ack_mapping_info_cb}
122};
123
115static int nes_inetaddr_event(struct notifier_block *, unsigned long, void *); 124static int nes_inetaddr_event(struct notifier_block *, unsigned long, void *);
116static int nes_net_event(struct notifier_block *, unsigned long, void *); 125static int nes_net_event(struct notifier_block *, unsigned long, void *);
117static int nes_notifiers_registered; 126static int nes_notifiers_registered;
@@ -672,6 +681,17 @@ static int nes_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
672 } 681 }
673 nes_notifiers_registered++; 682 nes_notifiers_registered++;
674 683
684 if (ibnl_add_client(RDMA_NL_NES, RDMA_NL_IWPM_NUM_OPS, nes_nl_cb_table))
685 printk(KERN_ERR PFX "%s[%u]: Failed to add netlink callback\n",
686 __func__, __LINE__);
687
688 ret = iwpm_init(RDMA_NL_NES);
689 if (ret) {
690 printk(KERN_ERR PFX "%s: port mapper initialization failed\n",
691 pci_name(pcidev));
692 goto bail7;
693 }
694
675 INIT_DELAYED_WORK(&nesdev->work, nes_recheck_link_status); 695 INIT_DELAYED_WORK(&nesdev->work, nes_recheck_link_status);
676 696
677 /* Initialize network devices */ 697 /* Initialize network devices */
@@ -710,6 +730,7 @@ static int nes_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
710 730
711 nes_debug(NES_DBG_INIT, "netdev_count=%d, nesadapter->netdev_count=%d\n", 731 nes_debug(NES_DBG_INIT, "netdev_count=%d, nesadapter->netdev_count=%d\n",
712 nesdev->netdev_count, nesdev->nesadapter->netdev_count); 732 nesdev->netdev_count, nesdev->nesadapter->netdev_count);
733 ibnl_remove_client(RDMA_NL_NES);
713 734
714 nes_notifiers_registered--; 735 nes_notifiers_registered--;
715 if (nes_notifiers_registered == 0) { 736 if (nes_notifiers_registered == 0) {
@@ -773,6 +794,8 @@ static void nes_remove(struct pci_dev *pcidev)
773 nesdev->nesadapter->netdev_count--; 794 nesdev->nesadapter->netdev_count--;
774 } 795 }
775 } 796 }
797 ibnl_remove_client(RDMA_NL_NES);
798 iwpm_exit(RDMA_NL_NES);
776 799
777 nes_notifiers_registered--; 800 nes_notifiers_registered--;
778 if (nes_notifiers_registered == 0) { 801 if (nes_notifiers_registered == 0) {
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
index 33cc58941a3e..bd9d132f11c7 100644
--- a/drivers/infiniband/hw/nes/nes.h
+++ b/drivers/infiniband/hw/nes/nes.h
@@ -51,6 +51,8 @@
51#include <rdma/ib_pack.h> 51#include <rdma/ib_pack.h>
52#include <rdma/rdma_cm.h> 52#include <rdma/rdma_cm.h>
53#include <rdma/iw_cm.h> 53#include <rdma/iw_cm.h>
54#include <rdma/rdma_netlink.h>
55#include <rdma/iw_portmap.h>
54 56
55#define NES_SEND_FIRST_WRITE 57#define NES_SEND_FIRST_WRITE
56 58
@@ -130,6 +132,7 @@
130#define NES_DBG_IW_TX 0x00040000 132#define NES_DBG_IW_TX 0x00040000
131#define NES_DBG_SHUTDOWN 0x00080000 133#define NES_DBG_SHUTDOWN 0x00080000
132#define NES_DBG_PAU 0x00100000 134#define NES_DBG_PAU 0x00100000
135#define NES_DBG_NLMSG 0x00200000
133#define NES_DBG_RSVD1 0x10000000 136#define NES_DBG_RSVD1 0x10000000
134#define NES_DBG_RSVD2 0x20000000 137#define NES_DBG_RSVD2 0x20000000
135#define NES_DBG_RSVD3 0x40000000 138#define NES_DBG_RSVD3 0x40000000
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index dfa9df484505..6f09a72e78d7 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. 2 * Copyright (c) 2006 - 2014 Intel Corporation. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -59,6 +59,7 @@
59#include <net/route.h> 59#include <net/route.h>
60#include <net/ip_fib.h> 60#include <net/ip_fib.h>
61#include <net/tcp.h> 61#include <net/tcp.h>
62#include <linux/fcntl.h>
62 63
63#include "nes.h" 64#include "nes.h"
64 65
@@ -166,7 +167,6 @@ int nes_rem_ref_cm_node(struct nes_cm_node *cm_node)
166{ 167{
167 return rem_ref_cm_node(cm_node->cm_core, cm_node); 168 return rem_ref_cm_node(cm_node->cm_core, cm_node);
168} 169}
169
170/** 170/**
171 * create_event 171 * create_event
172 */ 172 */
@@ -482,11 +482,11 @@ static void form_cm_frame(struct sk_buff *skb,
482 iph->ttl = 0x40; 482 iph->ttl = 0x40;
483 iph->protocol = 0x06; /* IPPROTO_TCP */ 483 iph->protocol = 0x06; /* IPPROTO_TCP */
484 484
485 iph->saddr = htonl(cm_node->loc_addr); 485 iph->saddr = htonl(cm_node->mapped_loc_addr);
486 iph->daddr = htonl(cm_node->rem_addr); 486 iph->daddr = htonl(cm_node->mapped_rem_addr);
487 487
488 tcph->source = htons(cm_node->loc_port); 488 tcph->source = htons(cm_node->mapped_loc_port);
489 tcph->dest = htons(cm_node->rem_port); 489 tcph->dest = htons(cm_node->mapped_rem_port);
490 tcph->seq = htonl(cm_node->tcp_cntxt.loc_seq_num); 490 tcph->seq = htonl(cm_node->tcp_cntxt.loc_seq_num);
491 491
492 if (flags & SET_ACK) { 492 if (flags & SET_ACK) {
@@ -525,6 +525,100 @@ static void form_cm_frame(struct sk_buff *skb,
525 cm_packets_created++; 525 cm_packets_created++;
526} 526}
527 527
528/*
529 * nes_create_sockaddr - Record ip addr and tcp port in a sockaddr struct
530 */
531static void nes_create_sockaddr(__be32 ip_addr, __be16 port,
532 struct sockaddr_storage *addr)
533{
534 struct sockaddr_in *nes_sockaddr = (struct sockaddr_in *)addr;
535 nes_sockaddr->sin_family = AF_INET;
536 memcpy(&nes_sockaddr->sin_addr.s_addr, &ip_addr, sizeof(__be32));
537 nes_sockaddr->sin_port = port;
538}
539
540/*
541 * nes_create_mapinfo - Create a mapinfo object in the port mapper data base
542 */
543static int nes_create_mapinfo(struct nes_cm_info *cm_info)
544{
545 struct sockaddr_storage local_sockaddr;
546 struct sockaddr_storage mapped_sockaddr;
547
548 nes_create_sockaddr(htonl(cm_info->loc_addr), htons(cm_info->loc_port),
549 &local_sockaddr);
550 nes_create_sockaddr(htonl(cm_info->mapped_loc_addr),
551 htons(cm_info->mapped_loc_port), &mapped_sockaddr);
552
553 return iwpm_create_mapinfo(&local_sockaddr,
554 &mapped_sockaddr, RDMA_NL_NES);
555}
556
557/*
558 * nes_remove_mapinfo - Remove a mapinfo object from the port mapper data base
559 * and send a remove mapping op message to
560 * the userspace port mapper
561 */
562static int nes_remove_mapinfo(u32 loc_addr, u16 loc_port,
563 u32 mapped_loc_addr, u16 mapped_loc_port)
564{
565 struct sockaddr_storage local_sockaddr;
566 struct sockaddr_storage mapped_sockaddr;
567
568 nes_create_sockaddr(htonl(loc_addr), htons(loc_port), &local_sockaddr);
569 nes_create_sockaddr(htonl(mapped_loc_addr), htons(mapped_loc_port),
570 &mapped_sockaddr);
571
572 iwpm_remove_mapinfo(&local_sockaddr, &mapped_sockaddr);
573 return iwpm_remove_mapping(&local_sockaddr, RDMA_NL_NES);
574}
575
576/*
577 * nes_form_pm_msg - Form a port mapper message with mapping info
578 */
579static void nes_form_pm_msg(struct nes_cm_info *cm_info,
580 struct iwpm_sa_data *pm_msg)
581{
582 nes_create_sockaddr(htonl(cm_info->loc_addr), htons(cm_info->loc_port),
583 &pm_msg->loc_addr);
584 nes_create_sockaddr(htonl(cm_info->rem_addr), htons(cm_info->rem_port),
585 &pm_msg->rem_addr);
586}
587
588/*
589 * nes_form_reg_msg - Form a port mapper message with dev info
590 */
591static void nes_form_reg_msg(struct nes_vnic *nesvnic,
592 struct iwpm_dev_data *pm_msg)
593{
594 memcpy(pm_msg->dev_name, nesvnic->nesibdev->ibdev.name,
595 IWPM_DEVNAME_SIZE);
596 memcpy(pm_msg->if_name, nesvnic->netdev->name, IWPM_IFNAME_SIZE);
597}
598
599/*
600 * nes_record_pm_msg - Save the received mapping info
601 */
602static void nes_record_pm_msg(struct nes_cm_info *cm_info,
603 struct iwpm_sa_data *pm_msg)
604{
605 struct sockaddr_in *mapped_loc_addr =
606 (struct sockaddr_in *)&pm_msg->mapped_loc_addr;
607 struct sockaddr_in *mapped_rem_addr =
608 (struct sockaddr_in *)&pm_msg->mapped_rem_addr;
609
610 if (mapped_loc_addr->sin_family == AF_INET) {
611 cm_info->mapped_loc_addr =
612 ntohl(mapped_loc_addr->sin_addr.s_addr);
613 cm_info->mapped_loc_port = ntohs(mapped_loc_addr->sin_port);
614 }
615 if (mapped_rem_addr->sin_family == AF_INET) {
616 cm_info->mapped_rem_addr =
617 ntohl(mapped_rem_addr->sin_addr.s_addr);
618 cm_info->mapped_rem_port = ntohs(mapped_rem_addr->sin_port);
619 }
620}
621
528/** 622/**
529 * print_core - dump a cm core 623 * print_core - dump a cm core
530 */ 624 */
@@ -1147,8 +1241,11 @@ static struct nes_cm_node *find_node(struct nes_cm_core *cm_core,
1147 loc_addr, loc_port, 1241 loc_addr, loc_port,
1148 cm_node->rem_addr, cm_node->rem_port, 1242 cm_node->rem_addr, cm_node->rem_port,
1149 rem_addr, rem_port); 1243 rem_addr, rem_port);
1150 if ((cm_node->loc_addr == loc_addr) && (cm_node->loc_port == loc_port) && 1244 if ((cm_node->mapped_loc_addr == loc_addr) &&
1151 (cm_node->rem_addr == rem_addr) && (cm_node->rem_port == rem_port)) { 1245 (cm_node->mapped_loc_port == loc_port) &&
1246 (cm_node->mapped_rem_addr == rem_addr) &&
1247 (cm_node->mapped_rem_port == rem_port)) {
1248
1152 add_ref_cm_node(cm_node); 1249 add_ref_cm_node(cm_node);
1153 spin_unlock_irqrestore(&cm_core->ht_lock, flags); 1250 spin_unlock_irqrestore(&cm_core->ht_lock, flags);
1154 return cm_node; 1251 return cm_node;
@@ -1165,18 +1262,28 @@ static struct nes_cm_node *find_node(struct nes_cm_core *cm_core,
1165 * find_listener - find a cm node listening on this addr-port pair 1262 * find_listener - find a cm node listening on this addr-port pair
1166 */ 1263 */
1167static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core, 1264static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core,
1168 nes_addr_t dst_addr, u16 dst_port, enum nes_cm_listener_state listener_state) 1265 nes_addr_t dst_addr, u16 dst_port,
1266 enum nes_cm_listener_state listener_state, int local)
1169{ 1267{
1170 unsigned long flags; 1268 unsigned long flags;
1171 struct nes_cm_listener *listen_node; 1269 struct nes_cm_listener *listen_node;
1270 nes_addr_t listen_addr;
1271 u16 listen_port;
1172 1272
1173 /* walk list and find cm_node associated with this session ID */ 1273 /* walk list and find cm_node associated with this session ID */
1174 spin_lock_irqsave(&cm_core->listen_list_lock, flags); 1274 spin_lock_irqsave(&cm_core->listen_list_lock, flags);
1175 list_for_each_entry(listen_node, &cm_core->listen_list.list, list) { 1275 list_for_each_entry(listen_node, &cm_core->listen_list.list, list) {
1276 if (local) {
1277 listen_addr = listen_node->loc_addr;
1278 listen_port = listen_node->loc_port;
1279 } else {
1280 listen_addr = listen_node->mapped_loc_addr;
1281 listen_port = listen_node->mapped_loc_port;
1282 }
1176 /* compare node pair, return node handle if a match */ 1283 /* compare node pair, return node handle if a match */
1177 if (((listen_node->loc_addr == dst_addr) || 1284 if (((listen_addr == dst_addr) ||
1178 listen_node->loc_addr == 0x00000000) && 1285 listen_addr == 0x00000000) &&
1179 (listen_node->loc_port == dst_port) && 1286 (listen_port == dst_port) &&
1180 (listener_state & listen_node->listener_state)) { 1287 (listener_state & listen_node->listener_state)) {
1181 atomic_inc(&listen_node->ref_count); 1288 atomic_inc(&listen_node->ref_count);
1182 spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); 1289 spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
@@ -1189,7 +1296,6 @@ static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core,
1189 return NULL; 1296 return NULL;
1190} 1297}
1191 1298
1192
1193/** 1299/**
1194 * add_hte_node - add a cm node to the hash table 1300 * add_hte_node - add a cm node to the hash table
1195 */ 1301 */
@@ -1310,9 +1416,20 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
1310 1416
1311 spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); 1417 spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
1312 1418
1313 if (listener->nesvnic) 1419 if (listener->nesvnic) {
1314 nes_manage_apbvt(listener->nesvnic, listener->loc_port, 1420 nes_manage_apbvt(listener->nesvnic,
1315 PCI_FUNC(listener->nesvnic->nesdev->pcidev->devfn), NES_MANAGE_APBVT_DEL); 1421 listener->mapped_loc_port,
1422 PCI_FUNC(listener->nesvnic->nesdev->pcidev->devfn),
1423 NES_MANAGE_APBVT_DEL);
1424
1425 nes_remove_mapinfo(listener->loc_addr,
1426 listener->loc_port,
1427 listener->mapped_loc_addr,
1428 listener->mapped_loc_port);
1429 nes_debug(NES_DBG_NLMSG,
1430 "Delete APBVT mapped_loc_port = %04X\n",
1431 listener->mapped_loc_port);
1432 }
1316 1433
1317 nes_debug(NES_DBG_CM, "destroying listener (%p)\n", listener); 1434 nes_debug(NES_DBG_CM, "destroying listener (%p)\n", listener);
1318 1435
@@ -1454,6 +1571,11 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
1454 cm_node->loc_port = cm_info->loc_port; 1571 cm_node->loc_port = cm_info->loc_port;
1455 cm_node->rem_port = cm_info->rem_port; 1572 cm_node->rem_port = cm_info->rem_port;
1456 1573
1574 cm_node->mapped_loc_addr = cm_info->mapped_loc_addr;
1575 cm_node->mapped_rem_addr = cm_info->mapped_rem_addr;
1576 cm_node->mapped_loc_port = cm_info->mapped_loc_port;
1577 cm_node->mapped_rem_port = cm_info->mapped_rem_port;
1578
1457 cm_node->mpa_frame_rev = mpa_version; 1579 cm_node->mpa_frame_rev = mpa_version;
1458 cm_node->send_rdma0_op = SEND_RDMA_READ_ZERO; 1580 cm_node->send_rdma0_op = SEND_RDMA_READ_ZERO;
1459 cm_node->mpav2_ird_ord = 0; 1581 cm_node->mpav2_ird_ord = 0;
@@ -1500,8 +1622,10 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
1500 cm_node->loopbackpartner = NULL; 1622 cm_node->loopbackpartner = NULL;
1501 1623
1502 /* get the mac addr for the remote node */ 1624 /* get the mac addr for the remote node */
1503 oldarpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE); 1625 oldarpindex = nes_arp_table(nesdev, cm_node->mapped_rem_addr,
1504 arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr, oldarpindex); 1626 NULL, NES_ARP_RESOLVE);
1627 arpindex = nes_addr_resolve_neigh(nesvnic,
1628 cm_node->mapped_rem_addr, oldarpindex);
1505 if (arpindex < 0) { 1629 if (arpindex < 0) {
1506 kfree(cm_node); 1630 kfree(cm_node);
1507 return NULL; 1631 return NULL;
@@ -1563,11 +1687,14 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core,
1563 mini_cm_dec_refcnt_listen(cm_core, cm_node->listener, 0); 1687 mini_cm_dec_refcnt_listen(cm_core, cm_node->listener, 0);
1564 } else { 1688 } else {
1565 if (cm_node->apbvt_set && cm_node->nesvnic) { 1689 if (cm_node->apbvt_set && cm_node->nesvnic) {
1566 nes_manage_apbvt(cm_node->nesvnic, cm_node->loc_port, 1690 nes_manage_apbvt(cm_node->nesvnic, cm_node->mapped_loc_port,
1567 PCI_FUNC( 1691 PCI_FUNC(cm_node->nesvnic->nesdev->pcidev->devfn),
1568 cm_node->nesvnic->nesdev->pcidev->devfn),
1569 NES_MANAGE_APBVT_DEL); 1692 NES_MANAGE_APBVT_DEL);
1570 } 1693 }
1694 nes_debug(NES_DBG_NLMSG, "Delete APBVT mapped_loc_port = %04X\n",
1695 cm_node->mapped_loc_port);
1696 nes_remove_mapinfo(cm_node->loc_addr, cm_node->loc_port,
1697 cm_node->mapped_loc_addr, cm_node->mapped_loc_port);
1571 } 1698 }
1572 1699
1573 atomic_dec(&cm_core->node_cnt); 1700 atomic_dec(&cm_core->node_cnt);
@@ -2235,17 +2362,21 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
2235 * mini_cm_listen - create a listen node with params 2362 * mini_cm_listen - create a listen node with params
2236 */ 2363 */
2237static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *cm_core, 2364static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *cm_core,
2238 struct nes_vnic *nesvnic, struct nes_cm_info *cm_info) 2365 struct nes_vnic *nesvnic, struct nes_cm_info *cm_info)
2239{ 2366{
2240 struct nes_cm_listener *listener; 2367 struct nes_cm_listener *listener;
2368 struct iwpm_dev_data pm_reg_msg;
2369 struct iwpm_sa_data pm_msg;
2241 unsigned long flags; 2370 unsigned long flags;
2371 int iwpm_err = 0;
2242 2372
2243 nes_debug(NES_DBG_CM, "Search for 0x%08x : 0x%04x\n", 2373 nes_debug(NES_DBG_CM, "Search for 0x%08x : 0x%04x\n",
2244 cm_info->loc_addr, cm_info->loc_port); 2374 cm_info->loc_addr, cm_info->loc_port);
2245 2375
2246 /* cannot have multiple matching listeners */ 2376 /* cannot have multiple matching listeners */
2247 listener = find_listener(cm_core, htonl(cm_info->loc_addr), 2377 listener = find_listener(cm_core, cm_info->loc_addr, cm_info->loc_port,
2248 htons(cm_info->loc_port), NES_CM_LISTENER_EITHER_STATE); 2378 NES_CM_LISTENER_EITHER_STATE, 1);
2379
2249 if (listener && listener->listener_state == NES_CM_LISTENER_ACTIVE_STATE) { 2380 if (listener && listener->listener_state == NES_CM_LISTENER_ACTIVE_STATE) {
2250 /* find automatically incs ref count ??? */ 2381 /* find automatically incs ref count ??? */
2251 atomic_dec(&listener->ref_count); 2382 atomic_dec(&listener->ref_count);
@@ -2254,6 +2385,22 @@ static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *cm_core,
2254 } 2385 }
2255 2386
2256 if (!listener) { 2387 if (!listener) {
2388 nes_form_reg_msg(nesvnic, &pm_reg_msg);
2389 iwpm_err = iwpm_register_pid(&pm_reg_msg, RDMA_NL_NES);
2390 if (iwpm_err) {
2391 nes_debug(NES_DBG_NLMSG,
2392 "Port Mapper reg pid fail (err = %d).\n", iwpm_err);
2393 }
2394 if (iwpm_valid_pid() && !iwpm_err) {
2395 nes_form_pm_msg(cm_info, &pm_msg);
2396 iwpm_err = iwpm_add_mapping(&pm_msg, RDMA_NL_NES);
2397 if (iwpm_err)
2398 nes_debug(NES_DBG_NLMSG,
2399 "Port Mapper query fail (err = %d).\n", iwpm_err);
2400 else
2401 nes_record_pm_msg(cm_info, &pm_msg);
2402 }
2403
2257 /* create a CM listen node (1/2 node to compare incoming traffic to) */ 2404 /* create a CM listen node (1/2 node to compare incoming traffic to) */
2258 listener = kzalloc(sizeof(*listener), GFP_ATOMIC); 2405 listener = kzalloc(sizeof(*listener), GFP_ATOMIC);
2259 if (!listener) { 2406 if (!listener) {
@@ -2261,8 +2408,10 @@ static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *cm_core,
2261 return NULL; 2408 return NULL;
2262 } 2409 }
2263 2410
2264 listener->loc_addr = htonl(cm_info->loc_addr); 2411 listener->loc_addr = cm_info->loc_addr;
2265 listener->loc_port = htons(cm_info->loc_port); 2412 listener->loc_port = cm_info->loc_port;
2413 listener->mapped_loc_addr = cm_info->mapped_loc_addr;
2414 listener->mapped_loc_port = cm_info->mapped_loc_port;
2266 listener->reused_node = 0; 2415 listener->reused_node = 0;
2267 2416
2268 atomic_set(&listener->ref_count, 1); 2417 atomic_set(&listener->ref_count, 1);
@@ -2324,14 +2473,18 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
2324 2473
2325 if (cm_info->loc_addr == cm_info->rem_addr) { 2474 if (cm_info->loc_addr == cm_info->rem_addr) {
2326 loopbackremotelistener = find_listener(cm_core, 2475 loopbackremotelistener = find_listener(cm_core,
2327 ntohl(nesvnic->local_ipaddr), cm_node->rem_port, 2476 cm_node->mapped_loc_addr, cm_node->mapped_rem_port,
2328 NES_CM_LISTENER_ACTIVE_STATE); 2477 NES_CM_LISTENER_ACTIVE_STATE, 0);
2329 if (loopbackremotelistener == NULL) { 2478 if (loopbackremotelistener == NULL) {
2330 create_event(cm_node, NES_CM_EVENT_ABORTED); 2479 create_event(cm_node, NES_CM_EVENT_ABORTED);
2331 } else { 2480 } else {
2332 loopback_cm_info = *cm_info; 2481 loopback_cm_info = *cm_info;
2333 loopback_cm_info.loc_port = cm_info->rem_port; 2482 loopback_cm_info.loc_port = cm_info->rem_port;
2334 loopback_cm_info.rem_port = cm_info->loc_port; 2483 loopback_cm_info.rem_port = cm_info->loc_port;
2484 loopback_cm_info.mapped_loc_port =
2485 cm_info->mapped_rem_port;
2486 loopback_cm_info.mapped_rem_port =
2487 cm_info->mapped_loc_port;
2335 loopback_cm_info.cm_id = loopbackremotelistener->cm_id; 2488 loopback_cm_info.cm_id = loopbackremotelistener->cm_id;
2336 loopbackremotenode = make_cm_node(cm_core, nesvnic, 2489 loopbackremotenode = make_cm_node(cm_core, nesvnic,
2337 &loopback_cm_info, loopbackremotelistener); 2490 &loopback_cm_info, loopbackremotelistener);
@@ -2560,6 +2713,12 @@ static int mini_cm_recv_pkt(struct nes_cm_core *cm_core,
2560 nfo.rem_addr = ntohl(iph->saddr); 2713 nfo.rem_addr = ntohl(iph->saddr);
2561 nfo.rem_port = ntohs(tcph->source); 2714 nfo.rem_port = ntohs(tcph->source);
2562 2715
2716 /* If port mapper is available these should be mapped address info */
2717 nfo.mapped_loc_addr = ntohl(iph->daddr);
2718 nfo.mapped_loc_port = ntohs(tcph->dest);
2719 nfo.mapped_rem_addr = ntohl(iph->saddr);
2720 nfo.mapped_rem_port = ntohs(tcph->source);
2721
2563 tmp_daddr = cpu_to_be32(iph->daddr); 2722 tmp_daddr = cpu_to_be32(iph->daddr);
2564 tmp_saddr = cpu_to_be32(iph->saddr); 2723 tmp_saddr = cpu_to_be32(iph->saddr);
2565 2724
@@ -2568,8 +2727,8 @@ static int mini_cm_recv_pkt(struct nes_cm_core *cm_core,
2568 2727
2569 do { 2728 do {
2570 cm_node = find_node(cm_core, 2729 cm_node = find_node(cm_core,
2571 nfo.rem_port, nfo.rem_addr, 2730 nfo.mapped_rem_port, nfo.mapped_rem_addr,
2572 nfo.loc_port, nfo.loc_addr); 2731 nfo.mapped_loc_port, nfo.mapped_loc_addr);
2573 2732
2574 if (!cm_node) { 2733 if (!cm_node) {
2575 /* Only type of packet accepted are for */ 2734 /* Only type of packet accepted are for */
@@ -2578,9 +2737,9 @@ static int mini_cm_recv_pkt(struct nes_cm_core *cm_core,
2578 skb_handled = 0; 2737 skb_handled = 0;
2579 break; 2738 break;
2580 } 2739 }
2581 listener = find_listener(cm_core, nfo.loc_addr, 2740 listener = find_listener(cm_core, nfo.mapped_loc_addr,
2582 nfo.loc_port, 2741 nfo.mapped_loc_port,
2583 NES_CM_LISTENER_ACTIVE_STATE); 2742 NES_CM_LISTENER_ACTIVE_STATE, 0);
2584 if (!listener) { 2743 if (!listener) {
2585 nfo.cm_id = NULL; 2744 nfo.cm_id = NULL;
2586 nfo.conn_type = 0; 2745 nfo.conn_type = 0;
@@ -3184,10 +3343,12 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
3184 3343
3185 nes_cm_init_tsa_conn(nesqp, cm_node); 3344 nes_cm_init_tsa_conn(nesqp, cm_node);
3186 3345
3187 nesqp->nesqp_context->tcpPorts[0] = cpu_to_le16(ntohs(laddr->sin_port)); 3346 nesqp->nesqp_context->tcpPorts[0] =
3188 nesqp->nesqp_context->tcpPorts[1] = cpu_to_le16(ntohs(raddr->sin_port)); 3347 cpu_to_le16(cm_node->mapped_loc_port);
3348 nesqp->nesqp_context->tcpPorts[1] =
3349 cpu_to_le16(cm_node->mapped_rem_port);
3189 3350
3190 nesqp->nesqp_context->ip0 = cpu_to_le32(ntohl(raddr->sin_addr.s_addr)); 3351 nesqp->nesqp_context->ip0 = cpu_to_le32(cm_node->mapped_rem_addr);
3191 3352
3192 nesqp->nesqp_context->misc2 |= cpu_to_le32( 3353 nesqp->nesqp_context->misc2 |= cpu_to_le32(
3193 (u32)PCI_FUNC(nesdev->pcidev->devfn) << 3354 (u32)PCI_FUNC(nesdev->pcidev->devfn) <<
@@ -3211,9 +3372,9 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
3211 memset(&nes_quad, 0, sizeof(nes_quad)); 3372 memset(&nes_quad, 0, sizeof(nes_quad));
3212 nes_quad.DstIpAdrIndex = 3373 nes_quad.DstIpAdrIndex =
3213 cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24); 3374 cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24);
3214 nes_quad.SrcIpadr = raddr->sin_addr.s_addr; 3375 nes_quad.SrcIpadr = htonl(cm_node->mapped_rem_addr);
3215 nes_quad.TcpPorts[0] = raddr->sin_port; 3376 nes_quad.TcpPorts[0] = htons(cm_node->mapped_rem_port);
3216 nes_quad.TcpPorts[1] = laddr->sin_port; 3377 nes_quad.TcpPorts[1] = htons(cm_node->mapped_loc_port);
3217 3378
3218 /* Produce hash key */ 3379 /* Produce hash key */
3219 crc_value = get_crc_value(&nes_quad); 3380 crc_value = get_crc_value(&nes_quad);
@@ -3315,6 +3476,9 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
3315 int apbvt_set = 0; 3476 int apbvt_set = 0;
3316 struct sockaddr_in *laddr = (struct sockaddr_in *)&cm_id->local_addr; 3477 struct sockaddr_in *laddr = (struct sockaddr_in *)&cm_id->local_addr;
3317 struct sockaddr_in *raddr = (struct sockaddr_in *)&cm_id->remote_addr; 3478 struct sockaddr_in *raddr = (struct sockaddr_in *)&cm_id->remote_addr;
3479 struct iwpm_dev_data pm_reg_msg;
3480 struct iwpm_sa_data pm_msg;
3481 int iwpm_err = 0;
3318 3482
3319 if (cm_id->remote_addr.ss_family != AF_INET) 3483 if (cm_id->remote_addr.ss_family != AF_INET)
3320 return -ENOSYS; 3484 return -ENOSYS;
@@ -3352,20 +3516,44 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
3352 nes_debug(NES_DBG_CM, "mpa private data len =%u\n", 3516 nes_debug(NES_DBG_CM, "mpa private data len =%u\n",
3353 conn_param->private_data_len); 3517 conn_param->private_data_len);
3354 3518
3519 /* set up the connection params for the node */
3520 cm_info.loc_addr = ntohl(laddr->sin_addr.s_addr);
3521 cm_info.loc_port = ntohs(laddr->sin_port);
3522 cm_info.rem_addr = ntohl(raddr->sin_addr.s_addr);
3523 cm_info.rem_port = ntohs(raddr->sin_port);
3524 cm_info.cm_id = cm_id;
3525 cm_info.conn_type = NES_CM_IWARP_CONN_TYPE;
3526
3527 /* No port mapper available, go with the specified peer information */
3528 cm_info.mapped_loc_addr = cm_info.loc_addr;
3529 cm_info.mapped_loc_port = cm_info.loc_port;
3530 cm_info.mapped_rem_addr = cm_info.rem_addr;
3531 cm_info.mapped_rem_port = cm_info.rem_port;
3532
3533 nes_form_reg_msg(nesvnic, &pm_reg_msg);
3534 iwpm_err = iwpm_register_pid(&pm_reg_msg, RDMA_NL_NES);
3535 if (iwpm_err) {
3536 nes_debug(NES_DBG_NLMSG,
3537 "Port Mapper reg pid fail (err = %d).\n", iwpm_err);
3538 }
3539 if (iwpm_valid_pid() && !iwpm_err) {
3540 nes_form_pm_msg(&cm_info, &pm_msg);
3541 iwpm_err = iwpm_add_and_query_mapping(&pm_msg, RDMA_NL_NES);
3542 if (iwpm_err)
3543 nes_debug(NES_DBG_NLMSG,
3544 "Port Mapper query fail (err = %d).\n", iwpm_err);
3545 else
3546 nes_record_pm_msg(&cm_info, &pm_msg);
3547 }
3548
3355 if (laddr->sin_addr.s_addr != raddr->sin_addr.s_addr) { 3549 if (laddr->sin_addr.s_addr != raddr->sin_addr.s_addr) {
3356 nes_manage_apbvt(nesvnic, ntohs(laddr->sin_port), 3550 nes_manage_apbvt(nesvnic, cm_info.mapped_loc_port,
3357 PCI_FUNC(nesdev->pcidev->devfn), 3551 PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD);
3358 NES_MANAGE_APBVT_ADD);
3359 apbvt_set = 1; 3552 apbvt_set = 1;
3360 } 3553 }
3361 3554
3362 /* set up the connection params for the node */ 3555 if (nes_create_mapinfo(&cm_info))
3363 cm_info.loc_addr = htonl(laddr->sin_addr.s_addr); 3556 return -ENOMEM;
3364 cm_info.loc_port = htons(laddr->sin_port);
3365 cm_info.rem_addr = htonl(raddr->sin_addr.s_addr);
3366 cm_info.rem_port = htons(raddr->sin_port);
3367 cm_info.cm_id = cm_id;
3368 cm_info.conn_type = NES_CM_IWARP_CONN_TYPE;
3369 3557
3370 cm_id->add_ref(cm_id); 3558 cm_id->add_ref(cm_id);
3371 3559
@@ -3375,10 +3563,14 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
3375 &cm_info); 3563 &cm_info);
3376 if (!cm_node) { 3564 if (!cm_node) {
3377 if (apbvt_set) 3565 if (apbvt_set)
3378 nes_manage_apbvt(nesvnic, ntohs(laddr->sin_port), 3566 nes_manage_apbvt(nesvnic, cm_info.mapped_loc_port,
3379 PCI_FUNC(nesdev->pcidev->devfn), 3567 PCI_FUNC(nesdev->pcidev->devfn),
3380 NES_MANAGE_APBVT_DEL); 3568 NES_MANAGE_APBVT_DEL);
3381 3569
3570 nes_debug(NES_DBG_NLMSG, "Delete mapped_loc_port = %04X\n",
3571 cm_info.mapped_loc_port);
3572 nes_remove_mapinfo(cm_info.loc_addr, cm_info.loc_port,
3573 cm_info.mapped_loc_addr, cm_info.mapped_loc_port);
3382 cm_id->rem_ref(cm_id); 3574 cm_id->rem_ref(cm_id);
3383 return -ENOMEM; 3575 return -ENOMEM;
3384 } 3576 }
@@ -3424,13 +3616,16 @@ int nes_create_listen(struct iw_cm_id *cm_id, int backlog)
3424 nesvnic->local_ipaddr, laddr->sin_addr.s_addr); 3616 nesvnic->local_ipaddr, laddr->sin_addr.s_addr);
3425 3617
3426 /* setup listen params in our api call struct */ 3618 /* setup listen params in our api call struct */
3427 cm_info.loc_addr = nesvnic->local_ipaddr; 3619 cm_info.loc_addr = ntohl(nesvnic->local_ipaddr);
3428 cm_info.loc_port = laddr->sin_port; 3620 cm_info.loc_port = ntohs(laddr->sin_port);
3429 cm_info.backlog = backlog; 3621 cm_info.backlog = backlog;
3430 cm_info.cm_id = cm_id; 3622 cm_info.cm_id = cm_id;
3431 3623
3432 cm_info.conn_type = NES_CM_IWARP_CONN_TYPE; 3624 cm_info.conn_type = NES_CM_IWARP_CONN_TYPE;
3433 3625
3626 /* No port mapper available, go with the specified info */
3627 cm_info.mapped_loc_addr = cm_info.loc_addr;
3628 cm_info.mapped_loc_port = cm_info.loc_port;
3434 3629
3435 cm_node = g_cm_core->api->listen(g_cm_core, nesvnic, &cm_info); 3630 cm_node = g_cm_core->api->listen(g_cm_core, nesvnic, &cm_info);
3436 if (!cm_node) { 3631 if (!cm_node) {
@@ -3442,7 +3637,10 @@ int nes_create_listen(struct iw_cm_id *cm_id, int backlog)
3442 cm_id->provider_data = cm_node; 3637 cm_id->provider_data = cm_node;
3443 3638
3444 if (!cm_node->reused_node) { 3639 if (!cm_node->reused_node) {
3445 err = nes_manage_apbvt(nesvnic, ntohs(laddr->sin_port), 3640 if (nes_create_mapinfo(&cm_info))
3641 return -ENOMEM;
3642
3643 err = nes_manage_apbvt(nesvnic, cm_node->mapped_loc_port,
3446 PCI_FUNC(nesvnic->nesdev->pcidev->devfn), 3644 PCI_FUNC(nesvnic->nesdev->pcidev->devfn),
3447 NES_MANAGE_APBVT_ADD); 3645 NES_MANAGE_APBVT_ADD);
3448 if (err) { 3646 if (err) {
@@ -3567,9 +3765,11 @@ static void cm_event_connected(struct nes_cm_event *event)
3567 nes_cm_init_tsa_conn(nesqp, cm_node); 3765 nes_cm_init_tsa_conn(nesqp, cm_node);
3568 3766
3569 /* set the QP tsa context */ 3767 /* set the QP tsa context */
3570 nesqp->nesqp_context->tcpPorts[0] = cpu_to_le16(ntohs(laddr->sin_port)); 3768 nesqp->nesqp_context->tcpPorts[0] =
3571 nesqp->nesqp_context->tcpPorts[1] = cpu_to_le16(ntohs(raddr->sin_port)); 3769 cpu_to_le16(cm_node->mapped_loc_port);
3572 nesqp->nesqp_context->ip0 = cpu_to_le32(ntohl(raddr->sin_addr.s_addr)); 3770 nesqp->nesqp_context->tcpPorts[1] =
3771 cpu_to_le16(cm_node->mapped_rem_port);
3772 nesqp->nesqp_context->ip0 = cpu_to_le32(cm_node->mapped_rem_addr);
3573 3773
3574 nesqp->nesqp_context->misc2 |= cpu_to_le32( 3774 nesqp->nesqp_context->misc2 |= cpu_to_le32(
3575 (u32)PCI_FUNC(nesdev->pcidev->devfn) << 3775 (u32)PCI_FUNC(nesdev->pcidev->devfn) <<
@@ -3599,9 +3799,9 @@ static void cm_event_connected(struct nes_cm_event *event)
3599 3799
3600 nes_quad.DstIpAdrIndex = 3800 nes_quad.DstIpAdrIndex =
3601 cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24); 3801 cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24);
3602 nes_quad.SrcIpadr = raddr->sin_addr.s_addr; 3802 nes_quad.SrcIpadr = htonl(cm_node->mapped_rem_addr);
3603 nes_quad.TcpPorts[0] = raddr->sin_port; 3803 nes_quad.TcpPorts[0] = htons(cm_node->mapped_rem_port);
3604 nes_quad.TcpPorts[1] = laddr->sin_port; 3804 nes_quad.TcpPorts[1] = htons(cm_node->mapped_loc_port);
3605 3805
3606 /* Produce hash key */ 3806 /* Produce hash key */
3607 crc_value = get_crc_value(&nes_quad); 3807 crc_value = get_crc_value(&nes_quad);
@@ -3629,7 +3829,7 @@ static void cm_event_connected(struct nes_cm_event *event)
3629 cm_event.ird = cm_node->ird_size; 3829 cm_event.ird = cm_node->ird_size;
3630 cm_event.ord = cm_node->ord_size; 3830 cm_event.ord = cm_node->ord_size;
3631 3831
3632 cm_event_laddr->sin_addr.s_addr = event->cm_info.rem_addr; 3832 cm_event_laddr->sin_addr.s_addr = htonl(event->cm_info.rem_addr);
3633 ret = cm_id->event_handler(cm_id, &cm_event); 3833 ret = cm_id->event_handler(cm_id, &cm_event);
3634 nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret); 3834 nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret);
3635 3835
diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h
index 522c99cd07c4..f522cf639789 100644
--- a/drivers/infiniband/hw/nes/nes_cm.h
+++ b/drivers/infiniband/hw/nes/nes_cm.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. 2 * Copyright (c) 2006 - 2014 Intel Corporation. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -293,8 +293,8 @@ struct nes_cm_listener {
293 struct list_head list; 293 struct list_head list;
294 struct nes_cm_core *cm_core; 294 struct nes_cm_core *cm_core;
295 u8 loc_mac[ETH_ALEN]; 295 u8 loc_mac[ETH_ALEN];
296 nes_addr_t loc_addr; 296 nes_addr_t loc_addr, mapped_loc_addr;
297 u16 loc_port; 297 u16 loc_port, mapped_loc_port;
298 struct iw_cm_id *cm_id; 298 struct iw_cm_id *cm_id;
299 enum nes_cm_conn_type conn_type; 299 enum nes_cm_conn_type conn_type;
300 atomic_t ref_count; 300 atomic_t ref_count;
@@ -308,7 +308,9 @@ struct nes_cm_listener {
308/* per connection node and node state information */ 308/* per connection node and node state information */
309struct nes_cm_node { 309struct nes_cm_node {
310 nes_addr_t loc_addr, rem_addr; 310 nes_addr_t loc_addr, rem_addr;
311 nes_addr_t mapped_loc_addr, mapped_rem_addr;
311 u16 loc_port, rem_port; 312 u16 loc_port, rem_port;
313 u16 mapped_loc_port, mapped_rem_port;
312 314
313 u8 loc_mac[ETH_ALEN]; 315 u8 loc_mac[ETH_ALEN];
314 u8 rem_mac[ETH_ALEN]; 316 u8 rem_mac[ETH_ALEN];
@@ -364,6 +366,10 @@ struct nes_cm_info {
364 u16 rem_port; 366 u16 rem_port;
365 nes_addr_t loc_addr; 367 nes_addr_t loc_addr;
366 nes_addr_t rem_addr; 368 nes_addr_t rem_addr;
369 u16 mapped_loc_port;
370 u16 mapped_rem_port;
371 nes_addr_t mapped_loc_addr;
372 nes_addr_t mapped_rem_addr;
367 373
368 enum nes_cm_conn_type conn_type; 374 enum nes_cm_conn_type conn_type;
369 int backlog; 375 int backlog;