Commit 16bbec3a authored by Taku Izumi's avatar Taku Izumi Committed by David S. Miller

fjes: Enhance changing MTU related work

This patch enhances the fjes_change_mtu() method
by introducing new flag named FJES_RX_MTU_CHANGING_DONE
in rx_status. At the same time, default MTU value is
changed into 65510 bytes.
Signed-off-by: default avatarTaku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 19a0a7fd
......@@ -179,6 +179,8 @@ void fjes_hw_setup_epbuf(struct epbuf_handler *epbh, u8 *mac_addr, u32 mtu)
for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++)
info->v1i.vlan_id[i] = vlan_id[i];
info->v1i.rx_status |= FJES_RX_MTU_CHANGING_DONE;
}
void
......@@ -810,7 +812,8 @@ bool fjes_hw_check_mtu(struct epbuf_handler *epbh, u32 mtu)
{
union ep_buffer_info *info = epbh->info;
return (info->v1i.frame_max == FJES_MTU_TO_FRAME_SIZE(mtu));
return ((info->v1i.frame_max == FJES_MTU_TO_FRAME_SIZE(mtu)) &&
info->v1i.rx_status & FJES_RX_MTU_CHANGING_DONE);
}
bool fjes_hw_check_vlan_id(struct epbuf_handler *epbh, u16 vlan_id)
......@@ -863,6 +866,9 @@ bool fjes_hw_epbuf_rx_is_empty(struct epbuf_handler *epbh)
{
union ep_buffer_info *info = epbh->info;
if (!(info->v1i.rx_status & FJES_RX_MTU_CHANGING_DONE))
return true;
if (info->v1i.count_max == 0)
return true;
......
......@@ -57,6 +57,7 @@ struct fjes_hw;
#define FJES_RX_STOP_REQ_DONE (0x1)
#define FJES_RX_STOP_REQ_REQUEST (0x2)
#define FJES_RX_POLL_WORK (0x4)
#define FJES_RX_MTU_CHANGING_DONE (0x8)
#define EP_BUFFER_SIZE \
(((sizeof(union ep_buffer_info) + (128 * (64 * 1024))) \
......
......@@ -481,6 +481,9 @@ static void fjes_tx_stall_task(struct work_struct *work)
info = adapter->hw.ep_shm_info[epid].tx.info;
if (!(info->v1i.rx_status & FJES_RX_MTU_CHANGING_DONE))
return;
if (EP_RING_FULL(info->v1i.head, info->v1i.tail,
info->v1i.count_max)) {
all_queue_available = 0;
......@@ -760,9 +763,11 @@ fjes_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
static int fjes_change_mtu(struct net_device *netdev, int new_mtu)
{
struct fjes_adapter *adapter = netdev_priv(netdev);
bool running = netif_running(netdev);
int ret = 0;
int idx;
struct fjes_hw *hw = &adapter->hw;
int ret = -EINVAL;
int idx, epidx;
for (idx = 0; fjes_support_mtu[idx] != 0; idx++) {
if (new_mtu <= fjes_support_mtu[idx]) {
......@@ -770,19 +775,54 @@ static int fjes_change_mtu(struct net_device *netdev, int new_mtu)
if (new_mtu == netdev->mtu)
return 0;
if (running)
fjes_close(netdev);
ret = 0;
break;
}
}
if (ret)
return ret;
if (running) {
for (epidx = 0; epidx < hw->max_epid; epidx++) {
if (epidx == hw->my_epid)
continue;
hw->ep_shm_info[epidx].tx.info->v1i.rx_status &=
~FJES_RX_MTU_CHANGING_DONE;
}
netif_tx_stop_all_queues(netdev);
netif_carrier_off(netdev);
cancel_work_sync(&adapter->tx_stall_task);
napi_disable(&adapter->napi);
msleep(1000);
netdev->mtu = new_mtu;
netif_tx_stop_all_queues(netdev);
}
if (running)
ret = fjes_open(netdev);
netdev->mtu = new_mtu;
return ret;
if (running) {
for (epidx = 0; epidx < hw->max_epid; epidx++) {
if (epidx == hw->my_epid)
continue;
local_irq_disable();
fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx,
netdev->dev_addr,
netdev->mtu);
local_irq_enable();
hw->ep_shm_info[epidx].tx.info->v1i.rx_status |=
FJES_RX_MTU_CHANGING_DONE;
}
netif_tx_wake_all_queues(netdev);
netif_carrier_on(netdev);
napi_enable(&adapter->napi);
}
return -EINVAL;
return ret;
}
static int fjes_vlan_rx_add_vid(struct net_device *netdev,
......@@ -1204,7 +1244,7 @@ static void fjes_netdev_setup(struct net_device *netdev)
netdev->watchdog_timeo = FJES_TX_RETRY_INTERVAL;
netdev->netdev_ops = &fjes_netdev_ops;
fjes_set_ethtool_ops(netdev);
netdev->mtu = fjes_support_mtu[0];
netdev->mtu = fjes_support_mtu[3];
netdev->flags |= IFF_BROADCAST;
netdev->features |= NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_FILTER;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment