aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x_main.c
diff options
context:
space:
mode:
authorEilon Greenstein <eilong@broadcom.com>2009-08-12 04:23:08 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-13 02:02:29 -0400
commit01cd452846c98609dd3efbee0deea050e6706f02 (patch)
tree87647fccfe40819aa803b1f8191d7d4127024e63 /drivers/net/bnx2x_main.c
parent239d686d494f10ecd83a89ddc4e31f9462ca4901 (diff)
bnx2x: MDC/MDIO CL45 IOCTLs
As suggested by Ben Hutchings <bhutchings@solarflare.com>, using the MDC/MDIO IOCTL Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r--drivers/net/bnx2x_main.c121
1 files changed, 84 insertions, 37 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index a695e7f0647c..145866764d46 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -8331,6 +8331,7 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
8331 u32 val, val2; 8331 u32 val, val2;
8332 u32 config; 8332 u32 config;
8333 u16 i; 8333 u16 i;
8334 u32 ext_phy_type;
8334 8335
8335 bp->link_params.bp = bp; 8336 bp->link_params.bp = bp;
8336 bp->link_params.port = port; 8337 bp->link_params.port = port;
@@ -8390,6 +8391,21 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
8390 8391
8391 bnx2x_link_settings_requested(bp); 8392 bnx2x_link_settings_requested(bp);
8392 8393
8394 /*
8395 * If connected directly, work with the internal PHY, otherwise, work
8396 * with the external PHY
8397 */
8398 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
8399 if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
8400 bp->mdio.prtad = bp->link_params.phy_addr;
8401
8402 else if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
8403 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN))
8404 bp->mdio.prtad =
8405 (bp->link_params.ext_phy_config &
8406 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
8407 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT;
8408
8393 val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper); 8409 val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper);
8394 val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower); 8410 val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower);
8395 bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff); 8411 bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff);
@@ -8614,7 +8630,7 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
8614 } else 8630 } else
8615 cmd->port = PORT_TP; 8631 cmd->port = PORT_TP;
8616 8632
8617 cmd->phy_address = bp->port.phy_addr; 8633 cmd->phy_address = bp->mdio.prtad;
8618 cmd->transceiver = XCVR_INTERNAL; 8634 cmd->transceiver = XCVR_INTERNAL;
8619 8635
8620 if (bp->link_params.req_line_speed == SPEED_AUTO_NEG) 8636 if (bp->link_params.req_line_speed == SPEED_AUTO_NEG)
@@ -11149,54 +11165,77 @@ static int bnx2x_change_mac_addr(struct net_device *dev, void *p)
11149} 11165}
11150 11166
11151/* called with rtnl_lock */ 11167/* called with rtnl_lock */
11152static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 11168static int bnx2x_mdio_read(struct net_device *netdev, int prtad,
11169 int devad, u16 addr)
11153{ 11170{
11154 struct mii_ioctl_data *data = if_mii(ifr); 11171 struct bnx2x *bp = netdev_priv(netdev);
11155 struct bnx2x *bp = netdev_priv(dev); 11172 u16 value;
11156 int port = BP_PORT(bp); 11173 int rc;
11157 int err; 11174 u32 phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
11158 11175
11159 switch (cmd) { 11176 DP(NETIF_MSG_LINK, "mdio_read: prtad 0x%x, devad 0x%x, addr 0x%x\n",
11160 case SIOCGMIIPHY: 11177 prtad, devad, addr);
11161 data->phy_id = bp->port.phy_addr;
11162 11178
11163 /* fallthrough */ 11179 if (prtad != bp->mdio.prtad) {
11180 DP(NETIF_MSG_LINK, "prtad missmatch (cmd:0x%x != bp:0x%x)\n",
11181 prtad, bp->mdio.prtad);
11182 return -EINVAL;
11183 }
11184
11185 /* The HW expects different devad if CL22 is used */
11186 devad = (devad == MDIO_DEVAD_NONE) ? DEFAULT_PHY_DEV_ADDR : devad;
11164 11187
11165 case SIOCGMIIREG: { 11188 bnx2x_acquire_phy_lock(bp);
11166 u16 mii_regval; 11189 rc = bnx2x_cl45_read(bp, BP_PORT(bp), phy_type, prtad,
11190 devad, addr, &value);
11191 bnx2x_release_phy_lock(bp);
11192 DP(NETIF_MSG_LINK, "mdio_read_val 0x%x rc = 0x%x\n", value, rc);
11167 11193
11168 if (!netif_running(dev)) 11194 if (!rc)
11169 return -EAGAIN; 11195 rc = value;
11196 return rc;
11197}
11170 11198
11171 mutex_lock(&bp->port.phy_mutex); 11199/* called with rtnl_lock */
11172 err = bnx2x_cl45_read(bp, port, 0, bp->port.phy_addr, 11200static int bnx2x_mdio_write(struct net_device *netdev, int prtad, int devad,
11173 DEFAULT_PHY_DEV_ADDR, 11201 u16 addr, u16 value)
11174 (data->reg_num & 0x1f), &mii_regval); 11202{
11175 data->val_out = mii_regval; 11203 struct bnx2x *bp = netdev_priv(netdev);
11176 mutex_unlock(&bp->port.phy_mutex); 11204 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
11177 return err; 11205 int rc;
11206
11207 DP(NETIF_MSG_LINK, "mdio_write: prtad 0x%x, devad 0x%x, addr 0x%x,"
11208 " value 0x%x\n", prtad, devad, addr, value);
11209
11210 if (prtad != bp->mdio.prtad) {
11211 DP(NETIF_MSG_LINK, "prtad missmatch (cmd:0x%x != bp:0x%x)\n",
11212 prtad, bp->mdio.prtad);
11213 return -EINVAL;
11178 } 11214 }
11179 11215
11180 case SIOCSMIIREG: 11216 /* The HW expects different devad if CL22 is used */
11181 if (!capable(CAP_NET_ADMIN)) 11217 devad = (devad == MDIO_DEVAD_NONE) ? DEFAULT_PHY_DEV_ADDR : devad;
11182 return -EPERM;
11183 11218
11184 if (!netif_running(dev)) 11219 bnx2x_acquire_phy_lock(bp);
11185 return -EAGAIN; 11220 rc = bnx2x_cl45_write(bp, BP_PORT(bp), ext_phy_type, prtad,
11221 devad, addr, value);
11222 bnx2x_release_phy_lock(bp);
11223 return rc;
11224}
11186 11225
11187 mutex_lock(&bp->port.phy_mutex); 11226/* called with rtnl_lock */
11188 err = bnx2x_cl45_write(bp, port, 0, bp->port.phy_addr, 11227static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
11189 DEFAULT_PHY_DEV_ADDR, 11228{
11190 (data->reg_num & 0x1f), data->val_in); 11229 struct bnx2x *bp = netdev_priv(dev);
11191 mutex_unlock(&bp->port.phy_mutex); 11230 struct mii_ioctl_data *mdio = if_mii(ifr);
11192 return err;
11193 11231
11194 default: 11232 DP(NETIF_MSG_LINK, "ioctl: phy id 0x%x, reg 0x%x, val_in 0x%x\n",
11195 /* do nothing */ 11233 mdio->phy_id, mdio->reg_num, mdio->val_in);
11196 break;
11197 }
11198 11234
11199 return -EOPNOTSUPP; 11235 if (!netif_running(dev))
11236 return -EAGAIN;
11237
11238 return mdio_mii_ioctl(&bp->mdio, mdio, cmd);
11200} 11239}
11201 11240
11202/* called with rtnl_lock */ 11241/* called with rtnl_lock */
@@ -11420,6 +11459,14 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
11420 dev->vlan_features |= NETIF_F_TSO6; 11459 dev->vlan_features |= NETIF_F_TSO6;
11421#endif 11460#endif
11422 11461
11462 /* get_port_hwinfo() will set prtad and mmds properly */
11463 bp->mdio.prtad = MDIO_PRTAD_NONE;
11464 bp->mdio.mmds = 0;
11465 bp->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
11466 bp->mdio.dev = dev;
11467 bp->mdio.mdio_read = bnx2x_mdio_read;
11468 bp->mdio.mdio_write = bnx2x_mdio_write;
11469
11423 return 0; 11470 return 0;
11424 11471
11425err_out_unmap: 11472err_out_unmap: