diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/infiniband/hw/nes | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/infiniband/hw/nes')
-rw-r--r-- | drivers/infiniband/hw/nes/Kconfig | 9 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes.c | 7 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes.h | 11 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.c | 213 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.h | 7 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_context.h | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.c | 491 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.h | 32 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_nic.c | 185 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_user.h | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_utils.c | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_verbs.c | 834 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_verbs.h | 23 |
13 files changed, 1009 insertions, 811 deletions
diff --git a/drivers/infiniband/hw/nes/Kconfig b/drivers/infiniband/hw/nes/Kconfig index d449eb6ec78e..846dc97cf260 100644 --- a/drivers/infiniband/hw/nes/Kconfig +++ b/drivers/infiniband/hw/nes/Kconfig | |||
@@ -4,14 +4,13 @@ config INFINIBAND_NES | |||
4 | select LIBCRC32C | 4 | select LIBCRC32C |
5 | select INET_LRO | 5 | select INET_LRO |
6 | ---help--- | 6 | ---help--- |
7 | This is a low-level driver for NetEffect RDMA enabled | 7 | This is the RDMA Network Interface Card (RNIC) driver for |
8 | Network Interface Cards (RNIC). | 8 | NetEffect Ethernet Cluster Server Adapters. |
9 | 9 | ||
10 | config INFINIBAND_NES_DEBUG | 10 | config INFINIBAND_NES_DEBUG |
11 | bool "Verbose debugging output" | 11 | bool "Verbose debugging output" |
12 | depends on INFINIBAND_NES | 12 | depends on INFINIBAND_NES |
13 | default n | 13 | default n |
14 | ---help--- | 14 | ---help--- |
15 | This option causes the NetEffect RNIC driver to produce debug | 15 | This option enables debug messages from the NetEffect RNIC |
16 | messages. Select this if you are developing the driver | 16 | driver. Select this if you are diagnosing a problem. |
17 | or trying to diagnose a problem. | ||
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index cbde0cfe27e0..de7b9d7166f3 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. | 2 | * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. |
3 | * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. | 3 | * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This software is available to you under a choice of one of two | 5 | * This software is available to you under a choice of one of two |
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/init.h> | 44 | #include <linux/init.h> |
45 | #include <linux/if_arp.h> | 45 | #include <linux/if_arp.h> |
46 | #include <linux/highmem.h> | 46 | #include <linux/highmem.h> |
47 | #include <linux/slab.h> | ||
47 | #include <asm/io.h> | 48 | #include <asm/io.h> |
48 | #include <asm/irq.h> | 49 | #include <asm/irq.h> |
49 | #include <asm/byteorder.h> | 50 | #include <asm/byteorder.h> |
@@ -110,6 +111,7 @@ static unsigned int sysfs_idx_addr; | |||
110 | 111 | ||
111 | static struct pci_device_id nes_pci_table[] = { | 112 | static struct pci_device_id nes_pci_table[] = { |
112 | {PCI_VENDOR_ID_NETEFFECT, PCI_DEVICE_ID_NETEFFECT_NE020, PCI_ANY_ID, PCI_ANY_ID}, | 113 | {PCI_VENDOR_ID_NETEFFECT, PCI_DEVICE_ID_NETEFFECT_NE020, PCI_ANY_ID, PCI_ANY_ID}, |
114 | {PCI_VENDOR_ID_NETEFFECT, PCI_DEVICE_ID_NETEFFECT_NE020_KR, PCI_ANY_ID, PCI_ANY_ID}, | ||
113 | {0} | 115 | {0} |
114 | }; | 116 | }; |
115 | 117 | ||
@@ -521,7 +523,8 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i | |||
521 | spin_lock_init(&nesdev->indexed_regs_lock); | 523 | spin_lock_init(&nesdev->indexed_regs_lock); |
522 | 524 | ||
523 | /* Remap the PCI registers in adapter BAR0 to kernel VA space */ | 525 | /* Remap the PCI registers in adapter BAR0 to kernel VA space */ |
524 | mmio_regs = ioremap_nocache(pci_resource_start(pcidev, BAR_0), sizeof(mmio_regs)); | 526 | mmio_regs = ioremap_nocache(pci_resource_start(pcidev, BAR_0), |
527 | pci_resource_len(pcidev, BAR_0)); | ||
525 | if (mmio_regs == NULL) { | 528 | if (mmio_regs == NULL) { |
526 | printk(KERN_ERR PFX "Unable to remap BAR0\n"); | 529 | printk(KERN_ERR PFX "Unable to remap BAR0\n"); |
527 | ret = -EIO; | 530 | ret = -EIO; |
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h index bcc6abc4faff..cc78fee1dd51 100644 --- a/drivers/infiniband/hw/nes/nes.h +++ b/drivers/infiniband/hw/nes/nes.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. | 2 | * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. |
3 | * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. | 3 | * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This software is available to you under a choice of one of two | 5 | * This software is available to you under a choice of one of two |
@@ -64,8 +64,9 @@ | |||
64 | * NetEffect PCI vendor id and NE010 PCI device id. | 64 | * NetEffect PCI vendor id and NE010 PCI device id. |
65 | */ | 65 | */ |
66 | #ifndef PCI_VENDOR_ID_NETEFFECT /* not in pci.ids yet */ | 66 | #ifndef PCI_VENDOR_ID_NETEFFECT /* not in pci.ids yet */ |
67 | #define PCI_VENDOR_ID_NETEFFECT 0x1678 | 67 | #define PCI_VENDOR_ID_NETEFFECT 0x1678 |
68 | #define PCI_DEVICE_ID_NETEFFECT_NE020 0x0100 | 68 | #define PCI_DEVICE_ID_NETEFFECT_NE020 0x0100 |
69 | #define PCI_DEVICE_ID_NETEFFECT_NE020_KR 0x0110 | ||
69 | #endif | 70 | #endif |
70 | 71 | ||
71 | #define NE020_REV 4 | 72 | #define NE020_REV 4 |
@@ -193,8 +194,8 @@ extern u32 cm_packets_created; | |||
193 | extern u32 cm_packets_received; | 194 | extern u32 cm_packets_received; |
194 | extern u32 cm_packets_dropped; | 195 | extern u32 cm_packets_dropped; |
195 | extern u32 cm_packets_retrans; | 196 | extern u32 cm_packets_retrans; |
196 | extern u32 cm_listens_created; | 197 | extern atomic_t cm_listens_created; |
197 | extern u32 cm_listens_destroyed; | 198 | extern atomic_t cm_listens_destroyed; |
198 | extern u32 cm_backlog_drops; | 199 | extern u32 cm_backlog_drops; |
199 | extern atomic_t cm_loopbacks; | 200 | extern atomic_t cm_loopbacks; |
200 | extern atomic_t cm_nodes_created; | 201 | extern atomic_t cm_nodes_created; |
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 73473db19863..986d6f32dded 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 - 2009 Intel-NE, Inc. All rights reserved. | 2 | * Copyright (c) 2006 - 2009 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 |
@@ -52,6 +52,8 @@ | |||
52 | #include <linux/random.h> | 52 | #include <linux/random.h> |
53 | #include <linux/list.h> | 53 | #include <linux/list.h> |
54 | #include <linux/threads.h> | 54 | #include <linux/threads.h> |
55 | #include <linux/highmem.h> | ||
56 | #include <linux/slab.h> | ||
55 | #include <net/arp.h> | 57 | #include <net/arp.h> |
56 | #include <net/neighbour.h> | 58 | #include <net/neighbour.h> |
57 | #include <net/route.h> | 59 | #include <net/route.h> |
@@ -66,8 +68,8 @@ u32 cm_packets_dropped; | |||
66 | u32 cm_packets_retrans; | 68 | u32 cm_packets_retrans; |
67 | u32 cm_packets_created; | 69 | u32 cm_packets_created; |
68 | u32 cm_packets_received; | 70 | u32 cm_packets_received; |
69 | u32 cm_listens_created; | 71 | atomic_t cm_listens_created; |
70 | u32 cm_listens_destroyed; | 72 | atomic_t cm_listens_destroyed; |
71 | u32 cm_backlog_drops; | 73 | u32 cm_backlog_drops; |
72 | atomic_t cm_loopbacks; | 74 | atomic_t cm_loopbacks; |
73 | atomic_t cm_nodes_created; | 75 | atomic_t cm_nodes_created; |
@@ -251,6 +253,33 @@ static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 *type, | |||
251 | 253 | ||
252 | mpa_frame = (struct ietf_mpa_frame *)buffer; | 254 | mpa_frame = (struct ietf_mpa_frame *)buffer; |
253 | cm_node->mpa_frame_size = ntohs(mpa_frame->priv_data_len); | 255 | cm_node->mpa_frame_size = ntohs(mpa_frame->priv_data_len); |
256 | /* make sure mpa private data len is less than 512 bytes */ | ||
257 | if (cm_node->mpa_frame_size > IETF_MAX_PRIV_DATA_LEN) { | ||
258 | nes_debug(NES_DBG_CM, "The received Length of Private" | ||
259 | " Data field exceeds 512 octets\n"); | ||
260 | return -EINVAL; | ||
261 | } | ||
262 | /* | ||
263 | * make sure MPA receiver interoperate with the | ||
264 | * received MPA version and MPA key information | ||
265 | * | ||
266 | */ | ||
267 | if (mpa_frame->rev != mpa_version) { | ||
268 | nes_debug(NES_DBG_CM, "The received mpa version" | ||
269 | " can not be interoperated\n"); | ||
270 | return -EINVAL; | ||
271 | } | ||
272 | if (cm_node->state != NES_CM_STATE_MPAREQ_SENT) { | ||
273 | if (memcmp(mpa_frame->key, IEFT_MPA_KEY_REQ, IETF_MPA_KEY_SIZE)) { | ||
274 | nes_debug(NES_DBG_CM, "Unexpected MPA Key received \n"); | ||
275 | return -EINVAL; | ||
276 | } | ||
277 | } else { | ||
278 | if (memcmp(mpa_frame->key, IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE)) { | ||
279 | nes_debug(NES_DBG_CM, "Unexpected MPA Key received \n"); | ||
280 | return -EINVAL; | ||
281 | } | ||
282 | } | ||
254 | 283 | ||
255 | if (cm_node->mpa_frame_size + sizeof(struct ietf_mpa_frame) != len) { | 284 | if (cm_node->mpa_frame_size + sizeof(struct ietf_mpa_frame) != len) { |
256 | nes_debug(NES_DBG_CM, "The received ietf buffer was not right" | 285 | nes_debug(NES_DBG_CM, "The received ietf buffer was not right" |
@@ -486,6 +515,8 @@ static void nes_retrans_expired(struct nes_cm_node *cm_node) | |||
486 | send_reset(cm_node, NULL); | 515 | send_reset(cm_node, NULL); |
487 | break; | 516 | break; |
488 | default: | 517 | default: |
518 | add_ref_cm_node(cm_node); | ||
519 | send_reset(cm_node, NULL); | ||
489 | create_event(cm_node, NES_CM_EVENT_ABORTED); | 520 | create_event(cm_node, NES_CM_EVENT_ABORTED); |
490 | } | 521 | } |
491 | } | 522 | } |
@@ -949,6 +980,7 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, | |||
949 | reset_entry); | 980 | reset_entry); |
950 | { | 981 | { |
951 | struct nes_cm_node *loopback = cm_node->loopbackpartner; | 982 | struct nes_cm_node *loopback = cm_node->loopbackpartner; |
983 | enum nes_cm_node_state old_state; | ||
952 | if (NES_CM_STATE_FIN_WAIT1 <= cm_node->state) { | 984 | if (NES_CM_STATE_FIN_WAIT1 <= cm_node->state) { |
953 | rem_ref_cm_node(cm_node->cm_core, cm_node); | 985 | rem_ref_cm_node(cm_node->cm_core, cm_node); |
954 | } else { | 986 | } else { |
@@ -960,11 +992,12 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, | |||
960 | NES_CM_STATE_CLOSED; | 992 | NES_CM_STATE_CLOSED; |
961 | WARN_ON(1); | 993 | WARN_ON(1); |
962 | } else { | 994 | } else { |
963 | cm_node->state = | 995 | old_state = cm_node->state; |
964 | NES_CM_STATE_CLOSED; | 996 | cm_node->state = NES_CM_STATE_LISTENER_DESTROYED; |
965 | rem_ref_cm_node( | 997 | if (old_state != NES_CM_STATE_MPAREQ_RCVD) |
966 | cm_node->cm_core, | 998 | rem_ref_cm_node( |
967 | cm_node); | 999 | cm_node->cm_core, |
1000 | cm_node); | ||
968 | } | 1001 | } |
969 | } else { | 1002 | } else { |
970 | struct nes_cm_event event; | 1003 | struct nes_cm_event event; |
@@ -979,20 +1012,10 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, | |||
979 | event.cm_info.loc_port = | 1012 | event.cm_info.loc_port = |
980 | loopback->loc_port; | 1013 | loopback->loc_port; |
981 | event.cm_info.cm_id = loopback->cm_id; | 1014 | event.cm_info.cm_id = loopback->cm_id; |
982 | cm_event_connect_error(&event); | 1015 | add_ref_cm_node(loopback); |
983 | loopback->state = NES_CM_STATE_CLOSED; | 1016 | loopback->state = NES_CM_STATE_CLOSED; |
984 | 1017 | cm_event_connect_error(&event); | |
985 | event.cm_node = cm_node; | 1018 | cm_node->state = NES_CM_STATE_LISTENER_DESTROYED; |
986 | event.cm_info.rem_addr = | ||
987 | cm_node->rem_addr; | ||
988 | event.cm_info.loc_addr = | ||
989 | cm_node->loc_addr; | ||
990 | event.cm_info.rem_port = | ||
991 | cm_node->rem_port; | ||
992 | event.cm_info.loc_port = | ||
993 | cm_node->loc_port; | ||
994 | event.cm_info.cm_id = cm_node->cm_id; | ||
995 | cm_event_reset(&event); | ||
996 | 1019 | ||
997 | rem_ref_cm_node(cm_node->cm_core, | 1020 | rem_ref_cm_node(cm_node->cm_core, |
998 | cm_node); | 1021 | cm_node); |
@@ -1021,7 +1044,7 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, | |||
1021 | kfree(listener); | 1044 | kfree(listener); |
1022 | listener = NULL; | 1045 | listener = NULL; |
1023 | ret = 0; | 1046 | ret = 0; |
1024 | cm_listens_destroyed++; | 1047 | atomic_inc(&cm_listens_destroyed); |
1025 | } else { | 1048 | } else { |
1026 | spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); | 1049 | spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); |
1027 | } | 1050 | } |
@@ -1077,12 +1100,13 @@ static inline int mini_cm_accelerated(struct nes_cm_core *cm_core, | |||
1077 | /** | 1100 | /** |
1078 | * nes_addr_resolve_neigh | 1101 | * nes_addr_resolve_neigh |
1079 | */ | 1102 | */ |
1080 | static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip) | 1103 | static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpindex) |
1081 | { | 1104 | { |
1082 | struct rtable *rt; | 1105 | struct rtable *rt; |
1083 | struct flowi fl; | 1106 | struct flowi fl; |
1084 | struct neighbour *neigh; | 1107 | struct neighbour *neigh; |
1085 | int rc = -1; | 1108 | int rc = arpindex; |
1109 | struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter; | ||
1086 | 1110 | ||
1087 | memset(&fl, 0, sizeof fl); | 1111 | memset(&fl, 0, sizeof fl); |
1088 | fl.nl_u.ip4_u.daddr = htonl(dst_ip); | 1112 | fl.nl_u.ip4_u.daddr = htonl(dst_ip); |
@@ -1098,6 +1122,21 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip) | |||
1098 | nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X" | 1122 | nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X" |
1099 | " is %pM, Gateway is 0x%08X \n", dst_ip, | 1123 | " is %pM, Gateway is 0x%08X \n", dst_ip, |
1100 | neigh->ha, ntohl(rt->rt_gateway)); | 1124 | neigh->ha, ntohl(rt->rt_gateway)); |
1125 | |||
1126 | if (arpindex >= 0) { | ||
1127 | if (!memcmp(nesadapter->arp_table[arpindex].mac_addr, | ||
1128 | neigh->ha, ETH_ALEN)){ | ||
1129 | /* Mac address same as in nes_arp_table */ | ||
1130 | neigh_release(neigh); | ||
1131 | ip_rt_put(rt); | ||
1132 | return rc; | ||
1133 | } | ||
1134 | |||
1135 | nes_manage_arp_cache(nesvnic->netdev, | ||
1136 | nesadapter->arp_table[arpindex].mac_addr, | ||
1137 | dst_ip, NES_ARP_DELETE); | ||
1138 | } | ||
1139 | |||
1101 | nes_manage_arp_cache(nesvnic->netdev, neigh->ha, | 1140 | nes_manage_arp_cache(nesvnic->netdev, neigh->ha, |
1102 | dst_ip, NES_ARP_ADD); | 1141 | dst_ip, NES_ARP_ADD); |
1103 | rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL, | 1142 | rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL, |
@@ -1113,7 +1152,6 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip) | |||
1113 | return rc; | 1152 | return rc; |
1114 | } | 1153 | } |
1115 | 1154 | ||
1116 | |||
1117 | /** | 1155 | /** |
1118 | * make_cm_node - create a new instance of a cm node | 1156 | * make_cm_node - create a new instance of a cm node |
1119 | */ | 1157 | */ |
@@ -1123,6 +1161,7 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core, | |||
1123 | { | 1161 | { |
1124 | struct nes_cm_node *cm_node; | 1162 | struct nes_cm_node *cm_node; |
1125 | struct timespec ts; | 1163 | struct timespec ts; |
1164 | int oldarpindex = 0; | ||
1126 | int arpindex = 0; | 1165 | int arpindex = 0; |
1127 | struct nes_device *nesdev; | 1166 | struct nes_device *nesdev; |
1128 | struct nes_adapter *nesadapter; | 1167 | struct nes_adapter *nesadapter; |
@@ -1176,17 +1215,18 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core, | |||
1176 | nesadapter = nesdev->nesadapter; | 1215 | nesadapter = nesdev->nesadapter; |
1177 | 1216 | ||
1178 | cm_node->loopbackpartner = NULL; | 1217 | cm_node->loopbackpartner = NULL; |
1218 | |||
1179 | /* get the mac addr for the remote node */ | 1219 | /* get the mac addr for the remote node */ |
1180 | if (ipv4_is_loopback(htonl(cm_node->rem_addr))) | 1220 | if (ipv4_is_loopback(htonl(cm_node->rem_addr))) |
1181 | arpindex = nes_arp_table(nesdev, ntohl(nesvnic->local_ipaddr), NULL, NES_ARP_RESOLVE); | 1221 | arpindex = nes_arp_table(nesdev, ntohl(nesvnic->local_ipaddr), NULL, NES_ARP_RESOLVE); |
1182 | else | 1222 | else { |
1183 | arpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE); | 1223 | oldarpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE); |
1224 | arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr, oldarpindex); | ||
1225 | |||
1226 | } | ||
1184 | if (arpindex < 0) { | 1227 | if (arpindex < 0) { |
1185 | arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr); | 1228 | kfree(cm_node); |
1186 | if (arpindex < 0) { | 1229 | return NULL; |
1187 | kfree(cm_node); | ||
1188 | return NULL; | ||
1189 | } | ||
1190 | } | 1230 | } |
1191 | 1231 | ||
1192 | /* copy the mac addr to node context */ | 1232 | /* copy the mac addr to node context */ |
@@ -1333,13 +1373,20 @@ static void handle_fin_pkt(struct nes_cm_node *cm_node) | |||
1333 | case NES_CM_STATE_SYN_RCVD: | 1373 | case NES_CM_STATE_SYN_RCVD: |
1334 | case NES_CM_STATE_SYN_SENT: | 1374 | case NES_CM_STATE_SYN_SENT: |
1335 | case NES_CM_STATE_ESTABLISHED: | 1375 | case NES_CM_STATE_ESTABLISHED: |
1336 | case NES_CM_STATE_MPAREQ_SENT: | ||
1337 | case NES_CM_STATE_MPAREJ_RCVD: | 1376 | case NES_CM_STATE_MPAREJ_RCVD: |
1338 | cm_node->tcp_cntxt.rcv_nxt++; | 1377 | cm_node->tcp_cntxt.rcv_nxt++; |
1339 | cleanup_retrans_entry(cm_node); | 1378 | cleanup_retrans_entry(cm_node); |
1340 | cm_node->state = NES_CM_STATE_LAST_ACK; | 1379 | cm_node->state = NES_CM_STATE_LAST_ACK; |
1341 | send_fin(cm_node, NULL); | 1380 | send_fin(cm_node, NULL); |
1342 | break; | 1381 | break; |
1382 | case NES_CM_STATE_MPAREQ_SENT: | ||
1383 | create_event(cm_node, NES_CM_EVENT_ABORTED); | ||
1384 | cm_node->tcp_cntxt.rcv_nxt++; | ||
1385 | cleanup_retrans_entry(cm_node); | ||
1386 | cm_node->state = NES_CM_STATE_CLOSED; | ||
1387 | add_ref_cm_node(cm_node); | ||
1388 | send_reset(cm_node, NULL); | ||
1389 | break; | ||
1343 | case NES_CM_STATE_FIN_WAIT1: | 1390 | case NES_CM_STATE_FIN_WAIT1: |
1344 | cm_node->tcp_cntxt.rcv_nxt++; | 1391 | cm_node->tcp_cntxt.rcv_nxt++; |
1345 | cleanup_retrans_entry(cm_node); | 1392 | cleanup_retrans_entry(cm_node); |
@@ -1590,6 +1637,7 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1590 | break; | 1637 | break; |
1591 | case NES_CM_STATE_CLOSED: | 1638 | case NES_CM_STATE_CLOSED: |
1592 | cleanup_retrans_entry(cm_node); | 1639 | cleanup_retrans_entry(cm_node); |
1640 | add_ref_cm_node(cm_node); | ||
1593 | send_reset(cm_node, skb); | 1641 | send_reset(cm_node, skb); |
1594 | break; | 1642 | break; |
1595 | case NES_CM_STATE_TSA: | 1643 | case NES_CM_STATE_TSA: |
@@ -1641,9 +1689,15 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1641 | passive_open_err(cm_node, skb, 1); | 1689 | passive_open_err(cm_node, skb, 1); |
1642 | break; | 1690 | break; |
1643 | case NES_CM_STATE_LISTENING: | 1691 | case NES_CM_STATE_LISTENING: |
1692 | cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq); | ||
1693 | cleanup_retrans_entry(cm_node); | ||
1694 | cm_node->state = NES_CM_STATE_CLOSED; | ||
1695 | send_reset(cm_node, skb); | ||
1696 | break; | ||
1644 | case NES_CM_STATE_CLOSED: | 1697 | case NES_CM_STATE_CLOSED: |
1645 | cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq); | 1698 | cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq); |
1646 | cleanup_retrans_entry(cm_node); | 1699 | cleanup_retrans_entry(cm_node); |
1700 | add_ref_cm_node(cm_node); | ||
1647 | send_reset(cm_node, skb); | 1701 | send_reset(cm_node, skb); |
1648 | break; | 1702 | break; |
1649 | case NES_CM_STATE_ESTABLISHED: | 1703 | case NES_CM_STATE_ESTABLISHED: |
@@ -1712,8 +1766,13 @@ static int handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1712 | dev_kfree_skb_any(skb); | 1766 | dev_kfree_skb_any(skb); |
1713 | break; | 1767 | break; |
1714 | case NES_CM_STATE_LISTENING: | 1768 | case NES_CM_STATE_LISTENING: |
1769 | cleanup_retrans_entry(cm_node); | ||
1770 | cm_node->state = NES_CM_STATE_CLOSED; | ||
1771 | send_reset(cm_node, skb); | ||
1772 | break; | ||
1715 | case NES_CM_STATE_CLOSED: | 1773 | case NES_CM_STATE_CLOSED: |
1716 | cleanup_retrans_entry(cm_node); | 1774 | cleanup_retrans_entry(cm_node); |
1775 | add_ref_cm_node(cm_node); | ||
1717 | send_reset(cm_node, skb); | 1776 | send_reset(cm_node, skb); |
1718 | break; | 1777 | break; |
1719 | case NES_CM_STATE_LAST_ACK: | 1778 | case NES_CM_STATE_LAST_ACK: |
@@ -1974,7 +2033,7 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, | |||
1974 | if (!cm_node) | 2033 | if (!cm_node) |
1975 | return NULL; | 2034 | return NULL; |
1976 | mpa_frame = &cm_node->mpa_frame; | 2035 | mpa_frame = &cm_node->mpa_frame; |
1977 | strcpy(mpa_frame->key, IEFT_MPA_KEY_REQ); | 2036 | memcpy(mpa_frame->key, IEFT_MPA_KEY_REQ, IETF_MPA_KEY_SIZE); |
1978 | mpa_frame->flags = IETF_MPA_FLAGS_CRC; | 2037 | mpa_frame->flags = IETF_MPA_FLAGS_CRC; |
1979 | mpa_frame->rev = IETF_MPA_VERSION; | 2038 | mpa_frame->rev = IETF_MPA_VERSION; |
1980 | mpa_frame->priv_data_len = htons(private_data_len); | 2039 | mpa_frame->priv_data_len = htons(private_data_len); |
@@ -2102,30 +2161,39 @@ static int mini_cm_reject(struct nes_cm_core *cm_core, | |||
2102 | cm_node->state = NES_CM_STATE_CLOSED; | 2161 | cm_node->state = NES_CM_STATE_CLOSED; |
2103 | rem_ref_cm_node(cm_core, cm_node); | 2162 | rem_ref_cm_node(cm_core, cm_node); |
2104 | } else { | 2163 | } else { |
2105 | ret = send_mpa_reject(cm_node); | 2164 | if (cm_node->state == NES_CM_STATE_LISTENER_DESTROYED) { |
2106 | if (ret) { | 2165 | rem_ref_cm_node(cm_core, cm_node); |
2107 | cm_node->state = NES_CM_STATE_CLOSED; | 2166 | } else { |
2108 | err = send_reset(cm_node, NULL); | 2167 | ret = send_mpa_reject(cm_node); |
2109 | if (err) | 2168 | if (ret) { |
2110 | WARN_ON(1); | 2169 | cm_node->state = NES_CM_STATE_CLOSED; |
2111 | } else | 2170 | err = send_reset(cm_node, NULL); |
2112 | cm_id->add_ref(cm_id); | 2171 | if (err) |
2172 | WARN_ON(1); | ||
2173 | } else | ||
2174 | cm_id->add_ref(cm_id); | ||
2175 | } | ||
2113 | } | 2176 | } |
2114 | } else { | 2177 | } else { |
2115 | cm_node->cm_id = NULL; | 2178 | cm_node->cm_id = NULL; |
2116 | event.cm_node = loopback; | 2179 | if (cm_node->state == NES_CM_STATE_LISTENER_DESTROYED) { |
2117 | event.cm_info.rem_addr = loopback->rem_addr; | 2180 | rem_ref_cm_node(cm_core, cm_node); |
2118 | event.cm_info.loc_addr = loopback->loc_addr; | 2181 | rem_ref_cm_node(cm_core, loopback); |
2119 | event.cm_info.rem_port = loopback->rem_port; | 2182 | } else { |
2120 | event.cm_info.loc_port = loopback->loc_port; | 2183 | event.cm_node = loopback; |
2121 | event.cm_info.cm_id = loopback->cm_id; | 2184 | event.cm_info.rem_addr = loopback->rem_addr; |
2122 | cm_event_mpa_reject(&event); | 2185 | event.cm_info.loc_addr = loopback->loc_addr; |
2123 | rem_ref_cm_node(cm_core, cm_node); | 2186 | event.cm_info.rem_port = loopback->rem_port; |
2124 | loopback->state = NES_CM_STATE_CLOSING; | 2187 | event.cm_info.loc_port = loopback->loc_port; |
2188 | event.cm_info.cm_id = loopback->cm_id; | ||
2189 | cm_event_mpa_reject(&event); | ||
2190 | rem_ref_cm_node(cm_core, cm_node); | ||
2191 | loopback->state = NES_CM_STATE_CLOSING; | ||
2125 | 2192 | ||
2126 | cm_id = loopback->cm_id; | 2193 | cm_id = loopback->cm_id; |
2127 | rem_ref_cm_node(cm_core, loopback); | 2194 | rem_ref_cm_node(cm_core, loopback); |
2128 | cm_id->rem_ref(cm_id); | 2195 | cm_id->rem_ref(cm_id); |
2196 | } | ||
2129 | } | 2197 | } |
2130 | 2198 | ||
2131 | return ret; | 2199 | return ret; |
@@ -2164,11 +2232,15 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod | |||
2164 | case NES_CM_STATE_CLOSING: | 2232 | case NES_CM_STATE_CLOSING: |
2165 | ret = -1; | 2233 | ret = -1; |
2166 | break; | 2234 | break; |
2167 | case NES_CM_STATE_MPAREJ_RCVD: | ||
2168 | case NES_CM_STATE_LISTENING: | 2235 | case NES_CM_STATE_LISTENING: |
2236 | cleanup_retrans_entry(cm_node); | ||
2237 | send_reset(cm_node, NULL); | ||
2238 | break; | ||
2239 | case NES_CM_STATE_MPAREJ_RCVD: | ||
2169 | case NES_CM_STATE_UNKNOWN: | 2240 | case NES_CM_STATE_UNKNOWN: |
2170 | case NES_CM_STATE_INITED: | 2241 | case NES_CM_STATE_INITED: |
2171 | case NES_CM_STATE_CLOSED: | 2242 | case NES_CM_STATE_CLOSED: |
2243 | case NES_CM_STATE_LISTENER_DESTROYED: | ||
2172 | ret = rem_ref_cm_node(cm_core, cm_node); | 2244 | ret = rem_ref_cm_node(cm_core, cm_node); |
2173 | break; | 2245 | break; |
2174 | case NES_CM_STATE_TSA: | 2246 | case NES_CM_STATE_TSA: |
@@ -2687,8 +2759,6 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2687 | struct nes_pd *nespd; | 2759 | struct nes_pd *nespd; |
2688 | u64 tagged_offset; | 2760 | u64 tagged_offset; |
2689 | 2761 | ||
2690 | |||
2691 | |||
2692 | ibqp = nes_get_qp(cm_id->device, conn_param->qpn); | 2762 | ibqp = nes_get_qp(cm_id->device, conn_param->qpn); |
2693 | if (!ibqp) | 2763 | if (!ibqp) |
2694 | return -EINVAL; | 2764 | return -EINVAL; |
@@ -2704,6 +2774,13 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2704 | "%s\n", cm_node, nesvnic, nesvnic->netdev, | 2774 | "%s\n", cm_node, nesvnic, nesvnic->netdev, |
2705 | nesvnic->netdev->name); | 2775 | nesvnic->netdev->name); |
2706 | 2776 | ||
2777 | if (NES_CM_STATE_LISTENER_DESTROYED == cm_node->state) { | ||
2778 | if (cm_node->loopbackpartner) | ||
2779 | rem_ref_cm_node(cm_node->cm_core, cm_node->loopbackpartner); | ||
2780 | rem_ref_cm_node(cm_node->cm_core, cm_node); | ||
2781 | return -EINVAL; | ||
2782 | } | ||
2783 | |||
2707 | /* associate the node with the QP */ | 2784 | /* associate the node with the QP */ |
2708 | nesqp->cm_node = (void *)cm_node; | 2785 | nesqp->cm_node = (void *)cm_node; |
2709 | cm_node->nesqp = nesqp; | 2786 | cm_node->nesqp = nesqp; |
@@ -2786,6 +2863,10 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2786 | cpu_to_le32(conn_param->private_data_len + | 2863 | cpu_to_le32(conn_param->private_data_len + |
2787 | sizeof(struct ietf_mpa_frame)); | 2864 | sizeof(struct ietf_mpa_frame)); |
2788 | wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = ibmr->lkey; | 2865 | wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = ibmr->lkey; |
2866 | if (nesqp->sq_kmapped) { | ||
2867 | nesqp->sq_kmapped = 0; | ||
2868 | kunmap(nesqp->page); | ||
2869 | } | ||
2789 | 2870 | ||
2790 | nesqp->nesqp_context->ird_ord_sizes |= | 2871 | nesqp->nesqp_context->ird_ord_sizes |= |
2791 | cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | | 2872 | cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | |
@@ -2929,7 +3010,7 @@ int nes_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len) | |||
2929 | if (cm_node->mpa_frame_size > MAX_CM_BUFFER) | 3010 | if (cm_node->mpa_frame_size > MAX_CM_BUFFER) |
2930 | return -EINVAL; | 3011 | return -EINVAL; |
2931 | 3012 | ||
2932 | strcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP); | 3013 | memcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE); |
2933 | if (loopback) { | 3014 | if (loopback) { |
2934 | memcpy(&loopback->mpa_frame.priv_data, pdata, pdata_len); | 3015 | memcpy(&loopback->mpa_frame.priv_data, pdata, pdata_len); |
2935 | loopback->mpa_frame.priv_data_len = pdata_len; | 3016 | loopback->mpa_frame.priv_data_len = pdata_len; |
@@ -2974,6 +3055,9 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2974 | if (!nesdev) | 3055 | if (!nesdev) |
2975 | return -EINVAL; | 3056 | return -EINVAL; |
2976 | 3057 | ||
3058 | if (!(cm_id->local_addr.sin_port) || !(cm_id->remote_addr.sin_port)) | ||
3059 | return -EINVAL; | ||
3060 | |||
2977 | nes_debug(NES_DBG_CM, "QP%u, current IP = 0x%08X, Destination IP = " | 3061 | nes_debug(NES_DBG_CM, "QP%u, current IP = 0x%08X, Destination IP = " |
2978 | "0x%08X:0x%04X, local = 0x%08X:0x%04X.\n", nesqp->hwqp.qp_id, | 3062 | "0x%08X:0x%04X, local = 0x%08X:0x%04X.\n", nesqp->hwqp.qp_id, |
2979 | ntohl(nesvnic->local_ipaddr), | 3063 | ntohl(nesvnic->local_ipaddr), |
@@ -3090,7 +3174,7 @@ int nes_create_listen(struct iw_cm_id *cm_id, int backlog) | |||
3090 | g_cm_core->api->stop_listener(g_cm_core, (void *)cm_node); | 3174 | g_cm_core->api->stop_listener(g_cm_core, (void *)cm_node); |
3091 | return err; | 3175 | return err; |
3092 | } | 3176 | } |
3093 | cm_listens_created++; | 3177 | atomic_inc(&cm_listens_created); |
3094 | } | 3178 | } |
3095 | 3179 | ||
3096 | cm_id->add_ref(cm_id); | 3180 | cm_id->add_ref(cm_id); |
@@ -3251,6 +3335,11 @@ static void cm_event_connected(struct nes_cm_event *event) | |||
3251 | wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0; | 3335 | wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0; |
3252 | wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0; | 3336 | wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0; |
3253 | 3337 | ||
3338 | if (nesqp->sq_kmapped) { | ||
3339 | nesqp->sq_kmapped = 0; | ||
3340 | kunmap(nesqp->page); | ||
3341 | } | ||
3342 | |||
3254 | /* use the reserved spot on the WQ for the extra first WQE */ | 3343 | /* use the reserved spot on the WQ for the extra first WQE */ |
3255 | nesqp->nesqp_context->ird_ord_sizes &= | 3344 | nesqp->nesqp_context->ird_ord_sizes &= |
3256 | cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | | 3345 | cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | |
@@ -3346,7 +3435,7 @@ static void cm_event_connect_error(struct nes_cm_event *event) | |||
3346 | nesqp->cm_id = NULL; | 3435 | nesqp->cm_id = NULL; |
3347 | cm_id->provider_data = NULL; | 3436 | cm_id->provider_data = NULL; |
3348 | cm_event.event = IW_CM_EVENT_CONNECT_REPLY; | 3437 | cm_event.event = IW_CM_EVENT_CONNECT_REPLY; |
3349 | cm_event.status = IW_CM_EVENT_STATUS_REJECTED; | 3438 | cm_event.status = -ECONNRESET; |
3350 | cm_event.provider_data = cm_id->provider_data; | 3439 | cm_event.provider_data = cm_id->provider_data; |
3351 | cm_event.local_addr = cm_id->local_addr; | 3440 | cm_event.local_addr = cm_id->local_addr; |
3352 | cm_event.remote_addr = cm_id->remote_addr; | 3441 | cm_event.remote_addr = cm_id->remote_addr; |
@@ -3390,6 +3479,8 @@ static void cm_event_reset(struct nes_cm_event *event) | |||
3390 | 3479 | ||
3391 | nes_debug(NES_DBG_CM, "%p - cm_id = %p\n", event->cm_node, cm_id); | 3480 | nes_debug(NES_DBG_CM, "%p - cm_id = %p\n", event->cm_node, cm_id); |
3392 | nesqp = cm_id->provider_data; | 3481 | nesqp = cm_id->provider_data; |
3482 | if (!nesqp) | ||
3483 | return; | ||
3393 | 3484 | ||
3394 | nesqp->cm_id = NULL; | 3485 | nesqp->cm_id = NULL; |
3395 | /* cm_id->provider_data = NULL; */ | 3486 | /* cm_id->provider_data = NULL; */ |
@@ -3401,8 +3492,8 @@ static void cm_event_reset(struct nes_cm_event *event) | |||
3401 | cm_event.private_data = NULL; | 3492 | cm_event.private_data = NULL; |
3402 | cm_event.private_data_len = 0; | 3493 | cm_event.private_data_len = 0; |
3403 | 3494 | ||
3404 | ret = cm_id->event_handler(cm_id, &cm_event); | ||
3405 | cm_id->add_ref(cm_id); | 3495 | cm_id->add_ref(cm_id); |
3496 | ret = cm_id->event_handler(cm_id, &cm_event); | ||
3406 | atomic_inc(&cm_closes); | 3497 | atomic_inc(&cm_closes); |
3407 | cm_event.event = IW_CM_EVENT_CLOSE; | 3498 | cm_event.event = IW_CM_EVENT_CLOSE; |
3408 | cm_event.status = IW_CM_EVENT_STATUS_OK; | 3499 | cm_event.status = IW_CM_EVENT_STATUS_OK; |
diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h index 90e8e4d8a5ce..d9825fda70a1 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 - 2009 Intel-NE, Inc. All rights reserved. | 2 | * Copyright (c) 2006 - 2009 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 |
@@ -47,6 +47,8 @@ | |||
47 | #define IEFT_MPA_KEY_REP "MPA ID Rep Frame" | 47 | #define IEFT_MPA_KEY_REP "MPA ID Rep Frame" |
48 | #define IETF_MPA_KEY_SIZE 16 | 48 | #define IETF_MPA_KEY_SIZE 16 |
49 | #define IETF_MPA_VERSION 1 | 49 | #define IETF_MPA_VERSION 1 |
50 | #define IETF_MAX_PRIV_DATA_LEN 512 | ||
51 | #define IETF_MPA_FRAME_SIZE 20 | ||
50 | 52 | ||
51 | enum ietf_mpa_flags { | 53 | enum ietf_mpa_flags { |
52 | IETF_MPA_FLAGS_MARKERS = 0x80, /* receive Markers */ | 54 | IETF_MPA_FLAGS_MARKERS = 0x80, /* receive Markers */ |
@@ -169,7 +171,7 @@ struct nes_timer_entry { | |||
169 | 171 | ||
170 | #define NES_CM_DEF_SEQ2 0x18ed5740 | 172 | #define NES_CM_DEF_SEQ2 0x18ed5740 |
171 | #define NES_CM_DEF_LOCAL_ID2 0xb807 | 173 | #define NES_CM_DEF_LOCAL_ID2 0xb807 |
172 | #define MAX_CM_BUFFER 512 | 174 | #define MAX_CM_BUFFER (IETF_MPA_FRAME_SIZE + IETF_MAX_PRIV_DATA_LEN) |
173 | 175 | ||
174 | 176 | ||
175 | typedef u32 nes_addr_t; | 177 | typedef u32 nes_addr_t; |
@@ -198,6 +200,7 @@ enum nes_cm_node_state { | |||
198 | NES_CM_STATE_TIME_WAIT, | 200 | NES_CM_STATE_TIME_WAIT, |
199 | NES_CM_STATE_LAST_ACK, | 201 | NES_CM_STATE_LAST_ACK, |
200 | NES_CM_STATE_CLOSING, | 202 | NES_CM_STATE_CLOSING, |
203 | NES_CM_STATE_LISTENER_DESTROYED, | ||
201 | NES_CM_STATE_CLOSED | 204 | NES_CM_STATE_CLOSED |
202 | }; | 205 | }; |
203 | 206 | ||
diff --git a/drivers/infiniband/hw/nes/nes_context.h b/drivers/infiniband/hw/nes/nes_context.h index 0fb8d81d9a62..b4393a16099d 100644 --- a/drivers/infiniband/hw/nes/nes_context.h +++ b/drivers/infiniband/hw/nes/nes_context.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. | 2 | * Copyright (c) 2006 - 2009 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 |
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 3512d6de3019..c36a3f514929 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. | 2 | * Copyright (c) 2006 - 2009 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 |
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/tcp.h> | 39 | #include <linux/tcp.h> |
40 | #include <linux/if_vlan.h> | 40 | #include <linux/if_vlan.h> |
41 | #include <linux/inet_lro.h> | 41 | #include <linux/inet_lro.h> |
42 | #include <linux/slab.h> | ||
42 | 43 | ||
43 | #include "nes.h" | 44 | #include "nes.h" |
44 | 45 | ||
@@ -424,8 +425,9 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { | |||
424 | 425 | ||
425 | nesadapter->base_pd = 1; | 426 | nesadapter->base_pd = 1; |
426 | 427 | ||
427 | nesadapter->device_cap_flags = | 428 | nesadapter->device_cap_flags = IB_DEVICE_LOCAL_DMA_LKEY | |
428 | IB_DEVICE_LOCAL_DMA_LKEY | IB_DEVICE_MEM_WINDOW; | 429 | IB_DEVICE_MEM_WINDOW | |
430 | IB_DEVICE_MEM_MGT_EXTENSIONS; | ||
429 | 431 | ||
430 | nesadapter->allocated_qps = (unsigned long *)&(((unsigned char *)nesadapter) | 432 | nesadapter->allocated_qps = (unsigned long *)&(((unsigned char *)nesadapter) |
431 | [(sizeof(struct nes_adapter)+(sizeof(unsigned long)-1))&(~(sizeof(unsigned long)-1))]); | 433 | [(sizeof(struct nes_adapter)+(sizeof(unsigned long)-1))&(~(sizeof(unsigned long)-1))]); |
@@ -436,11 +438,12 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { | |||
436 | nesadapter->qp_table = (struct nes_qp **)(&nesadapter->allocated_arps[BITS_TO_LONGS(arp_table_size)]); | 438 | nesadapter->qp_table = (struct nes_qp **)(&nesadapter->allocated_arps[BITS_TO_LONGS(arp_table_size)]); |
437 | 439 | ||
438 | 440 | ||
439 | /* mark the usual suspect QPs and CQs as in use */ | 441 | /* mark the usual suspect QPs, MR and CQs as in use */ |
440 | for (u32temp = 0; u32temp < NES_FIRST_QPN; u32temp++) { | 442 | for (u32temp = 0; u32temp < NES_FIRST_QPN; u32temp++) { |
441 | set_bit(u32temp, nesadapter->allocated_qps); | 443 | set_bit(u32temp, nesadapter->allocated_qps); |
442 | set_bit(u32temp, nesadapter->allocated_cqs); | 444 | set_bit(u32temp, nesadapter->allocated_cqs); |
443 | } | 445 | } |
446 | set_bit(0, nesadapter->allocated_mrs); | ||
444 | 447 | ||
445 | for (u32temp = 0; u32temp < 20; u32temp++) | 448 | for (u32temp = 0; u32temp < 20; u32temp++) |
446 | set_bit(u32temp, nesadapter->allocated_pds); | 449 | set_bit(u32temp, nesadapter->allocated_pds); |
@@ -481,7 +484,7 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { | |||
481 | nesadapter->max_irrq_wr = (u32temp >> 16) & 3; | 484 | nesadapter->max_irrq_wr = (u32temp >> 16) & 3; |
482 | 485 | ||
483 | nesadapter->max_sge = 4; | 486 | nesadapter->max_sge = 4; |
484 | nesadapter->max_cqe = 32767; | 487 | nesadapter->max_cqe = 32766; |
485 | 488 | ||
486 | if (nes_read_eeprom_values(nesdev, nesadapter)) { | 489 | if (nes_read_eeprom_values(nesdev, nesadapter)) { |
487 | printk(KERN_ERR PFX "Unable to read EEPROM data.\n"); | 490 | printk(KERN_ERR PFX "Unable to read EEPROM data.\n"); |
@@ -746,16 +749,28 @@ static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count, | |||
746 | 749 | ||
747 | if (hw_rev != NE020_REV) { | 750 | if (hw_rev != NE020_REV) { |
748 | /* init serdes 0 */ | 751 | /* init serdes 0 */ |
749 | if (wide_ppm_offset && (nesadapter->phy_type[0] == NES_PHY_TYPE_CX4)) | 752 | switch (nesadapter->phy_type[0]) { |
750 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000FFFAA); | 753 | case NES_PHY_TYPE_CX4: |
751 | else | 754 | if (wide_ppm_offset) |
755 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000FFFAA); | ||
756 | else | ||
757 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); | ||
758 | break; | ||
759 | case NES_PHY_TYPE_KR: | ||
760 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); | ||
761 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP0, 0x00000000); | ||
762 | break; | ||
763 | case NES_PHY_TYPE_PUMA_1G: | ||
752 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); | 764 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); |
753 | |||
754 | if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) { | ||
755 | sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0); | 765 | sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0); |
756 | sds |= 0x00000100; | 766 | sds |= 0x00000100; |
757 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds); | 767 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds); |
768 | break; | ||
769 | default: | ||
770 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); | ||
771 | break; | ||
758 | } | 772 | } |
773 | |||
759 | if (!OneG_Mode) | 774 | if (!OneG_Mode) |
760 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000); | 775 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000); |
761 | 776 | ||
@@ -776,6 +791,9 @@ static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count, | |||
776 | if (wide_ppm_offset) | 791 | if (wide_ppm_offset) |
777 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000FFFAA); | 792 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000FFFAA); |
778 | break; | 793 | break; |
794 | case NES_PHY_TYPE_KR: | ||
795 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP1, 0x00000000); | ||
796 | break; | ||
779 | case NES_PHY_TYPE_PUMA_1G: | 797 | case NES_PHY_TYPE_PUMA_1G: |
780 | sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1); | 798 | sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1); |
781 | sds |= 0x000000100; | 799 | sds |= 0x000000100; |
@@ -1277,108 +1295,115 @@ int nes_destroy_cqp(struct nes_device *nesdev) | |||
1277 | 1295 | ||
1278 | 1296 | ||
1279 | /** | 1297 | /** |
1280 | * nes_init_phy | 1298 | * nes_init_1g_phy |
1281 | */ | 1299 | */ |
1282 | int nes_init_phy(struct nes_device *nesdev) | 1300 | int nes_init_1g_phy(struct nes_device *nesdev, u8 phy_type, u8 phy_index) |
1283 | { | 1301 | { |
1284 | struct nes_adapter *nesadapter = nesdev->nesadapter; | ||
1285 | u32 counter = 0; | 1302 | u32 counter = 0; |
1286 | u32 sds; | ||
1287 | u32 mac_index = nesdev->mac_index; | ||
1288 | u32 tx_config = 0; | ||
1289 | u16 phy_data; | 1303 | u16 phy_data; |
1290 | u32 temp_phy_data = 0; | 1304 | int ret = 0; |
1291 | u32 temp_phy_data2 = 0; | ||
1292 | u8 phy_type = nesadapter->phy_type[mac_index]; | ||
1293 | u8 phy_index = nesadapter->phy_index[mac_index]; | ||
1294 | |||
1295 | if ((nesadapter->OneG_Mode) && | ||
1296 | (phy_type != NES_PHY_TYPE_PUMA_1G)) { | ||
1297 | nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index); | ||
1298 | if (phy_type == NES_PHY_TYPE_1G) { | ||
1299 | tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); | ||
1300 | tx_config &= 0xFFFFFFE3; | ||
1301 | tx_config |= 0x04; | ||
1302 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); | ||
1303 | } | ||
1304 | 1305 | ||
1305 | nes_read_1G_phy_reg(nesdev, 1, phy_index, &phy_data); | 1306 | nes_read_1G_phy_reg(nesdev, 1, phy_index, &phy_data); |
1306 | nes_write_1G_phy_reg(nesdev, 23, phy_index, 0xb000); | 1307 | nes_write_1G_phy_reg(nesdev, 23, phy_index, 0xb000); |
1307 | 1308 | ||
1308 | /* Reset the PHY */ | 1309 | /* Reset the PHY */ |
1309 | nes_write_1G_phy_reg(nesdev, 0, phy_index, 0x8000); | 1310 | nes_write_1G_phy_reg(nesdev, 0, phy_index, 0x8000); |
1310 | udelay(100); | 1311 | udelay(100); |
1311 | counter = 0; | 1312 | counter = 0; |
1312 | do { | 1313 | do { |
1313 | nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); | ||
1314 | if (counter++ > 100) | ||
1315 | break; | ||
1316 | } while (phy_data & 0x8000); | ||
1317 | |||
1318 | /* Setting no phy loopback */ | ||
1319 | phy_data &= 0xbfff; | ||
1320 | phy_data |= 0x1140; | ||
1321 | nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data); | ||
1322 | nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); | 1314 | nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); |
1323 | nes_read_1G_phy_reg(nesdev, 0x17, phy_index, &phy_data); | 1315 | if (counter++ > 100) { |
1324 | nes_read_1G_phy_reg(nesdev, 0x1e, phy_index, &phy_data); | 1316 | ret = -1; |
1325 | 1317 | break; | |
1326 | /* Setting the interrupt mask */ | 1318 | } |
1327 | nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data); | 1319 | } while (phy_data & 0x8000); |
1328 | nes_write_1G_phy_reg(nesdev, 0x19, phy_index, 0xffee); | 1320 | |
1329 | nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data); | 1321 | /* Setting no phy loopback */ |
1322 | phy_data &= 0xbfff; | ||
1323 | phy_data |= 0x1140; | ||
1324 | nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data); | ||
1325 | nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); | ||
1326 | nes_read_1G_phy_reg(nesdev, 0x17, phy_index, &phy_data); | ||
1327 | nes_read_1G_phy_reg(nesdev, 0x1e, phy_index, &phy_data); | ||
1328 | |||
1329 | /* Setting the interrupt mask */ | ||
1330 | nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data); | ||
1331 | nes_write_1G_phy_reg(nesdev, 0x19, phy_index, 0xffee); | ||
1332 | nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data); | ||
1333 | |||
1334 | /* turning on flow control */ | ||
1335 | nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data); | ||
1336 | nes_write_1G_phy_reg(nesdev, 4, phy_index, (phy_data & ~(0x03E0)) | 0xc00); | ||
1337 | nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data); | ||
1338 | |||
1339 | /* Clear Half duplex */ | ||
1340 | nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data); | ||
1341 | nes_write_1G_phy_reg(nesdev, 9, phy_index, phy_data & ~(0x0100)); | ||
1342 | nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data); | ||
1343 | |||
1344 | nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); | ||
1345 | nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data | 0x0300); | ||
1346 | |||
1347 | return ret; | ||
1348 | } | ||
1330 | 1349 | ||
1331 | /* turning on flow control */ | ||
1332 | nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data); | ||
1333 | nes_write_1G_phy_reg(nesdev, 4, phy_index, (phy_data & ~(0x03E0)) | 0xc00); | ||
1334 | nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data); | ||
1335 | 1350 | ||
1336 | /* Clear Half duplex */ | 1351 | /** |
1337 | nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data); | 1352 | * nes_init_2025_phy |
1338 | nes_write_1G_phy_reg(nesdev, 9, phy_index, phy_data & ~(0x0100)); | 1353 | */ |
1339 | nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data); | 1354 | int nes_init_2025_phy(struct nes_device *nesdev, u8 phy_type, u8 phy_index) |
1355 | { | ||
1356 | u32 temp_phy_data = 0; | ||
1357 | u32 temp_phy_data2 = 0; | ||
1358 | u32 counter = 0; | ||
1359 | u32 sds; | ||
1360 | u32 mac_index = nesdev->mac_index; | ||
1361 | int ret = 0; | ||
1362 | unsigned int first_attempt = 1; | ||
1340 | 1363 | ||
1341 | nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); | 1364 | /* Check firmware heartbeat */ |
1342 | nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data | 0x0300); | 1365 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); |
1366 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1367 | udelay(1500); | ||
1368 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); | ||
1369 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1343 | 1370 | ||
1344 | return 0; | 1371 | if (temp_phy_data != temp_phy_data2) { |
1372 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd); | ||
1373 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1374 | if ((temp_phy_data & 0xff) > 0x20) | ||
1375 | return 0; | ||
1376 | printk(PFX "Reinitialize external PHY\n"); | ||
1345 | } | 1377 | } |
1346 | 1378 | ||
1347 | if ((phy_type == NES_PHY_TYPE_IRIS) || | 1379 | /* no heartbeat, configure the PHY */ |
1348 | (phy_type == NES_PHY_TYPE_ARGUS) || | 1380 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000); |
1349 | (phy_type == NES_PHY_TYPE_SFP_D)) { | 1381 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0000); |
1350 | /* setup 10G MDIO operation */ | 1382 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A); |
1351 | tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); | 1383 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052); |
1352 | tx_config &= 0xFFFFFFE3; | ||
1353 | tx_config |= 0x15; | ||
1354 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); | ||
1355 | } | ||
1356 | if ((phy_type == NES_PHY_TYPE_ARGUS) || | ||
1357 | (phy_type == NES_PHY_TYPE_SFP_D)) { | ||
1358 | /* Check firmware heartbeat */ | ||
1359 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); | ||
1360 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1361 | udelay(1500); | ||
1362 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); | ||
1363 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1364 | 1384 | ||
1365 | if (temp_phy_data != temp_phy_data2) | 1385 | switch (phy_type) { |
1366 | return 0; | 1386 | case NES_PHY_TYPE_ARGUS: |
1387 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A); | ||
1388 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052); | ||
1389 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x000C); | ||
1390 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0008); | ||
1391 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0001); | ||
1392 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc31a, 0x0098); | ||
1393 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0026, 0x0E00); | ||
1367 | 1394 | ||
1368 | /* no heartbeat, configure the PHY */ | 1395 | /* setup LEDs */ |
1369 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000); | 1396 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd006, 0x0007); |
1370 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0000); | 1397 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd007, 0x000A); |
1398 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd008, 0x0009); | ||
1399 | break; | ||
1400 | |||
1401 | case NES_PHY_TYPE_SFP_D: | ||
1371 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A); | 1402 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A); |
1372 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052); | 1403 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052); |
1373 | if (phy_type == NES_PHY_TYPE_ARGUS) { | 1404 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x0004); |
1374 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x000C); | 1405 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0038); |
1375 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0008); | 1406 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0013); |
1376 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0001); | ||
1377 | } else { | ||
1378 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x0004); | ||
1379 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0038); | ||
1380 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0013); | ||
1381 | } | ||
1382 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc31a, 0x0098); | 1407 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc31a, 0x0098); |
1383 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0026, 0x0E00); | 1408 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0026, 0x0E00); |
1384 | 1409 | ||
@@ -1386,62 +1411,136 @@ int nes_init_phy(struct nes_device *nesdev) | |||
1386 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd006, 0x0007); | 1411 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd006, 0x0007); |
1387 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd007, 0x000A); | 1412 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd007, 0x000A); |
1388 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd008, 0x0009); | 1413 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd008, 0x0009); |
1414 | break; | ||
1389 | 1415 | ||
1390 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0028, 0xA528); | 1416 | case NES_PHY_TYPE_KR: |
1417 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A); | ||
1418 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052); | ||
1419 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x000C); | ||
1420 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0010); | ||
1421 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0013); | ||
1422 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc31a, 0x0080); | ||
1423 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0026, 0x0E00); | ||
1424 | |||
1425 | /* setup LEDs */ | ||
1426 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd006, 0x000B); | ||
1427 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd007, 0x0003); | ||
1428 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd008, 0x0004); | ||
1429 | |||
1430 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0022, 0x406D); | ||
1431 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0023, 0x0020); | ||
1432 | break; | ||
1433 | } | ||
1434 | |||
1435 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0028, 0xA528); | ||
1391 | 1436 | ||
1392 | /* Bring PHY out of reset */ | 1437 | /* Bring PHY out of reset */ |
1393 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0002); | 1438 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0002); |
1394 | 1439 | ||
1395 | /* Check for heartbeat */ | 1440 | /* Check for heartbeat */ |
1396 | counter = 0; | 1441 | counter = 0; |
1397 | mdelay(690); | 1442 | mdelay(690); |
1443 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); | ||
1444 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1445 | do { | ||
1446 | if (counter++ > 150) { | ||
1447 | printk(PFX "No PHY heartbeat\n"); | ||
1448 | break; | ||
1449 | } | ||
1450 | mdelay(1); | ||
1398 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); | 1451 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); |
1452 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1453 | } while ((temp_phy_data2 == temp_phy_data)); | ||
1454 | |||
1455 | /* wait for tracking */ | ||
1456 | counter = 0; | ||
1457 | do { | ||
1458 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd); | ||
1399 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | 1459 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); |
1400 | do { | 1460 | if (counter++ > 300) { |
1401 | if (counter++ > 150) { | 1461 | if (((temp_phy_data & 0xff) == 0x0) && first_attempt) { |
1402 | nes_debug(NES_DBG_PHY, "No PHY heartbeat\n"); | 1462 | first_attempt = 0; |
1403 | break; | 1463 | counter = 0; |
1404 | } | 1464 | /* reset AMCC PHY and try again */ |
1405 | mdelay(1); | 1465 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x00c0); |
1406 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); | 1466 | nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x0040); |
1407 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | 1467 | continue; |
1408 | } while ((temp_phy_data2 == temp_phy_data)); | 1468 | } else { |
1409 | 1469 | ret = 1; | |
1410 | /* wait for tracking */ | ||
1411 | counter = 0; | ||
1412 | do { | ||
1413 | nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd); | ||
1414 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1415 | if (counter++ > 300) { | ||
1416 | nes_debug(NES_DBG_PHY, "PHY did not track\n"); | ||
1417 | break; | 1470 | break; |
1418 | } | 1471 | } |
1419 | mdelay(10); | 1472 | } |
1420 | } while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70)); | 1473 | mdelay(10); |
1421 | 1474 | } while ((temp_phy_data & 0xff) < 0x30); | |
1422 | /* setup signal integrity */ | 1475 | |
1423 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000); | 1476 | /* setup signal integrity */ |
1424 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00D, 0x00FE); | 1477 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000); |
1425 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00E, 0x0032); | 1478 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00D, 0x00FE); |
1479 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00E, 0x0032); | ||
1480 | if (phy_type == NES_PHY_TYPE_KR) { | ||
1481 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00F, 0x000C); | ||
1482 | } else { | ||
1426 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00F, 0x0002); | 1483 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00F, 0x0002); |
1427 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc314, 0x0063); | 1484 | nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc314, 0x0063); |
1485 | } | ||
1486 | |||
1487 | /* reset serdes */ | ||
1488 | sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + mac_index * 0x200); | ||
1489 | sds |= 0x1; | ||
1490 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + mac_index * 0x200, sds); | ||
1491 | sds &= 0xfffffffe; | ||
1492 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + mac_index * 0x200, sds); | ||
1493 | |||
1494 | counter = 0; | ||
1495 | while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040) | ||
1496 | && (counter++ < 5000)) | ||
1497 | ; | ||
1498 | |||
1499 | return ret; | ||
1500 | } | ||
1501 | |||
1502 | |||
1503 | /** | ||
1504 | * nes_init_phy | ||
1505 | */ | ||
1506 | int nes_init_phy(struct nes_device *nesdev) | ||
1507 | { | ||
1508 | struct nes_adapter *nesadapter = nesdev->nesadapter; | ||
1509 | u32 mac_index = nesdev->mac_index; | ||
1510 | u32 tx_config = 0; | ||
1511 | unsigned long flags; | ||
1512 | u8 phy_type = nesadapter->phy_type[mac_index]; | ||
1513 | u8 phy_index = nesadapter->phy_index[mac_index]; | ||
1514 | int ret = 0; | ||
1428 | 1515 | ||
1429 | /* reset serdes */ | 1516 | tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); |
1430 | sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + | 1517 | if (phy_type == NES_PHY_TYPE_1G) { |
1431 | mac_index * 0x200); | 1518 | /* setup 1G MDIO operation */ |
1432 | sds |= 0x1; | 1519 | tx_config &= 0xFFFFFFE3; |
1433 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + | 1520 | tx_config |= 0x04; |
1434 | mac_index * 0x200, sds); | 1521 | } else { |
1435 | sds &= 0xfffffffe; | 1522 | /* setup 10G MDIO operation */ |
1436 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + | 1523 | tx_config &= 0xFFFFFFE3; |
1437 | mac_index * 0x200, sds); | 1524 | tx_config |= 0x15; |
1438 | |||
1439 | counter = 0; | ||
1440 | while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040) | ||
1441 | && (counter++ < 5000)) | ||
1442 | ; | ||
1443 | } | 1525 | } |
1444 | return 0; | 1526 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); |
1527 | |||
1528 | spin_lock_irqsave(&nesdev->nesadapter->phy_lock, flags); | ||
1529 | |||
1530 | switch (phy_type) { | ||
1531 | case NES_PHY_TYPE_1G: | ||
1532 | ret = nes_init_1g_phy(nesdev, phy_type, phy_index); | ||
1533 | break; | ||
1534 | case NES_PHY_TYPE_ARGUS: | ||
1535 | case NES_PHY_TYPE_SFP_D: | ||
1536 | case NES_PHY_TYPE_KR: | ||
1537 | ret = nes_init_2025_phy(nesdev, phy_type, phy_index); | ||
1538 | break; | ||
1539 | } | ||
1540 | |||
1541 | spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags); | ||
1542 | |||
1543 | return ret; | ||
1445 | } | 1544 | } |
1446 | 1545 | ||
1447 | 1546 | ||
@@ -1801,9 +1900,14 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic) | |||
1801 | u16 wqe_fragment_index; | 1900 | u16 wqe_fragment_index; |
1802 | u64 wqe_frag; | 1901 | u64 wqe_frag; |
1803 | u32 cqp_head; | 1902 | u32 cqp_head; |
1903 | u32 wqm_cfg0; | ||
1804 | unsigned long flags; | 1904 | unsigned long flags; |
1805 | int ret; | 1905 | int ret; |
1806 | 1906 | ||
1907 | /* clear wqe stall before destroying NIC QP */ | ||
1908 | wqm_cfg0 = nes_read_indexed(nesdev, NES_IDX_WQM_CONFIG0); | ||
1909 | nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG0, wqm_cfg0 & 0xFFFF7FFF); | ||
1910 | |||
1807 | /* Free remaining NIC receive buffers */ | 1911 | /* Free remaining NIC receive buffers */ |
1808 | while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) { | 1912 | while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) { |
1809 | nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail]; | 1913 | nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail]; |
@@ -1922,6 +2026,9 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic) | |||
1922 | 2026 | ||
1923 | pci_free_consistent(nesdev->pcidev, nesvnic->nic_mem_size, nesvnic->nic_vbase, | 2027 | pci_free_consistent(nesdev->pcidev, nesvnic->nic_mem_size, nesvnic->nic_vbase, |
1924 | nesvnic->nic_pbase); | 2028 | nesvnic->nic_pbase); |
2029 | |||
2030 | /* restore old wqm_cfg0 value */ | ||
2031 | nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG0, wqm_cfg0); | ||
1925 | } | 2032 | } |
1926 | 2033 | ||
1927 | /** | 2034 | /** |
@@ -2442,23 +2549,9 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2442 | } | 2549 | } |
2443 | } else { | 2550 | } else { |
2444 | switch (nesadapter->phy_type[mac_index]) { | 2551 | switch (nesadapter->phy_type[mac_index]) { |
2445 | case NES_PHY_TYPE_IRIS: | ||
2446 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||
2447 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
2448 | u32temp = 20; | ||
2449 | do { | ||
2450 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||
2451 | phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
2452 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | ||
2453 | break; | ||
2454 | temp_phy_data = phy_data; | ||
2455 | } while (1); | ||
2456 | nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", | ||
2457 | __func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP"); | ||
2458 | break; | ||
2459 | |||
2460 | case NES_PHY_TYPE_ARGUS: | 2552 | case NES_PHY_TYPE_ARGUS: |
2461 | case NES_PHY_TYPE_SFP_D: | 2553 | case NES_PHY_TYPE_SFP_D: |
2554 | case NES_PHY_TYPE_KR: | ||
2462 | /* clear the alarms */ | 2555 | /* clear the alarms */ |
2463 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008); | 2556 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008); |
2464 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001); | 2557 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001); |
@@ -3334,8 +3427,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, | |||
3334 | u16 async_event_id; | 3427 | u16 async_event_id; |
3335 | u8 tcp_state; | 3428 | u8 tcp_state; |
3336 | u8 iwarp_state; | 3429 | u8 iwarp_state; |
3337 | int must_disconn = 1; | ||
3338 | int must_terminate = 0; | ||
3339 | struct ib_event ibevent; | 3430 | struct ib_event ibevent; |
3340 | 3431 | ||
3341 | nes_debug(NES_DBG_AEQ, "\n"); | 3432 | nes_debug(NES_DBG_AEQ, "\n"); |
@@ -3349,6 +3440,8 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, | |||
3349 | BUG_ON(!context); | 3440 | BUG_ON(!context); |
3350 | } | 3441 | } |
3351 | 3442 | ||
3443 | /* context is nesqp unless async_event_id == CQ ERROR */ | ||
3444 | nesqp = (struct nes_qp *)(unsigned long)context; | ||
3352 | async_event_id = (u16)aeq_info; | 3445 | async_event_id = (u16)aeq_info; |
3353 | tcp_state = (aeq_info & NES_AEQE_TCP_STATE_MASK) >> NES_AEQE_TCP_STATE_SHIFT; | 3446 | tcp_state = (aeq_info & NES_AEQE_TCP_STATE_MASK) >> NES_AEQE_TCP_STATE_SHIFT; |
3354 | iwarp_state = (aeq_info & NES_AEQE_IWARP_STATE_MASK) >> NES_AEQE_IWARP_STATE_SHIFT; | 3447 | iwarp_state = (aeq_info & NES_AEQE_IWARP_STATE_MASK) >> NES_AEQE_IWARP_STATE_SHIFT; |
@@ -3360,8 +3453,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, | |||
3360 | 3453 | ||
3361 | switch (async_event_id) { | 3454 | switch (async_event_id) { |
3362 | case NES_AEQE_AEID_LLP_FIN_RECEIVED: | 3455 | case NES_AEQE_AEID_LLP_FIN_RECEIVED: |
3363 | nesqp = (struct nes_qp *)(unsigned long)context; | ||
3364 | |||
3365 | if (nesqp->term_flags) | 3456 | if (nesqp->term_flags) |
3366 | return; /* Ignore it, wait for close complete */ | 3457 | return; /* Ignore it, wait for close complete */ |
3367 | 3458 | ||
@@ -3376,79 +3467,48 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, | |||
3376 | async_event_id, nesqp->last_aeq, tcp_state); | 3467 | async_event_id, nesqp->last_aeq, tcp_state); |
3377 | } | 3468 | } |
3378 | 3469 | ||
3379 | if ((tcp_state != NES_AEQE_TCP_STATE_CLOSE_WAIT) || | 3470 | break; |
3380 | (nesqp->ibqp_state != IB_QPS_RTS)) { | ||
3381 | /* FIN Received but tcp state or IB state moved on, | ||
3382 | should expect a close complete */ | ||
3383 | return; | ||
3384 | } | ||
3385 | |||
3386 | case NES_AEQE_AEID_LLP_CLOSE_COMPLETE: | 3471 | case NES_AEQE_AEID_LLP_CLOSE_COMPLETE: |
3387 | nesqp = (struct nes_qp *)(unsigned long)context; | ||
3388 | if (nesqp->term_flags) { | 3472 | if (nesqp->term_flags) { |
3389 | nes_terminate_done(nesqp, 0); | 3473 | nes_terminate_done(nesqp, 0); |
3390 | return; | 3474 | return; |
3391 | } | 3475 | } |
3476 | spin_lock_irqsave(&nesqp->lock, flags); | ||
3477 | nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING; | ||
3478 | spin_unlock_irqrestore(&nesqp->lock, flags); | ||
3479 | nes_hw_modify_qp(nesdev, nesqp, NES_CQP_QP_IWARP_STATE_CLOSING, 0, 0); | ||
3480 | nes_cm_disconn(nesqp); | ||
3481 | break; | ||
3392 | 3482 | ||
3393 | case NES_AEQE_AEID_LLP_CONNECTION_RESET: | ||
3394 | case NES_AEQE_AEID_RESET_SENT: | 3483 | case NES_AEQE_AEID_RESET_SENT: |
3395 | nesqp = (struct nes_qp *)(unsigned long)context; | 3484 | tcp_state = NES_AEQE_TCP_STATE_CLOSED; |
3396 | if (async_event_id == NES_AEQE_AEID_RESET_SENT) { | ||
3397 | tcp_state = NES_AEQE_TCP_STATE_CLOSED; | ||
3398 | } | ||
3399 | spin_lock_irqsave(&nesqp->lock, flags); | 3485 | spin_lock_irqsave(&nesqp->lock, flags); |
3400 | nesqp->hw_iwarp_state = iwarp_state; | 3486 | nesqp->hw_iwarp_state = iwarp_state; |
3401 | nesqp->hw_tcp_state = tcp_state; | 3487 | nesqp->hw_tcp_state = tcp_state; |
3402 | nesqp->last_aeq = async_event_id; | 3488 | nesqp->last_aeq = async_event_id; |
3403 | 3489 | nesqp->hte_added = 0; | |
3404 | if ((tcp_state == NES_AEQE_TCP_STATE_CLOSED) || | ||
3405 | (tcp_state == NES_AEQE_TCP_STATE_TIME_WAIT)) { | ||
3406 | nesqp->hte_added = 0; | ||
3407 | next_iwarp_state = NES_CQP_QP_IWARP_STATE_ERROR | NES_CQP_QP_DEL_HTE; | ||
3408 | } | ||
3409 | |||
3410 | if ((nesqp->ibqp_state == IB_QPS_RTS) && | ||
3411 | ((tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) || | ||
3412 | (async_event_id == NES_AEQE_AEID_LLP_CONNECTION_RESET))) { | ||
3413 | switch (nesqp->hw_iwarp_state) { | ||
3414 | case NES_AEQE_IWARP_STATE_RTS: | ||
3415 | next_iwarp_state = NES_CQP_QP_IWARP_STATE_CLOSING; | ||
3416 | nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING; | ||
3417 | break; | ||
3418 | case NES_AEQE_IWARP_STATE_TERMINATE: | ||
3419 | must_disconn = 0; /* terminate path takes care of disconn */ | ||
3420 | if (nesqp->term_flags == 0) | ||
3421 | must_terminate = 1; | ||
3422 | break; | ||
3423 | } | ||
3424 | } else { | ||
3425 | if (async_event_id == NES_AEQE_AEID_LLP_FIN_RECEIVED) { | ||
3426 | /* FIN Received but ib state not RTS, | ||
3427 | close complete will be on its way */ | ||
3428 | must_disconn = 0; | ||
3429 | } | ||
3430 | } | ||
3431 | spin_unlock_irqrestore(&nesqp->lock, flags); | 3490 | spin_unlock_irqrestore(&nesqp->lock, flags); |
3491 | next_iwarp_state = NES_CQP_QP_IWARP_STATE_ERROR | NES_CQP_QP_DEL_HTE; | ||
3492 | nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0, 0); | ||
3493 | nes_cm_disconn(nesqp); | ||
3494 | break; | ||
3432 | 3495 | ||
3433 | if (must_terminate) | 3496 | case NES_AEQE_AEID_LLP_CONNECTION_RESET: |
3434 | nes_terminate_connection(nesdev, nesqp, aeqe, IB_EVENT_QP_FATAL); | 3497 | if (atomic_read(&nesqp->close_timer_started)) |
3435 | else if (must_disconn) { | 3498 | return; |
3436 | if (next_iwarp_state) { | 3499 | spin_lock_irqsave(&nesqp->lock, flags); |
3437 | nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u. next state = 0x%08X\n", | 3500 | nesqp->hw_iwarp_state = iwarp_state; |
3438 | nesqp->hwqp.qp_id, next_iwarp_state); | 3501 | nesqp->hw_tcp_state = tcp_state; |
3439 | nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0, 0); | 3502 | nesqp->last_aeq = async_event_id; |
3440 | } | 3503 | spin_unlock_irqrestore(&nesqp->lock, flags); |
3441 | nes_cm_disconn(nesqp); | 3504 | nes_cm_disconn(nesqp); |
3442 | } | ||
3443 | break; | 3505 | break; |
3444 | 3506 | ||
3445 | case NES_AEQE_AEID_TERMINATE_SENT: | 3507 | case NES_AEQE_AEID_TERMINATE_SENT: |
3446 | nesqp = (struct nes_qp *)(unsigned long)context; | ||
3447 | nes_terminate_send_fin(nesdev, nesqp, aeqe); | 3508 | nes_terminate_send_fin(nesdev, nesqp, aeqe); |
3448 | break; | 3509 | break; |
3449 | 3510 | ||
3450 | case NES_AEQE_AEID_LLP_TERMINATE_RECEIVED: | 3511 | case NES_AEQE_AEID_LLP_TERMINATE_RECEIVED: |
3451 | nesqp = (struct nes_qp *)(unsigned long)context; | ||
3452 | nes_terminate_received(nesdev, nesqp, aeqe); | 3512 | nes_terminate_received(nesdev, nesqp, aeqe); |
3453 | break; | 3513 | break; |
3454 | 3514 | ||
@@ -3462,7 +3522,8 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, | |||
3462 | case NES_AEQE_AEID_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER: | 3522 | case NES_AEQE_AEID_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER: |
3463 | case NES_AEQE_AEID_AMP_BOUNDS_VIOLATION: | 3523 | case NES_AEQE_AEID_AMP_BOUNDS_VIOLATION: |
3464 | case NES_AEQE_AEID_AMP_TO_WRAP: | 3524 | case NES_AEQE_AEID_AMP_TO_WRAP: |
3465 | nesqp = (struct nes_qp *)(unsigned long)context; | 3525 | printk(KERN_ERR PFX "QP[%u] async_event_id=0x%04X IB_EVENT_QP_ACCESS_ERR\n", |
3526 | nesqp->hwqp.qp_id, async_event_id); | ||
3466 | nes_terminate_connection(nesdev, nesqp, aeqe, IB_EVENT_QP_ACCESS_ERR); | 3527 | nes_terminate_connection(nesdev, nesqp, aeqe, IB_EVENT_QP_ACCESS_ERR); |
3467 | break; | 3528 | break; |
3468 | 3529 | ||
@@ -3470,7 +3531,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, | |||
3470 | case NES_AEQE_AEID_LLP_SEGMENT_TOO_SMALL: | 3531 | case NES_AEQE_AEID_LLP_SEGMENT_TOO_SMALL: |
3471 | case NES_AEQE_AEID_DDP_UBE_INVALID_MO: | 3532 | case NES_AEQE_AEID_DDP_UBE_INVALID_MO: |
3472 | case NES_AEQE_AEID_DDP_UBE_INVALID_QN: | 3533 | case NES_AEQE_AEID_DDP_UBE_INVALID_QN: |
3473 | nesqp = (struct nes_qp *)(unsigned long)context; | ||
3474 | if (iwarp_opcode(nesqp, aeq_info) > IWARP_OPCODE_TERM) { | 3534 | if (iwarp_opcode(nesqp, aeq_info) > IWARP_OPCODE_TERM) { |
3475 | aeq_info &= 0xffff0000; | 3535 | aeq_info &= 0xffff0000; |
3476 | aeq_info |= NES_AEQE_AEID_RDMAP_ROE_UNEXPECTED_OPCODE; | 3536 | aeq_info |= NES_AEQE_AEID_RDMAP_ROE_UNEXPECTED_OPCODE; |
@@ -3512,7 +3572,8 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, | |||
3512 | case NES_AEQE_AEID_STAG_ZERO_INVALID: | 3572 | case NES_AEQE_AEID_STAG_ZERO_INVALID: |
3513 | case NES_AEQE_AEID_ROE_INVALID_RDMA_READ_REQUEST: | 3573 | case NES_AEQE_AEID_ROE_INVALID_RDMA_READ_REQUEST: |
3514 | case NES_AEQE_AEID_ROE_INVALID_RDMA_WRITE_OR_READ_RESP: | 3574 | case NES_AEQE_AEID_ROE_INVALID_RDMA_WRITE_OR_READ_RESP: |
3515 | nesqp = (struct nes_qp *)(unsigned long)context; | 3575 | printk(KERN_ERR PFX "QP[%u] async_event_id=0x%04X IB_EVENT_QP_FATAL\n", |
3576 | nesqp->hwqp.qp_id, async_event_id); | ||
3516 | nes_terminate_connection(nesdev, nesqp, aeqe, IB_EVENT_QP_FATAL); | 3577 | nes_terminate_connection(nesdev, nesqp, aeqe, IB_EVENT_QP_FATAL); |
3517 | break; | 3578 | break; |
3518 | 3579 | ||
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index f28a41ba9fa1..bbbfe9fc5a5a 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. | 2 | * Copyright (c) 2006 - 2009 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 |
@@ -37,12 +37,12 @@ | |||
37 | 37 | ||
38 | #define NES_PHY_TYPE_CX4 1 | 38 | #define NES_PHY_TYPE_CX4 1 |
39 | #define NES_PHY_TYPE_1G 2 | 39 | #define NES_PHY_TYPE_1G 2 |
40 | #define NES_PHY_TYPE_IRIS 3 | ||
41 | #define NES_PHY_TYPE_ARGUS 4 | 40 | #define NES_PHY_TYPE_ARGUS 4 |
42 | #define NES_PHY_TYPE_PUMA_1G 5 | 41 | #define NES_PHY_TYPE_PUMA_1G 5 |
43 | #define NES_PHY_TYPE_PUMA_10G 6 | 42 | #define NES_PHY_TYPE_PUMA_10G 6 |
44 | #define NES_PHY_TYPE_GLADIUS 7 | 43 | #define NES_PHY_TYPE_GLADIUS 7 |
45 | #define NES_PHY_TYPE_SFP_D 8 | 44 | #define NES_PHY_TYPE_SFP_D 8 |
45 | #define NES_PHY_TYPE_KR 9 | ||
46 | 46 | ||
47 | #define NES_MULTICAST_PF_MAX 8 | 47 | #define NES_MULTICAST_PF_MAX 8 |
48 | 48 | ||
@@ -160,6 +160,7 @@ enum indexed_regs { | |||
160 | NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_HI = 0x7004, | 160 | NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_HI = 0x7004, |
161 | NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_LO = 0x7008, | 161 | NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_LO = 0x7008, |
162 | NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_HI = 0x700c, | 162 | NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_HI = 0x700c, |
163 | NES_IDX_WQM_CONFIG0 = 0x5000, | ||
163 | NES_IDX_WQM_CONFIG1 = 0x5004, | 164 | NES_IDX_WQM_CONFIG1 = 0x5004, |
164 | NES_IDX_CM_CONFIG = 0x5100, | 165 | NES_IDX_CM_CONFIG = 0x5100, |
165 | NES_IDX_NIC_LOGPORT_TO_PHYPORT = 0x6000, | 166 | NES_IDX_NIC_LOGPORT_TO_PHYPORT = 0x6000, |
@@ -546,11 +547,23 @@ enum nes_iwarp_sq_fmr_wqe_word_idx { | |||
546 | NES_IWARP_SQ_FMR_WQE_PBL_LENGTH_IDX = 14, | 547 | NES_IWARP_SQ_FMR_WQE_PBL_LENGTH_IDX = 14, |
547 | }; | 548 | }; |
548 | 549 | ||
550 | enum nes_iwarp_sq_fmr_opcodes { | ||
551 | NES_IWARP_SQ_FMR_WQE_ZERO_BASED = (1<<6), | ||
552 | NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_4K = (0<<7), | ||
553 | NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_2M = (1<<7), | ||
554 | NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_LOCAL_READ = (1<<16), | ||
555 | NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_LOCAL_WRITE = (1<<17), | ||
556 | NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_REMOTE_READ = (1<<18), | ||
557 | NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_REMOTE_WRITE = (1<<19), | ||
558 | NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_WINDOW_BIND = (1<<20), | ||
559 | }; | ||
560 | |||
561 | #define NES_IWARP_SQ_FMR_WQE_MR_LENGTH_HIGH_MASK 0xFF; | ||
562 | |||
549 | enum nes_iwarp_sq_locinv_wqe_word_idx { | 563 | enum nes_iwarp_sq_locinv_wqe_word_idx { |
550 | NES_IWARP_SQ_LOCINV_WQE_INV_STAG_IDX = 6, | 564 | NES_IWARP_SQ_LOCINV_WQE_INV_STAG_IDX = 6, |
551 | }; | 565 | }; |
552 | 566 | ||
553 | |||
554 | enum nes_iwarp_rq_wqe_word_idx { | 567 | enum nes_iwarp_rq_wqe_word_idx { |
555 | NES_IWARP_RQ_WQE_TOTAL_PAYLOAD_IDX = 1, | 568 | NES_IWARP_RQ_WQE_TOTAL_PAYLOAD_IDX = 1, |
556 | NES_IWARP_RQ_WQE_COMP_CTX_LOW_IDX = 2, | 569 | NES_IWARP_RQ_WQE_COMP_CTX_LOW_IDX = 2, |
@@ -1153,6 +1166,19 @@ struct nes_pbl { | |||
1153 | /* TODO: need to add list for two level tables */ | 1166 | /* TODO: need to add list for two level tables */ |
1154 | }; | 1167 | }; |
1155 | 1168 | ||
1169 | #define NES_4K_PBL_CHUNK_SIZE 4096 | ||
1170 | |||
1171 | struct nes_fast_mr_wqe_pbl { | ||
1172 | u64 *kva; | ||
1173 | dma_addr_t paddr; | ||
1174 | }; | ||
1175 | |||
1176 | struct nes_ib_fast_reg_page_list { | ||
1177 | struct ib_fast_reg_page_list ibfrpl; | ||
1178 | struct nes_fast_mr_wqe_pbl nes_wqe_pbl; | ||
1179 | u64 pbl; | ||
1180 | }; | ||
1181 | |||
1156 | struct nes_listener { | 1182 | struct nes_listener { |
1157 | struct work_struct work; | 1183 | struct work_struct work; |
1158 | struct workqueue_struct *wq; | 1184 | struct workqueue_struct *wq; |
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index e593af3354b8..b7c813f4be43 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. | 2 | * Copyright (c) 2006 - 2009 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 |
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/if_arp.h> | 40 | #include <linux/if_arp.h> |
41 | #include <linux/if_vlan.h> | 41 | #include <linux/if_vlan.h> |
42 | #include <linux/ethtool.h> | 42 | #include <linux/ethtool.h> |
43 | #include <linux/slab.h> | ||
43 | #include <net/tcp.h> | 44 | #include <net/tcp.h> |
44 | 45 | ||
45 | #include <net/inet_common.h> | 46 | #include <net/inet_common.h> |
@@ -810,6 +811,20 @@ static int nes_netdev_set_mac_address(struct net_device *netdev, void *p) | |||
810 | } | 811 | } |
811 | 812 | ||
812 | 813 | ||
814 | static void set_allmulti(struct nes_device *nesdev, u32 nic_active_bit) | ||
815 | { | ||
816 | u32 nic_active; | ||
817 | |||
818 | nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL); | ||
819 | nic_active |= nic_active_bit; | ||
820 | nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active); | ||
821 | nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL); | ||
822 | nic_active &= ~nic_active_bit; | ||
823 | nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active); | ||
824 | } | ||
825 | |||
826 | #define get_addr(addrs, index) ((addrs) + (index) * ETH_ALEN) | ||
827 | |||
813 | /** | 828 | /** |
814 | * nes_netdev_set_multicast_list | 829 | * nes_netdev_set_multicast_list |
815 | */ | 830 | */ |
@@ -818,7 +833,6 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
818 | struct nes_vnic *nesvnic = netdev_priv(netdev); | 833 | struct nes_vnic *nesvnic = netdev_priv(netdev); |
819 | struct nes_device *nesdev = nesvnic->nesdev; | 834 | struct nes_device *nesdev = nesvnic->nesdev; |
820 | struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter; | 835 | struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter; |
821 | struct dev_mc_list *multicast_addr; | ||
822 | u32 nic_active_bit; | 836 | u32 nic_active_bit; |
823 | u32 nic_active; | 837 | u32 nic_active; |
824 | u32 perfect_filter_register_address; | 838 | u32 perfect_filter_register_address; |
@@ -831,6 +845,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
831 | nics_per_function, 4); | 845 | nics_per_function, 4); |
832 | u8 max_pft_entries_avaiable = NES_PFT_SIZE - pft_entries_preallocated; | 846 | u8 max_pft_entries_avaiable = NES_PFT_SIZE - pft_entries_preallocated; |
833 | unsigned long flags; | 847 | unsigned long flags; |
848 | int mc_count = netdev_mc_count(netdev); | ||
834 | 849 | ||
835 | spin_lock_irqsave(&nesadapter->resource_lock, flags); | 850 | spin_lock_irqsave(&nesadapter->resource_lock, flags); |
836 | nic_active_bit = 1 << nesvnic->nic_index; | 851 | nic_active_bit = 1 << nesvnic->nic_index; |
@@ -845,12 +860,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
845 | mc_all_on = 1; | 860 | mc_all_on = 1; |
846 | } else if ((netdev->flags & IFF_ALLMULTI) || | 861 | } else if ((netdev->flags & IFF_ALLMULTI) || |
847 | (nesvnic->nic_index > 3)) { | 862 | (nesvnic->nic_index > 3)) { |
848 | nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL); | 863 | set_allmulti(nesdev, nic_active_bit); |
849 | nic_active |= nic_active_bit; | ||
850 | nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active); | ||
851 | nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL); | ||
852 | nic_active &= ~nic_active_bit; | ||
853 | nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active); | ||
854 | mc_all_on = 1; | 864 | mc_all_on = 1; |
855 | } else { | 865 | } else { |
856 | nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL); | 866 | nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL); |
@@ -862,19 +872,30 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
862 | } | 872 | } |
863 | 873 | ||
864 | nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscous = %d, All Multicast = %d.\n", | 874 | nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscous = %d, All Multicast = %d.\n", |
865 | netdev->mc_count, !!(netdev->flags & IFF_PROMISC), | 875 | mc_count, !!(netdev->flags & IFF_PROMISC), |
866 | !!(netdev->flags & IFF_ALLMULTI)); | 876 | !!(netdev->flags & IFF_ALLMULTI)); |
867 | if (!mc_all_on) { | 877 | if (!mc_all_on) { |
868 | multicast_addr = netdev->mc_list; | 878 | char *addrs; |
879 | int i; | ||
880 | struct dev_mc_list *mcaddr; | ||
881 | |||
882 | addrs = kmalloc(ETH_ALEN * mc_count, GFP_ATOMIC); | ||
883 | if (!addrs) { | ||
884 | set_allmulti(nesdev, nic_active_bit); | ||
885 | goto unlock; | ||
886 | } | ||
887 | i = 0; | ||
888 | netdev_for_each_mc_addr(mcaddr, netdev) | ||
889 | memcpy(get_addr(addrs, i++), | ||
890 | mcaddr->dmi_addr, ETH_ALEN); | ||
891 | |||
869 | perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW + | 892 | perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW + |
870 | pft_entries_preallocated * 0x8; | 893 | pft_entries_preallocated * 0x8; |
871 | for (mc_index = 0; mc_index < max_pft_entries_avaiable; | 894 | for (i = 0, mc_index = 0; mc_index < max_pft_entries_avaiable; |
872 | mc_index++) { | 895 | mc_index++) { |
873 | while (multicast_addr && nesvnic->mcrq_mcast_filter && | 896 | while (i < mc_count && nesvnic->mcrq_mcast_filter && |
874 | ((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic, | 897 | ((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic, |
875 | multicast_addr->dmi_addr)) == 0)) { | 898 | get_addr(addrs, i++))) == 0)); |
876 | multicast_addr = multicast_addr->next; | ||
877 | } | ||
878 | if (mc_nic_index < 0) | 899 | if (mc_nic_index < 0) |
879 | mc_nic_index = nesvnic->nic_index; | 900 | mc_nic_index = nesvnic->nic_index; |
880 | while (nesadapter->pft_mcast_map[mc_index] < 16 && | 901 | while (nesadapter->pft_mcast_map[mc_index] < 16 && |
@@ -890,17 +911,19 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
890 | } | 911 | } |
891 | if (mc_index >= max_pft_entries_avaiable) | 912 | if (mc_index >= max_pft_entries_avaiable) |
892 | break; | 913 | break; |
893 | if (multicast_addr) { | 914 | if (i < mc_count) { |
915 | char *addr = get_addr(addrs, i++); | ||
916 | |||
894 | nes_debug(NES_DBG_NIC_RX, "Assigning MC Address %pM to register 0x%04X nic_idx=%d\n", | 917 | nes_debug(NES_DBG_NIC_RX, "Assigning MC Address %pM to register 0x%04X nic_idx=%d\n", |
895 | multicast_addr->dmi_addr, | 918 | addr, |
896 | perfect_filter_register_address+(mc_index * 8), | 919 | perfect_filter_register_address+(mc_index * 8), |
897 | mc_nic_index); | 920 | mc_nic_index); |
898 | macaddr_high = ((u16)multicast_addr->dmi_addr[0]) << 8; | 921 | macaddr_high = ((u16) addr[0]) << 8; |
899 | macaddr_high += (u16)multicast_addr->dmi_addr[1]; | 922 | macaddr_high += (u16) addr[1]; |
900 | macaddr_low = ((u32)multicast_addr->dmi_addr[2]) << 24; | 923 | macaddr_low = ((u32) addr[2]) << 24; |
901 | macaddr_low += ((u32)multicast_addr->dmi_addr[3]) << 16; | 924 | macaddr_low += ((u32) addr[3]) << 16; |
902 | macaddr_low += ((u32)multicast_addr->dmi_addr[4]) << 8; | 925 | macaddr_low += ((u32) addr[4]) << 8; |
903 | macaddr_low += (u32)multicast_addr->dmi_addr[5]; | 926 | macaddr_low += (u32) addr[5]; |
904 | nes_write_indexed(nesdev, | 927 | nes_write_indexed(nesdev, |
905 | perfect_filter_register_address+(mc_index * 8), | 928 | perfect_filter_register_address+(mc_index * 8), |
906 | macaddr_low); | 929 | macaddr_low); |
@@ -908,7 +931,6 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
908 | perfect_filter_register_address+4+(mc_index * 8), | 931 | perfect_filter_register_address+4+(mc_index * 8), |
909 | (u32)macaddr_high | NES_MAC_ADDR_VALID | | 932 | (u32)macaddr_high | NES_MAC_ADDR_VALID | |
910 | ((((u32)(1<<mc_nic_index)) << 16))); | 933 | ((((u32)(1<<mc_nic_index)) << 16))); |
911 | multicast_addr = multicast_addr->next; | ||
912 | nesadapter->pft_mcast_map[mc_index] = | 934 | nesadapter->pft_mcast_map[mc_index] = |
913 | nesvnic->nic_index; | 935 | nesvnic->nic_index; |
914 | } else { | 936 | } else { |
@@ -920,21 +942,13 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
920 | nesadapter->pft_mcast_map[mc_index] = 255; | 942 | nesadapter->pft_mcast_map[mc_index] = 255; |
921 | } | 943 | } |
922 | } | 944 | } |
945 | kfree(addrs); | ||
923 | /* PFT is not large enough */ | 946 | /* PFT is not large enough */ |
924 | if (multicast_addr && multicast_addr->next) { | 947 | if (i < mc_count) |
925 | nic_active = nes_read_indexed(nesdev, | 948 | set_allmulti(nesdev, nic_active_bit); |
926 | NES_IDX_NIC_MULTICAST_ALL); | ||
927 | nic_active |= nic_active_bit; | ||
928 | nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, | ||
929 | nic_active); | ||
930 | nic_active = nes_read_indexed(nesdev, | ||
931 | NES_IDX_NIC_UNICAST_ALL); | ||
932 | nic_active &= ~nic_active_bit; | ||
933 | nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, | ||
934 | nic_active); | ||
935 | } | ||
936 | } | 949 | } |
937 | 950 | ||
951 | unlock: | ||
938 | spin_unlock_irqrestore(&nesadapter->resource_lock, flags); | 952 | spin_unlock_irqrestore(&nesadapter->resource_lock, flags); |
939 | } | 953 | } |
940 | 954 | ||
@@ -1080,11 +1094,14 @@ static int nes_netdev_set_rx_csum(struct net_device *netdev, u32 enable) | |||
1080 | 1094 | ||
1081 | 1095 | ||
1082 | /** | 1096 | /** |
1083 | * nes_netdev_get_stats_count | 1097 | * nes_netdev_get_sset_count |
1084 | */ | 1098 | */ |
1085 | static int nes_netdev_get_stats_count(struct net_device *netdev) | 1099 | static int nes_netdev_get_sset_count(struct net_device *netdev, int stringset) |
1086 | { | 1100 | { |
1087 | return NES_ETHTOOL_STAT_COUNT; | 1101 | if (stringset == ETH_SS_STATS) |
1102 | return NES_ETHTOOL_STAT_COUNT; | ||
1103 | else | ||
1104 | return -EINVAL; | ||
1088 | } | 1105 | } |
1089 | 1106 | ||
1090 | 1107 | ||
@@ -1227,8 +1244,8 @@ static void nes_netdev_get_ethtool_stats(struct net_device *netdev, | |||
1227 | target_stat_values[++index] = cm_packets_received; | 1244 | target_stat_values[++index] = cm_packets_received; |
1228 | target_stat_values[++index] = cm_packets_dropped; | 1245 | target_stat_values[++index] = cm_packets_dropped; |
1229 | target_stat_values[++index] = cm_packets_retrans; | 1246 | target_stat_values[++index] = cm_packets_retrans; |
1230 | target_stat_values[++index] = cm_listens_created; | 1247 | target_stat_values[++index] = atomic_read(&cm_listens_created); |
1231 | target_stat_values[++index] = cm_listens_destroyed; | 1248 | target_stat_values[++index] = atomic_read(&cm_listens_destroyed); |
1232 | target_stat_values[++index] = cm_backlog_drops; | 1249 | target_stat_values[++index] = cm_backlog_drops; |
1233 | target_stat_values[++index] = atomic_read(&cm_loopbacks); | 1250 | target_stat_values[++index] = atomic_read(&cm_loopbacks); |
1234 | target_stat_values[++index] = atomic_read(&cm_nodes_created); | 1251 | target_stat_values[++index] = atomic_read(&cm_nodes_created); |
@@ -1264,7 +1281,6 @@ static void nes_netdev_get_drvinfo(struct net_device *netdev, | |||
1264 | sprintf(drvinfo->fw_version, "%u.%u", nesadapter->firmware_version>>16, | 1281 | sprintf(drvinfo->fw_version, "%u.%u", nesadapter->firmware_version>>16, |
1265 | nesadapter->firmware_version & 0x000000ff); | 1282 | nesadapter->firmware_version & 0x000000ff); |
1266 | strcpy(drvinfo->version, DRV_VERSION); | 1283 | strcpy(drvinfo->version, DRV_VERSION); |
1267 | drvinfo->n_stats = nes_netdev_get_stats_count(netdev); | ||
1268 | drvinfo->testinfo_len = 0; | 1284 | drvinfo->testinfo_len = 0; |
1269 | drvinfo->eedump_len = 0; | 1285 | drvinfo->eedump_len = 0; |
1270 | drvinfo->regdump_len = 0; | 1286 | drvinfo->regdump_len = 0; |
@@ -1459,9 +1475,9 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd | |||
1459 | } | 1475 | } |
1460 | return 0; | 1476 | return 0; |
1461 | } | 1477 | } |
1462 | if ((phy_type == NES_PHY_TYPE_IRIS) || | 1478 | if ((phy_type == NES_PHY_TYPE_ARGUS) || |
1463 | (phy_type == NES_PHY_TYPE_ARGUS) || | 1479 | (phy_type == NES_PHY_TYPE_SFP_D) || |
1464 | (phy_type == NES_PHY_TYPE_SFP_D)) { | 1480 | (phy_type == NES_PHY_TYPE_KR)) { |
1465 | et_cmd->transceiver = XCVR_EXTERNAL; | 1481 | et_cmd->transceiver = XCVR_EXTERNAL; |
1466 | et_cmd->port = PORT_FIBRE; | 1482 | et_cmd->port = PORT_FIBRE; |
1467 | et_cmd->supported = SUPPORTED_FIBRE; | 1483 | et_cmd->supported = SUPPORTED_FIBRE; |
@@ -1516,7 +1532,7 @@ static const struct ethtool_ops nes_ethtool_ops = { | |||
1516 | .get_rx_csum = nes_netdev_get_rx_csum, | 1532 | .get_rx_csum = nes_netdev_get_rx_csum, |
1517 | .get_sg = ethtool_op_get_sg, | 1533 | .get_sg = ethtool_op_get_sg, |
1518 | .get_strings = nes_netdev_get_strings, | 1534 | .get_strings = nes_netdev_get_strings, |
1519 | .get_stats_count = nes_netdev_get_stats_count, | 1535 | .get_sset_count = nes_netdev_get_sset_count, |
1520 | .get_ethtool_stats = nes_netdev_get_ethtool_stats, | 1536 | .get_ethtool_stats = nes_netdev_get_ethtool_stats, |
1521 | .get_drvinfo = nes_netdev_get_drvinfo, | 1537 | .get_drvinfo = nes_netdev_get_drvinfo, |
1522 | .get_coalesce = nes_netdev_get_coalesce, | 1538 | .get_coalesce = nes_netdev_get_coalesce, |
@@ -1580,9 +1596,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1580 | struct nes_vnic *nesvnic; | 1596 | struct nes_vnic *nesvnic; |
1581 | struct net_device *netdev; | 1597 | struct net_device *netdev; |
1582 | struct nic_qp_map *curr_qp_map; | 1598 | struct nic_qp_map *curr_qp_map; |
1583 | u32 u32temp; | 1599 | u8 phy_type = nesdev->nesadapter->phy_type[nesdev->mac_index]; |
1584 | u16 phy_data; | ||
1585 | u16 temp_phy_data; | ||
1586 | 1600 | ||
1587 | netdev = alloc_etherdev(sizeof(struct nes_vnic)); | 1601 | netdev = alloc_etherdev(sizeof(struct nes_vnic)); |
1588 | if (!netdev) { | 1602 | if (!netdev) { |
@@ -1690,66 +1704,51 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1690 | 1704 | ||
1691 | if ((nesdev->netdev_count == 0) && | 1705 | if ((nesdev->netdev_count == 0) && |
1692 | ((PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index) || | 1706 | ((PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index) || |
1693 | ((nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) && | 1707 | ((phy_type == NES_PHY_TYPE_PUMA_1G) && |
1694 | (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || | 1708 | (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || |
1695 | ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { | 1709 | ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { |
1696 | /* | 1710 | u32 u32temp; |
1697 | * nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n", | 1711 | u32 link_mask; |
1698 | * NES_IDX_PHY_PCS_CONTROL_STATUS0 + (0x200 * (nesvnic->logical_port & 1))); | 1712 | u32 link_val; |
1699 | */ | 1713 | |
1700 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1714 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + |
1701 | (0x200 * (nesdev->mac_index & 1))); | 1715 | (0x200 * (nesdev->mac_index & 1))); |
1702 | if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_PUMA_1G) { | 1716 | if (phy_type != NES_PHY_TYPE_PUMA_1G) { |
1703 | u32temp |= 0x00200000; | 1717 | u32temp |= 0x00200000; |
1704 | nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1718 | nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + |
1705 | (0x200 * (nesdev->mac_index & 1)), u32temp); | 1719 | (0x200 * (nesdev->mac_index & 1)), u32temp); |
1706 | } | 1720 | } |
1707 | 1721 | ||
1708 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1722 | /* Check and set linkup here. This is for back to back */ |
1709 | (0x200 * (nesdev->mac_index & 1))); | 1723 | /* configuration where second port won't get link interrupt */ |
1710 | 1724 | switch (phy_type) { | |
1711 | if ((u32temp&0x0f1f0000) == 0x0f0f0000) { | 1725 | case NES_PHY_TYPE_PUMA_1G: |
1712 | if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) { | 1726 | if (nesdev->mac_index < 2) { |
1713 | nes_init_phy(nesdev); | 1727 | link_mask = 0x01010000; |
1714 | nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1); | 1728 | link_val = 0x01010000; |
1715 | temp_phy_data = (u16)nes_read_indexed(nesdev, | ||
1716 | NES_IDX_MAC_MDIO_CONTROL); | ||
1717 | u32temp = 20; | ||
1718 | do { | ||
1719 | nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1); | ||
1720 | phy_data = (u16)nes_read_indexed(nesdev, | ||
1721 | NES_IDX_MAC_MDIO_CONTROL); | ||
1722 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | ||
1723 | break; | ||
1724 | temp_phy_data = phy_data; | ||
1725 | } while (1); | ||
1726 | if (phy_data & 4) { | ||
1727 | nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); | ||
1728 | nesvnic->linkup = 1; | ||
1729 | } else { | ||
1730 | nes_debug(NES_DBG_INIT, "The Link is DOWN!!.\n"); | ||
1731 | } | ||
1732 | } else { | 1729 | } else { |
1733 | nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); | 1730 | link_mask = 0x02020000; |
1734 | nesvnic->linkup = 1; | 1731 | link_val = 0x02020000; |
1735 | } | ||
1736 | } else if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) { | ||
1737 | nes_debug(NES_DBG_INIT, "mac_index=%d, logical_port=%d, u32temp=0x%04X, PCI_FUNC=%d\n", | ||
1738 | nesdev->mac_index, nesvnic->logical_port, u32temp, PCI_FUNC(nesdev->pcidev->devfn)); | ||
1739 | if (((nesdev->mac_index < 2) && ((u32temp&0x01010000) == 0x01010000)) || | ||
1740 | ((nesdev->mac_index > 1) && ((u32temp&0x02020000) == 0x02020000))) { | ||
1741 | nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); | ||
1742 | nesvnic->linkup = 1; | ||
1743 | } | 1732 | } |
1733 | break; | ||
1734 | default: | ||
1735 | link_mask = 0x0f1f0000; | ||
1736 | link_val = 0x0f0f0000; | ||
1737 | break; | ||
1744 | } | 1738 | } |
1739 | |||
1740 | u32temp = nes_read_indexed(nesdev, | ||
1741 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + | ||
1742 | (0x200 * (nesdev->mac_index & 1))); | ||
1743 | if ((u32temp & link_mask) == link_val) | ||
1744 | nesvnic->linkup = 1; | ||
1745 | |||
1745 | /* clear the MAC interrupt status, assumes direct logical to physical mapping */ | 1746 | /* clear the MAC interrupt status, assumes direct logical to physical mapping */ |
1746 | u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); | 1747 | u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); |
1747 | nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", u32temp); | 1748 | nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", u32temp); |
1748 | nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index), u32temp); | 1749 | nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index), u32temp); |
1749 | 1750 | ||
1750 | if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_IRIS) | 1751 | nes_init_phy(nesdev); |
1751 | nes_init_phy(nesdev); | ||
1752 | |||
1753 | } | 1752 | } |
1754 | 1753 | ||
1755 | return netdev; | 1754 | return netdev; |
diff --git a/drivers/infiniband/hw/nes/nes_user.h b/drivers/infiniband/hw/nes/nes_user.h index cc90c14b49eb..71e133ab209b 100644 --- a/drivers/infiniband/hw/nes/nes_user.h +++ b/drivers/infiniband/hw/nes/nes_user.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. | 2 | * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. |
3 | * Copyright (c) 2005 Topspin Communications. All rights reserved. | 3 | * Copyright (c) 2005 Topspin Communications. All rights reserved. |
4 | * Copyright (c) 2005 Cisco Systems. All rights reserved. | 4 | * Copyright (c) 2005 Cisco Systems. All rights reserved. |
5 | * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. | 5 | * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. |
@@ -86,6 +86,7 @@ enum iwnes_memreg_type { | |||
86 | IWNES_MEMREG_TYPE_CQ = 0x0002, | 86 | IWNES_MEMREG_TYPE_CQ = 0x0002, |
87 | IWNES_MEMREG_TYPE_MW = 0x0003, | 87 | IWNES_MEMREG_TYPE_MW = 0x0003, |
88 | IWNES_MEMREG_TYPE_FMR = 0x0004, | 88 | IWNES_MEMREG_TYPE_FMR = 0x0004, |
89 | IWNES_MEMREG_TYPE_FMEM = 0x0005, | ||
89 | }; | 90 | }; |
90 | 91 | ||
91 | struct nes_mem_reg_req { | 92 | struct nes_mem_reg_req { |
diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c index 9687c397ce1a..186623d86959 100644 --- a/drivers/infiniband/hw/nes/nes_utils.c +++ b/drivers/infiniband/hw/nes/nes_utils.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. | 2 | * Copyright (c) 2006 - 2009 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 |
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/ethtool.h> | 38 | #include <linux/ethtool.h> |
39 | #include <linux/mii.h> | 39 | #include <linux/mii.h> |
40 | #include <linux/if_vlan.h> | 40 | #include <linux/if_vlan.h> |
41 | #include <linux/slab.h> | ||
41 | #include <linux/crc32.h> | 42 | #include <linux/crc32.h> |
42 | #include <linux/in.h> | 43 | #include <linux/in.h> |
43 | #include <linux/ip.h> | 44 | #include <linux/ip.h> |
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index a680c42d6e8c..e54f312e4bdc 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. | 2 | * Copyright (c) 2006 - 2009 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 |
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/moduleparam.h> | 35 | #include <linux/moduleparam.h> |
36 | #include <linux/random.h> | 36 | #include <linux/random.h> |
37 | #include <linux/highmem.h> | 37 | #include <linux/highmem.h> |
38 | #include <linux/slab.h> | ||
38 | #include <asm/byteorder.h> | 39 | #include <asm/byteorder.h> |
39 | 40 | ||
40 | #include <rdma/ib_verbs.h> | 41 | #include <rdma/ib_verbs.h> |
@@ -228,7 +229,7 @@ static int nes_bind_mw(struct ib_qp *ibqp, struct ib_mw *ibmw, | |||
228 | /* Check for SQ overflow */ | 229 | /* Check for SQ overflow */ |
229 | if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) { | 230 | if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) { |
230 | spin_unlock_irqrestore(&nesqp->lock, flags); | 231 | spin_unlock_irqrestore(&nesqp->lock, flags); |
231 | return -EINVAL; | 232 | return -ENOMEM; |
232 | } | 233 | } |
233 | 234 | ||
234 | wqe = &nesqp->hwqp.sq_vbase[head]; | 235 | wqe = &nesqp->hwqp.sq_vbase[head]; |
@@ -275,342 +276,236 @@ static int nes_bind_mw(struct ib_qp *ibqp, struct ib_mw *ibmw, | |||
275 | } | 276 | } |
276 | 277 | ||
277 | 278 | ||
278 | /** | 279 | /* |
279 | * nes_alloc_fmr | 280 | * nes_alloc_fast_mr |
280 | */ | 281 | */ |
281 | static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd, | 282 | static int alloc_fast_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd, |
282 | int ibmr_access_flags, | 283 | u32 stag, u32 page_count) |
283 | struct ib_fmr_attr *ibfmr_attr) | ||
284 | { | 284 | { |
285 | unsigned long flags; | ||
286 | struct nes_pd *nespd = to_nespd(ibpd); | ||
287 | struct nes_vnic *nesvnic = to_nesvnic(ibpd->device); | ||
288 | struct nes_device *nesdev = nesvnic->nesdev; | ||
289 | struct nes_adapter *nesadapter = nesdev->nesadapter; | ||
290 | struct nes_fmr *nesfmr; | ||
291 | struct nes_cqp_request *cqp_request; | ||
292 | struct nes_hw_cqp_wqe *cqp_wqe; | 285 | struct nes_hw_cqp_wqe *cqp_wqe; |
286 | struct nes_cqp_request *cqp_request; | ||
287 | unsigned long flags; | ||
293 | int ret; | 288 | int ret; |
294 | u32 stag; | 289 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
295 | u32 stag_index = 0; | ||
296 | u32 next_stag_index = 0; | ||
297 | u32 driver_key = 0; | ||
298 | u32 opcode = 0; | 290 | u32 opcode = 0; |
299 | u8 stag_key = 0; | 291 | u16 major_code; |
300 | int i=0; | 292 | u64 region_length = page_count * PAGE_SIZE; |
301 | struct nes_vpbl vpbl; | ||
302 | |||
303 | get_random_bytes(&next_stag_index, sizeof(next_stag_index)); | ||
304 | stag_key = (u8)next_stag_index; | ||
305 | |||
306 | driver_key = 0; | ||
307 | |||
308 | next_stag_index >>= 8; | ||
309 | next_stag_index %= nesadapter->max_mr; | ||
310 | |||
311 | ret = nes_alloc_resource(nesadapter, nesadapter->allocated_mrs, | ||
312 | nesadapter->max_mr, &stag_index, &next_stag_index); | ||
313 | if (ret) { | ||
314 | goto failed_resource_alloc; | ||
315 | } | ||
316 | |||
317 | nesfmr = kzalloc(sizeof(*nesfmr), GFP_KERNEL); | ||
318 | if (!nesfmr) { | ||
319 | ret = -ENOMEM; | ||
320 | goto failed_fmr_alloc; | ||
321 | } | ||
322 | |||
323 | nesfmr->nesmr.mode = IWNES_MEMREG_TYPE_FMR; | ||
324 | if (ibfmr_attr->max_pages == 1) { | ||
325 | /* use zero length PBL */ | ||
326 | nesfmr->nesmr.pbl_4k = 0; | ||
327 | nesfmr->nesmr.pbls_used = 0; | ||
328 | } else if (ibfmr_attr->max_pages <= 32) { | ||
329 | /* use PBL 256 */ | ||
330 | nesfmr->nesmr.pbl_4k = 0; | ||
331 | nesfmr->nesmr.pbls_used = 1; | ||
332 | } else if (ibfmr_attr->max_pages <= 512) { | ||
333 | /* use 4K PBLs */ | ||
334 | nesfmr->nesmr.pbl_4k = 1; | ||
335 | nesfmr->nesmr.pbls_used = 1; | ||
336 | } else { | ||
337 | /* use two level 4K PBLs */ | ||
338 | /* add support for two level 256B PBLs */ | ||
339 | nesfmr->nesmr.pbl_4k = 1; | ||
340 | nesfmr->nesmr.pbls_used = 1 + (ibfmr_attr->max_pages >> 9) + | ||
341 | ((ibfmr_attr->max_pages & 511) ? 1 : 0); | ||
342 | } | ||
343 | /* Register the region with the adapter */ | ||
344 | spin_lock_irqsave(&nesadapter->pbl_lock, flags); | ||
345 | |||
346 | /* track PBL resources */ | ||
347 | if (nesfmr->nesmr.pbls_used != 0) { | ||
348 | if (nesfmr->nesmr.pbl_4k) { | ||
349 | if (nesfmr->nesmr.pbls_used > nesadapter->free_4kpbl) { | ||
350 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | ||
351 | ret = -ENOMEM; | ||
352 | goto failed_vpbl_avail; | ||
353 | } else { | ||
354 | nesadapter->free_4kpbl -= nesfmr->nesmr.pbls_used; | ||
355 | } | ||
356 | } else { | ||
357 | if (nesfmr->nesmr.pbls_used > nesadapter->free_256pbl) { | ||
358 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | ||
359 | ret = -ENOMEM; | ||
360 | goto failed_vpbl_avail; | ||
361 | } else { | ||
362 | nesadapter->free_256pbl -= nesfmr->nesmr.pbls_used; | ||
363 | } | ||
364 | } | ||
365 | } | ||
366 | |||
367 | /* one level pbl */ | ||
368 | if (nesfmr->nesmr.pbls_used == 0) { | ||
369 | nesfmr->root_vpbl.pbl_vbase = NULL; | ||
370 | nes_debug(NES_DBG_MR, "zero level pbl \n"); | ||
371 | } else if (nesfmr->nesmr.pbls_used == 1) { | ||
372 | /* can change it to kmalloc & dma_map_single */ | ||
373 | nesfmr->root_vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096, | ||
374 | &nesfmr->root_vpbl.pbl_pbase); | ||
375 | if (!nesfmr->root_vpbl.pbl_vbase) { | ||
376 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | ||
377 | ret = -ENOMEM; | ||
378 | goto failed_vpbl_alloc; | ||
379 | } | ||
380 | nesfmr->leaf_pbl_cnt = 0; | ||
381 | nes_debug(NES_DBG_MR, "one level pbl, root_vpbl.pbl_vbase=%p \n", | ||
382 | nesfmr->root_vpbl.pbl_vbase); | ||
383 | } | ||
384 | /* two level pbl */ | ||
385 | else { | ||
386 | nesfmr->root_vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 8192, | ||
387 | &nesfmr->root_vpbl.pbl_pbase); | ||
388 | if (!nesfmr->root_vpbl.pbl_vbase) { | ||
389 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | ||
390 | ret = -ENOMEM; | ||
391 | goto failed_vpbl_alloc; | ||
392 | } | ||
393 | |||
394 | nesfmr->leaf_pbl_cnt = nesfmr->nesmr.pbls_used-1; | ||
395 | nesfmr->root_vpbl.leaf_vpbl = kzalloc(sizeof(*nesfmr->root_vpbl.leaf_vpbl)*1024, GFP_ATOMIC); | ||
396 | if (!nesfmr->root_vpbl.leaf_vpbl) { | ||
397 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | ||
398 | ret = -ENOMEM; | ||
399 | goto failed_leaf_vpbl_alloc; | ||
400 | } | ||
401 | |||
402 | nes_debug(NES_DBG_MR, "two level pbl, root_vpbl.pbl_vbase=%p" | ||
403 | " leaf_pbl_cnt=%d root_vpbl.leaf_vpbl=%p\n", | ||
404 | nesfmr->root_vpbl.pbl_vbase, nesfmr->leaf_pbl_cnt, nesfmr->root_vpbl.leaf_vpbl); | ||
405 | |||
406 | for (i=0; i<nesfmr->leaf_pbl_cnt; i++) | ||
407 | nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase = NULL; | ||
408 | |||
409 | for (i=0; i<nesfmr->leaf_pbl_cnt; i++) { | ||
410 | vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096, | ||
411 | &vpbl.pbl_pbase); | ||
412 | |||
413 | if (!vpbl.pbl_vbase) { | ||
414 | ret = -ENOMEM; | ||
415 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | ||
416 | goto failed_leaf_vpbl_pages_alloc; | ||
417 | } | ||
418 | |||
419 | nesfmr->root_vpbl.pbl_vbase[i].pa_low = cpu_to_le32((u32)vpbl.pbl_pbase); | ||
420 | nesfmr->root_vpbl.pbl_vbase[i].pa_high = cpu_to_le32((u32)((((u64)vpbl.pbl_pbase)>>32))); | ||
421 | nesfmr->root_vpbl.leaf_vpbl[i] = vpbl; | ||
422 | 293 | ||
423 | nes_debug(NES_DBG_MR, "pbase_low=0x%x, pbase_high=0x%x, vpbl=%p\n", | ||
424 | nesfmr->root_vpbl.pbl_vbase[i].pa_low, | ||
425 | nesfmr->root_vpbl.pbl_vbase[i].pa_high, | ||
426 | &nesfmr->root_vpbl.leaf_vpbl[i]); | ||
427 | } | ||
428 | } | ||
429 | nesfmr->ib_qp = NULL; | ||
430 | nesfmr->access_rights =0; | ||
431 | 294 | ||
432 | stag = stag_index << 8; | ||
433 | stag |= driver_key; | ||
434 | stag += (u32)stag_key; | ||
435 | |||
436 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | ||
437 | cqp_request = nes_get_cqp_request(nesdev); | 295 | cqp_request = nes_get_cqp_request(nesdev); |
438 | if (cqp_request == NULL) { | 296 | if (cqp_request == NULL) { |
439 | nes_debug(NES_DBG_MR, "Failed to get a cqp_request.\n"); | 297 | nes_debug(NES_DBG_MR, "Failed to get a cqp_request.\n"); |
440 | ret = -ENOMEM; | 298 | return -ENOMEM; |
441 | goto failed_leaf_vpbl_pages_alloc; | ||
442 | } | 299 | } |
300 | nes_debug(NES_DBG_MR, "alloc_fast_reg_mr: page_count = %d, " | ||
301 | "region_length = %llu\n", | ||
302 | page_count, region_length); | ||
443 | cqp_request->waiting = 1; | 303 | cqp_request->waiting = 1; |
444 | cqp_wqe = &cqp_request->cqp_wqe; | 304 | cqp_wqe = &cqp_request->cqp_wqe; |
445 | 305 | ||
446 | nes_debug(NES_DBG_MR, "Registering STag 0x%08X, index = 0x%08X\n", | 306 | spin_lock_irqsave(&nesadapter->pbl_lock, flags); |
447 | stag, stag_index); | 307 | if (nesadapter->free_4kpbl > 0) { |
448 | 308 | nesadapter->free_4kpbl--; | |
449 | opcode = NES_CQP_ALLOCATE_STAG | NES_CQP_STAG_VA_TO | NES_CQP_STAG_MR; | 309 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); |
450 | 310 | } else { | |
451 | if (nesfmr->nesmr.pbl_4k == 1) | 311 | /* No 4kpbl's available: */ |
452 | opcode |= NES_CQP_STAG_PBL_BLK_SIZE; | 312 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); |
453 | 313 | nes_debug(NES_DBG_MR, "Out of Pbls\n"); | |
454 | if (ibmr_access_flags & IB_ACCESS_REMOTE_WRITE) { | 314 | nes_free_cqp_request(nesdev, cqp_request); |
455 | opcode |= NES_CQP_STAG_RIGHTS_REMOTE_WRITE | | 315 | return -ENOMEM; |
456 | NES_CQP_STAG_RIGHTS_LOCAL_WRITE | NES_CQP_STAG_REM_ACC_EN; | ||
457 | nesfmr->access_rights |= | ||
458 | NES_CQP_STAG_RIGHTS_REMOTE_WRITE | NES_CQP_STAG_RIGHTS_LOCAL_WRITE | | ||
459 | NES_CQP_STAG_REM_ACC_EN; | ||
460 | } | 316 | } |
461 | 317 | ||
462 | if (ibmr_access_flags & IB_ACCESS_REMOTE_READ) { | 318 | opcode = NES_CQP_ALLOCATE_STAG | NES_CQP_STAG_MR | |
463 | opcode |= NES_CQP_STAG_RIGHTS_REMOTE_READ | | 319 | NES_CQP_STAG_PBL_BLK_SIZE | NES_CQP_STAG_VA_TO | |
464 | NES_CQP_STAG_RIGHTS_LOCAL_READ | NES_CQP_STAG_REM_ACC_EN; | 320 | NES_CQP_STAG_REM_ACC_EN; |
465 | nesfmr->access_rights |= | 321 | /* |
466 | NES_CQP_STAG_RIGHTS_REMOTE_READ | NES_CQP_STAG_RIGHTS_LOCAL_READ | | 322 | * The current OFED API does not support the zero based TO option. |
467 | NES_CQP_STAG_REM_ACC_EN; | 323 | * If added then need to changed the NES_CQP_STAG_VA* option. Also, |
468 | } | 324 | * the API does not support that ability to have the MR set for local |
325 | * access only when created and not allow the SQ op to override. Given | ||
326 | * this the remote enable must be set here. | ||
327 | */ | ||
469 | 328 | ||
470 | nes_fill_init_cqp_wqe(cqp_wqe, nesdev); | 329 | nes_fill_init_cqp_wqe(cqp_wqe, nesdev); |
471 | set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, opcode); | 330 | set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, opcode); |
472 | set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_LEN_HIGH_PD_IDX, (nespd->pd_id & 0x00007fff)); | 331 | set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_BLK_COUNT_IDX, 1); |
473 | set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_STAG_IDX, stag); | ||
474 | 332 | ||
475 | cqp_wqe->wqe_words[NES_CQP_STAG_WQE_PBL_BLK_COUNT_IDX] = | 333 | cqp_wqe->wqe_words[NES_CQP_STAG_WQE_LEN_HIGH_PD_IDX] = |
476 | cpu_to_le32((nesfmr->nesmr.pbls_used>1) ? | 334 | cpu_to_le32((u32)(region_length >> 8) & 0xff000000); |
477 | (nesfmr->nesmr.pbls_used-1) : nesfmr->nesmr.pbls_used); | 335 | cqp_wqe->wqe_words[NES_CQP_STAG_WQE_LEN_HIGH_PD_IDX] |= |
336 | cpu_to_le32(nespd->pd_id & 0x00007fff); | ||
337 | |||
338 | set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_STAG_IDX, stag); | ||
339 | set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_VA_LOW_IDX, 0); | ||
340 | set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_LEN_LOW_IDX, 0); | ||
341 | set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PA_LOW_IDX, 0); | ||
342 | set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_LEN_IDX, (page_count * 8)); | ||
343 | cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_STAG_PBL_BLK_SIZE); | ||
344 | barrier(); | ||
478 | 345 | ||
479 | atomic_set(&cqp_request->refcount, 2); | 346 | atomic_set(&cqp_request->refcount, 2); |
480 | nes_post_cqp_request(nesdev, cqp_request); | 347 | nes_post_cqp_request(nesdev, cqp_request); |
481 | 348 | ||
482 | /* Wait for CQP */ | 349 | /* Wait for CQP */ |
483 | ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0), | 350 | ret = wait_event_timeout(cqp_request->waitq, |
484 | NES_EVENT_TIMEOUT); | 351 | (0 != cqp_request->request_done), |
485 | nes_debug(NES_DBG_MR, "Register STag 0x%08X completed, wait_event_timeout ret = %u," | 352 | NES_EVENT_TIMEOUT); |
486 | " CQP Major:Minor codes = 0x%04X:0x%04X.\n", | 353 | |
487 | stag, ret, cqp_request->major_code, cqp_request->minor_code); | 354 | nes_debug(NES_DBG_MR, "Allocate STag 0x%08X completed, " |
488 | 355 | "wait_event_timeout ret = %u, CQP Major:Minor codes = " | |
489 | if ((!ret) || (cqp_request->major_code)) { | 356 | "0x%04X:0x%04X.\n", stag, ret, cqp_request->major_code, |
490 | nes_put_cqp_request(nesdev, cqp_request); | 357 | cqp_request->minor_code); |
491 | ret = (!ret) ? -ETIME : -EIO; | 358 | major_code = cqp_request->major_code; |
492 | goto failed_leaf_vpbl_pages_alloc; | ||
493 | } | ||
494 | nes_put_cqp_request(nesdev, cqp_request); | 359 | nes_put_cqp_request(nesdev, cqp_request); |
495 | nesfmr->nesmr.ibfmr.lkey = stag; | ||
496 | nesfmr->nesmr.ibfmr.rkey = stag; | ||
497 | nesfmr->attr = *ibfmr_attr; | ||
498 | |||
499 | return &nesfmr->nesmr.ibfmr; | ||
500 | |||
501 | failed_leaf_vpbl_pages_alloc: | ||
502 | /* unroll all allocated pages */ | ||
503 | for (i=0; i<nesfmr->leaf_pbl_cnt; i++) { | ||
504 | if (nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase) { | ||
505 | pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase, | ||
506 | nesfmr->root_vpbl.leaf_vpbl[i].pbl_pbase); | ||
507 | } | ||
508 | } | ||
509 | if (nesfmr->root_vpbl.leaf_vpbl) | ||
510 | kfree(nesfmr->root_vpbl.leaf_vpbl); | ||
511 | |||
512 | failed_leaf_vpbl_alloc: | ||
513 | if (nesfmr->leaf_pbl_cnt == 0) { | ||
514 | if (nesfmr->root_vpbl.pbl_vbase) | ||
515 | pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.pbl_vbase, | ||
516 | nesfmr->root_vpbl.pbl_pbase); | ||
517 | } else | ||
518 | pci_free_consistent(nesdev->pcidev, 8192, nesfmr->root_vpbl.pbl_vbase, | ||
519 | nesfmr->root_vpbl.pbl_pbase); | ||
520 | 360 | ||
521 | failed_vpbl_alloc: | 361 | if (!ret || major_code) { |
522 | if (nesfmr->nesmr.pbls_used != 0) { | ||
523 | spin_lock_irqsave(&nesadapter->pbl_lock, flags); | 362 | spin_lock_irqsave(&nesadapter->pbl_lock, flags); |
524 | if (nesfmr->nesmr.pbl_4k) | 363 | nesadapter->free_4kpbl++; |
525 | nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used; | ||
526 | else | ||
527 | nesadapter->free_256pbl += nesfmr->nesmr.pbls_used; | ||
528 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | 364 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); |
529 | } | 365 | } |
530 | 366 | ||
531 | failed_vpbl_avail: | 367 | if (!ret) |
532 | kfree(nesfmr); | 368 | return -ETIME; |
533 | 369 | else if (major_code) | |
534 | failed_fmr_alloc: | 370 | return -EIO; |
535 | nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); | 371 | return 0; |
536 | |||
537 | failed_resource_alloc: | ||
538 | return ERR_PTR(ret); | ||
539 | } | 372 | } |
540 | 373 | ||
541 | 374 | /* | |
542 | /** | 375 | * nes_alloc_fast_reg_mr |
543 | * nes_dealloc_fmr | ||
544 | */ | 376 | */ |
545 | static int nes_dealloc_fmr(struct ib_fmr *ibfmr) | 377 | struct ib_mr *nes_alloc_fast_reg_mr(struct ib_pd *ibpd, int max_page_list_len) |
546 | { | 378 | { |
547 | unsigned long flags; | 379 | struct nes_pd *nespd = to_nespd(ibpd); |
548 | struct nes_mr *nesmr = to_nesmr_from_ibfmr(ibfmr); | 380 | struct nes_vnic *nesvnic = to_nesvnic(ibpd->device); |
549 | struct nes_fmr *nesfmr = to_nesfmr(nesmr); | ||
550 | struct nes_vnic *nesvnic = to_nesvnic(ibfmr->device); | ||
551 | struct nes_device *nesdev = nesvnic->nesdev; | 381 | struct nes_device *nesdev = nesvnic->nesdev; |
552 | struct nes_adapter *nesadapter = nesdev->nesadapter; | 382 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
553 | int i = 0; | ||
554 | int rc; | ||
555 | 383 | ||
556 | /* free the resources */ | 384 | u32 next_stag_index; |
557 | if (nesfmr->leaf_pbl_cnt == 0) { | 385 | u8 stag_key = 0; |
558 | /* single PBL case */ | 386 | u32 driver_key = 0; |
559 | if (nesfmr->root_vpbl.pbl_vbase) | 387 | int err = 0; |
560 | pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.pbl_vbase, | 388 | u32 stag_index = 0; |
561 | nesfmr->root_vpbl.pbl_pbase); | 389 | struct nes_mr *nesmr; |
562 | } else { | 390 | u32 stag; |
563 | for (i = 0; i < nesfmr->leaf_pbl_cnt; i++) { | 391 | int ret; |
564 | pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase, | 392 | struct ib_mr *ibmr; |
565 | nesfmr->root_vpbl.leaf_vpbl[i].pbl_pbase); | 393 | /* |
566 | } | 394 | * Note: Set to always use a fixed length single page entry PBL. This is to allow |
567 | kfree(nesfmr->root_vpbl.leaf_vpbl); | 395 | * for the fast_reg_mr operation to always know the size of the PBL. |
568 | pci_free_consistent(nesdev->pcidev, 8192, nesfmr->root_vpbl.pbl_vbase, | 396 | */ |
569 | nesfmr->root_vpbl.pbl_pbase); | 397 | if (max_page_list_len > (NES_4K_PBL_CHUNK_SIZE / sizeof(u64))) |
570 | } | 398 | return ERR_PTR(-E2BIG); |
571 | nesmr->ibmw.device = ibfmr->device; | ||
572 | nesmr->ibmw.pd = ibfmr->pd; | ||
573 | nesmr->ibmw.rkey = ibfmr->rkey; | ||
574 | nesmr->ibmw.uobject = NULL; | ||
575 | 399 | ||
576 | rc = nes_dealloc_mw(&nesmr->ibmw); | 400 | get_random_bytes(&next_stag_index, sizeof(next_stag_index)); |
401 | stag_key = (u8)next_stag_index; | ||
402 | next_stag_index >>= 8; | ||
403 | next_stag_index %= nesadapter->max_mr; | ||
577 | 404 | ||
578 | if ((rc == 0) && (nesfmr->nesmr.pbls_used != 0)) { | 405 | err = nes_alloc_resource(nesadapter, nesadapter->allocated_mrs, |
579 | spin_lock_irqsave(&nesadapter->pbl_lock, flags); | 406 | nesadapter->max_mr, &stag_index, |
580 | if (nesfmr->nesmr.pbl_4k) { | 407 | &next_stag_index); |
581 | nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used; | 408 | if (err) |
582 | WARN_ON(nesadapter->free_4kpbl > nesadapter->max_4kpbl); | 409 | return ERR_PTR(err); |
583 | } else { | 410 | |
584 | nesadapter->free_256pbl += nesfmr->nesmr.pbls_used; | 411 | nesmr = kzalloc(sizeof(*nesmr), GFP_KERNEL); |
585 | WARN_ON(nesadapter->free_256pbl > nesadapter->max_256pbl); | 412 | if (!nesmr) { |
586 | } | 413 | nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); |
587 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | 414 | return ERR_PTR(-ENOMEM); |
588 | } | 415 | } |
589 | 416 | ||
590 | return rc; | 417 | stag = stag_index << 8; |
591 | } | 418 | stag |= driver_key; |
419 | stag += (u32)stag_key; | ||
592 | 420 | ||
421 | nes_debug(NES_DBG_MR, "Allocating STag 0x%08X index = 0x%08X\n", | ||
422 | stag, stag_index); | ||
593 | 423 | ||
594 | /** | 424 | ret = alloc_fast_reg_mr(nesdev, nespd, stag, max_page_list_len); |
595 | * nes_map_phys_fmr | 425 | |
426 | if (ret == 0) { | ||
427 | nesmr->ibmr.rkey = stag; | ||
428 | nesmr->ibmr.lkey = stag; | ||
429 | nesmr->mode = IWNES_MEMREG_TYPE_FMEM; | ||
430 | ibmr = &nesmr->ibmr; | ||
431 | } else { | ||
432 | kfree(nesmr); | ||
433 | nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); | ||
434 | ibmr = ERR_PTR(-ENOMEM); | ||
435 | } | ||
436 | return ibmr; | ||
437 | } | ||
438 | |||
439 | /* | ||
440 | * nes_alloc_fast_reg_page_list | ||
596 | */ | 441 | */ |
597 | static int nes_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list, | 442 | static struct ib_fast_reg_page_list *nes_alloc_fast_reg_page_list( |
598 | int list_len, u64 iova) | 443 | struct ib_device *ibdev, |
444 | int page_list_len) | ||
599 | { | 445 | { |
600 | return 0; | 446 | struct nes_vnic *nesvnic = to_nesvnic(ibdev); |
601 | } | 447 | struct nes_device *nesdev = nesvnic->nesdev; |
448 | struct ib_fast_reg_page_list *pifrpl; | ||
449 | struct nes_ib_fast_reg_page_list *pnesfrpl; | ||
602 | 450 | ||
451 | if (page_list_len > (NES_4K_PBL_CHUNK_SIZE / sizeof(u64))) | ||
452 | return ERR_PTR(-E2BIG); | ||
453 | /* | ||
454 | * Allocate the ib_fast_reg_page_list structure, the | ||
455 | * nes_fast_bpl structure, and the PLB table. | ||
456 | */ | ||
457 | pnesfrpl = kmalloc(sizeof(struct nes_ib_fast_reg_page_list) + | ||
458 | page_list_len * sizeof(u64), GFP_KERNEL); | ||
459 | |||
460 | if (!pnesfrpl) | ||
461 | return ERR_PTR(-ENOMEM); | ||
603 | 462 | ||
604 | /** | 463 | pifrpl = &pnesfrpl->ibfrpl; |
605 | * nes_unmap_frm | 464 | pifrpl->page_list = &pnesfrpl->pbl; |
465 | pifrpl->max_page_list_len = page_list_len; | ||
466 | /* | ||
467 | * Allocate the WQE PBL | ||
468 | */ | ||
469 | pnesfrpl->nes_wqe_pbl.kva = pci_alloc_consistent(nesdev->pcidev, | ||
470 | page_list_len * sizeof(u64), | ||
471 | &pnesfrpl->nes_wqe_pbl.paddr); | ||
472 | |||
473 | if (!pnesfrpl->nes_wqe_pbl.kva) { | ||
474 | kfree(pnesfrpl); | ||
475 | return ERR_PTR(-ENOMEM); | ||
476 | } | ||
477 | nes_debug(NES_DBG_MR, "nes_alloc_fast_reg_pbl: nes_frpl = %p, " | ||
478 | "ibfrpl = %p, ibfrpl.page_list = %p, pbl.kva = %p, " | ||
479 | "pbl.paddr= %p\n", pnesfrpl, &pnesfrpl->ibfrpl, | ||
480 | pnesfrpl->ibfrpl.page_list, pnesfrpl->nes_wqe_pbl.kva, | ||
481 | (void *)pnesfrpl->nes_wqe_pbl.paddr); | ||
482 | |||
483 | return pifrpl; | ||
484 | } | ||
485 | |||
486 | /* | ||
487 | * nes_free_fast_reg_page_list | ||
606 | */ | 488 | */ |
607 | static int nes_unmap_fmr(struct list_head *ibfmr_list) | 489 | static void nes_free_fast_reg_page_list(struct ib_fast_reg_page_list *pifrpl) |
608 | { | 490 | { |
609 | return 0; | 491 | struct nes_vnic *nesvnic = to_nesvnic(pifrpl->device); |
492 | struct nes_device *nesdev = nesvnic->nesdev; | ||
493 | struct nes_ib_fast_reg_page_list *pnesfrpl; | ||
494 | |||
495 | pnesfrpl = container_of(pifrpl, struct nes_ib_fast_reg_page_list, ibfrpl); | ||
496 | /* | ||
497 | * Free the WQE PBL. | ||
498 | */ | ||
499 | pci_free_consistent(nesdev->pcidev, | ||
500 | pifrpl->max_page_list_len * sizeof(u64), | ||
501 | pnesfrpl->nes_wqe_pbl.kva, | ||
502 | pnesfrpl->nes_wqe_pbl.paddr); | ||
503 | /* | ||
504 | * Free the PBL structure | ||
505 | */ | ||
506 | kfree(pnesfrpl); | ||
610 | } | 507 | } |
611 | 508 | ||
612 | |||
613 | |||
614 | /** | 509 | /** |
615 | * nes_query_device | 510 | * nes_query_device |
616 | */ | 511 | */ |
@@ -633,23 +528,23 @@ static int nes_query_device(struct ib_device *ibdev, struct ib_device_attr *prop | |||
633 | props->max_qp_wr = nesdev->nesadapter->max_qp_wr - 2; | 528 | props->max_qp_wr = nesdev->nesadapter->max_qp_wr - 2; |
634 | props->max_sge = nesdev->nesadapter->max_sge; | 529 | props->max_sge = nesdev->nesadapter->max_sge; |
635 | props->max_cq = nesibdev->max_cq; | 530 | props->max_cq = nesibdev->max_cq; |
636 | props->max_cqe = nesdev->nesadapter->max_cqe - 1; | 531 | props->max_cqe = nesdev->nesadapter->max_cqe; |
637 | props->max_mr = nesibdev->max_mr; | 532 | props->max_mr = nesibdev->max_mr; |
638 | props->max_mw = nesibdev->max_mr; | 533 | props->max_mw = nesibdev->max_mr; |
639 | props->max_pd = nesibdev->max_pd; | 534 | props->max_pd = nesibdev->max_pd; |
640 | props->max_sge_rd = 1; | 535 | props->max_sge_rd = 1; |
641 | switch (nesdev->nesadapter->max_irrq_wr) { | 536 | switch (nesdev->nesadapter->max_irrq_wr) { |
642 | case 0: | 537 | case 0: |
643 | props->max_qp_rd_atom = 1; | 538 | props->max_qp_rd_atom = 2; |
644 | break; | 539 | break; |
645 | case 1: | 540 | case 1: |
646 | props->max_qp_rd_atom = 4; | 541 | props->max_qp_rd_atom = 8; |
647 | break; | 542 | break; |
648 | case 2: | 543 | case 2: |
649 | props->max_qp_rd_atom = 16; | 544 | props->max_qp_rd_atom = 32; |
650 | break; | 545 | break; |
651 | case 3: | 546 | case 3: |
652 | props->max_qp_rd_atom = 32; | 547 | props->max_qp_rd_atom = 64; |
653 | break; | 548 | break; |
654 | default: | 549 | default: |
655 | props->max_qp_rd_atom = 0; | 550 | props->max_qp_rd_atom = 0; |
@@ -1121,6 +1016,7 @@ static int nes_setup_virt_qp(struct nes_qp *nesqp, struct nes_pbl *nespbl, | |||
1121 | kunmap(nesqp->page); | 1016 | kunmap(nesqp->page); |
1122 | return -ENOMEM; | 1017 | return -ENOMEM; |
1123 | } | 1018 | } |
1019 | nesqp->sq_kmapped = 1; | ||
1124 | nesqp->hwqp.q2_vbase = mem; | 1020 | nesqp->hwqp.q2_vbase = mem; |
1125 | mem += 256; | 1021 | mem += 256; |
1126 | memset(nesqp->hwqp.q2_vbase, 0, 256); | 1022 | memset(nesqp->hwqp.q2_vbase, 0, 256); |
@@ -1198,7 +1094,10 @@ static inline void nes_free_qp_mem(struct nes_device *nesdev, | |||
1198 | pci_free_consistent(nesdev->pcidev, nesqp->qp_mem_size, nesqp->hwqp.q2_vbase, nesqp->hwqp.q2_pbase); | 1094 | pci_free_consistent(nesdev->pcidev, nesqp->qp_mem_size, nesqp->hwqp.q2_vbase, nesqp->hwqp.q2_pbase); |
1199 | pci_free_consistent(nesdev->pcidev, 256, nesqp->pbl_vbase, nesqp->pbl_pbase ); | 1095 | pci_free_consistent(nesdev->pcidev, 256, nesqp->pbl_vbase, nesqp->pbl_pbase ); |
1200 | nesqp->pbl_vbase = NULL; | 1096 | nesqp->pbl_vbase = NULL; |
1201 | kunmap(nesqp->page); | 1097 | if (nesqp->sq_kmapped) { |
1098 | nesqp->sq_kmapped = 0; | ||
1099 | kunmap(nesqp->page); | ||
1100 | } | ||
1202 | } | 1101 | } |
1203 | } | 1102 | } |
1204 | 1103 | ||
@@ -1425,6 +1324,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, | |||
1425 | nesqp->nesqp_context->aeq_token_low = cpu_to_le32((u32)((unsigned long)(nesqp))); | 1324 | nesqp->nesqp_context->aeq_token_low = cpu_to_le32((u32)((unsigned long)(nesqp))); |
1426 | nesqp->nesqp_context->aeq_token_high = cpu_to_le32((u32)(upper_32_bits((unsigned long)(nesqp)))); | 1325 | nesqp->nesqp_context->aeq_token_high = cpu_to_le32((u32)(upper_32_bits((unsigned long)(nesqp)))); |
1427 | nesqp->nesqp_context->ird_ord_sizes = cpu_to_le32(NES_QPCONTEXT_ORDIRD_ALSMM | | 1326 | nesqp->nesqp_context->ird_ord_sizes = cpu_to_le32(NES_QPCONTEXT_ORDIRD_ALSMM | |
1327 | NES_QPCONTEXT_ORDIRD_AAH | | ||
1428 | ((((u32)nesadapter->max_irrq_wr) << | 1328 | ((((u32)nesadapter->max_irrq_wr) << |
1429 | NES_QPCONTEXT_ORDIRD_IRDSIZE_SHIFT) & NES_QPCONTEXT_ORDIRD_IRDSIZE_MASK)); | 1329 | NES_QPCONTEXT_ORDIRD_IRDSIZE_SHIFT) & NES_QPCONTEXT_ORDIRD_IRDSIZE_MASK)); |
1430 | if (disable_mpa_crc) { | 1330 | if (disable_mpa_crc) { |
@@ -1504,8 +1404,6 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, | |||
1504 | nes_debug(NES_DBG_QP, "QP%u structure located @%p.Size = %u.\n", | 1404 | nes_debug(NES_DBG_QP, "QP%u structure located @%p.Size = %u.\n", |
1505 | nesqp->hwqp.qp_id, nesqp, (u32)sizeof(*nesqp)); | 1405 | nesqp->hwqp.qp_id, nesqp, (u32)sizeof(*nesqp)); |
1506 | spin_lock_init(&nesqp->lock); | 1406 | spin_lock_init(&nesqp->lock); |
1507 | init_waitqueue_head(&nesqp->state_waitq); | ||
1508 | init_waitqueue_head(&nesqp->kick_waitq); | ||
1509 | nes_add_ref(&nesqp->ibqp); | 1407 | nes_add_ref(&nesqp->ibqp); |
1510 | break; | 1408 | break; |
1511 | default: | 1409 | default: |
@@ -1513,6 +1411,8 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, | |||
1513 | return ERR_PTR(-EINVAL); | 1411 | return ERR_PTR(-EINVAL); |
1514 | } | 1412 | } |
1515 | 1413 | ||
1414 | nesqp->sig_all = (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR); | ||
1415 | |||
1516 | /* update the QP table */ | 1416 | /* update the QP table */ |
1517 | nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp; | 1417 | nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp; |
1518 | nes_debug(NES_DBG_QP, "netdev refcnt=%u\n", | 1418 | nes_debug(NES_DBG_QP, "netdev refcnt=%u\n", |
@@ -1607,8 +1507,10 @@ static int nes_destroy_qp(struct ib_qp *ibqp) | |||
1607 | nes_ucontext->first_free_wq = nesqp->mmap_sq_db_index; | 1507 | nes_ucontext->first_free_wq = nesqp->mmap_sq_db_index; |
1608 | } | 1508 | } |
1609 | } | 1509 | } |
1610 | if (nesqp->pbl_pbase) | 1510 | if (nesqp->pbl_pbase && nesqp->sq_kmapped) { |
1511 | nesqp->sq_kmapped = 0; | ||
1611 | kunmap(nesqp->page); | 1512 | kunmap(nesqp->page); |
1513 | } | ||
1612 | } else { | 1514 | } else { |
1613 | /* Clean any pending completions from the cq(s) */ | 1515 | /* Clean any pending completions from the cq(s) */ |
1614 | if (nesqp->nesscq) | 1516 | if (nesqp->nesscq) |
@@ -1649,6 +1551,9 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, | |||
1649 | unsigned long flags; | 1551 | unsigned long flags; |
1650 | int ret; | 1552 | int ret; |
1651 | 1553 | ||
1554 | if (entries > nesadapter->max_cqe) | ||
1555 | return ERR_PTR(-EINVAL); | ||
1556 | |||
1652 | err = nes_alloc_resource(nesadapter, nesadapter->allocated_cqs, | 1557 | err = nes_alloc_resource(nesadapter, nesadapter->allocated_cqs, |
1653 | nesadapter->max_cq, &cq_num, &nesadapter->next_cq); | 1558 | nesadapter->max_cq, &cq_num, &nesadapter->next_cq); |
1654 | if (err) { | 1559 | if (err) { |
@@ -2606,9 +2511,6 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
2606 | stag = stag_index << 8; | 2511 | stag = stag_index << 8; |
2607 | stag |= driver_key; | 2512 | stag |= driver_key; |
2608 | stag += (u32)stag_key; | 2513 | stag += (u32)stag_key; |
2609 | if (stag == 0) { | ||
2610 | stag = 1; | ||
2611 | } | ||
2612 | 2514 | ||
2613 | iova_start = virt; | 2515 | iova_start = virt; |
2614 | /* Make the leaf PBL the root if only one PBL */ | 2516 | /* Make the leaf PBL the root if only one PBL */ |
@@ -2919,11 +2821,10 @@ static int nes_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | |||
2919 | attr->cap.max_send_wr = nesqp->hwqp.sq_size; | 2821 | attr->cap.max_send_wr = nesqp->hwqp.sq_size; |
2920 | attr->cap.max_recv_wr = nesqp->hwqp.rq_size; | 2822 | attr->cap.max_recv_wr = nesqp->hwqp.rq_size; |
2921 | attr->cap.max_recv_sge = 1; | 2823 | attr->cap.max_recv_sge = 1; |
2922 | if (nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) { | 2824 | if (nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) |
2923 | init_attr->cap.max_inline_data = 0; | 2825 | attr->cap.max_inline_data = 0; |
2924 | } else { | 2826 | else |
2925 | init_attr->cap.max_inline_data = 64; | 2827 | attr->cap.max_inline_data = 64; |
2926 | } | ||
2927 | 2828 | ||
2928 | init_attr->event_handler = nesqp->ibqp.event_handler; | 2829 | init_attr->event_handler = nesqp->ibqp.event_handler; |
2929 | init_attr->qp_context = nesqp->ibqp.qp_context; | 2830 | init_attr->qp_context = nesqp->ibqp.qp_context; |
@@ -3109,7 +3010,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | |||
3109 | " already done based on hw state.\n", | 3010 | " already done based on hw state.\n", |
3110 | nesqp->hwqp.qp_id); | 3011 | nesqp->hwqp.qp_id); |
3111 | issue_modify_qp = 0; | 3012 | issue_modify_qp = 0; |
3112 | nesqp->in_disconnect = 0; | ||
3113 | } | 3013 | } |
3114 | switch (nesqp->hw_iwarp_state) { | 3014 | switch (nesqp->hw_iwarp_state) { |
3115 | case NES_AEQE_IWARP_STATE_CLOSING: | 3015 | case NES_AEQE_IWARP_STATE_CLOSING: |
@@ -3122,7 +3022,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | |||
3122 | break; | 3022 | break; |
3123 | default: | 3023 | default: |
3124 | next_iwarp_state = NES_CQP_QP_IWARP_STATE_CLOSING; | 3024 | next_iwarp_state = NES_CQP_QP_IWARP_STATE_CLOSING; |
3125 | nesqp->in_disconnect = 1; | ||
3126 | nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING; | 3025 | nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING; |
3127 | break; | 3026 | break; |
3128 | } | 3027 | } |
@@ -3139,7 +3038,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | |||
3139 | next_iwarp_state = NES_CQP_QP_IWARP_STATE_TERMINATE; | 3038 | next_iwarp_state = NES_CQP_QP_IWARP_STATE_TERMINATE; |
3140 | nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_TERMINATE; | 3039 | nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_TERMINATE; |
3141 | issue_modify_qp = 1; | 3040 | issue_modify_qp = 1; |
3142 | nesqp->in_disconnect = 1; | ||
3143 | break; | 3041 | break; |
3144 | case IB_QPS_ERR: | 3042 | case IB_QPS_ERR: |
3145 | case IB_QPS_RESET: | 3043 | case IB_QPS_RESET: |
@@ -3162,7 +3060,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | |||
3162 | if ((nesqp->hw_tcp_state > NES_AEQE_TCP_STATE_CLOSED) && | 3060 | if ((nesqp->hw_tcp_state > NES_AEQE_TCP_STATE_CLOSED) && |
3163 | (nesqp->hw_tcp_state != NES_AEQE_TCP_STATE_TIME_WAIT)) { | 3061 | (nesqp->hw_tcp_state != NES_AEQE_TCP_STATE_TIME_WAIT)) { |
3164 | next_iwarp_state |= NES_CQP_QP_RESET; | 3062 | next_iwarp_state |= NES_CQP_QP_RESET; |
3165 | nesqp->in_disconnect = 1; | ||
3166 | } else { | 3063 | } else { |
3167 | nes_debug(NES_DBG_MOD_QP, "QP%u NOT setting NES_CQP_QP_RESET since TCP state = %u\n", | 3064 | nes_debug(NES_DBG_MOD_QP, "QP%u NOT setting NES_CQP_QP_RESET since TCP state = %u\n", |
3168 | nesqp->hwqp.qp_id, nesqp->hw_tcp_state); | 3065 | nesqp->hwqp.qp_id, nesqp->hw_tcp_state); |
@@ -3373,21 +3270,17 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, | |||
3373 | struct nes_device *nesdev = nesvnic->nesdev; | 3270 | struct nes_device *nesdev = nesvnic->nesdev; |
3374 | struct nes_qp *nesqp = to_nesqp(ibqp); | 3271 | struct nes_qp *nesqp = to_nesqp(ibqp); |
3375 | struct nes_hw_qp_wqe *wqe; | 3272 | struct nes_hw_qp_wqe *wqe; |
3376 | int err; | 3273 | int err = 0; |
3377 | u32 qsize = nesqp->hwqp.sq_size; | 3274 | u32 qsize = nesqp->hwqp.sq_size; |
3378 | u32 head; | 3275 | u32 head; |
3379 | u32 wqe_misc; | 3276 | u32 wqe_misc = 0; |
3380 | u32 wqe_count; | 3277 | u32 wqe_count = 0; |
3381 | u32 counter; | 3278 | u32 counter; |
3382 | u32 total_payload_length; | ||
3383 | |||
3384 | err = 0; | ||
3385 | wqe_misc = 0; | ||
3386 | wqe_count = 0; | ||
3387 | total_payload_length = 0; | ||
3388 | 3279 | ||
3389 | if (nesqp->ibqp_state > IB_QPS_RTS) | 3280 | if (nesqp->ibqp_state > IB_QPS_RTS) { |
3390 | return -EINVAL; | 3281 | err = -EINVAL; |
3282 | goto out; | ||
3283 | } | ||
3391 | 3284 | ||
3392 | spin_lock_irqsave(&nesqp->lock, flags); | 3285 | spin_lock_irqsave(&nesqp->lock, flags); |
3393 | 3286 | ||
@@ -3402,7 +3295,7 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, | |||
3402 | 3295 | ||
3403 | /* Check for SQ overflow */ | 3296 | /* Check for SQ overflow */ |
3404 | if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) { | 3297 | if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) { |
3405 | err = -EINVAL; | 3298 | err = -ENOMEM; |
3406 | break; | 3299 | break; |
3407 | } | 3300 | } |
3408 | 3301 | ||
@@ -3413,94 +3306,208 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, | |||
3413 | u64temp = (u64)(ib_wr->wr_id); | 3306 | u64temp = (u64)(ib_wr->wr_id); |
3414 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX, | 3307 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX, |
3415 | u64temp); | 3308 | u64temp); |
3416 | switch (ib_wr->opcode) { | 3309 | switch (ib_wr->opcode) { |
3417 | case IB_WR_SEND: | 3310 | case IB_WR_SEND: |
3418 | if (ib_wr->send_flags & IB_SEND_SOLICITED) { | 3311 | case IB_WR_SEND_WITH_INV: |
3419 | wqe_misc = NES_IWARP_SQ_OP_SENDSE; | 3312 | if (IB_WR_SEND == ib_wr->opcode) { |
3420 | } else { | 3313 | if (ib_wr->send_flags & IB_SEND_SOLICITED) |
3421 | wqe_misc = NES_IWARP_SQ_OP_SEND; | 3314 | wqe_misc = NES_IWARP_SQ_OP_SENDSE; |
3422 | } | 3315 | else |
3423 | if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { | 3316 | wqe_misc = NES_IWARP_SQ_OP_SEND; |
3424 | err = -EINVAL; | 3317 | } else { |
3425 | break; | 3318 | if (ib_wr->send_flags & IB_SEND_SOLICITED) |
3426 | } | 3319 | wqe_misc = NES_IWARP_SQ_OP_SENDSEINV; |
3427 | if (ib_wr->send_flags & IB_SEND_FENCE) { | 3320 | else |
3428 | wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; | 3321 | wqe_misc = NES_IWARP_SQ_OP_SENDINV; |
3429 | } | ||
3430 | if ((ib_wr->send_flags & IB_SEND_INLINE) && | ||
3431 | ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) && | ||
3432 | (ib_wr->sg_list[0].length <= 64)) { | ||
3433 | memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX], | ||
3434 | (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length); | ||
3435 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX, | ||
3436 | ib_wr->sg_list[0].length); | ||
3437 | wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA; | ||
3438 | } else { | ||
3439 | fill_wqe_sg_send(wqe, ib_wr, 1); | ||
3440 | } | ||
3441 | 3322 | ||
3442 | break; | 3323 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_INV_STAG_LOW_IDX, |
3443 | case IB_WR_RDMA_WRITE: | 3324 | ib_wr->ex.invalidate_rkey); |
3444 | wqe_misc = NES_IWARP_SQ_OP_RDMAW; | 3325 | } |
3445 | if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { | ||
3446 | nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=%u\n", | ||
3447 | ib_wr->num_sge, | ||
3448 | nesdev->nesadapter->max_sge); | ||
3449 | err = -EINVAL; | ||
3450 | break; | ||
3451 | } | ||
3452 | if (ib_wr->send_flags & IB_SEND_FENCE) { | ||
3453 | wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; | ||
3454 | } | ||
3455 | 3326 | ||
3456 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, | 3327 | if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { |
3457 | ib_wr->wr.rdma.rkey); | 3328 | err = -EINVAL; |
3458 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, | 3329 | break; |
3459 | ib_wr->wr.rdma.remote_addr); | ||
3460 | |||
3461 | if ((ib_wr->send_flags & IB_SEND_INLINE) && | ||
3462 | ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) && | ||
3463 | (ib_wr->sg_list[0].length <= 64)) { | ||
3464 | memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX], | ||
3465 | (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length); | ||
3466 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX, | ||
3467 | ib_wr->sg_list[0].length); | ||
3468 | wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA; | ||
3469 | } else { | ||
3470 | fill_wqe_sg_send(wqe, ib_wr, 1); | ||
3471 | } | ||
3472 | wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX] = | ||
3473 | wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]; | ||
3474 | break; | ||
3475 | case IB_WR_RDMA_READ: | ||
3476 | /* iWARP only supports 1 sge for RDMA reads */ | ||
3477 | if (ib_wr->num_sge > 1) { | ||
3478 | nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=1\n", | ||
3479 | ib_wr->num_sge); | ||
3480 | err = -EINVAL; | ||
3481 | break; | ||
3482 | } | ||
3483 | wqe_misc = NES_IWARP_SQ_OP_RDMAR; | ||
3484 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, | ||
3485 | ib_wr->wr.rdma.remote_addr); | ||
3486 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, | ||
3487 | ib_wr->wr.rdma.rkey); | ||
3488 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX, | ||
3489 | ib_wr->sg_list->length); | ||
3490 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_FRAG0_LOW_IDX, | ||
3491 | ib_wr->sg_list->addr); | ||
3492 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_STAG0_IDX, | ||
3493 | ib_wr->sg_list->lkey); | ||
3494 | break; | ||
3495 | default: | ||
3496 | /* error */ | ||
3497 | err = -EINVAL; | ||
3498 | break; | ||
3499 | } | 3330 | } |
3500 | 3331 | ||
3501 | if (ib_wr->send_flags & IB_SEND_SIGNALED) { | 3332 | if (ib_wr->send_flags & IB_SEND_FENCE) |
3502 | wqe_misc |= NES_IWARP_SQ_WQE_SIGNALED_COMPL; | 3333 | wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; |
3334 | |||
3335 | if ((ib_wr->send_flags & IB_SEND_INLINE) && | ||
3336 | ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) && | ||
3337 | (ib_wr->sg_list[0].length <= 64)) { | ||
3338 | memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX], | ||
3339 | (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length); | ||
3340 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX, | ||
3341 | ib_wr->sg_list[0].length); | ||
3342 | wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA; | ||
3343 | } else { | ||
3344 | fill_wqe_sg_send(wqe, ib_wr, 1); | ||
3345 | } | ||
3346 | |||
3347 | break; | ||
3348 | case IB_WR_RDMA_WRITE: | ||
3349 | wqe_misc = NES_IWARP_SQ_OP_RDMAW; | ||
3350 | if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { | ||
3351 | nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=%u\n", | ||
3352 | ib_wr->num_sge, nesdev->nesadapter->max_sge); | ||
3353 | err = -EINVAL; | ||
3354 | break; | ||
3355 | } | ||
3356 | |||
3357 | if (ib_wr->send_flags & IB_SEND_FENCE) | ||
3358 | wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; | ||
3359 | |||
3360 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, | ||
3361 | ib_wr->wr.rdma.rkey); | ||
3362 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, | ||
3363 | ib_wr->wr.rdma.remote_addr); | ||
3364 | |||
3365 | if ((ib_wr->send_flags & IB_SEND_INLINE) && | ||
3366 | ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) && | ||
3367 | (ib_wr->sg_list[0].length <= 64)) { | ||
3368 | memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX], | ||
3369 | (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length); | ||
3370 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX, | ||
3371 | ib_wr->sg_list[0].length); | ||
3372 | wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA; | ||
3373 | } else { | ||
3374 | fill_wqe_sg_send(wqe, ib_wr, 1); | ||
3375 | } | ||
3376 | |||
3377 | wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX] = | ||
3378 | wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]; | ||
3379 | break; | ||
3380 | case IB_WR_RDMA_READ: | ||
3381 | case IB_WR_RDMA_READ_WITH_INV: | ||
3382 | /* iWARP only supports 1 sge for RDMA reads */ | ||
3383 | if (ib_wr->num_sge > 1) { | ||
3384 | nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=1\n", | ||
3385 | ib_wr->num_sge); | ||
3386 | err = -EINVAL; | ||
3387 | break; | ||
3388 | } | ||
3389 | if (ib_wr->opcode == IB_WR_RDMA_READ) { | ||
3390 | wqe_misc = NES_IWARP_SQ_OP_RDMAR; | ||
3391 | } else { | ||
3392 | wqe_misc = NES_IWARP_SQ_OP_RDMAR_LOCINV; | ||
3393 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_INV_STAG_LOW_IDX, | ||
3394 | ib_wr->ex.invalidate_rkey); | ||
3395 | } | ||
3396 | |||
3397 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, | ||
3398 | ib_wr->wr.rdma.remote_addr); | ||
3399 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, | ||
3400 | ib_wr->wr.rdma.rkey); | ||
3401 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX, | ||
3402 | ib_wr->sg_list->length); | ||
3403 | set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_FRAG0_LOW_IDX, | ||
3404 | ib_wr->sg_list->addr); | ||
3405 | set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_STAG0_IDX, | ||
3406 | ib_wr->sg_list->lkey); | ||
3407 | break; | ||
3408 | case IB_WR_LOCAL_INV: | ||
3409 | wqe_misc = NES_IWARP_SQ_OP_LOCINV; | ||
3410 | set_wqe_32bit_value(wqe->wqe_words, | ||
3411 | NES_IWARP_SQ_LOCINV_WQE_INV_STAG_IDX, | ||
3412 | ib_wr->ex.invalidate_rkey); | ||
3413 | break; | ||
3414 | case IB_WR_FAST_REG_MR: | ||
3415 | { | ||
3416 | int i; | ||
3417 | int flags = ib_wr->wr.fast_reg.access_flags; | ||
3418 | struct nes_ib_fast_reg_page_list *pnesfrpl = | ||
3419 | container_of(ib_wr->wr.fast_reg.page_list, | ||
3420 | struct nes_ib_fast_reg_page_list, | ||
3421 | ibfrpl); | ||
3422 | u64 *src_page_list = pnesfrpl->ibfrpl.page_list; | ||
3423 | u64 *dst_page_list = pnesfrpl->nes_wqe_pbl.kva; | ||
3424 | |||
3425 | if (ib_wr->wr.fast_reg.page_list_len > | ||
3426 | (NES_4K_PBL_CHUNK_SIZE / sizeof(u64))) { | ||
3427 | nes_debug(NES_DBG_IW_TX, "SQ_FMR: bad page_list_len\n"); | ||
3428 | err = -EINVAL; | ||
3429 | break; | ||
3430 | } | ||
3431 | wqe_misc = NES_IWARP_SQ_OP_FAST_REG; | ||
3432 | set_wqe_64bit_value(wqe->wqe_words, | ||
3433 | NES_IWARP_SQ_FMR_WQE_VA_FBO_LOW_IDX, | ||
3434 | ib_wr->wr.fast_reg.iova_start); | ||
3435 | set_wqe_32bit_value(wqe->wqe_words, | ||
3436 | NES_IWARP_SQ_FMR_WQE_LENGTH_LOW_IDX, | ||
3437 | ib_wr->wr.fast_reg.length); | ||
3438 | set_wqe_32bit_value(wqe->wqe_words, | ||
3439 | NES_IWARP_SQ_FMR_WQE_MR_STAG_IDX, | ||
3440 | ib_wr->wr.fast_reg.rkey); | ||
3441 | /* Set page size: */ | ||
3442 | if (ib_wr->wr.fast_reg.page_shift == 12) { | ||
3443 | wqe_misc |= NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_4K; | ||
3444 | } else if (ib_wr->wr.fast_reg.page_shift == 21) { | ||
3445 | wqe_misc |= NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_2M; | ||
3446 | } else { | ||
3447 | nes_debug(NES_DBG_IW_TX, "Invalid page shift," | ||
3448 | " ib_wr=%u, max=1\n", ib_wr->num_sge); | ||
3449 | err = -EINVAL; | ||
3450 | break; | ||
3451 | } | ||
3452 | /* Set access_flags */ | ||
3453 | wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_LOCAL_READ; | ||
3454 | if (flags & IB_ACCESS_LOCAL_WRITE) | ||
3455 | wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_LOCAL_WRITE; | ||
3456 | |||
3457 | if (flags & IB_ACCESS_REMOTE_WRITE) | ||
3458 | wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_REMOTE_WRITE; | ||
3459 | |||
3460 | if (flags & IB_ACCESS_REMOTE_READ) | ||
3461 | wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_REMOTE_READ; | ||
3462 | |||
3463 | if (flags & IB_ACCESS_MW_BIND) | ||
3464 | wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_WINDOW_BIND; | ||
3465 | |||
3466 | /* Fill in PBL info: */ | ||
3467 | if (ib_wr->wr.fast_reg.page_list_len > | ||
3468 | pnesfrpl->ibfrpl.max_page_list_len) { | ||
3469 | nes_debug(NES_DBG_IW_TX, "Invalid page list length," | ||
3470 | " ib_wr=%p, value=%u, max=%u\n", | ||
3471 | ib_wr, ib_wr->wr.fast_reg.page_list_len, | ||
3472 | pnesfrpl->ibfrpl.max_page_list_len); | ||
3473 | err = -EINVAL; | ||
3474 | break; | ||
3475 | } | ||
3476 | |||
3477 | set_wqe_64bit_value(wqe->wqe_words, | ||
3478 | NES_IWARP_SQ_FMR_WQE_PBL_ADDR_LOW_IDX, | ||
3479 | pnesfrpl->nes_wqe_pbl.paddr); | ||
3480 | |||
3481 | set_wqe_32bit_value(wqe->wqe_words, | ||
3482 | NES_IWARP_SQ_FMR_WQE_PBL_LENGTH_IDX, | ||
3483 | ib_wr->wr.fast_reg.page_list_len * 8); | ||
3484 | |||
3485 | for (i = 0; i < ib_wr->wr.fast_reg.page_list_len; i++) | ||
3486 | dst_page_list[i] = cpu_to_le64(src_page_list[i]); | ||
3487 | |||
3488 | nes_debug(NES_DBG_IW_TX, "SQ_FMR: iova_start: %p, " | ||
3489 | "length: %d, rkey: %0x, pgl_paddr: %p, " | ||
3490 | "page_list_len: %u, wqe_misc: %x\n", | ||
3491 | (void *)ib_wr->wr.fast_reg.iova_start, | ||
3492 | ib_wr->wr.fast_reg.length, | ||
3493 | ib_wr->wr.fast_reg.rkey, | ||
3494 | (void *)pnesfrpl->nes_wqe_pbl.paddr, | ||
3495 | ib_wr->wr.fast_reg.page_list_len, | ||
3496 | wqe_misc); | ||
3497 | break; | ||
3498 | } | ||
3499 | default: | ||
3500 | /* error */ | ||
3501 | err = -EINVAL; | ||
3502 | break; | ||
3503 | } | 3503 | } |
3504 | |||
3505 | if (err) | ||
3506 | break; | ||
3507 | |||
3508 | if ((ib_wr->send_flags & IB_SEND_SIGNALED) || nesqp->sig_all) | ||
3509 | wqe_misc |= NES_IWARP_SQ_WQE_SIGNALED_COMPL; | ||
3510 | |||
3504 | wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = cpu_to_le32(wqe_misc); | 3511 | wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = cpu_to_le32(wqe_misc); |
3505 | 3512 | ||
3506 | ib_wr = ib_wr->next; | 3513 | ib_wr = ib_wr->next; |
@@ -3522,6 +3529,7 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, | |||
3522 | 3529 | ||
3523 | spin_unlock_irqrestore(&nesqp->lock, flags); | 3530 | spin_unlock_irqrestore(&nesqp->lock, flags); |
3524 | 3531 | ||
3532 | out: | ||
3525 | if (err) | 3533 | if (err) |
3526 | *bad_wr = ib_wr; | 3534 | *bad_wr = ib_wr; |
3527 | return err; | 3535 | return err; |
@@ -3548,8 +3556,10 @@ static int nes_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, | |||
3548 | u32 counter; | 3556 | u32 counter; |
3549 | u32 total_payload_length; | 3557 | u32 total_payload_length; |
3550 | 3558 | ||
3551 | if (nesqp->ibqp_state > IB_QPS_RTS) | 3559 | if (nesqp->ibqp_state > IB_QPS_RTS) { |
3552 | return -EINVAL; | 3560 | err = -EINVAL; |
3561 | goto out; | ||
3562 | } | ||
3553 | 3563 | ||
3554 | spin_lock_irqsave(&nesqp->lock, flags); | 3564 | spin_lock_irqsave(&nesqp->lock, flags); |
3555 | 3565 | ||
@@ -3568,7 +3578,7 @@ static int nes_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, | |||
3568 | } | 3578 | } |
3569 | /* Check for RQ overflow */ | 3579 | /* Check for RQ overflow */ |
3570 | if (((head + (2 * qsize) - nesqp->hwqp.rq_tail) % qsize) == (qsize - 1)) { | 3580 | if (((head + (2 * qsize) - nesqp->hwqp.rq_tail) % qsize) == (qsize - 1)) { |
3571 | err = -EINVAL; | 3581 | err = -ENOMEM; |
3572 | break; | 3582 | break; |
3573 | } | 3583 | } |
3574 | 3584 | ||
@@ -3612,6 +3622,7 @@ static int nes_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, | |||
3612 | 3622 | ||
3613 | spin_unlock_irqrestore(&nesqp->lock, flags); | 3623 | spin_unlock_irqrestore(&nesqp->lock, flags); |
3614 | 3624 | ||
3625 | out: | ||
3615 | if (err) | 3626 | if (err) |
3616 | *bad_wr = ib_wr; | 3627 | *bad_wr = ib_wr; |
3617 | return err; | 3628 | return err; |
@@ -3720,6 +3731,12 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
3720 | nes_debug(NES_DBG_CQ, "Operation = Send.\n"); | 3731 | nes_debug(NES_DBG_CQ, "Operation = Send.\n"); |
3721 | entry->opcode = IB_WC_SEND; | 3732 | entry->opcode = IB_WC_SEND; |
3722 | break; | 3733 | break; |
3734 | case NES_IWARP_SQ_OP_LOCINV: | ||
3735 | entry->opcode = IB_WR_LOCAL_INV; | ||
3736 | break; | ||
3737 | case NES_IWARP_SQ_OP_FAST_REG: | ||
3738 | entry->opcode = IB_WC_FAST_REG_MR; | ||
3739 | break; | ||
3723 | } | 3740 | } |
3724 | 3741 | ||
3725 | nesqp->hwqp.sq_tail = (wqe_index+1)&(nesqp->hwqp.sq_size - 1); | 3742 | nesqp->hwqp.sq_tail = (wqe_index+1)&(nesqp->hwqp.sq_size - 1); |
@@ -3890,10 +3907,9 @@ struct nes_ib_device *nes_init_ofa_device(struct net_device *netdev) | |||
3890 | nesibdev->ibdev.dealloc_mw = nes_dealloc_mw; | 3907 | nesibdev->ibdev.dealloc_mw = nes_dealloc_mw; |
3891 | nesibdev->ibdev.bind_mw = nes_bind_mw; | 3908 | nesibdev->ibdev.bind_mw = nes_bind_mw; |
3892 | 3909 | ||
3893 | nesibdev->ibdev.alloc_fmr = nes_alloc_fmr; | 3910 | nesibdev->ibdev.alloc_fast_reg_mr = nes_alloc_fast_reg_mr; |
3894 | nesibdev->ibdev.unmap_fmr = nes_unmap_fmr; | 3911 | nesibdev->ibdev.alloc_fast_reg_page_list = nes_alloc_fast_reg_page_list; |
3895 | nesibdev->ibdev.dealloc_fmr = nes_dealloc_fmr; | 3912 | nesibdev->ibdev.free_fast_reg_page_list = nes_free_fast_reg_page_list; |
3896 | nesibdev->ibdev.map_phys_fmr = nes_map_phys_fmr; | ||
3897 | 3913 | ||
3898 | nesibdev->ibdev.attach_mcast = nes_multicast_attach; | 3914 | nesibdev->ibdev.attach_mcast = nes_multicast_attach; |
3899 | nesibdev->ibdev.detach_mcast = nes_multicast_detach; | 3915 | nesibdev->ibdev.detach_mcast = nes_multicast_detach; |
diff --git a/drivers/infiniband/hw/nes/nes_verbs.h b/drivers/infiniband/hw/nes/nes_verbs.h index 89822d75f82e..2df9993e0cac 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.h +++ b/drivers/infiniband/hw/nes/nes_verbs.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. | 2 | * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. |
3 | * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. | 3 | * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This software is available to you under a choice of one of two | 5 | * This software is available to you under a choice of one of two |
@@ -135,19 +135,15 @@ struct nes_qp { | |||
135 | struct ib_qp ibqp; | 135 | struct ib_qp ibqp; |
136 | void *allocated_buffer; | 136 | void *allocated_buffer; |
137 | struct iw_cm_id *cm_id; | 137 | struct iw_cm_id *cm_id; |
138 | struct workqueue_struct *wq; | ||
139 | struct nes_cq *nesscq; | 138 | struct nes_cq *nesscq; |
140 | struct nes_cq *nesrcq; | 139 | struct nes_cq *nesrcq; |
141 | struct nes_pd *nespd; | 140 | struct nes_pd *nespd; |
142 | void *cm_node; /* handle of the node this QP is associated with */ | 141 | void *cm_node; /* handle of the node this QP is associated with */ |
143 | struct ietf_mpa_frame *ietf_frame; | 142 | struct ietf_mpa_frame *ietf_frame; |
144 | dma_addr_t ietf_frame_pbase; | 143 | dma_addr_t ietf_frame_pbase; |
145 | wait_queue_head_t state_waitq; | ||
146 | struct ib_mr *lsmm_mr; | 144 | struct ib_mr *lsmm_mr; |
147 | unsigned long socket; | ||
148 | struct nes_hw_qp hwqp; | 145 | struct nes_hw_qp hwqp; |
149 | struct work_struct work; | 146 | struct work_struct work; |
150 | struct work_struct ae_work; | ||
151 | enum ib_qp_state ibqp_state; | 147 | enum ib_qp_state ibqp_state; |
152 | u32 iwarp_state; | 148 | u32 iwarp_state; |
153 | u32 hte_index; | 149 | u32 hte_index; |
@@ -165,19 +161,20 @@ struct nes_qp { | |||
165 | struct page *page; | 161 | struct page *page; |
166 | struct timer_list terminate_timer; | 162 | struct timer_list terminate_timer; |
167 | enum ib_event_type terminate_eventtype; | 163 | enum ib_event_type terminate_eventtype; |
168 | wait_queue_head_t kick_waitq; | 164 | u16 active_conn:1; |
169 | u16 in_disconnect; | 165 | u16 skip_lsmm:1; |
166 | u16 user_mode:1; | ||
167 | u16 hte_added:1; | ||
168 | u16 flush_issued:1; | ||
169 | u16 destroyed:1; | ||
170 | u16 sig_all:1; | ||
171 | u16 rsvd:9; | ||
170 | u16 private_data_len; | 172 | u16 private_data_len; |
171 | u16 term_sq_flush_code; | 173 | u16 term_sq_flush_code; |
172 | u16 term_rq_flush_code; | 174 | u16 term_rq_flush_code; |
173 | u8 active_conn; | ||
174 | u8 skip_lsmm; | ||
175 | u8 user_mode; | ||
176 | u8 hte_added; | ||
177 | u8 hw_iwarp_state; | 175 | u8 hw_iwarp_state; |
178 | u8 flush_issued; | ||
179 | u8 hw_tcp_state; | 176 | u8 hw_tcp_state; |
180 | u8 term_flags; | 177 | u8 term_flags; |
181 | u8 destroyed; | 178 | u8 sq_kmapped; |
182 | }; | 179 | }; |
183 | #endif /* NES_VERBS_H */ | 180 | #endif /* NES_VERBS_H */ |