Commit 0e1de5d6 authored by Eric Schneider's avatar Eric Schneider Committed by Roland Dreier

RDMA/nes: Add support for SFP+ PHY

This patch enables the iw_nes module for NetEffect RNICs to support
additional PHYs including SFP+ (referred to as ARGUS in the code).
Signed-off-by: default avatarEric Schneider <eric.schneider@neteffect.com>
Signed-off-by: default avatarGlenn Streiff <gstreiff@neteffect.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 37dab411
...@@ -536,8 +536,8 @@ int nes_register_ofa_device(struct nes_ib_device *); ...@@ -536,8 +536,8 @@ int nes_register_ofa_device(struct nes_ib_device *);
int nes_read_eeprom_values(struct nes_device *, struct nes_adapter *); int nes_read_eeprom_values(struct nes_device *, struct nes_adapter *);
void nes_write_1G_phy_reg(struct nes_device *, u8, u8, u16); void nes_write_1G_phy_reg(struct nes_device *, u8, u8, u16);
void nes_read_1G_phy_reg(struct nes_device *, u8, u8, u16 *); void nes_read_1G_phy_reg(struct nes_device *, u8, u8, u16 *);
void nes_write_10G_phy_reg(struct nes_device *, u16, u8, u16); void nes_write_10G_phy_reg(struct nes_device *, u16, u8, u16, u16);
void nes_read_10G_phy_reg(struct nes_device *, u16, u8); void nes_read_10G_phy_reg(struct nes_device *, u8, u8, u16);
struct nes_cqp_request *nes_get_cqp_request(struct nes_device *); struct nes_cqp_request *nes_get_cqp_request(struct nes_device *);
void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *, int); void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *, int);
int nes_arp_table(struct nes_device *, u32, u8 *, u32); int nes_arp_table(struct nes_device *, u32, u8 *, u32);
......
This diff is collapsed.
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
#define NES_PHY_TYPE_1G 2 #define NES_PHY_TYPE_1G 2
#define NES_PHY_TYPE_IRIS 3 #define NES_PHY_TYPE_IRIS 3
#define NES_PHY_TYPE_ARGUS 4
#define NES_PHY_TYPE_PUMA_1G 5
#define NES_PHY_TYPE_PUMA_10G 6 #define NES_PHY_TYPE_PUMA_10G 6
#define NES_MULTICAST_PF_MAX 8 #define NES_MULTICAST_PF_MAX 8
......
...@@ -1377,21 +1377,29 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd ...@@ -1377,21 +1377,29 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd
et_cmd->duplex = DUPLEX_FULL; et_cmd->duplex = DUPLEX_FULL;
et_cmd->port = PORT_MII; et_cmd->port = PORT_MII;
if (nesadapter->OneG_Mode) { if (nesadapter->OneG_Mode) {
et_cmd->supported = SUPPORTED_1000baseT_Full|SUPPORTED_Autoneg;
et_cmd->advertising = ADVERTISED_1000baseT_Full|ADVERTISED_Autoneg;
et_cmd->speed = SPEED_1000; et_cmd->speed = SPEED_1000;
nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], if (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) {
&phy_data); et_cmd->supported = SUPPORTED_1000baseT_Full;
if (phy_data&0x1000) { et_cmd->advertising = ADVERTISED_1000baseT_Full;
et_cmd->autoneg = AUTONEG_ENABLE; et_cmd->autoneg = AUTONEG_DISABLE;
et_cmd->transceiver = XCVR_INTERNAL;
et_cmd->phy_address = nesdev->mac_index;
} else { } else {
et_cmd->supported = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg;
et_cmd->advertising = ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg;
nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], &phy_data);
if (phy_data & 0x1000)
et_cmd->autoneg = AUTONEG_ENABLE;
else
et_cmd->autoneg = AUTONEG_DISABLE; et_cmd->autoneg = AUTONEG_DISABLE;
}
et_cmd->transceiver = XCVR_EXTERNAL; et_cmd->transceiver = XCVR_EXTERNAL;
et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index];
}
} else { } else {
if (nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) { if ((nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) ||
(nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_ARGUS)) {
et_cmd->transceiver = XCVR_EXTERNAL; et_cmd->transceiver = XCVR_EXTERNAL;
et_cmd->port = PORT_FIBRE; et_cmd->port = PORT_FIBRE;
et_cmd->supported = SUPPORTED_FIBRE; et_cmd->supported = SUPPORTED_FIBRE;
...@@ -1422,7 +1430,8 @@ static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd ...@@ -1422,7 +1430,8 @@ static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd
struct nes_adapter *nesadapter = nesdev->nesadapter; struct nes_adapter *nesadapter = nesdev->nesadapter;
u16 phy_data; u16 phy_data;
if (nesadapter->OneG_Mode) { if ((nesadapter->OneG_Mode) &&
(nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_PUMA_1G)) {
nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index],
&phy_data); &phy_data);
if (et_cmd->autoneg) { if (et_cmd->autoneg) {
...@@ -1615,27 +1624,34 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, ...@@ -1615,27 +1624,34 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]); list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]);
if ((nesdev->netdev_count == 0) && if ((nesdev->netdev_count == 0) &&
(PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) { ((PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index) ||
nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n", ((nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) &&
NES_IDX_PHY_PCS_CONTROL_STATUS0+(0x200*(nesvnic->logical_port&1))); (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) ||
((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) {
/*
* nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n",
* NES_IDX_PHY_PCS_CONTROL_STATUS0 + (0x200 * (nesvnic->logical_port & 1)));
*/
u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
(0x200*(nesvnic->logical_port&1))); (0x200 * (nesdev->mac_index & 1)));
if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_PUMA_1G) {
u32temp |= 0x00200000; u32temp |= 0x00200000;
nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
(0x200*(nesvnic->logical_port&1)), u32temp); (0x200 * (nesdev->mac_index & 1)), u32temp);
}
u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
(0x200*(nesvnic->logical_port&1)) ); (0x200 * (nesdev->mac_index & 1)));
if ((u32temp&0x0f1f0000) == 0x0f0f0000) { if ((u32temp&0x0f1f0000) == 0x0f0f0000) {
if (nesdev->nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) { if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) {
nes_init_phy(nesdev); nes_init_phy(nesdev);
nes_read_10G_phy_reg(nesdev, 1, nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1);
nesdev->nesadapter->phy_index[nesvnic->logical_port]);
temp_phy_data = (u16)nes_read_indexed(nesdev, temp_phy_data = (u16)nes_read_indexed(nesdev,
NES_IDX_MAC_MDIO_CONTROL); NES_IDX_MAC_MDIO_CONTROL);
u32temp = 20; u32temp = 20;
do { do {
nes_read_10G_phy_reg(nesdev, 1, nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1);
nesdev->nesadapter->phy_index[nesvnic->logical_port]);
phy_data = (u16)nes_read_indexed(nesdev, phy_data = (u16)nes_read_indexed(nesdev,
NES_IDX_MAC_MDIO_CONTROL); NES_IDX_MAC_MDIO_CONTROL);
if ((phy_data == temp_phy_data) || (!(--u32temp))) if ((phy_data == temp_phy_data) || (!(--u32temp)))
...@@ -1652,6 +1668,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, ...@@ -1652,6 +1668,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); nes_debug(NES_DBG_INIT, "The Link is UP!!.\n");
nesvnic->linkup = 1; nesvnic->linkup = 1;
} }
} else if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) {
nes_debug(NES_DBG_INIT, "mac_index=%d, logical_port=%d, u32temp=0x%04X, PCI_FUNC=%d\n",
nesdev->mac_index, nesvnic->logical_port, u32temp, PCI_FUNC(nesdev->pcidev->devfn));
if (((nesdev->mac_index < 2) && ((u32temp&0x01010000) == 0x01010000)) ||
((nesdev->mac_index > 1) && ((u32temp&0x02020000) == 0x02020000))) {
nes_debug(NES_DBG_INIT, "The Link is UP!!.\n");
nesvnic->linkup = 1;
}
} }
/* clear the MAC interrupt status, assumes direct logical to physical mapping */ /* clear the MAC interrupt status, assumes direct logical to physical mapping */
u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index));
......
...@@ -444,15 +444,13 @@ void nes_read_1G_phy_reg(struct nes_device *nesdev, u8 phy_reg, u8 phy_addr, u16 ...@@ -444,15 +444,13 @@ void nes_read_1G_phy_reg(struct nes_device *nesdev, u8 phy_reg, u8 phy_addr, u16
/** /**
* nes_write_10G_phy_reg * nes_write_10G_phy_reg
*/ */
void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_addr, u8 dev_addr, u16 phy_reg,
u8 phy_addr, u16 data) u16 data)
{ {
u32 dev_addr;
u32 port_addr; u32 port_addr;
u32 u32temp; u32 u32temp;
u32 counter; u32 counter;
dev_addr = 1;
port_addr = phy_addr; port_addr = phy_addr;
/* set address */ /* set address */
...@@ -492,14 +490,12 @@ void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, ...@@ -492,14 +490,12 @@ void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg,
* This routine only issues the read, the data must be read * This routine only issues the read, the data must be read
* separately. * separately.
*/ */
void nes_read_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, u8 phy_addr) void nes_read_10G_phy_reg(struct nes_device *nesdev, u8 phy_addr, u8 dev_addr, u16 phy_reg)
{ {
u32 dev_addr;
u32 port_addr; u32 port_addr;
u32 u32temp; u32 u32temp;
u32 counter; u32 counter;
dev_addr = 1;
port_addr = phy_addr; port_addr = phy_addr;
/* set address */ /* set address */
......
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