diff options
Diffstat (limited to 'drivers/infiniband/hw/nes/nes_verbs.c')
| -rw-r--r-- | drivers/infiniband/hw/nes/nes_verbs.c | 263 | 
1 files changed, 132 insertions, 131 deletions
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 5b53ca5a228..218dd357428 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -1186,11 +1186,13 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd,  					nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num);  					kfree(nesqp->allocated_buffer);  					nes_debug(NES_DBG_QP, "ib_copy_from_udata() Failed \n"); -					return NULL; +					return ERR_PTR(-EFAULT);  				}  				if (req.user_wqe_buffers) {  					virt_wqs = 1;  				} +				if (req.user_qp_buffer) +					nesqp->nesuqp_addr = req.user_qp_buffer;  				if ((ibpd->uobject) && (ibpd->uobject->context)) {  					nesqp->user_mode = 1;  					nes_ucontext = to_nesucontext(ibpd->uobject->context); @@ -2307,7 +2309,7 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,  	struct nes_device *nesdev = nesvnic->nesdev;  	struct nes_adapter *nesadapter = nesdev->nesadapter;  	struct ib_mr *ibmr = ERR_PTR(-EINVAL); -	struct ib_umem_chunk *chunk; +	struct scatterlist *sg;  	struct nes_ucontext *nes_ucontext;  	struct nes_pbl *nespbl;  	struct nes_mr *nesmr; @@ -2315,7 +2317,7 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,  	struct nes_mem_reg_req req;  	struct nes_vpbl vpbl;  	struct nes_root_vpbl root_vpbl; -	int nmap_index, page_index; +	int entry, page_index;  	int page_count = 0;  	int err, pbl_depth = 0;  	int chunk_pages; @@ -2330,6 +2332,7 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,  	u16 pbl_count;  	u8 single_page = 1;  	u8 stag_key; +	int first_page = 1;  	region = ib_umem_get(pd->uobject->context, start, length, acc, 0);  	if (IS_ERR(region)) { @@ -2380,128 +2383,125 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,  			}  			nesmr->region = region; -			list_for_each_entry(chunk, ®ion->chunk_list, list) { -				nes_debug(NES_DBG_MR, "Chunk: nents = %u, nmap = %u .\n", -						chunk->nents, chunk->nmap); -				for (nmap_index = 0; nmap_index < chunk->nmap; ++nmap_index) { -					if (sg_dma_address(&chunk->page_list[nmap_index]) & ~PAGE_MASK) { -						ib_umem_release(region); -						nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); -						nes_debug(NES_DBG_MR, "Unaligned Memory Buffer: 0x%x\n", -								(unsigned int) sg_dma_address(&chunk->page_list[nmap_index])); -						ibmr = ERR_PTR(-EINVAL); -						kfree(nesmr); -						goto reg_user_mr_err; -					} +			for_each_sg(region->sg_head.sgl, sg, region->nmap, entry) { +				if (sg_dma_address(sg) & ~PAGE_MASK) { +					ib_umem_release(region); +					nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); +					nes_debug(NES_DBG_MR, "Unaligned Memory Buffer: 0x%x\n", +						  (unsigned int) sg_dma_address(sg)); +					ibmr = ERR_PTR(-EINVAL); +					kfree(nesmr); +					goto reg_user_mr_err; +				} -					if (!sg_dma_len(&chunk->page_list[nmap_index])) { -						ib_umem_release(region); -						nes_free_resource(nesadapter, nesadapter->allocated_mrs, -								stag_index); -						nes_debug(NES_DBG_MR, "Invalid Buffer Size\n"); -						ibmr = ERR_PTR(-EINVAL); -						kfree(nesmr); -						goto reg_user_mr_err; -					} +				if (!sg_dma_len(sg)) { +					ib_umem_release(region); +					nes_free_resource(nesadapter, nesadapter->allocated_mrs, +							  stag_index); +					nes_debug(NES_DBG_MR, "Invalid Buffer Size\n"); +					ibmr = ERR_PTR(-EINVAL); +					kfree(nesmr); +					goto reg_user_mr_err; +				} -					region_length += sg_dma_len(&chunk->page_list[nmap_index]); -					chunk_pages = sg_dma_len(&chunk->page_list[nmap_index]) >> 12; -					region_length -= skip_pages << 12; -					for (page_index=skip_pages; page_index < chunk_pages; page_index++) { -						skip_pages = 0; -						if ((page_count!=0)&&(page_count<<12)-(region->offset&(4096-1))>=region->length) -							goto enough_pages; -						if ((page_count&0x01FF) == 0) { -							if (page_count >= 1024 * 512) { +				region_length += sg_dma_len(sg); +				chunk_pages = sg_dma_len(sg) >> 12; +				region_length -= skip_pages << 12; +				for (page_index = skip_pages; page_index < chunk_pages; page_index++) { +					skip_pages = 0; +					if ((page_count != 0) && (page_count<<12)-(region->offset&(4096-1)) >= region->length) +						goto enough_pages; +					if ((page_count&0x01FF) == 0) { +						if (page_count >= 1024 * 512) { +							ib_umem_release(region); +							nes_free_resource(nesadapter, +									  nesadapter->allocated_mrs, stag_index); +							kfree(nesmr); +							ibmr = ERR_PTR(-E2BIG); +							goto reg_user_mr_err; +						} +						if (root_pbl_index == 1) { +							root_vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, +									8192, &root_vpbl.pbl_pbase); +							nes_debug(NES_DBG_MR, "Allocating root PBL, va = %p, pa = 0x%08X\n", +								  root_vpbl.pbl_vbase, (unsigned int)root_vpbl.pbl_pbase); +							if (!root_vpbl.pbl_vbase) {  								ib_umem_release(region); -								nes_free_resource(nesadapter, -										nesadapter->allocated_mrs, stag_index); +								pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase, +										    vpbl.pbl_pbase); +								nes_free_resource(nesadapter, nesadapter->allocated_mrs, +										  stag_index);  								kfree(nesmr); -								ibmr = ERR_PTR(-E2BIG); +								ibmr = ERR_PTR(-ENOMEM);  								goto reg_user_mr_err;  							} -							if (root_pbl_index == 1) { -								root_vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, -										8192, &root_vpbl.pbl_pbase); -								nes_debug(NES_DBG_MR, "Allocating root PBL, va = %p, pa = 0x%08X\n", -										root_vpbl.pbl_vbase, (unsigned int)root_vpbl.pbl_pbase); -								if (!root_vpbl.pbl_vbase) { -									ib_umem_release(region); -									pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase, -											vpbl.pbl_pbase); -									nes_free_resource(nesadapter, nesadapter->allocated_mrs, -											stag_index); -									kfree(nesmr); -									ibmr = ERR_PTR(-ENOMEM); -									goto reg_user_mr_err; -								} -								root_vpbl.leaf_vpbl = kzalloc(sizeof(*root_vpbl.leaf_vpbl)*1024, -										GFP_KERNEL); -								if (!root_vpbl.leaf_vpbl) { -									ib_umem_release(region); -									pci_free_consistent(nesdev->pcidev, 8192, root_vpbl.pbl_vbase, -											root_vpbl.pbl_pbase); -									pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase, -											vpbl.pbl_pbase); -									nes_free_resource(nesadapter, nesadapter->allocated_mrs, -											stag_index); -									kfree(nesmr); -									ibmr = ERR_PTR(-ENOMEM); -									goto reg_user_mr_err; -								} -								root_vpbl.pbl_vbase[0].pa_low = -										cpu_to_le32((u32)vpbl.pbl_pbase); -								root_vpbl.pbl_vbase[0].pa_high = -										cpu_to_le32((u32)((((u64)vpbl.pbl_pbase) >> 32))); -								root_vpbl.leaf_vpbl[0] = vpbl; -							} -							vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096, -									&vpbl.pbl_pbase); -							nes_debug(NES_DBG_MR, "Allocating leaf PBL, va = %p, pa = 0x%08X\n", -									vpbl.pbl_vbase, (unsigned int)vpbl.pbl_pbase); -							if (!vpbl.pbl_vbase) { +							root_vpbl.leaf_vpbl = kzalloc(sizeof(*root_vpbl.leaf_vpbl)*1024, +									GFP_KERNEL); +							if (!root_vpbl.leaf_vpbl) {  								ib_umem_release(region); -								nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); -								ibmr = ERR_PTR(-ENOMEM); +								pci_free_consistent(nesdev->pcidev, 8192, root_vpbl.pbl_vbase, +										    root_vpbl.pbl_pbase); +								pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase, +										    vpbl.pbl_pbase); +								nes_free_resource(nesadapter, nesadapter->allocated_mrs, +										  stag_index);  								kfree(nesmr); +								ibmr = ERR_PTR(-ENOMEM);  								goto reg_user_mr_err;  							} -							if (1 <= root_pbl_index) { -								root_vpbl.pbl_vbase[root_pbl_index].pa_low = -										cpu_to_le32((u32)vpbl.pbl_pbase); -								root_vpbl.pbl_vbase[root_pbl_index].pa_high = -										cpu_to_le32((u32)((((u64)vpbl.pbl_pbase)>>32))); -								root_vpbl.leaf_vpbl[root_pbl_index] = vpbl; -							} -							root_pbl_index++; -							cur_pbl_index = 0; +							root_vpbl.pbl_vbase[0].pa_low = +									cpu_to_le32((u32)vpbl.pbl_pbase); +							root_vpbl.pbl_vbase[0].pa_high = +									cpu_to_le32((u32)((((u64)vpbl.pbl_pbase) >> 32))); +							root_vpbl.leaf_vpbl[0] = vpbl;  						} -						if (single_page) { -							if (page_count != 0) { -								if ((last_dma_addr+4096) != -										(sg_dma_address(&chunk->page_list[nmap_index])+ -										(page_index*4096))) -									single_page = 0; -								last_dma_addr = sg_dma_address(&chunk->page_list[nmap_index])+ -										(page_index*4096); -							} else { -								first_dma_addr = sg_dma_address(&chunk->page_list[nmap_index])+ -										(page_index*4096); -								last_dma_addr = first_dma_addr; -							} +						vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096, +								&vpbl.pbl_pbase); +						nes_debug(NES_DBG_MR, "Allocating leaf PBL, va = %p, pa = 0x%08X\n", +							  vpbl.pbl_vbase, (unsigned int)vpbl.pbl_pbase); +						if (!vpbl.pbl_vbase) { +							ib_umem_release(region); +							nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); +							ibmr = ERR_PTR(-ENOMEM); +							kfree(nesmr); +							goto reg_user_mr_err; +						} +						if (1 <= root_pbl_index) { +							root_vpbl.pbl_vbase[root_pbl_index].pa_low = +									cpu_to_le32((u32)vpbl.pbl_pbase); +							root_vpbl.pbl_vbase[root_pbl_index].pa_high = +									cpu_to_le32((u32)((((u64)vpbl.pbl_pbase)>>32))); +							root_vpbl.leaf_vpbl[root_pbl_index] = vpbl; +						} +						root_pbl_index++; +						cur_pbl_index = 0; +					} +					if (single_page) { +						if (page_count != 0) { +							if ((last_dma_addr+4096) != +									(sg_dma_address(sg)+ +									(page_index*4096))) +								single_page = 0; +							last_dma_addr = sg_dma_address(sg)+ +									(page_index*4096); +						} else { +							first_dma_addr = sg_dma_address(sg)+ +									(page_index*4096); +							last_dma_addr = first_dma_addr;  						} - -						vpbl.pbl_vbase[cur_pbl_index].pa_low = -								cpu_to_le32((u32)(sg_dma_address(&chunk->page_list[nmap_index])+ -								(page_index*4096))); -						vpbl.pbl_vbase[cur_pbl_index].pa_high = -								cpu_to_le32((u32)((((u64)(sg_dma_address(&chunk->page_list[nmap_index])+ -								(page_index*4096))) >> 32))); -						cur_pbl_index++; -						page_count++;  					} + +					vpbl.pbl_vbase[cur_pbl_index].pa_low = +							cpu_to_le32((u32)(sg_dma_address(sg)+ +							(page_index*4096))); +					vpbl.pbl_vbase[cur_pbl_index].pa_high = +							cpu_to_le32((u32)((((u64)(sg_dma_address(sg)+ +							(page_index*4096))) >> 32))); +					cur_pbl_index++; +					page_count++;  				}  			} +  			enough_pages:  			nes_debug(NES_DBG_MR, "calculating stag, stag_index=0x%08x, driver_key=0x%08x,"  					" stag_key=0x%08x\n", @@ -2613,25 +2613,28 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,  				  nespbl->pbl_size, (unsigned long) nespbl->pbl_pbase,  				  (void *) nespbl->pbl_vbase, nespbl->user_base); -			list_for_each_entry(chunk, ®ion->chunk_list, list) { -				for (nmap_index = 0; nmap_index < chunk->nmap; ++nmap_index) { -					chunk_pages = sg_dma_len(&chunk->page_list[nmap_index]) >> 12; -					chunk_pages += (sg_dma_len(&chunk->page_list[nmap_index]) & (4096-1)) ? 1 : 0; -					nespbl->page = sg_page(&chunk->page_list[0]); -					for (page_index=0; page_index<chunk_pages; page_index++) { -						((__le32 *)pbl)[0] = cpu_to_le32((u32) -								(sg_dma_address(&chunk->page_list[nmap_index])+ -								(page_index*4096))); -						((__le32 *)pbl)[1] = cpu_to_le32(((u64) -								(sg_dma_address(&chunk->page_list[nmap_index])+ -								(page_index*4096)))>>32); -						nes_debug(NES_DBG_MR, "pbl=%p, *pbl=0x%016llx, 0x%08x%08x\n", pbl, -								(unsigned long long)*pbl, -								le32_to_cpu(((__le32 *)pbl)[1]), le32_to_cpu(((__le32 *)pbl)[0])); -						pbl++; -					} +			for_each_sg(region->sg_head.sgl, sg, region->nmap, entry) { +				chunk_pages = sg_dma_len(sg) >> 12; +				chunk_pages += (sg_dma_len(sg) & (4096-1)) ? 1 : 0; +				if (first_page) { +					nespbl->page = sg_page(sg); +					first_page = 0; +				} + +				for (page_index = 0; page_index < chunk_pages; page_index++) { +					((__le32 *)pbl)[0] = cpu_to_le32((u32) +							(sg_dma_address(sg)+ +							(page_index*4096))); +					((__le32 *)pbl)[1] = cpu_to_le32(((u64) +							(sg_dma_address(sg)+ +							(page_index*4096)))>>32); +					nes_debug(NES_DBG_MR, "pbl=%p, *pbl=0x%016llx, 0x%08x%08x\n", pbl, +						  (unsigned long long)*pbl, +						  le32_to_cpu(((__le32 *)pbl)[1]), le32_to_cpu(((__le32 *)pbl)[0])); +					pbl++;  				}  			} +  			if (req.reg_type == IWNES_MEMREG_TYPE_QP) {  				list_add_tail(&nespbl->list, &nes_ucontext->qp_reg_mem_list);  			} else { @@ -2834,7 +2837,7 @@ static int nes_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,  	init_attr->qp_context = nesqp->ibqp.qp_context;  	init_attr->send_cq = nesqp->ibqp.send_cq;  	init_attr->recv_cq = nesqp->ibqp.recv_cq; -	init_attr->srq = nesqp->ibqp.srq = nesqp->ibqp.srq; +	init_attr->srq = nesqp->ibqp.srq;  	init_attr->cap = attr->cap;  	return 0; @@ -3134,9 +3137,7 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,  				" original_last_aeq = 0x%04X. last_aeq = 0x%04X.\n",  				nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount),  				original_last_aeq, nesqp->last_aeq); -		if ((!ret) || -				((original_last_aeq != NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) && -				(ret))) { +		if (!ret || original_last_aeq != NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) {  			if (dont_wait) {  				if (nesqp->cm_id && nesqp->hw_tcp_state != 0) {  					nes_debug(NES_DBG_MOD_QP, "QP%u Queuing fake disconnect for QP refcount (%d),"  | 
