IB/hfi1: Allow MgmtAllowed on B2B setups
authorJan Sokolowski <jan.sokolowski@intel.com>
Mon, 6 Nov 2017 14:38:16 +0000 (06:38 -0800)
committerDoug Ledford <dledford@redhat.com>
Mon, 13 Nov 2017 20:53:56 +0000 (15:53 -0500)
HFI's are hard-wired to send Device Info frames with
MgmtAllowed bit set to 0. This means in B2B setups,
MgmtAllowed would never be allowed, which prevents
remote opa management tools from working properly.

Assume MgmtAllowed if a neighbor is also an HFI.

Fixes: 98b9ee2002a8 ("IB/hfi1: Cache neighbor secure data after link up")
Reviewed-by: Sebastian Sanchez <sebastian.sanchez@intel.com>
Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
Signed-off-by: Jan Sokolowski <jan.sokolowski@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/hfi1/chip.c
drivers/infiniband/hw/hfi1/hfi.h
drivers/infiniband/hw/hfi1/intr.c

index 05e03a05fcc916355695d90a30a7f951f2c2e5a8..2523b6291f95bc2a536f66ba5cfea7889a4e3005 100644 (file)
@@ -1036,7 +1036,6 @@ static void read_vc_local_link_width(struct hfi1_devdata *dd, u8 *misc_bits,
                                     u8 *flag_bits, u16 *link_widths);
 static void read_remote_device_id(struct hfi1_devdata *dd, u16 *device_id,
                                  u8 *device_rev);
-static void read_mgmt_allowed(struct hfi1_devdata *dd, u8 *mgmt_allowed);
 static void read_local_lni(struct hfi1_devdata *dd, u8 *enable_lane_rx);
 static int read_tx_settings(struct hfi1_devdata *dd, u8 *enable_lane_tx,
                            u8 *tx_polarity_inversion,
@@ -7197,27 +7196,6 @@ static int lcb_to_port_ltp(int lcb_crc)
        return port_ltp;
 }
 
-/*
- * Our neighbor has indicated that we are allowed to act as a fabric
- * manager, so place the full management partition key in the second
- * (0-based) pkey array position (see OPAv1, section 20.2.2.6.8). Note
- * that we should already have the limited management partition key in
- * array element 1, and also that the port is not yet up when
- * add_full_mgmt_pkey() is invoked.
- */
-static void add_full_mgmt_pkey(struct hfi1_pportdata *ppd)
-{
-       struct hfi1_devdata *dd = ppd->dd;
-
-       /* Sanity check - ppd->pkeys[2] should be 0, or already initialized */
-       if (!((ppd->pkeys[2] == 0) || (ppd->pkeys[2] == FULL_MGMT_P_KEY)))
-               dd_dev_warn(dd, "%s pkey[2] already set to 0x%x, resetting it to 0x%x\n",
-                           __func__, ppd->pkeys[2], FULL_MGMT_P_KEY);
-       ppd->pkeys[2] = FULL_MGMT_P_KEY;
-       (void)hfi1_set_ib_cfg(ppd, HFI1_IB_CFG_PKEYS, 0);
-       hfi1_event_pkey_change(ppd->dd, ppd->port);
-}
-
 static void clear_full_mgmt_pkey(struct hfi1_pportdata *ppd)
 {
        if (ppd->pkeys[2] != 0) {
@@ -7414,11 +7392,7 @@ void handle_verify_cap(struct work_struct *work)
                              &partner_supported_crc);
        read_vc_remote_link_width(dd, &remote_tx_rate, &link_widths);
        read_remote_device_id(dd, &device_id, &device_rev);
-       /*
-        * And the 'MgmtAllowed' information, which is exchanged during
-        * LNI, is also be available at this point.
-        */
-       read_mgmt_allowed(dd, &ppd->mgmt_allowed);
+
        /* print the active widths */
        get_link_widths(dd, &active_tx, &active_rx);
        dd_dev_info(dd,
@@ -7546,9 +7520,6 @@ void handle_verify_cap(struct work_struct *work)
        write_csr(dd, DC_LCB_ERR_EN, 0); /* mask LCB errors */
        set_8051_lcb_access(dd);
 
-       if (ppd->mgmt_allowed)
-               add_full_mgmt_pkey(ppd);
-
        /* tell the 8051 to go to LinkUp */
        set_link_state(ppd, HLS_GOING_UP);
 }
@@ -8960,14 +8931,6 @@ static void read_local_lni(struct hfi1_devdata *dd, u8 *enable_lane_rx)
        *enable_lane_rx = (frame >> ENABLE_LANE_RX_SHIFT) & ENABLE_LANE_RX_MASK;
 }
 
