0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/interrupt.h>
0009
0010 #include "mlxbf_gige.h"
0011 #include "mlxbf_gige_regs.h"
0012
0013 static irqreturn_t mlxbf_gige_error_intr(int irq, void *dev_id)
0014 {
0015 struct mlxbf_gige *priv;
0016 u64 int_status;
0017
0018 priv = dev_id;
0019
0020 int_status = readq(priv->base + MLXBF_GIGE_INT_STATUS);
0021
0022 if (int_status & MLXBF_GIGE_INT_STATUS_HW_ACCESS_ERROR)
0023 priv->stats.hw_access_errors++;
0024
0025 if (int_status & MLXBF_GIGE_INT_STATUS_TX_CHECKSUM_INPUTS) {
0026 priv->stats.tx_invalid_checksums++;
0027
0028
0029
0030
0031
0032 }
0033
0034 if (int_status & MLXBF_GIGE_INT_STATUS_TX_SMALL_FRAME_SIZE) {
0035 priv->stats.tx_small_frames++;
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 }
0047
0048 if (int_status & MLXBF_GIGE_INT_STATUS_TX_PI_CI_EXCEED_WQ_SIZE)
0049 priv->stats.tx_index_errors++;
0050
0051 if (int_status & MLXBF_GIGE_INT_STATUS_SW_CONFIG_ERROR)
0052 priv->stats.sw_config_errors++;
0053
0054 if (int_status & MLXBF_GIGE_INT_STATUS_SW_ACCESS_ERROR)
0055 priv->stats.sw_access_errors++;
0056
0057
0058
0059
0060
0061
0062
0063 int_status &= ~MLXBF_GIGE_INT_STATUS_RX_RECEIVE_PACKET;
0064
0065 writeq(int_status, priv->base + MLXBF_GIGE_INT_STATUS);
0066
0067 return IRQ_HANDLED;
0068 }
0069
0070 static irqreturn_t mlxbf_gige_rx_intr(int irq, void *dev_id)
0071 {
0072 struct mlxbf_gige *priv;
0073
0074 priv = dev_id;
0075
0076
0077
0078
0079
0080
0081
0082 napi_schedule(&priv->napi);
0083
0084 return IRQ_HANDLED;
0085 }
0086
0087 static irqreturn_t mlxbf_gige_llu_plu_intr(int irq, void *dev_id)
0088 {
0089 return IRQ_HANDLED;
0090 }
0091
0092 int mlxbf_gige_request_irqs(struct mlxbf_gige *priv)
0093 {
0094 int err;
0095
0096 err = request_irq(priv->error_irq, mlxbf_gige_error_intr, 0,
0097 "mlxbf_gige_error", priv);
0098 if (err) {
0099 dev_err(priv->dev, "Request error_irq failure\n");
0100 return err;
0101 }
0102
0103 err = request_irq(priv->rx_irq, mlxbf_gige_rx_intr, 0,
0104 "mlxbf_gige_rx", priv);
0105 if (err) {
0106 dev_err(priv->dev, "Request rx_irq failure\n");
0107 goto free_error_irq;
0108 }
0109
0110 err = request_irq(priv->llu_plu_irq, mlxbf_gige_llu_plu_intr, 0,
0111 "mlxbf_gige_llu_plu", priv);
0112 if (err) {
0113 dev_err(priv->dev, "Request llu_plu_irq failure\n");
0114 goto free_rx_irq;
0115 }
0116
0117 return 0;
0118
0119 free_rx_irq:
0120 free_irq(priv->rx_irq, priv);
0121
0122 free_error_irq:
0123 free_irq(priv->error_irq, priv);
0124
0125 return err;
0126 }
0127
0128 void mlxbf_gige_free_irqs(struct mlxbf_gige *priv)
0129 {
0130 free_irq(priv->error_irq, priv);
0131 free_irq(priv->rx_irq, priv);
0132 free_irq(priv->llu_plu_irq, priv);
0133 }