IB/core: Add ib_find_exact_cached_pkey()
authorJack Morgenstein <jackm@dev.mellanox.co.il>
Fri, 3 Aug 2012 08:40:39 +0000 (08:40 +0000)
committerRoland Dreier <roland@purestorage.com>
Mon, 1 Oct 2012 03:33:30 +0000 (20:33 -0700)
When P_Key tables potentially contain both full and partial membership
copies for the same P_Key, we need a function to find the index for an
exact (16-bit) P_Key.

This is necessary when the master forwards QP1 MADs sent by guests.
If the guest has sent the MAD with a limited membership P_Key, we need
to to forward the MAD using the same limited membership P_Key.  Since
the master may have both the limited and the full member P_Keys in its
table, we must make sure to retrieve the limited membership P_Key in
this case.

Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/core/cache.c
include/rdma/ib_cache.h

index 4da381b74f54ab9c611bf491cab0f4645fb354c9..80f6cf2449fb9b852533d254ab8e6cbabc706156 100644 (file)
@@ -199,6 +199,38 @@ int ib_find_cached_pkey(struct ib_device *device,
 }
 EXPORT_SYMBOL(ib_find_cached_pkey);
 
+int ib_find_exact_cached_pkey(struct ib_device *device,
+                             u8                port_num,
+                             u16               pkey,
+                             u16              *index)
+{
+       struct ib_pkey_cache *cache;
+       unsigned long flags;
+       int i;
+       int ret = -ENOENT;
+
+       if (port_num < start_port(device) || port_num > end_port(device))
+               return -EINVAL;
+
+       read_lock_irqsave(&device->cache.lock, flags);
+
+       cache = device->cache.pkey_cache[port_num - start_port(device)];
+
+       *index = -1;
+
+       for (i = 0; i < cache->table_len; ++i)
+               if (cache->table[i] == pkey) {
+                       *index = i;
+                       ret = 0;
+                       break;
+               }
+
+       read_unlock_irqrestore(&device->cache.lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(ib_find_exact_cached_pkey);
+
 int ib_get_cached_lmc(struct ib_device *device,
                      u8                port_num,
                      u8                *lmc)
index 00a2b8ec327f7c1ce089172c2a1a92474bfee39e..ad9a3c280944ff3581ac9313a04387198f2c0fd9 100644 (file)
@@ -100,6 +100,22 @@ int ib_find_cached_pkey(struct ib_device    *device,
                        u16                  pkey,
                        u16                 *index);
 
+/**
+ * ib_find_exact_cached_pkey - Returns the PKey table index where a specified
+ *   PKey value occurs. Comparison uses the FULL 16 bits (incl membership bit)
+ * @device: The device to query.
+ * @port_num: The port number of the device to search for the PKey.
+ * @pkey: The PKey value to search for.
+ * @index: The index into the cached PKey table where the PKey was found.
+ *
+ * ib_find_exact_cached_pkey() searches the specified PKey table in
+ * the local software cache.
+ */
+int ib_find_exact_cached_pkey(struct ib_device    *device,
+                             u8                   port_num,
+                             u16                  pkey,
+                             u16                 *index);
+
 /**
  * ib_get_cached_lmc - Returns a cached lmc table entry
  * @device: The device to query.