| 1 | // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause |
| 2 | /* |
| 3 | * Copyright(c) 2015, 2016 Intel Corporation. |
| 4 | */ |
| 5 | |
| 6 | #include <linux/pci.h> |
| 7 | #include <linux/delay.h> |
| 8 | #include <linux/bitmap.h> |
| 9 | |
| 10 | #include "hfi.h" |
| 11 | #include "common.h" |
| 12 | #include "sdma.h" |
| 13 | |
| 14 | #define LINK_UP_DELAY 500 /* in microseconds */ |
| 15 | |
| 16 | static void set_mgmt_allowed(struct hfi1_pportdata *ppd) |
| 17 | { |
| 18 | u32 frame; |
| 19 | struct hfi1_devdata *dd = ppd->dd; |
| 20 | |
| 21 | if (ppd->neighbor_type == NEIGHBOR_TYPE_HFI) { |
| 22 | ppd->mgmt_allowed = 1; |
| 23 | } else { |
| 24 | read_8051_config(dd, REMOTE_LNI_INFO, GENERAL_CONFIG, &frame); |
| 25 | ppd->mgmt_allowed = (frame >> MGMT_ALLOWED_SHIFT) |
| 26 | & MGMT_ALLOWED_MASK; |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | /* |
| 31 | * Our neighbor has indicated that we are allowed to act as a fabric |
| 32 | * manager, so place the full management partition key in the second |
| 33 | * (0-based) pkey array position. Note that we should already have |
| 34 | * the limited management partition key in array element 1, and also |
| 35 | * that the port is not yet up when add_full_mgmt_pkey() is invoked. |
| 36 | */ |
| 37 | static void add_full_mgmt_pkey(struct hfi1_pportdata *ppd) |
| 38 | { |
| 39 | struct hfi1_devdata *dd = ppd->dd; |
| 40 | |
| 41 | /* Sanity check - ppd->pkeys[2] should be 0, or already initialized */ |
| 42 | if (!((ppd->pkeys[2] == 0) || (ppd->pkeys[2] == FULL_MGMT_P_KEY))) |
| 43 | dd_dev_warn(dd, "%s pkey[2] already set to 0x%x, resetting it to 0x%x\n" , |
| 44 | __func__, ppd->pkeys[2], FULL_MGMT_P_KEY); |
| 45 | ppd->pkeys[2] = FULL_MGMT_P_KEY; |
| 46 | (void)hfi1_set_ib_cfg(ppd, HFI1_IB_CFG_PKEYS, val: 0); |
| 47 | hfi1_event_pkey_change(dd: ppd->dd, port: ppd->port); |
| 48 | } |
| 49 | |
| 50 | static void signal_ib_event(struct hfi1_pportdata *ppd, enum ib_event_type ev) |
| 51 | { |
| 52 | struct ib_event event; |
| 53 | struct hfi1_devdata *dd = ppd->dd; |
| 54 | |
| 55 | /* |
| 56 | * Only call ib_dispatch_event() if the IB device has been |
| 57 | * registered. HFI1_INITED is set iff the driver has successfully |
| 58 | * registered with the IB core. |
| 59 | */ |
| 60 | if (!(dd->flags & HFI1_INITTED)) |
| 61 | return; |
| 62 | event.device = &dd->verbs_dev.rdi.ibdev; |
| 63 | event.element.port_num = ppd->port; |
| 64 | event.event = ev; |
| 65 | ib_dispatch_event(event: &event); |
| 66 | } |
| 67 | |
| 68 | /** |
| 69 | * handle_linkup_change - finish linkup/down state changes |
| 70 | * @dd: valid device |
| 71 | * @linkup: link state information |
| 72 | * |
| 73 | * Handle a linkup or link down notification. |
| 74 | * The HW needs time to finish its link up state change. Give it that chance. |
| 75 | * |
| 76 | * This is called outside an interrupt. |
| 77 | * |
| 78 | */ |
| 79 | void handle_linkup_change(struct hfi1_devdata *dd, u32 linkup) |
| 80 | { |
| 81 | struct hfi1_pportdata *ppd = &dd->pport[0]; |
| 82 | enum ib_event_type ev; |
| 83 | |
| 84 | if (!(ppd->linkup ^ !!linkup)) |
| 85 | return; /* no change, nothing to do */ |
| 86 | |
| 87 | if (linkup) { |
| 88 | /* |
| 89 | * Quick linkup and all link up on the simulator does not |
| 90 | * trigger or implement: |
| 91 | * - VerifyCap interrupt |
| 92 | * - VerifyCap frames |
| 93 | * But rather moves directly to LinkUp. |
| 94 | * |
| 95 | * Do the work of the VerifyCap interrupt handler, |
| 96 | * handle_verify_cap(), but do not try moving the state to |
| 97 | * LinkUp as we are already there. |
| 98 | * |
| 99 | * NOTE: This uses this device's vAU, vCU, and vl15_init for |
| 100 | * the remote values. Both sides must be using the values. |
| 101 | */ |
| 102 | if (quick_linkup || dd->icode == ICODE_FUNCTIONAL_SIMULATOR) { |
| 103 | set_up_vau(dd, vau: dd->vau); |
| 104 | set_up_vl15(dd, vl15buf: dd->vl15_init); |
| 105 | assign_remote_cm_au_table(dd, vcu: dd->vcu); |
| 106 | } |
| 107 | |
| 108 | ppd->neighbor_guid = |
| 109 | read_csr(dd, DC_DC8051_STS_REMOTE_GUID); |
| 110 | ppd->neighbor_type = |
| 111 | read_csr(dd, DC_DC8051_STS_REMOTE_NODE_TYPE) & |
| 112 | DC_DC8051_STS_REMOTE_NODE_TYPE_VAL_MASK; |
| 113 | ppd->neighbor_port_number = |
| 114 | read_csr(dd, DC_DC8051_STS_REMOTE_PORT_NO) & |
| 115 | DC_DC8051_STS_REMOTE_PORT_NO_VAL_SMASK; |
| 116 | ppd->neighbor_fm_security = |
| 117 | read_csr(dd, DC_DC8051_STS_REMOTE_FM_SECURITY) & |
| 118 | DC_DC8051_STS_LOCAL_FM_SECURITY_DISABLED_MASK; |
| 119 | dd_dev_info(dd, |
| 120 | "Neighbor Guid %llx, Type %d, Port Num %d\n" , |
| 121 | ppd->neighbor_guid, ppd->neighbor_type, |
| 122 | ppd->neighbor_port_number); |
| 123 | |
| 124 | /* HW needs LINK_UP_DELAY to settle, give it that chance */ |
| 125 | udelay(LINK_UP_DELAY); |
| 126 | |
| 127 | /* |
| 128 | * 'MgmtAllowed' information, which is exchanged during |
| 129 | * LNI, is available at this point. |
| 130 | */ |
| 131 | set_mgmt_allowed(ppd); |
| 132 | |
| 133 | if (ppd->mgmt_allowed) |
| 134 | add_full_mgmt_pkey(ppd); |
| 135 | |
| 136 | /* physical link went up */ |
| 137 | ppd->linkup = 1; |
| 138 | ppd->offline_disabled_reason = |
| 139 | HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE); |
| 140 | |
| 141 | /* link widths are not available until the link is fully up */ |
| 142 | get_linkup_link_widths(ppd); |
| 143 | |
| 144 | } else { |
| 145 | /* physical link went down */ |
| 146 | ppd->linkup = 0; |
| 147 | |
| 148 | /* clear HW details of the previous connection */ |
| 149 | ppd->actual_vls_operational = 0; |
| 150 | reset_link_credits(dd); |
| 151 | |
| 152 | /* freeze after a link down to guarantee a clean egress */ |
| 153 | start_freeze_handling(ppd, FREEZE_SELF | FREEZE_LINK_DOWN); |
| 154 | |
| 155 | ev = IB_EVENT_PORT_ERR; |
| 156 | |
| 157 | hfi1_set_uevent_bits(ppd, _HFI1_EVENT_LINKDOWN_BIT); |
| 158 | |
| 159 | /* if we are down, the neighbor is down */ |
| 160 | ppd->neighbor_normal = 0; |
| 161 | |
| 162 | /* notify IB of the link change */ |
| 163 | signal_ib_event(ppd, ev); |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | /* |
| 168 | * Handle receive or urgent interrupts for user contexts. This means a user |
| 169 | * process was waiting for a packet to arrive, and didn't want to poll. |
| 170 | */ |
| 171 | void handle_user_interrupt(struct hfi1_ctxtdata *rcd) |
| 172 | { |
| 173 | struct hfi1_devdata *dd = rcd->dd; |
| 174 | unsigned long flags; |
| 175 | |
| 176 | spin_lock_irqsave(&dd->uctxt_lock, flags); |
| 177 | if (bitmap_empty(src: rcd->in_use_ctxts, HFI1_MAX_SHARED_CTXTS)) |
| 178 | goto done; |
| 179 | |
| 180 | if (test_and_clear_bit(HFI1_CTXT_WAITING_RCV, addr: &rcd->event_flags)) { |
| 181 | wake_up_interruptible(&rcd->wait); |
| 182 | hfi1_rcvctrl(dd, HFI1_RCVCTRL_INTRAVAIL_DIS, rcd); |
| 183 | } else if (test_and_clear_bit(HFI1_CTXT_WAITING_URG, |
| 184 | addr: &rcd->event_flags)) { |
| 185 | rcd->urgent++; |
| 186 | wake_up_interruptible(&rcd->wait); |
| 187 | } |
| 188 | done: |
| 189 | spin_unlock_irqrestore(lock: &dd->uctxt_lock, flags); |
| 190 | } |
| 191 | |