]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/sfc/falcon.c
sfc: Use explicit bool for boolean variables, parameters and return values
[linux-2.6-omap-h63xx.git] / drivers / net / sfc / falcon.c
index 790db89db3454cd8da3ef1feb873b27b781abd1b..fb069712222fb7db03cc225cf9d990fcbe45f622 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/seq_file.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
 #include "net_driver.h"
 #include "bitfield.h"
 #include "efx.h"
  * struct falcon_nic_data - Falcon NIC state
  * @next_buffer_table: First available buffer table id
  * @pci_dev2: The secondary PCI device if present
+ * @i2c_data: Operations and state for I2C bit-bashing algorithm
  */
 struct falcon_nic_data {
        unsigned next_buffer_table;
        struct pci_dev *pci_dev2;
+       struct i2c_algo_bit_data i2c_data;
 };
 
 /**************************************************************************
@@ -175,39 +179,52 @@ static inline int falcon_event_present(efx_qword_t *event)
  *
  **************************************************************************
  */
-static void falcon_setsdascl(struct efx_i2c_interface *i2c)
+static void falcon_setsda(void *data, int state)
 {
+       struct efx_nic *efx = (struct efx_nic *)data;
        efx_oword_t reg;
 
-       falcon_read(i2c->efx, &reg, GPIO_CTL_REG_KER);
-       EFX_SET_OWORD_FIELD(reg, GPIO0_OEN, (i2c->scl ? 0 : 1));
-       EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, (i2c->sda ? 0 : 1));
-       falcon_write(i2c->efx, &reg, GPIO_CTL_REG_KER);
+       falcon_read(efx, &reg, GPIO_CTL_REG_KER);
+       EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, !state);
+       falcon_write(efx, &reg, GPIO_CTL_REG_KER);
 }
 
-static int falcon_getsda(struct efx_i2c_interface *i2c)
+static void falcon_setscl(void *data, int state)
 {
+       struct efx_nic *efx = (struct efx_nic *)data;
        efx_oword_t reg;
 
-       falcon_read(i2c->efx, &reg, GPIO_CTL_REG_KER);
+       falcon_read(efx, &reg, GPIO_CTL_REG_KER);
+       EFX_SET_OWORD_FIELD(reg, GPIO0_OEN, !state);
+       falcon_write(efx, &reg, GPIO_CTL_REG_KER);
+}
+
+static int falcon_getsda(void *data)
+{
+       struct efx_nic *efx = (struct efx_nic *)data;
+       efx_oword_t reg;
+
+       falcon_read(efx, &reg, GPIO_CTL_REG_KER);
        return EFX_OWORD_FIELD(reg, GPIO3_IN);
 }
 
-static int falcon_getscl(struct efx_i2c_interface *i2c)
+static int falcon_getscl(void *data)
 {
+       struct efx_nic *efx = (struct efx_nic *)data;
        efx_oword_t reg;
 
-       falcon_read(i2c->efx, &reg, GPIO_CTL_REG_KER);
-       return EFX_DWORD_FIELD(reg, GPIO0_IN);
+       falcon_read(efx, &reg, GPIO_CTL_REG_KER);
+       return EFX_OWORD_FIELD(reg, GPIO0_IN);
 }
 
