aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/benet/be_cmds.c65
-rw-r--r--drivers/net/benet/be_cmds.h8
-rw-r--r--drivers/net/benet/be_main.c5
-rw-r--r--drivers/net/bnx2x/bnx2x.h2
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.c49
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.h2
-rw-r--r--drivers/net/bnx2x/bnx2x_ethtool.c34
-rw-r--r--drivers/net/bnx2x/bnx2x_hsi.h18
-rw-r--r--drivers/net/bnx2x/bnx2x_link.c1642
-rw-r--r--drivers/net/bnx2x/bnx2x_link.h59
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c43
-rw-r--r--drivers/net/bnx2x/bnx2x_reg.h25
-rw-r--r--drivers/net/bonding/bond_main.c9
-rw-r--r--drivers/net/caif/Kconfig9
-rw-r--r--drivers/net/caif/Makefile3
-rw-r--r--drivers/net/caif/caif_hsi.c1220
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c6
-rw-r--r--drivers/net/sungem.c889
-rw-r--r--drivers/net/sungem.h25
-rw-r--r--include/net/caif/caif_hsi.h145
-rw-r--r--include/net/sctp/sctp.h11
-rw-r--r--include/net/sctp/structs.h17
-rw-r--r--include/net/sctp/user.h1
-rw-r--r--net/8021q/vlan.c15
-rw-r--r--net/8021q/vlan_dev.c4
-rw-r--r--net/8021q/vlanproc.c4
-rw-r--r--net/batman-adv/aggregation.c23
-rw-r--r--net/batman-adv/aggregation.h5
-rw-r--r--net/batman-adv/bat_debugfs.c11
-rw-r--r--net/batman-adv/bat_sysfs.c15
-rw-r--r--net/batman-adv/bitarray.c6
-rw-r--r--net/batman-adv/bitarray.h6
-rw-r--r--net/batman-adv/gateway_client.c19
-rw-r--r--net/batman-adv/gateway_common.c19
-rw-r--r--net/batman-adv/hard-interface.c25
-rw-r--r--net/batman-adv/hard-interface.h6
-rw-r--r--net/batman-adv/hash.c7
-rw-r--r--net/batman-adv/hash.h6
-rw-r--r--net/batman-adv/icmp_socket.c4
-rw-r--r--net/batman-adv/main.c4
-rw-r--r--net/batman-adv/main.h30
-rw-r--r--net/batman-adv/originator.c12
-rw-r--r--net/batman-adv/originator.h14
-rw-r--r--net/batman-adv/ring_buffer.c4
-rw-r--r--net/batman-adv/ring_buffer.h2
-rw-r--r--net/batman-adv/routing.c54
-rw-r--r--net/batman-adv/routing.h12
-rw-r--r--net/batman-adv/send.c44
-rw-r--r--net/batman-adv/send.h12
-rw-r--r--net/batman-adv/soft-interface.c22
-rw-r--r--net/batman-adv/soft-interface.h4
-rw-r--r--net/batman-adv/translation-table.c44
-rw-r--r--net/batman-adv/translation-table.h13
-rw-r--r--net/batman-adv/types.h8
-rw-r--r--net/batman-adv/unicast.c30
-rw-r--r--net/batman-adv/unicast.h8
-rw-r--r--net/batman-adv/vis.c91
-rw-r--r--net/sctp/associola.c6
-rw-r--r--net/sctp/bind_addr.c15
-rw-r--r--net/sctp/ipv6.c2
-rw-r--r--net/sctp/outqueue.c13
-rw-r--r--net/sctp/protocol.c151
-rw-r--r--net/sctp/sm_make_chunk.c29
-rw-r--r--net/sctp/socket.c170
-rw-r--r--net/sctp/sysctl.c7
65 files changed, 3671 insertions, 1592 deletions
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 81654ae16c6..0c12c2d4532 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -799,12 +799,12 @@ static u32 be_encoded_q_len(int q_len)
return len_encoded;
}
-int be_cmd_mccq_create(struct be_adapter *adapter,
+int be_cmd_mccq_ext_create(struct be_adapter *adapter,
struct be_queue_info *mccq,
struct be_queue_info *cq)
{
struct be_mcc_wrb *wrb;
- struct be_cmd_req_mcc_create *req;
+ struct be_cmd_req_mcc_ext_create *req;
struct be_dma_mem *q_mem = &mccq->dma_mem;
void *ctxt;
int status;
@@ -859,6 +859,67 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
return status;
}
+int be_cmd_mccq_org_create(struct be_adapter *adapter,
+ struct be_queue_info *mccq,
+ struct be_queue_info *cq)
+{
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_mcc_create *req;
+ struct be_dma_mem *q_mem = &mccq->dma_mem;
+ void *ctxt;
+ int status;
+
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
+
+ wrb = wrb_from_mbox(adapter);
+ req = embedded_payload(wrb);
+ ctxt = &req->context;
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+ OPCODE_COMMON_MCC_CREATE);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_MCC_CREATE, sizeof(*req));
+
+ req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
+
+ AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1);
+ AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt,
+ be_encoded_q_len(mccq->len));
+ AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id);
+
+ be_dws_cpu_to_le(ctxt, sizeof(req->context));
+
+ be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
+
+ status = be_mbox_notify_wait(adapter);
+ if (!status) {
+ struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
+ mccq->id = le16_to_cpu(resp->id);
+ mccq->created = true;
+ }
+
+ mutex_unlock(&adapter->mbox_lock);
+ return status;
+}
+
+int be_cmd_mccq_create(struct be_adapter *adapter,
+ struct be_queue_info *mccq,
+ struct be_queue_info *cq)
+{
+ int status;
+
+ status = be_cmd_mccq_ext_create(adapter, mccq, cq);
+ if (status && !lancer_chip(adapter)) {
+ dev_warn(&adapter->pdev->dev, "Upgrade to F/W ver 2.102.235.0 "
+ "or newer to avoid conflicting priorities between NIC "
+ "and FCoE traffic");
+ status = be_cmd_mccq_org_create(adapter, mccq, cq);
+ }
+ return status;
+}
+
int be_cmd_txq_create(struct be_adapter *adapter,
struct be_queue_info *txq,
struct be_queue_info *cq)
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 8148cc66cbe..d08289e21f6 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -434,6 +434,14 @@ struct be_cmd_req_mcc_create {
struct be_cmd_req_hdr hdr;
u16 num_pages;
u16 cq_id;
+ u8 context[sizeof(struct amap_mcc_context_be) / 8];
+ struct phys_addr pages[8];
+} __packed;
+
+struct be_cmd_req_mcc_ext_create {
+ struct be_cmd_req_hdr hdr;
+ u16 num_pages;
+ u16 cq_id;
u32 async_event_bitmap[1];
u8 context[sizeof(struct amap_mcc_context_be) / 8];
struct phys_addr pages[8];
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index a485f7fdaf3..5824c95c784 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -3396,6 +3396,11 @@ static int __devinit be_probe(struct pci_dev *pdev,
}
dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num);
+ /* By default all priorities are enabled.
+ * Needed in case of no GRP5 evt support
+ */
+ adapter->vlan_prio_bmap = 0xff;
+
schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
return 0;
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index 668a578c49e..480e02df86e 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -1492,7 +1492,7 @@ void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp);
void bnx2x_invalidate_uc_list(struct bnx2x *bp);
void bnx2x_update_coalesce(struct bnx2x *bp);
-int bnx2x_get_link_cfg_idx(struct bnx2x *bp);
+int bnx2x_get_cur_phy_idx(struct bnx2x *bp);
static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
int wait)
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 289044332ed..9b248348c0e 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -2803,6 +2803,55 @@ static int bnx2x_reload_if_running(struct net_device *dev)
return bnx2x_nic_load(bp, LOAD_NORMAL);
}
+int bnx2x_get_cur_phy_idx(struct bnx2x *bp)
+{
+ u32 sel_phy_idx = 0;
+ if (bp->link_params.num_phys <= 1)
+ return INT_PHY;
+
+ if (bp->link_vars.link_up) {
+ sel_phy_idx = EXT_PHY1;
+ /* In case link is SERDES, check if the EXT_PHY2 is the one */
+ if ((bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) &&
+ (bp->link_params.phy[EXT_PHY2].supported & SUPPORTED_FIBRE))
+ sel_phy_idx = EXT_PHY2;
+ } else {
+
+ switch (bnx2x_phy_selection(&bp->link_params)) {
+ case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
+ sel_phy_idx = EXT_PHY1;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
+ sel_phy_idx = EXT_PHY2;
+ break;
+ }
+ }
+
+ return sel_phy_idx;
+
+}
+int bnx2x_get_link_cfg_idx(struct bnx2x *bp)
+{
+ u32 sel_phy_idx = bnx2x_get_cur_phy_idx(bp);
+ /*
+ * The selected actived PHY is always after swapping (in case PHY
+ * swapping is enabled). So when swapping is enabled, we need to reverse
+ * the configuration
+ */
+
+ if (bp->link_params.multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED) {
+ if (sel_phy_idx == EXT_PHY1)
+ sel_phy_idx = EXT_PHY2;
+ else if (sel_phy_idx == EXT_PHY2)
+ sel_phy_idx = EXT_PHY1;
+ }
+ return LINK_CONFIG_IDX(sel_phy_idx);
+}
+
/* called with rtnl_lock */
int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
{
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h
index 1a3545bd8a9..19f8638ed51 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/bnx2x/bnx2x_cmn.h
@@ -1063,6 +1063,8 @@ static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp)
}
#endif
+int bnx2x_get_link_cfg_idx(struct bnx2x *bp);
+
static inline void __storm_memset_struct(struct bnx2x *bp,
u32 addr, size_t size, u32 *data)
{
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index 727fe89ff37..2957353f7c2 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -162,6 +162,33 @@ static const struct {
};
#define BNX2X_NUM_STATS ARRAY_SIZE(bnx2x_stats_arr)
+static int bnx2x_get_port_type(struct bnx2x *bp)
+{
+ int port_type;
+ u32 phy_idx = bnx2x_get_cur_phy_idx(bp);
+ switch (bp->link_params.phy[phy_idx].media_type) {
+ case ETH_PHY_SFP_FIBER:
+ case ETH_PHY_XFP_FIBER:
+ case ETH_PHY_KR:
+ case ETH_PHY_CX4:
+ port_type = PORT_FIBRE;
+ break;
+ case ETH_PHY_DA_TWINAX:
+ port_type = PORT_DA;
+ break;
+ case ETH_PHY_BASE_T:
+ port_type = PORT_TP;
+ break;
+ case ETH_PHY_NOT_PRESENT:
+ port_type = PORT_NONE;
+ break;
+ case ETH_PHY_UNSPECIFIED:
+ default:
+ port_type = PORT_OTHER;
+ break;
+ }
+ return port_type;
+}
static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
@@ -188,12 +215,7 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if (IS_MF(bp))
ethtool_cmd_speed_set(cmd, bnx2x_get_mf_speed(bp));
- if (bp->port.supported[cfg_idx] & SUPPORTED_TP)
- cmd->port = PORT_TP;
- else if (bp->port.supported[cfg_idx] & SUPPORTED_FIBRE)
- cmd->port = PORT_FIBRE;
- else
- BNX2X_ERR("XGXS PHY Failure detected\n");
+ cmd->port = bnx2x_get_port_type(bp);
cmd->phy_address = bp->mdio.prtad;
cmd->transceiver = XCVR_INTERNAL;
diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h
index cdf19fe7c7f..b8b4b2f0b60 100644
--- a/drivers/net/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/bnx2x/bnx2x_hsi.h
@@ -263,7 +263,20 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
#define PORT_HW_CFG_FAULT_MODULE_LED_GPIO2 0x00000200
#define PORT_HW_CFG_FAULT_MODULE_LED_GPIO3 0x00000300
#define PORT_HW_CFG_FAULT_MODULE_LED_DISABLED 0x00000400
- u32 Reserved01[12]; /* 0x158 */
+
+ u32 Reserved01[10]; /* 0x158 */
+
+ u32 aeu_int_mask; /* 0x190 */
+
+ u32 media_type; /* 0x194 */
+#define PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK 0x000000FF
+#define PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT 0
+
+#define PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK 0x0000FF00
+#define PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT 8
+
+#define PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK 0x00FF0000
+#define PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT 16
/* for external PHY, or forced mode or during AN */
u16 xgxs_config_rx[4]; /* 0x198 */
@@ -417,6 +430,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84823 0x00000b00
#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM54640 0x00000c00
#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84833 0x00000d00
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8722 0x00000f00
#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_FAILURE 0x0000fd00
#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_NOT_CONN 0x0000ff00
@@ -453,6 +467,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_SHIFT 24
#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT 0x00000000
#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482 0x01000000
+#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD 0x02000000
#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN 0xff000000
#define PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK 0x00ff0000
@@ -473,6 +488,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC 0x00000a00
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823 0x00000b00
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833 0x00000d00
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722 0x00000f00
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN 0x0000ff00
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c
index 076e11f5769..15b5bc17433 100644
--- a/drivers/net/bnx2x/bnx2x_link.c
+++ b/drivers/net/bnx2x/bnx2x_link.c
@@ -342,7 +342,7 @@ void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
}
-u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
+int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
{
/* ETS disabled configuration*/
struct bnx2x *bp = params->bp;
@@ -464,6 +464,29 @@ void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
/******************************************************************/
/* MAC/PBF section */
/******************************************************************/
+static void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id, u8 port)
+{
+ u32 mode, emac_base;
+ /**
+ * Set clause 45 mode, slow down the MDIO clock to 2.5MHz
+ * (a value of 49==0x31) and make sure that the AUTO poll is off
+ */
+
+ if (CHIP_IS_E2(bp))
+ emac_base = GRCBASE_EMAC0;
+ else
+ emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+ mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+ mode &= ~(EMAC_MDIO_MODE_AUTO_POLL |
+ EMAC_MDIO_MODE_CLOCK_CNT);
+ mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
+
+ mode |= (EMAC_MDIO_MODE_CLAUSE_45);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, mode);
+
+ udelay(40);
+}
+
static void bnx2x_emac_init(struct link_params *params,
struct link_vars *vars)
{
@@ -495,7 +518,7 @@ static void bnx2x_emac_init(struct link_params *params,
}
timeout--;
} while (val & EMAC_MODE_RESET);
-
+ bnx2x_set_mdio_clk(bp, params->chip_id, port);
/* Set mac address */
val = ((params->mac_addr[0] << 8) |
params->mac_addr[1]);
@@ -508,8 +531,8 @@ static void bnx2x_emac_init(struct link_params *params,
EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
}
-static u8 bnx2x_emac_enable(struct link_params *params,
- struct link_vars *vars, u8 lb)
+static int bnx2x_emac_enable(struct link_params *params,
+ struct link_vars *vars, u8 lb)
{
struct bnx2x *bp = params->bp;
u8 port = params->port;
@@ -1002,9 +1025,9 @@ void bnx2x_update_pfc(struct link_params *params,
REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
}
-static u8 bnx2x_bmac1_enable(struct link_params *params,
- struct link_vars *vars,
- u8 is_lb)
+static int bnx2x_bmac1_enable(struct link_params *params,
+ struct link_vars *vars,
+ u8 is_lb)
{
struct bnx2x *bp = params->bp;
u8 port = params->port;
@@ -1066,9 +1089,9 @@ static u8 bnx2x_bmac1_enable(struct link_params *params,
return 0;
}
-static u8 bnx2x_bmac2_enable(struct link_params *params,
- struct link_vars *vars,
- u8 is_lb)
+static int bnx2x_bmac2_enable(struct link_params *params,
+ struct link_vars *vars,
+ u8 is_lb)
{
struct bnx2x *bp = params->bp;
u8 port = params->port;
@@ -1131,11 +1154,12 @@ static u8 bnx2x_bmac2_enable(struct link_params *params,
return 0;
}
-static u8 bnx2x_bmac_enable(struct link_params *params,
- struct link_vars *vars,
- u8 is_lb)
+static int bnx2x_bmac_enable(struct link_params *params,
+ struct link_vars *vars,
+ u8 is_lb)
{
- u8 rc, port = params->port;
+ int rc = 0;
+ u8 port = params->port;
struct bnx2x *bp = params->bp;
u32 val;
/* reset and unreset the BigMac */
@@ -1218,8 +1242,8 @@ static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
}
}
-static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
- u32 line_speed)
+static int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
+ u32 line_speed)
{
struct bnx2x *bp = params->bp;
u8 port = params->port;
@@ -1351,149 +1375,119 @@ static u32 bnx2x_get_emac_base(struct bnx2x *bp,
/******************************************************************/
/* CL45 access functions */
/******************************************************************/
-static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
- u8 devad, u16 reg, u16 val)
+static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
+ u8 devad, u16 reg, u16 *ret_val)
{
- u32 tmp, saved_mode;
- u8 i, rc = 0;
- /*
- * Set clause 45 mode, slow down the MDIO clock to 2.5MHz
- * (a value of 49==0x31) and make sure that the AUTO poll is off
- */
-
- saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
- EMAC_MDIO_MODE_CLOCK_CNT);
- tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
- (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
- REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
- REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- udelay(40);
+ u32 val;
+ u16 i;
+ int rc = 0;
/* address */
-
- tmp = ((phy->addr << 21) | (devad << 16) | reg |
+ val = ((phy->addr << 21) | (devad << 16) | reg |
EMAC_MDIO_COMM_COMMAND_ADDRESS |
EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
for (i = 0; i < 50; i++) {
udelay(10);
- tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
- if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
+ val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
+ if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
udelay(5);
break;
}
}
- if (tmp & EMAC_MDIO_COMM_START_BUSY) {
- DP(NETIF_MSG_LINK, "write phy register failed\n");
+ if (val & EMAC_MDIO_COMM_START_BUSY) {
+ DP(NETIF_MSG_LINK, "read phy register failed\n");
netdev_err(bp->dev, "MDC/MDIO access timeout\n");
+ *ret_val = 0;
rc = -EFAULT;
} else {
/* data */
- tmp = ((phy->addr << 21) | (devad << 16) | val |
- EMAC_MDIO_COMM_COMMAND_WRITE_45 |
+ val = ((phy->addr << 21) | (devad << 16) |
+ EMAC_MDIO_COMM_COMMAND_READ_45 |
EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
for (i = 0; i < 50; i++) {
udelay(10);
- tmp = REG_RD(bp, phy->mdio_ctrl +
+ val = REG_RD(bp, phy->mdio_ctrl +
EMAC_REG_EMAC_MDIO_COMM);
- if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
- udelay(5);
+ if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
+ *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
break;
}
}
- if (tmp & EMAC_MDIO_COMM_START_BUSY) {
- DP(NETIF_MSG_LINK, "write phy register failed\n");
+ if (val & EMAC_MDIO_COMM_START_BUSY) {
+ DP(NETIF_MSG_LINK, "read phy register failed\n");
netdev_err(bp->dev, "MDC/MDIO access timeout\n");
+ *ret_val = 0;