diff options
| author | Taku Izumi <izumi.taku@jp.fujitsu.com> | 2016-04-14 22:25:40 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2016-04-16 21:51:01 -0400 |
| commit | 16bbec3a50efec46b679c3408c8be09f09dbcb7e (patch) | |
| tree | 6d88a0df0e561aa52c2a9f18a747e6253e900fd9 | |
| parent | 19a0a7fd55af4658414de955f401cddaffc1f0ba (diff) | |
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: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/fjes/fjes_hw.c | 8 | ||||
| -rw-r--r-- | drivers/net/fjes/fjes_hw.h | 1 | ||||
| -rw-r--r-- | drivers/net/fjes/fjes_main.c | 60 |
3 files changed, 58 insertions, 11 deletions
diff --git a/drivers/net/fjes/fjes_hw.c b/drivers/net/fjes/fjes_hw.c index b103adb8d62e..e9f494bd70ad 100644 --- a/drivers/net/fjes/fjes_hw.c +++ b/drivers/net/fjes/fjes_hw.c | |||
| @@ -179,6 +179,8 @@ void fjes_hw_setup_epbuf(struct epbuf_handler *epbh, u8 *mac_addr, u32 mtu) | |||
| 179 | 179 | ||
| 180 | for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++) | 180 | for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++) |
| 181 | info->v1i.vlan_id[i] = vlan_id[i]; | 181 | info->v1i.vlan_id[i] = vlan_id[i]; |
| 182 | |||
| 183 | info->v1i.rx_status |= FJES_RX_MTU_CHANGING_DONE; | ||
| 182 | } | 184 | } |
| 183 | 185 | ||
| 184 | void | 186 | void |
| @@ -810,7 +812,8 @@ bool fjes_hw_check_mtu(struct epbuf_handler *epbh, u32 mtu) | |||
| 810 | { | 812 | { |
| 811 | union ep_buffer_info *info = epbh->info; | 813 | union ep_buffer_info *info = epbh->info; |
| 812 | 814 | ||
| 813 | return (info->v1i.frame_max == FJES_MTU_TO_FRAME_SIZE(mtu)); | 815 | return ((info->v1i.frame_max == FJES_MTU_TO_FRAME_SIZE(mtu)) && |
| 816 | info->v1i.rx_status & FJES_RX_MTU_CHANGING_DONE); | ||
| 814 | } | 817 | } |
| 815 | 818 | ||
| 816 | bool fjes_hw_check_vlan_id(struct epbuf_handler *epbh, u16 vlan_id) | 819 | 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 | { | 866 | { |
| 864 | union ep_buffer_info *info = epbh->info; | 867 | union ep_buffer_info *info = epbh->info; |
| 865 | 868 | ||
| 869 | if (!(info->v1i.rx_status & FJES_RX_MTU_CHANGING_DONE)) | ||
| 870 | return true; | ||
| 871 | |||
| 866 | if (info->v1i.count_max == 0) | 872 | if (info->v1i.count_max == 0) |
| 867 | return true; | 873 | return true; |
| 868 | 874 | ||
diff --git a/drivers/net/fjes/fjes_hw.h b/drivers/net/fjes/fjes_hw.h index baee7f59834b..f40cf0792a39 100644 --- a/drivers/net/fjes/fjes_hw.h +++ b/drivers/net/fjes/fjes_hw.h | |||
| @@ -57,6 +57,7 @@ struct fjes_hw; | |||
| 57 | #define FJES_RX_STOP_REQ_DONE (0x1) | 57 | #define FJES_RX_STOP_REQ_DONE (0x1) |
| 58 | #define FJES_RX_STOP_REQ_REQUEST (0x2) | 58 | #define FJES_RX_STOP_REQ_REQUEST (0x2) |
| 59 | #define FJES_RX_POLL_WORK (0x4) | 59 | #define FJES_RX_POLL_WORK (0x4) |
| 60 | #define FJES_RX_MTU_CHANGING_DONE (0x8) | ||
| 60 | 61 | ||
| 61 | #define EP_BUFFER_SIZE \ | 62 | #define EP_BUFFER_SIZE \ |
| 62 | (((sizeof(union ep_buffer_info) + (128 * (64 * 1024))) \ | 63 | (((sizeof(union ep_buffer_info) + (128 * (64 * 1024))) \ |
diff --git a/drivers/net/fjes/fjes_main.c b/drivers/net/fjes/fjes_main.c index e22a86976dcf..3c0c1202f237 100644 --- a/drivers/net/fjes/fjes_main.c +++ b/drivers/net/fjes/fjes_main.c | |||
| @@ -481,6 +481,9 @@ static void fjes_tx_stall_task(struct work_struct *work) | |||
| 481 | 481 | ||
| 482 | info = adapter->hw.ep_shm_info[epid].tx.info; | 482 | info = adapter->hw.ep_shm_info[epid].tx.info; |
| 483 | 483 | ||
| 484 | if (!(info->v1i.rx_status & FJES_RX_MTU_CHANGING_DONE)) | ||
| 485 | return; | ||
| 486 | |||
| 484 | if (EP_RING_FULL(info->v1i.head, info->v1i.tail, | 487 | if (EP_RING_FULL(info->v1i.head, info->v1i.tail, |
| 485 | info->v1i.count_max)) { | 488 | info->v1i.count_max)) { |
| 486 | all_queue_available = 0; | 489 | all_queue_available = 0; |
| @@ -760,9 +763,11 @@ fjes_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) | |||
| 760 | 763 | ||
| 761 | static int fjes_change_mtu(struct net_device *netdev, int new_mtu) | 764 | static int fjes_change_mtu(struct net_device *netdev, int new_mtu) |
| 762 | { | 765 | { |
| 766 | struct fjes_adapter *adapter = netdev_priv(netdev); | ||
| 763 | bool running = netif_running(netdev); | 767 | bool running = netif_running(netdev); |
| 764 | int ret = 0; | 768 | struct fjes_hw *hw = &adapter->hw; |
| 765 | int idx; | 769 | int ret = -EINVAL; |
| 770 | int idx, epidx; | ||
| 766 | 771 | ||
| 767 | for (idx = 0; fjes_support_mtu[idx] != 0; idx++) { | 772 | for (idx = 0; fjes_support_mtu[idx] != 0; idx++) { |
| 768 | if (new_mtu <= fjes_support_mtu[idx]) { | 773 | if (new_mtu <= fjes_support_mtu[idx]) { |
| @@ -770,19 +775,54 @@ static int fjes_change_mtu(struct net_device *netdev, int new_mtu) | |||
| 770 | if (new_mtu == netdev->mtu) | 775 | if (new_mtu == netdev->mtu) |
| 771 | return 0; | 776 | return 0; |
| 772 | 777 | ||
| 773 | if (running) | 778 | ret = 0; |
| 774 | fjes_close(netdev); | 779 | break; |
| 780 | } | ||
| 781 | } | ||
| 782 | |||
| 783 | if (ret) | ||
| 784 | return ret; | ||
| 785 | |||
| 786 | if (running) { | ||
| 787 | for (epidx = 0; epidx < hw->max_epid; epidx++) { | ||
| 788 | if (epidx == hw->my_epid) | ||
| 789 | continue; | ||
| 790 | hw->ep_shm_info[epidx].tx.info->v1i.rx_status &= | ||
| 791 | ~FJES_RX_MTU_CHANGING_DONE; | ||
| 792 | } | ||
| 793 | netif_tx_stop_all_queues(netdev); | ||
| 794 | netif_carrier_off(netdev); | ||
| 795 | cancel_work_sync(&adapter->tx_stall_task); | ||
| 796 | napi_disable(&adapter->napi); | ||
| 797 | |||
| 798 | msleep(1000); | ||
| 775 | 799 | ||
| 776 | netdev->mtu = new_mtu; | 800 | netif_tx_stop_all_queues(netdev); |
| 801 | } | ||
| 777 | 802 | ||
| 778 | if (running) | 803 | netdev->mtu = new_mtu; |
| 779 | ret = fjes_open(netdev); | ||
| 780 | 804 | ||
| 781 | return ret; | 805 | if (running) { |
| 806 | for (epidx = 0; epidx < hw->max_epid; epidx++) { | ||
| 807 | if (epidx == hw->my_epid) | ||
| 808 | continue; | ||
| 809 | |||
| 810 | local_irq_disable(); | ||
| 811 | fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx, | ||
| 812 | netdev->dev_addr, | ||
| 813 | netdev->mtu); | ||
| 814 | local_irq_enable(); | ||
| 815 | |||
| 816 | hw->ep_shm_info[epidx].tx.info->v1i.rx_status |= | ||
| 817 | FJES_RX_MTU_CHANGING_DONE; | ||
| 782 | } | 818 | } |
| 819 | |||
| 820 | netif_tx_wake_all_queues(netdev); | ||
| 821 | netif_carrier_on(netdev); | ||
| 822 | napi_enable(&adapter->napi); | ||
| 783 | } | 823 | } |
| 784 | 824 | ||
| 785 | return -EINVAL; | 825 | return ret; |
| 786 | } | 826 | } |
| 787 | 827 | ||
| 788 | static int fjes_vlan_rx_add_vid(struct net_device *netdev, | 828 | 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 | netdev->watchdog_timeo = FJES_TX_RETRY_INTERVAL; | 1244 | netdev->watchdog_timeo = FJES_TX_RETRY_INTERVAL; |
| 1205 | netdev->netdev_ops = &fjes_netdev_ops; | 1245 | netdev->netdev_ops = &fjes_netdev_ops; |
| 1206 | fjes_set_ethtool_ops(netdev); | 1246 | fjes_set_ethtool_ops(netdev); |
| 1207 | netdev->mtu = fjes_support_mtu[0]; | 1247 | netdev->mtu = fjes_support_mtu[3]; |
| 1208 | netdev->flags |= IFF_BROADCAST; | 1248 | netdev->flags |= IFF_BROADCAST; |
| 1209 | netdev->features |= NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_FILTER; | 1249 | netdev->features |= NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_FILTER; |
| 1210 | } | 1250 | } |
