sfc: Move Falcon global event handling to falcon.c
authorBen Hutchings <bhutchings@solarflare.com>
Thu, 2 Dec 2010 13:47:45 +0000 (13:47 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 3 Dec 2010 17:08:08 +0000 (09:08 -0800)
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/sfc/falcon.c
drivers/net/sfc/net_driver.h
drivers/net/sfc/nic.c

index af62899bb98149f686505eef2be3cb0725835ea3..fd5bf0b7e8a271dbeb0999b30db526319406d36e 100644 (file)
@@ -881,6 +881,40 @@ static void falcon_remove_port(struct efx_nic *efx)
        efx_nic_free_buffer(efx, &efx->stats_buffer);
 }
 
+/* Global events are basically PHY events */
+static bool
+falcon_handle_global_event(struct efx_channel *channel, efx_qword_t *event)
+{
+       struct efx_nic *efx = channel->efx;
+
+       if (EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_G_PHY0_INTR) ||
+           EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XG_PHY0_INTR) ||
+           EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XFP_PHY0_INTR))
+               /* Ignored */
+               return true;
+
+       if ((efx_nic_rev(efx) == EFX_REV_FALCON_B0) &&
+           EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_XG_MGT_INTR)) {
+               efx->xmac_poll_required = true;
+               return true;
+       }
+
+       if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1 ?
+           EFX_QWORD_FIELD(*event, FSF_AA_GLB_EV_RX_RECOVERY) :
+           EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_RX_RECOVERY)) {
+               netif_err(efx, rx_err, efx->net_dev,
+                         "channel %d seen global RX_RESET event. Resetting.\n",
+                         channel->channel);
+
+               atomic_inc(&efx->rx_reset);
+               efx_schedule_reset(efx, EFX_WORKAROUND_6555(efx) ?
+                                  RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE);
+               return true;
+       }
+
+       return false;
+}
+
 /**************************************************************************
  *
  * Falcon test code
@@ -1702,6 +1736,7 @@ struct efx_nic_type falcon_a1_nic_type = {
        .reset = falcon_reset_hw,
        .probe_port = falcon_probe_port,
        .remove_port = falcon_remove_port,
+       .handle_global_event = falcon_handle_global_event,
        .prepare_flush = falcon_prepare_flush,
        .update_stats = falcon_update_nic_stats,
        .start_stats = falcon_start_nic_stats,
@@ -1742,6 +1777,7 @@ struct efx_nic_type falcon_b0_nic_type = {
        .reset = falcon_reset_hw,
        .probe_port = falcon_probe_port,
        .remove_port = falcon_remove_port,
+       .handle_global_event = falcon_handle_global_event,
        .prepare_flush = falcon_prepare_flush,
        .update_stats = falcon_update_nic_stats,
        .start_stats = falcon_start_nic_stats,
index 2ffc920d6ec06bd76a9c219bdece68fca4c940fd..f9d53a01bbc57b8f3bc2450b4260968a759ea892 100644 (file)
@@ -819,6 +819,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
  *     be called while the controller is uninitialised.
  * @probe_port: Probe the MAC and PHY
  * @remove_port: Free resources allocated by probe_port()
+ * @handle_global_event: Handle a "global" event (may be %NULL)
  * @prepare_flush: Prepare the hardware for flushing the DMA queues
  * @update_stats: Update statistics not provided by event handling
  * @start_stats: Start the regular fetching of statistics
@@ -863,6 +864,7 @@ struct efx_nic_type {
        int (*reset)(struct efx_nic *efx, enum reset_type method);
        int (*probe_port)(struct efx_nic *efx);
        void (*remove_port)(struct efx_nic *efx);
+       bool (*handle_global_event)(struct efx_channel *channel, efx_qword_t *);
        void (*prepare_flush)(struct efx_nic *efx);
        void (*update_stats)(struct efx_nic *efx);
        void (*start_stats)(struct efx_nic *efx);
index 41c36b9a4244b907907936b0a6abeaf8f2a301d1..9743cff15130ff044c98e6917ce58935e0e983af 100644 (file)
@@ -894,46 +894,6 @@ efx_handle_generated_event(struct efx_channel *channel, efx_qword_t *event)
                          channel->channel, EFX_QWORD_VAL(*event));
 }
 
-/* Global events are basically PHY events */
-static void
-efx_handle_global_event(struct efx_channel *channel, efx_qword_t *event)
-{
-       struct efx_nic *efx = channel->efx;
-       bool handled = false;
-
-       if (EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_G_PHY0_INTR) ||
-           EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XG_PHY0_INTR) ||
-           EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XFP_PHY0_INTR)) {
-               /* Ignored */
-               handled = true;
-       }
-
-       if ((efx_nic_rev(efx) >= EFX_REV_FALCON_B0) &&
-           EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_XG_MGT_INTR)) {
-               efx->xmac_poll_required = true;
-               handled = true;
-       }
-
-       if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1 ?
-           EFX_QWORD_FIELD(*event, FSF_AA_GLB_EV_RX_RECOVERY) :
-           EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_RX_RECOVERY)) {
-               netif_err(efx, rx_err, efx->net_dev,
-                         "channel %d seen global RX_RESET event. Resetting.\n",
-                         channel->channel);
-
-               atomic_inc(&efx->rx_reset);
-               efx_schedule_reset(efx, EFX_WORKAROUND_6555(efx) ?
-                                  RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE);
-               handled = true;
-       }
-
-       if (!handled)
-               netif_err(efx, hw, efx->net_dev,
-                         "channel %d unknown global event "
-                         EFX_QWORD_FMT "\n", channel->channel,
-                         EFX_QWORD_VAL(*event));
-}
-
 static void
 efx_handle_driver_event(struct efx_channel *channel, efx_qword_t *event)
 {
@@ -1050,15 +1010,17 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget)
                case FSE_AZ_EV_CODE_DRV_GEN_EV:
                        efx_handle_generated_event(channel, &event);
                        break;
-               case FSE_AZ_EV_CODE_GLOBAL_EV:
-                       efx_handle_global_event(channel, &event);
-                       break;
                case FSE_AZ_EV_CODE_DRIVER_EV:
                        efx_handle_driver_event(channel, &event);
                        break;
                case FSE_CZ_EV_CODE_MCDI_EV:
                        efx_mcdi_process_event(channel, &event);
                        break;
+               case FSE_AZ_EV_CODE_GLOBAL_EV:
+                       if (efx->type->handle_global_event &&
+                           efx->type->handle_global_event(channel, &event))
+                               break;
+                       /* else fall through */
                default:
                        netif_err(channel->efx, hw, channel->efx->net_dev,
                                  "channel %d unknown event type %d (data "