-static struct efx_i2c_bit_operations falcon_i2c_bit_operations = {
-       .setsda         = falcon_setsdascl,
-       .setscl         = falcon_setsdascl,
+static struct i2c_algo_bit_data falcon_i2c_bit_operations = {
+       .setsda         = falcon_setsda,
+       .setscl         = falcon_setscl,
        .getsda         = falcon_getsda,
        .getscl         = falcon_getscl,
-       .udelay         = 100,
-       .mdelay         = 10,
+       .udelay         = 5,
+       /* Wait up to 50 ms for slave to let us pull SCL high */
+       .timeout        = DIV_ROUND_UP(HZ, 20),
 };
 
 /**************************************************************************
@@ -457,9 +474,9 @@ int falcon_init_tx(struct efx_tx_queue *tx_queue)
                              TX_NON_IP_DROP_DIS_B0, 1);
 
        if (falcon_rev(efx) >= FALCON_REV_B0) {
-               int csum = !(efx->net_dev->features & NETIF_F_IP_CSUM);
-               EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, csum);
-               EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, csum);
+               int csum = tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM;
+               EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, !csum);
+               EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, !csum);
        }
 
        falcon_write_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base,
@@ -468,10 +485,11 @@ int falcon_init_tx(struct efx_tx_queue *tx_queue)
        if (falcon_rev(efx) < FALCON_REV_B0) {
                efx_oword_t reg;
 
-               BUG_ON(tx_queue->queue >= 128); /* HW limit */
+               /* Only 128 bits in this register */
+               BUILD_BUG_ON(EFX_TX_QUEUE_COUNT >= 128);
 
                falcon_read(efx, &reg, TX_CHKSM_CFG_REG_KER_A1);
-               if (efx->net_dev->features & NETIF_F_IP_CSUM)
+               if (tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM)
                        clear_bit_le(tx_queue->queue, (void *)&reg);
                else
                        set_bit_le(tx_queue->queue, (void *)&reg);
@@ -521,7 +539,7 @@ static int falcon_flush_tx_queue(struct efx_tx_queue *tx_queue)
 
        if (EFX_WORKAROUND_11557(efx)) {
                efx_oword_t reg;
-               int enabled;
+               bool enabled;
 
                falcon_read_table(efx, &reg, efx->type->txd_ptr_tbl_base,
                                  tx_queue->queue);
@@ -626,8 +644,8 @@ int falcon_init_rx(struct efx_rx_queue *rx_queue)
        efx_oword_t rx_desc_ptr;
        struct efx_nic *efx = rx_queue->efx;
        int rc;
-       int is_b0 = falcon_rev(efx) >= FALCON_REV_B0;
-       int iscsi_digest_en = is_b0;
+       bool is_b0 = falcon_rev(efx) >= FALCON_REV_B0;
+       bool iscsi_digest_en = is_b0;
 
        EFX_LOG(efx, "RX queue %d ring in special buffers %d-%d\n",
                rx_queue->queue, rx_queue->rxd.index,
@@ -677,7 +695,8 @@ static int falcon_flush_rx_queue(struct efx_rx_queue *rx_queue)
        read_ptr = channel->eventq_read_ptr;
        for (i = 0; i < FALCON_EVQ_SIZE; ++i) {
                efx_qword_t *event = falcon_event(channel, read_ptr);
-               int ev_code, ev_sub_code, ev_queue, ev_failed;
+               int ev_code, ev_sub_code, ev_queue;
+               bool ev_failed;
                if (!falcon_event_present(event))
                        break;
 
@@ -704,7 +723,7 @@ static int falcon_flush_rx_queue(struct efx_rx_queue *rx_queue)
 
        if (EFX_WORKAROUND_11557(efx)) {
                efx_oword_t reg;
-               int enabled;
+               bool enabled;
 
                falcon_read_table(efx, &reg, efx->type->rxd_ptr_tbl_base,
                                  rx_queue->queue);
@@ -830,39 +849,19 @@ static inline void falcon_handle_tx_event(struct efx_channel *channel,
        }
 }
 
-/* Check received packet's destination MAC address. */
-static int check_dest_mac(struct efx_rx_queue *rx_queue,
-                         const efx_qword_t *event)
-{
-       struct efx_rx_buffer *rx_buf;
-       struct efx_nic *efx = rx_queue->efx;
-       int rx_ev_desc_ptr;
-       struct ethhdr *eh;
-
-       if (efx->promiscuous)
-               return 1;
-
-       rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, RX_EV_DESC_PTR);
-       rx_buf = efx_rx_buffer(rx_queue, rx_ev_desc_ptr);
-       eh = (struct ethhdr *)rx_buf->data;
-       if (memcmp(eh->h_dest, efx->net_dev->dev_addr, ETH_ALEN))
-               return 0;
-       return 1;
-}
-
 /* Detect errors included in the rx_evt_pkt_ok bit. */
 static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
                                    const efx_qword_t *event,
-                                   unsigned *rx_ev_pkt_ok,
-                                   int *discard, int byte_count)
+                                   bool *rx_ev_pkt_ok,
+                                   bool *discard)
 {
        struct efx_nic *efx = rx_queue->efx;
-       unsigned rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err;
-       unsigned rx_ev_tcp_udp_chksum_err, rx_ev_eth_crc_err;
-       unsigned rx_ev_frm_trunc, rx_ev_drib_nib, rx_ev_tobe_disc;
-       unsigned rx_ev_pkt_type, rx_ev_other_err, rx_ev_pause_frm;
-       unsigned rx_ev_ip_frag_err, rx_ev_hdr_type, rx_ev_mcast_pkt;
-       int snap, non_ip;
+       bool rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err;
+       bool rx_ev_tcp_udp_chksum_err, rx_ev_eth_crc_err;
+       bool rx_ev_frm_trunc, rx_ev_drib_nib, rx_ev_tobe_disc;
+       bool rx_ev_other_err, rx_ev_pause_frm;
+       bool rx_ev_ip_frag_err, rx_ev_hdr_type, rx_ev_mcast_pkt;
+       unsigned rx_ev_pkt_type;
 
        rx_ev_hdr_type = EFX_QWORD_FIELD(*event, RX_EV_HDR_TYPE);
        rx_ev_mcast_pkt = EFX_QWORD_FIELD(*event, RX_EV_MCAST_PKT);
@@ -886,41 +885,6 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
                           rx_ev_buf_owner_id_err | rx_ev_eth_crc_err |
                           rx_ev_frm_trunc | rx_ev_ip_hdr_chksum_err);
 
-       snap = (rx_ev_pkt_type == RX_EV_PKT_TYPE_LLC_DECODE) ||
-               (rx_ev_pkt_type == RX_EV_PKT_TYPE_VLAN_LLC_DECODE);
-       non_ip = (rx_ev_hdr_type == RX_EV_HDR_TYPE_NON_IP_DECODE);
-
-       /* SFC bug 5475/8970: The Falcon XMAC incorrectly calculates the
-        * length field of an LLC frame, which sets TOBE_DISC. We could set
-        * PASS_LEN_ERR, but we want the MAC to filter out short frames (to
-        * protect the RX block).
-        *
-        * bug5475 - LLC/SNAP: Falcon identifies SNAP packets.
-        * bug8970 - LLC/noSNAP: Falcon does not provide an LLC flag.
-        *                       LLC can't encapsulate IP, so by definition
-        *                       these packets are NON_IP.
-        *
-        * Unicast mismatch will also cause TOBE_DISC, so the driver needs
-        * to check this.
-        */
-       if (EFX_WORKAROUND_5475(efx) && rx_ev_tobe_disc && (snap || non_ip)) {
-               /* If all the other flags are zero then we can state the
-                * entire packet is ok, which will flag to the kernel not
-                * to recalculate checksums.
-                */
-               if (!(non_ip | rx_ev_other_err | rx_ev_pause_frm))
-                       *rx_ev_pkt_ok = 1;
-
-               rx_ev_tobe_disc = 0;
-
-               /* TOBE_DISC is set for unicast mismatch.  But given that
-                * we can't trust TOBE_DISC here, we must validate the dest
-                * MAC address ourselves.
-                */
-               if (!rx_ev_mcast_pkt && !check_dest_mac(rx_queue, event))
-                       rx_ev_tobe_disc = 1;
-       }
-
        /* Count errors that are not in MAC stats. */
        if (rx_ev_frm_trunc)
                ++rx_queue->channel->n_rx_frm_trunc;
@@ -944,7 +908,7 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
 #ifdef EFX_ENABLE_DEBUG
        if (rx_ev_other_err) {
                EFX_INFO_RL(efx, " RX queue %d unexpected RX event "
-                           EFX_QWORD_FMT "%s%s%s%s%s%s%s%s%s\n",
+                           EFX_QWORD_FMT "%s%s%s%s%s%s%s%s\n",
                            rx_queue->queue, EFX_QWORD_VAL(*event),
                            rx_ev_buf_owner_id_err ? " [OWNER_ID_ERR]" : "",
                            rx_ev_ip_hdr_chksum_err ?
@@ -955,8 +919,7 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
                            rx_ev_frm_trunc ? " [FRM_TRUNC]" : "",
                            rx_ev_drib_nib ? " [DRIB_NIB]" : "",
                            rx_ev_tobe_disc ? " [TOBE_DISC]" : "",
-                           rx_ev_pause_frm ? " [PAUSE]" : "",
-                           snap ? " [SNAP/LLC]" : "");
+                           rx_ev_pause_frm ? " [PAUSE]" : "");
        }
 #endif
 
