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