static void fjes_free_resources(struct fjes_adapter *adapter) { struct net_device *netdev = adapter->netdev; struct fjes_device_command_param param; struct ep_share_mem_info *buf_pair; struct fjes_hw *hw = &adapter->hw; bool reset_flag = false; unsigned long flags; int result; int epidx; for (epidx = 0; epidx < hw->max_epid; epidx++) { if (epidx == hw->my_epid) continue; mutex_lock(&hw->hw_info.lock); result = fjes_hw_unregister_buff_addr(hw, epidx); mutex_unlock(&hw->hw_info.lock); hw->ep_shm_info[epidx].ep_stats.com_unregist_buf_exec += 1; if (result) reset_flag = true; buf_pair = &hw->ep_shm_info[epidx]; spin_lock_irqsave(&hw->rx_status_lock, flags); fjes_hw_setup_epbuf(&buf_pair->tx, netdev->dev_addr, netdev->mtu); spin_unlock_irqrestore(&hw->rx_status_lock, flags); clear_bit(epidx, &hw->txrx_stop_req_bit); } if (reset_flag || adapter->force_reset) { result = fjes_hw_reset(hw); adapter->force_reset = false; if (result) adapter->open_guard = true; hw->hw_info.buffer_share_bit = 0; memset((void *)¶m, 0, sizeof(param)); param.req_len = hw->hw_info.req_buf_size; param.req_start = __pa(hw->hw_info.req_buf); param.res_len = hw->hw_info.res_buf_size; param.res_start = __pa(hw->hw_info.res_buf); param.share_start = __pa(hw->hw_info.share->ep_status); fjes_hw_init_command_registers(hw, ¶m); } }
static int fjes_hw_setup(struct fjes_hw *hw) { u8 mac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; struct fjes_device_command_param param; struct ep_share_mem_info *buf_pair; size_t mem_size; int result; int epidx; void *buf; hw->hw_info.max_epid = &hw->max_epid; hw->hw_info.my_epid = &hw->my_epid; buf = kcalloc(hw->max_epid, sizeof(struct ep_share_mem_info), GFP_KERNEL); if (!buf) return -ENOMEM; hw->ep_shm_info = (struct ep_share_mem_info *)buf; mem_size = FJES_DEV_REQ_BUF_SIZE(hw->max_epid); hw->hw_info.req_buf = kzalloc(mem_size, GFP_KERNEL); if (!(hw->hw_info.req_buf)) return -ENOMEM; hw->hw_info.req_buf_size = mem_size; mem_size = FJES_DEV_RES_BUF_SIZE(hw->max_epid); hw->hw_info.res_buf = kzalloc(mem_size, GFP_KERNEL); if (!(hw->hw_info.res_buf)) return -ENOMEM; hw->hw_info.res_buf_size = mem_size; result = fjes_hw_alloc_shared_status_region(hw); if (result) return result; hw->hw_info.buffer_share_bit = 0; hw->hw_info.buffer_unshare_reserve_bit = 0; for (epidx = 0; epidx < hw->max_epid; epidx++) { if (epidx != hw->my_epid) { buf_pair = &hw->ep_shm_info[epidx]; result = fjes_hw_alloc_epbuf(&buf_pair->tx); if (result) return result; result = fjes_hw_alloc_epbuf(&buf_pair->rx); if (result) return result; fjes_hw_setup_epbuf(&buf_pair->tx, mac, fjes_support_mtu[0]); fjes_hw_setup_epbuf(&buf_pair->rx, mac, fjes_support_mtu[0]); } } memset(¶m, 0, sizeof(param)); param.req_len = hw->hw_info.req_buf_size; param.req_start = __pa(hw->hw_info.req_buf); param.res_len = hw->hw_info.res_buf_size; param.res_start = __pa(hw->hw_info.res_buf); param.share_start = __pa(hw->hw_info.share->ep_status); fjes_hw_init_command_registers(hw, ¶m); return 0; }