@@ -993,9 +956,9 @@ static inline int falcon_handle_rx_event(struct efx_channel *channel,
                                         const efx_qword_t *event)
 {
        unsigned int rx_ev_q_label, rx_ev_desc_ptr, rx_ev_byte_cnt;
-       unsigned int rx_ev_pkt_ok, rx_ev_hdr_type, rx_ev_mcast_pkt;
+       unsigned int rx_ev_hdr_type, rx_ev_mcast_pkt;
        unsigned expected_ptr;
-       int discard = 0, checksummed;
+       bool rx_ev_pkt_ok, discard = false, checksummed;
        struct efx_rx_queue *rx_queue;
        struct efx_nic *efx = channel->efx;
 
@@ -1023,8 +986,8 @@ static inline int falcon_handle_rx_event(struct efx_channel *channel,
                checksummed = RX_EV_HDR_TYPE_HAS_CHECKSUMS(rx_ev_hdr_type);
        } else {
                falcon_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok,
-                                       &discard, rx_ev_byte_cnt);
-               checksummed = 0;
+                                       &discard);
+               checksummed = false;
        }
 
        /* Detect multicast packets that didn't match the filter */
@@ -1034,7 +997,7 @@ static inline int falcon_handle_rx_event(struct efx_channel *channel,
                        EFX_QWORD_FIELD(*event, RX_EV_MCAST_HASH_MATCH);
 
                if (unlikely(!rx_ev_mcast_hash_match))
-                       discard = 1;
+                       discard = true;
        }
 
        /* Handle received packet */
