|
@@ -411,6 +411,10 @@ static int reset_rx_pools(struct ibmvnic_adapter *adapter)
|
|
|
struct ibmvnic_rx_pool *rx_pool;
|
|
|
int rx_scrqs;
|
|
|
int i, j, rc;
|
|
|
+ u64 *size_array;
|
|
|
+
|
|
|
+ size_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
|
|
|
+ be32_to_cpu(adapter->login_rsp_buf->off_rxadd_buff_size));
|
|
|
|
|
|
rx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
|
|
|
for (i = 0; i < rx_scrqs; i++) {
|
|
@@ -418,7 +422,17 @@ static int reset_rx_pools(struct ibmvnic_adapter *adapter)
|
|
|
|
|
|
netdev_dbg(adapter->netdev, "Re-setting rx_pool[%d]\n", i);
|
|
|
|
|
|
- rc = reset_long_term_buff(adapter, &rx_pool->long_term_buff);
|
|
|
+ if (rx_pool->buff_size != be64_to_cpu(size_array[i])) {
|
|
|
+ free_long_term_buff(adapter, &rx_pool->long_term_buff);
|
|
|
+ rx_pool->buff_size = be64_to_cpu(size_array[i]);
|
|
|
+ alloc_long_term_buff(adapter, &rx_pool->long_term_buff,
|
|
|
+ rx_pool->size *
|
|
|
+ rx_pool->buff_size);
|
|
|
+ } else {
|
|
|
+ rc = reset_long_term_buff(adapter,
|
|
|
+ &rx_pool->long_term_buff);
|
|
|
+ }
|
|
|
+
|
|
|
if (rc)
|
|
|
return rc;
|
|
|
|
|
@@ -440,14 +454,12 @@ static int reset_rx_pools(struct ibmvnic_adapter *adapter)
|
|
|
static void release_rx_pools(struct ibmvnic_adapter *adapter)
|
|
|
{
|
|
|
struct ibmvnic_rx_pool *rx_pool;
|
|
|
- int rx_scrqs;
|
|
|
int i, j;
|
|
|
|
|
|
if (!adapter->rx_pool)
|
|
|
return;
|
|
|
|
|
|
- rx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
|
|
|
- for (i = 0; i < rx_scrqs; i++) {
|
|
|
+ for (i = 0; i < adapter->num_active_rx_pools; i++) {
|
|
|
rx_pool = &adapter->rx_pool[i];
|
|
|
|
|
|
netdev_dbg(adapter->netdev, "Releasing rx_pool[%d]\n", i);
|
|
@@ -470,6 +482,7 @@ static void release_rx_pools(struct ibmvnic_adapter *adapter)
|
|
|
|
|
|
kfree(adapter->rx_pool);
|
|
|
adapter->rx_pool = NULL;
|
|
|
+ adapter->num_active_rx_pools = 0;
|
|
|
}
|
|
|
|
|
|
static int init_rx_pools(struct net_device *netdev)
|
|
@@ -494,6 +507,8 @@ static int init_rx_pools(struct net_device *netdev)
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
+ adapter->num_active_rx_pools = 0;
|
|
|
+
|
|
|
for (i = 0; i < rxadd_subcrqs; i++) {
|
|
|
rx_pool = &adapter->rx_pool[i];
|
|
|
|
|
@@ -537,6 +552,8 @@ static int init_rx_pools(struct net_device *netdev)
|
|
|
rx_pool->next_free = 0;
|
|
|
}
|
|
|
|
|
|
+ adapter->num_active_rx_pools = rxadd_subcrqs;
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -587,13 +604,12 @@ static void release_vpd_data(struct ibmvnic_adapter *adapter)
|
|
|
static void release_tx_pools(struct ibmvnic_adapter *adapter)
|
|
|
{
|
|
|
struct ibmvnic_tx_pool *tx_pool;
|
|
|
- int i, tx_scrqs;
|
|
|
+ int i;
|
|
|
|
|
|
if (!adapter->tx_pool)
|
|
|
return;
|
|
|
|
|
|
- tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
|
|
|
- for (i = 0; i < tx_scrqs; i++) {
|
|
|
+ for (i = 0; i < adapter->num_active_tx_pools; i++) {
|
|
|
netdev_dbg(adapter->netdev, "Releasing tx_pool[%d]\n", i);
|
|
|
tx_pool = &adapter->tx_pool[i];
|
|
|
kfree(tx_pool->tx_buff);
|
|
@@ -604,6 +620,7 @@ static void release_tx_pools(struct ibmvnic_adapter *adapter)
|
|
|
|
|
|
kfree(adapter->tx_pool);
|
|
|
adapter->tx_pool = NULL;
|
|
|
+ adapter->num_active_tx_pools = 0;
|
|
|
}
|
|
|
|
|
|
static int init_tx_pools(struct net_device *netdev)
|
|
@@ -620,6 +637,8 @@ static int init_tx_pools(struct net_device *netdev)
|
|
|
if (!adapter->tx_pool)
|
|
|
return -1;
|
|
|
|
|
|
+ adapter->num_active_tx_pools = 0;
|
|
|
+
|
|
|
for (i = 0; i < tx_subcrqs; i++) {
|
|
|
tx_pool = &adapter->tx_pool[i];
|
|
|
|
|
@@ -667,6 +686,8 @@ static int init_tx_pools(struct net_device *netdev)
|
|
|
tx_pool->producer_index = 0;
|
|
|
}
|
|
|
|
|
|
+ adapter->num_active_tx_pools = tx_subcrqs;
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -861,7 +882,7 @@ static int ibmvnic_get_vpd(struct ibmvnic_adapter *adapter)
|
|
|
if (adapter->vpd->buff)
|
|
|
len = adapter->vpd->len;
|
|
|
|
|
|
- reinit_completion(&adapter->fw_done);
|
|
|
+ init_completion(&adapter->fw_done);
|
|
|
crq.get_vpd_size.first = IBMVNIC_CRQ_CMD;
|
|
|
crq.get_vpd_size.cmd = GET_VPD_SIZE;
|
|
|
ibmvnic_send_crq(adapter, &crq);
|
|
@@ -923,6 +944,13 @@ static int init_resources(struct ibmvnic_adapter *adapter)
|
|
|
if (!adapter->vpd)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
+ /* Vital Product Data (VPD) */
|
|
|
+ rc = ibmvnic_get_vpd(adapter);
|
|
|
+ if (rc) {
|
|
|
+ netdev_err(netdev, "failed to initialize Vital Product Data (VPD)\n");
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
adapter->map_id = 1;
|
|
|
adapter->napi = kcalloc(adapter->req_rx_queues,
|
|
|
sizeof(struct napi_struct), GFP_KERNEL);
|
|
@@ -996,7 +1024,7 @@ static int __ibmvnic_open(struct net_device *netdev)
|
|
|
static int ibmvnic_open(struct net_device *netdev)
|
|
|
{
|
|
|
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
|
|
|
- int rc, vpd;
|
|
|
+ int rc;
|
|
|
|
|
|
mutex_lock(&adapter->reset_lock);
|
|
|
|
|
@@ -1019,11 +1047,6 @@ static int ibmvnic_open(struct net_device *netdev)
|
|
|
rc = __ibmvnic_open(netdev);
|
|
|
netif_carrier_on(netdev);
|
|
|
|
|
|
- /* Vital Product Data (VPD) */
|
|
|
- vpd = ibmvnic_get_vpd(adapter);
|
|
|
- if (vpd)
|
|
|
- netdev_err(netdev, "failed to initialize Vital Product Data (VPD)\n");
|
|
|
-
|
|
|
mutex_unlock(&adapter->reset_lock);
|
|
|
|
|
|
return rc;
|
|
@@ -1553,6 +1576,7 @@ static int ibmvnic_set_mac(struct net_device *netdev, void *p)
|
|
|
static int do_reset(struct ibmvnic_adapter *adapter,
|
|
|
struct ibmvnic_rwi *rwi, u32 reset_state)
|
|
|
{
|
|
|
+ u64 old_num_rx_queues, old_num_tx_queues;
|
|
|
struct net_device *netdev = adapter->netdev;
|
|
|
int i, rc;
|
|
|
|
|
@@ -1562,6 +1586,9 @@ static int do_reset(struct ibmvnic_adapter *adapter,
|
|
|
netif_carrier_off(netdev);
|
|
|
adapter->reset_reason = rwi->reset_reason;
|
|
|
|
|
|
+ old_num_rx_queues = adapter->req_rx_queues;
|
|
|
+ old_num_tx_queues = adapter->req_tx_queues;
|
|
|
+
|
|
|
if (rwi->reset_reason == VNIC_RESET_MOBILITY) {
|
|
|
rc = ibmvnic_reenable_crq_queue(adapter);
|
|
|
if (rc)
|
|
@@ -1606,6 +1633,12 @@ static int do_reset(struct ibmvnic_adapter *adapter,
|
|
|
rc = init_resources(adapter);
|
|
|
if (rc)
|
|
|
return rc;
|
|
|
+ } else if (adapter->req_rx_queues != old_num_rx_queues ||
|
|
|
+ adapter->req_tx_queues != old_num_tx_queues) {
|
|
|
+ release_rx_pools(adapter);
|
|
|
+ release_tx_pools(adapter);
|
|
|
+ init_rx_pools(netdev);
|
|
|
+ init_tx_pools(netdev);
|
|
|
} else {
|
|
|
rc = reset_tx_pools(adapter);
|
|
|
if (rc)
|
|
@@ -3603,7 +3636,17 @@ static void handle_request_cap_rsp(union ibmvnic_crq *crq,
|
|
|
*req_value,
|
|
|
(long int)be64_to_cpu(crq->request_capability_rsp.
|
|
|
number), name);
|
|
|
- *req_value = be64_to_cpu(crq->request_capability_rsp.number);
|
|
|
+
|
|
|
+ if (be16_to_cpu(crq->request_capability_rsp.capability) ==
|
|
|
+ REQ_MTU) {
|
|
|
+ pr_err("mtu of %llu is not supported. Reverting.\n",
|
|
|
+ *req_value);
|
|
|
+ *req_value = adapter->fallback.mtu;
|
|
|
+ } else {
|
|
|
+ *req_value =
|
|
|
+ be64_to_cpu(crq->request_capability_rsp.number);
|
|
|
+ }
|
|
|
+
|
|
|
ibmvnic_send_req_caps(adapter, 1);
|
|
|
return;
|
|
|
default:
|