Commit 24ea818e authored by Yuval Mintz's avatar Yuval Mintz Committed by David S. Miller

bnx2x: link module eeprom

Add the ethtool functionality of accessing optic modules'
information and eeprom to the bnx2x driver.
Signed-off-by: default avatarYuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: default avatarYaniv Rosner <yaniv.rosner@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent dbef807e
...@@ -1160,6 +1160,65 @@ static int bnx2x_get_eeprom(struct net_device *dev, ...@@ -1160,6 +1160,65 @@ static int bnx2x_get_eeprom(struct net_device *dev,
return rc; return rc;
} }
static int bnx2x_get_module_eeprom(struct net_device *dev,
struct ethtool_eeprom *ee,
u8 *data)
{
struct bnx2x *bp = netdev_priv(dev);
int rc = 0, phy_idx;
u8 *user_data = data;
int remaining_len = ee->len, xfer_size;
unsigned int page_off = ee->offset;
if (!netif_running(dev)) {
DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
"cannot access eeprom when the interface is down\n");
return -EAGAIN;
}
phy_idx = bnx2x_get_cur_phy_idx(bp);
bnx2x_acquire_phy_lock(bp);
while (!rc && remaining_len > 0) {
xfer_size = (remaining_len > SFP_EEPROM_PAGE_SIZE) ?
SFP_EEPROM_PAGE_SIZE : remaining_len;
rc = bnx2x_read_sfp_module_eeprom(&bp->link_params.phy[phy_idx],
&bp->link_params,
page_off,
xfer_size,
user_data);
remaining_len -= xfer_size;
user_data += xfer_size;
page_off += xfer_size;
}
bnx2x_release_phy_lock(bp);
return rc;
}
static int bnx2x_get_module_info(struct net_device *dev,
struct ethtool_modinfo *modinfo)
{
struct bnx2x *bp = netdev_priv(dev);
int phy_idx;
if (!netif_running(dev)) {
DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
"cannot access eeprom when the interface is down\n");
return -EAGAIN;
}
phy_idx = bnx2x_get_cur_phy_idx(bp);
switch (bp->link_params.phy[phy_idx].media_type) {
case ETH_PHY_SFPP_10G_FIBER:
case ETH_PHY_SFP_1G_FIBER:
case ETH_PHY_DA_TWINAX:
modinfo->type = ETH_MODULE_SFF_8079;
modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
return 0;
default:
return -EOPNOTSUPP;
}
}
static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val, static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val,
u32 cmd_flags) u32 cmd_flags)
{ {
...@@ -2915,6 +2974,8 @@ static const struct ethtool_ops bnx2x_ethtool_ops = { ...@@ -2915,6 +2974,8 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
.set_rxfh_indir = bnx2x_set_rxfh_indir, .set_rxfh_indir = bnx2x_set_rxfh_indir,
.get_channels = bnx2x_get_channels, .get_channels = bnx2x_get_channels,
.set_channels = bnx2x_set_channels, .set_channels = bnx2x_set_channels,
.get_module_info = bnx2x_get_module_info,
.get_module_eeprom = bnx2x_get_module_eeprom,
.get_eee = bnx2x_get_eee, .get_eee = bnx2x_get_eee,
.set_eee = bnx2x_set_eee, .set_eee = bnx2x_set_eee,
}; };
......
...@@ -7695,7 +7695,7 @@ static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, ...@@ -7695,7 +7695,7 @@ static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
struct bnx2x *bp = params->bp; struct bnx2x *bp = params->bp;
u16 val = 0; u16 val = 0;
u16 i; u16 i;
if (byte_cnt > 16) { if (byte_cnt > SFP_EEPROM_PAGE_SIZE) {
DP(NETIF_MSG_LINK, DP(NETIF_MSG_LINK,
"Reading from eeprom is limited to 0xf\n"); "Reading from eeprom is limited to 0xf\n");
return -EINVAL; return -EINVAL;
...@@ -7764,7 +7764,8 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, ...@@ -7764,7 +7764,8 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
u32 data_array[4]; u32 data_array[4];
u16 addr32; u16 addr32;
struct bnx2x *bp = params->bp; struct bnx2x *bp = params->bp;
if (byte_cnt > 16) {
if (byte_cnt > SFP_EEPROM_PAGE_SIZE) {
DP(NETIF_MSG_LINK, DP(NETIF_MSG_LINK,
"Reading from eeprom is limited to 16 bytes\n"); "Reading from eeprom is limited to 16 bytes\n");
return -EINVAL; return -EINVAL;
...@@ -7794,7 +7795,7 @@ static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, ...@@ -7794,7 +7795,7 @@ static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
struct bnx2x *bp = params->bp; struct bnx2x *bp = params->bp;
u16 val, i; u16 val, i;
if (byte_cnt > 16) { if (byte_cnt > SFP_EEPROM_PAGE_SIZE) {
DP(NETIF_MSG_LINK, DP(NETIF_MSG_LINK,
"Reading from eeprom is limited to 0xf\n"); "Reading from eeprom is limited to 0xf\n");
return -EINVAL; return -EINVAL;
...@@ -7877,7 +7878,7 @@ int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, ...@@ -7877,7 +7878,7 @@ int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
struct link_params *params, u16 addr, struct link_params *params, u16 addr,
u8 byte_cnt, u8 *o_buf) u8 byte_cnt, u8 *o_buf)
{ {
int rc = -EINVAL; int rc = -EOPNOTSUPP;
switch (phy->type) { switch (phy->type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
rc = bnx2x_8726_read_sfp_module_eeprom(phy, params, addr, rc = bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#define SPEED_AUTO_NEG 0 #define SPEED_AUTO_NEG 0
#define SPEED_20000 20000 #define SPEED_20000 20000
#define SFP_EEPROM_PAGE_SIZE 16
#define SFP_EEPROM_VENDOR_NAME_ADDR 0x14 #define SFP_EEPROM_VENDOR_NAME_ADDR 0x14
#define SFP_EEPROM_VENDOR_NAME_SIZE 16 #define SFP_EEPROM_VENDOR_NAME_SIZE 16
#define SFP_EEPROM_VENDOR_OUI_ADDR 0x25 #define SFP_EEPROM_VENDOR_OUI_ADDR 0x25
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment