diff options
Diffstat (limited to 'drivers/net/benet')
-rw-r--r-- | drivers/net/benet/be.h | 16 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.c | 96 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.h | 82 | ||||
-rw-r--r-- | drivers/net/benet/be_ethtool.c | 79 | ||||
-rw-r--r-- | drivers/net/benet/be_main.c | 17 |
5 files changed, 270 insertions, 20 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index a80da0e14a5..ce7563175ce 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -35,20 +35,31 @@ #define DRV_VER "2.101.205" #define DRV_NAME "be2net" #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" +#define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" #define OC_NAME "Emulex OneConnect 10Gbps NIC" +#define OC_NAME1 "Emulex OneConnect 10Gbps NIC (be3)" #define DRV_DESC BE_NAME "Driver" #define BE_VENDOR_ID 0x19a2 #define BE_DEVICE_ID1 0x211 +#define BE_DEVICE_ID2 0x221 #define OC_DEVICE_ID1 0x700 #define OC_DEVICE_ID2 0x701 +#define OC_DEVICE_ID3 0x710 static inline char *nic_name(struct pci_dev *pdev) { - if (pdev->device == OC_DEVICE_ID1 || pdev->device == OC_DEVICE_ID2) + switch (pdev->device) { + case OC_DEVICE_ID1: + case OC_DEVICE_ID2: return OC_NAME; - else + case OC_DEVICE_ID3: + return OC_NAME1; + case BE_DEVICE_ID2: + return BE3_NAME; + default: return BE_NAME; + } } /* Number of bytes of an RX frame that are copied to skb->data */ @@ -181,7 +192,6 @@ struct be_drvr_stats { struct be_stats_obj { struct be_drvr_stats drvr_stats; - struct net_device_stats net_stats; struct be_dma_mem cmd; }; diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 28a0eda9268..cc75dd0df0d 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -834,7 +834,7 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) /* Uses synchronous mcc */ int be_cmd_link_status_query(struct be_adapter *adapter, - bool *link_up) + bool *link_up, u8 *mac_speed, u16 *link_speed) { struct be_mcc_wrb *wrb; struct be_cmd_req_link_status *req; @@ -855,8 +855,11 @@ int be_cmd_link_status_query(struct be_adapter *adapter, status = be_mcc_notify_wait(adapter); if (!status) { struct be_cmd_resp_link_status *resp = embedded_payload(wrb); - if (resp->mac_speed != PHY_LINK_SPEED_ZERO) + if (resp->mac_speed != PHY_LINK_SPEED_ZERO) { *link_up = true; + *link_speed = le16_to_cpu(resp->link_speed); + *mac_speed = resp->mac_speed; + } } spin_unlock_bh(&adapter->mcc_lock); @@ -1129,6 +1132,95 @@ int be_cmd_reset_function(struct be_adapter *adapter) return status; } +/* Uses sync mcc */ +int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, + u8 bcn, u8 sts, u8 state) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_enable_disable_beacon *req; + int status; + + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + req = embedded_payload(wrb); + + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); + + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_ENABLE_DISABLE_BEACON, sizeof(*req)); + + req->port_num = port_num; + req->beacon_state = state; + req->beacon_duration = bcn; + req->status_duration = sts; + + status = be_mcc_notify_wait(adapter); + + spin_unlock_bh(&adapter->mcc_lock); + return status; +} + +/* Uses sync mcc */ +int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_get_beacon_state *req; + int status; + + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + req = embedded_payload(wrb); + + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); + + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_GET_BEACON_STATE, sizeof(*req)); + + req->port_num = port_num; + + status = be_mcc_notify_wait(adapter); + if (!status) { + struct be_cmd_resp_get_beacon_state *resp = + embedded_payload(wrb); + *state = resp->beacon_state; + } + + spin_unlock_bh(&adapter->mcc_lock); + return status; +} + +/* Uses sync mcc */ +int be_cmd_read_port_type(struct be_adapter *adapter, u32 port, + u8 *connector) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_port_type *req; + int status; + + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + req = embedded_payload(wrb); + + be_wrb_hdr_prepare(wrb, sizeof(struct be_cmd_resp_port_type), true, 0); + + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_READ_TRANSRECV_DATA, sizeof(*req)); + + req->port = cpu_to_le32(port); + req->page_num = cpu_to_le32(TR_PAGE_A0); + status = be_mcc_notify_wait(adapter); + if (!status) { + struct be_cmd_resp_port_type *resp = embedded_payload(wrb); + *connector = resp->data.connector; + } + + spin_unlock_bh(&adapter->mcc_lock); + return status; +} + int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, u32 flash_type, u32 flash_opcode, u32 buf_size) { diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index e5f9676cf1b..69dc017c814 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -138,6 +138,9 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_NTWK_PMAC_ADD 59 #define OPCODE_COMMON_NTWK_PMAC_DEL 60 #define OPCODE_COMMON_FUNCTION_RESET 61 +#define OPCODE_COMMON_ENABLE_DISABLE_BEACON 69 +#define OPCODE_COMMON_GET_BEACON_STATE 70 +#define OPCODE_COMMON_READ_TRANSRECV_DATA 73 #define OPCODE_ETH_ACPI_CONFIG 2 #define OPCODE_ETH_PROMISCUOUS 3 @@ -633,9 +636,47 @@ struct be_cmd_resp_link_status { u8 mac_fault; u8 mgmt_mac_duplex; u8 mgmt_mac_speed; - u16 rsvd0; + u16 link_speed; + u32 rsvd0; } __packed; +/******************** Port Identification ***************************/ +/* Identifies the type of port attached to NIC */ +struct be_cmd_req_port_type { + struct be_cmd_req_hdr hdr; + u32 page_num; + u32 port; +}; + +enum { + TR_PAGE_A0 = 0xa0, + TR_PAGE_A2 = 0xa2 +}; + +struct be_cmd_resp_port_type { + struct be_cmd_resp_hdr hdr; + u32 page_num; + u32 port; + struct data { + u8 identifier; + u8 identifier_ext; + u8 connector; + u8 transceiver[8]; + u8 rsvd0[3]; + u8 length_km; + u8 length_hm; + u8 length_om1; + u8 length_om2; + u8 length_cu; + u8 length_cu_m; + u8 vendor_name[16]; + u8 rsvd; + u8 vendor_oui[3]; + u8 vendor_pn[16]; + u8 vendor_rev[4]; + } data; +}; + /******************** Get FW Version *******************/ struct be_cmd_req_get_fw_version { struct be_cmd_req_hdr hdr; @@ -699,6 +740,37 @@ struct be_cmd_resp_query_fw_cfg { u32 rsvd[26]; }; +/******************** Port Beacon ***************************/ + +#define BEACON_STATE_ENABLED 0x1 +#define BEACON_STATE_DISABLED 0x0 + +struct be_cmd_req_enable_disable_beacon { + struct be_cmd_req_hdr hdr; + u8 port_num; + u8 beacon_state; + u8 beacon_duration; + u8 status_duration; +} __packed; + +struct be_cmd_resp_enable_disable_beacon { + struct be_cmd_resp_hdr resp_hdr; + u32 rsvd0; +} __packed; + +struct be_cmd_req_get_beacon_state { + struct be_cmd_req_hdr hdr; + u8 port_num; + u8 rsvd0; + u16 rsvd1; +} __packed; + +struct be_cmd_resp_get_beacon_state { + struct be_cmd_resp_hdr resp_hdr; + u8 beacon_state; + u8 rsvd0[3]; +} __packed; + /****************** Firmware Flash ******************/ struct flashrom_params { u32 op_code; @@ -743,7 +815,7 @@ extern int be_cmd_rxq_create(struct be_adapter *adapter, extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, int type); extern int be_cmd_link_status_query(struct be_adapter *adapter, - bool *link_up); + bool *link_up, u8 *mac_speed, u16 *link_speed); extern int be_cmd_reset(struct be_adapter *adapter); extern int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd); @@ -765,6 +837,12 @@ extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *cap); extern int be_cmd_reset_function(struct be_adapter *adapter); extern int be_process_mcc(struct be_adapter *adapter); +extern int be_cmd_set_beacon_state(struct be_adapter *adapter, + u8 port_num, u8 beacon, u8 status, u8 state); +extern int be_cmd_get_beacon_state(struct be_adapter *adapter, + u8 port_num, u32 *state); +extern int be_cmd_read_port_type(struct be_adapter *adapter, u32 port, + u8 *connector); extern int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, u32 flash_oper, u32 flash_opcode, u32 buf_size); diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index cda5bf2fc50..edebce99490 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -234,7 +234,7 @@ be_get_ethtool_stats(struct net_device *netdev, struct be_rxf_stats *rxf_stats = &hw_stats->rxf; struct be_port_rxf_stats *port_stats = &rxf_stats->port[adapter->port_num]; - struct net_device_stats *net_stats = &adapter->stats.net_stats; + struct net_device_stats *net_stats = &netdev->stats; struct be_erx_stats *erx_stats = &hw_stats->erx; void *p = NULL; int i; @@ -281,16 +281,55 @@ be_get_stat_strings(struct net_device *netdev, uint32_t stringset, } } -static int be_get_stats_count(struct net_device *netdev) +static int be_get_sset_count(struct net_device *netdev, int stringset) { - return ETHTOOL_STATS_NUM; + switch (stringset) { + case ETH_SS_STATS: + return ETHTOOL_STATS_NUM; + default: + return -EINVAL; + } } static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { - ecmd->speed = SPEED_10000; + struct be_adapter *adapter = netdev_priv(netdev); + u8 mac_speed = 0, connector = 0; + u16 link_speed = 0; + bool link_up = false; + + be_cmd_link_status_query(adapter, &link_up, &mac_speed, &link_speed); + + /* link_speed is in units of 10 Mbps */ + if (link_speed) { + ecmd->speed = link_speed*10; + } else { + switch (mac_speed) { + case PHY_LINK_SPEED_1GBPS: + ecmd->speed = SPEED_1000; + break; + case PHY_LINK_SPEED_10GBPS: + ecmd->speed = SPEED_10000; + break; + } + } ecmd->duplex = DUPLEX_FULL; ecmd->autoneg = AUTONEG_DISABLE; + ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP); + + be_cmd_read_port_type(adapter, adapter->port_num, &connector); + switch (connector) { + case 7: + ecmd->port = PORT_FIBRE; + break; + default: + ecmd->port = PORT_TP; + break; + } + + ecmd->phy_address = adapter->port_num; + ecmd->transceiver = XCVR_INTERNAL; + return 0; } @@ -333,6 +372,35 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) } static int +be_phys_id(struct net_device *netdev, u32 data) +{ + struct be_adapter *adapter = netdev_priv(netdev); + int status; + u32 cur; + + if (!netif_running(netdev)) + return 0; + + be_cmd_get_beacon_state(adapter, adapter->port_num, &cur); + + if (cur == BEACON_STATE_ENABLED) + return 0; + + if (data < 2) + data = 2; + + status = be_cmd_set_beacon_state(adapter, adapter->port_num, 0, 0, + BEACON_STATE_ENABLED); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(data*HZ); + + status = be_cmd_set_beacon_state(adapter, adapter->port_num, 0, 0, + BEACON_STATE_DISABLED); + + return status; +} + +static int be_do_flash(struct net_device *netdev, struct ethtool_flash *efl) { struct be_adapter *adapter = netdev_priv(netdev); @@ -364,7 +432,8 @@ const struct ethtool_ops be_ethtool_ops = { .get_tso = ethtool_op_get_tso, .set_tso = ethtool_op_set_tso, .get_strings = be_get_stat_strings, - .get_stats_count = be_get_stats_count, + .phys_id = be_phys_id, + .get_sset_count = be_get_sset_count, .get_ethtool_stats = be_get_ethtool_stats, .flash_device = be_do_flash, }; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 1f941f02771..43180dc210a 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -31,8 +31,10 @@ MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, + { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) }, { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) }, { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) }, + { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID3) }, { 0 } }; MODULE_DEVICE_TABLE(pci, be_dev_ids); @@ -141,7 +143,7 @@ void netdev_stats_update(struct be_adapter *adapter) struct be_rxf_stats *rxf_stats = &hw_stats->rxf; struct be_port_rxf_stats *port_stats = &rxf_stats->port[adapter->port_num]; - struct net_device_stats *dev_stats = &adapter->stats.net_stats; + struct net_device_stats *dev_stats = &adapter->netdev->stats; struct be_erx_stats *erx_stats = &hw_stats->erx; dev_stats->rx_packets = port_stats->rx_total_frames; @@ -269,9 +271,7 @@ static void be_rx_eqd_update(struct be_adapter *adapter) static struct net_device_stats *be_get_stats(struct net_device *dev) { - struct be_adapter *adapter = netdev_priv(dev); - - return &adapter->stats.net_stats; + return &dev->stats; } static u32 be_calc_rate(u64 bytes, unsigned long ticks) @@ -758,7 +758,7 @@ static void be_rx_compl_process(struct be_adapter *adapter, if ((adapter->cap == 0x400) && !vtm) vlanf = 0; - skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN); + skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN); if (!skb) { if (net_ratelimit()) dev_warn(&adapter->pdev->dev, "skb alloc failed\n"); @@ -766,8 +766,6 @@ static void be_rx_compl_process(struct be_adapter *adapter, return; } - skb_reserve(skb, NET_IP_ALIGN); - skb_fill_rx_data(adapter, skb, rxcp); if (do_pkt_csum(rxcp, adapter->rx_csum)) @@ -1590,6 +1588,8 @@ static int be_open(struct net_device *netdev) struct be_eq_obj *tx_eq = &adapter->tx_eq; bool link_up; int status; + u8 mac_speed; + u16 link_speed; /* First time posting */ be_post_rx_frags(adapter); @@ -1608,7 +1608,8 @@ static int be_open(struct net_device *netdev) /* Rx compl queue may be in unarmed state; rearm it */ be_cq_notify(adapter, adapter->rx_obj.cq.id, true, 0); - status = be_cmd_link_status_query(adapter, &link_up); + status = be_cmd_link_status_query(adapter, &link_up, &mac_speed, + &link_speed); if (status) return status; be_link_status_update(adapter, link_up); |