GNU Linux-libre 6.8.9-gnu
[releases.git] / drivers / net / fjes / fjes_hw.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  FUJITSU Extended Socket Network Device driver
4  *  Copyright (c) 2015 FUJITSU LIMITED
5  */
6
7 #include "fjes_hw.h"
8 #include "fjes.h"
9 #include "fjes_trace.h"
10
11 static void fjes_hw_update_zone_task(struct work_struct *);
12 static void fjes_hw_epstop_task(struct work_struct *);
13
14 /* supported MTU list */
15 const u32 fjes_support_mtu[] = {
16         FJES_MTU_DEFINE(8 * 1024),
17         FJES_MTU_DEFINE(16 * 1024),
18         FJES_MTU_DEFINE(32 * 1024),
19         FJES_MTU_DEFINE(64 * 1024),
20         0
21 };
22
23 u32 fjes_hw_rd32(struct fjes_hw *hw, u32 reg)
24 {
25         u8 *base = hw->base;
26         u32 value = 0;
27
28         value = readl(&base[reg]);
29
30         return value;
31 }
32
33 static u8 *fjes_hw_iomap(struct fjes_hw *hw)
34 {
35         u8 *base;
36
37         if (!request_mem_region(hw->hw_res.start, hw->hw_res.size,
38                                 fjes_driver_name)) {
39                 pr_err("request_mem_region failed\n");
40                 return NULL;
41         }
42
43         base = (u8 *)ioremap(hw->hw_res.start, hw->hw_res.size);
44
45         return base;
46 }
47
48 static void fjes_hw_iounmap(struct fjes_hw *hw)
49 {
50         iounmap(hw->base);
51         release_mem_region(hw->hw_res.start, hw->hw_res.size);
52 }
53
54 int fjes_hw_reset(struct fjes_hw *hw)
55 {
56         union REG_DCTL dctl;
57         int timeout;
58
59         dctl.reg = 0;
60         dctl.bits.reset = 1;
61         wr32(XSCT_DCTL, dctl.reg);
62
63         timeout = FJES_DEVICE_RESET_TIMEOUT * 1000;
64         dctl.reg = rd32(XSCT_DCTL);
65         while ((dctl.bits.reset == 1) && (timeout > 0)) {
66                 msleep(1000);
67                 dctl.reg = rd32(XSCT_DCTL);
68                 timeout -= 1000;
69         }
70
71         return timeout > 0 ? 0 : -EIO;
72 }
73
74 static int fjes_hw_get_max_epid(struct fjes_hw *hw)
75 {
76         union REG_MAX_EP info;
77
78         info.reg = rd32(XSCT_MAX_EP);
79
80         return info.bits.maxep;
81 }
82
83 static int fjes_hw_get_my_epid(struct fjes_hw *hw)
84 {
85         union REG_OWNER_EPID info;
86
87         info.reg = rd32(XSCT_OWNER_EPID);
88
89         return info.bits.epid;
90 }
91
92 static int fjes_hw_alloc_shared_status_region(struct fjes_hw *hw)
93 {
94         size_t size;
95
96         size = sizeof(struct fjes_device_shared_info) +
97             (sizeof(u8) * hw->max_epid);
98         hw->hw_info.share = kzalloc(size, GFP_KERNEL);
99         if (!hw->hw_info.share)
100                 return -ENOMEM;
101
102         hw->hw_info.share->epnum = hw->max_epid;
103
104         return 0;
105 }
106
107 static void fjes_hw_free_shared_status_region(struct fjes_hw *hw)
108 {
109         kfree(hw->hw_info.share);
110         hw->hw_info.share = NULL;
111 }
112
113 static int fjes_hw_alloc_epbuf(struct epbuf_handler *epbh)
114 {
115         void *mem;
116
117         mem = vzalloc(EP_BUFFER_SIZE);
118         if (!mem)
119                 return -ENOMEM;
120
121         epbh->buffer = mem;
122         epbh->size = EP_BUFFER_SIZE;
123
124         epbh->info = (union ep_buffer_info *)mem;
125         epbh->ring = (u8 *)(mem + sizeof(union ep_buffer_info));
126
127         return 0;
128 }
129
130 static void fjes_hw_free_epbuf(struct epbuf_handler *epbh)
131 {
132         vfree(epbh->buffer);
133         epbh->buffer = NULL;
134         epbh->size = 0;
135
136         epbh->info = NULL;
137         epbh->ring = NULL;
138 }
139
140 void fjes_hw_setup_epbuf(struct epbuf_handler *epbh, const u8 *mac_addr,
141                          u32 mtu)
142 {
143         union ep_buffer_info *info = epbh->info;
144         u16 vlan_id[EP_BUFFER_SUPPORT_VLAN_MAX];
145         int i;
146
147         for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++)
148                 vlan_id[i] = info->v1i.vlan_id[i];
149
150         memset(info, 0, sizeof(union ep_buffer_info));
151
152         info->v1i.version = 0;  /* version 0 */
153
154         for (i = 0; i < ETH_ALEN; i++)
155                 info->v1i.mac_addr[i] = mac_addr[i];
156
157         info->v1i.head = 0;
158         info->v1i.tail = 1;
159
160         info->v1i.info_size = sizeof(union ep_buffer_info);
161         info->v1i.buffer_size = epbh->size - info->v1i.info_size;
162
163         info->v1i.frame_max = FJES_MTU_TO_FRAME_SIZE(mtu);
164         info->v1i.count_max =
165             EP_RING_NUM(info->v1i.buffer_size, info->v1i.frame_max);
166
167         for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++)
168                 info->v1i.vlan_id[i] = vlan_id[i];
169
170         info->v1i.rx_status |= FJES_RX_MTU_CHANGING_DONE;
171 }
172
173 void
174 fjes_hw_init_command_registers(struct fjes_hw *hw,
175                                struct fjes_device_command_param *param)
176 {
177         /* Request Buffer length */
178         wr32(XSCT_REQBL, (__le32)(param->req_len));
179         /* Response Buffer Length */
180         wr32(XSCT_RESPBL, (__le32)(param->res_len));
181
182         /* Request Buffer Address */
183         wr32(XSCT_REQBAL,
184              (__le32)(param->req_start & GENMASK_ULL(31, 0)));
185         wr32(XSCT_REQBAH,
186              (__le32)((param->req_start & GENMASK_ULL(63, 32)) >> 32));
187
188         /* Response Buffer Address */
189         wr32(XSCT_RESPBAL,
190              (__le32)(param->res_start & GENMASK_ULL(31, 0)));
191         wr32(XSCT_RESPBAH,
192              (__le32)((param->res_start & GENMASK_ULL(63, 32)) >> 32));
193
194         /* Share status address */
195         wr32(XSCT_SHSTSAL,
196              (__le32)(param->share_start & GENMASK_ULL(31, 0)));
197         wr32(XSCT_SHSTSAH,
198              (__le32)((param->share_start & GENMASK_ULL(63, 32)) >> 32));
199 }
200
201 static int fjes_hw_setup(struct fjes_hw *hw)
202 {
203         u8 mac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
204         struct fjes_device_command_param param;
205         struct ep_share_mem_info *buf_pair;
206         unsigned long flags;
207         size_t mem_size;
208         int result;
209         int epidx;
210         void *buf;
211
212         hw->hw_info.max_epid = &hw->max_epid;
213         hw->hw_info.my_epid = &hw->my_epid;
214
215         buf = kcalloc(hw->max_epid, sizeof(struct ep_share_mem_info),
216                       GFP_KERNEL);
217         if (!buf)
218                 return -ENOMEM;
219
220         hw->ep_shm_info = (struct ep_share_mem_info *)buf;
221
222         mem_size = FJES_DEV_REQ_BUF_SIZE(hw->max_epid);
223         hw->hw_info.req_buf = kzalloc(mem_size, GFP_KERNEL);
224         if (!(hw->hw_info.req_buf)) {
225                 result = -ENOMEM;
226                 goto free_ep_info;
227         }
228
229         hw->hw_info.req_buf_size = mem_size;
230
231         mem_size = FJES_DEV_RES_BUF_SIZE(hw->max_epid);
232         hw->hw_info.res_buf = kzalloc(mem_size, GFP_KERNEL);
233         if (!(hw->hw_info.res_buf)) {
234                 result = -ENOMEM;
235                 goto free_req_buf;
236         }
237
238         hw->hw_info.res_buf_size = mem_size;
239
240         result = fjes_hw_alloc_shared_status_region(hw);
241         if (result)
242                 goto free_res_buf;
243
244         hw->hw_info.buffer_share_bit = 0;
245         hw->hw_info.buffer_unshare_reserve_bit = 0;
246
247         for (epidx = 0; epidx < hw->max_epid; epidx++) {
248                 if (epidx != hw->my_epid) {
249                         buf_pair = &hw->ep_shm_info[epidx];
250
251                         result = fjes_hw_alloc_epbuf(&buf_pair->tx);
252                         if (result)
253                                 goto free_epbuf;
254
255                         result = fjes_hw_alloc_epbuf(&buf_pair->rx);
256                         if (result)
257                                 goto free_epbuf;
258
259                         spin_lock_irqsave(&hw->rx_status_lock, flags);
260                         fjes_hw_setup_epbuf(&buf_pair->tx, mac,
261                                             fjes_support_mtu[0]);
262                         fjes_hw_setup_epbuf(&buf_pair->rx, mac,
263                                             fjes_support_mtu[0]);
264                         spin_unlock_irqrestore(&hw->rx_status_lock, flags);
265                 }
266         }
267
268         memset(&param, 0, sizeof(param));
269
270         param.req_len = hw->hw_info.req_buf_size;
271         param.req_start = __pa(hw->hw_info.req_buf);
272         param.res_len = hw->hw_info.res_buf_size;
273         param.res_start = __pa(hw->hw_info.res_buf);
274
275         param.share_start = __pa(hw->hw_info.share->ep_status);
276
277         fjes_hw_init_command_registers(hw, &param);
278
279         return 0;
280
281 free_epbuf:
282         for (epidx = 0; epidx < hw->max_epid ; epidx++) {
283                 if (epidx == hw->my_epid)
284                         continue;
285                 fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].tx);
286                 fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].rx);
287         }
288         fjes_hw_free_shared_status_region(hw);
289 free_res_buf:
290         kfree(hw->hw_info.res_buf);
291         hw->hw_info.res_buf = NULL;
292 free_req_buf:
293         kfree(hw->hw_info.req_buf);
294         hw->hw_info.req_buf = NULL;
295 free_ep_info:
296         kfree(hw->ep_shm_info);
297         hw->ep_shm_info = NULL;
298         return result;
299 }
300
301 static void fjes_hw_cleanup(struct fjes_hw *hw)
302 {
303         int epidx;
304
305         if (!hw->ep_shm_info)
306                 return;
307
308         fjes_hw_free_shared_status_region(hw);
309
310         kfree(hw->hw_info.req_buf);
311         hw->hw_info.req_buf = NULL;
312
313         kfree(hw->hw_info.res_buf);
314         hw->hw_info.res_buf = NULL;
315
316         for (epidx = 0; epidx < hw->max_epid ; epidx++) {
317                 if (epidx == hw->my_epid)
318                         continue;
319                 fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].tx);
320                 fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].rx);
321         }
322
323         kfree(hw->ep_shm_info);
324         hw->ep_shm_info = NULL;
325 }
326
327 int fjes_hw_init(struct fjes_hw *hw)
328 {
329         int ret;
330
331         hw->base = fjes_hw_iomap(hw);
332         if (!hw->base)
333                 return -EIO;
334
335         ret = fjes_hw_reset(hw);
336         if (ret)
337                 return ret;
338
339         fjes_hw_set_irqmask(hw, REG_ICTL_MASK_ALL, true);
340
341         INIT_WORK(&hw->update_zone_task, fjes_hw_update_zone_task);
342         INIT_WORK(&hw->epstop_task, fjes_hw_epstop_task);
343
344         mutex_init(&hw->hw_info.lock);
345         spin_lock_init(&hw->rx_status_lock);
346
347         hw->max_epid = fjes_hw_get_max_epid(hw);
348         hw->my_epid = fjes_hw_get_my_epid(hw);
349
350         if ((hw->max_epid == 0) || (hw->my_epid >= hw->max_epid))
351                 return -ENXIO;
352
353         ret = fjes_hw_setup(hw);
354
355         hw->hw_info.trace = vzalloc(FJES_DEBUG_BUFFER_SIZE);
356         hw->hw_info.trace_size = FJES_DEBUG_BUFFER_SIZE;
357
358         return ret;
359 }
360
361 void fjes_hw_exit(struct fjes_hw *hw)
362 {
363         int ret;
364
365         if (hw->base) {
366
367                 if (hw->debug_mode) {
368                         /* disable debug mode */
369                         mutex_lock(&hw->hw_info.lock);
370                         fjes_hw_stop_debug(hw);
371                         mutex_unlock(&hw->hw_info.lock);
372                 }
373                 vfree(hw->hw_info.trace);
374                 hw->hw_info.trace = NULL;
375                 hw->hw_info.trace_size = 0;
376                 hw->debug_mode = 0;
377
378                 ret = fjes_hw_reset(hw);
379                 if (ret)
380                         pr_err("%s: reset error", __func__);
381
382                 fjes_hw_iounmap(hw);
383                 hw->base = NULL;
384         }
385
386         fjes_hw_cleanup(hw);
387
388         cancel_work_sync(&hw->update_zone_task);
389         cancel_work_sync(&hw->epstop_task);
390 }
391
392 static enum fjes_dev_command_response_e
393 fjes_hw_issue_request_command(struct fjes_hw *hw,
394                               enum fjes_dev_command_request_type type)
395 {
396         enum fjes_dev_command_response_e ret = FJES_CMD_STATUS_UNKNOWN;
397         union REG_CR cr;
398         union REG_CS cs;
399         int timeout = FJES_COMMAND_REQ_TIMEOUT * 1000;
400
401         cr.reg = 0;
402         cr.bits.req_start = 1;
403         cr.bits.req_code = type;
404         wr32(XSCT_CR, cr.reg);
405         cr.reg = rd32(XSCT_CR);
406
407         if (cr.bits.error == 0) {
408                 timeout = FJES_COMMAND_REQ_TIMEOUT * 1000;
409                 cs.reg = rd32(XSCT_CS);
410
411                 while ((cs.bits.complete != 1) && timeout > 0) {
412                         msleep(1000);
413                         cs.reg = rd32(XSCT_CS);
414                         timeout -= 1000;
415                 }
416
417                 if (cs.bits.complete == 1)
418                         ret = FJES_CMD_STATUS_NORMAL;
419                 else if (timeout <= 0)
420                         ret = FJES_CMD_STATUS_TIMEOUT;
421
422         } else {
423                 switch (cr.bits.err_info) {
424                 case FJES_CMD_REQ_ERR_INFO_PARAM:
425                         ret = FJES_CMD_STATUS_ERROR_PARAM;
426                         break;
427                 case FJES_CMD_REQ_ERR_INFO_STATUS:
428                         ret = FJES_CMD_STATUS_ERROR_STATUS;
429                         break;
430                 default:
431                         ret = FJES_CMD_STATUS_UNKNOWN;
432                         break;
433                 }
434         }
435
436         trace_fjes_hw_issue_request_command(&cr, &cs, timeout, ret);
437
438         return ret;
439 }
440
441 int fjes_hw_request_info(struct fjes_hw *hw)
442 {
443         union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
444         union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
445         enum fjes_dev_command_response_e ret;
446         int result;
447
448         memset(req_buf, 0, hw->hw_info.req_buf_size);
449         memset(res_buf, 0, hw->hw_info.res_buf_size);
450
451         req_buf->info.length = FJES_DEV_COMMAND_INFO_REQ_LEN;
452
453         res_buf->info.length = 0;
454         res_buf->info.code = 0;
455
456         ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_INFO);
457         trace_fjes_hw_request_info(hw, res_buf);
458
459         result = 0;
460
461         if (FJES_DEV_COMMAND_INFO_RES_LEN((*hw->hw_info.max_epid)) !=
462                 res_buf->info.length) {
463                 trace_fjes_hw_request_info_err("Invalid res_buf");
464                 result = -ENOMSG;
465         } else if (ret == FJES_CMD_STATUS_NORMAL) {
466                 switch (res_buf->info.code) {
467                 case FJES_CMD_REQ_RES_CODE_NORMAL:
468                         result = 0;
469                         break;
470                 default:
471                         result = -EPERM;
472                         break;
473                 }
474         } else {
475                 switch (ret) {
476                 case FJES_CMD_STATUS_UNKNOWN:
477                         result = -EPERM;
478                         break;
479                 case FJES_CMD_STATUS_TIMEOUT:
480                         trace_fjes_hw_request_info_err("Timeout");
481                         result = -EBUSY;
482                         break;
483                 case FJES_CMD_STATUS_ERROR_PARAM:
484                         result = -EPERM;
485                         break;
486                 case FJES_CMD_STATUS_ERROR_STATUS:
487                         result = -EPERM;
488                         break;
489                 default:
490                         result = -EPERM;
491                         break;
492                 }
493         }
494
495         return result;
496 }
497
498 int fjes_hw_register_buff_addr(struct fjes_hw *hw, int dest_epid,
499                                struct ep_share_mem_info *buf_pair)
500 {
501         union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
502         union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
503         enum fjes_dev_command_response_e ret;
504         int page_count;
505         int timeout;
506         int i, idx;
507         void *addr;
508         int result;
509
510         if (test_bit(dest_epid, &hw->hw_info.buffer_share_bit))
511                 return 0;
512
513         memset(req_buf, 0, hw->hw_info.req_buf_size);
514         memset(res_buf, 0, hw->hw_info.res_buf_size);
515
516         req_buf->share_buffer.length = FJES_DEV_COMMAND_SHARE_BUFFER_REQ_LEN(
517                                                 buf_pair->tx.size,
518                                                 buf_pair->rx.size);
519         req_buf->share_buffer.epid = dest_epid;
520
521         idx = 0;
522         req_buf->share_buffer.buffer[idx++] = buf_pair->tx.size;
523         page_count = buf_pair->tx.size / EP_BUFFER_INFO_SIZE;
524         for (i = 0; i < page_count; i++) {
525                 addr = ((u8 *)(buf_pair->tx.buffer)) +
526                                 (i * EP_BUFFER_INFO_SIZE);
527                 req_buf->share_buffer.buffer[idx++] =
528                                 (__le64)(page_to_phys(vmalloc_to_page(addr)) +
529                                                 offset_in_page(addr));
530         }
531
532         req_buf->share_buffer.buffer[idx++] = buf_pair->rx.size;
533         page_count = buf_pair->rx.size / EP_BUFFER_INFO_SIZE;
534         for (i = 0; i < page_count; i++) {
535                 addr = ((u8 *)(buf_pair->rx.buffer)) +
536                                 (i * EP_BUFFER_INFO_SIZE);
537                 req_buf->share_buffer.buffer[idx++] =
538                                 (__le64)(page_to_phys(vmalloc_to_page(addr)) +
539                                                 offset_in_page(addr));
540         }
541
542         res_buf->share_buffer.length = 0;
543         res_buf->share_buffer.code = 0;
544
545         trace_fjes_hw_register_buff_addr_req(req_buf, buf_pair);
546
547         ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_SHARE_BUFFER);
548
549         timeout = FJES_COMMAND_REQ_BUFF_TIMEOUT * 1000;
550         while ((ret == FJES_CMD_STATUS_NORMAL) &&
551                (res_buf->share_buffer.length ==
552                 FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN) &&
553                (res_buf->share_buffer.code == FJES_CMD_REQ_RES_CODE_BUSY) &&
554                (timeout > 0)) {
555                         msleep(200 + hw->my_epid * 20);
556                         timeout -= (200 + hw->my_epid * 20);
557
558                         res_buf->share_buffer.length = 0;
559                         res_buf->share_buffer.code = 0;
560
561                         ret = fjes_hw_issue_request_command(
562                                         hw, FJES_CMD_REQ_SHARE_BUFFER);
563         }
564
565         result = 0;
566
567         trace_fjes_hw_register_buff_addr(res_buf, timeout);
568
569         if (res_buf->share_buffer.length !=
570                         FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN) {
571                 trace_fjes_hw_register_buff_addr_err("Invalid res_buf");
572                 result = -ENOMSG;
573         } else if (ret == FJES_CMD_STATUS_NORMAL) {
574                 switch (res_buf->share_buffer.code) {
575                 case FJES_CMD_REQ_RES_CODE_NORMAL:
576                         result = 0;
577                         set_bit(dest_epid, &hw->hw_info.buffer_share_bit);
578                         break;
579                 case FJES_CMD_REQ_RES_CODE_BUSY:
580                         trace_fjes_hw_register_buff_addr_err("Busy Timeout");
581                         result = -EBUSY;
582                         break;
583                 default:
584                         result = -EPERM;
585                         break;
586                 }
587         } else {
588                 switch (ret) {
589                 case FJES_CMD_STATUS_UNKNOWN:
590                         result = -EPERM;
591                         break;
592                 case FJES_CMD_STATUS_TIMEOUT:
593                         trace_fjes_hw_register_buff_addr_err("Timeout");
594                         result = -EBUSY;
595                         break;
596                 case FJES_CMD_STATUS_ERROR_PARAM:
597                 case FJES_CMD_STATUS_ERROR_STATUS:
598                 default:
599                         result = -EPERM;
600                         break;
601                 }
602         }
603
604         return result;
605 }
606
607 int fjes_hw_unregister_buff_addr(struct fjes_hw *hw, int dest_epid)
608 {
609         union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
610         union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
611         struct fjes_device_shared_info *share = hw->hw_info.share;
612         enum fjes_dev_command_response_e ret;
613         int timeout;
614         int result;
615
616         if (!hw->base)
617                 return -EPERM;
618
619         if (!req_buf || !res_buf || !share)
620                 return -EPERM;
621
622         if (!test_bit(dest_epid, &hw->hw_info.buffer_share_bit))
623                 return 0;
624
625         memset(req_buf, 0, hw->hw_info.req_buf_size);
626         memset(res_buf, 0, hw->hw_info.res_buf_size);
627
628         req_buf->unshare_buffer.length =
629                         FJES_DEV_COMMAND_UNSHARE_BUFFER_REQ_LEN;
630         req_buf->unshare_buffer.epid = dest_epid;
631
632         res_buf->unshare_buffer.length = 0;
633         res_buf->unshare_buffer.code = 0;
634
635         trace_fjes_hw_unregister_buff_addr_req(req_buf);
636         ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_UNSHARE_BUFFER);
637
638         timeout = FJES_COMMAND_REQ_BUFF_TIMEOUT * 1000;
639         while ((ret == FJES_CMD_STATUS_NORMAL) &&
640                (res_buf->unshare_buffer.length ==
641                 FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN) &&
642                (res_buf->unshare_buffer.code ==
643                 FJES_CMD_REQ_RES_CODE_BUSY) &&
644                (timeout > 0)) {
645                 msleep(200 + hw->my_epid * 20);
646                 timeout -= (200 + hw->my_epid * 20);
647
648                 res_buf->unshare_buffer.length = 0;
649                 res_buf->unshare_buffer.code = 0;
650
651                 ret =
652                 fjes_hw_issue_request_command(hw, FJES_CMD_REQ_UNSHARE_BUFFER);
653         }
654
655         result = 0;
656
657         trace_fjes_hw_unregister_buff_addr(res_buf, timeout);
658
659         if (res_buf->unshare_buffer.length !=
660                         FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN) {
661                 trace_fjes_hw_unregister_buff_addr_err("Invalid res_buf");
662                 result = -ENOMSG;
663         } else if (ret == FJES_CMD_STATUS_NORMAL) {
664                 switch (res_buf->unshare_buffer.code) {
665                 case FJES_CMD_REQ_RES_CODE_NORMAL:
666                         result = 0;
667                         clear_bit(dest_epid, &hw->hw_info.buffer_share_bit);
668                         break;
669                 case FJES_CMD_REQ_RES_CODE_BUSY:
670                         trace_fjes_hw_unregister_buff_addr_err("Busy Timeout");
671                         result = -EBUSY;
672                         break;
673                 default:
674                         result = -EPERM;
675                         break;
676                 }
677         } else {
678                 switch (ret) {
679                 case FJES_CMD_STATUS_UNKNOWN:
680                         result = -EPERM;
681                         break;
682                 case FJES_CMD_STATUS_TIMEOUT:
683                         trace_fjes_hw_unregister_buff_addr_err("Timeout");
684                         result = -EBUSY;
685                         break;
686                 case FJES_CMD_STATUS_ERROR_PARAM:
687                 case FJES_CMD_STATUS_ERROR_STATUS:
688                 default:
689                         result = -EPERM;
690                         break;
691                 }
692         }
693
694         return result;
695 }
696
697 int fjes_hw_raise_interrupt(struct fjes_hw *hw, int dest_epid,
698                             enum REG_ICTL_MASK  mask)
699 {
700         u32 ig = mask | dest_epid;
701
702         wr32(XSCT_IG, cpu_to_le32(ig));
703
704         return 0;
705 }
706
707 u32 fjes_hw_capture_interrupt_status(struct fjes_hw *hw)
708 {
709         u32 cur_is;
710
711         cur_is = rd32(XSCT_IS);
712
713         return cur_is;
714 }
715
716 void fjes_hw_set_irqmask(struct fjes_hw *hw,
717                          enum REG_ICTL_MASK intr_mask, bool mask)
718 {
719         if (mask)
720                 wr32(XSCT_IMS, intr_mask);
721         else
722                 wr32(XSCT_IMC, intr_mask);
723 }
724
725 bool fjes_hw_epid_is_same_zone(struct fjes_hw *hw, int epid)
726 {
727         if (epid >= hw->max_epid)
728                 return false;
729
730         if ((hw->ep_shm_info[epid].es_status !=
731                         FJES_ZONING_STATUS_ENABLE) ||
732                 (hw->ep_shm_info[hw->my_epid].zone ==
733                         FJES_ZONING_ZONE_TYPE_NONE))
734                 return false;
735         else
736                 return (hw->ep_shm_info[epid].zone ==
737                                 hw->ep_shm_info[hw->my_epid].zone);
738 }
739
740 int fjes_hw_epid_is_shared(struct fjes_device_shared_info *share,
741                            int dest_epid)
742 {
743         int value = false;
744
745         if (dest_epid < share->epnum)
746                 value = share->ep_status[dest_epid];
747
748         return value;
749 }
750
751 static bool fjes_hw_epid_is_stop_requested(struct fjes_hw *hw, int src_epid)
752 {
753         return test_bit(src_epid, &hw->txrx_stop_req_bit);
754 }
755
756 static bool fjes_hw_epid_is_stop_process_done(struct fjes_hw *hw, int src_epid)
757 {
758         return (hw->ep_shm_info[src_epid].tx.info->v1i.rx_status &
759                         FJES_RX_STOP_REQ_DONE);
760 }
761
762 enum ep_partner_status
763 fjes_hw_get_partner_ep_status(struct fjes_hw *hw, int epid)
764 {
765         enum ep_partner_status status;
766
767         if (fjes_hw_epid_is_shared(hw->hw_info.share, epid)) {
768                 if (fjes_hw_epid_is_stop_requested(hw, epid)) {
769                         status = EP_PARTNER_WAITING;
770                 } else {
771                         if (fjes_hw_epid_is_stop_process_done(hw, epid))
772                                 status = EP_PARTNER_COMPLETE;
773                         else
774                                 status = EP_PARTNER_SHARED;
775                 }
776         } else {
777                 status = EP_PARTNER_UNSHARE;
778         }
779
780         return status;
781 }
782
783 void fjes_hw_raise_epstop(struct fjes_hw *hw)
784 {
785         enum ep_partner_status status;
786         unsigned long flags;
787         int epidx;
788
789         for (epidx = 0; epidx < hw->max_epid; epidx++) {
790                 if (epidx == hw->my_epid)
791                         continue;
792
793                 status = fjes_hw_get_partner_ep_status(hw, epidx);
794                 switch (status) {
795                 case EP_PARTNER_SHARED:
796                         fjes_hw_raise_interrupt(hw, epidx,
797                                                 REG_ICTL_MASK_TXRX_STOP_REQ);
798                         hw->ep_shm_info[epidx].ep_stats.send_intr_unshare += 1;
799                         break;
800                 default:
801                         break;
802                 }
803
804                 set_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit);
805                 set_bit(epidx, &hw->txrx_stop_req_bit);
806
807                 spin_lock_irqsave(&hw->rx_status_lock, flags);
808                 hw->ep_shm_info[epidx].tx.info->v1i.rx_status |=
809                                 FJES_RX_STOP_REQ_REQUEST;
810                 spin_unlock_irqrestore(&hw->rx_status_lock, flags);
811         }
812 }
813
814 int fjes_hw_wait_epstop(struct fjes_hw *hw)
815 {
816         enum ep_partner_status status;
817         union ep_buffer_info *info;
818         int wait_time = 0;
819         int epidx;
820
821         while (hw->hw_info.buffer_unshare_reserve_bit &&
822                (wait_time < FJES_COMMAND_EPSTOP_WAIT_TIMEOUT * 1000)) {
823                 for (epidx = 0; epidx < hw->max_epid; epidx++) {
824                         if (epidx == hw->my_epid)
825                                 continue;
826                         status = fjes_hw_epid_is_shared(hw->hw_info.share,
827                                                         epidx);
828                         info = hw->ep_shm_info[epidx].rx.info;
829                         if ((!status ||
830                              (info->v1i.rx_status &
831                               FJES_RX_STOP_REQ_DONE)) &&
832                             test_bit(epidx,
833                                      &hw->hw_info.buffer_unshare_reserve_bit)) {
834                                 clear_bit(epidx,
835                                           &hw->hw_info.buffer_unshare_reserve_bit);
836                         }
837                 }
838
839                 msleep(100);
840                 wait_time += 100;
841         }
842
843         for (epidx = 0; epidx < hw->max_epid; epidx++) {
844                 if (epidx == hw->my_epid)
845                         continue;
846                 if (test_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit))
847                         clear_bit(epidx,
848                                   &hw->hw_info.buffer_unshare_reserve_bit);
849         }
850
851         return (wait_time < FJES_COMMAND_EPSTOP_WAIT_TIMEOUT * 1000)
852                         ? 0 : -EBUSY;
853 }
854
855 bool fjes_hw_check_epbuf_version(struct epbuf_handler *epbh, u32 version)
856 {
857         union ep_buffer_info *info = epbh->info;
858
859         return (info->common.version == version);
860 }
861
862 bool fjes_hw_check_mtu(struct epbuf_handler *epbh, u32 mtu)
863 {
864         union ep_buffer_info *info = epbh->info;
865
866         return ((info->v1i.frame_max == FJES_MTU_TO_FRAME_SIZE(mtu)) &&
867                 info->v1i.rx_status & FJES_RX_MTU_CHANGING_DONE);
868 }
869
870 bool fjes_hw_check_vlan_id(struct epbuf_handler *epbh, u16 vlan_id)
871 {
872         union ep_buffer_info *info = epbh->info;
873         bool ret = false;
874         int i;
875
876         if (vlan_id == 0) {
877                 ret = true;
878         } else {
879                 for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++) {
880                         if (vlan_id == info->v1i.vlan_id[i]) {
881                                 ret = true;
882                                 break;
883                         }
884                 }
885         }
886         return ret;
887 }
888
889 bool fjes_hw_set_vlan_id(struct epbuf_handler *epbh, u16 vlan_id)
890 {
891         union ep_buffer_info *info = epbh->info;
892         int i;
893
894         for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++) {
895                 if (info->v1i.vlan_id[i] == 0) {
896                         info->v1i.vlan_id[i] = vlan_id;
897                         return true;
898                 }
899         }
900         return false;
901 }
902
903 void fjes_hw_del_vlan_id(struct epbuf_handler *epbh, u16 vlan_id)
904 {
905         union ep_buffer_info *info = epbh->info;
906         int i;
907
908         if (0 != vlan_id) {
909                 for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++) {
910                         if (vlan_id == info->v1i.vlan_id[i])
911                                 info->v1i.vlan_id[i] = 0;
912                 }
913         }
914 }
915
916 bool fjes_hw_epbuf_rx_is_empty(struct epbuf_handler *epbh)
917 {
918         union ep_buffer_info *info = epbh->info;
919
920         if (!(info->v1i.rx_status & FJES_RX_MTU_CHANGING_DONE))
921                 return true;
922
923         if (info->v1i.count_max == 0)
924                 return true;
925
926         return EP_RING_EMPTY(info->v1i.head, info->v1i.tail,
927                              info->v1i.count_max);
928 }
929
930 void *fjes_hw_epbuf_rx_curpkt_get_addr(struct epbuf_handler *epbh,
931                                        size_t *psize)
932 {
933         union ep_buffer_info *info = epbh->info;
934         struct esmem_frame *ring_frame;
935         void *frame;
936
937         ring_frame = (struct esmem_frame *)&(epbh->ring[EP_RING_INDEX
938                                              (info->v1i.head,
939                                               info->v1i.count_max) *
940                                              info->v1i.frame_max]);
941
942         *psize = (size_t)ring_frame->frame_size;
943
944         frame = ring_frame->frame_data;
945
946         return frame;
947 }
948
949 void fjes_hw_epbuf_rx_curpkt_drop(struct epbuf_handler *epbh)
950 {
951         union ep_buffer_info *info = epbh->info;
952
953         if (fjes_hw_epbuf_rx_is_empty(epbh))
954                 return;
955
956         EP_RING_INDEX_INC(epbh->info->v1i.head, info->v1i.count_max);
957 }
958
959 int fjes_hw_epbuf_tx_pkt_send(struct epbuf_handler *epbh,
960                               void *frame, size_t size)
961 {
962         union ep_buffer_info *info = epbh->info;
963         struct esmem_frame *ring_frame;
964
965         if (EP_RING_FULL(info->v1i.head, info->v1i.tail, info->v1i.count_max))
966                 return -ENOBUFS;
967
968         ring_frame = (struct esmem_frame *)&(epbh->ring[EP_RING_INDEX
969                                              (info->v1i.tail - 1,
970                                               info->v1i.count_max) *
971                                              info->v1i.frame_max]);
972
973         ring_frame->frame_size = size;
974         memcpy((void *)(ring_frame->frame_data), (void *)frame, size);
975
976         EP_RING_INDEX_INC(epbh->info->v1i.tail, info->v1i.count_max);
977
978         return 0;
979 }
980
981 static void fjes_hw_update_zone_task(struct work_struct *work)
982 {
983         struct fjes_hw *hw = container_of(work,
984                         struct fjes_hw, update_zone_task);
985
986         struct my_s {u8 es_status; u8 zone; } *info;
987         union fjes_device_command_res *res_buf;
988         enum ep_partner_status pstatus;
989
990         struct fjes_adapter *adapter;
991         struct net_device *netdev;
992         unsigned long flags;
993
994         ulong unshare_bit = 0;
995         ulong share_bit = 0;
996         ulong irq_bit = 0;
997
998         int epidx;
999         int ret;
1000
1001         adapter = (struct fjes_adapter *)hw->back;
1002         netdev = adapter->netdev;
1003         res_buf = hw->hw_info.res_buf;
1004         info = (struct my_s *)&res_buf->info.info;
1005
1006         mutex_lock(&hw->hw_info.lock);
1007
1008         ret = fjes_hw_request_info(hw);
1009         switch (ret) {
1010         case -ENOMSG:
1011         case -EBUSY:
1012         default:
1013                 if (!work_pending(&adapter->force_close_task)) {
1014                         adapter->force_reset = true;
1015                         schedule_work(&adapter->force_close_task);
1016                 }
1017                 break;
1018
1019         case 0:
1020
1021                 for (epidx = 0; epidx < hw->max_epid; epidx++) {
1022                         if (epidx == hw->my_epid) {
1023                                 hw->ep_shm_info[epidx].es_status =
1024                                         info[epidx].es_status;
1025                                 hw->ep_shm_info[epidx].zone =
1026                                         info[epidx].zone;
1027                                 continue;
1028                         }
1029
1030                         pstatus = fjes_hw_get_partner_ep_status(hw, epidx);
1031                         switch (pstatus) {
1032                         case EP_PARTNER_UNSHARE:
1033                         default:
1034                                 if ((info[epidx].zone !=
1035                                         FJES_ZONING_ZONE_TYPE_NONE) &&
1036                                     (info[epidx].es_status ==
1037                                         FJES_ZONING_STATUS_ENABLE) &&
1038                                     (info[epidx].zone ==
1039                                         info[hw->my_epid].zone))
1040                                         set_bit(epidx, &share_bit);
1041                                 else
1042                                         set_bit(epidx, &unshare_bit);
1043                                 break;
1044
1045                         case EP_PARTNER_COMPLETE:
1046                         case EP_PARTNER_WAITING:
1047                                 if ((info[epidx].zone ==
1048                                         FJES_ZONING_ZONE_TYPE_NONE) ||
1049                                     (info[epidx].es_status !=
1050                                         FJES_ZONING_STATUS_ENABLE) ||
1051                                     (info[epidx].zone !=
1052                                         info[hw->my_epid].zone)) {
1053                                         set_bit(epidx,
1054                                                 &adapter->unshare_watch_bitmask);
1055                                         set_bit(epidx,
1056                                                 &hw->hw_info.buffer_unshare_reserve_bit);
1057                                 }
1058                                 break;
1059
1060                         case EP_PARTNER_SHARED:
1061                                 if ((info[epidx].zone ==
1062                                         FJES_ZONING_ZONE_TYPE_NONE) ||
1063                                     (info[epidx].es_status !=
1064                                         FJES_ZONING_STATUS_ENABLE) ||
1065                                     (info[epidx].zone !=
1066                                         info[hw->my_epid].zone))
1067                                         set_bit(epidx, &irq_bit);
1068                                 break;
1069                         }
1070
1071                         hw->ep_shm_info[epidx].es_status =
1072                                 info[epidx].es_status;
1073                         hw->ep_shm_info[epidx].zone = info[epidx].zone;
1074                 }
1075                 break;
1076         }
1077
1078         mutex_unlock(&hw->hw_info.lock);
1079
1080         for (epidx = 0; epidx < hw->max_epid; epidx++) {
1081                 if (epidx == hw->my_epid)
1082                         continue;
1083
1084                 if (test_bit(epidx, &share_bit)) {
1085                         spin_lock_irqsave(&hw->rx_status_lock, flags);
1086                         fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx,
1087                                             netdev->dev_addr, netdev->mtu);
1088                         spin_unlock_irqrestore(&hw->rx_status_lock, flags);
1089
1090                         mutex_lock(&hw->hw_info.lock);
1091
1092                         ret = fjes_hw_register_buff_addr(
1093                                 hw, epidx, &hw->ep_shm_info[epidx]);
1094
1095                         switch (ret) {
1096                         case 0:
1097                                 break;
1098                         case -ENOMSG:
1099                         case -EBUSY:
1100                         default:
1101                                 if (!work_pending(&adapter->force_close_task)) {
1102                                         adapter->force_reset = true;
1103                                         schedule_work(
1104                                           &adapter->force_close_task);
1105                                 }
1106                                 break;
1107                         }
1108                         mutex_unlock(&hw->hw_info.lock);
1109
1110                         hw->ep_shm_info[epidx].ep_stats
1111                                               .com_regist_buf_exec += 1;
1112                 }
1113
1114                 if (test_bit(epidx, &unshare_bit)) {
1115                         mutex_lock(&hw->hw_info.lock);
1116
1117                         ret = fjes_hw_unregister_buff_addr(hw, epidx);
1118
1119                         switch (ret) {
1120                         case 0:
1121                                 break;
1122                         case -ENOMSG:
1123                         case -EBUSY:
1124                         default:
1125                                 if (!work_pending(&adapter->force_close_task)) {
1126                                         adapter->force_reset = true;
1127                                         schedule_work(
1128                                           &adapter->force_close_task);
1129                                 }
1130                                 break;
1131                         }
1132
1133                         mutex_unlock(&hw->hw_info.lock);
1134
1135                         hw->ep_shm_info[epidx].ep_stats
1136                                               .com_unregist_buf_exec += 1;
1137
1138                         if (ret == 0) {
1139                                 spin_lock_irqsave(&hw->rx_status_lock, flags);
1140                                 fjes_hw_setup_epbuf(
1141                                         &hw->ep_shm_info[epidx].tx,
1142                                         netdev->dev_addr, netdev->mtu);
1143                                 spin_unlock_irqrestore(&hw->rx_status_lock,
1144                                                        flags);
1145                         }
1146                 }
1147
1148                 if (test_bit(epidx, &irq_bit)) {
1149                         fjes_hw_raise_interrupt(hw, epidx,
1150                                                 REG_ICTL_MASK_TXRX_STOP_REQ);
1151
1152                         hw->ep_shm_info[epidx].ep_stats.send_intr_unshare += 1;
1153
1154                         set_bit(epidx, &hw->txrx_stop_req_bit);
1155                         spin_lock_irqsave(&hw->rx_status_lock, flags);
1156                         hw->ep_shm_info[epidx].tx.
1157                                 info->v1i.rx_status |=
1158                                         FJES_RX_STOP_REQ_REQUEST;
1159                         spin_unlock_irqrestore(&hw->rx_status_lock, flags);
1160                         set_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit);
1161                 }
1162         }
1163
1164         if (irq_bit || adapter->unshare_watch_bitmask) {
1165                 if (!work_pending(&adapter->unshare_watch_task))
1166                         queue_work(adapter->control_wq,
1167                                    &adapter->unshare_watch_task);
1168         }
1169 }
1170
1171 static void fjes_hw_epstop_task(struct work_struct *work)
1172 {
1173         struct fjes_hw *hw = container_of(work, struct fjes_hw, epstop_task);
1174         struct fjes_adapter *adapter = (struct fjes_adapter *)hw->back;
1175         unsigned long flags;
1176
1177         ulong remain_bit;
1178         int epid_bit;
1179
1180         while ((remain_bit = hw->epstop_req_bit)) {
1181                 for (epid_bit = 0; remain_bit; remain_bit >>= 1, epid_bit++) {
1182                         if (remain_bit & 1) {
1183                                 spin_lock_irqsave(&hw->rx_status_lock, flags);
1184                                 hw->ep_shm_info[epid_bit].
1185                                         tx.info->v1i.rx_status |=
1186                                                 FJES_RX_STOP_REQ_DONE;
1187                                 spin_unlock_irqrestore(&hw->rx_status_lock,
1188                                                        flags);
1189
1190                                 clear_bit(epid_bit, &hw->epstop_req_bit);
1191                                 set_bit(epid_bit,
1192                                         &adapter->unshare_watch_bitmask);
1193
1194                                 if (!work_pending(&adapter->unshare_watch_task))
1195                                         queue_work(
1196                                                 adapter->control_wq,
1197                                                 &adapter->unshare_watch_task);
1198                         }
1199                 }
1200         }
1201 }
1202
1203 int fjes_hw_start_debug(struct fjes_hw *hw)
1204 {
1205         union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
1206         union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
1207         enum fjes_dev_command_response_e ret;
1208         int page_count;
1209         int result = 0;
1210         void *addr;
1211         int i;
1212
1213         if (!hw->hw_info.trace)
1214                 return -EPERM;
1215         memset(hw->hw_info.trace, 0, FJES_DEBUG_BUFFER_SIZE);
1216
1217         memset(req_buf, 0, hw->hw_info.req_buf_size);
1218         memset(res_buf, 0, hw->hw_info.res_buf_size);
1219
1220         req_buf->start_trace.length =
1221                 FJES_DEV_COMMAND_START_DBG_REQ_LEN(hw->hw_info.trace_size);
1222         req_buf->start_trace.mode = hw->debug_mode;
1223         req_buf->start_trace.buffer_len = hw->hw_info.trace_size;
1224         page_count = hw->hw_info.trace_size / FJES_DEBUG_PAGE_SIZE;
1225         for (i = 0; i < page_count; i++) {
1226                 addr = ((u8 *)hw->hw_info.trace) + i * FJES_DEBUG_PAGE_SIZE;
1227                 req_buf->start_trace.buffer[i] =
1228                         (__le64)(page_to_phys(vmalloc_to_page(addr)) +
1229                         offset_in_page(addr));
1230         }
1231
1232         res_buf->start_trace.length = 0;
1233         res_buf->start_trace.code = 0;
1234
1235         trace_fjes_hw_start_debug_req(req_buf);
1236         ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_START_DEBUG);
1237         trace_fjes_hw_start_debug(res_buf);
1238
1239         if (res_buf->start_trace.length !=
1240                 FJES_DEV_COMMAND_START_DBG_RES_LEN) {
1241                 result = -ENOMSG;
1242                 trace_fjes_hw_start_debug_err("Invalid res_buf");
1243         } else if (ret == FJES_CMD_STATUS_NORMAL) {
1244                 switch (res_buf->start_trace.code) {
1245                 case FJES_CMD_REQ_RES_CODE_NORMAL:
1246                         result = 0;
1247                         break;
1248                 default:
1249                         result = -EPERM;
1250                         break;
1251                 }
1252         } else {
1253                 switch (ret) {
1254                 case FJES_CMD_STATUS_UNKNOWN:
1255                         result = -EPERM;
1256                         break;
1257                 case FJES_CMD_STATUS_TIMEOUT:
1258                         trace_fjes_hw_start_debug_err("Busy Timeout");
1259                         result = -EBUSY;
1260                         break;
1261                 case FJES_CMD_STATUS_ERROR_PARAM:
1262                 case FJES_CMD_STATUS_ERROR_STATUS:
1263                 default:
1264                         result = -EPERM;
1265                         break;
1266                 }
1267         }
1268
1269         return result;
1270 }
1271
1272 int fjes_hw_stop_debug(struct fjes_hw *hw)
1273 {
1274         union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
1275         union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
1276         enum fjes_dev_command_response_e ret;
1277         int result = 0;
1278
1279         if (!hw->hw_info.trace)
1280                 return -EPERM;
1281
1282         memset(req_buf, 0, hw->hw_info.req_buf_size);
1283         memset(res_buf, 0, hw->hw_info.res_buf_size);
1284         req_buf->stop_trace.length = FJES_DEV_COMMAND_STOP_DBG_REQ_LEN;
1285
1286         res_buf->stop_trace.length = 0;
1287         res_buf->stop_trace.code = 0;
1288
1289         ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_STOP_DEBUG);
1290         trace_fjes_hw_stop_debug(res_buf);
1291
1292         if (res_buf->stop_trace.length != FJES_DEV_COMMAND_STOP_DBG_RES_LEN) {
1293                 trace_fjes_hw_stop_debug_err("Invalid res_buf");
1294                 result = -ENOMSG;
1295         } else if (ret == FJES_CMD_STATUS_NORMAL) {
1296                 switch (res_buf->stop_trace.code) {
1297                 case FJES_CMD_REQ_RES_CODE_NORMAL:
1298                         result = 0;
1299                         hw->debug_mode = 0;
1300                         break;
1301                 default:
1302                         result = -EPERM;
1303                         break;
1304                 }
1305         } else {
1306                 switch (ret) {
1307                 case FJES_CMD_STATUS_UNKNOWN:
1308                         result = -EPERM;
1309                         break;
1310                 case FJES_CMD_STATUS_TIMEOUT:
1311                         result = -EBUSY;
1312                         trace_fjes_hw_stop_debug_err("Busy Timeout");
1313                         break;
1314                 case FJES_CMD_STATUS_ERROR_PARAM:
1315                 case FJES_CMD_STATUS_ERROR_STATUS:
1316                 default:
1317                         result = -EPERM;
1318                         break;
1319                 }
1320         }
1321
1322         return result;
1323 }