| .. | .. |
|---|
| 929 | 929 | |
|---|
| 930 | 930 | static void release_login_buffer(struct ibmvnic_adapter *adapter) |
|---|
| 931 | 931 | { |
|---|
| 932 | + if (!adapter->login_buf) |
|---|
| 933 | + return; |
|---|
| 934 | + |
|---|
| 935 | + dma_unmap_single(&adapter->vdev->dev, adapter->login_buf_token, |
|---|
| 936 | + adapter->login_buf_sz, DMA_TO_DEVICE); |
|---|
| 932 | 937 | kfree(adapter->login_buf); |
|---|
| 933 | 938 | adapter->login_buf = NULL; |
|---|
| 934 | 939 | } |
|---|
| 935 | 940 | |
|---|
| 936 | 941 | static void release_login_rsp_buffer(struct ibmvnic_adapter *adapter) |
|---|
| 937 | 942 | { |
|---|
| 943 | + if (!adapter->login_rsp_buf) |
|---|
| 944 | + return; |
|---|
| 945 | + |
|---|
| 946 | + dma_unmap_single(&adapter->vdev->dev, adapter->login_rsp_buf_token, |
|---|
| 947 | + adapter->login_rsp_buf_sz, DMA_FROM_DEVICE); |
|---|
| 938 | 948 | kfree(adapter->login_rsp_buf); |
|---|
| 939 | 949 | adapter->login_rsp_buf = NULL; |
|---|
| 940 | 950 | } |
|---|
| .. | .. |
|---|
| 3861 | 3871 | if (rc) { |
|---|
| 3862 | 3872 | adapter->login_pending = false; |
|---|
| 3863 | 3873 | netdev_err(adapter->netdev, "Failed to send login, rc=%d\n", rc); |
|---|
| 3864 | | - goto buf_rsp_map_failed; |
|---|
| 3874 | + goto buf_send_failed; |
|---|
| 3865 | 3875 | } |
|---|
| 3866 | 3876 | |
|---|
| 3867 | 3877 | return 0; |
|---|
| 3868 | 3878 | |
|---|
| 3879 | +buf_send_failed: |
|---|
| 3880 | + dma_unmap_single(dev, rsp_buffer_token, rsp_buffer_size, |
|---|
| 3881 | + DMA_FROM_DEVICE); |
|---|
| 3869 | 3882 | buf_rsp_map_failed: |
|---|
| 3870 | 3883 | kfree(login_rsp_buffer); |
|---|
| 3871 | 3884 | adapter->login_rsp_buf = NULL; |
|---|
| .. | .. |
|---|
| 4430 | 4443 | int num_tx_pools; |
|---|
| 4431 | 4444 | int num_rx_pools; |
|---|
| 4432 | 4445 | u64 *size_array; |
|---|
| 4446 | + u32 rsp_len; |
|---|
| 4433 | 4447 | int i; |
|---|
| 4434 | 4448 | |
|---|
| 4435 | 4449 | /* CHECK: Test/set of login_pending does not need to be atomic |
|---|
| .. | .. |
|---|
| 4440 | 4454 | return 0; |
|---|
| 4441 | 4455 | } |
|---|
| 4442 | 4456 | adapter->login_pending = false; |
|---|
| 4443 | | - |
|---|
| 4444 | | - dma_unmap_single(dev, adapter->login_buf_token, adapter->login_buf_sz, |
|---|
| 4445 | | - DMA_TO_DEVICE); |
|---|
| 4446 | | - dma_unmap_single(dev, adapter->login_rsp_buf_token, |
|---|
| 4447 | | - adapter->login_rsp_buf_sz, DMA_FROM_DEVICE); |
|---|
| 4448 | 4457 | |
|---|
| 4449 | 4458 | /* If the number of queues requested can't be allocated by the |
|---|
| 4450 | 4459 | * server, the login response will return with code 1. We will need |
|---|
| .. | .. |
|---|
| 4481 | 4490 | ibmvnic_reset(adapter, VNIC_RESET_FATAL); |
|---|
| 4482 | 4491 | return -EIO; |
|---|
| 4483 | 4492 | } |
|---|
| 4493 | + |
|---|
| 4494 | + rsp_len = be32_to_cpu(login_rsp->len); |
|---|
| 4495 | + if (be32_to_cpu(login->login_rsp_len) < rsp_len || |
|---|
| 4496 | + rsp_len <= be32_to_cpu(login_rsp->off_txsubm_subcrqs) || |
|---|
| 4497 | + rsp_len <= be32_to_cpu(login_rsp->off_rxadd_subcrqs) || |
|---|
| 4498 | + rsp_len <= be32_to_cpu(login_rsp->off_rxadd_buff_size) || |
|---|
| 4499 | + rsp_len <= be32_to_cpu(login_rsp->off_supp_tx_desc)) { |
|---|
| 4500 | + /* This can happen if a login request times out and there are |
|---|
| 4501 | + * 2 outstanding login requests sent, the LOGIN_RSP crq |
|---|
| 4502 | + * could have been for the older login request. So we are |
|---|
| 4503 | + * parsing the newer response buffer which may be incomplete |
|---|
| 4504 | + */ |
|---|
| 4505 | + dev_err(dev, "FATAL: Login rsp offsets/lengths invalid\n"); |
|---|
| 4506 | + ibmvnic_reset(adapter, VNIC_RESET_FATAL); |
|---|
| 4507 | + return -EIO; |
|---|
| 4508 | + } |
|---|
| 4509 | + |
|---|
| 4484 | 4510 | size_array = (u64 *)((u8 *)(adapter->login_rsp_buf) + |
|---|
| 4485 | 4511 | be32_to_cpu(adapter->login_rsp_buf->off_rxadd_buff_size)); |
|---|
| 4486 | 4512 | /* variable buffer sizes are not supported, so just read the |
|---|