aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.c204
1 files changed, 101 insertions, 103 deletions
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index a9399e96e942..6774b3cbc5f9 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -163,21 +163,6 @@ static long h_reg_sub_crq(unsigned long unit_address, unsigned long token,
return rc;
}
-/* net_device_ops functions */
-
-static void init_rx_pool(struct ibmvnic_adapter *adapter,
- struct ibmvnic_rx_pool *rx_pool, int num, int index,
- int buff_size, int active)
-{
- netdev_dbg(adapter->netdev,
- "Initializing rx_pool %d, %d buffs, %d bytes each\n",
- index, num, buff_size);
- rx_pool->size = num;
- rx_pool->index = index;
- rx_pool->buff_size = buff_size;
- rx_pool->active = active;
-}
-
static int alloc_long_term_buff(struct ibmvnic_adapter *adapter,
struct ibmvnic_long_term_buff *ltb, int size)
{
@@ -214,42 +199,6 @@ static void free_long_term_buff(struct ibmvnic_adapter *adapter,
send_request_unmap(adapter, ltb->map_id);
}
-static int alloc_rx_pool(struct ibmvnic_adapter *adapter,
- struct ibmvnic_rx_pool *pool)
-{
- struct device *dev = &adapter->vdev->dev;
- int i;
-
- pool->free_map = kcalloc(pool->size, sizeof(int), GFP_KERNEL);
- if (!pool->free_map)
- return -ENOMEM;
-
- pool->rx_buff = kcalloc(pool->size, sizeof(struct ibmvnic_rx_buff),
- GFP_KERNEL);
-
- if (!pool->rx_buff) {
- dev_err(dev, "Couldn't alloc rx buffers\n");
- kfree(pool->free_map);
- return -ENOMEM;
- }
-
- if (alloc_long_term_buff(adapter, &pool->long_term_buff,
- pool->size * pool->buff_size)) {
- kfree(pool->free_map);
- kfree(pool->rx_buff);
- return -ENOMEM;
- }
-
- for (i = 0; i < pool->size; ++i)
- pool->free_map[i] = i;
-
- atomic_set(&pool->available, 0);
- pool->next_alloc = 0;
- pool->next_free = 0;
-
- return 0;
-}
-
static void replenish_rx_pool(struct ibmvnic_adapter *adapter,
struct ibmvnic_rx_pool *pool)
{
@@ -354,25 +303,105 @@ static void replenish_pools(struct ibmvnic_adapter *adapter)
}
}
-static void free_rx_pool(struct ibmvnic_adapter *adapter,
- struct ibmvnic_rx_pool *pool)
+static void release_rx_pools(struct ibmvnic_adapter *adapter)
{
- int i;
-
- kfree(pool->free_map);
- pool->free_map = NULL;
+ struct ibmvnic_rx_pool *rx_pool;
+ int rx_scrqs;
+ int i, j;
- if (!pool->rx_buff)
+ if (!adapter->rx_pool)
return;
- for (i = 0; i < pool->size; i++) {
- if (pool->rx_buff[i].skb) {
- dev_kfree_skb_any(pool->rx_buff[i].skb);
- pool->rx_buff[i].skb = NULL;
+ rx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
+ for (i = 0; i < rx_scrqs; i++) {
+ rx_pool = &adapter->rx_pool[i];
+
+ kfree(rx_pool->free_map);
+ free_long_term_buff(adapter, &rx_pool->long_term_buff);
+
+ if (!rx_pool->rx_buff)
+ continue;
+
+ for (j = 0; j < rx_pool->size; j++) {
+ if (rx_pool->rx_buff[j].skb) {
+ dev_kfree_skb_any(rx_pool->rx_buff[i].skb);
+ rx_pool->rx_buff[i].skb = NULL;
+ }
+ }
+
+ kfree(rx_pool->rx_buff);
+ }
+
+ kfree(adapter->rx_pool);
+ adapter->rx_pool = NULL;
+}
+
+static int init_rx_pools(struct net_device *netdev)
+{
+ struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+ struct device *dev = &adapter->vdev->dev;
+ struct ibmvnic_rx_pool *rx_pool;
+ int rxadd_subcrqs;
+ u64 *size_array;
+ int i, j;
+
+ rxadd_subcrqs =
+ be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
+ size_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
+ be32_to_cpu(adapter->login_rsp_buf->off_rxadd_buff_size));
+
+ adapter->rx_pool = kcalloc(rxadd_subcrqs,
+ sizeof(struct ibmvnic_rx_pool),
+ GFP_KERNEL);
+ if (!adapter->rx_pool) {
+ dev_err(dev, "Failed to allocate rx pools\n");
+ return -1;
+ }
+
+ for (i = 0; i < rxadd_subcrqs; i++) {
+ rx_pool = &adapter->rx_pool[i];
+
+ netdev_dbg(adapter->netdev,
+ "Initializing rx_pool %d, %lld buffs, %lld bytes each\n",
+ i, adapter->req_rx_add_entries_per_subcrq,
+ be64_to_cpu(size_array[i]));
+
+ rx_pool->size = adapter->req_rx_add_entries_per_subcrq;
+ rx_pool->index = i;
+ rx_pool->buff_size = be64_to_cpu(size_array[i]);
+ rx_pool->active = 1;
+
+ rx_pool->free_map = kcalloc(rx_pool->size, sizeof(int),
+ GFP_KERNEL);
+ if (!rx_pool->free_map) {
+ release_rx_pools(adapter);
+ return -1;
+ }
+
+ rx_pool->rx_buff = kcalloc(rx_pool->size,
+ sizeof(struct ibmvnic_rx_buff),
+ GFP_KERNEL);
+ if (!rx_pool->rx_buff) {
+ dev_err(dev, "Couldn't alloc rx buffers\n");
+ release_rx_pools(adapter);
+ return -1;
+ }
+
+ if (alloc_long_term_buff(adapter, &rx_pool->long_term_buff,
+ rx_pool->size * rx_pool->buff_size)) {
+ release_rx_pools(adapter);
+ return -1;
}
+
+ for (j = 0; j < rx_pool->size; ++j)
+ rx_pool->free_map[j] = j;
+
+ atomic_set(&rx_pool->available, 0);
+ rx_pool->next_alloc = 0;
+ rx_pool->next_free = 0;
}
- kfree(pool->rx_buff);
- pool->rx_buff = NULL;
+
+ return 0;
}
static void release_tx_pools(struct ibmvnic_adapter *adapter)
@@ -526,10 +555,9 @@ static int ibmvnic_open(struct net_device *netdev)
struct device *dev = &adapter->vdev->dev;
union ibmvnic_crq crq;
int rxadd_subcrqs;
- u64 *size_array;
int tx_subcrqs;
int rc = 0;
- int i, j;
+ int i;
if (adapter->is_closed) {
rc = ibmvnic_init(adapter);
@@ -557,9 +585,7 @@ static int ibmvnic_open(struct net_device *netdev)
be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
tx_subcrqs =
be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
- size_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
- be32_to_cpu(adapter->login_rsp_buf->
- off_rxadd_buff_size));
+
adapter->map_id = 1;
adapter->napi = kcalloc(adapter->req_rx_queues,
sizeof(struct napi_struct), GFP_KERNEL);
@@ -570,21 +596,12 @@ static int ibmvnic_open(struct net_device *netdev)
NAPI_POLL_WEIGHT);
napi_enable(&adapter->napi[i]);
}
- adapter->rx_pool =
- kcalloc(rxadd_subcrqs, sizeof(struct ibmvnic_rx_pool), GFP_KERNEL);
- if (!adapter->rx_pool)
- goto rx_pool_arr_alloc_failed;
send_map_query(adapter);
- for (i = 0; i < rxadd_subcrqs; i++) {
- init_rx_pool(adapter, &adapter->rx_pool[i],
- adapter->req_rx_add_entries_per_subcrq, i,
- be64_to_cpu(size_array[i]), 1);
- if (alloc_rx_pool(adapter, &adapter->rx_pool[i])) {
- dev_err(dev, "Couldn't alloc rx pool\n");
- goto rx_pool_alloc_failed;
- }
- }
+
+ rc = init_rx_pools(netdev);
+ if (rc)
+ goto rx_pool_failed;
rc = init_tx_pools(netdev);
if (rc)
@@ -621,15 +638,7 @@ bounce_init_failed:
kfree(adapter->tx_pool[i].free_map);
tx_pool_failed:
i = rxadd_subcrqs;
-rx_pool_alloc_failed:
- for (j = 0; j < i; j++) {
- free_rx_pool(adapter, &adapter->rx_pool[j]);
- free_long_term_buff(adapter,
- &adapter->rx_pool[j].long_term_buff);
- }
- kfree(adapter->rx_pool);
- adapter->rx_pool = NULL;
-rx_pool_arr_alloc_failed:
+rx_pool_failed:
for (i = 0; i < adapter->req_rx_queues; i++)
napi_disable(&adapter->napi[i]);
alloc_napi_failed:
@@ -640,21 +649,10 @@ alloc_napi_failed:
static void ibmvnic_release_resources(struct ibmvnic_adapter *adapter)
{
struct device *dev = &adapter->vdev->dev;
- int rx_scrqs;
- int i;
release_bounce_buffer(adapter);
release_tx_pools(adapter);
-
- rx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
- for (i = 0; i < rx_scrqs; i++) {
- struct ibmvnic_rx_pool *rx_pool = &adapter->rx_pool[i];
-
- free_rx_pool(adapter, rx_pool);
- free_long_term_buff(adapter, &rx_pool->long_term_buff);
- }
- kfree(adapter->rx_pool);
- adapter->rx_pool = NULL;
+ release_rx_pools(adapter);
release_sub_crqs(adapter);
release_crq_queue(adapter);