diff options
author | Jesse Brandeburg <jesse.brandeburg@intel.com> | 2008-09-11 22:55:32 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-09-24 18:54:49 -0400 |
commit | cf8280ee7be3aaf44d32e389f15c725b850e5e32 (patch) | |
tree | 3511ef0b19370597c7bd5fbe43a74d563522adeb /drivers | |
parent | ce94bf469edf84228771b58489944cf654aeb496 (diff) |
ixgbe: Update watchdog thread to accomodate longerlink_up events
This patch updates the link_up code and watchdog thread so that link_up
doesn't cause stack overflows due to long waits in interrupt context.
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ixgbe/ixgbe.h | 6 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_82598.c | 29 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_ethtool.c | 2 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 129 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_type.h | 3 |
5 files changed, 118 insertions, 51 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 90b53830196c..2b827a67c9c5 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h | |||
@@ -309,6 +309,12 @@ struct ixgbe_adapter { | |||
309 | u64 lro_aggregated; | 309 | u64 lro_aggregated; |
310 | u64 lro_flushed; | 310 | u64 lro_flushed; |
311 | u64 lro_no_desc; | 311 | u64 lro_no_desc; |
312 | |||
313 | u32 link_speed; | ||
314 | bool link_up; | ||
315 | unsigned long link_check_timeout; | ||
316 | |||
317 | struct work_struct watchdog_task; | ||
312 | }; | 318 | }; |
313 | 319 | ||
314 | enum ixbge_state_t { | 320 | enum ixbge_state_t { |
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index ba09063260d9..1e014bcc72d9 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c | |||
@@ -47,7 +47,8 @@ static s32 ixgbe_get_copper_link_settings_82598(struct ixgbe_hw *hw, | |||
47 | static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw); | 47 | static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw); |
48 | static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw); | 48 | static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw); |
49 | static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed, | 49 | static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed, |
50 | bool *link_up); | 50 | bool *link_up, |
51 | bool link_up_wait_to_complete); | ||
51 | static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, u32 speed, | 52 | static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, u32 speed, |
52 | bool autoneg, | 53 | bool autoneg, |
53 | bool autoneg_wait_to_complete); | 54 | bool autoneg_wait_to_complete); |
@@ -277,20 +278,36 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw) | |||
277 | * @hw: pointer to hardware structure | 278 | * @hw: pointer to hardware structure |
278 | * @speed: pointer to link speed | 279 | * @speed: pointer to link speed |
279 | * @link_up: true is link is up, false otherwise | 280 | * @link_up: true is link is up, false otherwise |
281 | * @link_up_wait_to_complete: bool used to wait for link up or not | ||
280 | * | 282 | * |
281 | * Reads the links register to determine if link is up and the current speed | 283 | * Reads the links register to determine if link is up and the current speed |
282 | **/ | 284 | **/ |
283 | static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed, | 285 | static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed, |
284 | bool *link_up) | 286 | bool *link_up, |
287 | bool link_up_wait_to_complete) | ||
285 | { | 288 | { |
286 | u32 links_reg; | 289 | u32 links_reg; |
290 | u32 i; | ||
287 | 291 | ||
288 | links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); | 292 | links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); |
289 | 293 | ||
290 | if (links_reg & IXGBE_LINKS_UP) | 294 | if (link_up_wait_to_complete) { |
291 | *link_up = true; | 295 | for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { |
292 | else | 296 | if (links_reg & IXGBE_LINKS_UP) { |
293 | *link_up = false; | 297 | *link_up = true; |
298 | break; | ||
299 | } else { | ||
300 | *link_up = false; | ||
301 | } | ||
302 | msleep(100); | ||
303 | links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); | ||
304 | } | ||
305 | } else { | ||
306 | if (links_reg & IXGBE_LINKS_UP) | ||
307 | *link_up = true; | ||
308 | else | ||
309 | *link_up = false; | ||
310 | } | ||
294 | 311 | ||
295 | if (links_reg & IXGBE_LINKS_SPEED) | 312 | if (links_reg & IXGBE_LINKS_SPEED) |
296 | *speed = IXGBE_LINK_SPEED_10GB_FULL; | 313 | *speed = IXGBE_LINK_SPEED_10GB_FULL; |
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 61c000e23094..8f0e3f93e6b1 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c | |||
@@ -130,7 +130,7 @@ static int ixgbe_get_settings(struct net_device *netdev, | |||
130 | ecmd->port = PORT_FIBRE; | 130 | ecmd->port = PORT_FIBRE; |
131 | } | 131 | } |
132 | 132 | ||
133 | adapter->hw.mac.ops.check_link(hw, &(link_speed), &link_up); | 133 | adapter->hw.mac.ops.check_link(hw, &(link_speed), &link_up, false); |
134 | if (link_up) { | 134 | if (link_up) { |
135 | ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ? | 135 | ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ? |
136 | SPEED_10000 : SPEED_1000; | 136 | SPEED_10000 : SPEED_1000; |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 904819586e2a..036393e5383e 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -902,6 +902,20 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) | |||
902 | return; | 902 | return; |
903 | } | 903 | } |
904 | 904 | ||
905 | |||
906 | static void ixgbe_check_lsc(struct ixgbe_adapter *adapter) | ||
907 | { | ||
908 | struct ixgbe_hw *hw = &adapter->hw; | ||
909 | |||
910 | adapter->lsc_int++; | ||
911 | adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; | ||
912 | adapter->link_check_timeout = jiffies; | ||
913 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) { | ||
914 | IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC); | ||
915 | schedule_work(&adapter->watchdog_task); | ||
916 | } | ||
917 | } | ||
918 | |||
905 | static irqreturn_t ixgbe_msix_lsc(int irq, void *data) | 919 | static irqreturn_t ixgbe_msix_lsc(int irq, void *data) |
906 | { | 920 | { |
907 | struct net_device *netdev = data; | 921 | struct net_device *netdev = data; |
@@ -909,11 +923,8 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) | |||
909 | struct ixgbe_hw *hw = &adapter->hw; | 923 | struct ixgbe_hw *hw = &adapter->hw; |
910 | u32 eicr = IXGBE_READ_REG(hw, IXGBE_EICR); | 924 | u32 eicr = IXGBE_READ_REG(hw, IXGBE_EICR); |
911 | 925 | ||
912 | if (eicr & IXGBE_EICR_LSC) { | 926 | if (eicr & IXGBE_EICR_LSC) |
913 | adapter->lsc_int++; | 927 | ixgbe_check_lsc(adapter); |
914 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | ||
915 | mod_timer(&adapter->watchdog_timer, jiffies); | ||
916 | } | ||
917 | 928 | ||
918 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | 929 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) |
919 | IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); | 930 | IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); |
@@ -1237,12 +1248,8 @@ static irqreturn_t ixgbe_intr(int irq, void *data) | |||
1237 | if (!eicr) | 1248 | if (!eicr) |
1238 | return IRQ_NONE; /* Not our interrupt */ | 1249 | return IRQ_NONE; /* Not our interrupt */ |
1239 | 1250 | ||
1240 | if (eicr & IXGBE_EICR_LSC) { | 1251 | if (eicr & IXGBE_EICR_LSC) |
1241 | adapter->lsc_int++; | 1252 | ixgbe_check_lsc(adapter); |
1242 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | ||
1243 | mod_timer(&adapter->watchdog_timer, jiffies); | ||
1244 | } | ||
1245 | |||
1246 | 1253 | ||
1247 | if (netif_rx_schedule_prep(netdev, &adapter->q_vector[0].napi)) { | 1254 | if (netif_rx_schedule_prep(netdev, &adapter->q_vector[0].napi)) { |
1248 | adapter->tx_ring[0].total_packets = 0; | 1255 | adapter->tx_ring[0].total_packets = 0; |
@@ -1897,6 +1904,8 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) | |||
1897 | 1904 | ||
1898 | /* bring the link up in the watchdog, this could race with our first | 1905 | /* bring the link up in the watchdog, this could race with our first |
1899 | * link up interrupt but shouldn't be a problem */ | 1906 | * link up interrupt but shouldn't be a problem */ |
1907 | adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; | ||
1908 | adapter->link_check_timeout = jiffies; | ||
1900 | mod_timer(&adapter->watchdog_timer, jiffies); | 1909 | mod_timer(&adapter->watchdog_timer, jiffies); |
1901 | return 0; | 1910 | return 0; |
1902 | } | 1911 | } |
@@ -2098,6 +2107,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) | |||
2098 | 2107 | ||
2099 | ixgbe_napi_disable_all(adapter); | 2108 | ixgbe_napi_disable_all(adapter); |
2100 | del_timer_sync(&adapter->watchdog_timer); | 2109 | del_timer_sync(&adapter->watchdog_timer); |
2110 | cancel_work_sync(&adapter->watchdog_task); | ||
2101 | 2111 | ||
2102 | netif_carrier_off(netdev); | 2112 | netif_carrier_off(netdev); |
2103 | netif_tx_stop_all_queues(netdev); | 2113 | netif_tx_stop_all_queues(netdev); |
@@ -3010,27 +3020,74 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) | |||
3010 | static void ixgbe_watchdog(unsigned long data) | 3020 | static void ixgbe_watchdog(unsigned long data) |
3011 | { | 3021 | { |
3012 | struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; | 3022 | struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; |
3013 | struct net_device *netdev = adapter->netdev; | 3023 | struct ixgbe_hw *hw = &adapter->hw; |
3014 | bool link_up; | 3024 | |
3015 | u32 link_speed = 0; | 3025 | /* Do the watchdog outside of interrupt context due to the lovely |
3026 | * delays that some of the newer hardware requires */ | ||
3027 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) { | ||
3028 | /* Cause software interrupt to ensure rx rings are cleaned */ | ||
3029 | if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { | ||
3030 | u32 eics = | ||
3031 | (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1; | ||
3032 | IXGBE_WRITE_REG(hw, IXGBE_EICS, eics); | ||
3033 | } else { | ||
3034 | /* For legacy and MSI interrupts don't set any bits that | ||
3035 | * are enabled for EIAM, because this operation would | ||
3036 | * set *both* EIMS and EICS for any bit in EIAM */ | ||
3037 | IXGBE_WRITE_REG(hw, IXGBE_EICS, | ||
3038 | (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER)); | ||
3039 | } | ||
3040 | /* Reset the timer */ | ||
3041 | mod_timer(&adapter->watchdog_timer, | ||
3042 | round_jiffies(jiffies + 2 * HZ)); | ||
3043 | } | ||
3016 | 3044 | ||
3017 | adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up); | 3045 | schedule_work(&adapter->watchdog_task); |
3046 | } | ||
3047 | |||
3048 | /** | ||
3049 | * ixgbe_watchdog_task - worker thread to bring link up | ||
3050 | * @work: pointer to work_struct containing our data | ||
3051 | **/ | ||
3052 | static void ixgbe_watchdog_task(struct work_struct *work) | ||
3053 | { | ||
3054 | struct ixgbe_adapter *adapter = container_of(work, | ||
3055 | struct ixgbe_adapter, | ||
3056 | watchdog_task); | ||
3057 | struct net_device *netdev = adapter->netdev; | ||
3058 | struct ixgbe_hw *hw = &adapter->hw; | ||
3059 | u32 link_speed = adapter->link_speed; | ||
3060 | bool link_up = adapter->link_up; | ||
3061 | |||
3062 | adapter->flags |= IXGBE_FLAG_IN_WATCHDOG_TASK; | ||
3063 | |||
3064 | if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) { | ||
3065 | hw->mac.ops.check_link(hw, &link_speed, &link_up, false); | ||
3066 | if (link_up || | ||
3067 | time_after(jiffies, (adapter->link_check_timeout + | ||
3068 | IXGBE_TRY_LINK_TIMEOUT))) { | ||
3069 | IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC); | ||
3070 | adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; | ||
3071 | } | ||
3072 | adapter->link_up = link_up; | ||
3073 | adapter->link_speed = link_speed; | ||
3074 | } | ||
3018 | 3075 | ||
3019 | if (link_up) { | 3076 | if (link_up) { |
3020 | if (!netif_carrier_ok(netdev)) { | 3077 | if (!netif_carrier_ok(netdev)) { |
3021 | u32 frctl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL); | 3078 | u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL); |
3022 | u32 rmcs = IXGBE_READ_REG(&adapter->hw, IXGBE_RMCS); | 3079 | u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS); |
3023 | #define FLOW_RX (frctl & IXGBE_FCTRL_RFCE) | 3080 | #define FLOW_RX (frctl & IXGBE_FCTRL_RFCE) |
3024 | #define FLOW_TX (rmcs & IXGBE_RMCS_TFCE_802_3X) | 3081 | #define FLOW_TX (rmcs & IXGBE_RMCS_TFCE_802_3X) |
3025 | DPRINTK(LINK, INFO, "NIC Link is Up %s, " | 3082 | DPRINTK(LINK, INFO, "NIC Link is Up %s, " |
3026 | "Flow Control: %s\n", | 3083 | "Flow Control: %s\n", |
3027 | (link_speed == IXGBE_LINK_SPEED_10GB_FULL ? | 3084 | (link_speed == IXGBE_LINK_SPEED_10GB_FULL ? |
3028 | "10 Gbps" : | 3085 | "10 Gbps" : |
3029 | (link_speed == IXGBE_LINK_SPEED_1GB_FULL ? | 3086 | (link_speed == IXGBE_LINK_SPEED_1GB_FULL ? |
3030 | "1 Gbps" : "unknown speed")), | 3087 | "1 Gbps" : "unknown speed")), |
3031 | ((FLOW_RX && FLOW_TX) ? "RX/TX" : | 3088 | ((FLOW_RX && FLOW_TX) ? "RX/TX" : |
3032 | (FLOW_RX ? "RX" : | 3089 | (FLOW_RX ? "RX" : |
3033 | (FLOW_TX ? "TX" : "None")))); | 3090 | (FLOW_TX ? "TX" : "None")))); |
3034 | 3091 | ||
3035 | netif_carrier_on(netdev); | 3092 | netif_carrier_on(netdev); |
3036 | netif_tx_wake_all_queues(netdev); | 3093 | netif_tx_wake_all_queues(netdev); |
@@ -3039,6 +3096,8 @@ static void ixgbe_watchdog(unsigned long data) | |||
3039 | adapter->detect_tx_hung = true; | 3096 | adapter->detect_tx_hung = true; |
3040 | } | 3097 | } |
3041 | } else { | 3098 | } else { |
3099 | adapter->link_up = false; | ||
3100 | adapter->link_speed = 0; | ||
3042 | if (netif_carrier_ok(netdev)) { | 3101 | if (netif_carrier_ok(netdev)) { |
3043 | DPRINTK(LINK, INFO, "NIC Link is Down\n"); | 3102 | DPRINTK(LINK, INFO, "NIC Link is Down\n"); |
3044 | netif_carrier_off(netdev); | 3103 | netif_carrier_off(netdev); |
@@ -3047,24 +3106,7 @@ static void ixgbe_watchdog(unsigned long data) | |||
3047 | } | 3106 | } |
3048 | 3107 | ||
3049 | ixgbe_update_stats(adapter); | 3108 | ixgbe_update_stats(adapter); |
3050 | 3109 | adapter->flags &= ~IXGBE_FLAG_IN_WATCHDOG_TASK; | |
3051 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) { | ||
3052 | /* Cause software interrupt to ensure rx rings are cleaned */ | ||
3053 | if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { | ||
3054 | u32 eics = | ||
3055 | (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1; | ||
3056 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, eics); | ||
3057 | } else { | ||
3058 | /* for legacy and MSI interrupts don't set any bits that | ||
3059 | * are enabled for EIAM, because this operation would | ||
3060 | * set *both* EIMS and EICS for any bit in EIAM */ | ||
3061 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, | ||
3062 | (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER)); | ||
3063 | } | ||
3064 | /* Reset the timer */ | ||
3065 | mod_timer(&adapter->watchdog_timer, | ||
3066 | round_jiffies(jiffies + 2 * HZ)); | ||
3067 | } | ||
3068 | } | 3110 | } |
3069 | 3111 | ||
3070 | static int ixgbe_tso(struct ixgbe_adapter *adapter, | 3112 | static int ixgbe_tso(struct ixgbe_adapter *adapter, |
@@ -3707,6 +3749,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
3707 | adapter->watchdog_timer.data = (unsigned long)adapter; | 3749 | adapter->watchdog_timer.data = (unsigned long)adapter; |
3708 | 3750 | ||
3709 | INIT_WORK(&adapter->reset_task, ixgbe_reset_task); | 3751 | INIT_WORK(&adapter->reset_task, ixgbe_reset_task); |
3752 | INIT_WORK(&adapter->watchdog_task, ixgbe_watchdog_task); | ||
3710 | 3753 | ||
3711 | err = ixgbe_init_interrupt_scheme(adapter); | 3754 | err = ixgbe_init_interrupt_scheme(adapter); |
3712 | if (err) | 3755 | if (err) |
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 3e9c483ad8e6..172f766acdea 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h | |||
@@ -703,6 +703,7 @@ | |||
703 | #define IXGBE_LINKS_TL_FAULT 0x00001000 | 703 | #define IXGBE_LINKS_TL_FAULT 0x00001000 |
704 | #define IXGBE_LINKS_SIGNAL 0x00000F00 | 704 | #define IXGBE_LINKS_SIGNAL 0x00000F00 |
705 | 705 | ||
706 | #define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */ | ||
706 | #define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */ | 707 | #define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */ |
707 | 708 | ||
708 | /* SW Semaphore Register bitmasks */ | 709 | /* SW Semaphore Register bitmasks */ |
@@ -1249,7 +1250,7 @@ struct ixgbe_mac_operations { | |||
1249 | s32 (*reset)(struct ixgbe_hw *); | 1250 | s32 (*reset)(struct ixgbe_hw *); |
1250 | enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *); | 1251 | enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *); |
1251 | s32 (*setup_link)(struct ixgbe_hw *); | 1252 | s32 (*setup_link)(struct ixgbe_hw *); |
1252 | s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *); | 1253 | s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *, bool); |
1253 | s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool); | 1254 | s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool); |
1254 | s32 (*get_link_settings)(struct ixgbe_hw *, u32 *, bool *); | 1255 | s32 (*get_link_settings)(struct ixgbe_hw *, u32 *, bool *); |
1255 | }; | 1256 | }; |