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) ...@@ -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++) for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++)
info->v1i.vlan_id[i] = vlan_id[i]; info->v1i.vlan_id[i] = vlan_id[i];
info->v1i.rx_status |= FJES_RX_MTU_CHANGING_DONE;
} }
void void
...@@ -810,7 +812,8 @@ bool fjes_hw_check_mtu(struct epbuf_handler *epbh, u32 mtu) ...@@ -810,7 +812,8 @@ bool fjes_hw_check_mtu(struct epbuf_handler *epbh, u32 mtu)
{ {
union ep_buffer_info *info = epbh->info; 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) 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) ...@@ -863,6 +866,9 @@ bool fjes_hw_epbuf_rx_is_empty(struct epbuf_handler *epbh)
{ {
union ep_buffer_info *info = epbh->info; 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) if (info->v1i.count_max == 0)
return true; return true;
......
...@@ -57,6 +57,7 @@ struct fjes_hw; ...@@ -57,6 +57,7 @@ struct fjes_hw;
#define FJES_RX_STOP_REQ_DONE (0x1) #define FJES_RX_STOP_REQ_DONE (0x1)
#define FJES_RX_STOP_REQ_REQUEST (0x2) #define FJES_RX_STOP_REQ_REQUEST (0x2)
#define FJES_RX_POLL_WORK (0x4) #define FJES_RX_POLL_WORK (0x4)
#define FJES_RX_MTU_CHANGING_DONE (0x8)
#define EP_BUFFER_SIZE \ #define EP_BUFFER_SIZE \
(((sizeof(union ep_buffer_info) + (128 * (64 * 1024))) \ (((sizeof(union ep_buffer_info) + (128 * (64 * 1024))) \
......
...@@ -481,6 +481,9 @@ static void fjes_tx_stall_task(struct work_struct *work) ...@@ -481,6 +481,9 @@ static void fjes_tx_stall_task(struct work_struct *work)
info = adapter->hw.ep_shm_info[epid].tx.info; 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, if (EP_RING_FULL(info->v1i.head, info->v1i.tail,
info->v1i.count_max)) { info->v1i.count_max)) {
all_queue_available = 0; all_queue_available = 0;
...@@ -760,9 +763,11 @@ fjes_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) ...@@ -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) static int fjes_change_mtu(struct net_device *netdev, int new_mtu)
{ {
struct fjes_adapter *adapter = netdev_priv(netdev);
bool running = netif_running(netdev); bool running = netif_running(netdev);
int ret = 0; struct fjes_hw *hw = &adapter->hw;
int idx; int ret = -EINVAL;
int idx, epidx;
for (idx = 0; fjes_support_mtu[idx] != 0; idx++) { for (idx = 0; fjes_support_mtu[idx] != 0; idx++) {
if (new_mtu <= fjes_support_mtu[idx]) { if (new_mtu <= fjes_support_mtu[idx]) {
...@@ -770,19 +775,54 @@ static int fjes_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -770,19 +775,54 @@ static int fjes_change_mtu(struct net_device *netdev, int new_mtu)
if (new_mtu == netdev->mtu) if (new_mtu == netdev->mtu)
return 0; return 0;
if (running) ret = 0;
fjes_close(netdev); 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) netdev->mtu = new_mtu;
ret = fjes_open(netdev);
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, static int fjes_vlan_rx_add_vid(struct net_device *netdev,
...@@ -1204,7 +1244,7 @@ static void fjes_netdev_setup(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->watchdog_timeo = FJES_TX_RETRY_INTERVAL;
netdev->netdev_ops = &fjes_netdev_ops; netdev->netdev_ops = &fjes_netdev_ops;
fjes_set_ethtool_ops(netdev); fjes_set_ethtool_ops(netdev);
netdev->mtu = fjes_support_mtu[0]; netdev->mtu = fjes_support_mtu[3];
netdev->flags |= IFF_BROADCAST; netdev->flags |= IFF_BROADCAST;
netdev->features |= NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_FILTER; 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