aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r--drivers/net/sfc/efx.c35
-rw-r--r--drivers/net/sfc/efx.h3
-rw-r--r--drivers/net/sfc/falcon.c69
-rw-r--r--drivers/net/sfc/falcon.h1
-rw-r--r--drivers/net/sfc/net_driver.h24
-rw-r--r--drivers/net/sfc/qt202x_phy.c26
-rw-r--r--drivers/net/sfc/tenxpress.c69
7 files changed, 103 insertions, 124 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 1009d1eeba82..b5a7e91590dc 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -583,7 +583,7 @@ void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue, int delay)
583 * netif_carrier_on/off) of the link status, and also maintains the 583 * netif_carrier_on/off) of the link status, and also maintains the
584 * link status's stop on the port's TX queue. 584 * link status's stop on the port's TX queue.
585 */ 585 */
586static void efx_link_status_changed(struct efx_nic *efx) 586void efx_link_status_changed(struct efx_nic *efx)
587{ 587{
588 struct efx_link_state *link_state = &efx->link_state; 588 struct efx_link_state *link_state = &efx->link_state;
589 589
@@ -675,19 +675,6 @@ void efx_reconfigure_port(struct efx_nic *efx)
675 mutex_unlock(&efx->mac_lock); 675 mutex_unlock(&efx->mac_lock);
676} 676}
677 677
678/* Asynchronous efx_reconfigure_port work item. To speed up efx_flush_all()
679 * we don't efx_reconfigure_port() if the port is disabled. Care is taken
680 * in efx_stop_all() and efx_start_port() to prevent PHY events being lost */
681static void efx_phy_work(struct work_struct *data)
682{
683 struct efx_nic *efx = container_of(data, struct efx_nic, phy_work);
684
685 mutex_lock(&efx->mac_lock);
686 if (efx->port_enabled)
687 __efx_reconfigure_port(efx);
688 mutex_unlock(&efx->mac_lock);
689}
690
691/* Asynchronous work item for changing MAC promiscuity and multicast 678/* Asynchronous work item for changing MAC promiscuity and multicast
692 * hash. Avoid a drain/rx_ingress enable by reconfiguring the current 679 * hash. Avoid a drain/rx_ingress enable by reconfiguring the current
693 * MAC directly. */ 680 * MAC directly. */
@@ -768,9 +755,6 @@ fail1:
768 return rc; 755 return rc;
769} 756}
770 757
771/* Allow efx_reconfigure_port() to be scheduled, and close the window
772 * between efx_stop_port and efx_flush_all whereby a previously scheduled
773 * efx_phy_work()/efx_mac_work() may have been cancelled */
774static void efx_start_port(struct efx_nic *efx) 758static void efx_start_port(struct efx_nic *efx)
775{ 759{
776 EFX_LOG(efx, "start port\n"); 760 EFX_LOG(efx, "start port\n");
@@ -787,10 +771,7 @@ static void efx_start_port(struct efx_nic *efx)
787 mutex_unlock(&efx->mac_lock); 771 mutex_unlock(&efx->mac_lock);
788} 772}
789 773
790/* Prevent efx_phy_work, efx_mac_work, and efx_monitor() from executing, 774/* Prevent efx_mac_work() and efx_monitor() from working */
791 * and efx_set_multicast_list() from scheduling efx_phy_work. efx_phy_work
792 * and efx_mac_work may still be scheduled via NAPI processing until
793 * efx_flush_all() is called */
794static void efx_stop_port(struct efx_nic *efx) 775static void efx_stop_port(struct efx_nic *efx)
795{ 776{
796 EFX_LOG(efx, "stop port\n"); 777 EFX_LOG(efx, "stop port\n");
@@ -1188,8 +1169,6 @@ static void efx_flush_all(struct efx_nic *efx)
1188 1169
1189 /* Stop scheduled port reconfigurations */ 1170 /* Stop scheduled port reconfigurations */
1190 cancel_work_sync(&efx->mac_work); 1171 cancel_work_sync(&efx->mac_work);
1191 cancel_work_sync(&efx->phy_work);
1192
1193} 1172}
1194 1173
1195/* Quiesce hardware and software without bringing the link down. 1174/* Quiesce hardware and software without bringing the link down.
@@ -1227,7 +1206,7 @@ static void efx_stop_all(struct efx_nic *efx)
1227 * window to loose phy events */ 1206 * window to loose phy events */
1228 efx_stop_port(efx); 1207 efx_stop_port(efx);
1229 1208
1230 /* Flush efx_phy_work, efx_mac_work, refill_workqueue, monitor_work */ 1209 /* Flush efx_mac_work(), refill_workqueue, monitor_work */
1231 efx_flush_all(efx); 1210 efx_flush_all(efx);
1232 1211
1233 /* Isolate the MAC from the TX and RX engines, so that queue 1212 /* Isolate the MAC from the TX and RX engines, so that queue
@@ -1907,6 +1886,10 @@ void efx_port_dummy_op_void(struct efx_nic *efx) {}
1907void efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) 1886void efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
1908{ 1887{
1909} 1888}
1889bool efx_port_dummy_op_poll(struct efx_nic *efx)
1890{
1891 return false;
1892}
1910 1893
1911static struct efx_mac_operations efx_dummy_mac_operations = { 1894static struct efx_mac_operations efx_dummy_mac_operations = {
1912 .reconfigure = efx_port_dummy_op_void, 1895 .reconfigure = efx_port_dummy_op_void,
@@ -1915,9 +1898,8 @@ static struct efx_mac_operations efx_dummy_mac_operations = {
1915static struct efx_phy_operations efx_dummy_phy_operations = { 1898static struct efx_phy_operations efx_dummy_phy_operations = {
1916 .init = efx_port_dummy_op_int, 1899 .init = efx_port_dummy_op_int,
1917 .reconfigure = efx_port_dummy_op_void, 1900 .reconfigure = efx_port_dummy_op_void,
1918 .poll = efx_port_dummy_op_void, 1901 .poll = efx_port_dummy_op_poll,
1919 .fini = efx_port_dummy_op_void, 1902 .fini = efx_port_dummy_op_void,
1920 .clear_interrupt = efx_port_dummy_op_void,
1921}; 1903};
1922 1904
1923/************************************************************************** 1905/**************************************************************************
@@ -1957,7 +1939,6 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
1957 efx->mac_op = &efx_dummy_mac_operations; 1939 efx->mac_op = &efx_dummy_mac_operations;
1958 efx->phy_op = &efx_dummy_phy_operations; 1940 efx->phy_op = &efx_dummy_phy_operations;
1959 efx->mdio.dev = net_dev; 1941 efx->mdio.dev = net_dev;
1960 INIT_WORK(&efx->phy_work, efx_phy_work);
1961 INIT_WORK(&efx->mac_work, efx_mac_work); 1942 INIT_WORK(&efx->mac_work, efx_mac_work);
1962 atomic_set(&efx->netif_stop_count, 1); 1943 atomic_set(&efx->netif_stop_count, 1);
1963 1944
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 01b93f93d316..15edda2a2242 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -90,6 +90,7 @@ extern int efx_port_dummy_op_int(struct efx_nic *efx);
90extern void efx_port_dummy_op_void(struct efx_nic *efx); 90extern void efx_port_dummy_op_void(struct efx_nic *efx);
91extern void 91extern void
92efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); 92efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);
93extern bool efx_port_dummy_op_poll(struct efx_nic *efx);
93 94
94/* MTD */ 95/* MTD */
95#ifdef CONFIG_SFC_MTD 96#ifdef CONFIG_SFC_MTD
@@ -113,4 +114,6 @@ static inline void efx_schedule_channel(struct efx_channel *channel)
113 napi_schedule(&channel->napi_str); 114 napi_schedule(&channel->napi_str);
114} 115}
115 116
117extern void efx_link_status_changed(struct efx_nic *efx);
118
116#endif /* EFX_EFX_H */ 119#endif /* EFX_EFX_H */
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index e26043eb01b5..e16faad70283 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -893,8 +893,7 @@ static void falcon_handle_global_event(struct efx_channel *channel,
893 if (EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_G_PHY0_INTR) || 893 if (EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_G_PHY0_INTR) ||
894 EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XG_PHY0_INTR) || 894 EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XG_PHY0_INTR) ||
895 EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XFP_PHY0_INTR)) { 895 EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XFP_PHY0_INTR)) {
896 efx->phy_op->clear_interrupt(efx); 896 /* Ignored */
897 queue_work(efx->workqueue, &efx->phy_work);
898 handled = true; 897 handled = true;
899 } 898 }
900 899
@@ -1140,20 +1139,6 @@ void falcon_generate_test_event(struct efx_channel *channel, unsigned int magic)
1140 falcon_generate_event(channel, &test_event); 1139 falcon_generate_event(channel, &test_event);
1141} 1140}
1142 1141
1143void falcon_sim_phy_event(struct efx_nic *efx)
1144{
1145 efx_qword_t phy_event;
1146
1147 EFX_POPULATE_QWORD_1(phy_event, FSF_AZ_EV_CODE,
1148 FSE_AZ_EV_CODE_GLOBAL_EV);
1149 if (EFX_IS10G(efx))
1150 EFX_SET_QWORD_FIELD(phy_event, FSF_AB_GLB_EV_XG_PHY0_INTR, 1);
1151 else
1152 EFX_SET_QWORD_FIELD(phy_event, FSF_AB_GLB_EV_G_PHY0_INTR, 1);
1153
1154 falcon_generate_event(&efx->channel[0], &phy_event);
1155}
1156
1157/************************************************************************** 1142/**************************************************************************
1158 * 1143 *
1159 * Flush handling 1144 * Flush handling
@@ -2063,6 +2048,25 @@ static void falcon_stats_timer_func(unsigned long context)
2063 spin_unlock(&efx->stats_lock); 2048 spin_unlock(&efx->stats_lock);
2064} 2049}
2065 2050
2051static bool falcon_loopback_link_poll(struct efx_nic *efx)
2052{
2053 struct efx_link_state old_state = efx->link_state;
2054
2055 WARN_ON(!mutex_is_locked(&efx->mac_lock));
2056 WARN_ON(!LOOPBACK_INTERNAL(efx));
2057
2058 efx->link_state.fd = true;
2059 efx->link_state.fc = efx->wanted_fc;
2060 efx->link_state.up = true;
2061
2062 if (efx->loopback_mode == LOOPBACK_GMAC)
2063 efx->link_state.speed = 1000;
2064 else
2065 efx->link_state.speed = 10000;
2066
2067 return !efx_link_state_equal(&efx->link_state, &old_state);
2068}
2069
2066/************************************************************************** 2070/**************************************************************************
2067 * 2071 *
2068 * PHY access via GMII 2072 * PHY access via GMII
@@ -2225,15 +2229,6 @@ int falcon_switch_mac(struct efx_nic *efx)
2225 /* Don't try to fetch MAC stats while we're switching MACs */ 2229 /* Don't try to fetch MAC stats while we're switching MACs */
2226 falcon_stop_nic_stats(efx); 2230 falcon_stop_nic_stats(efx);
2227 2231
2228 /* Internal loopbacks override the phy speed setting */
2229 if (efx->loopback_mode == LOOPBACK_GMAC) {
2230 efx->link_state.speed = 1000;
2231 efx->link_state.fd = true;
2232 } else if (LOOPBACK_INTERNAL(efx)) {
2233 efx->link_state.speed = 10000;
2234 efx->link_state.fd = true;
2235 }
2236
2237 WARN_ON(!mutex_is_locked(&efx->mac_lock)); 2232 WARN_ON(!mutex_is_locked(&efx->mac_lock));
2238 efx->mac_op = (EFX_IS10G(efx) ? 2233 efx->mac_op = (EFX_IS10G(efx) ?
2239 &falcon_xmac_operations : &falcon_gmac_operations); 2234 &falcon_xmac_operations : &falcon_gmac_operations);
@@ -2610,16 +2605,36 @@ fail5:
2610 2605
2611void falcon_monitor(struct efx_nic *efx) 2606void falcon_monitor(struct efx_nic *efx)
2612{ 2607{
2608 bool link_changed;
2613 int rc; 2609 int rc;
2614 2610
2611 BUG_ON(!mutex_is_locked(&efx->mac_lock));
2612
2615 rc = falcon_board(efx)->type->monitor(efx); 2613 rc = falcon_board(efx)->type->monitor(efx);
2616 if (rc) { 2614 if (rc) {
2617 EFX_ERR(efx, "Board sensor %s; shutting down PHY\n", 2615 EFX_ERR(efx, "Board sensor %s; shutting down PHY\n",
2618 (rc == -ERANGE) ? "reported fault" : "failed"); 2616 (rc == -ERANGE) ? "reported fault" : "failed");
2619 efx->phy_mode |= PHY_MODE_LOW_POWER; 2617 efx->phy_mode |= PHY_MODE_LOW_POWER;
2620 falcon_sim_phy_event(efx); 2618 __efx_reconfigure_port(efx);
2621 } 2619 }
2622 efx->phy_op->poll(efx); 2620
2621 if (LOOPBACK_INTERNAL(efx))
2622 link_changed = falcon_loopback_link_poll(efx);
2623 else
2624 link_changed = efx->phy_op->poll(efx);
2625
2626 if (link_changed) {
2627 falcon_stop_nic_stats(efx);
2628 falcon_deconfigure_mac_wrapper(efx);
2629
2630 falcon_switch_mac(efx);
2631 efx->mac_op->reconfigure(efx);
2632
2633 falcon_start_nic_stats(efx);
2634
2635 efx_link_status_changed(efx);
2636 }
2637
2623 if (EFX_IS10G(efx)) 2638 if (EFX_IS10G(efx))
2624 falcon_poll_xmac(efx); 2639 falcon_poll_xmac(efx);
2625} 2640}
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h
index c70bb084216f..a561f6758bc6 100644
--- a/drivers/net/sfc/falcon.h
+++ b/drivers/net/sfc/falcon.h
@@ -145,7 +145,6 @@ extern int falcon_init_interrupt(struct efx_nic *efx);
145extern void falcon_enable_interrupts(struct efx_nic *efx); 145extern void falcon_enable_interrupts(struct efx_nic *efx);
146extern void falcon_generate_test_event(struct efx_channel *channel, 146extern void falcon_generate_test_event(struct efx_channel *channel,
147 unsigned int magic); 147 unsigned int magic);
148extern void falcon_sim_phy_event(struct efx_nic *efx);
149extern void falcon_generate_interrupt(struct efx_nic *efx); 148extern void falcon_generate_interrupt(struct efx_nic *efx);
150extern void falcon_set_int_moderation(struct efx_channel *channel); 149extern void falcon_set_int_moderation(struct efx_channel *channel);
151extern void falcon_disable_interrupts(struct efx_nic *efx); 150extern void falcon_disable_interrupts(struct efx_nic *efx);
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index ead1c982365b..fb9327c5ea57 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -503,6 +503,13 @@ struct efx_link_state {
503 unsigned int speed; 503 unsigned int speed;
504}; 504};
505 505
506static inline bool efx_link_state_equal(const struct efx_link_state *left,
507 const struct efx_link_state *right)
508{
509 return left->up == right->up && left->fd == right->fd &&
510 left->fc == right->fc && left->speed == right->speed;
511}
512
506/** 513/**
507 * struct efx_mac_operations - Efx MAC operations table 514 * struct efx_mac_operations - Efx MAC operations table
508 * @reconfigure: Reconfigure MAC. Serialised by the mac_lock 515 * @reconfigure: Reconfigure MAC. Serialised by the mac_lock
@@ -520,8 +527,8 @@ struct efx_mac_operations {
520 * @init: Initialise PHY 527 * @init: Initialise PHY
521 * @fini: Shut down PHY 528 * @fini: Shut down PHY
522 * @reconfigure: Reconfigure PHY (e.g. for new link parameters) 529 * @reconfigure: Reconfigure PHY (e.g. for new link parameters)
523 * @clear_interrupt: Clear down interrupt 530 * @poll: Update @link_state and report whether it changed.
524 * @poll: Poll for hardware state. Serialised by the mac_lock. 531 * Serialised by the mac_lock.
525 * @get_settings: Get ethtool settings. Serialised by the mac_lock. 532 * @get_settings: Get ethtool settings. Serialised by the mac_lock.
526 * @set_settings: Set ethtool settings. Serialised by the mac_lock. 533 * @set_settings: Set ethtool settings. Serialised by the mac_lock.
527 * @set_npage_adv: Set abilities advertised in (Extended) Next Page 534 * @set_npage_adv: Set abilities advertised in (Extended) Next Page
@@ -538,8 +545,7 @@ struct efx_phy_operations {
538 int (*init) (struct efx_nic *efx); 545 int (*init) (struct efx_nic *efx);
539 void (*fini) (struct efx_nic *efx); 546 void (*fini) (struct efx_nic *efx);
540 void (*reconfigure) (struct efx_nic *efx); 547 void (*reconfigure) (struct efx_nic *efx);
541 void (*clear_interrupt) (struct efx_nic *efx); 548 bool (*poll) (struct efx_nic *efx);
542 void (*poll) (struct efx_nic *efx);
543 void (*get_settings) (struct efx_nic *efx, 549 void (*get_settings) (struct efx_nic *efx,
544 struct ethtool_cmd *ecmd); 550 struct ethtool_cmd *ecmd);
545 int (*set_settings) (struct efx_nic *efx, 551 int (*set_settings) (struct efx_nic *efx,
@@ -700,10 +706,10 @@ union efx_multicast_hash {
700 * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode, 706 * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode,
701 * @port_inhibited, efx_monitor() and efx_reconfigure_port() 707 * @port_inhibited, efx_monitor() and efx_reconfigure_port()
702 * @port_enabled: Port enabled indicator. 708 * @port_enabled: Port enabled indicator.
703 * Serialises efx_stop_all(), efx_start_all(), efx_monitor(), 709 * Serialises efx_stop_all(), efx_start_all(), efx_monitor() and
704 * efx_phy_work(), and efx_mac_work() with kernel interfaces. Safe to read 710 * efx_mac_work() with kernel interfaces. Safe to read under any
705 * under any one of the rtnl_lock, mac_lock, or netif_tx_lock, but all 711 * one of the rtnl_lock, mac_lock, or netif_tx_lock, but all three must
706 * three must be held to modify it. 712 * be held to modify it.
707 * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock 713 * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock
708 * @port_initialized: Port initialized? 714 * @port_initialized: Port initialized?
709 * @net_dev: Operating system network device. Consider holding the rtnl lock 715 * @net_dev: Operating system network device. Consider holding the rtnl lock
@@ -729,7 +735,6 @@ union efx_multicast_hash {
729 * @promiscuous: Promiscuous flag. Protected by netif_tx_lock. 735 * @promiscuous: Promiscuous flag. Protected by netif_tx_lock.
730 * @multicast_hash: Multicast hash table 736 * @multicast_hash: Multicast hash table
731 * @wanted_fc: Wanted flow control flags 737 * @wanted_fc: Wanted flow control flags
732 * @phy_work: work item for dealing with PHY events
733 * @mac_work: Work item for changing MAC promiscuity and multicast hash 738 * @mac_work: Work item for changing MAC promiscuity and multicast hash
734 * @loopback_mode: Loopback status 739 * @loopback_mode: Loopback status
735 * @loopback_modes: Supported loopback mode bitmask 740 * @loopback_modes: Supported loopback mode bitmask
@@ -802,7 +807,6 @@ struct efx_nic {
802 807
803 enum phy_type phy_type; 808 enum phy_type phy_type;
804 spinlock_t phy_lock; 809 spinlock_t phy_lock;
805 struct work_struct phy_work;
806 struct efx_phy_operations *phy_op; 810 struct efx_phy_operations *phy_op;
807 void *phy_data; 811 void *phy_data;
808 struct mdio_if_info mdio; 812 struct mdio_if_info mdio;
diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c
index f9c354e9fc3c..1b174c3e6c12 100644
--- a/drivers/net/sfc/qt202x_phy.c
+++ b/drivers/net/sfc/qt202x_phy.c
@@ -167,29 +167,26 @@ static int qt202x_phy_init(struct efx_nic *efx)
167 return rc; 167 return rc;
168} 168}
169 169
170static void qt202x_phy_clear_interrupt(struct efx_nic *efx)
171{
172 /* Read to clear link status alarm */
173 efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT);
174}
175
176static int qt202x_link_ok(struct efx_nic *efx) 170static int qt202x_link_ok(struct efx_nic *efx)
177{ 171{
178 return efx_mdio_links_ok(efx, QT202X_REQUIRED_DEVS); 172 return efx_mdio_links_ok(efx, QT202X_REQUIRED_DEVS);
179} 173}
180 174
181static void qt202x_phy_poll(struct efx_nic *efx) 175static bool qt202x_phy_poll(struct efx_nic *efx)
182{ 176{
183 int link_up = qt202x_link_ok(efx); 177 bool was_up = efx->link_state.up;
184 /* Simulate a PHY event if link state has changed */ 178
185 if (link_up != efx->link_state.up) 179 efx->link_state.up = qt202x_link_ok(efx);
186 falcon_sim_phy_event(efx); 180 efx->link_state.speed = 10000;
181 efx->link_state.fd = true;
182 efx->link_state.fc = efx->wanted_fc;
183
184 return efx->link_state.up != was_up;
187} 185}
188 186
189static void qt202x_phy_reconfigure(struct efx_nic *efx) 187static void qt202x_phy_reconfigure(struct efx_nic *efx)
190{ 188{
191 struct qt202x_phy_data *phy_data = efx->phy_data; 189 struct qt202x_phy_data *phy_data = efx->phy_data;
192 struct efx_link_state *link_state = &efx->link_state;
193 190
194 if (efx->phy_type == PHY_TYPE_QT2025C) { 191 if (efx->phy_type == PHY_TYPE_QT2025C) {
195 /* There are several different register bits which can 192 /* There are several different register bits which can
@@ -216,10 +213,6 @@ static void qt202x_phy_reconfigure(struct efx_nic *efx)
216 efx_mdio_phy_reconfigure(efx); 213 efx_mdio_phy_reconfigure(efx);
217 214
218 phy_data->phy_mode = efx->phy_mode; 215 phy_data->phy_mode = efx->phy_mode;
219 link_state->up = qt202x_link_ok(efx);
220 link_state->speed = 10000;
221 link_state->fd = true;
222 link_state->fc = efx->wanted_fc;
223} 216}
224 217
225static void qt202x_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 218static void qt202x_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
@@ -240,7 +233,6 @@ struct efx_phy_operations falcon_qt202x_phy_ops = {
240 .reconfigure = qt202x_phy_reconfigure, 233 .reconfigure = qt202x_phy_reconfigure,
241 .poll = qt202x_phy_poll, 234 .poll = qt202x_phy_poll,
242 .fini = qt202x_phy_fini, 235 .fini = qt202x_phy_fini,
243 .clear_interrupt = qt202x_phy_clear_interrupt,
244 .get_settings = qt202x_phy_get_settings, 236 .get_settings = qt202x_phy_get_settings,
245 .set_settings = efx_mdio_set_settings, 237 .set_settings = efx_mdio_set_settings,
246 .mmds = QT202X_REQUIRED_DEVS, 238 .mmds = QT202X_REQUIRED_DEVS,
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index e6232fe26072..1bd79650a00f 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -503,7 +503,6 @@ static void tenxpress_low_power(struct efx_nic *efx)
503static void tenxpress_phy_reconfigure(struct efx_nic *efx) 503static void tenxpress_phy_reconfigure(struct efx_nic *efx)
504{ 504{
505 struct tenxpress_phy_data *phy_data = efx->phy_data; 505 struct tenxpress_phy_data *phy_data = efx->phy_data;
506 struct efx_link_state *link_state = &efx->link_state;
507 struct ethtool_cmd ecmd; 506 struct ethtool_cmd ecmd;
508 bool phy_mode_change, loop_reset; 507 bool phy_mode_change, loop_reset;
509 508
@@ -544,53 +543,41 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
544 543
545 phy_data->loopback_mode = efx->loopback_mode; 544 phy_data->loopback_mode = efx->loopback_mode;
546 phy_data->phy_mode = efx->phy_mode; 545 phy_data->phy_mode = efx->phy_mode;
547
548 if (efx->phy_type == PHY_TYPE_SFX7101) {
549 link_state->speed = 10000;
550 link_state->fd = true;
551 link_state->up = sfx7101_link_ok(efx);
552 } else {
553 efx->phy_op->get_settings(efx, &ecmd);
554 link_state->speed = ecmd.speed;
555 link_state->fd = ecmd.duplex == DUPLEX_FULL;
556 link_state->up = sft9001_link_ok(efx, &ecmd);
557 }
558 link_state->fc = efx_mdio_get_pause(efx);
559} 546}
560 547
561/* Poll PHY for interrupt */ 548static void
562static void tenxpress_phy_poll(struct efx_nic *efx) 549tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd);
550
551/* Poll for link state changes */
552static bool tenxpress_phy_poll(struct efx_nic *efx)
563{ 553{
564 struct tenxpress_phy_data *phy_data = efx->phy_data; 554 struct efx_link_state old_state = efx->link_state;
565 struct efx_link_state *link_state = &efx->link_state;
566 bool change = false;
567 555
568 if (efx->phy_type == PHY_TYPE_SFX7101) { 556 if (efx->phy_type == PHY_TYPE_SFX7101) {
569 bool link_ok = sfx7101_link_ok(efx); 557 efx->link_state.up = sfx7101_link_ok(efx);
570 if (link_ok != link_state->up) { 558 efx->link_state.speed = 10000;
571 change = true; 559 efx->link_state.fd = true;
572 } else { 560 efx->link_state.fc = efx_mdio_get_pause(efx);
573 unsigned int link_fc = efx_mdio_get_pause(efx); 561
574 if (link_fc != link_state->fc) 562 sfx7101_check_bad_lp(efx, efx->link_state.up);
575 change = true;
576 }
577 sfx7101_check_bad_lp(efx, link_ok);
578 } else if (efx->loopback_mode) {
579 bool link_ok = sft9001_link_ok(efx, NULL);
580 if (link_ok != link_state->up)
581 change = true;
582 } else { 563 } else {
583 int status = efx_mdio_read(efx, MDIO_MMD_PMAPMD, 564 struct ethtool_cmd ecmd;
584 MDIO_PMA_LASI_STAT);
585 if (status & MDIO_PMA_LASI_LSALARM)
586 change = true;
587 }
588 565
589 if (change) 566 /* Check the LASI alarm first */
590 falcon_sim_phy_event(efx); 567 if (efx->loopback_mode == LOOPBACK_NONE &&
568 !(efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT) &
569 MDIO_PMA_LASI_LSALARM))
570 return false;
591 571
592 if (phy_data->phy_mode != PHY_MODE_NORMAL) 572 tenxpress_get_settings(efx, &ecmd);
593 return; 573
574 efx->link_state.up = sft9001_link_ok(efx, &ecmd);
575 efx->link_state.speed = ecmd.speed;
576 efx->link_state.fd = (ecmd.duplex == DUPLEX_FULL);
577 efx->link_state.fc = efx_mdio_get_pause(efx);
578 }
579
580 return !efx_link_state_equal(&efx->link_state, &old_state);
594} 581}
595 582
596static void tenxpress_phy_fini(struct efx_nic *efx) 583static void tenxpress_phy_fini(struct efx_nic *efx)
@@ -818,7 +805,6 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = {
818 .reconfigure = tenxpress_phy_reconfigure, 805 .reconfigure = tenxpress_phy_reconfigure,
819 .poll = tenxpress_phy_poll, 806 .poll = tenxpress_phy_poll,
820 .fini = tenxpress_phy_fini, 807 .fini = tenxpress_phy_fini,
821 .clear_interrupt = efx_port_dummy_op_void,
822 .get_settings = tenxpress_get_settings, 808 .get_settings = tenxpress_get_settings,
823 .set_settings = tenxpress_set_settings, 809 .set_settings = tenxpress_set_settings,
824 .set_npage_adv = sfx7101_set_npage_adv, 810 .set_npage_adv = sfx7101_set_npage_adv,
@@ -835,7 +821,6 @@ struct efx_phy_operations falcon_sft9001_phy_ops = {
835 .reconfigure = tenxpress_phy_reconfigure, 821 .reconfigure = tenxpress_phy_reconfigure,
836 .poll = tenxpress_phy_poll, 822 .poll = tenxpress_phy_poll,
837 .fini = tenxpress_phy_fini, 823 .fini = tenxpress_phy_fini,
838 .clear_interrupt = efx_port_dummy_op_void,
839 .get_settings = tenxpress_get_settings, 824 .get_settings = tenxpress_get_settings,
840 .set_settings = tenxpress_set_settings, 825 .set_settings = tenxpress_set_settings,
841 .set_npage_adv = sft9001_set_npage_adv, 826 .set_npage_adv = sft9001_set_npage_adv,