@@ -1049,23 +1012,23 @@ static void falcon_handle_global_event(struct efx_channel *channel,
                                       efx_qword_t *event)
 {
        struct efx_nic *efx = channel->efx;
-       int is_phy_event = 0, handled = 0;
+       bool is_phy_event = false, handled = false;
 
        /* Check for interrupt on either port.  Some boards have a
         * single PHY wired to the interrupt line for port 1. */
        if (EFX_QWORD_FIELD(*event, G_PHY0_INTR) ||
            EFX_QWORD_FIELD(*event, G_PHY1_INTR) ||
            EFX_QWORD_FIELD(*event, XG_PHY_INTR))
-               is_phy_event = 1;
+               is_phy_event = true;
 
        if ((falcon_rev(efx) >= FALCON_REV_B0) &&
            EFX_OWORD_FIELD(*event, XG_MNT_INTR_B0))
-               is_phy_event = 1;
+               is_phy_event = true;
 
        if (is_phy_event) {
                efx->phy_op->clear_interrupt(efx);
                queue_work(efx->workqueue, &efx->reconfigure_work);
-               handled = 1;
+               handled = true;
        }
 
        if (EFX_QWORD_FIELD_VER(efx, *event, RX_RECOVERY)) {
@@ -1075,7 +1038,7 @@ static void falcon_handle_global_event(struct efx_channel *channel,
                atomic_inc(&efx->rx_reset);
                efx_schedule_reset(efx, EFX_WORKAROUND_6555(efx) ?
                                   RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE);
-               handled = 1;
+               handled = true;
        }
 
        if (!handled)
@@ -1795,7 +1758,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
 {
        efx_oword_t reg;
        int link_speed;
-       unsigned int tx_fc;
+       bool tx_fc;
 
        if (efx->link_options & GM_LPA_10000)
                link_speed = 0x3;
@@ -1830,7 +1793,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
        /* Transmission of pause frames when RX crosses the threshold is
         * covered by RX_XOFF_MAC_EN and XM_TX_CFG_REG:XM_FCNTL.
         * Action on receipt of pause frames is controller by XM_DIS_FCNTL */
-       tx_fc = (efx->flow_control & EFX_FC_TX) ? 1 : 0;
+       tx_fc = !!(efx->flow_control & EFX_FC_TX);
        falcon_read(efx, &reg, RX_CFG_REG_KER);
        EFX_SET_OWORD_FIELD_VER(efx, reg, RX_XOFF_MAC_EN, tx_fc);
 
@@ -1934,7 +1897,7 @@ static int falcon_gmii_wait(struct efx_nic *efx)
 static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
                              int addr, int value)
 {
-       struct efx_nic *efx = net_dev->priv;
+       struct efx_nic *efx = netdev_priv(net_dev);
        unsigned int phy_id2 = phy_id & FALCON_PHY_ID_ID_MASK;
        efx_oword_t reg;
 
@@ -2002,7 +1965,7 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
  * could be read, -1 will be returned. */
 static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
 {
-       struct efx_nic *efx = net_dev->priv;
+       struct efx_nic *efx = netdev_priv(net_dev);
        unsigned int phy_addr = phy_id & FALCON_PHY_ID_ID_MASK;
        efx_oword_t reg;
        int value = -1;
@@ -2103,7 +2066,7 @@ int falcon_probe_port(struct efx_nic *efx)
                return rc;
 
        /* Set up GMII structure for PHY */
-       efx->mii.supports_gmii = 1;
+       efx->mii.supports_gmii = true;
        falcon_init_mdio(&efx->mii);
 
        /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */
@@ -2405,12 +2368,6 @@ int falcon_probe_nic(struct efx_nic *efx)
        struct falcon_nic_data *nic_data;
        int rc;
 
-       /* Initialise I2C interface state */
-       efx->i2c.efx = efx;
-       efx->i2c.op = &falcon_i2c_bit_operations;
-       efx->i2c.sda = 1;
-       efx->i2c.scl = 1;
-
        /* Allocate storage for hardware specific data */
        nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL);
        efx->nic_data = nic_data;
@@ -2461,6 +2418,17 @@ int falcon_probe_nic(struct efx_nic *efx)
        if (rc)
                goto fail5;
 
+       /* Initialise I2C adapter */
+       efx->i2c_adap.owner = THIS_MODULE;
+       nic_data->i2c_data = falcon_i2c_bit_operations;
+       nic_data->i2c_data.data = efx;
+       efx->i2c_adap.algo_data = &nic_data->i2c_data;
+       efx->i2c_adap.dev.parent = &efx->pci_dev->dev;
+       strlcpy(efx->i2c_adap.name, "SFC4000 GPIO", sizeof(efx->i2c_adap.name));
+       rc = i2c_bit_add_bus(&efx->i2c_adap);
+       if (rc)
+               goto fail5;
+
        return 0;
 
  fail5:
@@ -2619,8 +2587,8 @@ int falcon_init_nic(struct efx_nic *efx)
                  rx_xoff_thresh_bytes : efx->type->rx_xoff_thresh);
        EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XOFF_MAC_TH, thresh / 256);
        /* RX control FIFO thresholds [32 entries] */
-       EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XON_TX_TH, 25);
-       EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XOFF_TX_TH, 20);
+       EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XON_TX_TH, 20);
+       EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XOFF_TX_TH, 25);
        falcon_write(efx, &temp, RX_CFG_REG_KER);
 
        /* Set destination of both TX and RX Flush events */
@@ -2635,6 +2603,10 @@ int falcon_init_nic(struct efx_nic *efx)
 void falcon_remove_nic(struct efx_nic *efx)
 {
        struct falcon_nic_data *nic_data = efx->nic_data;
+       int rc;
+
+       rc = i2c_del_adapter(&efx->i2c_adap);
+       BUG_ON(rc);
 
        falcon_free_buffer(efx, &efx->irq_status);