From 782d640afd15af7a1faf01cfe566ca4ac511319d Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Thu, 7 Apr 2011 07:32:18 +0000 Subject: net: atl*: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Things left as they were: - atl1: is RX checksum really enabled? - atl2: copy-paste from atl1, with-errors-on-modify I presume - atl1c: there's a bug: MTU can't be changed if device is not up Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c_main.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'drivers/net/atl1c/atl1c_main.c') diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 7d9d5067a65c..894d485bf5bc 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -484,6 +484,15 @@ static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter, adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ? roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE; } + +static u32 atl1c_fix_features(struct net_device *netdev, u32 features) +{ + if (netdev->mtu > MAX_TSO_FRAME_SIZE) + features &= ~(NETIF_F_TSO | NETIF_F_TSO6); + + return features; +} + /* * atl1c_change_mtu - Change the Maximum Transfer Unit * @netdev: network interface device structure @@ -510,14 +519,8 @@ static int atl1c_change_mtu(struct net_device *netdev, int new_mtu) netdev->mtu = new_mtu; adapter->hw.max_frame_size = new_mtu; atl1c_set_rxbufsize(adapter, netdev); - if (new_mtu > MAX_TSO_FRAME_SIZE) { - adapter->netdev->features &= ~NETIF_F_TSO; - adapter->netdev->features &= ~NETIF_F_TSO6; - } else { - adapter->netdev->features |= NETIF_F_TSO; - adapter->netdev->features |= NETIF_F_TSO6; - } atl1c_down(adapter); + netdev_update_features(netdev); atl1c_up(adapter); clear_bit(__AT_RESETTING, &adapter->flags); if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) { @@ -2585,6 +2588,7 @@ static const struct net_device_ops atl1c_netdev_ops = { .ndo_set_mac_address = atl1c_set_mac_addr, .ndo_set_multicast_list = atl1c_set_multi, .ndo_change_mtu = atl1c_change_mtu, + .ndo_fix_features = atl1c_fix_features, .ndo_do_ioctl = atl1c_ioctl, .ndo_tx_timeout = atl1c_tx_timeout, .ndo_get_stats = atl1c_get_stats, @@ -2605,12 +2609,13 @@ static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev) atl1c_set_ethtool_ops(netdev); /* TODO: add when ready */ - netdev->features = NETIF_F_SG | + netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_TX | - NETIF_F_HW_VLAN_RX | NETIF_F_TSO | NETIF_F_TSO6; + netdev->features = netdev->hw_features | + NETIF_F_HW_VLAN_RX; return 0; } -- cgit v1.2.3 From 0c78641d7f677c8f420f1c302b4848135b207eb8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 00:55:20 -0700 Subject: atl1c: Fix set-but-unused variable. The variable 'extra_size' is set but unused in atl1c_configure_tx(). Just kill it off. Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c_main.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net/atl1c/atl1c_main.c') diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 894d485bf5bc..5c64a5d91544 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -1095,10 +1095,8 @@ static void atl1c_configure_tx(struct atl1c_adapter *adapter) u32 max_pay_load; u16 tx_offload_thresh; u32 txq_ctrl_data; - u32 extra_size = 0; /* Jumbo frame threshold in QWORD unit */ u32 max_pay_load_data; - extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN; tx_offload_thresh = MAX_TX_OFFLOAD_THRESH; AT_WRITE_REG(hw, REG_TX_TSO_OFFLOAD_THRESH, (tx_offload_thresh >> 3) & TX_TSO_OFFLOAD_THRESH_MASK); -- cgit v1.2.3 From cb771838715b1c470bc5735bdae709b33b18e0ad Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Wed, 20 Apr 2011 09:00:49 +0000 Subject: atl1c: Fix work event interrupt/task races The mechanism used to initiate work events from the interrupt handler has a classic read/modify/write race between the interrupt handler that sets the condition, and the worker task that reads and clears the condition. Close these races by using atomic bit fields. Cc: stable@kernel.org Cc: Jie Yang Signed-off-by: Tim Gardner Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c.h | 6 +++--- drivers/net/atl1c/atl1c_main.c | 14 +++++--------- 2 files changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers/net/atl1c/atl1c_main.c') diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h index 7cb375e0e29c..925929d764ca 100644 --- a/drivers/net/atl1c/atl1c.h +++ b/drivers/net/atl1c/atl1c.h @@ -566,9 +566,9 @@ struct atl1c_adapter { #define __AT_TESTING 0x0001 #define __AT_RESETTING 0x0002 #define __AT_DOWN 0x0003 - u8 work_event; -#define ATL1C_WORK_EVENT_RESET 0x01 -#define ATL1C_WORK_EVENT_LINK_CHANGE 0x02 + unsigned long work_event; +#define ATL1C_WORK_EVENT_RESET 0 +#define ATL1C_WORK_EVENT_LINK_CHANGE 1 u32 msg_enable; bool have_msi; diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 7d9d5067a65c..a6e1c36e48e6 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -325,7 +325,7 @@ static void atl1c_link_chg_event(struct atl1c_adapter *adapter) } } - adapter->work_event |= ATL1C_WORK_EVENT_LINK_CHANGE; + set_bit(ATL1C_WORK_EVENT_LINK_CHANGE, &adapter->work_event); schedule_work(&adapter->common_task); } @@ -337,20 +337,16 @@ static void atl1c_common_task(struct work_struct *work) adapter = container_of(work, struct atl1c_adapter, common_task); netdev = adapter->netdev; - if (adapter->work_event & ATL1C_WORK_EVENT_RESET) { - adapter->work_event &= ~ATL1C_WORK_EVENT_RESET; + if (test_and_clear_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event)) { netif_device_detach(netdev); atl1c_down(adapter); atl1c_up(adapter); netif_device_attach(netdev); - return; } - if (adapter->work_event & ATL1C_WORK_EVENT_LINK_CHANGE) { - adapter->work_event &= ~ATL1C_WORK_EVENT_LINK_CHANGE; + if (test_and_clear_bit(ATL1C_WORK_EVENT_LINK_CHANGE, + &adapter->work_event)) atl1c_check_link_status(adapter); - } - return; } @@ -369,7 +365,7 @@ static void atl1c_tx_timeout(struct net_device *netdev) struct atl1c_adapter *adapter = netdev_priv(netdev); /* Do the reset outside of interrupt context */ - adapter->work_event |= ATL1C_WORK_EVENT_RESET; + set_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event); schedule_work(&adapter->common_task); } -- cgit v1.2.3 From d187c1aab8d30771bb781c745b150f6159467d6f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 19 May 2011 18:44:41 -0400 Subject: atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined. Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net/atl1c/atl1c_main.c') diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 48868de386a0..1269ba5d6e56 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -2537,6 +2537,7 @@ static int atl1c_suspend(struct device *dev) return 0; } +#ifdef CONFIG_PM_SLEEP static int atl1c_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); @@ -2563,6 +2564,7 @@ static int atl1c_resume(struct device *dev) return 0; } +#endif static void atl1c_shutdown(struct pci_dev *pdev) { -- cgit v1.2.3