14d0e5007SSukumar Swaminathan /*
24d0e5007SSukumar Swaminathan * CDDL HEADER START
34d0e5007SSukumar Swaminathan *
44d0e5007SSukumar Swaminathan * The contents of this file are subject to the terms of the
54d0e5007SSukumar Swaminathan * Common Development and Distribution License (the "License").
64d0e5007SSukumar Swaminathan * You may not use this file except in compliance with the License.
74d0e5007SSukumar Swaminathan *
84d0e5007SSukumar Swaminathan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94d0e5007SSukumar Swaminathan * or http://www.opensolaris.org/os/licensing.
104d0e5007SSukumar Swaminathan * See the License for the specific language governing permissions
114d0e5007SSukumar Swaminathan * and limitations under the License.
124d0e5007SSukumar Swaminathan *
134d0e5007SSukumar Swaminathan * When distributing Covered Code, include this CDDL HEADER in each
144d0e5007SSukumar Swaminathan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154d0e5007SSukumar Swaminathan * If applicable, add the following below this CDDL HEADER, with the
164d0e5007SSukumar Swaminathan * fields enclosed by brackets "[]" replaced with your own identifying
174d0e5007SSukumar Swaminathan * information: Portions Copyright [yyyy] [name of copyright owner]
184d0e5007SSukumar Swaminathan *
194d0e5007SSukumar Swaminathan * CDDL HEADER END
204d0e5007SSukumar Swaminathan */
214d0e5007SSukumar Swaminathan
223abb112fSGarrett D'Amore /* Copyright © 2003-2011 Emulex. All rights reserved. */
234d0e5007SSukumar Swaminathan
2415c07adcSJohn Levon /*
2515c07adcSJohn Levon * Copyright (c) 2018, Joyent, Inc.
2615c07adcSJohn Levon */
2715c07adcSJohn Levon
284d0e5007SSukumar Swaminathan /*
294d0e5007SSukumar Swaminathan * Source file containing the implementation of the driver entry points
304d0e5007SSukumar Swaminathan * and related helper functions
314d0e5007SSukumar Swaminathan */
324d0e5007SSukumar Swaminathan
334d0e5007SSukumar Swaminathan #include <oce_impl.h>
344d0e5007SSukumar Swaminathan #include <oce_ioctl.h>
354d0e5007SSukumar Swaminathan
364d0e5007SSukumar Swaminathan /* array of properties supported by this driver */
370dc2366fSVenugopal Iyer char *oce_priv_props[] = {
380dc2366fSVenugopal Iyer "_tx_ring_size",
390dc2366fSVenugopal Iyer "_tx_bcopy_limit",
400dc2366fSVenugopal Iyer "_rx_ring_size",
411878b971SVenugopal Iyer "_rx_bcopy_limit",
420dc2366fSVenugopal Iyer NULL
434d0e5007SSukumar Swaminathan };
444d0e5007SSukumar Swaminathan
455b9d3151SSukumar Swaminathan extern int pow10[];
465b9d3151SSukumar Swaminathan
474d0e5007SSukumar Swaminathan /* ---[ static function declarations ]----------------------------------- */
484d0e5007SSukumar Swaminathan static int oce_set_priv_prop(struct oce_dev *dev, const char *name,
494d0e5007SSukumar Swaminathan uint_t size, const void *val);
504d0e5007SSukumar Swaminathan
514d0e5007SSukumar Swaminathan static int oce_get_priv_prop(struct oce_dev *dev, const char *name,
520dc2366fSVenugopal Iyer uint_t size, void *val);
534d0e5007SSukumar Swaminathan
544d0e5007SSukumar Swaminathan /* ---[ GLD entry points ]----------------------------------------------- */
554d0e5007SSukumar Swaminathan int
oce_m_start(void * arg)564d0e5007SSukumar Swaminathan oce_m_start(void *arg)
574d0e5007SSukumar Swaminathan {
584d0e5007SSukumar Swaminathan struct oce_dev *dev = arg;
594d0e5007SSukumar Swaminathan int ret;
604d0e5007SSukumar Swaminathan
614d0e5007SSukumar Swaminathan mutex_enter(&dev->dev_lock);
624d0e5007SSukumar Swaminathan
634d0e5007SSukumar Swaminathan if (dev->state & STATE_MAC_STARTED) {
644d0e5007SSukumar Swaminathan mutex_exit(&dev->dev_lock);
654d0e5007SSukumar Swaminathan return (0);
664d0e5007SSukumar Swaminathan }
674d0e5007SSukumar Swaminathan
684d0e5007SSukumar Swaminathan if (dev->suspended) {
694d0e5007SSukumar Swaminathan mutex_exit(&dev->dev_lock);
704d0e5007SSukumar Swaminathan return (EIO);
714d0e5007SSukumar Swaminathan }
724d0e5007SSukumar Swaminathan ret = oce_start(dev);
734d0e5007SSukumar Swaminathan if (ret != DDI_SUCCESS) {
744d0e5007SSukumar Swaminathan mutex_exit(&dev->dev_lock);
754d0e5007SSukumar Swaminathan return (EIO);
764d0e5007SSukumar Swaminathan }
774d0e5007SSukumar Swaminathan
784d0e5007SSukumar Swaminathan dev->state |= STATE_MAC_STARTED;
794d0e5007SSukumar Swaminathan mutex_exit(&dev->dev_lock);
804d0e5007SSukumar Swaminathan
814d0e5007SSukumar Swaminathan
824d0e5007SSukumar Swaminathan return (DDI_SUCCESS);
834d0e5007SSukumar Swaminathan }
844d0e5007SSukumar Swaminathan
854d0e5007SSukumar Swaminathan int
oce_start(struct oce_dev * dev)864d0e5007SSukumar Swaminathan oce_start(struct oce_dev *dev)
874d0e5007SSukumar Swaminathan {
884d0e5007SSukumar Swaminathan int qidx = 0;
895b9d3151SSukumar Swaminathan struct link_status link = {0};
904d0e5007SSukumar Swaminathan
914d0e5007SSukumar Swaminathan /* get link status */
925b9d3151SSukumar Swaminathan (void) oce_get_link_status(dev, &link);
934d0e5007SSukumar Swaminathan
945b9d3151SSukumar Swaminathan dev->link_status = (link.logical_link_status == NTWK_LOGICAL_LINK_UP) ?
955b9d3151SSukumar Swaminathan LINK_STATE_UP : LINK_STATE_DOWN;
965b9d3151SSukumar Swaminathan
975b9d3151SSukumar Swaminathan dev->link_speed = link.qos_link_speed ? link.qos_link_speed * 10 :
985b9d3151SSukumar Swaminathan pow10[link.mac_speed];
998d738d7dSSukumar Swaminathan
1005b9d3151SSukumar Swaminathan mac_link_update(dev->mac_handle, dev->link_status);
1015b9d3151SSukumar Swaminathan
1025b9d3151SSukumar Swaminathan for (qidx = 0; qidx < dev->nwqs; qidx++) {
1035b9d3151SSukumar Swaminathan (void) oce_start_wq(dev->wq[qidx]);
1045b9d3151SSukumar Swaminathan }
1055b9d3151SSukumar Swaminathan for (qidx = 0; qidx < dev->nrqs; qidx++) {
1065b9d3151SSukumar Swaminathan (void) oce_start_rq(dev->rq[qidx]);
1075b9d3151SSukumar Swaminathan }
1088d738d7dSSukumar Swaminathan (void) oce_start_mq(dev->mq);
1098d738d7dSSukumar Swaminathan /* enable interrupts */
1108d738d7dSSukumar Swaminathan oce_ei(dev);
1114d0e5007SSukumar Swaminathan /* arm the eqs */
1124d0e5007SSukumar Swaminathan for (qidx = 0; qidx < dev->neqs; qidx++) {
1134d0e5007SSukumar Swaminathan oce_arm_eq(dev, dev->eq[qidx]->eq_id, 0, B_TRUE, B_FALSE);
1144d0e5007SSukumar Swaminathan }
1155b9d3151SSukumar Swaminathan /* TODO update state */
1164d0e5007SSukumar Swaminathan return (DDI_SUCCESS);
1174d0e5007SSukumar Swaminathan } /* oce_start */
1184d0e5007SSukumar Swaminathan
1194d0e5007SSukumar Swaminathan
1204d0e5007SSukumar Swaminathan void
oce_m_stop(void * arg)1214d0e5007SSukumar Swaminathan oce_m_stop(void *arg)
1224d0e5007SSukumar Swaminathan {
1234d0e5007SSukumar Swaminathan struct oce_dev *dev = arg;
1244d0e5007SSukumar Swaminathan
1254d0e5007SSukumar Swaminathan /* disable interrupts */
1264d0e5007SSukumar Swaminathan
1274d0e5007SSukumar Swaminathan mutex_enter(&dev->dev_lock);
1284d0e5007SSukumar Swaminathan if (dev->suspended) {
1294d0e5007SSukumar Swaminathan mutex_exit(&dev->dev_lock);
1304d0e5007SSukumar Swaminathan return;
1314d0e5007SSukumar Swaminathan }
1328d738d7dSSukumar Swaminathan dev->state |= STATE_MAC_STOPPING;
1334d0e5007SSukumar Swaminathan oce_stop(dev);
1344d0e5007SSukumar Swaminathan dev->state &= ~(STATE_MAC_STOPPING | STATE_MAC_STARTED);
1354d0e5007SSukumar Swaminathan mutex_exit(&dev->dev_lock);
1364d0e5007SSukumar Swaminathan }
1378d738d7dSSukumar Swaminathan /* called with Tx/Rx comp locks held */
1384d0e5007SSukumar Swaminathan void
oce_stop(struct oce_dev * dev)1394d0e5007SSukumar Swaminathan oce_stop(struct oce_dev *dev)
1404d0e5007SSukumar Swaminathan {
1415b9d3151SSukumar Swaminathan int qidx;
1428d738d7dSSukumar Swaminathan /* disable interrupts */
1438d738d7dSSukumar Swaminathan oce_di(dev);
1445b9d3151SSukumar Swaminathan for (qidx = 0; qidx < dev->nwqs; qidx++) {
1455b9d3151SSukumar Swaminathan mutex_enter(&dev->wq[qidx]->tx_lock);
1465b9d3151SSukumar Swaminathan }
1478d738d7dSSukumar Swaminathan mutex_enter(&dev->mq->lock);
1488d738d7dSSukumar Swaminathan /* complete the pending Tx */
1495b9d3151SSukumar Swaminathan for (qidx = 0; qidx < dev->nwqs; qidx++)
1505b9d3151SSukumar Swaminathan oce_clean_wq(dev->wq[qidx]);
1518d738d7dSSukumar Swaminathan /* Release all the locks */
1528d738d7dSSukumar Swaminathan mutex_exit(&dev->mq->lock);
1535b9d3151SSukumar Swaminathan for (qidx = 0; qidx < dev->nwqs; qidx++)
1545b9d3151SSukumar Swaminathan mutex_exit(&dev->wq[qidx]->tx_lock);
1555b9d3151SSukumar Swaminathan if (dev->link_status == LINK_STATE_UP) {
1565b9d3151SSukumar Swaminathan dev->link_status = LINK_STATE_UNKNOWN;
1575b9d3151SSukumar Swaminathan mac_link_update(dev->mac_handle, dev->link_status);
1585b9d3151SSukumar Swaminathan }
1594d0e5007SSukumar Swaminathan
1604d0e5007SSukumar Swaminathan } /* oce_stop */
1614d0e5007SSukumar Swaminathan
1624d0e5007SSukumar Swaminathan int
oce_m_multicast(void * arg,boolean_t add,const uint8_t * mca)1634d0e5007SSukumar Swaminathan oce_m_multicast(void *arg, boolean_t add, const uint8_t *mca)
1644d0e5007SSukumar Swaminathan {
1654d0e5007SSukumar Swaminathan struct oce_dev *dev = (struct oce_dev *)arg;
1664d0e5007SSukumar Swaminathan struct ether_addr *mca_drv_list;
1678d738d7dSSukumar Swaminathan struct ether_addr mca_hw_list[OCE_MAX_MCA];
1685b9d3151SSukumar Swaminathan uint16_t new_mcnt = dev->num_mca;
1694d0e5007SSukumar Swaminathan int ret;
1704d0e5007SSukumar Swaminathan int i;
1714d0e5007SSukumar Swaminathan
1724d0e5007SSukumar Swaminathan /* check the address */
1734d0e5007SSukumar Swaminathan if ((mca[0] & 0x1) == 0) {
1744d0e5007SSukumar Swaminathan return (EINVAL);
1754d0e5007SSukumar Swaminathan }
1764d0e5007SSukumar Swaminathan /* Allocate the local array for holding the addresses temporarily */
177*ce17336eSAndy Fiddaman bzero(&mca_hw_list, sizeof (mca_hw_list));
1784d0e5007SSukumar Swaminathan mca_drv_list = &dev->multi_cast[0];
1798d738d7dSSukumar Swaminathan
1808d738d7dSSukumar Swaminathan DEV_LOCK(dev);
1814d0e5007SSukumar Swaminathan if (add) {
1824d0e5007SSukumar Swaminathan /* check if we exceeded hw max supported */
1835b9d3151SSukumar Swaminathan if (new_mcnt < OCE_MAX_MCA) {
1848d738d7dSSukumar Swaminathan /* copy entire dev mca to the mbx */
1858d738d7dSSukumar Swaminathan bcopy((void*)mca_drv_list,
1868d738d7dSSukumar Swaminathan (void*)mca_hw_list,
1878d738d7dSSukumar Swaminathan (dev->num_mca * sizeof (struct ether_addr)));
1888d738d7dSSukumar Swaminathan /* Append the new one to local list */
1898d738d7dSSukumar Swaminathan bcopy(mca, &mca_hw_list[dev->num_mca],
1908d738d7dSSukumar Swaminathan sizeof (struct ether_addr));
1914d0e5007SSukumar Swaminathan }
1925b9d3151SSukumar Swaminathan new_mcnt++;
1934d0e5007SSukumar Swaminathan } else {
1948d738d7dSSukumar Swaminathan struct ether_addr *hwlistp = &mca_hw_list[0];
1954d0e5007SSukumar Swaminathan for (i = 0; i < dev->num_mca; i++) {
1964d0e5007SSukumar Swaminathan /* copy only if it does not match */
1974d0e5007SSukumar Swaminathan if (bcmp((mca_drv_list + i), mca, ETHERADDRL)) {
1984d0e5007SSukumar Swaminathan bcopy(mca_drv_list + i, hwlistp,
1994d0e5007SSukumar Swaminathan ETHERADDRL);
2004d0e5007SSukumar Swaminathan hwlistp++;
2015b9d3151SSukumar Swaminathan } else {
2025b9d3151SSukumar Swaminathan new_mcnt--;
2034d0e5007SSukumar Swaminathan }
2044d0e5007SSukumar Swaminathan }
2054d0e5007SSukumar Swaminathan }
2064d0e5007SSukumar Swaminathan
2074d0e5007SSukumar Swaminathan if (dev->suspended) {
2084d0e5007SSukumar Swaminathan goto finish;
2094d0e5007SSukumar Swaminathan }
2105b9d3151SSukumar Swaminathan if (new_mcnt > OCE_MAX_MCA) {
2115b9d3151SSukumar Swaminathan ret = oce_set_multicast_table(dev, dev->if_id, &mca_hw_list[0],
2125b9d3151SSukumar Swaminathan OCE_MAX_MCA, B_TRUE);
2138d738d7dSSukumar Swaminathan } else {
2148d738d7dSSukumar Swaminathan ret = oce_set_multicast_table(dev, dev->if_id,
2158d738d7dSSukumar Swaminathan &mca_hw_list[0], new_mcnt, B_FALSE);
2168d738d7dSSukumar Swaminathan }
21715c07adcSJohn Levon if (ret != 0) {
2183abb112fSGarrett D'Amore oce_log(dev, CE_WARN, MOD_CONFIG,
2193abb112fSGarrett D'Amore "mcast %s fails", add ? "ADD" : "DEL");
2208d738d7dSSukumar Swaminathan DEV_UNLOCK(dev);
2214d0e5007SSukumar Swaminathan return (EIO);
2224d0e5007SSukumar Swaminathan }
2234d0e5007SSukumar Swaminathan /*
2244d0e5007SSukumar Swaminathan * Copy the local structure to dev structure
2254d0e5007SSukumar Swaminathan */
2264d0e5007SSukumar Swaminathan finish:
2278d738d7dSSukumar Swaminathan if (new_mcnt && new_mcnt <= OCE_MAX_MCA) {
2288d738d7dSSukumar Swaminathan bcopy(mca_hw_list, mca_drv_list,
2298d738d7dSSukumar Swaminathan new_mcnt * sizeof (struct ether_addr));
2305b9d3151SSukumar Swaminathan
2315b9d3151SSukumar Swaminathan dev->num_mca = (uint16_t)new_mcnt;
2328d738d7dSSukumar Swaminathan }
2338d738d7dSSukumar Swaminathan DEV_UNLOCK(dev);
2343abb112fSGarrett D'Amore oce_log(dev, CE_NOTE, MOD_CONFIG,
2353abb112fSGarrett D'Amore "mcast %s, addr=%02x:%02x:%02x:%02x:%02x:%02x, num_mca=%d",
2363abb112fSGarrett D'Amore add ? "ADD" : "DEL",
2373abb112fSGarrett D'Amore mca[0], mca[1], mca[2], mca[3], mca[4], mca[5],
2383abb112fSGarrett D'Amore dev->num_mca);
2394d0e5007SSukumar Swaminathan return (0);
2404d0e5007SSukumar Swaminathan } /* oce_m_multicast */
2414d0e5007SSukumar Swaminathan
2424d0e5007SSukumar Swaminathan int
oce_m_unicast(void * arg,const uint8_t * uca)2434d0e5007SSukumar Swaminathan oce_m_unicast(void *arg, const uint8_t *uca)
2444d0e5007SSukumar Swaminathan {
2454d0e5007SSukumar Swaminathan struct oce_dev *dev = arg;
2464d0e5007SSukumar Swaminathan int ret;
2474d0e5007SSukumar Swaminathan
2484d0e5007SSukumar Swaminathan DEV_LOCK(dev);
2494d0e5007SSukumar Swaminathan if (dev->suspended) {
2504d0e5007SSukumar Swaminathan bcopy(uca, dev->unicast_addr, ETHERADDRL);
2513abb112fSGarrett D'Amore dev->num_smac = 0;
2524d0e5007SSukumar Swaminathan DEV_UNLOCK(dev);
2534d0e5007SSukumar Swaminathan return (DDI_SUCCESS);
2544d0e5007SSukumar Swaminathan }
2554d0e5007SSukumar Swaminathan
2564d0e5007SSukumar Swaminathan /* Delete previous one and add new one */
2578d738d7dSSukumar Swaminathan ret = oce_del_mac(dev, dev->if_id, &dev->pmac_id);
2584d0e5007SSukumar Swaminathan if (ret != DDI_SUCCESS) {
2598d738d7dSSukumar Swaminathan DEV_UNLOCK(dev);
2604d0e5007SSukumar Swaminathan return (EIO);
2614d0e5007SSukumar Swaminathan }
2623abb112fSGarrett D'Amore dev->num_smac = 0;
2635b9d3151SSukumar Swaminathan bzero(dev->unicast_addr, ETHERADDRL);
2644d0e5007SSukumar Swaminathan
2654d0e5007SSukumar Swaminathan /* Set the New MAC addr earlier is no longer valid */
2668d738d7dSSukumar Swaminathan ret = oce_add_mac(dev, dev->if_id, uca, &dev->pmac_id);
2674d0e5007SSukumar Swaminathan if (ret != DDI_SUCCESS) {
2688d738d7dSSukumar Swaminathan DEV_UNLOCK(dev);
2694d0e5007SSukumar Swaminathan return (EIO);
2704d0e5007SSukumar Swaminathan }
2715b9d3151SSukumar Swaminathan bcopy(uca, dev->unicast_addr, ETHERADDRL);
2723abb112fSGarrett D'Amore dev->num_smac = 1;
2738d738d7dSSukumar Swaminathan DEV_UNLOCK(dev);
2744d0e5007SSukumar Swaminathan return (ret);
2754d0e5007SSukumar Swaminathan } /* oce_m_unicast */
2764d0e5007SSukumar Swaminathan
2775b9d3151SSukumar Swaminathan /*
2785b9d3151SSukumar Swaminathan * Hashing policy for load balancing over the set of TX rings
2795b9d3151SSukumar Swaminathan * available to the driver.
2805b9d3151SSukumar Swaminathan */
2814d0e5007SSukumar Swaminathan mblk_t *
oce_m_send(void * arg,mblk_t * mp)2824d0e5007SSukumar Swaminathan oce_m_send(void *arg, mblk_t *mp)
2834d0e5007SSukumar Swaminathan {
2844d0e5007SSukumar Swaminathan struct oce_dev *dev = arg;
2854d0e5007SSukumar Swaminathan mblk_t *nxt_pkt;
2864d0e5007SSukumar Swaminathan mblk_t *rmp = NULL;
2878d738d7dSSukumar Swaminathan struct oce_wq *wq;
2884d0e5007SSukumar Swaminathan
2894d0e5007SSukumar Swaminathan DEV_LOCK(dev);
2908d738d7dSSukumar Swaminathan if (dev->suspended || !(dev->state & STATE_MAC_STARTED)) {
2914d0e5007SSukumar Swaminathan DEV_UNLOCK(dev);
2924d0e5007SSukumar Swaminathan freemsg(mp);
2934d0e5007SSukumar Swaminathan return (NULL);
2944d0e5007SSukumar Swaminathan }
2954d0e5007SSukumar Swaminathan DEV_UNLOCK(dev);
2965b9d3151SSukumar Swaminathan /*
2975b9d3151SSukumar Swaminathan * Hash to pick a wq
2985b9d3151SSukumar Swaminathan */
2995b9d3151SSukumar Swaminathan wq = oce_get_wq(dev, mp);
3004d0e5007SSukumar Swaminathan
3014d0e5007SSukumar Swaminathan while (mp != NULL) {
3024d0e5007SSukumar Swaminathan /* Save the Pointer since mp will be freed in case of copy */
3034d0e5007SSukumar Swaminathan nxt_pkt = mp->b_next;
3044d0e5007SSukumar Swaminathan mp->b_next = NULL;
3054d0e5007SSukumar Swaminathan /* Hardcode wq since we have only one */
3068d738d7dSSukumar Swaminathan rmp = oce_send_packet(wq, mp);
3074d0e5007SSukumar Swaminathan if (rmp != NULL) {
3088d738d7dSSukumar Swaminathan /* reschedule Tx */
3098d738d7dSSukumar Swaminathan wq->resched = B_TRUE;
3108d738d7dSSukumar Swaminathan oce_arm_cq(dev, wq->cq->cq_id, 0, B_TRUE);
3114d0e5007SSukumar Swaminathan /* restore the chain */
3124d0e5007SSukumar Swaminathan rmp->b_next = nxt_pkt;
3134d0e5007SSukumar Swaminathan break;
3144d0e5007SSukumar Swaminathan }
3154d0e5007SSukumar Swaminathan mp = nxt_pkt;
3164d0e5007SSukumar Swaminathan }
3174d0e5007SSukumar Swaminathan return (rmp);
3184d0e5007SSukumar Swaminathan } /* oce_send */
3194d0e5007SSukumar Swaminathan
3204d0e5007SSukumar Swaminathan boolean_t
oce_m_getcap(void * arg,mac_capab_t cap,void * data)3214d0e5007SSukumar Swaminathan oce_m_getcap(void *arg, mac_capab_t cap, void *data)
3224d0e5007SSukumar Swaminathan {
3234d0e5007SSukumar Swaminathan struct oce_dev *dev = arg;
3244d0e5007SSukumar Swaminathan boolean_t ret = B_TRUE;
3254d0e5007SSukumar Swaminathan switch (cap) {
3264d0e5007SSukumar Swaminathan
3274d0e5007SSukumar Swaminathan case MAC_CAPAB_HCKSUM: {
3284d0e5007SSukumar Swaminathan uint32_t *csum_flags = u32ptr(data);
3294d0e5007SSukumar Swaminathan *csum_flags = HCKSUM_ENABLE |
3304d0e5007SSukumar Swaminathan HCKSUM_INET_FULL_V4 |
3314d0e5007SSukumar Swaminathan HCKSUM_IPHDRCKSUM;
3324d0e5007SSukumar Swaminathan break;
3334d0e5007SSukumar Swaminathan }
3344d0e5007SSukumar Swaminathan case MAC_CAPAB_LSO: {
3354d0e5007SSukumar Swaminathan mac_capab_lso_t *mcap_lso = (mac_capab_lso_t *)data;
3364d0e5007SSukumar Swaminathan if (dev->lso_capable) {
3374d0e5007SSukumar Swaminathan mcap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4;
3384d0e5007SSukumar Swaminathan mcap_lso->lso_basic_tcp_ipv4.lso_max = OCE_LSO_MAX_SIZE;
3394d0e5007SSukumar Swaminathan } else {
3404d0e5007SSukumar Swaminathan ret = B_FALSE;
3414d0e5007SSukumar Swaminathan }
3424d0e5007SSukumar Swaminathan break;
3434d0e5007SSukumar Swaminathan }
3444d0e5007SSukumar Swaminathan default:
3454d0e5007SSukumar Swaminathan ret = B_FALSE;
3464d0e5007SSukumar Swaminathan break;
3474d0e5007SSukumar Swaminathan }
3484d0e5007SSukumar Swaminathan return (ret);
3494d0e5007SSukumar Swaminathan } /* oce_m_getcap */
3504d0e5007SSukumar Swaminathan
3514d0e5007SSukumar Swaminathan int
oce_m_setprop(void * arg,const char * name,mac_prop_id_t id,uint_t size,const void * val)3524d0e5007SSukumar Swaminathan oce_m_setprop(void *arg, const char *name, mac_prop_id_t id,
3534d0e5007SSukumar Swaminathan uint_t size, const void *val)
3544d0e5007SSukumar Swaminathan {
3554d0e5007SSukumar Swaminathan struct oce_dev *dev = arg;
3564d0e5007SSukumar Swaminathan int ret = 0;
3574d0e5007SSukumar Swaminathan
3588d738d7dSSukumar Swaminathan DEV_LOCK(dev);
3594d0e5007SSukumar Swaminathan switch (id) {
3604d0e5007SSukumar Swaminathan case MAC_PROP_MTU: {
3614d0e5007SSukumar Swaminathan uint32_t mtu;
3624d0e5007SSukumar Swaminathan
3634d0e5007SSukumar Swaminathan bcopy(val, &mtu, sizeof (uint32_t));
3644d0e5007SSukumar Swaminathan
3654d0e5007SSukumar Swaminathan if (dev->mtu == mtu) {
3664d0e5007SSukumar Swaminathan ret = 0;
3674d0e5007SSukumar Swaminathan break;
3684d0e5007SSukumar Swaminathan }
3694d0e5007SSukumar Swaminathan
3704d0e5007SSukumar Swaminathan if (mtu != OCE_MIN_MTU && mtu != OCE_MAX_MTU) {
3714d0e5007SSukumar Swaminathan ret = EINVAL;
3724d0e5007SSukumar Swaminathan break;
3734d0e5007SSukumar Swaminathan }
3744d0e5007SSukumar Swaminathan
3754d0e5007SSukumar Swaminathan ret = mac_maxsdu_update(dev->mac_handle, mtu);
3764d0e5007SSukumar Swaminathan if (0 == ret) {
3774d0e5007SSukumar Swaminathan dev->mtu = mtu;
3784d0e5007SSukumar Swaminathan break;
3794d0e5007SSukumar Swaminathan }
3804d0e5007SSukumar Swaminathan break;
3814d0e5007SSukumar Swaminathan }
3824d0e5007SSukumar Swaminathan
3834d0e5007SSukumar Swaminathan case MAC_PROP_FLOWCTRL: {
3844d0e5007SSukumar Swaminathan link_flowctrl_t flowctrl;
3854d0e5007SSukumar Swaminathan uint32_t fc = 0;
3864d0e5007SSukumar Swaminathan
3874d0e5007SSukumar Swaminathan bcopy(val, &flowctrl, sizeof (link_flowctrl_t));
3884d0e5007SSukumar Swaminathan
3894d0e5007SSukumar Swaminathan switch (flowctrl) {
3904d0e5007SSukumar Swaminathan case LINK_FLOWCTRL_NONE:
3914d0e5007SSukumar Swaminathan fc = 0;
3924d0e5007SSukumar Swaminathan break;
3934d0e5007SSukumar Swaminathan
3944d0e5007SSukumar Swaminathan case LINK_FLOWCTRL_RX:
3954d0e5007SSukumar Swaminathan fc = OCE_FC_RX;
3964d0e5007SSukumar Swaminathan break;
3974d0e5007SSukumar Swaminathan
3984d0e5007SSukumar Swaminathan case LINK_FLOWCTRL_TX:
3994d0e5007SSukumar Swaminathan fc = OCE_FC_TX;
4004d0e5007SSukumar Swaminathan break;
4014d0e5007SSukumar Swaminathan
4024d0e5007SSukumar Swaminathan case LINK_FLOWCTRL_BI:
4034d0e5007SSukumar Swaminathan fc = OCE_FC_RX | OCE_FC_TX;
4044d0e5007SSukumar Swaminathan break;
4054d0e5007SSukumar Swaminathan default:
4064d0e5007SSukumar Swaminathan ret = EINVAL;
4074d0e5007SSukumar Swaminathan break;
4084d0e5007SSukumar Swaminathan } /* switch flowctrl */
4094d0e5007SSukumar Swaminathan
4104d0e5007SSukumar Swaminathan if (ret)
4114d0e5007SSukumar Swaminathan break;
4124d0e5007SSukumar Swaminathan
4134d0e5007SSukumar Swaminathan if (fc == dev->flow_control)
4144d0e5007SSukumar Swaminathan break;
4154d0e5007SSukumar Swaminathan
4164d0e5007SSukumar Swaminathan if (dev->suspended) {
4174d0e5007SSukumar Swaminathan dev->flow_control = fc;
4184d0e5007SSukumar Swaminathan break;
4194d0e5007SSukumar Swaminathan }
4204d0e5007SSukumar Swaminathan /* call to set flow control */
4214d0e5007SSukumar Swaminathan ret = oce_set_flow_control(dev, fc);
4224d0e5007SSukumar Swaminathan /* store the new fc setting on success */
4234d0e5007SSukumar Swaminathan if (ret == 0) {
4244d0e5007SSukumar Swaminathan dev->flow_control = fc;
4254d0e5007SSukumar Swaminathan }
4264d0e5007SSukumar Swaminathan break;
4274d0e5007SSukumar Swaminathan }
4284d0e5007SSukumar Swaminathan
4294d0e5007SSukumar Swaminathan case MAC_PROP_PRIVATE:
4304d0e5007SSukumar Swaminathan ret = oce_set_priv_prop(dev, name, size, val);
4314d0e5007SSukumar Swaminathan break;
4324d0e5007SSukumar Swaminathan
4334d0e5007SSukumar Swaminathan default:
4344d0e5007SSukumar Swaminathan ret = ENOTSUP;
4354d0e5007SSukumar Swaminathan break;
4364d0e5007SSukumar Swaminathan } /* switch id */
4374d0e5007SSukumar Swaminathan
4388d738d7dSSukumar Swaminathan DEV_UNLOCK(dev);
4394d0e5007SSukumar Swaminathan return (ret);
4404d0e5007SSukumar Swaminathan } /* oce_m_setprop */
4414d0e5007SSukumar Swaminathan
4424d0e5007SSukumar Swaminathan int
oce_m_getprop(void * arg,const char * name,mac_prop_id_t id,uint_t size,void * val)4434d0e5007SSukumar Swaminathan oce_m_getprop(void *arg, const char *name, mac_prop_id_t id,
4440dc2366fSVenugopal Iyer uint_t size, void *val)
4454d0e5007SSukumar Swaminathan {
4464d0e5007SSukumar Swaminathan struct oce_dev *dev = arg;
4474d0e5007SSukumar Swaminathan uint32_t ret = 0;
4484d0e5007SSukumar Swaminathan
4494d0e5007SSukumar Swaminathan switch (id) {
4500dc2366fSVenugopal Iyer case MAC_PROP_ADV_10GFDX_CAP:
4510dc2366fSVenugopal Iyer case MAC_PROP_EN_10GFDX_CAP:
4524d0e5007SSukumar Swaminathan *(uint8_t *)val = 0x01;
4534d0e5007SSukumar Swaminathan break;
4544d0e5007SSukumar Swaminathan
4554d0e5007SSukumar Swaminathan case MAC_PROP_DUPLEX: {
4560dc2366fSVenugopal Iyer uint32_t *mode = (uint32_t *)val;
4574d0e5007SSukumar Swaminathan
4580dc2366fSVenugopal Iyer ASSERT(size >= sizeof (link_duplex_t));
4590dc2366fSVenugopal Iyer if (dev->state & STATE_MAC_STARTED)
4600dc2366fSVenugopal Iyer *mode = LINK_DUPLEX_FULL;
4610dc2366fSVenugopal Iyer else
4620dc2366fSVenugopal Iyer *mode = LINK_DUPLEX_UNKNOWN;
4634d0e5007SSukumar Swaminathan break;
4644d0e5007SSukumar Swaminathan }
4654d0e5007SSukumar Swaminathan
4664d0e5007SSukumar Swaminathan case MAC_PROP_SPEED: {
4670dc2366fSVenugopal Iyer uint64_t *speed = (uint64_t *)val;
4685b9d3151SSukumar Swaminathan struct link_status link = {0};
4694d0e5007SSukumar Swaminathan
4700dc2366fSVenugopal Iyer ASSERT(size >= sizeof (uint64_t));
4710dc2366fSVenugopal Iyer *speed = 0;
4725b9d3151SSukumar Swaminathan
4735b9d3151SSukumar Swaminathan if (dev->state & STATE_MAC_STARTED) {
4745b9d3151SSukumar Swaminathan if (dev->link_speed < 0) {
4755b9d3151SSukumar Swaminathan (void) oce_get_link_status(dev, &link);
4765b9d3151SSukumar Swaminathan dev->link_speed = link.qos_link_speed ?
4775b9d3151SSukumar Swaminathan link.qos_link_speed * 10 :
4785b9d3151SSukumar Swaminathan pow10[link.mac_speed];
4795b9d3151SSukumar Swaminathan }
4805b9d3151SSukumar Swaminathan
4815b9d3151SSukumar Swaminathan *speed = dev->link_speed * 1000000ull;
4824d0e5007SSukumar Swaminathan }
4834d0e5007SSukumar Swaminathan break;
4844d0e5007SSukumar Swaminathan }
4854d0e5007SSukumar Swaminathan
4864d0e5007SSukumar Swaminathan case MAC_PROP_FLOWCTRL: {
4874d0e5007SSukumar Swaminathan link_flowctrl_t *fc = (link_flowctrl_t *)val;
4884d0e5007SSukumar Swaminathan
4890dc2366fSVenugopal Iyer ASSERT(size >= sizeof (link_flowctrl_t));
4900dc2366fSVenugopal Iyer if (dev->flow_control & OCE_FC_TX &&
4910dc2366fSVenugopal Iyer dev->flow_control & OCE_FC_RX)
4920dc2366fSVenugopal Iyer *fc = LINK_FLOWCTRL_BI;
4930dc2366fSVenugopal Iyer else if (dev->flow_control == OCE_FC_TX)
4940dc2366fSVenugopal Iyer *fc = LINK_FLOWCTRL_TX;
4950dc2366fSVenugopal Iyer else if (dev->flow_control == OCE_FC_RX)
4960dc2366fSVenugopal Iyer *fc = LINK_FLOWCTRL_RX;
4970dc2366fSVenugopal Iyer else if (dev->flow_control == 0)
4980dc2366fSVenugopal Iyer *fc = LINK_FLOWCTRL_NONE;
4990dc2366fSVenugopal Iyer else
5004d0e5007SSukumar Swaminathan ret = EINVAL;
5014d0e5007SSukumar Swaminathan break;
5024d0e5007SSukumar Swaminathan }
5034d0e5007SSukumar Swaminathan
5040dc2366fSVenugopal Iyer case MAC_PROP_PRIVATE:
5050dc2366fSVenugopal Iyer ret = oce_get_priv_prop(dev, name, size, val);
5064d0e5007SSukumar Swaminathan break;
5070dc2366fSVenugopal Iyer
5084d0e5007SSukumar Swaminathan default:
5098d738d7dSSukumar Swaminathan ret = ENOTSUP;
5104d0e5007SSukumar Swaminathan break;
5114d0e5007SSukumar Swaminathan } /* switch id */
5124d0e5007SSukumar Swaminathan return (ret);
5134d0e5007SSukumar Swaminathan } /* oce_m_getprop */
5144d0e5007SSukumar Swaminathan
5150dc2366fSVenugopal Iyer void
oce_m_propinfo(void * arg,const char * name,mac_prop_id_t pr_num,mac_prop_info_handle_t prh)5160dc2366fSVenugopal Iyer oce_m_propinfo(void *arg, const char *name, mac_prop_id_t pr_num,
5170dc2366fSVenugopal Iyer mac_prop_info_handle_t prh)
5180dc2366fSVenugopal Iyer {
5190dc2366fSVenugopal Iyer _NOTE(ARGUNUSED(arg));
5200dc2366fSVenugopal Iyer
5210dc2366fSVenugopal Iyer switch (pr_num) {
5220dc2366fSVenugopal Iyer case MAC_PROP_AUTONEG:
5230dc2366fSVenugopal Iyer case MAC_PROP_EN_AUTONEG:
5240dc2366fSVenugopal Iyer case MAC_PROP_ADV_1000FDX_CAP:
5250dc2366fSVenugopal Iyer case MAC_PROP_EN_1000FDX_CAP:
5260dc2366fSVenugopal Iyer case MAC_PROP_ADV_1000HDX_CAP:
5270dc2366fSVenugopal Iyer case MAC_PROP_EN_1000HDX_CAP:
5280dc2366fSVenugopal Iyer case MAC_PROP_ADV_100FDX_CAP:
5290dc2366fSVenugopal Iyer case MAC_PROP_EN_100FDX_CAP:
5300dc2366fSVenugopal Iyer case MAC_PROP_ADV_100HDX_CAP:
5310dc2366fSVenugopal Iyer case MAC_PROP_EN_100HDX_CAP:
5320dc2366fSVenugopal Iyer case MAC_PROP_ADV_10FDX_CAP:
5330dc2366fSVenugopal Iyer case MAC_PROP_EN_10FDX_CAP:
5340dc2366fSVenugopal Iyer case MAC_PROP_ADV_10HDX_CAP:
5350dc2366fSVenugopal Iyer case MAC_PROP_EN_10HDX_CAP:
5360dc2366fSVenugopal Iyer case MAC_PROP_ADV_100T4_CAP:
5370dc2366fSVenugopal Iyer case MAC_PROP_EN_100T4_CAP:
5380dc2366fSVenugopal Iyer case MAC_PROP_ADV_10GFDX_CAP:
5390dc2366fSVenugopal Iyer case MAC_PROP_EN_10GFDX_CAP:
5400dc2366fSVenugopal Iyer case MAC_PROP_SPEED:
5410dc2366fSVenugopal Iyer case MAC_PROP_DUPLEX:
5420dc2366fSVenugopal Iyer mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
5430dc2366fSVenugopal Iyer break;
5440dc2366fSVenugopal Iyer
5450dc2366fSVenugopal Iyer case MAC_PROP_MTU:
5460dc2366fSVenugopal Iyer mac_prop_info_set_range_uint32(prh, OCE_MIN_MTU, OCE_MAX_MTU);
5470dc2366fSVenugopal Iyer break;
5480dc2366fSVenugopal Iyer
5490dc2366fSVenugopal Iyer case MAC_PROP_PRIVATE: {
5500dc2366fSVenugopal Iyer char valstr[64];
5510dc2366fSVenugopal Iyer int value;
5520dc2366fSVenugopal Iyer
5530dc2366fSVenugopal Iyer if (strcmp(name, "_tx_ring_size") == 0) {
5540dc2366fSVenugopal Iyer value = OCE_DEFAULT_TX_RING_SIZE;
5550dc2366fSVenugopal Iyer } else if (strcmp(name, "_rx_ring_size") == 0) {
5560dc2366fSVenugopal Iyer value = OCE_DEFAULT_RX_RING_SIZE;
5570dc2366fSVenugopal Iyer } else {
5580dc2366fSVenugopal Iyer return;
5590dc2366fSVenugopal Iyer }
5600dc2366fSVenugopal Iyer
5610dc2366fSVenugopal Iyer (void) snprintf(valstr, sizeof (valstr), "%d", value);
5620dc2366fSVenugopal Iyer mac_prop_info_set_default_str(prh, valstr);
56312d61dabSSukumar Swaminathan mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
5640dc2366fSVenugopal Iyer break;
5650dc2366fSVenugopal Iyer }
5660dc2366fSVenugopal Iyer }
5670dc2366fSVenugopal Iyer } /* oce_m_propinfo */
5680dc2366fSVenugopal Iyer
5694d0e5007SSukumar Swaminathan /*
5704d0e5007SSukumar Swaminathan * function to handle dlpi streams message from GLDv3 mac layer
5714d0e5007SSukumar Swaminathan */
5724d0e5007SSukumar Swaminathan void
oce_m_ioctl(void * arg,queue_t * wq,mblk_t * mp)5734d0e5007SSukumar Swaminathan oce_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
5744d0e5007SSukumar Swaminathan {
5754d0e5007SSukumar Swaminathan struct oce_dev *dev = arg;
5764d0e5007SSukumar Swaminathan struct iocblk *iocp;
5774d0e5007SSukumar Swaminathan int cmd;
5784d0e5007SSukumar Swaminathan uint32_t payload_length;
5794d0e5007SSukumar Swaminathan int ret;
5804d0e5007SSukumar Swaminathan
5814d0e5007SSukumar Swaminathan iocp = (struct iocblk *)voidptr(mp->b_rptr);
5824d0e5007SSukumar Swaminathan iocp->ioc_error = 0;
5834d0e5007SSukumar Swaminathan cmd = iocp->ioc_cmd;
5844d0e5007SSukumar Swaminathan
5854d0e5007SSukumar Swaminathan DEV_LOCK(dev);
5864d0e5007SSukumar Swaminathan if (dev->suspended) {
5874d0e5007SSukumar Swaminathan miocnak(wq, mp, 0, EINVAL);
5884d0e5007SSukumar Swaminathan DEV_UNLOCK(dev);
5894d0e5007SSukumar Swaminathan return;
5904d0e5007SSukumar Swaminathan }
5914d0e5007SSukumar Swaminathan DEV_UNLOCK(dev);
5924d0e5007SSukumar Swaminathan
5934d0e5007SSukumar Swaminathan switch (cmd) {
5944d0e5007SSukumar Swaminathan
5954d0e5007SSukumar Swaminathan case OCE_ISSUE_MBOX: {
5964d0e5007SSukumar Swaminathan ret = oce_issue_mbox(dev, wq, mp, &payload_length);
5973abb112fSGarrett D'Amore miocack(wq, mp, payload_length, ret);
5983abb112fSGarrett D'Amore break;
5993abb112fSGarrett D'Amore }
6003abb112fSGarrett D'Amore case OCE_QUERY_DRIVER_DATA: {
6013abb112fSGarrett D'Amore struct oce_driver_query *drv_query =
6023abb112fSGarrett D'Amore (struct oce_driver_query *)(void *)mp->b_cont->b_rptr;
6033abb112fSGarrett D'Amore
6043abb112fSGarrett D'Amore /* if the driver version does not match bail */
6053abb112fSGarrett D'Amore if (drv_query->version != OCN_VERSION_SUPPORTED) {
6063abb112fSGarrett D'Amore oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
6073abb112fSGarrett D'Amore "One Connect version mismatch");
6083abb112fSGarrett D'Amore miocnak(wq, mp, 0, ENOTSUP);
6093abb112fSGarrett D'Amore break;
6103abb112fSGarrett D'Amore }
6113abb112fSGarrett D'Amore
6123abb112fSGarrett D'Amore /* fill the return values */
6133abb112fSGarrett D'Amore bcopy(OCE_MOD_NAME, drv_query->driver_name,
6143abb112fSGarrett D'Amore (sizeof (OCE_MOD_NAME) > 32) ?
6153abb112fSGarrett D'Amore 31 : sizeof (OCE_MOD_NAME));
6163abb112fSGarrett D'Amore drv_query->driver_name[31] = '\0';
6173abb112fSGarrett D'Amore
6183abb112fSGarrett D'Amore bcopy(OCE_VERSION, drv_query->driver_version,
6193abb112fSGarrett D'Amore (sizeof (OCE_VERSION) > 32) ? 31 :
6203abb112fSGarrett D'Amore sizeof (OCE_VERSION));
6213abb112fSGarrett D'Amore drv_query->driver_version[31] = '\0';
6223abb112fSGarrett D'Amore
6233abb112fSGarrett D'Amore if (dev->num_smac == 0) {
6243abb112fSGarrett D'Amore drv_query->num_smac = 1;
6253abb112fSGarrett D'Amore bcopy(dev->mac_addr, drv_query->smac_addr[0],
6263abb112fSGarrett D'Amore ETHERADDRL);
6274d0e5007SSukumar Swaminathan } else {
6283abb112fSGarrett D'Amore drv_query->num_smac = dev->num_smac;
6293abb112fSGarrett D'Amore bcopy(dev->unicast_addr, drv_query->smac_addr[0],
6303abb112fSGarrett D'Amore ETHERADDRL);
6314d0e5007SSukumar Swaminathan }
6323abb112fSGarrett D'Amore
6333abb112fSGarrett D'Amore bcopy(dev->mac_addr, drv_query->pmac_addr, ETHERADDRL);
6343abb112fSGarrett D'Amore
6353abb112fSGarrett D'Amore payload_length = sizeof (struct oce_driver_query);
6363abb112fSGarrett D'Amore miocack(wq, mp, payload_length, 0);
6374d0e5007SSukumar Swaminathan break;
6384d0e5007SSukumar Swaminathan }
6394d0e5007SSukumar Swaminathan
6404d0e5007SSukumar Swaminathan default:
6414d0e5007SSukumar Swaminathan miocnak(wq, mp, 0, ENOTSUP);
6424d0e5007SSukumar Swaminathan break;
6434d0e5007SSukumar Swaminathan }
6444d0e5007SSukumar Swaminathan } /* oce_m_ioctl */
6454d0e5007SSukumar Swaminathan
6464d0e5007SSukumar Swaminathan int
oce_m_promiscuous(void * arg,boolean_t enable)6474d0e5007SSukumar Swaminathan oce_m_promiscuous(void *arg, boolean_t enable)
6484d0e5007SSukumar Swaminathan {
6494d0e5007SSukumar Swaminathan struct oce_dev *dev = arg;
6504d0e5007SSukumar Swaminathan int ret = 0;
6514d0e5007SSukumar Swaminathan
6524d0e5007SSukumar Swaminathan DEV_LOCK(dev);
6534d0e5007SSukumar Swaminathan
6544d0e5007SSukumar Swaminathan if (dev->promisc == enable) {
6554d0e5007SSukumar Swaminathan DEV_UNLOCK(dev);
6564d0e5007SSukumar Swaminathan return (ret);
6574d0e5007SSukumar Swaminathan }
6584d0e5007SSukumar Swaminathan
6594d0e5007SSukumar Swaminathan if (dev->suspended) {
6608d738d7dSSukumar Swaminathan /* remember the setting */
6618d738d7dSSukumar Swaminathan dev->promisc = enable;
6624d0e5007SSukumar Swaminathan DEV_UNLOCK(dev);
6634d0e5007SSukumar Swaminathan return (ret);
6644d0e5007SSukumar Swaminathan }
6654d0e5007SSukumar Swaminathan
6664d0e5007SSukumar Swaminathan ret = oce_set_promiscuous(dev, enable);
6678d738d7dSSukumar Swaminathan if (ret == DDI_SUCCESS)
6688d738d7dSSukumar Swaminathan dev->promisc = enable;
6698d738d7dSSukumar Swaminathan DEV_UNLOCK(dev);
6704d0e5007SSukumar Swaminathan return (ret);
6714d0e5007SSukumar Swaminathan } /* oce_m_promiscuous */
6724d0e5007SSukumar Swaminathan
6734d0e5007SSukumar Swaminathan /*
6744d0e5007SSukumar Swaminathan * function to set a private property.
6754d0e5007SSukumar Swaminathan * Called from the set_prop GLD entry point
6764d0e5007SSukumar Swaminathan *
6774d0e5007SSukumar Swaminathan * dev - sofware handle to the device
6784d0e5007SSukumar Swaminathan * name - string containing the property name
6794d0e5007SSukumar Swaminathan * size - length of the string in name
6804d0e5007SSukumar Swaminathan * val - pointer to a location where the value to set is stored
6814d0e5007SSukumar Swaminathan *
6824d0e5007SSukumar Swaminathan * return EINVAL => invalid value in val 0 => success
6834d0e5007SSukumar Swaminathan */
6844d0e5007SSukumar Swaminathan static int
oce_set_priv_prop(struct oce_dev * dev,const char * name,uint_t size,const void * val)6854d0e5007SSukumar Swaminathan oce_set_priv_prop(struct oce_dev *dev, const char *name,
6864d0e5007SSukumar Swaminathan uint_t size, const void *val)
6874d0e5007SSukumar Swaminathan {
6884d0e5007SSukumar Swaminathan int ret = ENOTSUP;
6894d0e5007SSukumar Swaminathan long result;
6904d0e5007SSukumar Swaminathan
6914d0e5007SSukumar Swaminathan _NOTE(ARGUNUSED(size));
6924d0e5007SSukumar Swaminathan
6934d0e5007SSukumar Swaminathan if (NULL == val) {
6944d0e5007SSukumar Swaminathan ret = EINVAL;
6954d0e5007SSukumar Swaminathan return (ret);
6964d0e5007SSukumar Swaminathan }
6974d0e5007SSukumar Swaminathan
6984d0e5007SSukumar Swaminathan if (strcmp(name, "_tx_bcopy_limit") == 0) {
6994d0e5007SSukumar Swaminathan (void) ddi_strtol(val, (char **)NULL, 0, &result);
7004d0e5007SSukumar Swaminathan if (result <= OCE_WQ_BUF_SIZE) {
7018d738d7dSSukumar Swaminathan if (result != dev->tx_bcopy_limit)
7028d738d7dSSukumar Swaminathan dev->tx_bcopy_limit = (uint32_t)result;
7038d738d7dSSukumar Swaminathan ret = 0;
7048d738d7dSSukumar Swaminathan } else {
7058d738d7dSSukumar Swaminathan ret = EINVAL;
7068d738d7dSSukumar Swaminathan }
7078d738d7dSSukumar Swaminathan }
7088d738d7dSSukumar Swaminathan if (strcmp(name, "_rx_bcopy_limit") == 0) {
7098d738d7dSSukumar Swaminathan (void) ddi_strtol(val, (char **)NULL, 0, &result);
7108d738d7dSSukumar Swaminathan if (result <= OCE_RQ_BUF_SIZE) {
7118d738d7dSSukumar Swaminathan if (result != dev->rx_bcopy_limit)
7128d738d7dSSukumar Swaminathan dev->rx_bcopy_limit = (uint32_t)result;
7134d0e5007SSukumar Swaminathan ret = 0;
7144d0e5007SSukumar Swaminathan } else {
7154d0e5007SSukumar Swaminathan ret = EINVAL;
7164d0e5007SSukumar Swaminathan }
7174d0e5007SSukumar Swaminathan }
7184d0e5007SSukumar Swaminathan
7194d0e5007SSukumar Swaminathan return (ret);
7204d0e5007SSukumar Swaminathan } /* oce_set_priv_prop */
7214d0e5007SSukumar Swaminathan
7224d0e5007SSukumar Swaminathan /*
7234d0e5007SSukumar Swaminathan * function to get the value of a private property. Called from get_prop
7244d0e5007SSukumar Swaminathan *
7254d0e5007SSukumar Swaminathan * dev - software handle to the device
7264d0e5007SSukumar Swaminathan * name - string containing the property name
7274d0e5007SSukumar Swaminathan * size - length of the string contained name
7284d0e5007SSukumar Swaminathan * val - [OUT] pointer to the location where the result is returned
7294d0e5007SSukumar Swaminathan *
7304d0e5007SSukumar Swaminathan * return EINVAL => invalid request 0 => success
7314d0e5007SSukumar Swaminathan */
7324d0e5007SSukumar Swaminathan static int
oce_get_priv_prop(struct oce_dev * dev,const char * name,uint_t size,void * val)7334d0e5007SSukumar Swaminathan oce_get_priv_prop(struct oce_dev *dev, const char *name,
7340dc2366fSVenugopal Iyer uint_t size, void *val)
7354d0e5007SSukumar Swaminathan {
7364d0e5007SSukumar Swaminathan int value;
7374d0e5007SSukumar Swaminathan
7384d0e5007SSukumar Swaminathan if (strcmp(name, "_tx_ring_size") == 0) {
7390dc2366fSVenugopal Iyer value = dev->tx_ring_size;
7400dc2366fSVenugopal Iyer } else if (strcmp(name, "_tx_bcopy_limit") == 0) {
7418d738d7dSSukumar Swaminathan value = dev->tx_bcopy_limit;
7420dc2366fSVenugopal Iyer } else if (strcmp(name, "_rx_ring_size") == 0) {
7430dc2366fSVenugopal Iyer value = dev->rx_ring_size;
7440dc2366fSVenugopal Iyer } else if (strcmp(name, "_rx_bcopy_limit") == 0) {
7458d738d7dSSukumar Swaminathan value = dev->rx_bcopy_limit;
7460dc2366fSVenugopal Iyer } else {
7470dc2366fSVenugopal Iyer return (ENOTSUP);
7484d0e5007SSukumar Swaminathan }
7494d0e5007SSukumar Swaminathan
7500dc2366fSVenugopal Iyer (void) snprintf(val, size, "%d", value);
7510dc2366fSVenugopal Iyer return (0);
7524d0e5007SSukumar Swaminathan } /* oce_get_priv_prop */
753