1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright(c) 2022 - 2025 Mucse Corporation. */ 3 4 #include <linux/errno.h> 5 #include <linux/bitfield.h> 6 #include <linux/iopoll.h> 7 8 #include "rnpgbe_mbx.h" 9 10 /** 11 * mbx_data_rd32 - Reads reg with base mbx->fwpf_shm_base 12 * @mbx: pointer to the MBX structure 13 * @reg: register offset 14 * 15 * Return: register value 16 **/ 17 static u32 mbx_data_rd32(struct mucse_mbx_info *mbx, u32 reg) 18 { 19 struct mucse_hw *hw = container_of(mbx, struct mucse_hw, mbx); 20 21 return readl(hw->hw_addr + mbx->fwpf_shm_base + reg); 22 } 23 24 /** 25 * mbx_data_wr32 - Writes value to reg with base mbx->fwpf_shm_base 26 * @mbx: pointer to the MBX structure 27 * @reg: register offset 28 * @value: value to be written 29 * 30 **/ 31 static void mbx_data_wr32(struct mucse_mbx_info *mbx, u32 reg, u32 value) 32 { 33 struct mucse_hw *hw = container_of(mbx, struct mucse_hw, mbx); 34 35 writel(value, hw->hw_addr + mbx->fwpf_shm_base + reg); 36 } 37 38 /** 39 * mbx_ctrl_rd32 - Reads reg with base mbx->fwpf_ctrl_base 40 * @mbx: pointer to the MBX structure 41 * @reg: register offset 42 * 43 * Return: register value 44 **/ 45 static u32 mbx_ctrl_rd32(struct mucse_mbx_info *mbx, u32 reg) 46 { 47 struct mucse_hw *hw = container_of(mbx, struct mucse_hw, mbx); 48 49 return readl(hw->hw_addr + mbx->fwpf_ctrl_base + reg); 50 } 51 52 /** 53 * mbx_ctrl_wr32 - Writes value to reg with base mbx->fwpf_ctrl_base 54 * @mbx: pointer to the MBX structure 55 * @reg: register offset 56 * @value: value to be written 57 * 58 **/ 59 static void mbx_ctrl_wr32(struct mucse_mbx_info *mbx, u32 reg, u32 value) 60 { 61 struct mucse_hw *hw = container_of(mbx, struct mucse_hw, mbx); 62 63 writel(value, hw->hw_addr + mbx->fwpf_ctrl_base + reg); 64 } 65 66 /** 67 * mucse_mbx_get_lock_pf - Write ctrl and read back lock status 68 * @hw: pointer to the HW structure 69 * 70 * Return: register value after write 71 **/ 72 static u32 mucse_mbx_get_lock_pf(struct mucse_hw *hw) 73 { 74 struct mucse_mbx_info *mbx = &hw->mbx; 75 u32 reg = MUCSE_MBX_PF2FW_CTRL(mbx); 76 77 mbx_ctrl_wr32(mbx, reg, MUCSE_MBX_PFU); 78 79 return mbx_ctrl_rd32(mbx, reg); 80 } 81 82 /** 83 * mucse_obtain_mbx_lock_pf - Obtain mailbox lock 84 * @hw: pointer to the HW structure 85 * 86 * Pair with mucse_release_mbx_lock_pf() 87 * This function maybe used in an irq handler. 88 * 89 * Return: 0 on success, negative errno on failure 90 **/ 91 static int mucse_obtain_mbx_lock_pf(struct mucse_hw *hw) 92 { 93 struct mucse_mbx_info *mbx = &hw->mbx; 94 u32 val; 95 96 return read_poll_timeout_atomic(mucse_mbx_get_lock_pf, 97 val, val & MUCSE_MBX_PFU, 98 mbx->delay_us, 99 mbx->timeout_us, 100 false, hw); 101 } 102 103 /** 104 * mucse_release_mbx_lock_pf - Release mailbox lock 105 * @hw: pointer to the HW structure 106 * @req: send a request or not 107 * 108 * Pair with mucse_obtain_mbx_lock_pf(): 109 * - Releases the mailbox lock by clearing MUCSE_MBX_PFU bit 110 * - Simultaneously sends the request by setting MUCSE_MBX_REQ bit 111 * if req is true 112 * (Both bits are in the same mailbox control register, 113 * so operations are combined) 114 **/ 115 static void mucse_release_mbx_lock_pf(struct mucse_hw *hw, bool req) 116 { 117 struct mucse_mbx_info *mbx = &hw->mbx; 118 u32 reg = MUCSE_MBX_PF2FW_CTRL(mbx); 119 120 mbx_ctrl_wr32(mbx, reg, req ? MUCSE_MBX_REQ : 0); 121 } 122 123 /** 124 * mucse_mbx_get_fwreq - Read fw req from reg 125 * @mbx: pointer to the mbx structure 126 * 127 * Return: the fwreq value 128 **/ 129 static u16 mucse_mbx_get_fwreq(struct mucse_mbx_info *mbx) 130 { 131 u32 val = mbx_data_rd32(mbx, MUCSE_MBX_FW2PF_CNT); 132 133 return FIELD_GET(GENMASK_U32(15, 0), val); 134 } 135 136 /** 137 * mucse_mbx_inc_pf_ack - Increase ack 138 * @hw: pointer to the HW structure 139 * 140 * mucse_mbx_inc_pf_ack reads pf_ack from hw, then writes 141 * new value back after increase 142 **/ 143 static void mucse_mbx_inc_pf_ack(struct mucse_hw *hw) 144 { 145 struct mucse_mbx_info *mbx = &hw->mbx; 146 u16 ack; 147 u32 val; 148 149 val = mbx_data_rd32(mbx, MUCSE_MBX_PF2FW_CNT); 150 ack = FIELD_GET(GENMASK_U32(31, 16), val); 151 ack++; 152 val &= ~GENMASK_U32(31, 16); 153 val |= FIELD_PREP(GENMASK_U32(31, 16), ack); 154 mbx_data_wr32(mbx, MUCSE_MBX_PF2FW_CNT, val); 155 } 156 157 /** 158 * mucse_read_mbx_pf - Read a message from the mailbox 159 * @hw: pointer to the HW structure 160 * @msg: the message buffer 161 * @size: length of buffer 162 * 163 * mucse_read_mbx_pf copies a message from the mbx buffer to the caller's 164 * memory buffer. The presumption is that the caller knows that there was 165 * a message due to a fw request so no polling for message is needed. 166 * 167 * Return: 0 on success, negative errno on failure 168 **/ 169 static int mucse_read_mbx_pf(struct mucse_hw *hw, u32 *msg, u16 size) 170 { 171 const int size_in_words = size / sizeof(u32); 172 struct mucse_mbx_info *mbx = &hw->mbx; 173 int err; 174 175 err = mucse_obtain_mbx_lock_pf(hw); 176 if (err) 177 return err; 178 179 for (int i = 0; i < size_in_words; i++) 180 msg[i] = mbx_data_rd32(mbx, MUCSE_MBX_FWPF_SHM + 4 * i); 181 /* Hw needs write data_reg at last */ 182 mbx_data_wr32(mbx, MUCSE_MBX_FWPF_SHM, 0); 183 /* flush reqs as we have read this request data */ 184 hw->mbx.fw_req = mucse_mbx_get_fwreq(mbx); 185 mucse_mbx_inc_pf_ack(hw); 186 mucse_release_mbx_lock_pf(hw, false); 187 188 return 0; 189 } 190 191 /** 192 * mucse_check_for_msg_pf - Check to see if the fw has sent mail 193 * @hw: pointer to the HW structure 194 * 195 * Return: 0 if the fw has set the Status bit or else -EIO 196 **/ 197 static int mucse_check_for_msg_pf(struct mucse_hw *hw) 198 { 199 struct mucse_mbx_info *mbx = &hw->mbx; 200 u16 fw_req; 201 202 fw_req = mucse_mbx_get_fwreq(mbx); 203 /* chip's register is reset to 0 when rc send reset 204 * mbx command. Return -EIO if in this state, others 205 * fw == hw->mbx.fw_req means no new msg. 206 **/ 207 if (fw_req == 0 || fw_req == hw->mbx.fw_req) 208 return -EIO; 209 210 return 0; 211 } 212 213 /** 214 * mucse_poll_for_msg - Wait for message notification 215 * @hw: pointer to the HW structure 216 * 217 * Return: 0 on success, negative errno on failure 218 **/ 219 static int mucse_poll_for_msg(struct mucse_hw *hw) 220 { 221 struct mucse_mbx_info *mbx = &hw->mbx; 222 int val; 223 224 return read_poll_timeout(mucse_check_for_msg_pf, 225 val, !val, mbx->delay_us, 226 mbx->timeout_us, 227 false, hw); 228 } 229 230 /** 231 * mucse_poll_and_read_mbx - Wait for message notification and receive message 232 * @hw: pointer to the HW structure 233 * @msg: the message buffer 234 * @size: length of buffer 235 * 236 * Return: 0 if it successfully received a message notification and 237 * copied it into the receive buffer, negative errno on failure 238 **/ 239 int mucse_poll_and_read_mbx(struct mucse_hw *hw, u32 *msg, u16 size) 240 { 241 int err; 242 243 err = mucse_poll_for_msg(hw); 244 if (err) 245 return err; 246 247 return mucse_read_mbx_pf(hw, msg, size); 248 } 249 250 /** 251 * mucse_mbx_get_fwack - Read fw ack from reg 252 * @mbx: pointer to the MBX structure 253 * 254 * Return: the fwack value 255 **/ 256 static u16 mucse_mbx_get_fwack(struct mucse_mbx_info *mbx) 257 { 258 u32 val = mbx_data_rd32(mbx, MUCSE_MBX_FW2PF_CNT); 259 260 return FIELD_GET(GENMASK_U32(31, 16), val); 261 } 262 263 /** 264 * mucse_mbx_inc_pf_req - Increase req 265 * @hw: pointer to the HW structure 266 * 267 * mucse_mbx_inc_pf_req reads pf_req from hw, then writes 268 * new value back after increase 269 **/ 270 static void mucse_mbx_inc_pf_req(struct mucse_hw *hw) 271 { 272 struct mucse_mbx_info *mbx = &hw->mbx; 273 u16 req; 274 u32 val; 275 276 val = mbx_data_rd32(mbx, MUCSE_MBX_PF2FW_CNT); 277 req = FIELD_GET(GENMASK_U32(15, 0), val); 278 req++; 279 val &= ~GENMASK_U32(15, 0); 280 val |= FIELD_PREP(GENMASK_U32(15, 0), req); 281 mbx_data_wr32(mbx, MUCSE_MBX_PF2FW_CNT, val); 282 } 283 284 /** 285 * mucse_write_mbx_pf - Place a message in the mailbox 286 * @hw: pointer to the HW structure 287 * @msg: the message buffer 288 * @size: length of buffer 289 * 290 * Return: 0 if it successfully copied message into the buffer, 291 * negative errno on failure 292 **/ 293 static int mucse_write_mbx_pf(struct mucse_hw *hw, u32 *msg, u16 size) 294 { 295 const int size_in_words = size / sizeof(u32); 296 struct mucse_mbx_info *mbx = &hw->mbx; 297 int err; 298 299 err = mucse_obtain_mbx_lock_pf(hw); 300 if (err) 301 return err; 302 303 for (int i = 0; i < size_in_words; i++) 304 mbx_data_wr32(mbx, MUCSE_MBX_FWPF_SHM + i * 4, msg[i]); 305 306 /* flush acks as we are overwriting the message buffer */ 307 hw->mbx.fw_ack = mucse_mbx_get_fwack(mbx); 308 mucse_mbx_inc_pf_req(hw); 309 mucse_release_mbx_lock_pf(hw, true); 310 311 return 0; 312 } 313 314 /** 315 * mucse_check_for_ack_pf - Check to see if the fw has ACKed 316 * @hw: pointer to the HW structure 317 * 318 * Return: 0 if the fw has set the Status bit or else -EIO 319 **/ 320 static int mucse_check_for_ack_pf(struct mucse_hw *hw) 321 { 322 struct mucse_mbx_info *mbx = &hw->mbx; 323 u16 fw_ack; 324 325 fw_ack = mucse_mbx_get_fwack(mbx); 326 /* chip's register is reset to 0 when rc send reset 327 * mbx command. Return -EIO if in this state, others 328 * fw_ack == hw->mbx.fw_ack means no new ack. 329 **/ 330 if (fw_ack == 0 || fw_ack == hw->mbx.fw_ack) 331 return -EIO; 332 333 return 0; 334 } 335 336 /** 337 * mucse_poll_for_ack - Wait for message acknowledgment 338 * @hw: pointer to the HW structure 339 * 340 * Return: 0 if it successfully received a message acknowledgment, 341 * else negative errno 342 **/ 343 static int mucse_poll_for_ack(struct mucse_hw *hw) 344 { 345 struct mucse_mbx_info *mbx = &hw->mbx; 346 int val; 347 348 return read_poll_timeout(mucse_check_for_ack_pf, 349 val, !val, mbx->delay_us, 350 mbx->timeout_us, 351 false, hw); 352 } 353 354 /** 355 * mucse_write_and_wait_ack_mbx - Write a message to the mailbox, wait for ack 356 * @hw: pointer to the HW structure 357 * @msg: the message buffer 358 * @size: length of buffer 359 * 360 * Return: 0 if it successfully copied message into the buffer and 361 * received an ack to that message within delay * timeout_cnt period 362 **/ 363 int mucse_write_and_wait_ack_mbx(struct mucse_hw *hw, u32 *msg, u16 size) 364 { 365 int err; 366 367 err = mucse_write_mbx_pf(hw, msg, size); 368 if (err) 369 return err; 370 371 return mucse_poll_for_ack(hw); 372 } 373 374 /** 375 * mucse_mbx_reset - Reset mbx info, sync info from regs 376 * @hw: pointer to the HW structure 377 * 378 * mucse_mbx_reset resets all mbx variables to default. 379 **/ 380 static void mucse_mbx_reset(struct mucse_hw *hw) 381 { 382 struct mucse_mbx_info *mbx = &hw->mbx; 383 u32 val; 384 385 val = mbx_data_rd32(mbx, MUCSE_MBX_FW2PF_CNT); 386 hw->mbx.fw_req = FIELD_GET(GENMASK_U32(15, 0), val); 387 hw->mbx.fw_ack = FIELD_GET(GENMASK_U32(31, 16), val); 388 mbx_ctrl_wr32(mbx, MUCSE_MBX_PF2FW_CTRL(mbx), 0); 389 mbx_ctrl_wr32(mbx, MUCSE_MBX_FWPF_MASK(mbx), GENMASK_U32(31, 16)); 390 } 391 392 /** 393 * mucse_init_mbx_params_pf - Set initial values for pf mailbox 394 * @hw: pointer to the HW structure 395 * 396 * Initializes the hw->mbx struct to correct values for pf mailbox 397 */ 398 void mucse_init_mbx_params_pf(struct mucse_hw *hw) 399 { 400 struct mucse_mbx_info *mbx = &hw->mbx; 401 402 mbx->delay_us = 100; 403 mbx->timeout_us = 4 * USEC_PER_SEC; 404 mutex_init(&mbx->lock); 405 mucse_mbx_reset(hw); 406 } 407