From patchwork Thu Jun 18 00:49:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taku Izumi X-Patchwork-Id: 6632421 Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D3F7E9F358 for ; Thu, 18 Jun 2015 00:55:08 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BB12A207E6 for ; Thu, 18 Jun 2015 00:55:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 97C63207EB for ; Thu, 18 Jun 2015 00:55:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753428AbbFRAyV (ORCPT ); Wed, 17 Jun 2015 20:54:21 -0400 Received: from mgwkm01.jp.fujitsu.com ([202.219.69.168]:57331 "EHLO mgwkm01.jp.fujitsu.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753228AbbFRAxa (ORCPT ); Wed, 17 Jun 2015 20:53:30 -0400 Received: from kw-mxauth.gw.nic.fujitsu.com (unknown [192.168.231.132]) by mgwkm01.jp.fujitsu.com with smtp id 0ffa_7a85_a825c804_70ad_4702_a404_6f1fa2a510d8; Thu, 18 Jun 2015 09:53:28 +0900 Received: from m3050.s.css.fujitsu.com (msm.b.css.fujitsu.com [10.134.21.208]) by kw-mxauth.gw.nic.fujitsu.com (Postfix) with ESMTP id 515A8AC08C2; Thu, 18 Jun 2015 09:53:27 +0900 (JST) Received: from localhost.localdomain (unknown [10.124.196.197]) by m3050.s.css.fujitsu.com (Postfix) with ESMTP id 17A25166; Thu, 18 Jun 2015 09:53:27 +0900 (JST) From: Taku Izumi To: platform-driver-x86@vger.kernel.org, dvhart@infradead.org Cc: rkhan@redhat.com, alexander.h.duyck@redhat.com, netdev@vger.kernel.org, linux-acpi@vger.kernel.org, Taku Izumi Subject: [PATCH 19/22] fjes: update_zone_task Date: Thu, 18 Jun 2015 09:49:44 +0900 Message-Id: <1434588587-25655-19-git-send-email-izumi.taku@jp.fujitsu.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1434588587-25655-1-git-send-email-izumi.taku@jp.fujitsu.com> References: <1434588359-25589-1-git-send-email-izumi.taku@jp.fujitsu.com> <1434588587-25655-1-git-send-email-izumi.taku@jp.fujitsu.com> X-TM-AS-MML: disable Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds update_zone_task. Zoning information can be changed by user. This task is used to monitor if zoning information is changed or not. Signed-off-by: Taku Izumi --- drivers/platform/x86/fjes/fjes_hw.c | 183 ++++++++++++++++++++++++++++++++++ drivers/platform/x86/fjes/fjes_hw.h | 1 + drivers/platform/x86/fjes/fjes_main.c | 14 +++ 3 files changed, 198 insertions(+) diff --git a/drivers/platform/x86/fjes/fjes_hw.c b/drivers/platform/x86/fjes/fjes_hw.c index 85f9693..e07b266 100644 --- a/drivers/platform/x86/fjes/fjes_hw.c +++ b/drivers/platform/x86/fjes/fjes_hw.c @@ -22,6 +22,8 @@ #include "fjes_hw.h" #include "fjes.h" +static void fjes_hw_update_zone_task(struct work_struct *); + /* supported MTU list */ u32 fjes_support_mtu[] = { FJES_MTU_DEFINE(8 * 1024), @@ -331,6 +333,8 @@ int fjes_hw_init(struct fjes_hw *hw) fjes_hw_set_irqmask(hw, REG_ICTL_MASK_ALL, true); + INIT_WORK(&hw->update_zone_task, fjes_hw_update_zone_task); + mutex_init(&hw->hw_info.lock); hw->max_epid = fjes_hw_get_max_epid(hw); @@ -358,6 +362,8 @@ void fjes_hw_exit(struct fjes_hw *hw) } fjes_hw_cleanup(hw); + + cancel_work_sync(&hw->update_zone_task); } static enum fjes_dev_command_response_e fjes_hw_issue_request_command( @@ -940,3 +946,180 @@ int fjes_hw_epbuf_tx_pkt_send(struct epbuf_handler *epbh, return 0; } +static void fjes_hw_update_zone_task(struct work_struct *work) +{ + + struct fjes_hw *hw = container_of(work, + struct fjes_hw, update_zone_task); + struct fjes_adapter *adapter = (struct fjes_adapter *)hw->back; + struct net_device *netdev = adapter->netdev; + int ret; + int epidx; + enum ep_partner_status pstatus; + unsigned long share_bit = 0; + unsigned long unshare_bit = 0; + unsigned long irq_bit = 0; + bool update = false; + union fjes_device_command_res *res_buf = + hw->hw_info.res_buf; + + mutex_lock(&hw->hw_info.lock); + + ret = fjes_hw_request_info(hw); + switch (ret) { + case -ENOMSG: + case -EBUSY: + default: + if (!work_pending(&adapter->force_close_task)) { + adapter->force_reset = true; + schedule_work(&adapter->force_close_task); + } + break; + + case 0: + + for (epidx = 0; epidx < hw->max_epid; epidx++) { + if (epidx != hw->my_epid) { + + pstatus = fjes_hw_get_partner_ep_status(hw, epidx); + switch (pstatus) { + case EP_PARTNER_UNSHARE: + default: + if ((res_buf->info.info[epidx].zone != + FJES_ZONING_ZONE_TYPE_NONE) && + (res_buf->info.info[epidx].es_status == + FJES_ZONING_STATUS_ENABLE) && + (res_buf->info.info[epidx].zone == + res_buf->info.info[hw->my_epid].zone)) + set_bit(epidx, &share_bit); + else + set_bit(epidx, &unshare_bit); + break; + + case EP_PARTNER_COMPLETE: + case EP_PARTNER_WAITING: + if ((res_buf->info.info[epidx].zone == + FJES_ZONING_ZONE_TYPE_NONE) || + (res_buf->info.info[epidx].es_status != + FJES_ZONING_STATUS_ENABLE) || + (res_buf->info.info[epidx].zone != + res_buf->info. + info[hw->my_epid].zone)) { + + set_bit(epidx, + &adapter->unshare_watch_bitmask); + set_bit(epidx, + &hw->hw_info.buffer_unshare_reserve_bit); + } + break; + + case EP_PARTNER_SHARED: + if ((res_buf->info.info[epidx].zone == + FJES_ZONING_ZONE_TYPE_NONE) || + (res_buf->info.info[epidx].es_status != + FJES_ZONING_STATUS_ENABLE) || + (res_buf->info.info[epidx].zone != + res_buf->info. + info[hw->my_epid].zone)) + + set_bit(epidx, &irq_bit); + break; + } + + } + + if (hw->ep_shm_info[epidx].zone != + res_buf->info.info[epidx].zone) + update = true; + hw->ep_shm_info[epidx].es_status = + res_buf->info.info[epidx].es_status; + hw->ep_shm_info[epidx].zone = + res_buf->info.info[epidx].zone; + + } + break; + } + + mutex_unlock(&hw->hw_info.lock); + + for (epidx = 0; epidx < hw->max_epid; epidx++) { + + if (epidx == hw->my_epid) + continue; + + if (test_bit(epidx, &share_bit)) { + + fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx, + netdev->dev_addr, netdev->mtu); + + mutex_lock(&hw->hw_info.lock); + + ret = fjes_hw_register_buff_addr(hw, epidx, + &hw->ep_shm_info[epidx]); + + switch (ret) { + case 0: + break; + case -ENOMSG: + case -EBUSY: + default: + if (!work_pending(&adapter->force_close_task)) { + adapter->force_reset = true; + schedule_work( + &adapter->force_close_task); + } + break; + } + + mutex_unlock(&hw->hw_info.lock); + } + + + if (test_bit(epidx, &unshare_bit)) { + + mutex_lock(&hw->hw_info.lock); + + ret = fjes_hw_unregister_buff_addr(hw, epidx); + + switch (ret) { + case 0: + break; + case -ENOMSG: + case -EBUSY: + default: + if (!work_pending(&adapter->force_close_task)) { + adapter->force_reset = true; + schedule_work( + &adapter->force_close_task); + } + break; + } + + mutex_unlock(&hw->hw_info.lock); + + if (ret == 0) + fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx, + netdev->dev_addr, netdev->mtu); + + } + + if (test_bit(epidx, &irq_bit)) { + fjes_hw_raise_interrupt(hw, epidx, + REG_ICTL_MASK_TXRX_STOP_REQ); + + set_bit(epidx, &hw->txrx_stop_req_bit); + hw->ep_shm_info[epidx].tx. + info->v1i.rx_status |= + FJES_RX_STOP_REQ_REQUEST; + set_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit); + } + + } + + if (irq_bit || adapter->unshare_watch_bitmask) { + if (!work_pending(&adapter->unshare_watch_task)) + queue_work(adapter->control_wq, + &adapter->unshare_watch_task); + } +} + diff --git a/drivers/platform/x86/fjes/fjes_hw.h b/drivers/platform/x86/fjes/fjes_hw.h index 14e8db9..1b0afc0 100644 --- a/drivers/platform/x86/fjes/fjes_hw.h +++ b/drivers/platform/x86/fjes/fjes_hw.h @@ -284,6 +284,7 @@ struct fjes_hw { unsigned long txrx_stop_req_bit; unsigned long epstop_req_bit; + struct work_struct update_zone_task; int my_epid; int max_epid; diff --git a/drivers/platform/x86/fjes/fjes_main.c b/drivers/platform/x86/fjes/fjes_main.c index 1bba967..900aa65 100644 --- a/drivers/platform/x86/fjes/fjes_main.c +++ b/drivers/platform/x86/fjes/fjes_main.c @@ -323,6 +323,8 @@ static int fjes_close(struct net_device *netdev) cancel_work_sync(&adapter->raise_intr_rxdata_task); cancel_work_sync(&adapter->tx_stall_task); + cancel_work_sync(&hw->update_zone_task); + fjes_hw_wait_epstop(hw); fjes_free_resources(adapter); @@ -852,6 +854,15 @@ static int fjes_vlan_rx_kill_vid(struct net_device *netdev, return 0; } +static void fjes_update_zone_irq(struct fjes_adapter *adapter, + int src_epid) +{ + struct fjes_hw *hw = &adapter->hw; + + if (!work_pending(&hw->update_zone_task)) + queue_work(adapter->control_wq, &hw->update_zone_task); +} + static irqreturn_t fjes_intr(int irq, void *data) { struct fjes_adapter *adapter = data; @@ -866,6 +877,9 @@ static irqreturn_t fjes_intr(int irq, void *data) if (icr & REG_ICTL_MASK_RX_DATA) fjes_rx_irq(adapter, icr & REG_IS_MASK_EPID); + if (icr & REG_ICTL_MASK_INFO_UPDATE) + fjes_update_zone_irq(adapter, icr & REG_IS_MASK_EPID); + ret = IRQ_HANDLED; } else ret = IRQ_NONE;