提交 e67c958c 编写于 作者: C Chiqijun 提交者: Yang Yingliang

net/hinic: Support doorbell BAR size of 256K in SDI mode

driver inclusion
category: bugfix
bugzilla: 4472

-----------------------------------------------------------------------

A VF in 1822 needs to consume 1M + 48k of VF space, and each PCI-bridge
reserves io memory of 4M, so after hot-plugging more than 3 network cards,
there will be insufficient bar space. To solve this problem, modify the
bar space size in the 1822 SDI bare metal and virtual machine scenarios.
Signed-off-by: NChiqijun <chiqijun@huawei.com>
Reviewed-by: NLuoshaokai <luoshaokai@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 470c344d
...@@ -125,6 +125,10 @@ ...@@ -125,6 +125,10 @@
#define HINIC_CEQ_CONS_IDX_0_ADDR_BASE 0x1008 #define HINIC_CEQ_CONS_IDX_0_ADDR_BASE 0x1008
#define HINIC_CEQ_CONS_IDX_1_ADDR_BASE 0x100C #define HINIC_CEQ_CONS_IDX_1_ADDR_BASE 0x100C
/* For multi-host mgmt
* CEQ_CTRL_0_ADDR: bit26~29: uP write vf mode is normal(0x0),bmgw(0x1),
* vmgw(0x2)
*/
#define HINIC_CSR_CEQ_CTRL_0_ADDR(idx) \ #define HINIC_CSR_CEQ_CTRL_0_ADDR(idx) \
(HINIC_CEQ_CTRL_0_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE) (HINIC_CEQ_CTRL_0_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE)
......
...@@ -393,6 +393,12 @@ struct acl_service_cap { ...@@ -393,6 +393,12 @@ struct acl_service_cap {
u32 scqc_sz; /* 64B */ u32 scqc_sz; /* 64B */
}; };
enum hinic_chip_mode {
CHIP_MODE_NORMAL,
CHIP_MODE_BMGW,
CHIP_MODE_VMGW,
};
bool hinic_support_nic(void *hwdev, struct nic_service_cap *cap); bool hinic_support_nic(void *hwdev, struct nic_service_cap *cap);
bool hinic_support_roce(void *hwdev, struct rdma_service_cap *cap); bool hinic_support_roce(void *hwdev, struct rdma_service_cap *cap);
bool hinic_support_fcoe(void *hwdev, struct fcoe_service_cap *cap); bool hinic_support_fcoe(void *hwdev, struct fcoe_service_cap *cap);
...@@ -553,4 +559,5 @@ u16 hinic_pf_id_of_vf_hw(void *hwdev); ...@@ -553,4 +559,5 @@ u16 hinic_pf_id_of_vf_hw(void *hwdev);
u16 hinic_global_func_id_hw(void *hwdev); u16 hinic_global_func_id_hw(void *hwdev);
bool hinic_func_for_pt(void *hwdev); bool hinic_func_for_pt(void *hwdev);
bool hinic_func_for_hwpt(void *hwdev); bool hinic_func_for_hwpt(void *hwdev);
u32 hinic_get_db_size(void *cfg_reg_base, enum hinic_chip_mode *chip_mode);
#endif #endif
...@@ -240,12 +240,6 @@ struct hinic_heartbeat_enhanced { ...@@ -240,12 +240,6 @@ struct hinic_heartbeat_enhanced {
#define HINIC_BOARD_TYPE_MULTI_HOST_ETH_25GE 12 #define HINIC_BOARD_TYPE_MULTI_HOST_ETH_25GE 12
enum hinic_chip_mode {
CHIP_MODE_NORMAL,
CHIP_MODE_BMGW,
CHIP_MODE_VMGW,
};
/* new version of roce qp not limited by power of 2 */ /* new version of roce qp not limited by power of 2 */
#define HINIC_CMD_VER_ROCE_QP 1 #define HINIC_CMD_VER_ROCE_QP 1
/* new version for add function id in multi-host */ /* new version for add function id in multi-host */
......
...@@ -283,14 +283,19 @@ static void set_mpf(struct hinic_hwif *hwif) ...@@ -283,14 +283,19 @@ static void set_mpf(struct hinic_hwif *hwif)
hinic_hwif_write_reg(hwif, addr, val); hinic_hwif_write_reg(hwif, addr, val);
} }
static void init_db_area_idx(struct hinic_free_db_area *free_db_area) static void init_db_area_idx(struct hinic_hwif *hwif)
{ {
struct hinic_free_db_area *free_db_area;
u32 db_max_areas;
u32 i; u32 i;
for (i = 0; i < HINIC_DB_MAX_AREAS; i++) free_db_area = &hwif->free_db_area;
db_max_areas = hwif->db_size / HINIC_DB_PAGE_SIZE;
for (i = 0; i < db_max_areas; i++)
free_db_area->db_idx[i] = i; free_db_area->db_idx[i] = i;
free_db_area->num_free = HINIC_DB_MAX_AREAS; free_db_area->num_free = db_max_areas;
spin_lock_init(&free_db_area->idx_lock); spin_lock_init(&free_db_area->idx_lock);
} }
...@@ -298,6 +303,7 @@ static void init_db_area_idx(struct hinic_free_db_area *free_db_area) ...@@ -298,6 +303,7 @@ static void init_db_area_idx(struct hinic_free_db_area *free_db_area)
static int get_db_idx(struct hinic_hwif *hwif, u32 *idx) static int get_db_idx(struct hinic_hwif *hwif, u32 *idx)
{ {
struct hinic_free_db_area *free_db_area = &hwif->free_db_area; struct hinic_free_db_area *free_db_area = &hwif->free_db_area;
u32 db_max_areas = hwif->db_size / HINIC_DB_PAGE_SIZE;
u32 pos; u32 pos;
u32 pg_idx; u32 pg_idx;
...@@ -312,14 +318,14 @@ static int get_db_idx(struct hinic_hwif *hwif, u32 *idx) ...@@ -312,14 +318,14 @@ static int get_db_idx(struct hinic_hwif *hwif, u32 *idx)
free_db_area->num_free--; free_db_area->num_free--;
pos = free_db_area->alloc_pos++; pos = free_db_area->alloc_pos++;
pos &= HINIC_DB_MAX_AREAS - 1; pos &= db_max_areas - 1;
pg_idx = free_db_area->db_idx[pos]; pg_idx = free_db_area->db_idx[pos];
free_db_area->db_idx[pos] = 0xFFFFFFFF; free_db_area->db_idx[pos] = 0xFFFFFFFF;
/* pg_idx out of range */ /* pg_idx out of range */
if (pg_idx >= HINIC_DB_MAX_AREAS) if (pg_idx >= db_max_areas)
goto retry; goto retry;
spin_unlock(&free_db_area->idx_lock); spin_unlock(&free_db_area->idx_lock);
...@@ -332,15 +338,16 @@ static int get_db_idx(struct hinic_hwif *hwif, u32 *idx) ...@@ -332,15 +338,16 @@ static int get_db_idx(struct hinic_hwif *hwif, u32 *idx)
static void free_db_idx(struct hinic_hwif *hwif, u32 idx) static void free_db_idx(struct hinic_hwif *hwif, u32 idx)
{ {
struct hinic_free_db_area *free_db_area = &hwif->free_db_area; struct hinic_free_db_area *free_db_area = &hwif->free_db_area;
u32 db_max_areas = hwif->db_size / HINIC_DB_PAGE_SIZE;
u32 pos; u32 pos;
if (idx >= HINIC_DB_MAX_AREAS) if (idx >= db_max_areas)
return; return;
spin_lock(&free_db_area->idx_lock); spin_lock(&free_db_area->idx_lock);
pos = free_db_area->return_pos++; pos = free_db_area->return_pos++;
pos &= HINIC_DB_MAX_AREAS - 1; pos &= db_max_areas - 1;
free_db_area->db_idx[pos] = idx; free_db_area->db_idx[pos] = idx;
...@@ -386,7 +393,7 @@ int hinic_alloc_db_addr(void *hwdev, void __iomem **db_base, ...@@ -386,7 +393,7 @@ int hinic_alloc_db_addr(void *hwdev, void __iomem **db_base,
*db_base = hwif->db_base + idx * HINIC_DB_PAGE_SIZE; *db_base = hwif->db_base + idx * HINIC_DB_PAGE_SIZE;
if (!dwqe_base) if (!dwqe_base || hwif->chip_mode != CHIP_MODE_NORMAL)
return 0; return 0;
offset = ((u64)idx) << PAGE_SHIFT; offset = ((u64)idx) << PAGE_SHIFT;
...@@ -433,7 +440,9 @@ int hinic_alloc_db_phy_addr(void *hwdev, u64 *db_base, u64 *dwqe_base) ...@@ -433,7 +440,9 @@ int hinic_alloc_db_phy_addr(void *hwdev, u64 *db_base, u64 *dwqe_base)
return -EFAULT; return -EFAULT;
*db_base = hwif->db_base_phy + idx * HINIC_DB_PAGE_SIZE; *db_base = hwif->db_base_phy + idx * HINIC_DB_PAGE_SIZE;
*dwqe_base = *db_base + HINIC_DB_DWQE_SIZE;
if (hwif->chip_mode == CHIP_MODE_NORMAL)
*dwqe_base = *db_base + HINIC_DB_DWQE_SIZE;
return 0; return 0;
} }
...@@ -559,7 +568,13 @@ int hinic_init_hwif(struct hinic_hwdev *hwdev, void *cfg_reg_base, ...@@ -559,7 +568,13 @@ int hinic_init_hwif(struct hinic_hwdev *hwdev, void *cfg_reg_base,
hwif->db_base_phy = db_base_phy; hwif->db_base_phy = db_base_phy;
hwif->db_base = db_base; hwif->db_base = db_base;
hwif->dwqe_mapping = dwqe_mapping; hwif->dwqe_mapping = dwqe_mapping;
init_db_area_idx(&hwif->free_db_area);
hwif->db_size = hinic_get_db_size(cfg_reg_base, &hwif->chip_mode);
sdk_info(hwdev->dev_hdl, "Doorbell size: 0x%x, chip mode: %d\n",
hwif->db_size, hwif->chip_mode);
init_db_area_idx(hwif);
err = wait_hwif_ready(hwdev); err = wait_hwif_ready(hwdev);
if (err) { if (err) {
...@@ -924,3 +939,43 @@ u8 hinic_ppf_idx(void *hwdev) ...@@ -924,3 +939,43 @@ u8 hinic_ppf_idx(void *hwdev)
return hwif->attr.ppf_idx; return hwif->attr.ppf_idx;
} }
EXPORT_SYMBOL(hinic_ppf_idx); EXPORT_SYMBOL(hinic_ppf_idx);
#define CEQ_CTRL_0_CHIP_MODE_SHIFT 26
#define CEQ_CTRL_0_CHIP_MODE_MASK 0xFU
#define CEQ_CTRL_0_GET(val, member) \
(((val) >> CEQ_CTRL_0_##member##_SHIFT) & \
CEQ_CTRL_0_##member##_MASK)
/**
* hinic_get_db_size - get db size ceq ctrl: bit26~29: uP write vf mode is
* normal(0x0), bmgw(0x1) or vmgw(0x2) and normal mode db size is 512k,
* bmgw or vmgw mode db size is 256k
* @cfg_reg_base: pointer to cfg_reg_base
* @chip_mode: pointer to chip_mode
*/
u32 hinic_get_db_size(void *cfg_reg_base, enum hinic_chip_mode *chip_mode)
{
u32 attr0, ctrl0;
attr0 = be32_to_cpu(readl((u8 __iomem *)cfg_reg_base +
HINIC_CSR_FUNC_ATTR0_ADDR));
/* PF is always normal mode & db size is 512K */
if (HINIC_AF0_GET(attr0, FUNC_TYPE) != TYPE_VF) {
*chip_mode = CHIP_MODE_NORMAL;
return HINIC_DB_DWQE_SIZE;
}
ctrl0 = be32_to_cpu(readl((u8 __iomem *)cfg_reg_base +
HINIC_CSR_CEQ_CTRL_0_ADDR(0)));
*chip_mode = CEQ_CTRL_0_GET(ctrl0, CHIP_MODE);
switch (*chip_mode) {
case CHIP_MODE_VMGW:
case CHIP_MODE_BMGW:
return HINIC_GW_VF_DB_SIZE;
default:
return HINIC_DB_DWQE_SIZE;
}
}
...@@ -64,6 +64,8 @@ struct hinic_hwif { ...@@ -64,6 +64,8 @@ struct hinic_hwif {
struct hinic_func_attr attr; struct hinic_func_attr attr;
void *pdev; void *pdev;
enum hinic_chip_mode chip_mode;
u32 db_size;
}; };
struct hinic_dma_addr_align { struct hinic_dma_addr_align {
......
...@@ -43,8 +43,6 @@ ...@@ -43,8 +43,6 @@
#define HINIC_PCI_DB_BAR 4 #define HINIC_PCI_DB_BAR 4
#define HINIC_PCI_VENDOR_ID 0x19e5 #define HINIC_PCI_VENDOR_ID 0x19e5
#define HINIC_DB_DWQE_SIZE 0x00080000
#define SELF_TEST_BAR_ADDR_OFFSET 0x883c #define SELF_TEST_BAR_ADDR_OFFSET 0x883c
#define HINIC_SECOND_BASE (1000) #define HINIC_SECOND_BASE (1000)
...@@ -131,6 +129,7 @@ struct hinic_pcidev { ...@@ -131,6 +129,7 @@ struct hinic_pcidev {
struct work_struct slave_nic_work; struct work_struct slave_nic_work;
struct workqueue_struct *slave_nic_init_workq; struct workqueue_struct *slave_nic_init_workq;
struct delayed_work slave_nic_init_dwork; struct delayed_work slave_nic_init_dwork;
enum hinic_chip_mode chip_mode;
bool nic_cur_enable; bool nic_cur_enable;
bool nic_des_enable; bool nic_des_enable;
}; };
...@@ -1836,6 +1835,7 @@ void hinic_event_process(void *adapter, struct hinic_event_info *event) ...@@ -1836,6 +1835,7 @@ void hinic_event_process(void *adapter, struct hinic_event_info *event)
static int mapping_bar(struct pci_dev *pdev, struct hinic_pcidev *pci_adapter) static int mapping_bar(struct pci_dev *pdev, struct hinic_pcidev *pci_adapter)
{ {
u32 db_dwqe_size;
u64 dwqe_addr; u64 dwqe_addr;
pci_adapter->cfg_reg_base = pci_adapter->cfg_reg_base =
...@@ -1854,19 +1854,25 @@ static int mapping_bar(struct pci_dev *pdev, struct hinic_pcidev *pci_adapter) ...@@ -1854,19 +1854,25 @@ static int mapping_bar(struct pci_dev *pdev, struct hinic_pcidev *pci_adapter)
goto map_intr_bar_err; goto map_intr_bar_err;
} }
db_dwqe_size = hinic_get_db_size(pci_adapter->cfg_reg_base,
&pci_adapter->chip_mode);
pci_adapter->db_base_phy = pci_resource_start(pdev, HINIC_PCI_DB_BAR); pci_adapter->db_base_phy = pci_resource_start(pdev, HINIC_PCI_DB_BAR);
pci_adapter->db_base = ioremap(pci_adapter->db_base_phy, pci_adapter->db_base = ioremap(pci_adapter->db_base_phy,
HINIC_DB_DWQE_SIZE); db_dwqe_size);
if (!pci_adapter->db_base) { if (!pci_adapter->db_base) {
sdk_err(&pci_adapter->pcidev->dev, sdk_err(&pci_adapter->pcidev->dev,
"Failed to map doorbell regs\n"); "Failed to map doorbell regs\n");
goto map_db_err; goto map_db_err;
} }
dwqe_addr = pci_adapter->db_base_phy + HINIC_DB_DWQE_SIZE; if (pci_adapter->chip_mode != CHIP_MODE_NORMAL)
return 0;
dwqe_addr = pci_adapter->db_base_phy + db_dwqe_size;
/* arm do not support call ioremap_wc() */ /* arm do not support call ioremap_wc() */
pci_adapter->dwqe_mapping = __ioremap(dwqe_addr, HINIC_DB_DWQE_SIZE, pci_adapter->dwqe_mapping = __ioremap(dwqe_addr, db_dwqe_size,
__pgprot(PROT_DEVICE_nGnRnE)); __pgprot(PROT_DEVICE_nGnRnE));
if (!pci_adapter->dwqe_mapping) { if (!pci_adapter->dwqe_mapping) {
sdk_err(&pci_adapter->pcidev->dev, "Failed to io_mapping_create_wc\n"); sdk_err(&pci_adapter->pcidev->dev, "Failed to io_mapping_create_wc\n");
...@@ -1889,7 +1895,8 @@ static int mapping_bar(struct pci_dev *pdev, struct hinic_pcidev *pci_adapter) ...@@ -1889,7 +1895,8 @@ static int mapping_bar(struct pci_dev *pdev, struct hinic_pcidev *pci_adapter)
static void unmapping_bar(struct hinic_pcidev *pci_adapter) static void unmapping_bar(struct hinic_pcidev *pci_adapter)
{ {
iounmap(pci_adapter->dwqe_mapping); if (pci_adapter->chip_mode == CHIP_MODE_NORMAL)
iounmap(pci_adapter->dwqe_mapping);
iounmap(pci_adapter->db_base); iounmap(pci_adapter->db_base);
iounmap(pci_adapter->intr_reg_base); iounmap(pci_adapter->intr_reg_base);
......
...@@ -527,6 +527,8 @@ enum hinic_pf_status { ...@@ -527,6 +527,8 @@ enum hinic_pf_status {
/* total doorbell or direct wqe size is 512kB, db num: 128, dwqe: 128 */ /* total doorbell or direct wqe size is 512kB, db num: 128, dwqe: 128 */
#define HINIC_DB_DWQE_SIZE 0x00080000 #define HINIC_DB_DWQE_SIZE 0x00080000
/* BMGW & VMGW VF db size 256k, have no dwqe space */
#define HINIC_GW_VF_DB_SIZE 0x00040000
/* db/dwqe page size: 4K */ /* db/dwqe page size: 4K */
#define HINIC_DB_PAGE_SIZE 0x00001000ULL #define HINIC_DB_PAGE_SIZE 0x00001000ULL
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册