Print this page
NEX-1890 update oce from source provided by Emulex
*** 17,47 ****
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
! /* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Source file containing the implementation of the driver entry points
* and related helper functions
*/
#include <oce_impl.h>
#include <oce_ioctl.h>
- /* array of properties supported by this driver */
- char *oce_priv_props[] = {
- "_tx_ring_size",
- "_tx_bcopy_limit",
- "_rx_ring_size",
- "_rx_bcopy_limit",
- NULL
- };
-
- extern int pow10[];
-
/* ---[ static function declarations ]----------------------------------- */
static int oce_set_priv_prop(struct oce_dev *dev, const char *name,
uint_t size, const void *val);
static int oce_get_priv_prop(struct oce_dev *dev, const char *name,
--- 17,41 ----
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
! /*
! * Copyright (c) 2009-2012 Emulex. All rights reserved.
! * Use is subject to license terms.
! */
+
+
/*
* Source file containing the implementation of the driver entry points
* and related helper functions
*/
#include <oce_impl.h>
#include <oce_ioctl.h>
/* ---[ static function declarations ]----------------------------------- */
static int oce_set_priv_prop(struct oce_dev *dev, const char *name,
uint_t size, const void *val);
static int oce_get_priv_prop(struct oce_dev *dev, const char *name,
*** 50,60 ****
/* ---[ GLD entry points ]----------------------------------------------- */
int
oce_m_start(void *arg)
{
struct oce_dev *dev = arg;
! int ret;
mutex_enter(&dev->dev_lock);
if (dev->state & STATE_MAC_STARTED) {
mutex_exit(&dev->dev_lock);
--- 44,54 ----
/* ---[ GLD entry points ]----------------------------------------------- */
int
oce_m_start(void *arg)
{
struct oce_dev *dev = arg;
! int i;
mutex_enter(&dev->dev_lock);
if (dev->state & STATE_MAC_STARTED) {
mutex_exit(&dev->dev_lock);
*** 63,162 ****
if (dev->suspended) {
mutex_exit(&dev->dev_lock);
return (EIO);
}
! ret = oce_start(dev);
! if (ret != DDI_SUCCESS) {
mutex_exit(&dev->dev_lock);
! return (EIO);
}
! dev->state |= STATE_MAC_STARTED;
mutex_exit(&dev->dev_lock);
return (DDI_SUCCESS);
}
int
oce_start(struct oce_dev *dev)
{
int qidx = 0;
- struct link_status link = {0};
! /* get link status */
! (void) oce_get_link_status(dev, &link);
! dev->link_status = (link.logical_link_status == NTWK_LOGICAL_LINK_UP) ?
! LINK_STATE_UP : LINK_STATE_DOWN;
! dev->link_speed = link.qos_link_speed ? link.qos_link_speed * 10 :
! pow10[link.mac_speed];
! mac_link_update(dev->mac_handle, dev->link_status);
! for (qidx = 0; qidx < dev->nwqs; qidx++) {
! (void) oce_start_wq(dev->wq[qidx]);
}
! for (qidx = 0; qidx < dev->nrqs; qidx++) {
! (void) oce_start_rq(dev->rq[qidx]);
}
(void) oce_start_mq(dev->mq);
! /* enable interrupts */
! oce_ei(dev);
/* arm the eqs */
! for (qidx = 0; qidx < dev->neqs; qidx++) {
! oce_arm_eq(dev, dev->eq[qidx]->eq_id, 0, B_TRUE, B_FALSE);
}
! /* TODO update state */
return (DDI_SUCCESS);
} /* oce_start */
void
oce_m_stop(void *arg)
{
struct oce_dev *dev = arg;
- /* disable interrupts */
-
mutex_enter(&dev->dev_lock);
if (dev->suspended) {
mutex_exit(&dev->dev_lock);
return;
}
! dev->state |= STATE_MAC_STOPPING;
oce_stop(dev);
! dev->state &= ~(STATE_MAC_STOPPING | STATE_MAC_STARTED);
mutex_exit(&dev->dev_lock);
}
/* called with Tx/Rx comp locks held */
void
oce_stop(struct oce_dev *dev)
{
int qidx;
/* disable interrupts */
! oce_di(dev);
for (qidx = 0; qidx < dev->nwqs; qidx++) {
! mutex_enter(&dev->wq[qidx]->tx_lock);
}
mutex_enter(&dev->mq->lock);
! /* complete the pending Tx */
! for (qidx = 0; qidx < dev->nwqs; qidx++)
! oce_clean_wq(dev->wq[qidx]);
/* Release all the locks */
mutex_exit(&dev->mq->lock);
for (qidx = 0; qidx < dev->nwqs; qidx++)
! mutex_exit(&dev->wq[qidx]->tx_lock);
if (dev->link_status == LINK_STATE_UP) {
dev->link_status = LINK_STATE_UNKNOWN;
mac_link_update(dev->mac_handle, dev->link_status);
}
} /* oce_stop */
int
oce_m_multicast(void *arg, boolean_t add, const uint8_t *mca)
{
struct oce_dev *dev = (struct oce_dev *)arg;
struct ether_addr *mca_drv_list;
--- 57,260 ----
if (dev->suspended) {
mutex_exit(&dev->dev_lock);
return (EIO);
}
!
! /* allocate Tx buffers */
! if (oce_init_tx(dev) != DDI_SUCCESS) {
mutex_exit(&dev->dev_lock);
! oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
! "Failed to init rings");
! return (DDI_FAILURE);
}
! if (oce_start(dev) != DDI_SUCCESS) {
! oce_fini_tx(dev);
mutex_exit(&dev->dev_lock);
+ return (EIO);
+ }
+ dev->state |= STATE_MAC_STARTED;
+ /* initialise the group locks */
+ for (i = 0; i < dev->num_rx_groups; i++) {
+ mutex_init(&dev->rx_group[i].grp_lock, NULL, MUTEX_DRIVER,
+ DDI_INTR_PRI(dev->intr_pri));
+ }
+ mutex_exit(&dev->dev_lock);
+ oce_enable_wd_timer(dev);
return (DDI_SUCCESS);
}
+ void
+ oce_start_eqs(struct oce_dev *dev)
+ {
+ int qidx = 0;
+
+ for (qidx = 0; qidx < dev->neqs; qidx++) {
+ mutex_enter(&dev->eq[qidx].lock);
+ oce_arm_eq(dev, dev->eq[qidx].eq_id, 0, B_TRUE, B_FALSE);
+ dev->eq[qidx].qstate = QSTARTED;
+ mutex_exit(&dev->eq[qidx].lock);
+ }
+ }
+
+ void
+ oce_stop_eqs(struct oce_dev *dev)
+ {
+ int qidx = 0;
+
+ for (qidx = 0; qidx < dev->neqs; qidx++) {
+ mutex_enter(&dev->eq[qidx].lock);
+ oce_arm_eq(dev, dev->eq[qidx].eq_id, 0, B_FALSE, B_FALSE);
+ dev->eq[qidx].qstate = QSTOPPED;
+ mutex_exit(&dev->eq[qidx].lock);
+ }
+ }
int
oce_start(struct oce_dev *dev)
{
int qidx = 0;
! /* disable the interrupts */
! if (!LANCER_CHIP(dev))
! oce_chip_di(dev);
! /* set default flow control */
! (void) oce_set_flow_control(dev, dev->flow_control, MBX_BOOTSTRAP);
! (void) oce_set_promiscuous(dev, dev->promisc, MBX_BOOTSTRAP);
! if (oce_ei(dev) != DDI_SUCCESS) {
! return (DDI_FAILURE);
! }
! if (oce_create_queues(dev) != DDI_SUCCESS) {
! goto cleanup_handler;
! }
! for (qidx = 0; qidx < dev->tx_rings; qidx++) {
! mac_ring_intr_set(dev->default_tx_rings[qidx].tx->handle,
! dev->htable[dev->default_tx_rings[qidx].tx->cq->eq->idx]);
! (void) oce_start_wq(dev->default_tx_rings[qidx].tx);
}
!
! if (oce_create_mcc_queue(dev) != DDI_SUCCESS) {
! goto delete_queues;
}
(void) oce_start_mq(dev->mq);
!
! dev->state |= STATE_INTR_ENABLED;
!
! if (!LANCER_CHIP(dev))
! oce_chip_ei(dev);
!
/* arm the eqs */
! oce_start_eqs(dev);
!
! /* get link status */
! if (oce_get_link_status(dev, &dev->link_status, &dev->link_speed,
! (uint8_t *)&dev->link_duplex, 1, MBX_ASYNC_MQ) != DDI_SUCCESS) {
! (void) oce_get_link_status(dev, &dev->link_status,
! &dev->link_speed, (uint8_t *)&dev->link_duplex,
! 0, MBX_ASYNC_MQ);
}
! oce_log(dev, CE_NOTE, MOD_CONFIG, "link speed %d "
! "link status %d", dev->link_speed, dev->link_status);
!
! mac_link_update(dev->mac_handle, dev->link_status);
return (DDI_SUCCESS);
+
+ delete_queues:
+ oce_delete_queues(dev);
+ cleanup_handler:
+ (void) oce_di(dev);
+ return (DDI_FAILURE);
} /* oce_start */
void
oce_m_stop(void *arg)
{
struct oce_dev *dev = arg;
+ int i;
mutex_enter(&dev->dev_lock);
if (dev->suspended) {
mutex_exit(&dev->dev_lock);
return;
}
!
! dev->state &= ~STATE_MAC_STARTED;
oce_stop(dev);
!
! /* free Tx buffers */
! oce_fini_tx(dev);
!
! for (i = 0; i < dev->rx_rings; i++) {
! while (dev->rq[i].pending > 0) {
! oce_log(dev, CE_NOTE, MOD_CONFIG,
! "%d pending buffers on rq %p\n",
! dev->rq[i].pending, (void *)&dev->rq[i]);
! drv_usecwait(10 * 1000);
! }
! }
!
! /* destroy group locks */
! for (i = 0; i < dev->num_rx_groups; i++) {
! mutex_destroy(&dev->rx_group[i].grp_lock);
! }
!
mutex_exit(&dev->dev_lock);
+ oce_disable_wd_timer(dev);
}
+
+
/* called with Tx/Rx comp locks held */
void
oce_stop(struct oce_dev *dev)
{
int qidx;
+
+ dev->state |= STATE_MAC_STOPPING;
+
/* disable interrupts */
! (void) oce_di(dev);
! oce_stop_eqs(dev);
! dev->state &= (~STATE_INTR_ENABLED);
!
for (qidx = 0; qidx < dev->nwqs; qidx++) {
! mac_ring_intr_set(dev->default_tx_rings[qidx].tx->handle, NULL);
! mutex_enter(&dev->wq[qidx].tx_lock);
}
mutex_enter(&dev->mq->lock);
!
! for (qidx = 0; qidx < dev->tx_rings; qidx++) {
! /* stop and flush the Tx */
! (void) oce_clean_wq(dev->default_tx_rings[qidx].tx);
! }
!
! /* Free the pending commands */
! oce_clean_mq(dev->mq);
!
/* Release all the locks */
mutex_exit(&dev->mq->lock);
for (qidx = 0; qidx < dev->nwqs; qidx++)
! mutex_exit(&dev->wq[qidx].tx_lock);
!
if (dev->link_status == LINK_STATE_UP) {
dev->link_status = LINK_STATE_UNKNOWN;
mac_link_update(dev->mac_handle, dev->link_status);
}
+ oce_delete_mcc_queue(dev);
+ oce_delete_queues(dev);
+
+ dev->state &= ~STATE_MAC_STOPPING;
} /* oce_stop */
+
int
oce_m_multicast(void *arg, boolean_t add, const uint8_t *mca)
{
struct oce_dev *dev = (struct oce_dev *)arg;
struct ether_addr *mca_drv_list;
*** 163,176 ****
struct ether_addr mca_hw_list[OCE_MAX_MCA];
uint16_t new_mcnt = dev->num_mca;
int ret;
int i;
- /* check the address */
- if ((mca[0] & 0x1) == 0) {
- return (EINVAL);
- }
/* Allocate the local array for holding the addresses temporarily */
bzero(&mca_hw_list, sizeof (&mca_hw_list));
mca_drv_list = &dev->multi_cast[0];
DEV_LOCK(dev);
--- 261,270 ----
*** 192,220 ****
/* copy only if it does not match */
if (bcmp((mca_drv_list + i), mca, ETHERADDRL)) {
bcopy(mca_drv_list + i, hwlistp,
ETHERADDRL);
hwlistp++;
- } else {
- new_mcnt--;
}
}
}
if (dev->suspended) {
goto finish;
}
if (new_mcnt > OCE_MAX_MCA) {
ret = oce_set_multicast_table(dev, dev->if_id, &mca_hw_list[0],
! OCE_MAX_MCA, B_TRUE);
} else {
ret = oce_set_multicast_table(dev, dev->if_id,
! &mca_hw_list[0], new_mcnt, B_FALSE);
}
if (ret != 0) {
oce_log(dev, CE_WARN, MOD_CONFIG,
! "mcast %s fails", add ? "ADD" : "DEL");
DEV_UNLOCK(dev);
return (EIO);
}
/*
* Copy the local structure to dev structure
--- 286,314 ----
/* copy only if it does not match */
if (bcmp((mca_drv_list + i), mca, ETHERADDRL)) {
bcopy(mca_drv_list + i, hwlistp,
ETHERADDRL);
hwlistp++;
}
}
+ /* Decrement the count */
+ new_mcnt--;
}
if (dev->suspended) {
goto finish;
}
if (new_mcnt > OCE_MAX_MCA) {
ret = oce_set_multicast_table(dev, dev->if_id, &mca_hw_list[0],
! OCE_MAX_MCA, B_TRUE, MBX_BOOTSTRAP);
} else {
ret = oce_set_multicast_table(dev, dev->if_id,
! &mca_hw_list[0], new_mcnt, B_FALSE, MBX_BOOTSTRAP);
}
if (ret != 0) {
oce_log(dev, CE_WARN, MOD_CONFIG,
! "mcast %s failed 0x%x", add ? "ADD" : "DEL", ret);
DEV_UNLOCK(dev);
return (EIO);
}
/*
* Copy the local structure to dev structure
*** 233,320 ****
mca[0], mca[1], mca[2], mca[3], mca[4], mca[5],
dev->num_mca);
return (0);
} /* oce_m_multicast */
- int
- oce_m_unicast(void *arg, const uint8_t *uca)
- {
- struct oce_dev *dev = arg;
- int ret;
- DEV_LOCK(dev);
- if (dev->suspended) {
- bcopy(uca, dev->unicast_addr, ETHERADDRL);
- dev->num_smac = 0;
- DEV_UNLOCK(dev);
- return (DDI_SUCCESS);
- }
-
- /* Delete previous one and add new one */
- ret = oce_del_mac(dev, dev->if_id, &dev->pmac_id);
- if (ret != DDI_SUCCESS) {
- DEV_UNLOCK(dev);
- return (EIO);
- }
- dev->num_smac = 0;
- bzero(dev->unicast_addr, ETHERADDRL);
-
- /* Set the New MAC addr earlier is no longer valid */
- ret = oce_add_mac(dev, dev->if_id, uca, &dev->pmac_id);
- if (ret != DDI_SUCCESS) {
- DEV_UNLOCK(dev);
- return (EIO);
- }
- bcopy(uca, dev->unicast_addr, ETHERADDRL);
- dev->num_smac = 1;
- DEV_UNLOCK(dev);
- return (ret);
- } /* oce_m_unicast */
-
- /*
- * Hashing policy for load balancing over the set of TX rings
- * available to the driver.
- */
- mblk_t *
- oce_m_send(void *arg, mblk_t *mp)
- {
- struct oce_dev *dev = arg;
- mblk_t *nxt_pkt;
- mblk_t *rmp = NULL;
- struct oce_wq *wq;
-
- DEV_LOCK(dev);
- if (dev->suspended || !(dev->state & STATE_MAC_STARTED)) {
- DEV_UNLOCK(dev);
- freemsg(mp);
- return (NULL);
- }
- DEV_UNLOCK(dev);
- /*
- * Hash to pick a wq
- */
- wq = oce_get_wq(dev, mp);
-
- while (mp != NULL) {
- /* Save the Pointer since mp will be freed in case of copy */
- nxt_pkt = mp->b_next;
- mp->b_next = NULL;
- /* Hardcode wq since we have only one */
- rmp = oce_send_packet(wq, mp);
- if (rmp != NULL) {
- /* reschedule Tx */
- wq->resched = B_TRUE;
- oce_arm_cq(dev, wq->cq->cq_id, 0, B_TRUE);
- /* restore the chain */
- rmp->b_next = nxt_pkt;
- break;
- }
- mp = nxt_pkt;
- }
- return (rmp);
- } /* oce_send */
-
boolean_t
oce_m_getcap(void *arg, mac_capab_t cap, void *data)
{
struct oce_dev *dev = arg;
boolean_t ret = B_TRUE;
--- 327,337 ----
*** 335,344 ****
--- 352,366 ----
} else {
ret = B_FALSE;
}
break;
}
+ case MAC_CAPAB_RINGS:
+
+ ret = oce_fill_rings_capab(dev, (mac_capab_rings_t *)data);
+ break;
+
default:
ret = B_FALSE;
break;
}
return (ret);
*** 366,375 ****
--- 388,402 ----
if (mtu != OCE_MIN_MTU && mtu != OCE_MAX_MTU) {
ret = EINVAL;
break;
}
+ if (dev->state & STATE_MAC_STARTED) {
+ ret = EBUSY;
+ break;
+ }
+
ret = mac_maxsdu_update(dev->mac_handle, mtu);
if (0 == ret) {
dev->mtu = mtu;
break;
}
*** 412,422 ****
if (dev->suspended) {
dev->flow_control = fc;
break;
}
/* call to set flow control */
! ret = oce_set_flow_control(dev, fc);
/* store the new fc setting on success */
if (ret == 0) {
dev->flow_control = fc;
}
break;
--- 439,449 ----
if (dev->suspended) {
dev->flow_control = fc;
break;
}
/* call to set flow control */
! ret = oce_set_flow_control(dev, fc, MBX_ASYNC_MQ);
/* store the new fc setting on success */
if (ret == 0) {
dev->flow_control = fc;
}
break;
*** 458,483 ****
*mode = LINK_DUPLEX_UNKNOWN;
break;
}
case MAC_PROP_SPEED: {
! uint64_t *speed = (uint64_t *)val;
! struct link_status link = {0};
!
! ASSERT(size >= sizeof (uint64_t));
! *speed = 0;
!
! if (dev->state & STATE_MAC_STARTED) {
! if (dev->link_speed < 0) {
! (void) oce_get_link_status(dev, &link);
! dev->link_speed = link.qos_link_speed ?
! link.qos_link_speed * 10 :
! pow10[link.mac_speed];
! }
!
! *speed = dev->link_speed * 1000000ull;
! }
break;
}
case MAC_PROP_FLOWCTRL: {
link_flowctrl_t *fc = (link_flowctrl_t *)val;
--- 485,497 ----
*mode = LINK_DUPLEX_UNKNOWN;
break;
}
case MAC_PROP_SPEED: {
! uint64_t speed;
! speed = dev->link_speed * 1000000ull;
! bcopy(&speed, val, sizeof (speed));
break;
}
case MAC_PROP_FLOWCTRL: {
link_flowctrl_t *fc = (link_flowctrl_t *)val;
*** 543,564 ****
break;
case MAC_PROP_PRIVATE: {
char valstr[64];
int value;
! if (strcmp(name, "_tx_ring_size") == 0) {
value = OCE_DEFAULT_TX_RING_SIZE;
} else if (strcmp(name, "_rx_ring_size") == 0) {
value = OCE_DEFAULT_RX_RING_SIZE;
! } else {
return;
- }
(void) snprintf(valstr, sizeof (valstr), "%d", value);
mac_prop_info_set_default_str(prh, valstr);
! mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
break;
}
}
} /* oce_m_propinfo */
--- 557,601 ----
break;
case MAC_PROP_PRIVATE: {
char valstr[64];
int value;
+ uint_t perm = MAC_PROP_PERM_READ;
! bzero(valstr, sizeof (valstr));
! if (strcmp(name, "_tx_rings") == 0) {
! value = OCE_DEFAULT_WQS;
! } else if (strcmp(name, "_tx_ring_size") == 0) {
value = OCE_DEFAULT_TX_RING_SIZE;
+ perm = MAC_PROP_PERM_RW;
+ } else if (strcmp(name, "_tx_bcopy_limit") == 0) {
+ value = OCE_DEFAULT_TX_BCOPY_LIMIT;
+ perm = MAC_PROP_PERM_RW;
+ } else if (strcmp(name, "_tx_reclaim_threshold") == 0) {
+ value = OCE_DEFAULT_TX_RECLAIM_THRESHOLD;
+ perm = MAC_PROP_PERM_RW;
+ } else if (strcmp(name, "_rx_rings") == 0) {
+ value = OCE_DEFAULT_RQS;
+ } else if (strcmp(name, "_rx_rings_per_group") == 0) {
+ value = OCE_DEF_RING_PER_GROUP;
} else if (strcmp(name, "_rx_ring_size") == 0) {
value = OCE_DEFAULT_RX_RING_SIZE;
! } else if (strcmp(name, "_rx_bcopy_limit") == 0) {
! value = OCE_DEFAULT_RX_BCOPY_LIMIT;
! perm = MAC_PROP_PERM_RW;
! } else if (strcmp(name, "_rx_pkts_per_intr") == 0) {
! value = OCE_DEFAULT_RX_PKTS_PER_INTR;
! perm = MAC_PROP_PERM_RW;
! } else if (strcmp(name, "_log_level") == 0) {
! value = OCE_DEFAULT_LOG_SETTINGS;
! perm = MAC_PROP_PERM_RW;
! } else
return;
(void) snprintf(valstr, sizeof (valstr), "%d", value);
mac_prop_info_set_default_str(prh, valstr);
! mac_prop_info_set_perm(prh, perm);
break;
}
}
} /* oce_m_propinfo */
*** 587,597 ****
DEV_UNLOCK(dev);
switch (cmd) {
case OCE_ISSUE_MBOX: {
! ret = oce_issue_mbox(dev, wq, mp, &payload_length);
miocack(wq, mp, payload_length, ret);
break;
}
case OCE_QUERY_DRIVER_DATA: {
struct oce_driver_query *drv_query =
--- 624,634 ----
DEV_UNLOCK(dev);
switch (cmd) {
case OCE_ISSUE_MBOX: {
! ret = oce_issue_mbox_passthru(dev, wq, mp, &payload_length);
miocack(wq, mp, payload_length, ret);
break;
}
case OCE_QUERY_DRIVER_DATA: {
struct oce_driver_query *drv_query =
*** 657,669 ****
dev->promisc = enable;
DEV_UNLOCK(dev);
return (ret);
}
! ret = oce_set_promiscuous(dev, enable);
! if (ret == DDI_SUCCESS)
dev->promisc = enable;
DEV_UNLOCK(dev);
return (ret);
} /* oce_m_promiscuous */
/*
--- 694,720 ----
dev->promisc = enable;
DEV_UNLOCK(dev);
return (ret);
}
! ret = oce_set_promiscuous(dev, enable, MBX_ASYNC_MQ);
! if (ret == DDI_SUCCESS) {
dev->promisc = enable;
+ if (!(enable)) {
+ struct ether_addr *mca_drv_list;
+ mca_drv_list = &dev->multi_cast[0];
+ if (dev->num_mca > OCE_MAX_MCA) {
+ ret = oce_set_multicast_table(dev, dev->if_id,
+ &mca_drv_list[0], OCE_MAX_MCA, B_TRUE,
+ MBX_ASYNC_MQ);
+ } else {
+ ret = oce_set_multicast_table(dev, dev->if_id,
+ &mca_drv_list[0], dev->num_mca, B_FALSE,
+ MBX_ASYNC_MQ);
+ }
+ }
+ }
DEV_UNLOCK(dev);
return (ret);
} /* oce_m_promiscuous */
/*
*** 679,718 ****
*/
static int
oce_set_priv_prop(struct oce_dev *dev, const char *name,
uint_t size, const void *val)
{
! int ret = ENOTSUP;
long result;
_NOTE(ARGUNUSED(size));
if (NULL == val) {
! ret = EINVAL;
! return (ret);
}
-
- if (strcmp(name, "_tx_bcopy_limit") == 0) {
(void) ddi_strtol(val, (char **)NULL, 0, &result);
! if (result <= OCE_WQ_BUF_SIZE) {
if (result != dev->tx_bcopy_limit)
dev->tx_bcopy_limit = (uint32_t)result;
ret = 0;
- } else {
- ret = EINVAL;
}
}
! if (strcmp(name, "_rx_bcopy_limit") == 0) {
! (void) ddi_strtol(val, (char **)NULL, 0, &result);
! if (result <= OCE_RQ_BUF_SIZE) {
! if (result != dev->rx_bcopy_limit)
dev->rx_bcopy_limit = (uint32_t)result;
ret = 0;
- } else {
- ret = EINVAL;
}
}
return (ret);
} /* oce_set_priv_prop */
/*
--- 730,790 ----
*/
static int
oce_set_priv_prop(struct oce_dev *dev, const char *name,
uint_t size, const void *val)
{
! int ret = EINVAL;
long result;
_NOTE(ARGUNUSED(size));
if (NULL == val) {
! return (EINVAL);
}
(void) ddi_strtol(val, (char **)NULL, 0, &result);
! if (strcmp(name, "_tx_ring_size") == 0) {
! if (result <= SIZE_2K) {
! if (dev->tx_ring_size != result) {
! dev->tx_ring_size = (uint32_t)result;
! }
! ret = 0;
! }
! } else if (strcmp(name, "_tx_bcopy_limit") == 0) {
! if (result <= SIZE_2K) {
if (result != dev->tx_bcopy_limit)
dev->tx_bcopy_limit = (uint32_t)result;
ret = 0;
}
+ } else if (strcmp(name, "_tx_reclaim_threshold") == 0) {
+ if (result <= dev->tx_ring_size) {
+ if (dev->tx_reclaim_threshold != result) {
+ dev->tx_reclaim_threshold = (uint32_t)result;
}
! ret = 0;
! }
! } else if (strcmp(name, "_rx_bcopy_limit") == 0) {
! if (result <= dev->mtu) {
! if (dev->rx_bcopy_limit != result) {
dev->rx_bcopy_limit = (uint32_t)result;
+ }
ret = 0;
}
+ } else if (strcmp(name, "_rx_pkts_per_intr") == 0) {
+ if (result <= dev->rx_ring_size) {
+ if (dev->rx_pkt_per_intr != result) {
+ dev->rx_pkt_per_intr = (uint32_t)result;
}
+ ret = 0;
+ }
+ } else if (strcmp(name, "_log_level") == 0) {
+ if (result <= OCE_MAX_LOG_SETTINGS) {
+ /* derive from the loglevel */
+ dev->severity = (uint16_t)(result & 0xffff);
+ dev->mod_mask = (uint16_t)(result >> 16);
+ }
+ ret = 0;
+ }
return (ret);
} /* oce_set_priv_prop */
/*
*** 729,746 ****
oce_get_priv_prop(struct oce_dev *dev, const char *name,
uint_t size, void *val)
{
int value;
! if (strcmp(name, "_tx_ring_size") == 0) {
value = dev->tx_ring_size;
} else if (strcmp(name, "_tx_bcopy_limit") == 0) {
value = dev->tx_bcopy_limit;
} else if (strcmp(name, "_rx_ring_size") == 0) {
value = dev->rx_ring_size;
} else if (strcmp(name, "_rx_bcopy_limit") == 0) {
value = dev->rx_bcopy_limit;
} else {
return (ENOTSUP);
}
(void) snprintf(val, size, "%d", value);
--- 801,830 ----
oce_get_priv_prop(struct oce_dev *dev, const char *name,
uint_t size, void *val)
{
int value;
! if (strcmp(name, "_tx_rings") == 0) {
! value = dev->tx_rings;
! } else if (strcmp(name, "_tx_ring_size") == 0) {
value = dev->tx_ring_size;
} else if (strcmp(name, "_tx_bcopy_limit") == 0) {
value = dev->tx_bcopy_limit;
+ } else if (strcmp(name, "_tx_reclaim_threshold") == 0) {
+ value = dev->tx_reclaim_threshold;
+ } else if (strcmp(name, "_rx_rings") == 0) {
+ value = dev->rx_rings;
+ } else if (strcmp(name, "_rx_rings_per_group") == 0) {
+ value = dev->rx_rings_per_group;
} else if (strcmp(name, "_rx_ring_size") == 0) {
value = dev->rx_ring_size;
} else if (strcmp(name, "_rx_bcopy_limit") == 0) {
value = dev->rx_bcopy_limit;
+ } else if (strcmp(name, "_rx_pkts_per_intr") == 0) {
+ value = dev->rx_pkt_per_intr;
+ } else if (strcmp(name, "_log_level") == 0) {
+ value = (dev->mod_mask << 16UL) | dev->severity;
} else {
return (ENOTSUP);
}
(void) snprintf(val, size, "%d", value);