-static void read_mgmt_allowed(struct hfi1_devdata *dd, u8 *mgmt_allowed)
-{
-       u32 frame;
-
-       read_8051_config(dd, REMOTE_LNI_INFO, GENERAL_CONFIG, &frame);
-       *mgmt_allowed = (frame >> MGMT_ALLOWED_SHIFT) & MGMT_ALLOWED_MASK;
-}
-
 static void read_last_local_state(struct hfi1_devdata *dd, u32 *lls)
 {
        read_8051_config(dd, LAST_LOCAL_STATE_COMPLETE, GENERAL_CONFIG, lls);
index 08d394f384c657a2f046a677a97018a0e2a24cc9..4a9b4d7efe6362f31457672882e882af3bfdfc46 100644 (file)
@@ -95,6 +95,9 @@
 #define DROP_PACKET_OFF                0
 #define DROP_PACKET_ON         1
 
+#define NEIGHBOR_TYPE_HFI              0
+#define NEIGHBOR_TYPE_SWITCH   1
+
 extern unsigned long hfi1_cap_mask;
 #define HFI1_CAP_KGET_MASK(mask, cap) ((mask) & HFI1_CAP_##cap)
 #define HFI1_CAP_UGET_MASK(mask, cap) \
index 3e3184ddab5bf78de328c3a733b678e1e9b6a835..387305b768e94d6ed745cff42b26cdf47200d7c5 100644 (file)
 
 #define LINK_UP_DELAY  500  /* in microseconds */
 
+static void set_mgmt_allowed(struct hfi1_pportdata *ppd)
+{
+       u32 frame;
+       struct hfi1_devdata *dd = ppd->dd;
+
+       if (ppd->neighbor_type == NEIGHBOR_TYPE_HFI) {
+               ppd->mgmt_allowed = 1;
+       } else {
+               read_8051_config(dd, REMOTE_LNI_INFO, GENERAL_CONFIG, &frame);
+               ppd->mgmt_allowed = (frame >> MGMT_ALLOWED_SHIFT)
+               & MGMT_ALLOWED_MASK;
+       }
+}
+
+/*
+ * Our neighbor has indicated that we are allowed to act as a fabric
+ * manager, so place the full management partition key in the second
+ * (0-based) pkey array position. Note that we should already have
+ * the limited management partition key in array element 1, and also
+ * that the port is not yet up when add_full_mgmt_pkey() is invoked.
+ */
+static void add_full_mgmt_pkey(struct hfi1_pportdata *ppd)
+{
+       struct hfi1_devdata *dd = ppd->dd;
+
+       /* Sanity check - ppd->pkeys[2] should be 0, or already initialized */
+       if (!((ppd->pkeys[2] == 0) || (ppd->pkeys[2] == FULL_MGMT_P_KEY)))
+               dd_dev_warn(dd, "%s pkey[2] already set to 0x%x, resetting it to 0x%x\n",
+                           __func__, ppd->pkeys[2], FULL_MGMT_P_KEY);
+       ppd->pkeys[2] = FULL_MGMT_P_KEY;
+       (void)hfi1_set_ib_cfg(ppd, HFI1_IB_CFG_PKEYS, 0);
+       hfi1_event_pkey_change(ppd->dd, ppd->port);
+}
+
 /**
  * format_hwmsg - format a single hwerror message
  * @msg message buffer
@@ -163,6 +197,15 @@ void handle_linkup_change(struct hfi1_devdata *dd, u32 linkup)
                /* HW needs LINK_UP_DELAY to settle, give it that chance */
                udelay(LINK_UP_DELAY);
 
+               /*
+                * 'MgmtAllowed' information, which is exchanged during
+                * LNI, is available at this point.
+                */
+               set_mgmt_allowed(ppd);
+
+               if (ppd->mgmt_allowed)
+                       add_full_mgmt_pkey(ppd);
+
                /* physical link went up */
                ppd->linkup = 1;
                ppd->offline_disabled_reason =