Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  FUJITSU Extended Socket Network Device driver
0004  *  Copyright (c) 2015 FUJITSU LIMITED
0005  */
0006 
0007 #include "fjes_hw.h"
0008 #include "fjes.h"
0009 #include "fjes_trace.h"
0010 
0011 static void fjes_hw_update_zone_task(struct work_struct *);
0012 static void fjes_hw_epstop_task(struct work_struct *);
0013 
0014 /* supported MTU list */
0015 const u32 fjes_support_mtu[] = {
0016     FJES_MTU_DEFINE(8 * 1024),
0017     FJES_MTU_DEFINE(16 * 1024),
0018     FJES_MTU_DEFINE(32 * 1024),
0019     FJES_MTU_DEFINE(64 * 1024),
0020     0
0021 };
0022 
0023 u32 fjes_hw_rd32(struct fjes_hw *hw, u32 reg)
0024 {
0025     u8 *base = hw->base;
0026     u32 value = 0;
0027 
0028     value = readl(&base[reg]);
0029 
0030     return value;
0031 }
0032 
0033 static u8 *fjes_hw_iomap(struct fjes_hw *hw)
0034 {
0035     u8 *base;
0036 
0037     if (!request_mem_region(hw->hw_res.start, hw->hw_res.size,
0038                 fjes_driver_name)) {
0039         pr_err("request_mem_region failed\n");
0040         return NULL;
0041     }
0042 
0043     base = (u8 *)ioremap(hw->hw_res.start, hw->hw_res.size);
0044 
0045     return base;
0046 }
0047 
0048 static void fjes_hw_iounmap(struct fjes_hw *hw)
0049 {
0050     iounmap(hw->base);
0051     release_mem_region(hw->hw_res.start, hw->hw_res.size);
0052 }
0053 
0054 int fjes_hw_reset(struct fjes_hw *hw)
0055 {
0056     union REG_DCTL dctl;
0057     int timeout;
0058 
0059     dctl.reg = 0;
0060     dctl.bits.reset = 1;
0061     wr32(XSCT_DCTL, dctl.reg);
0062 
0063     timeout = FJES_DEVICE_RESET_TIMEOUT * 1000;
0064     dctl.reg = rd32(XSCT_DCTL);
0065     while ((dctl.bits.reset == 1) && (timeout > 0)) {
0066         msleep(1000);
0067         dctl.reg = rd32(XSCT_DCTL);
0068         timeout -= 1000;
0069     }
0070 
0071     return timeout > 0 ? 0 : -EIO;
0072 }
0073 
0074 static int fjes_hw_get_max_epid(struct fjes_hw *hw)
0075 {
0076     union REG_MAX_EP info;
0077 
0078     info.reg = rd32(XSCT_MAX_EP);
0079 
0080     return info.bits.maxep;
0081 }
0082 
0083 static int fjes_hw_get_my_epid(struct fjes_hw *hw)
0084 {
0085     union REG_OWNER_EPID info;
0086 
0087     info.reg = rd32(XSCT_OWNER_EPID);
0088 
0089     return info.bits.epid;
0090 }
0091 
0092 static int fjes_hw_alloc_shared_status_region(struct fjes_hw *hw)
0093 {
0094     size_t size;
0095 
0096     size = sizeof(struct fjes_device_shared_info) +
0097         (sizeof(u8) * hw->max_epid);
0098     hw->hw_info.share = kzalloc(size, GFP_KERNEL);
0099     if (!hw->hw_info.share)
0100         return -ENOMEM;
0101 
0102     hw->hw_info.share->epnum = hw->max_epid;
0103 
0104     return 0;
0105 }
0106 
0107 static void fjes_hw_free_shared_status_region(struct fjes_hw *hw)
0108 {
0109     kfree(hw->hw_info.share);
0110     hw->hw_info.share = NULL;
0111 }
0112 
0113 static int fjes_hw_alloc_epbuf(struct epbuf_handler *epbh)
0114 {
0115     void *mem;
0116 
0117     mem = vzalloc(EP_BUFFER_SIZE);
0118     if (!mem)
0119         return -ENOMEM;
0120 
0121     epbh->buffer = mem;
0122     epbh->size = EP_BUFFER_SIZE;
0123 
0124     epbh->info = (union ep_buffer_info *)mem;
0125     epbh->ring = (u8 *)(mem + sizeof(union ep_buffer_info));
0126 
0127     return 0;
0128 }
0129 
0130 static void fjes_hw_free_epbuf(struct epbuf_handler *epbh)
0131 {
0132     vfree(epbh->buffer);
0133     epbh->buffer = NULL;
0134     epbh->size = 0;
0135 
0136     epbh->info = NULL;
0137     epbh->ring = NULL;
0138 }
0139 
0140 void fjes_hw_setup_epbuf(struct epbuf_handler *epbh, const u8 *mac_addr,
0141              u32 mtu)
0142 {
0143     union ep_buffer_info *info = epbh->info;
0144     u16 vlan_id[EP_BUFFER_SUPPORT_VLAN_MAX];
0145     int i;
0146 
0147     for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++)
0148         vlan_id[i] = info->v1i.vlan_id[i];
0149 
0150     memset(info, 0, sizeof(union ep_buffer_info));
0151 
0152     info->v1i.version = 0;  /* version 0 */
0153 
0154     for (i = 0; i < ETH_ALEN; i++)
0155         info->v1i.mac_addr[i] = mac_addr[i];
0156 
0157     info->v1i.head = 0;
0158     info->v1i.tail = 1;
0159 
0160     info->v1i.info_size = sizeof(union ep_buffer_info);
0161     info->v1i.buffer_size = epbh->size - info->v1i.info_size;
0162 
0163     info->v1i.frame_max = FJES_MTU_TO_FRAME_SIZE(mtu);
0164     info->v1i.count_max =
0165         EP_RING_NUM(info->v1i.buffer_size, info->v1i.frame_max);
0166 
0167     for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++)
0168         info->v1i.vlan_id[i] = vlan_id[i];
0169 
0170     info->v1i.rx_status |= FJES_RX_MTU_CHANGING_DONE;
0171 }
0172 
0173 void
0174 fjes_hw_init_command_registers(struct fjes_hw *hw,
0175                    struct fjes_device_command_param *param)
0176 {
0177     /* Request Buffer length */
0178     wr32(XSCT_REQBL, (__le32)(param->req_len));
0179     /* Response Buffer Length */
0180     wr32(XSCT_RESPBL, (__le32)(param->res_len));
0181 
0182     /* Request Buffer Address */
0183     wr32(XSCT_REQBAL,
0184          (__le32)(param->req_start & GENMASK_ULL(31, 0)));
0185     wr32(XSCT_REQBAH,
0186          (__le32)((param->req_start & GENMASK_ULL(63, 32)) >> 32));
0187 
0188     /* Response Buffer Address */
0189     wr32(XSCT_RESPBAL,
0190          (__le32)(param->res_start & GENMASK_ULL(31, 0)));
0191     wr32(XSCT_RESPBAH,
0192          (__le32)((param->res_start & GENMASK_ULL(63, 32)) >> 32));
0193 
0194     /* Share status address */
0195     wr32(XSCT_SHSTSAL,
0196          (__le32)(param->share_start & GENMASK_ULL(31, 0)));
0197     wr32(XSCT_SHSTSAH,
0198          (__le32)((param->share_start & GENMASK_ULL(63, 32)) >> 32));
0199 }
0200 
0201 static int fjes_hw_setup(struct fjes_hw *hw)
0202 {
0203     u8 mac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
0204     struct fjes_device_command_param param;
0205     struct ep_share_mem_info *buf_pair;
0206     unsigned long flags;
0207     size_t mem_size;
0208     int result;
0209     int epidx;
0210     void *buf;
0211 
0212     hw->hw_info.max_epid = &hw->max_epid;
0213     hw->hw_info.my_epid = &hw->my_epid;
0214 
0215     buf = kcalloc(hw->max_epid, sizeof(struct ep_share_mem_info),
0216               GFP_KERNEL);
0217     if (!buf)
0218         return -ENOMEM;
0219 
0220     hw->ep_shm_info = (struct ep_share_mem_info *)buf;
0221 
0222     mem_size = FJES_DEV_REQ_BUF_SIZE(hw->max_epid);
0223     hw->hw_info.req_buf = kzalloc(mem_size, GFP_KERNEL);
0224     if (!(hw->hw_info.req_buf))
0225         return -ENOMEM;
0226 
0227     hw->hw_info.req_buf_size = mem_size;
0228 
0229     mem_size = FJES_DEV_RES_BUF_SIZE(hw->max_epid);
0230     hw->hw_info.res_buf = kzalloc(mem_size, GFP_KERNEL);
0231     if (!(hw->hw_info.res_buf))
0232         return -ENOMEM;
0233 
0234     hw->hw_info.res_buf_size = mem_size;
0235 
0236     result = fjes_hw_alloc_shared_status_region(hw);
0237     if (result)
0238         return result;
0239 
0240     hw->hw_info.buffer_share_bit = 0;
0241     hw->hw_info.buffer_unshare_reserve_bit = 0;
0242 
0243     for (epidx = 0; epidx < hw->max_epid; epidx++) {
0244         if (epidx != hw->my_epid) {
0245             buf_pair = &hw->ep_shm_info[epidx];
0246 
0247             result = fjes_hw_alloc_epbuf(&buf_pair->tx);
0248             if (result)
0249                 return result;
0250 
0251             result = fjes_hw_alloc_epbuf(&buf_pair->rx);
0252             if (result)
0253                 return result;
0254 
0255             spin_lock_irqsave(&hw->rx_status_lock, flags);
0256             fjes_hw_setup_epbuf(&buf_pair->tx, mac,
0257                         fjes_support_mtu[0]);
0258             fjes_hw_setup_epbuf(&buf_pair->rx, mac,
0259                         fjes_support_mtu[0]);
0260             spin_unlock_irqrestore(&hw->rx_status_lock, flags);
0261         }
0262     }
0263 
0264     memset(&param, 0, sizeof(param));
0265 
0266     param.req_len = hw->hw_info.req_buf_size;
0267     param.req_start = __pa(hw->hw_info.req_buf);
0268     param.res_len = hw->hw_info.res_buf_size;
0269     param.res_start = __pa(hw->hw_info.res_buf);
0270 
0271     param.share_start = __pa(hw->hw_info.share->ep_status);
0272 
0273     fjes_hw_init_command_registers(hw, &param);
0274 
0275     return 0;
0276 }
0277 
0278 static void fjes_hw_cleanup(struct fjes_hw *hw)
0279 {
0280     int epidx;
0281 
0282     if (!hw->ep_shm_info)
0283         return;
0284 
0285     fjes_hw_free_shared_status_region(hw);
0286 
0287     kfree(hw->hw_info.req_buf);
0288     hw->hw_info.req_buf = NULL;
0289 
0290     kfree(hw->hw_info.res_buf);
0291     hw->hw_info.res_buf = NULL;
0292 
0293     for (epidx = 0; epidx < hw->max_epid ; epidx++) {
0294         if (epidx == hw->my_epid)
0295             continue;
0296         fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].tx);
0297         fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].rx);
0298     }
0299 
0300     kfree(hw->ep_shm_info);
0301     hw->ep_shm_info = NULL;
0302 }
0303 
0304 int fjes_hw_init(struct fjes_hw *hw)
0305 {
0306     int ret;
0307 
0308     hw->base = fjes_hw_iomap(hw);
0309     if (!hw->base)
0310         return -EIO;
0311 
0312     ret = fjes_hw_reset(hw);
0313     if (ret)
0314         return ret;
0315 
0316     fjes_hw_set_irqmask(hw, REG_ICTL_MASK_ALL, true);
0317 
0318     INIT_WORK(&hw->update_zone_task, fjes_hw_update_zone_task);
0319     INIT_WORK(&hw->epstop_task, fjes_hw_epstop_task);
0320 
0321     mutex_init(&hw->hw_info.lock);
0322     spin_lock_init(&hw->rx_status_lock);
0323 
0324     hw->max_epid = fjes_hw_get_max_epid(hw);
0325     hw->my_epid = fjes_hw_get_my_epid(hw);
0326 
0327     if ((hw->max_epid == 0) || (hw->my_epid >= hw->max_epid))
0328         return -ENXIO;
0329 
0330     ret = fjes_hw_setup(hw);
0331 
0332     hw->hw_info.trace = vzalloc(FJES_DEBUG_BUFFER_SIZE);
0333     hw->hw_info.trace_size = FJES_DEBUG_BUFFER_SIZE;
0334 
0335     return ret;
0336 }
0337 
0338 void fjes_hw_exit(struct fjes_hw *hw)
0339 {
0340     int ret;
0341 
0342     if (hw->base) {
0343 
0344         if (hw->debug_mode) {
0345             /* disable debug mode */
0346             mutex_lock(&hw->hw_info.lock);
0347             fjes_hw_stop_debug(hw);
0348             mutex_unlock(&hw->hw_info.lock);
0349         }
0350         vfree(hw->hw_info.trace);
0351         hw->hw_info.trace = NULL;
0352         hw->hw_info.trace_size = 0;
0353         hw->debug_mode = 0;
0354 
0355         ret = fjes_hw_reset(hw);
0356         if (ret)
0357             pr_err("%s: reset error", __func__);
0358 
0359         fjes_hw_iounmap(hw);
0360         hw->base = NULL;
0361     }
0362 
0363     fjes_hw_cleanup(hw);
0364 
0365     cancel_work_sync(&hw->update_zone_task);
0366     cancel_work_sync(&hw->epstop_task);
0367 }
0368 
0369 static enum fjes_dev_command_response_e
0370 fjes_hw_issue_request_command(struct fjes_hw *hw,
0371                   enum fjes_dev_command_request_type type)
0372 {
0373     enum fjes_dev_command_response_e ret = FJES_CMD_STATUS_UNKNOWN;
0374     union REG_CR cr;
0375     union REG_CS cs;
0376     int timeout = FJES_COMMAND_REQ_TIMEOUT * 1000;
0377 
0378     cr.reg = 0;
0379     cr.bits.req_start = 1;
0380     cr.bits.req_code = type;
0381     wr32(XSCT_CR, cr.reg);
0382     cr.reg = rd32(XSCT_CR);
0383 
0384     if (cr.bits.error == 0) {
0385         timeout = FJES_COMMAND_REQ_TIMEOUT * 1000;
0386         cs.reg = rd32(XSCT_CS);
0387 
0388         while ((cs.bits.complete != 1) && timeout > 0) {
0389             msleep(1000);
0390             cs.reg = rd32(XSCT_CS);
0391             timeout -= 1000;
0392         }
0393 
0394         if (cs.bits.complete == 1)
0395             ret = FJES_CMD_STATUS_NORMAL;
0396         else if (timeout <= 0)
0397             ret = FJES_CMD_STATUS_TIMEOUT;
0398 
0399     } else {
0400         switch (cr.bits.err_info) {
0401         case FJES_CMD_REQ_ERR_INFO_PARAM:
0402             ret = FJES_CMD_STATUS_ERROR_PARAM;
0403             break;
0404         case FJES_CMD_REQ_ERR_INFO_STATUS:
0405             ret = FJES_CMD_STATUS_ERROR_STATUS;
0406             break;
0407         default:
0408             ret = FJES_CMD_STATUS_UNKNOWN;
0409             break;
0410         }
0411     }
0412 
0413     trace_fjes_hw_issue_request_command(&cr, &cs, timeout, ret);
0414 
0415     return ret;
0416 }
0417 
0418 int fjes_hw_request_info(struct fjes_hw *hw)
0419 {
0420     union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
0421     union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
0422     enum fjes_dev_command_response_e ret;
0423     int result;
0424 
0425     memset(req_buf, 0, hw->hw_info.req_buf_size);
0426     memset(res_buf, 0, hw->hw_info.res_buf_size);
0427 
0428     req_buf->info.length = FJES_DEV_COMMAND_INFO_REQ_LEN;
0429 
0430     res_buf->info.length = 0;
0431     res_buf->info.code = 0;
0432 
0433     ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_INFO);
0434     trace_fjes_hw_request_info(hw, res_buf);
0435 
0436     result = 0;
0437 
0438     if (FJES_DEV_COMMAND_INFO_RES_LEN((*hw->hw_info.max_epid)) !=
0439         res_buf->info.length) {
0440         trace_fjes_hw_request_info_err("Invalid res_buf");
0441         result = -ENOMSG;
0442     } else if (ret == FJES_CMD_STATUS_NORMAL) {
0443         switch (res_buf->info.code) {
0444         case FJES_CMD_REQ_RES_CODE_NORMAL:
0445             result = 0;
0446             break;
0447         default:
0448             result = -EPERM;
0449             break;
0450         }
0451     } else {
0452         switch (ret) {
0453         case FJES_CMD_STATUS_UNKNOWN:
0454             result = -EPERM;
0455             break;
0456         case FJES_CMD_STATUS_TIMEOUT:
0457             trace_fjes_hw_request_info_err("Timeout");
0458             result = -EBUSY;
0459             break;
0460         case FJES_CMD_STATUS_ERROR_PARAM:
0461             result = -EPERM;
0462             break;
0463         case FJES_CMD_STATUS_ERROR_STATUS:
0464             result = -EPERM;
0465             break;
0466         default:
0467             result = -EPERM;
0468             break;
0469         }
0470     }
0471 
0472     return result;
0473 }
0474 
0475 int fjes_hw_register_buff_addr(struct fjes_hw *hw, int dest_epid,
0476                    struct ep_share_mem_info *buf_pair)
0477 {
0478     union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
0479     union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
0480     enum fjes_dev_command_response_e ret;
0481     int page_count;
0482     int timeout;
0483     int i, idx;
0484     void *addr;
0485     int result;
0486 
0487     if (test_bit(dest_epid, &hw->hw_info.buffer_share_bit))
0488         return 0;
0489 
0490     memset(req_buf, 0, hw->hw_info.req_buf_size);
0491     memset(res_buf, 0, hw->hw_info.res_buf_size);
0492 
0493     req_buf->share_buffer.length = FJES_DEV_COMMAND_SHARE_BUFFER_REQ_LEN(
0494                         buf_pair->tx.size,
0495                         buf_pair->rx.size);
0496     req_buf->share_buffer.epid = dest_epid;
0497 
0498     idx = 0;
0499     req_buf->share_buffer.buffer[idx++] = buf_pair->tx.size;
0500     page_count = buf_pair->tx.size / EP_BUFFER_INFO_SIZE;
0501     for (i = 0; i < page_count; i++) {
0502         addr = ((u8 *)(buf_pair->tx.buffer)) +
0503                 (i * EP_BUFFER_INFO_SIZE);
0504         req_buf->share_buffer.buffer[idx++] =
0505                 (__le64)(page_to_phys(vmalloc_to_page(addr)) +
0506                         offset_in_page(addr));
0507     }
0508 
0509     req_buf->share_buffer.buffer[idx++] = buf_pair->rx.size;
0510     page_count = buf_pair->rx.size / EP_BUFFER_INFO_SIZE;
0511     for (i = 0; i < page_count; i++) {
0512         addr = ((u8 *)(buf_pair->rx.buffer)) +
0513                 (i * EP_BUFFER_INFO_SIZE);
0514         req_buf->share_buffer.buffer[idx++] =
0515                 (__le64)(page_to_phys(vmalloc_to_page(addr)) +
0516                         offset_in_page(addr));
0517     }
0518 
0519     res_buf->share_buffer.length = 0;
0520     res_buf->share_buffer.code = 0;
0521 
0522     trace_fjes_hw_register_buff_addr_req(req_buf, buf_pair);
0523 
0524     ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_SHARE_BUFFER);
0525 
0526     timeout = FJES_COMMAND_REQ_BUFF_TIMEOUT * 1000;
0527     while ((ret == FJES_CMD_STATUS_NORMAL) &&
0528            (res_buf->share_buffer.length ==
0529         FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN) &&
0530            (res_buf->share_buffer.code == FJES_CMD_REQ_RES_CODE_BUSY) &&
0531            (timeout > 0)) {
0532             msleep(200 + hw->my_epid * 20);
0533             timeout -= (200 + hw->my_epid * 20);
0534 
0535             res_buf->share_buffer.length = 0;
0536             res_buf->share_buffer.code = 0;
0537 
0538             ret = fjes_hw_issue_request_command(
0539                     hw, FJES_CMD_REQ_SHARE_BUFFER);
0540     }
0541 
0542     result = 0;
0543 
0544     trace_fjes_hw_register_buff_addr(res_buf, timeout);
0545 
0546     if (res_buf->share_buffer.length !=
0547             FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN) {
0548         trace_fjes_hw_register_buff_addr_err("Invalid res_buf");
0549         result = -ENOMSG;
0550     } else if (ret == FJES_CMD_STATUS_NORMAL) {
0551         switch (res_buf->share_buffer.code) {
0552         case FJES_CMD_REQ_RES_CODE_NORMAL:
0553             result = 0;
0554             set_bit(dest_epid, &hw->hw_info.buffer_share_bit);
0555             break;
0556         case FJES_CMD_REQ_RES_CODE_BUSY:
0557             trace_fjes_hw_register_buff_addr_err("Busy Timeout");
0558             result = -EBUSY;
0559             break;
0560         default:
0561             result = -EPERM;
0562             break;
0563         }
0564     } else {
0565         switch (ret) {
0566         case FJES_CMD_STATUS_UNKNOWN:
0567             result = -EPERM;
0568             break;
0569         case FJES_CMD_STATUS_TIMEOUT:
0570             trace_fjes_hw_register_buff_addr_err("Timeout");
0571             result = -EBUSY;
0572             break;
0573         case FJES_CMD_STATUS_ERROR_PARAM:
0574         case FJES_CMD_STATUS_ERROR_STATUS:
0575         default:
0576             result = -EPERM;
0577             break;
0578         }
0579     }
0580 
0581     return result;
0582 }
0583 
0584 int fjes_hw_unregister_buff_addr(struct fjes_hw *hw, int dest_epid)
0585 {
0586     union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
0587     union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
0588     struct fjes_device_shared_info *share = hw->hw_info.share;
0589     enum fjes_dev_command_response_e ret;
0590     int timeout;
0591     int result;
0592 
0593     if (!hw->base)
0594         return -EPERM;
0595 
0596     if (!req_buf || !res_buf || !share)
0597         return -EPERM;
0598 
0599     if (!test_bit(dest_epid, &hw->hw_info.buffer_share_bit))
0600         return 0;
0601 
0602     memset(req_buf, 0, hw->hw_info.req_buf_size);
0603     memset(res_buf, 0, hw->hw_info.res_buf_size);
0604 
0605     req_buf->unshare_buffer.length =
0606             FJES_DEV_COMMAND_UNSHARE_BUFFER_REQ_LEN;
0607     req_buf->unshare_buffer.epid = dest_epid;
0608 
0609     res_buf->unshare_buffer.length = 0;
0610     res_buf->unshare_buffer.code = 0;
0611 
0612     trace_fjes_hw_unregister_buff_addr_req(req_buf);
0613     ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_UNSHARE_BUFFER);
0614 
0615     timeout = FJES_COMMAND_REQ_BUFF_TIMEOUT * 1000;
0616     while ((ret == FJES_CMD_STATUS_NORMAL) &&
0617            (res_buf->unshare_buffer.length ==
0618         FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN) &&
0619            (res_buf->unshare_buffer.code ==
0620         FJES_CMD_REQ_RES_CODE_BUSY) &&
0621            (timeout > 0)) {
0622         msleep(200 + hw->my_epid * 20);
0623         timeout -= (200 + hw->my_epid * 20);
0624 
0625         res_buf->unshare_buffer.length = 0;
0626         res_buf->unshare_buffer.code = 0;
0627 
0628         ret =
0629         fjes_hw_issue_request_command(hw, FJES_CMD_REQ_UNSHARE_BUFFER);
0630     }
0631 
0632     result = 0;
0633 
0634     trace_fjes_hw_unregister_buff_addr(res_buf, timeout);
0635 
0636     if (res_buf->unshare_buffer.length !=
0637             FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN) {
0638         trace_fjes_hw_unregister_buff_addr_err("Invalid res_buf");
0639         result = -ENOMSG;
0640     } else if (ret == FJES_CMD_STATUS_NORMAL) {
0641         switch (res_buf->unshare_buffer.code) {
0642         case FJES_CMD_REQ_RES_CODE_NORMAL:
0643             result = 0;
0644             clear_bit(dest_epid, &hw->hw_info.buffer_share_bit);
0645             break;
0646         case FJES_CMD_REQ_RES_CODE_BUSY:
0647             trace_fjes_hw_unregister_buff_addr_err("Busy Timeout");
0648             result = -EBUSY;
0649             break;
0650         default:
0651             result = -EPERM;
0652             break;
0653         }
0654     } else {
0655         switch (ret) {
0656         case FJES_CMD_STATUS_UNKNOWN:
0657             result = -EPERM;
0658             break;
0659         case FJES_CMD_STATUS_TIMEOUT:
0660             trace_fjes_hw_unregister_buff_addr_err("Timeout");
0661             result = -EBUSY;
0662             break;
0663         case FJES_CMD_STATUS_ERROR_PARAM:
0664         case FJES_CMD_STATUS_ERROR_STATUS:
0665         default:
0666             result = -EPERM;
0667             break;
0668         }
0669     }
0670 
0671     return result;
0672 }
0673 
0674 int fjes_hw_raise_interrupt(struct fjes_hw *hw, int dest_epid,
0675                 enum REG_ICTL_MASK  mask)
0676 {
0677     u32 ig = mask | dest_epid;
0678 
0679     wr32(XSCT_IG, cpu_to_le32(ig));
0680 
0681     return 0;
0682 }
0683 
0684 u32 fjes_hw_capture_interrupt_status(struct fjes_hw *hw)
0685 {
0686     u32 cur_is;
0687 
0688     cur_is = rd32(XSCT_IS);
0689 
0690     return cur_is;
0691 }
0692 
0693 void fjes_hw_set_irqmask(struct fjes_hw *hw,
0694              enum REG_ICTL_MASK intr_mask, bool mask)
0695 {
0696     if (mask)
0697         wr32(XSCT_IMS, intr_mask);
0698     else
0699         wr32(XSCT_IMC, intr_mask);
0700 }
0701 
0702 bool fjes_hw_epid_is_same_zone(struct fjes_hw *hw, int epid)
0703 {
0704     if (epid >= hw->max_epid)
0705         return false;
0706 
0707     if ((hw->ep_shm_info[epid].es_status !=
0708             FJES_ZONING_STATUS_ENABLE) ||
0709         (hw->ep_shm_info[hw->my_epid].zone ==
0710             FJES_ZONING_ZONE_TYPE_NONE))
0711         return false;
0712     else
0713         return (hw->ep_shm_info[epid].zone ==
0714                 hw->ep_shm_info[hw->my_epid].zone);
0715 }
0716 
0717 int fjes_hw_epid_is_shared(struct fjes_device_shared_info *share,
0718                int dest_epid)
0719 {
0720     int value = false;
0721 
0722     if (dest_epid < share->epnum)
0723         value = share->ep_status[dest_epid];
0724 
0725     return value;
0726 }
0727 
0728 static bool fjes_hw_epid_is_stop_requested(struct fjes_hw *hw, int src_epid)
0729 {
0730     return test_bit(src_epid, &hw->txrx_stop_req_bit);
0731 }
0732 
0733 static bool fjes_hw_epid_is_stop_process_done(struct fjes_hw *hw, int src_epid)
0734 {
0735     return (hw->ep_shm_info[src_epid].tx.info->v1i.rx_status &
0736             FJES_RX_STOP_REQ_DONE);
0737 }
0738 
0739 enum ep_partner_status
0740 fjes_hw_get_partner_ep_status(struct fjes_hw *hw, int epid)
0741 {
0742     enum ep_partner_status status;
0743 
0744     if (fjes_hw_epid_is_shared(hw->hw_info.share, epid)) {
0745         if (fjes_hw_epid_is_stop_requested(hw, epid)) {
0746             status = EP_PARTNER_WAITING;
0747         } else {
0748             if (fjes_hw_epid_is_stop_process_done(hw, epid))
0749                 status = EP_PARTNER_COMPLETE;
0750             else
0751                 status = EP_PARTNER_SHARED;
0752         }
0753     } else {
0754         status = EP_PARTNER_UNSHARE;
0755     }
0756 
0757     return status;
0758 }
0759 
0760 void fjes_hw_raise_epstop(struct fjes_hw *hw)
0761 {
0762     enum ep_partner_status status;
0763     unsigned long flags;
0764     int epidx;
0765 
0766     for (epidx = 0; epidx < hw->max_epid; epidx++) {
0767         if (epidx == hw->my_epid)
0768             continue;
0769 
0770         status = fjes_hw_get_partner_ep_status(hw, epidx);
0771         switch (status) {
0772         case EP_PARTNER_SHARED:
0773             fjes_hw_raise_interrupt(hw, epidx,
0774                         REG_ICTL_MASK_TXRX_STOP_REQ);
0775             hw->ep_shm_info[epidx].ep_stats.send_intr_unshare += 1;
0776             break;
0777         default:
0778             break;
0779         }
0780 
0781         set_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit);
0782         set_bit(epidx, &hw->txrx_stop_req_bit);
0783 
0784         spin_lock_irqsave(&hw->rx_status_lock, flags);
0785         hw->ep_shm_info[epidx].tx.info->v1i.rx_status |=
0786                 FJES_RX_STOP_REQ_REQUEST;
0787         spin_unlock_irqrestore(&hw->rx_status_lock, flags);
0788     }
0789 }
0790 
0791 int fjes_hw_wait_epstop(struct fjes_hw *hw)
0792 {
0793     enum ep_partner_status status;
0794     union ep_buffer_info *info;
0795     int wait_time = 0;
0796     int epidx;
0797 
0798     while (hw->hw_info.buffer_unshare_reserve_bit &&
0799            (wait_time < FJES_COMMAND_EPSTOP_WAIT_TIMEOUT * 1000)) {
0800         for (epidx = 0; epidx < hw->max_epid; epidx++) {
0801             if (epidx == hw->my_epid)
0802                 continue;
0803             status = fjes_hw_epid_is_shared(hw->hw_info.share,
0804                             epidx);
0805             info = hw->ep_shm_info[epidx].rx.info;
0806             if ((!status ||
0807                  (info->v1i.rx_status &
0808                   FJES_RX_STOP_REQ_DONE)) &&
0809                 test_bit(epidx,
0810                      &hw->hw_info.buffer_unshare_reserve_bit)) {
0811                 clear_bit(epidx,
0812                       &hw->hw_info.buffer_unshare_reserve_bit);
0813             }
0814         }
0815 
0816         msleep(100);
0817         wait_time += 100;
0818     }
0819 
0820     for (epidx = 0; epidx < hw->max_epid; epidx++) {
0821         if (epidx == hw->my_epid)
0822             continue;
0823         if (test_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit))
0824             clear_bit(epidx,
0825                   &hw->hw_info.buffer_unshare_reserve_bit);
0826     }
0827 
0828     return (wait_time < FJES_COMMAND_EPSTOP_WAIT_TIMEOUT * 1000)
0829             ? 0 : -EBUSY;
0830 }
0831 
0832 bool fjes_hw_check_epbuf_version(struct epbuf_handler *epbh, u32 version)
0833 {
0834     union ep_buffer_info *info = epbh->info;
0835 
0836     return (info->common.version == version);
0837 }
0838 
0839 bool fjes_hw_check_mtu(struct epbuf_handler *epbh, u32 mtu)
0840 {
0841     union ep_buffer_info *info = epbh->info;
0842 
0843     return ((info->v1i.frame_max == FJES_MTU_TO_FRAME_SIZE(mtu)) &&
0844         info->v1i.rx_status & FJES_RX_MTU_CHANGING_DONE);
0845 }
0846 
0847 bool fjes_hw_check_vlan_id(struct epbuf_handler *epbh, u16 vlan_id)
0848 {
0849     union ep_buffer_info *info = epbh->info;
0850     bool ret = false;
0851     int i;
0852 
0853     if (vlan_id == 0) {
0854         ret = true;
0855     } else {
0856         for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++) {
0857             if (vlan_id == info->v1i.vlan_id[i]) {
0858                 ret = true;
0859                 break;
0860             }
0861         }
0862     }
0863     return ret;
0864 }
0865 
0866 bool fjes_hw_set_vlan_id(struct epbuf_handler *epbh, u16 vlan_id)
0867 {
0868     union ep_buffer_info *info = epbh->info;
0869     int i;
0870 
0871     for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++) {
0872         if (info->v1i.vlan_id[i] == 0) {
0873             info->v1i.vlan_id[i] = vlan_id;
0874             return true;
0875         }
0876     }
0877     return false;
0878 }
0879 
0880 void fjes_hw_del_vlan_id(struct epbuf_handler *epbh, u16 vlan_id)
0881 {
0882     union ep_buffer_info *info = epbh->info;
0883     int i;
0884 
0885     if (0 != vlan_id) {
0886         for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++) {
0887             if (vlan_id == info->v1i.vlan_id[i])
0888                 info->v1i.vlan_id[i] = 0;
0889         }
0890     }
0891 }
0892 
0893 bool fjes_hw_epbuf_rx_is_empty(struct epbuf_handler *epbh)
0894 {
0895     union ep_buffer_info *info = epbh->info;
0896 
0897     if (!(info->v1i.rx_status & FJES_RX_MTU_CHANGING_DONE))
0898         return true;
0899 
0900     if (info->v1i.count_max == 0)
0901         return true;
0902 
0903     return EP_RING_EMPTY(info->v1i.head, info->v1i.tail,
0904                  info->v1i.count_max);
0905 }
0906 
0907 void *fjes_hw_epbuf_rx_curpkt_get_addr(struct epbuf_handler *epbh,
0908                        size_t *psize)
0909 {
0910     union ep_buffer_info *info = epbh->info;
0911     struct esmem_frame *ring_frame;
0912     void *frame;
0913 
0914     ring_frame = (struct esmem_frame *)&(epbh->ring[EP_RING_INDEX
0915                          (info->v1i.head,
0916                           info->v1i.count_max) *
0917                          info->v1i.frame_max]);
0918 
0919     *psize = (size_t)ring_frame->frame_size;
0920 
0921     frame = ring_frame->frame_data;
0922 
0923     return frame;
0924 }
0925 
0926 void fjes_hw_epbuf_rx_curpkt_drop(struct epbuf_handler *epbh)
0927 {
0928     union ep_buffer_info *info = epbh->info;
0929 
0930     if (fjes_hw_epbuf_rx_is_empty(epbh))
0931         return;
0932 
0933     EP_RING_INDEX_INC(epbh->info->v1i.head, info->v1i.count_max);
0934 }
0935 
0936 int fjes_hw_epbuf_tx_pkt_send(struct epbuf_handler *epbh,
0937                   void *frame, size_t size)
0938 {
0939     union ep_buffer_info *info = epbh->info;
0940     struct esmem_frame *ring_frame;
0941 
0942     if (EP_RING_FULL(info->v1i.head, info->v1i.tail, info->v1i.count_max))
0943         return -ENOBUFS;
0944 
0945     ring_frame = (struct esmem_frame *)&(epbh->ring[EP_RING_INDEX
0946                          (info->v1i.tail - 1,
0947                           info->v1i.count_max) *
0948                          info->v1i.frame_max]);
0949 
0950     ring_frame->frame_size = size;
0951     memcpy((void *)(ring_frame->frame_data), (void *)frame, size);
0952 
0953     EP_RING_INDEX_INC(epbh->info->v1i.tail, info->v1i.count_max);
0954 
0955     return 0;
0956 }
0957 
0958 static void fjes_hw_update_zone_task(struct work_struct *work)
0959 {
0960     struct fjes_hw *hw = container_of(work,
0961             struct fjes_hw, update_zone_task);
0962 
0963     struct my_s {u8 es_status; u8 zone; } *info;
0964     union fjes_device_command_res *res_buf;
0965     enum ep_partner_status pstatus;
0966 
0967     struct fjes_adapter *adapter;
0968     struct net_device *netdev;
0969     unsigned long flags;
0970 
0971     ulong unshare_bit = 0;
0972     ulong share_bit = 0;
0973     ulong irq_bit = 0;
0974 
0975     int epidx;
0976     int ret;
0977 
0978     adapter = (struct fjes_adapter *)hw->back;
0979     netdev = adapter->netdev;
0980     res_buf = hw->hw_info.res_buf;
0981     info = (struct my_s *)&res_buf->info.info;
0982 
0983     mutex_lock(&hw->hw_info.lock);
0984 
0985     ret = fjes_hw_request_info(hw);
0986     switch (ret) {
0987     case -ENOMSG:
0988     case -EBUSY:
0989     default:
0990         if (!work_pending(&adapter->force_close_task)) {
0991             adapter->force_reset = true;
0992             schedule_work(&adapter->force_close_task);
0993         }
0994         break;
0995 
0996     case 0:
0997 
0998         for (epidx = 0; epidx < hw->max_epid; epidx++) {
0999             if (epidx == hw->my_epid) {
1000                 hw->ep_shm_info[epidx].es_status =
1001                     info[epidx].es_status;
1002                 hw->ep_shm_info[epidx].zone =
1003                     info[epidx].zone;
1004                 continue;
1005             }
1006 
1007             pstatus = fjes_hw_get_partner_ep_status(hw, epidx);
1008             switch (pstatus) {
1009             case EP_PARTNER_UNSHARE:
1010             default:
1011                 if ((info[epidx].zone !=
1012                     FJES_ZONING_ZONE_TYPE_NONE) &&
1013                     (info[epidx].es_status ==
1014                     FJES_ZONING_STATUS_ENABLE) &&
1015                     (info[epidx].zone ==
1016                     info[hw->my_epid].zone))
1017                     set_bit(epidx, &share_bit);
1018                 else
1019                     set_bit(epidx, &unshare_bit);
1020                 break;
1021 
1022             case EP_PARTNER_COMPLETE:
1023             case EP_PARTNER_WAITING:
1024                 if ((info[epidx].zone ==
1025                     FJES_ZONING_ZONE_TYPE_NONE) ||
1026                     (info[epidx].es_status !=
1027                     FJES_ZONING_STATUS_ENABLE) ||
1028                     (info[epidx].zone !=
1029                     info[hw->my_epid].zone)) {
1030                     set_bit(epidx,
1031                         &adapter->unshare_watch_bitmask);
1032                     set_bit(epidx,
1033                         &hw->hw_info.buffer_unshare_reserve_bit);
1034                 }
1035                 break;
1036 
1037             case EP_PARTNER_SHARED:
1038                 if ((info[epidx].zone ==
1039                     FJES_ZONING_ZONE_TYPE_NONE) ||
1040                     (info[epidx].es_status !=
1041                     FJES_ZONING_STATUS_ENABLE) ||
1042                     (info[epidx].zone !=
1043                     info[hw->my_epid].zone))
1044                     set_bit(epidx, &irq_bit);
1045                 break;
1046             }
1047 
1048             hw->ep_shm_info[epidx].es_status =
1049                 info[epidx].es_status;
1050             hw->ep_shm_info[epidx].zone = info[epidx].zone;
1051         }
1052         break;
1053     }
1054 
1055     mutex_unlock(&hw->hw_info.lock);
1056 
1057     for (epidx = 0; epidx < hw->max_epid; epidx++) {
1058         if (epidx == hw->my_epid)
1059             continue;
1060 
1061         if (test_bit(epidx, &share_bit)) {
1062             spin_lock_irqsave(&hw->rx_status_lock, flags);
1063             fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx,
1064                         netdev->dev_addr, netdev->mtu);
1065             spin_unlock_irqrestore(&hw->rx_status_lock, flags);
1066 
1067             mutex_lock(&hw->hw_info.lock);
1068 
1069             ret = fjes_hw_register_buff_addr(
1070                 hw, epidx, &hw->ep_shm_info[epidx]);
1071 
1072             switch (ret) {
1073             case 0:
1074                 break;
1075             case -ENOMSG:
1076             case -EBUSY:
1077             default:
1078                 if (!work_pending(&adapter->force_close_task)) {
1079                     adapter->force_reset = true;
1080                     schedule_work(
1081                       &adapter->force_close_task);
1082                 }
1083                 break;
1084             }
1085             mutex_unlock(&hw->hw_info.lock);
1086 
1087             hw->ep_shm_info[epidx].ep_stats
1088                           .com_regist_buf_exec += 1;
1089         }
1090 
1091         if (test_bit(epidx, &unshare_bit)) {
1092             mutex_lock(&hw->hw_info.lock);
1093 
1094             ret = fjes_hw_unregister_buff_addr(hw, epidx);
1095 
1096             switch (ret) {
1097             case 0:
1098                 break;
1099             case -ENOMSG:
1100             case -EBUSY:
1101             default:
1102                 if (!work_pending(&adapter->force_close_task)) {
1103                     adapter->force_reset = true;
1104                     schedule_work(
1105                       &adapter->force_close_task);
1106                 }
1107                 break;
1108             }
1109 
1110             mutex_unlock(&hw->hw_info.lock);
1111 
1112             hw->ep_shm_info[epidx].ep_stats
1113                           .com_unregist_buf_exec += 1;
1114 
1115             if (ret == 0) {
1116                 spin_lock_irqsave(&hw->rx_status_lock, flags);
1117                 fjes_hw_setup_epbuf(
1118                     &hw->ep_shm_info[epidx].tx,
1119                     netdev->dev_addr, netdev->mtu);
1120                 spin_unlock_irqrestore(&hw->rx_status_lock,
1121                                flags);
1122             }
1123         }
1124 
1125         if (test_bit(epidx, &irq_bit)) {
1126             fjes_hw_raise_interrupt(hw, epidx,
1127                         REG_ICTL_MASK_TXRX_STOP_REQ);
1128 
1129             hw->ep_shm_info[epidx].ep_stats.send_intr_unshare += 1;
1130 
1131             set_bit(epidx, &hw->txrx_stop_req_bit);
1132             spin_lock_irqsave(&hw->rx_status_lock, flags);
1133             hw->ep_shm_info[epidx].tx.
1134                 info->v1i.rx_status |=
1135                     FJES_RX_STOP_REQ_REQUEST;
1136             spin_unlock_irqrestore(&hw->rx_status_lock, flags);
1137             set_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit);
1138         }
1139     }
1140 
1141     if (irq_bit || adapter->unshare_watch_bitmask) {
1142         if (!work_pending(&adapter->unshare_watch_task))
1143             queue_work(adapter->control_wq,
1144                    &adapter->unshare_watch_task);
1145     }
1146 }
1147 
1148 static void fjes_hw_epstop_task(struct work_struct *work)
1149 {
1150     struct fjes_hw *hw = container_of(work, struct fjes_hw, epstop_task);
1151     struct fjes_adapter *adapter = (struct fjes_adapter *)hw->back;
1152     unsigned long flags;
1153 
1154     ulong remain_bit;
1155     int epid_bit;
1156 
1157     while ((remain_bit = hw->epstop_req_bit)) {
1158         for (epid_bit = 0; remain_bit; remain_bit >>= 1, epid_bit++) {
1159             if (remain_bit & 1) {
1160                 spin_lock_irqsave(&hw->rx_status_lock, flags);
1161                 hw->ep_shm_info[epid_bit].
1162                     tx.info->v1i.rx_status |=
1163                         FJES_RX_STOP_REQ_DONE;
1164                 spin_unlock_irqrestore(&hw->rx_status_lock,
1165                                flags);
1166 
1167                 clear_bit(epid_bit, &hw->epstop_req_bit);
1168                 set_bit(epid_bit,
1169                     &adapter->unshare_watch_bitmask);
1170 
1171                 if (!work_pending(&adapter->unshare_watch_task))
1172                     queue_work(
1173                         adapter->control_wq,
1174                         &adapter->unshare_watch_task);
1175             }
1176         }
1177     }
1178 }
1179 
1180 int fjes_hw_start_debug(struct fjes_hw *hw)
1181 {
1182     union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
1183     union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
1184     enum fjes_dev_command_response_e ret;
1185     int page_count;
1186     int result = 0;
1187     void *addr;
1188     int i;
1189 
1190     if (!hw->hw_info.trace)
1191         return -EPERM;
1192     memset(hw->hw_info.trace, 0, FJES_DEBUG_BUFFER_SIZE);
1193 
1194     memset(req_buf, 0, hw->hw_info.req_buf_size);
1195     memset(res_buf, 0, hw->hw_info.res_buf_size);
1196 
1197     req_buf->start_trace.length =
1198         FJES_DEV_COMMAND_START_DBG_REQ_LEN(hw->hw_info.trace_size);
1199     req_buf->start_trace.mode = hw->debug_mode;
1200     req_buf->start_trace.buffer_len = hw->hw_info.trace_size;
1201     page_count = hw->hw_info.trace_size / FJES_DEBUG_PAGE_SIZE;
1202     for (i = 0; i < page_count; i++) {
1203         addr = ((u8 *)hw->hw_info.trace) + i * FJES_DEBUG_PAGE_SIZE;
1204         req_buf->start_trace.buffer[i] =
1205             (__le64)(page_to_phys(vmalloc_to_page(addr)) +
1206             offset_in_page(addr));
1207     }
1208 
1209     res_buf->start_trace.length = 0;
1210     res_buf->start_trace.code = 0;
1211 
1212     trace_fjes_hw_start_debug_req(req_buf);
1213     ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_START_DEBUG);
1214     trace_fjes_hw_start_debug(res_buf);
1215 
1216     if (res_buf->start_trace.length !=
1217         FJES_DEV_COMMAND_START_DBG_RES_LEN) {
1218         result = -ENOMSG;
1219         trace_fjes_hw_start_debug_err("Invalid res_buf");
1220     } else if (ret == FJES_CMD_STATUS_NORMAL) {
1221         switch (res_buf->start_trace.code) {
1222         case FJES_CMD_REQ_RES_CODE_NORMAL:
1223             result = 0;
1224             break;
1225         default:
1226             result = -EPERM;
1227             break;
1228         }
1229     } else {
1230         switch (ret) {
1231         case FJES_CMD_STATUS_UNKNOWN:
1232             result = -EPERM;
1233             break;
1234         case FJES_CMD_STATUS_TIMEOUT:
1235             trace_fjes_hw_start_debug_err("Busy Timeout");
1236             result = -EBUSY;
1237             break;
1238         case FJES_CMD_STATUS_ERROR_PARAM:
1239         case FJES_CMD_STATUS_ERROR_STATUS:
1240         default:
1241             result = -EPERM;
1242             break;
1243         }
1244     }
1245 
1246     return result;
1247 }
1248 
1249 int fjes_hw_stop_debug(struct fjes_hw *hw)
1250 {
1251     union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
1252     union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
1253     enum fjes_dev_command_response_e ret;
1254     int result = 0;
1255 
1256     if (!hw->hw_info.trace)
1257         return -EPERM;
1258 
1259     memset(req_buf, 0, hw->hw_info.req_buf_size);
1260     memset(res_buf, 0, hw->hw_info.res_buf_size);
1261     req_buf->stop_trace.length = FJES_DEV_COMMAND_STOP_DBG_REQ_LEN;
1262 
1263     res_buf->stop_trace.length = 0;
1264     res_buf->stop_trace.code = 0;
1265 
1266     ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_STOP_DEBUG);
1267     trace_fjes_hw_stop_debug(res_buf);
1268 
1269     if (res_buf->stop_trace.length != FJES_DEV_COMMAND_STOP_DBG_RES_LEN) {
1270         trace_fjes_hw_stop_debug_err("Invalid res_buf");
1271         result = -ENOMSG;
1272     } else if (ret == FJES_CMD_STATUS_NORMAL) {
1273         switch (res_buf->stop_trace.code) {
1274         case FJES_CMD_REQ_RES_CODE_NORMAL:
1275             result = 0;
1276             hw->debug_mode = 0;
1277             break;
1278         default:
1279             result = -EPERM;
1280             break;
1281         }
1282     } else {
1283         switch (ret) {
1284         case FJES_CMD_STATUS_UNKNOWN:
1285             result = -EPERM;
1286             break;
1287         case FJES_CMD_STATUS_TIMEOUT:
1288             result = -EBUSY;
1289             trace_fjes_hw_stop_debug_err("Busy Timeout");
1290             break;
1291         case FJES_CMD_STATUS_ERROR_PARAM:
1292         case FJES_CMD_STATUS_ERROR_STATUS:
1293         default:
1294             result = -EPERM;
1295             break;
1296         }
1297     }
1298 
1299     return result;
1300 }