fjes: Introduce spinlock for rx_status
This patch introduces spinlock of rx_status for proper excusive control. Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
16bbec3a50
commit
bd5a256991
@ -216,6 +216,7 @@ static int fjes_hw_setup(struct fjes_hw *hw)
|
|||||||
u8 mac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
u8 mac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
struct fjes_device_command_param param;
|
struct fjes_device_command_param param;
|
||||||
struct ep_share_mem_info *buf_pair;
|
struct ep_share_mem_info *buf_pair;
|
||||||
|
unsigned long flags;
|
||||||
size_t mem_size;
|
size_t mem_size;
|
||||||
int result;
|
int result;
|
||||||
int epidx;
|
int epidx;
|
||||||
@ -264,10 +265,12 @@ static int fjes_hw_setup(struct fjes_hw *hw)
|
|||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
fjes_hw_setup_epbuf(&buf_pair->tx, mac,
|
fjes_hw_setup_epbuf(&buf_pair->tx, mac,
|
||||||
fjes_support_mtu[0]);
|
fjes_support_mtu[0]);
|
||||||
fjes_hw_setup_epbuf(&buf_pair->rx, mac,
|
fjes_hw_setup_epbuf(&buf_pair->rx, mac,
|
||||||
fjes_support_mtu[0]);
|
fjes_support_mtu[0]);
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,6 +332,7 @@ int fjes_hw_init(struct fjes_hw *hw)
|
|||||||
INIT_WORK(&hw->epstop_task, fjes_hw_epstop_task);
|
INIT_WORK(&hw->epstop_task, fjes_hw_epstop_task);
|
||||||
|
|
||||||
mutex_init(&hw->hw_info.lock);
|
mutex_init(&hw->hw_info.lock);
|
||||||
|
spin_lock_init(&hw->rx_status_lock);
|
||||||
|
|
||||||
hw->max_epid = fjes_hw_get_max_epid(hw);
|
hw->max_epid = fjes_hw_get_max_epid(hw);
|
||||||
hw->my_epid = fjes_hw_get_my_epid(hw);
|
hw->my_epid = fjes_hw_get_my_epid(hw);
|
||||||
@ -736,6 +740,7 @@ fjes_hw_get_partner_ep_status(struct fjes_hw *hw, int epid)
|
|||||||
void fjes_hw_raise_epstop(struct fjes_hw *hw)
|
void fjes_hw_raise_epstop(struct fjes_hw *hw)
|
||||||
{
|
{
|
||||||
enum ep_partner_status status;
|
enum ep_partner_status status;
|
||||||
|
unsigned long flags;
|
||||||
int epidx;
|
int epidx;
|
||||||
|
|
||||||
for (epidx = 0; epidx < hw->max_epid; epidx++) {
|
for (epidx = 0; epidx < hw->max_epid; epidx++) {
|
||||||
@ -755,8 +760,10 @@ void fjes_hw_raise_epstop(struct fjes_hw *hw)
|
|||||||
set_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit);
|
set_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit);
|
||||||
set_bit(epidx, &hw->txrx_stop_req_bit);
|
set_bit(epidx, &hw->txrx_stop_req_bit);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
hw->ep_shm_info[epidx].tx.info->v1i.rx_status |=
|
hw->ep_shm_info[epidx].tx.info->v1i.rx_status |=
|
||||||
FJES_RX_STOP_REQ_REQUEST;
|
FJES_RX_STOP_REQ_REQUEST;
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -938,6 +945,7 @@ static void fjes_hw_update_zone_task(struct work_struct *work)
|
|||||||
|
|
||||||
struct fjes_adapter *adapter;
|
struct fjes_adapter *adapter;
|
||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
ulong unshare_bit = 0;
|
ulong unshare_bit = 0;
|
||||||
ulong share_bit = 0;
|
ulong share_bit = 0;
|
||||||
@ -1030,8 +1038,10 @@ static void fjes_hw_update_zone_task(struct work_struct *work)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (test_bit(epidx, &share_bit)) {
|
if (test_bit(epidx, &share_bit)) {
|
||||||
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx,
|
fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx,
|
||||||
netdev->dev_addr, netdev->mtu);
|
netdev->dev_addr, netdev->mtu);
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock, flags);
|
||||||
|
|
||||||
mutex_lock(&hw->hw_info.lock);
|
mutex_lock(&hw->hw_info.lock);
|
||||||
|
|
||||||
@ -1075,10 +1085,14 @@ static void fjes_hw_update_zone_task(struct work_struct *work)
|
|||||||
|
|
||||||
mutex_unlock(&hw->hw_info.lock);
|
mutex_unlock(&hw->hw_info.lock);
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0) {
|
||||||
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
fjes_hw_setup_epbuf(
|
fjes_hw_setup_epbuf(
|
||||||
&hw->ep_shm_info[epidx].tx,
|
&hw->ep_shm_info[epidx].tx,
|
||||||
netdev->dev_addr, netdev->mtu);
|
netdev->dev_addr, netdev->mtu);
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock,
|
||||||
|
flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_bit(epidx, &irq_bit)) {
|
if (test_bit(epidx, &irq_bit)) {
|
||||||
@ -1086,9 +1100,11 @@ static void fjes_hw_update_zone_task(struct work_struct *work)
|
|||||||
REG_ICTL_MASK_TXRX_STOP_REQ);
|
REG_ICTL_MASK_TXRX_STOP_REQ);
|
||||||
|
|
||||||
set_bit(epidx, &hw->txrx_stop_req_bit);
|
set_bit(epidx, &hw->txrx_stop_req_bit);
|
||||||
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
hw->ep_shm_info[epidx].tx.
|
hw->ep_shm_info[epidx].tx.
|
||||||
info->v1i.rx_status |=
|
info->v1i.rx_status |=
|
||||||
FJES_RX_STOP_REQ_REQUEST;
|
FJES_RX_STOP_REQ_REQUEST;
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock, flags);
|
||||||
set_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit);
|
set_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1104,6 +1120,7 @@ static void fjes_hw_epstop_task(struct work_struct *work)
|
|||||||
{
|
{
|
||||||
struct fjes_hw *hw = container_of(work, struct fjes_hw, epstop_task);
|
struct fjes_hw *hw = container_of(work, struct fjes_hw, epstop_task);
|
||||||
struct fjes_adapter *adapter = (struct fjes_adapter *)hw->back;
|
struct fjes_adapter *adapter = (struct fjes_adapter *)hw->back;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
ulong remain_bit;
|
ulong remain_bit;
|
||||||
int epid_bit;
|
int epid_bit;
|
||||||
@ -1111,9 +1128,12 @@ static void fjes_hw_epstop_task(struct work_struct *work)
|
|||||||
while ((remain_bit = hw->epstop_req_bit)) {
|
while ((remain_bit = hw->epstop_req_bit)) {
|
||||||
for (epid_bit = 0; remain_bit; remain_bit >>= 1, epid_bit++) {
|
for (epid_bit = 0; remain_bit; remain_bit >>= 1, epid_bit++) {
|
||||||
if (remain_bit & 1) {
|
if (remain_bit & 1) {
|
||||||
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
hw->ep_shm_info[epid_bit].
|
hw->ep_shm_info[epid_bit].
|
||||||
tx.info->v1i.rx_status |=
|
tx.info->v1i.rx_status |=
|
||||||
FJES_RX_STOP_REQ_DONE;
|
FJES_RX_STOP_REQ_DONE;
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock,
|
||||||
|
flags);
|
||||||
|
|
||||||
clear_bit(epid_bit, &hw->epstop_req_bit);
|
clear_bit(epid_bit, &hw->epstop_req_bit);
|
||||||
set_bit(epid_bit,
|
set_bit(epid_bit,
|
||||||
|
@ -300,6 +300,8 @@ struct fjes_hw {
|
|||||||
u8 *base;
|
u8 *base;
|
||||||
|
|
||||||
struct fjes_hw_info hw_info;
|
struct fjes_hw_info hw_info;
|
||||||
|
|
||||||
|
spinlock_t rx_status_lock; /* spinlock for rx_status */
|
||||||
};
|
};
|
||||||
|
|
||||||
int fjes_hw_init(struct fjes_hw *);
|
int fjes_hw_init(struct fjes_hw *);
|
||||||
|
@ -290,6 +290,7 @@ static int fjes_close(struct net_device *netdev)
|
|||||||
{
|
{
|
||||||
struct fjes_adapter *adapter = netdev_priv(netdev);
|
struct fjes_adapter *adapter = netdev_priv(netdev);
|
||||||
struct fjes_hw *hw = &adapter->hw;
|
struct fjes_hw *hw = &adapter->hw;
|
||||||
|
unsigned long flags;
|
||||||
int epidx;
|
int epidx;
|
||||||
|
|
||||||
netif_tx_stop_all_queues(netdev);
|
netif_tx_stop_all_queues(netdev);
|
||||||
@ -299,13 +300,18 @@ static int fjes_close(struct net_device *netdev)
|
|||||||
|
|
||||||
napi_disable(&adapter->napi);
|
napi_disable(&adapter->napi);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
for (epidx = 0; epidx < hw->max_epid; epidx++) {
|
for (epidx = 0; epidx < hw->max_epid; epidx++) {
|
||||||
if (epidx == hw->my_epid)
|
if (epidx == hw->my_epid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
adapter->hw.ep_shm_info[epidx].tx.info->v1i.rx_status &=
|
if (fjes_hw_get_partner_ep_status(hw, epidx) ==
|
||||||
~FJES_RX_POLL_WORK;
|
EP_PARTNER_SHARED)
|
||||||
|
adapter->hw.ep_shm_info[epidx]
|
||||||
|
.tx.info->v1i.rx_status &=
|
||||||
|
~FJES_RX_POLL_WORK;
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock, flags);
|
||||||
|
|
||||||
fjes_free_irq(adapter);
|
fjes_free_irq(adapter);
|
||||||
|
|
||||||
@ -330,6 +336,7 @@ static int fjes_setup_resources(struct fjes_adapter *adapter)
|
|||||||
struct net_device *netdev = adapter->netdev;
|
struct net_device *netdev = adapter->netdev;
|
||||||
struct ep_share_mem_info *buf_pair;
|
struct ep_share_mem_info *buf_pair;
|
||||||
struct fjes_hw *hw = &adapter->hw;
|
struct fjes_hw *hw = &adapter->hw;
|
||||||
|
unsigned long flags;
|
||||||
int result;
|
int result;
|
||||||
int epidx;
|
int epidx;
|
||||||
|
|
||||||
@ -371,8 +378,10 @@ static int fjes_setup_resources(struct fjes_adapter *adapter)
|
|||||||
|
|
||||||
buf_pair = &hw->ep_shm_info[epidx];
|
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,
|
fjes_hw_setup_epbuf(&buf_pair->tx, netdev->dev_addr,
|
||||||
netdev->mtu);
|
netdev->mtu);
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock, flags);
|
||||||
|
|
||||||
if (fjes_hw_epid_is_same_zone(hw, epidx)) {
|
if (fjes_hw_epid_is_same_zone(hw, epidx)) {
|
||||||
mutex_lock(&hw->hw_info.lock);
|
mutex_lock(&hw->hw_info.lock);
|
||||||
@ -402,6 +411,7 @@ static void fjes_free_resources(struct fjes_adapter *adapter)
|
|||||||
struct ep_share_mem_info *buf_pair;
|
struct ep_share_mem_info *buf_pair;
|
||||||
struct fjes_hw *hw = &adapter->hw;
|
struct fjes_hw *hw = &adapter->hw;
|
||||||
bool reset_flag = false;
|
bool reset_flag = false;
|
||||||
|
unsigned long flags;
|
||||||
int result;
|
int result;
|
||||||
int epidx;
|
int epidx;
|
||||||
|
|
||||||
@ -418,8 +428,10 @@ static void fjes_free_resources(struct fjes_adapter *adapter)
|
|||||||
|
|
||||||
buf_pair = &hw->ep_shm_info[epidx];
|
buf_pair = &hw->ep_shm_info[epidx];
|
||||||
|
|
||||||
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
fjes_hw_setup_epbuf(&buf_pair->tx,
|
fjes_hw_setup_epbuf(&buf_pair->tx,
|
||||||
netdev->dev_addr, netdev->mtu);
|
netdev->dev_addr, netdev->mtu);
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock, flags);
|
||||||
|
|
||||||
clear_bit(epidx, &hw->txrx_stop_req_bit);
|
clear_bit(epidx, &hw->txrx_stop_req_bit);
|
||||||
}
|
}
|
||||||
@ -766,6 +778,7 @@ static int fjes_change_mtu(struct net_device *netdev, int new_mtu)
|
|||||||
struct fjes_adapter *adapter = netdev_priv(netdev);
|
struct fjes_adapter *adapter = netdev_priv(netdev);
|
||||||
bool running = netif_running(netdev);
|
bool running = netif_running(netdev);
|
||||||
struct fjes_hw *hw = &adapter->hw;
|
struct fjes_hw *hw = &adapter->hw;
|
||||||
|
unsigned long flags;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
int idx, epidx;
|
int idx, epidx;
|
||||||
|
|
||||||
@ -784,12 +797,15 @@ static int fjes_change_mtu(struct net_device *netdev, int new_mtu)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (running) {
|
if (running) {
|
||||||
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
for (epidx = 0; epidx < hw->max_epid; epidx++) {
|
for (epidx = 0; epidx < hw->max_epid; epidx++) {
|
||||||
if (epidx == hw->my_epid)
|
if (epidx == hw->my_epid)
|
||||||
continue;
|
continue;
|
||||||
hw->ep_shm_info[epidx].tx.info->v1i.rx_status &=
|
hw->ep_shm_info[epidx].tx.info->v1i.rx_status &=
|
||||||
~FJES_RX_MTU_CHANGING_DONE;
|
~FJES_RX_MTU_CHANGING_DONE;
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock, flags);
|
||||||
|
|
||||||
netif_tx_stop_all_queues(netdev);
|
netif_tx_stop_all_queues(netdev);
|
||||||
netif_carrier_off(netdev);
|
netif_carrier_off(netdev);
|
||||||
cancel_work_sync(&adapter->tx_stall_task);
|
cancel_work_sync(&adapter->tx_stall_task);
|
||||||
@ -803,23 +819,25 @@ static int fjes_change_mtu(struct net_device *netdev, int new_mtu)
|
|||||||
netdev->mtu = new_mtu;
|
netdev->mtu = new_mtu;
|
||||||
|
|
||||||
if (running) {
|
if (running) {
|
||||||
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
for (epidx = 0; epidx < hw->max_epid; epidx++) {
|
for (epidx = 0; epidx < hw->max_epid; epidx++) {
|
||||||
if (epidx == hw->my_epid)
|
if (epidx == hw->my_epid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
local_irq_disable();
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx,
|
fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx,
|
||||||
netdev->dev_addr,
|
netdev->dev_addr,
|
||||||
netdev->mtu);
|
netdev->mtu);
|
||||||
local_irq_enable();
|
|
||||||
|
|
||||||
hw->ep_shm_info[epidx].tx.info->v1i.rx_status |=
|
hw->ep_shm_info[epidx].tx.info->v1i.rx_status |=
|
||||||
FJES_RX_MTU_CHANGING_DONE;
|
FJES_RX_MTU_CHANGING_DONE;
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
netif_tx_wake_all_queues(netdev);
|
netif_tx_wake_all_queues(netdev);
|
||||||
netif_carrier_on(netdev);
|
netif_carrier_on(netdev);
|
||||||
napi_enable(&adapter->napi);
|
napi_enable(&adapter->napi);
|
||||||
|
napi_schedule(&adapter->napi);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -866,6 +884,7 @@ static void fjes_txrx_stop_req_irq(struct fjes_adapter *adapter,
|
|||||||
{
|
{
|
||||||
struct fjes_hw *hw = &adapter->hw;
|
struct fjes_hw *hw = &adapter->hw;
|
||||||
enum ep_partner_status status;
|
enum ep_partner_status status;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
status = fjes_hw_get_partner_ep_status(hw, src_epid);
|
status = fjes_hw_get_partner_ep_status(hw, src_epid);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
@ -875,8 +894,10 @@ static void fjes_txrx_stop_req_irq(struct fjes_adapter *adapter,
|
|||||||
break;
|
break;
|
||||||
case EP_PARTNER_WAITING:
|
case EP_PARTNER_WAITING:
|
||||||
if (src_epid < hw->my_epid) {
|
if (src_epid < hw->my_epid) {
|
||||||
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
hw->ep_shm_info[src_epid].tx.info->v1i.rx_status |=
|
hw->ep_shm_info[src_epid].tx.info->v1i.rx_status |=
|
||||||
FJES_RX_STOP_REQ_DONE;
|
FJES_RX_STOP_REQ_DONE;
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock, flags);
|
||||||
|
|
||||||
clear_bit(src_epid, &hw->txrx_stop_req_bit);
|
clear_bit(src_epid, &hw->txrx_stop_req_bit);
|
||||||
set_bit(src_epid, &adapter->unshare_watch_bitmask);
|
set_bit(src_epid, &adapter->unshare_watch_bitmask);
|
||||||
@ -902,14 +923,17 @@ static void fjes_stop_req_irq(struct fjes_adapter *adapter, int src_epid)
|
|||||||
{
|
{
|
||||||
struct fjes_hw *hw = &adapter->hw;
|
struct fjes_hw *hw = &adapter->hw;
|
||||||
enum ep_partner_status status;
|
enum ep_partner_status status;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
set_bit(src_epid, &hw->hw_info.buffer_unshare_reserve_bit);
|
set_bit(src_epid, &hw->hw_info.buffer_unshare_reserve_bit);
|
||||||
|
|
||||||
status = fjes_hw_get_partner_ep_status(hw, src_epid);
|
status = fjes_hw_get_partner_ep_status(hw, src_epid);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case EP_PARTNER_WAITING:
|
case EP_PARTNER_WAITING:
|
||||||
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
hw->ep_shm_info[src_epid].tx.info->v1i.rx_status |=
|
hw->ep_shm_info[src_epid].tx.info->v1i.rx_status |=
|
||||||
FJES_RX_STOP_REQ_DONE;
|
FJES_RX_STOP_REQ_DONE;
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock, flags);
|
||||||
clear_bit(src_epid, &hw->txrx_stop_req_bit);
|
clear_bit(src_epid, &hw->txrx_stop_req_bit);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case EP_PARTNER_UNSHARE:
|
case EP_PARTNER_UNSHARE:
|
||||||
@ -1042,13 +1066,17 @@ static int fjes_poll(struct napi_struct *napi, int budget)
|
|||||||
size_t frame_len;
|
size_t frame_len;
|
||||||
void *frame;
|
void *frame;
|
||||||
|
|
||||||
|
spin_lock(&hw->rx_status_lock);
|
||||||
for (epidx = 0; epidx < hw->max_epid; epidx++) {
|
for (epidx = 0; epidx < hw->max_epid; epidx++) {
|
||||||
if (epidx == hw->my_epid)
|
if (epidx == hw->my_epid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
adapter->hw.ep_shm_info[epidx].tx.info->v1i.rx_status |=
|
if (fjes_hw_get_partner_ep_status(hw, epidx) ==
|
||||||
FJES_RX_POLL_WORK;
|
EP_PARTNER_SHARED)
|
||||||
|
adapter->hw.ep_shm_info[epidx]
|
||||||
|
.tx.info->v1i.rx_status |= FJES_RX_POLL_WORK;
|
||||||
}
|
}
|
||||||
|
spin_unlock(&hw->rx_status_lock);
|
||||||
|
|
||||||
while (work_done < budget) {
|
while (work_done < budget) {
|
||||||
prefetch(&adapter->hw);
|
prefetch(&adapter->hw);
|
||||||
@ -1106,13 +1134,17 @@ static int fjes_poll(struct napi_struct *napi, int budget)
|
|||||||
if (((long)jiffies - (long)adapter->rx_last_jiffies) < 3) {
|
if (((long)jiffies - (long)adapter->rx_last_jiffies) < 3) {
|
||||||
napi_reschedule(napi);
|
napi_reschedule(napi);
|
||||||
} else {
|
} else {
|
||||||
|
spin_lock(&hw->rx_status_lock);
|
||||||
for (epidx = 0; epidx < hw->max_epid; epidx++) {
|
for (epidx = 0; epidx < hw->max_epid; epidx++) {
|
||||||
if (epidx == hw->my_epid)
|
if (epidx == hw->my_epid)
|
||||||
continue;
|
continue;
|
||||||
adapter->hw.ep_shm_info[epidx]
|
if (fjes_hw_get_partner_ep_status(hw, epidx) ==
|
||||||
.tx.info->v1i.rx_status &=
|
EP_PARTNER_SHARED)
|
||||||
|
adapter->hw.ep_shm_info[epidx].tx
|
||||||
|
.info->v1i.rx_status &=
|
||||||
~FJES_RX_POLL_WORK;
|
~FJES_RX_POLL_WORK;
|
||||||
}
|
}
|
||||||
|
spin_unlock(&hw->rx_status_lock);
|
||||||
|
|
||||||
fjes_hw_set_irqmask(hw, REG_ICTL_MASK_RX_DATA, false);
|
fjes_hw_set_irqmask(hw, REG_ICTL_MASK_RX_DATA, false);
|
||||||
}
|
}
|
||||||
@ -1281,6 +1313,7 @@ static void fjes_watch_unshare_task(struct work_struct *work)
|
|||||||
int max_epid, my_epid, epidx;
|
int max_epid, my_epid, epidx;
|
||||||
int stop_req, stop_req_done;
|
int stop_req, stop_req_done;
|
||||||
ulong unshare_watch_bitmask;
|
ulong unshare_watch_bitmask;
|
||||||
|
unsigned long flags;
|
||||||
int wait_time = 0;
|
int wait_time = 0;
|
||||||
int is_shared;
|
int is_shared;
|
||||||
int ret;
|
int ret;
|
||||||
@ -1333,8 +1366,10 @@ static void fjes_watch_unshare_task(struct work_struct *work)
|
|||||||
}
|
}
|
||||||
mutex_unlock(&hw->hw_info.lock);
|
mutex_unlock(&hw->hw_info.lock);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx,
|
fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx,
|
||||||
netdev->dev_addr, netdev->mtu);
|
netdev->dev_addr, netdev->mtu);
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock, flags);
|
||||||
|
|
||||||
clear_bit(epidx, &hw->txrx_stop_req_bit);
|
clear_bit(epidx, &hw->txrx_stop_req_bit);
|
||||||
clear_bit(epidx, &unshare_watch_bitmask);
|
clear_bit(epidx, &unshare_watch_bitmask);
|
||||||
@ -1372,9 +1407,12 @@ static void fjes_watch_unshare_task(struct work_struct *work)
|
|||||||
}
|
}
|
||||||
mutex_unlock(&hw->hw_info.lock);
|
mutex_unlock(&hw->hw_info.lock);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
fjes_hw_setup_epbuf(
|
fjes_hw_setup_epbuf(
|
||||||
&hw->ep_shm_info[epidx].tx,
|
&hw->ep_shm_info[epidx].tx,
|
||||||
netdev->dev_addr, netdev->mtu);
|
netdev->dev_addr, netdev->mtu);
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock,
|
||||||
|
flags);
|
||||||
|
|
||||||
clear_bit(epidx, &hw->txrx_stop_req_bit);
|
clear_bit(epidx, &hw->txrx_stop_req_bit);
|
||||||
clear_bit(epidx, &unshare_watch_bitmask);
|
clear_bit(epidx, &unshare_watch_bitmask);
|
||||||
@ -1382,8 +1420,11 @@ static void fjes_watch_unshare_task(struct work_struct *work)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (test_bit(epidx, &unshare_watch_bitmask)) {
|
if (test_bit(epidx, &unshare_watch_bitmask)) {
|
||||||
|
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||||
hw->ep_shm_info[epidx].tx.info->v1i.rx_status &=
|
hw->ep_shm_info[epidx].tx.info->v1i.rx_status &=
|
||||||
~FJES_RX_STOP_REQ_DONE;
|
~FJES_RX_STOP_REQ_DONE;
|
||||||
|
spin_unlock_irqrestore(&hw->rx_status_lock,
|
||||||
|
flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user