Skip to content

Commit

Permalink
sfc: Use kernel I2C system and i2c-algo-bit driver
Browse files Browse the repository at this point in the history
Remove our own implementation of I2C bit-banging.

Signed-off-by: Ben Hutchings <[email protected]>
Signed-off-by: Jeff Garzik <[email protected]>
  • Loading branch information
Ben Hutchings authored and Jeff Garzik committed May 31, 2008
1 parent 9e833be commit 37b5a60
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 559 deletions.
2 changes: 2 additions & 0 deletions drivers/net/sfc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ config SFC
select MII
select INET_LRO
select CRC32
select I2C
select I2C_ALGOBIT
help
This driver supports 10-gigabit Ethernet cards based on
the Solarflare Communications Solarstorm SFC4000 controller.
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/sfc/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
sfc-y += efx.o falcon.o tx.o rx.o falcon_xmac.o \
i2c-direct.o selftest.o ethtool.o xfp_phy.o \
selftest.o ethtool.o xfp_phy.o \
mdio_10g.o tenxpress.o boards.o sfe4001.o

obj-$(CONFIG_SFC) += sfc.o
2 changes: 1 addition & 1 deletion drivers/net/sfc/boards.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ static struct efx_board_data board_data[] = {
[EFX_BOARD_INVALID] =
{NULL, NULL, dummy_init},
[EFX_BOARD_SFE4001] =
{"SFE4001", "10GBASE-T adapter", sfe4001_poweron},
{"SFE4001", "10GBASE-T adapter", sfe4001_init},
[EFX_BOARD_SFE4002] =
{"SFE4002", "XFP adapter", sfe4002_init},
};
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/sfc/boards.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ enum efx_board_type {
};

extern int efx_set_board_info(struct efx_nic *efx, u16 revision_info);
extern int sfe4001_poweron(struct efx_nic *efx);
extern void sfe4001_poweroff(struct efx_nic *efx);
extern int sfe4001_init(struct efx_nic *efx);
/* Are we putting the PHY into flash config mode */
extern unsigned int sfe4001_phy_flash_cfg;

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/sfc/efx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1815,6 +1815,7 @@ static struct efx_board efx_dummy_board_info = {
.init = efx_nic_dummy_op_int,
.init_leds = efx_port_dummy_op_int,
.set_fault_led = efx_port_dummy_op_blink,
.fini = efx_port_dummy_op_void,
};

/**************************************************************************
Expand Down Expand Up @@ -1941,6 +1942,7 @@ static void efx_pci_remove_main(struct efx_nic *efx)
efx_fini_port(efx);

/* Shutdown the board, then the NIC and board state */
efx->board_info.fini(efx);
falcon_fini_interrupt(efx);

efx_fini_napi(efx);
Expand Down
72 changes: 52 additions & 20 deletions drivers/net/sfc/falcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -36,10 +38,12 @@
* 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;
};

/**************************************************************************
Expand Down Expand Up @@ -175,39 +179,57 @@ 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,
/*
* This is the number of system clock ticks after which
* i2c-algo-bit gives up waiting for SCL to become high.
* It must be at least 2 since the first tick can happen
* immediately after it starts waiting.
*/
.timeout = 2,
};

/**************************************************************************
Expand Down Expand Up @@ -2403,12 +2425,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;
Expand Down Expand Up @@ -2459,6 +2475,18 @@ int falcon_probe_nic(struct efx_nic *efx)
if (rc)
goto fail5;

/* Initialise I2C adapter */
efx->i2c_adap.owner = THIS_MODULE;
efx->i2c_adap.class = I2C_CLASS_HWMON;
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;
strcpy(efx->i2c_adap.name, "SFC4000 GPIO");
rc = i2c_bit_add_bus(&efx->i2c_adap);
if (rc)
goto fail5;

return 0;

fail5:
Expand Down Expand Up @@ -2633,6 +2661,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);

Expand Down
Loading

0 comments on commit 37b5a60

Please sign in to comment.