diff options
Diffstat (limited to 'drivers/net/ethernet/emulex/benet/be_cmds.c')
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.c | 187 |
1 files changed, 131 insertions, 56 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 24c80d1d70b..25d3290b8ca 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2011 Emulex + * Copyright (C) 2005 - 2013 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -718,10 +718,8 @@ static struct be_mcc_wrb *wrb_from_mccq(struct be_adapter *adapter) if (!mccq->created) return NULL; - if (atomic_read(&mccq->used) >= mccq->len) { - dev_err(&adapter->pdev->dev, "Out of MCCQ wrbs\n"); + if (atomic_read(&mccq->used) >= mccq->len) return NULL; - } wrb = queue_head_node(mccq); queue_head_inc(mccq); @@ -1127,15 +1125,14 @@ int be_cmd_mccq_create(struct be_adapter *adapter, return status; } -int be_cmd_txq_create(struct be_adapter *adapter, - struct be_queue_info *txq, - struct be_queue_info *cq) +int be_cmd_txq_create(struct be_adapter *adapter, struct be_tx_obj *txo) { struct be_mcc_wrb *wrb; struct be_cmd_req_eth_tx_create *req; + struct be_queue_info *txq = &txo->q; + struct be_queue_info *cq = &txo->cq; struct be_dma_mem *q_mem = &txq->dma_mem; - void *ctxt; - int status; + int status, ver = 0; spin_lock_bh(&adapter->mcc_lock); @@ -1146,34 +1143,37 @@ int be_cmd_txq_create(struct be_adapter *adapter, } req = embedded_payload(wrb); - ctxt = &req->context; be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_TX_CREATE, sizeof(*req), wrb, NULL); if (lancer_chip(adapter)) { req->hdr.version = 1; - AMAP_SET_BITS(struct amap_tx_context, if_id, ctxt, - adapter->if_handle); + req->if_id = cpu_to_le16(adapter->if_handle); + } else if (BEx_chip(adapter)) { + if (adapter->function_caps & BE_FUNCTION_CAPS_SUPER_NIC) + req->hdr.version = 2; + } else { /* For SH */ + req->hdr.version = 2; } req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); req->ulp_num = BE_ULP1_NUM; req->type = BE_ETH_TX_RING_TYPE_STANDARD; - - AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt, - be_encoded_q_len(txq->len)); - AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1); - AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id); - - be_dws_cpu_to_le(ctxt, sizeof(req->context)); - + req->cq_id = cpu_to_le16(cq->id); + req->queue_size = be_encoded_q_len(txq->len); be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); + ver = req->hdr.version; + status = be_mcc_notify_wait(adapter); if (!status) { struct be_cmd_resp_eth_tx_create *resp = embedded_payload(wrb); txq->id = le16_to_cpu(resp->cid); + if (ver == 2) + txo->db_offset = le32_to_cpu(resp->db_offset); + else + txo->db_offset = DB_TXULP1_OFFSET; txq->created = true; } @@ -1866,7 +1866,7 @@ err: /* Uses mbox */ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, - u32 *mode, u32 *caps) + u32 *mode, u32 *caps, u16 *asic_rev) { struct be_mcc_wrb *wrb; struct be_cmd_req_query_fw_cfg *req; @@ -1887,6 +1887,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, *port_num = le32_to_cpu(resp->phys_port); *mode = le32_to_cpu(resp->function_mode); *caps = le32_to_cpu(resp->function_caps); + *asic_rev = le32_to_cpu(resp->asic_revision) & 0xFF; } mutex_unlock(&adapter->mbox_lock); @@ -1929,7 +1930,8 @@ int be_cmd_reset_function(struct be_adapter *adapter) return status; } -int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size) +int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, + u32 rss_hash_opts, u16 table_size) { struct be_mcc_wrb *wrb; struct be_cmd_req_rss_config *req; @@ -1948,16 +1950,12 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size) OPCODE_ETH_RSS_CONFIG, sizeof(*req), wrb, NULL); req->if_id = cpu_to_le32(adapter->if_handle); - req->enable_rss = cpu_to_le16(RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV4 | - RSS_ENABLE_TCP_IPV6 | RSS_ENABLE_IPV6); + req->enable_rss = cpu_to_le16(rss_hash_opts); + req->cpu_table_size_log2 = cpu_to_le16(fls(table_size) - 1); - if (lancer_chip(adapter) || skyhawk_chip(adapter)) { + if (lancer_chip(adapter) || skyhawk_chip(adapter)) req->hdr.version = 1; - req->enable_rss |= cpu_to_le16(RSS_ENABLE_UDP_IPV4 | - RSS_ENABLE_UDP_IPV6); - } - req->cpu_table_size_log2 = cpu_to_le16(fls(table_size) - 1); memcpy(req->cpu_table, rsstable, table_size); memcpy(req->hash, myhash, sizeof(myhash)); be_dws_cpu_to_le(req->hash, sizeof(req->hash)); @@ -2375,7 +2373,6 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter, { struct be_mcc_wrb *wrb; struct be_cmd_req_seeprom_read *req; - struct be_sge *sge; int status; spin_lock_bh(&adapter->mcc_lock); @@ -2386,7 +2383,6 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter, goto err; } req = nonemb_cmd->va; - sge = nonembedded_sgl(wrb); be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_SEEPROM_READ, sizeof(*req), wrb, @@ -2701,10 +2697,8 @@ int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, cmd.size = sizeof(struct be_cmd_req_set_mac_list); cmd.va = dma_alloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma, GFP_KERNEL); - if (!cmd.va) { - dev_err(&adapter->pdev->dev, "Memory alloc failure\n"); + if (!cmd.va) return -ENOMEM; - } spin_lock_bh(&adapter->mcc_lock); @@ -2978,14 +2972,15 @@ static struct be_nic_resource_desc *be_get_nic_desc(u8 *buf, u32 desc_count, int i; for (i = 0; i < desc_count; i++) { - desc->desc_len = RESOURCE_DESC_SIZE; + desc->desc_len = desc->desc_len ? : RESOURCE_DESC_SIZE; if (((void *)desc + desc->desc_len) > (void *)(buf + max_buf_size)) { desc = NULL; break; } - if (desc->desc_type == NIC_RESOURCE_DESC_TYPE_ID) + if (desc->desc_type == NIC_RESOURCE_DESC_TYPE_V0 || + desc->desc_type == NIC_RESOURCE_DESC_TYPE_V1) break; desc = (void *)desc + desc->desc_len; @@ -3030,6 +3025,9 @@ int be_cmd_get_func_config(struct be_adapter *adapter) OPCODE_COMMON_GET_FUNC_CONFIG, cmd.size, wrb, &cmd); + if (skyhawk_chip(adapter)) + req->hdr.version = 1; + status = be_mbox_notify_wait(adapter); if (!status) { struct be_cmd_resp_get_func_config *resp = cmd.va; @@ -3061,23 +3059,41 @@ err: return status; } - /* Uses sync mcc */ -int be_cmd_get_profile_config(struct be_adapter *adapter, u32 *cap_flags, - u8 domain) +/* Uses mbox */ +int be_cmd_get_profile_config_mbox(struct be_adapter *adapter, + u8 domain, struct be_dma_mem *cmd) { struct be_mcc_wrb *wrb; struct be_cmd_req_get_profile_config *req; int status; - struct be_dma_mem cmd; - memset(&cmd, 0, sizeof(struct be_dma_mem)); - cmd.size = sizeof(struct be_cmd_resp_get_profile_config); - cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, - &cmd.dma); - if (!cmd.va) { - dev_err(&adapter->pdev->dev, "Memory alloc failure\n"); - return -ENOMEM; - } + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; + wrb = wrb_from_mbox(adapter); + + req = cmd->va; + be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_GET_PROFILE_CONFIG, + cmd->size, wrb, cmd); + + req->type = ACTIVE_PROFILE_TYPE; + req->hdr.domain = domain; + if (!lancer_chip(adapter)) + req->hdr.version = 1; + + status = be_mbox_notify_wait(adapter); + + mutex_unlock(&adapter->mbox_lock); + return status; +} + +/* Uses sync mcc */ +int be_cmd_get_profile_config_mccq(struct be_adapter *adapter, + u8 domain, struct be_dma_mem *cmd) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_get_profile_config *req; + int status; spin_lock_bh(&adapter->mcc_lock); @@ -3087,16 +3103,47 @@ int be_cmd_get_profile_config(struct be_adapter *adapter, u32 *cap_flags, goto err; } - req = cmd.va; - + req = cmd->va; be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_GET_PROFILE_CONFIG, - cmd.size, wrb, &cmd); + cmd->size, wrb, cmd); req->type = ACTIVE_PROFILE_TYPE; req->hdr.domain = domain; + if (!lancer_chip(adapter)) + req->hdr.version = 1; status = be_mcc_notify_wait(adapter); + +err: + spin_unlock_bh(&adapter->mcc_lock); + return status; +} + +/* Uses sync mcc, if MCCQ is already created otherwise mbox */ +int be_cmd_get_profile_config(struct be_adapter *adapter, u32 *cap_flags, + u16 *txq_count, u8 domain) +{ + struct be_queue_info *mccq = &adapter->mcc_obj.q; + struct be_dma_mem cmd; + int status; + + memset(&cmd, 0, sizeof(struct be_dma_mem)); + if (!lancer_chip(adapter)) + cmd.size = sizeof(struct be_cmd_resp_get_profile_config_v1); + else + cmd.size = sizeof(struct be_cmd_resp_get_profile_config); + cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, + &cmd.dma); + if (!cmd.va) { + dev_err(&adapter->pdev->dev, "Memory alloc failure\n"); + return -ENOMEM; + } + + if (!mccq->created) + status = be_cmd_get_profile_config_mbox(adapter, domain, &cmd); + else + status = be_cmd_get_profile_config_mccq(adapter, domain, &cmd); if (!status) { struct be_cmd_resp_get_profile_config *resp = cmd.va; u32 desc_count = le32_to_cpu(resp->desc_count); @@ -3109,12 +3156,15 @@ int be_cmd_get_profile_config(struct be_adapter *adapter, u32 *cap_flags, status = -EINVAL; goto err; } - *cap_flags = le32_to_cpu(desc->cap_flags); + if (cap_flags) + *cap_flags = le32_to_cpu(desc->cap_flags); + if (txq_count) + *txq_count = le32_to_cpu(desc->txq_count); } err: - spin_unlock_bh(&adapter->mcc_lock); - pci_free_consistent(adapter->pdev, cmd.size, - cmd.va, cmd.dma); + if (cmd.va) + pci_free_consistent(adapter->pdev, cmd.size, + cmd.va, cmd.dma); return status; } @@ -3143,7 +3193,7 @@ int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps, req->hdr.domain = domain; req->desc_count = cpu_to_le32(1); - req->nic_desc.desc_type = NIC_RESOURCE_DESC_TYPE_ID; + req->nic_desc.desc_type = NIC_RESOURCE_DESC_TYPE_V0; req->nic_desc.desc_len = RESOURCE_DESC_SIZE; req->nic_desc.flags = (1 << QUN) | (1 << IMM) | (1 << NOSV); req->nic_desc.pf_num = adapter->pf_number; @@ -3240,6 +3290,31 @@ err: return status; } +int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_intr_set *req; + int status; + + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; + + wrb = wrb_from_mbox(adapter); + + req = embedded_payload(wrb); + + be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_SET_INTERRUPT_ENABLE, sizeof(*req), + wrb, NULL); + + req->intr_enabled = intr_enable; + + status = be_mbox_notify_wait(adapter); + + mutex_unlock(&adapter->mbox_lock); + return status; +} + int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload, int wrb_payload_size, u16 *cmd_status, u16 *ext_status) { |