1*14b24e2bSVaishali Kulkarni /* 2*14b24e2bSVaishali Kulkarni * CDDL HEADER START 3*14b24e2bSVaishali Kulkarni * 4*14b24e2bSVaishali Kulkarni * The contents of this file are subject to the terms of the 5*14b24e2bSVaishali Kulkarni * Common Development and Distribution License, v.1, (the "License"). 6*14b24e2bSVaishali Kulkarni * You may not use this file except in compliance with the License. 7*14b24e2bSVaishali Kulkarni * 8*14b24e2bSVaishali Kulkarni * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*14b24e2bSVaishali Kulkarni * or http://opensource.org/licenses/CDDL-1.0. 10*14b24e2bSVaishali Kulkarni * See the License for the specific language governing permissions 11*14b24e2bSVaishali Kulkarni * and limitations under the License. 12*14b24e2bSVaishali Kulkarni * 13*14b24e2bSVaishali Kulkarni * When distributing Covered Code, include this CDDL HEADER in each 14*14b24e2bSVaishali Kulkarni * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*14b24e2bSVaishali Kulkarni * If applicable, add the following below this CDDL HEADER, with the 16*14b24e2bSVaishali Kulkarni * fields enclosed by brackets "[]" replaced with your own identifying 17*14b24e2bSVaishali Kulkarni * information: Portions Copyright [yyyy] [name of copyright owner] 18*14b24e2bSVaishali Kulkarni * 19*14b24e2bSVaishali Kulkarni * CDDL HEADER END 20*14b24e2bSVaishali Kulkarni */ 21*14b24e2bSVaishali Kulkarni 22*14b24e2bSVaishali Kulkarni /* 23*14b24e2bSVaishali Kulkarni * Copyright 2014-2017 Cavium, Inc. 24*14b24e2bSVaishali Kulkarni * The contents of this file are subject to the terms of the Common Development 25*14b24e2bSVaishali Kulkarni * and Distribution License, v.1, (the "License"). 26*14b24e2bSVaishali Kulkarni 27*14b24e2bSVaishali Kulkarni * You may not use this file except in compliance with the License. 28*14b24e2bSVaishali Kulkarni 29*14b24e2bSVaishali Kulkarni * You can obtain a copy of the License at available 30*14b24e2bSVaishali Kulkarni * at http://opensource.org/licenses/CDDL-1.0 31*14b24e2bSVaishali Kulkarni 32*14b24e2bSVaishali Kulkarni * See the License for the specific language governing permissions and 33*14b24e2bSVaishali Kulkarni * limitations under the License. 34*14b24e2bSVaishali Kulkarni */ 35*14b24e2bSVaishali Kulkarni 36*14b24e2bSVaishali Kulkarni 37*14b24e2bSVaishali Kulkarni #include "qede.h" 38*14b24e2bSVaishali Kulkarni 39*14b24e2bSVaishali Kulkarni #define FP_LOCK(ptr) \ 40*14b24e2bSVaishali Kulkarni mutex_enter(&ptr->fp_lock); 41*14b24e2bSVaishali Kulkarni #define FP_UNLOCK(ptr) \ 42*14b24e2bSVaishali Kulkarni mutex_exit(&ptr->fp_lock); 43*14b24e2bSVaishali Kulkarni 44*14b24e2bSVaishali Kulkarni int 45*14b24e2bSVaishali Kulkarni qede_ucst_find(qede_t *qede, const uint8_t *mac_addr) 46*14b24e2bSVaishali Kulkarni { 47*14b24e2bSVaishali Kulkarni int slot; 48*14b24e2bSVaishali Kulkarni 49*14b24e2bSVaishali Kulkarni for(slot = 0; slot < qede->ucst_total; slot++) { 50*14b24e2bSVaishali Kulkarni if (bcmp(qede->ucst_mac[slot].mac_addr.ether_addr_octet, 51*14b24e2bSVaishali Kulkarni mac_addr, ETHERADDRL) == 0) { 52*14b24e2bSVaishali Kulkarni return (slot); 53*14b24e2bSVaishali Kulkarni } 54*14b24e2bSVaishali Kulkarni } 55*14b24e2bSVaishali Kulkarni return (-1); 56*14b24e2bSVaishali Kulkarni 57*14b24e2bSVaishali Kulkarni } 58*14b24e2bSVaishali Kulkarni 59*14b24e2bSVaishali Kulkarni static int 60*14b24e2bSVaishali Kulkarni qede_set_mac_addr(qede_t *qede, uint8_t *mac_addr, uint8_t fl) 61*14b24e2bSVaishali Kulkarni { 62*14b24e2bSVaishali Kulkarni struct ecore_filter_ucast params; 63*14b24e2bSVaishali Kulkarni 64*14b24e2bSVaishali Kulkarni memset(¶ms, 0, sizeof (params)); 65*14b24e2bSVaishali Kulkarni 66*14b24e2bSVaishali Kulkarni params.opcode = fl; 67*14b24e2bSVaishali Kulkarni params.type = ECORE_FILTER_MAC; 68*14b24e2bSVaishali Kulkarni params.is_rx_filter = true; 69*14b24e2bSVaishali Kulkarni params.is_tx_filter = true; 70*14b24e2bSVaishali Kulkarni COPY_ETH_ADDRESS(mac_addr, params.mac); 71*14b24e2bSVaishali Kulkarni 72*14b24e2bSVaishali Kulkarni return (ecore_filter_ucast_cmd(&qede->edev, 73*14b24e2bSVaishali Kulkarni ¶ms, ECORE_SPQ_MODE_EBLOCK, NULL)); 74*14b24e2bSVaishali Kulkarni 75*14b24e2bSVaishali Kulkarni 76*14b24e2bSVaishali Kulkarni } 77*14b24e2bSVaishali Kulkarni static int 78*14b24e2bSVaishali Kulkarni qede_add_macaddr(qede_t *qede, uint8_t *mac_addr) 79*14b24e2bSVaishali Kulkarni { 80*14b24e2bSVaishali Kulkarni int i, ret = 0; 81*14b24e2bSVaishali Kulkarni 82*14b24e2bSVaishali Kulkarni i = qede_ucst_find(qede, mac_addr); 83*14b24e2bSVaishali Kulkarni if (i != -1) { 84*14b24e2bSVaishali Kulkarni /* LINTED E_ARGUMENT_MISMATCH */ 85*14b24e2bSVaishali Kulkarni qede_info(qede, "mac addr already added %d\n", 86*14b24e2bSVaishali Kulkarni qede->ucst_avail); 87*14b24e2bSVaishali Kulkarni return (0); 88*14b24e2bSVaishali Kulkarni } 89*14b24e2bSVaishali Kulkarni if (qede->ucst_avail == 0) { 90*14b24e2bSVaishali Kulkarni qede_info(qede, "add macaddr ignored \n"); 91*14b24e2bSVaishali Kulkarni return (ENOSPC); 92*14b24e2bSVaishali Kulkarni } 93*14b24e2bSVaishali Kulkarni for (i = 0; i < qede->ucst_total; i++) { 94*14b24e2bSVaishali Kulkarni if (qede->ucst_mac[i].set == 0) { 95*14b24e2bSVaishali Kulkarni break; 96*14b24e2bSVaishali Kulkarni } 97*14b24e2bSVaishali Kulkarni } 98*14b24e2bSVaishali Kulkarni if (i >= qede->ucst_total) { 99*14b24e2bSVaishali Kulkarni qede_info(qede, "add macaddr ignored no space"); 100*14b24e2bSVaishali Kulkarni return (ENOSPC); 101*14b24e2bSVaishali Kulkarni } 102*14b24e2bSVaishali Kulkarni ret = qede_set_mac_addr(qede, (uint8_t *)mac_addr, ECORE_FILTER_ADD); 103*14b24e2bSVaishali Kulkarni if (ret == 0) { 104*14b24e2bSVaishali Kulkarni bcopy(mac_addr, 105*14b24e2bSVaishali Kulkarni qede->ucst_mac[i].mac_addr.ether_addr_octet, 106*14b24e2bSVaishali Kulkarni ETHERADDRL); 107*14b24e2bSVaishali Kulkarni qede->ucst_mac[i].set = 1; 108*14b24e2bSVaishali Kulkarni qede->ucst_avail--; 109*14b24e2bSVaishali Kulkarni /* LINTED E_ARGUMENT_MISMATCH */ 110*14b24e2bSVaishali Kulkarni qede_info(qede, " add macaddr passed for addr " 111*14b24e2bSVaishali Kulkarni "%02x:%02x:%02x:%02x:%02x:%02x", 112*14b24e2bSVaishali Kulkarni mac_addr[0], mac_addr[1], 113*14b24e2bSVaishali Kulkarni mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); 114*14b24e2bSVaishali Kulkarni } else { 115*14b24e2bSVaishali Kulkarni /* LINTED E_ARGUMENT_MISMATCH */ 116*14b24e2bSVaishali Kulkarni qede_info(qede, "add macaddr failed for addr " 117*14b24e2bSVaishali Kulkarni "%02x:%02x:%02x:%02x:%02x:%02x", 118*14b24e2bSVaishali Kulkarni mac_addr[0], mac_addr[1], 119*14b24e2bSVaishali Kulkarni mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); 120*14b24e2bSVaishali Kulkarni 121*14b24e2bSVaishali Kulkarni } 122*14b24e2bSVaishali Kulkarni if (qede->ucst_avail == (qede->ucst_total -1)) { 123*14b24e2bSVaishali Kulkarni u8 bcast_addr[] = 124*14b24e2bSVaishali Kulkarni { 125*14b24e2bSVaishali Kulkarni 0xff, 0xff, 0xff, 0xff, 0xff, 126*14b24e2bSVaishali Kulkarni 0xff 127*14b24e2bSVaishali Kulkarni }; 128*14b24e2bSVaishali Kulkarni for (i = 0; i < qede->ucst_total; i++) { 129*14b24e2bSVaishali Kulkarni if (qede->ucst_mac[i].set == 0) 130*14b24e2bSVaishali Kulkarni break; 131*14b24e2bSVaishali Kulkarni } 132*14b24e2bSVaishali Kulkarni ret = qede_set_mac_addr(qede, 133*14b24e2bSVaishali Kulkarni (uint8_t *)bcast_addr, ECORE_FILTER_ADD); 134*14b24e2bSVaishali Kulkarni if (ret == 0) { 135*14b24e2bSVaishali Kulkarni bcopy(bcast_addr, 136*14b24e2bSVaishali Kulkarni qede->ucst_mac[i].mac_addr.ether_addr_octet, 137*14b24e2bSVaishali Kulkarni ETHERADDRL); 138*14b24e2bSVaishali Kulkarni qede->ucst_mac[i].set = 1; 139*14b24e2bSVaishali Kulkarni qede->ucst_avail--; 140*14b24e2bSVaishali Kulkarni } else { 141*14b24e2bSVaishali Kulkarni 142*14b24e2bSVaishali Kulkarni /* LINTED E_ARGUMENT_MISMATCH */ 143*14b24e2bSVaishali Kulkarni qede_info(qede, "add macaddr failed for addr " 144*14b24e2bSVaishali Kulkarni "%02x:%02x:%02x:%02x:%02x:%02x", 145*14b24e2bSVaishali Kulkarni mac_addr[0], mac_addr[1], 146*14b24e2bSVaishali Kulkarni mac_addr[2], mac_addr[3], mac_addr[4], 147*14b24e2bSVaishali Kulkarni mac_addr[5]); 148*14b24e2bSVaishali Kulkarni } 149*14b24e2bSVaishali Kulkarni 150*14b24e2bSVaishali Kulkarni } 151*14b24e2bSVaishali Kulkarni 152*14b24e2bSVaishali Kulkarni return (ret); 153*14b24e2bSVaishali Kulkarni 154*14b24e2bSVaishali Kulkarni } 155*14b24e2bSVaishali Kulkarni 156*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS 157*14b24e2bSVaishali Kulkarni static int 158*14b24e2bSVaishali Kulkarni qede_add_mac_addr(void *arg, const uint8_t *mac_addr, const uint64_t flags) 159*14b24e2bSVaishali Kulkarni #else 160*14b24e2bSVaishali Kulkarni static int 161*14b24e2bSVaishali Kulkarni qede_add_mac_addr(void *arg, const uint8_t *mac_addr) 162*14b24e2bSVaishali Kulkarni #endif 163*14b24e2bSVaishali Kulkarni { 164*14b24e2bSVaishali Kulkarni qede_mac_group_t *rx_group = (qede_mac_group_t *)arg; 165*14b24e2bSVaishali Kulkarni qede_t *qede = rx_group->qede; 166*14b24e2bSVaishali Kulkarni int ret = DDI_SUCCESS; 167*14b24e2bSVaishali Kulkarni 168*14b24e2bSVaishali Kulkarni /* LINTED E_ARGUMENT_MISMATCH */ 169*14b24e2bSVaishali Kulkarni qede_info(qede, " mac addr :" MAC_STRING, MACTOSTR(mac_addr)); 170*14b24e2bSVaishali Kulkarni 171*14b24e2bSVaishali Kulkarni mutex_enter(&qede->gld_lock); 172*14b24e2bSVaishali Kulkarni if (qede->qede_state == QEDE_STATE_SUSPENDED) { 173*14b24e2bSVaishali Kulkarni mutex_exit(&qede->gld_lock); 174*14b24e2bSVaishali Kulkarni return (ECANCELED); 175*14b24e2bSVaishali Kulkarni } 176*14b24e2bSVaishali Kulkarni ret = qede_add_macaddr(qede, (uint8_t *)mac_addr); 177*14b24e2bSVaishali Kulkarni 178*14b24e2bSVaishali Kulkarni mutex_exit(&qede->gld_lock); 179*14b24e2bSVaishali Kulkarni 180*14b24e2bSVaishali Kulkarni 181*14b24e2bSVaishali Kulkarni return (ret); 182*14b24e2bSVaishali Kulkarni } 183*14b24e2bSVaishali Kulkarni 184*14b24e2bSVaishali Kulkarni static int 185*14b24e2bSVaishali Kulkarni qede_rem_macaddr(qede_t *qede, uint8_t *mac_addr) 186*14b24e2bSVaishali Kulkarni { 187*14b24e2bSVaishali Kulkarni int ret = 0; 188*14b24e2bSVaishali Kulkarni int i; 189*14b24e2bSVaishali Kulkarni 190*14b24e2bSVaishali Kulkarni i = qede_ucst_find(qede, mac_addr); 191*14b24e2bSVaishali Kulkarni if (i == -1) { 192*14b24e2bSVaishali Kulkarni /* LINTED E_ARGUMENT_MISMATCH */ 193*14b24e2bSVaishali Kulkarni qede_info(qede, 194*14b24e2bSVaishali Kulkarni "mac addr not there to remove", 195*14b24e2bSVaishali Kulkarni MAC_STRING, MACTOSTR(mac_addr)); 196*14b24e2bSVaishali Kulkarni return (0); 197*14b24e2bSVaishali Kulkarni } 198*14b24e2bSVaishali Kulkarni if (qede->ucst_mac[i].set == 0) { 199*14b24e2bSVaishali Kulkarni return (EINVAL); 200*14b24e2bSVaishali Kulkarni } 201*14b24e2bSVaishali Kulkarni ret = qede_set_mac_addr(qede, (uint8_t *)mac_addr, ECORE_FILTER_REMOVE); 202*14b24e2bSVaishali Kulkarni if (ret == 0) { 203*14b24e2bSVaishali Kulkarni bzero(qede->ucst_mac[i].mac_addr.ether_addr_octet,ETHERADDRL); 204*14b24e2bSVaishali Kulkarni qede->ucst_mac[i].set = 0; 205*14b24e2bSVaishali Kulkarni qede->ucst_avail++; 206*14b24e2bSVaishali Kulkarni } else { 207*14b24e2bSVaishali Kulkarni /* LINTED E_ARGUMENT_MISMATCH */ 208*14b24e2bSVaishali Kulkarni qede_info(qede, "mac addr remove failed", 209*14b24e2bSVaishali Kulkarni MAC_STRING, MACTOSTR(mac_addr)); 210*14b24e2bSVaishali Kulkarni } 211*14b24e2bSVaishali Kulkarni return (ret); 212*14b24e2bSVaishali Kulkarni 213*14b24e2bSVaishali Kulkarni } 214*14b24e2bSVaishali Kulkarni 215*14b24e2bSVaishali Kulkarni 216*14b24e2bSVaishali Kulkarni static int 217*14b24e2bSVaishali Kulkarni qede_rem_mac_addr(void *arg, const uint8_t *mac_addr) 218*14b24e2bSVaishali Kulkarni { 219*14b24e2bSVaishali Kulkarni qede_mac_group_t *rx_group = (qede_mac_group_t *)arg; 220*14b24e2bSVaishali Kulkarni qede_t *qede = rx_group->qede; 221*14b24e2bSVaishali Kulkarni int ret = DDI_SUCCESS; 222*14b24e2bSVaishali Kulkarni 223*14b24e2bSVaishali Kulkarni /* LINTED E_ARGUMENT_MISMATCH */ 224*14b24e2bSVaishali Kulkarni qede_info(qede, "mac addr remove:" MAC_STRING, MACTOSTR(mac_addr)); 225*14b24e2bSVaishali Kulkarni mutex_enter(&qede->gld_lock); 226*14b24e2bSVaishali Kulkarni if (qede->qede_state == QEDE_STATE_SUSPENDED) { 227*14b24e2bSVaishali Kulkarni mutex_exit(&qede->gld_lock); 228*14b24e2bSVaishali Kulkarni return (ECANCELED); 229*14b24e2bSVaishali Kulkarni } 230*14b24e2bSVaishali Kulkarni ret = qede_rem_macaddr(qede, (uint8_t *)mac_addr); 231*14b24e2bSVaishali Kulkarni mutex_exit(&qede->gld_lock); 232*14b24e2bSVaishali Kulkarni return (ret); 233*14b24e2bSVaishali Kulkarni } 234*14b24e2bSVaishali Kulkarni 235*14b24e2bSVaishali Kulkarni 236*14b24e2bSVaishali Kulkarni static int 237*14b24e2bSVaishali Kulkarni qede_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val) 238*14b24e2bSVaishali Kulkarni { 239*14b24e2bSVaishali Kulkarni int ret = 0; 240*14b24e2bSVaishali Kulkarni 241*14b24e2bSVaishali Kulkarni qede_fastpath_t *fp = (qede_fastpath_t *)rh; 242*14b24e2bSVaishali Kulkarni qede_tx_ring_t *tx_ring = fp->tx_ring[0]; 243*14b24e2bSVaishali Kulkarni qede_t *qede = fp->qede; 244*14b24e2bSVaishali Kulkarni 245*14b24e2bSVaishali Kulkarni 246*14b24e2bSVaishali Kulkarni if (qede->qede_state == QEDE_STATE_SUSPENDED) 247*14b24e2bSVaishali Kulkarni return (ECANCELED); 248*14b24e2bSVaishali Kulkarni 249*14b24e2bSVaishali Kulkarni switch (stat) { 250*14b24e2bSVaishali Kulkarni case MAC_STAT_OBYTES: 251*14b24e2bSVaishali Kulkarni *val = tx_ring->tx_byte_count; 252*14b24e2bSVaishali Kulkarni break; 253*14b24e2bSVaishali Kulkarni 254*14b24e2bSVaishali Kulkarni case MAC_STAT_OPACKETS: 255*14b24e2bSVaishali Kulkarni *val = tx_ring->tx_pkt_count; 256*14b24e2bSVaishali Kulkarni break; 257*14b24e2bSVaishali Kulkarni 258*14b24e2bSVaishali Kulkarni default: 259*14b24e2bSVaishali Kulkarni *val = 0; 260*14b24e2bSVaishali Kulkarni ret = ENOTSUP; 261*14b24e2bSVaishali Kulkarni } 262*14b24e2bSVaishali Kulkarni 263*14b24e2bSVaishali Kulkarni return (ret); 264*14b24e2bSVaishali Kulkarni } 265*14b24e2bSVaishali Kulkarni 266*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS 267*14b24e2bSVaishali Kulkarni static mblk_t * 268*14b24e2bSVaishali Kulkarni qede_rx_ring_poll(void *arg, int poll_bytes, int poll_pkts) 269*14b24e2bSVaishali Kulkarni { 270*14b24e2bSVaishali Kulkarni #else 271*14b24e2bSVaishali Kulkarni static mblk_t * 272*14b24e2bSVaishali Kulkarni qede_rx_ring_poll(void *arg, int poll_bytes) 273*14b24e2bSVaishali Kulkarni { 274*14b24e2bSVaishali Kulkarni /* XXX pick a value at the moment */ 275*14b24e2bSVaishali Kulkarni int poll_pkts = 100; 276*14b24e2bSVaishali Kulkarni #endif 277*14b24e2bSVaishali Kulkarni qede_fastpath_t *fp = (qede_fastpath_t *)arg; 278*14b24e2bSVaishali Kulkarni mblk_t *mp = NULL; 279*14b24e2bSVaishali Kulkarni int work_done = 0; 280*14b24e2bSVaishali Kulkarni qede_t *qede = fp->qede; 281*14b24e2bSVaishali Kulkarni 282*14b24e2bSVaishali Kulkarni if (poll_bytes == 0) { 283*14b24e2bSVaishali Kulkarni return (NULL); 284*14b24e2bSVaishali Kulkarni } 285*14b24e2bSVaishali Kulkarni 286*14b24e2bSVaishali Kulkarni mutex_enter(&fp->fp_lock); 287*14b24e2bSVaishali Kulkarni qede->intrSbPollCnt[fp->vect_info->vect_index]++; 288*14b24e2bSVaishali Kulkarni 289*14b24e2bSVaishali Kulkarni mp = qede_process_fastpath(fp, poll_bytes, poll_pkts, &work_done); 290*14b24e2bSVaishali Kulkarni if (mp != NULL) { 291*14b24e2bSVaishali Kulkarni fp->rx_ring->rx_poll_cnt++; 292*14b24e2bSVaishali Kulkarni } else if ((mp == NULL) && (work_done == 0)) { 293*14b24e2bSVaishali Kulkarni qede->intrSbPollNoChangeCnt[fp->vect_info->vect_index]++; 294*14b24e2bSVaishali Kulkarni } 295*14b24e2bSVaishali Kulkarni 296*14b24e2bSVaishali Kulkarni mutex_exit(&fp->fp_lock); 297*14b24e2bSVaishali Kulkarni return (mp); 298*14b24e2bSVaishali Kulkarni } 299*14b24e2bSVaishali Kulkarni 300*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS 301*14b24e2bSVaishali Kulkarni static int 302*14b24e2bSVaishali Kulkarni qede_rx_ring_intr_enable(mac_ring_driver_t rh) 303*14b24e2bSVaishali Kulkarni #else 304*14b24e2bSVaishali Kulkarni static int 305*14b24e2bSVaishali Kulkarni qede_rx_ring_intr_enable(mac_intr_handle_t rh) 306*14b24e2bSVaishali Kulkarni #endif 307*14b24e2bSVaishali Kulkarni { 308*14b24e2bSVaishali Kulkarni qede_fastpath_t *fp = (qede_fastpath_t *)rh; 309*14b24e2bSVaishali Kulkarni 310*14b24e2bSVaishali Kulkarni mutex_enter(&fp->qede->drv_lock); 311*14b24e2bSVaishali Kulkarni if (!fp->sb_phys && (fp->sb_dma_handle == NULL)) { 312*14b24e2bSVaishali Kulkarni mutex_exit(&fp->qede->drv_lock); 313*14b24e2bSVaishali Kulkarni return (DDI_FAILURE); 314*14b24e2bSVaishali Kulkarni } 315*14b24e2bSVaishali Kulkarni 316*14b24e2bSVaishali Kulkarni fp->rx_ring->intrEnableCnt++; 317*14b24e2bSVaishali Kulkarni qede_enable_hw_intr(fp); 318*14b24e2bSVaishali Kulkarni fp->disabled_by_poll = 0; 319*14b24e2bSVaishali Kulkarni mutex_exit(&fp->qede->drv_lock); 320*14b24e2bSVaishali Kulkarni 321*14b24e2bSVaishali Kulkarni return (DDI_SUCCESS); 322*14b24e2bSVaishali Kulkarni } 323*14b24e2bSVaishali Kulkarni 324*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS 325*14b24e2bSVaishali Kulkarni static int 326*14b24e2bSVaishali Kulkarni qede_rx_ring_intr_disable(mac_ring_driver_t rh) 327*14b24e2bSVaishali Kulkarni #else 328*14b24e2bSVaishali Kulkarni static int 329*14b24e2bSVaishali Kulkarni qede_rx_ring_intr_disable(mac_intr_handle_t rh) 330*14b24e2bSVaishali Kulkarni #endif 331*14b24e2bSVaishali Kulkarni { 332*14b24e2bSVaishali Kulkarni qede_fastpath_t *fp = (qede_fastpath_t *)rh; 333*14b24e2bSVaishali Kulkarni 334*14b24e2bSVaishali Kulkarni mutex_enter(&fp->qede->drv_lock); 335*14b24e2bSVaishali Kulkarni if (!fp->sb_phys && (fp->sb_dma_handle == NULL)) { 336*14b24e2bSVaishali Kulkarni mutex_exit(&fp->qede->drv_lock); 337*14b24e2bSVaishali Kulkarni return (DDI_FAILURE); 338*14b24e2bSVaishali Kulkarni } 339*14b24e2bSVaishali Kulkarni fp->rx_ring->intrDisableCnt++; 340*14b24e2bSVaishali Kulkarni qede_disable_hw_intr(fp); 341*14b24e2bSVaishali Kulkarni fp->disabled_by_poll = 1; 342*14b24e2bSVaishali Kulkarni mutex_exit(&fp->qede->drv_lock); 343*14b24e2bSVaishali Kulkarni return (DDI_SUCCESS); 344*14b24e2bSVaishali Kulkarni } 345*14b24e2bSVaishali Kulkarni 346*14b24e2bSVaishali Kulkarni static int 347*14b24e2bSVaishali Kulkarni qede_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val) 348*14b24e2bSVaishali Kulkarni { 349*14b24e2bSVaishali Kulkarni 350*14b24e2bSVaishali Kulkarni int ret = 0; 351*14b24e2bSVaishali Kulkarni 352*14b24e2bSVaishali Kulkarni qede_fastpath_t *fp = (qede_fastpath_t *)rh; 353*14b24e2bSVaishali Kulkarni qede_t *qede = fp->qede; 354*14b24e2bSVaishali Kulkarni qede_rx_ring_t *rx_ring = fp->rx_ring; 355*14b24e2bSVaishali Kulkarni 356*14b24e2bSVaishali Kulkarni if (qede->qede_state == QEDE_STATE_SUSPENDED) { 357*14b24e2bSVaishali Kulkarni return (ECANCELED); 358*14b24e2bSVaishali Kulkarni } 359*14b24e2bSVaishali Kulkarni 360*14b24e2bSVaishali Kulkarni switch (stat) { 361*14b24e2bSVaishali Kulkarni case MAC_STAT_RBYTES: 362*14b24e2bSVaishali Kulkarni *val = rx_ring->rx_byte_cnt; 363*14b24e2bSVaishali Kulkarni break; 364*14b24e2bSVaishali Kulkarni case MAC_STAT_IPACKETS: 365*14b24e2bSVaishali Kulkarni *val = rx_ring->rx_pkt_cnt; 366*14b24e2bSVaishali Kulkarni break; 367*14b24e2bSVaishali Kulkarni default: 368*14b24e2bSVaishali Kulkarni *val = 0; 369*14b24e2bSVaishali Kulkarni ret = ENOTSUP; 370*14b24e2bSVaishali Kulkarni break; 371*14b24e2bSVaishali Kulkarni } 372*14b24e2bSVaishali Kulkarni 373*14b24e2bSVaishali Kulkarni return (ret); 374*14b24e2bSVaishali Kulkarni } 375*14b24e2bSVaishali Kulkarni 376*14b24e2bSVaishali Kulkarni static int 377*14b24e2bSVaishali Kulkarni qede_get_global_ring_index(qede_t *qede, int gindex, int rindex) 378*14b24e2bSVaishali Kulkarni { 379*14b24e2bSVaishali Kulkarni qede_fastpath_t *fp; 380*14b24e2bSVaishali Kulkarni qede_rx_ring_t *rx_ring; 381*14b24e2bSVaishali Kulkarni int i = 0; 382*14b24e2bSVaishali Kulkarni 383*14b24e2bSVaishali Kulkarni for (i = 0; i < qede->num_fp; i++) { 384*14b24e2bSVaishali Kulkarni fp = &qede->fp_array[i]; 385*14b24e2bSVaishali Kulkarni rx_ring = fp->rx_ring; 386*14b24e2bSVaishali Kulkarni 387*14b24e2bSVaishali Kulkarni if (rx_ring->group_index == gindex) { 388*14b24e2bSVaishali Kulkarni rindex--; 389*14b24e2bSVaishali Kulkarni } 390*14b24e2bSVaishali Kulkarni if (rindex < 0) { 391*14b24e2bSVaishali Kulkarni return (i); 392*14b24e2bSVaishali Kulkarni } 393*14b24e2bSVaishali Kulkarni } 394*14b24e2bSVaishali Kulkarni 395*14b24e2bSVaishali Kulkarni return (-1); 396*14b24e2bSVaishali Kulkarni } 397*14b24e2bSVaishali Kulkarni 398*14b24e2bSVaishali Kulkarni static void 399*14b24e2bSVaishali Kulkarni qede_rx_ring_stop(mac_ring_driver_t rh) 400*14b24e2bSVaishali Kulkarni { 401*14b24e2bSVaishali Kulkarni qede_fastpath_t *fp = (qede_fastpath_t *)rh; 402*14b24e2bSVaishali Kulkarni qede_rx_ring_t *rx_ring = fp->rx_ring; 403*14b24e2bSVaishali Kulkarni 404*14b24e2bSVaishali Kulkarni qede_print("!%s(%d): called", __func__,fp->qede->instance); 405*14b24e2bSVaishali Kulkarni mutex_enter(&fp->fp_lock); 406*14b24e2bSVaishali Kulkarni rx_ring->mac_ring_started = B_FALSE; 407*14b24e2bSVaishali Kulkarni mutex_exit(&fp->fp_lock); 408*14b24e2bSVaishali Kulkarni } 409*14b24e2bSVaishali Kulkarni 410*14b24e2bSVaishali Kulkarni static int 411*14b24e2bSVaishali Kulkarni qede_rx_ring_start(mac_ring_driver_t rh, u64 mr_gen_num) 412*14b24e2bSVaishali Kulkarni { 413*14b24e2bSVaishali Kulkarni qede_fastpath_t *fp = (qede_fastpath_t *)rh; 414*14b24e2bSVaishali Kulkarni qede_rx_ring_t *rx_ring = fp->rx_ring; 415*14b24e2bSVaishali Kulkarni 416*14b24e2bSVaishali Kulkarni qede_print("!%s(%d): called", __func__,fp->qede->instance); 417*14b24e2bSVaishali Kulkarni mutex_enter(&fp->fp_lock); 418*14b24e2bSVaishali Kulkarni rx_ring->mr_gen_num = mr_gen_num; 419*14b24e2bSVaishali Kulkarni rx_ring->mac_ring_started = B_TRUE; 420*14b24e2bSVaishali Kulkarni rx_ring->intrDisableCnt = 0; 421*14b24e2bSVaishali Kulkarni rx_ring->intrEnableCnt = 0; 422*14b24e2bSVaishali Kulkarni fp->disabled_by_poll = 0; 423*14b24e2bSVaishali Kulkarni 424*14b24e2bSVaishali Kulkarni mutex_exit(&fp->fp_lock); 425*14b24e2bSVaishali Kulkarni 426*14b24e2bSVaishali Kulkarni return (DDI_SUCCESS); 427*14b24e2bSVaishali Kulkarni } 428*14b24e2bSVaishali Kulkarni 429*14b24e2bSVaishali Kulkarni /* Callback function from mac layer to register rings */ 430*14b24e2bSVaishali Kulkarni void 431*14b24e2bSVaishali Kulkarni qede_fill_ring(void *arg, mac_ring_type_t rtype, const int group_index, 432*14b24e2bSVaishali Kulkarni const int ring_index, mac_ring_info_t *infop, mac_ring_handle_t rh) 433*14b24e2bSVaishali Kulkarni { 434*14b24e2bSVaishali Kulkarni qede_t *qede = (qede_t *)arg; 435*14b24e2bSVaishali Kulkarni mac_intr_t *mintr = &infop->mri_intr; 436*14b24e2bSVaishali Kulkarni 437*14b24e2bSVaishali Kulkarni switch (rtype) { 438*14b24e2bSVaishali Kulkarni case MAC_RING_TYPE_RX: { 439*14b24e2bSVaishali Kulkarni /* 440*14b24e2bSVaishali Kulkarni * Index passed as a param is the ring index within the 441*14b24e2bSVaishali Kulkarni * given group index. If multiple groups are supported 442*14b24e2bSVaishali Kulkarni * then need to search into all groups to find out the 443*14b24e2bSVaishali Kulkarni * global ring index for the passed group relative 444*14b24e2bSVaishali Kulkarni * ring index 445*14b24e2bSVaishali Kulkarni */ 446*14b24e2bSVaishali Kulkarni int global_ring_index = qede_get_global_ring_index(qede, 447*14b24e2bSVaishali Kulkarni group_index, ring_index); 448*14b24e2bSVaishali Kulkarni qede_fastpath_t *fp; 449*14b24e2bSVaishali Kulkarni qede_rx_ring_t *rx_ring; 450*14b24e2bSVaishali Kulkarni int i; 451*14b24e2bSVaishali Kulkarni 452*14b24e2bSVaishali Kulkarni /* 453*14b24e2bSVaishali Kulkarni * global_ring_index < 0 means group index passed 454*14b24e2bSVaishali Kulkarni * was registered by our driver 455*14b24e2bSVaishali Kulkarni */ 456*14b24e2bSVaishali Kulkarni ASSERT(global_ring_index >= 0); 457*14b24e2bSVaishali Kulkarni 458*14b24e2bSVaishali Kulkarni if (rh == NULL) { 459*14b24e2bSVaishali Kulkarni cmn_err(CE_WARN, "!rx ring(%d) ring handle NULL", 460*14b24e2bSVaishali Kulkarni global_ring_index); 461*14b24e2bSVaishali Kulkarni } 462*14b24e2bSVaishali Kulkarni 463*14b24e2bSVaishali Kulkarni fp = &qede->fp_array[global_ring_index]; 464*14b24e2bSVaishali Kulkarni rx_ring = fp->rx_ring; 465*14b24e2bSVaishali Kulkarni fp->qede = qede; 466*14b24e2bSVaishali Kulkarni 467*14b24e2bSVaishali Kulkarni rx_ring->mac_ring_handle = rh; 468*14b24e2bSVaishali Kulkarni 469*14b24e2bSVaishali Kulkarni qede_info(qede, "rx_ring %d mac_ring_handle %p", 470*14b24e2bSVaishali Kulkarni rx_ring->rss_id, rh); 471*14b24e2bSVaishali Kulkarni 472*14b24e2bSVaishali Kulkarni /* mri_driver passed as arg to mac_ring* callbacks */ 473*14b24e2bSVaishali Kulkarni infop->mri_driver = (mac_ring_driver_t)fp; 474*14b24e2bSVaishali Kulkarni /* 475*14b24e2bSVaishali Kulkarni * mri_start callback will supply a mac rings generation 476*14b24e2bSVaishali Kulkarni * number which is needed while indicating packets 477*14b24e2bSVaishali Kulkarni * upstream via mac_ring_rx() call 478*14b24e2bSVaishali Kulkarni */ 479*14b24e2bSVaishali Kulkarni infop->mri_start = qede_rx_ring_start; 480*14b24e2bSVaishali Kulkarni infop->mri_stop = qede_rx_ring_stop; 481*14b24e2bSVaishali Kulkarni infop->mri_poll = qede_rx_ring_poll; 482*14b24e2bSVaishali Kulkarni infop->mri_stat = qede_rx_ring_stat; 483*14b24e2bSVaishali Kulkarni 484*14b24e2bSVaishali Kulkarni mintr->mi_handle = (mac_intr_handle_t)fp; 485*14b24e2bSVaishali Kulkarni mintr->mi_enable = qede_rx_ring_intr_enable; 486*14b24e2bSVaishali Kulkarni mintr->mi_disable = qede_rx_ring_intr_disable; 487*14b24e2bSVaishali Kulkarni if (qede->intr_ctx.intr_type_in_use & 488*14b24e2bSVaishali Kulkarni (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) { 489*14b24e2bSVaishali Kulkarni mintr->mi_ddi_handle = 490*14b24e2bSVaishali Kulkarni qede->intr_ctx. 491*14b24e2bSVaishali Kulkarni intr_hdl_array[global_ring_index + qede->num_hwfns]; 492*14b24e2bSVaishali Kulkarni } 493*14b24e2bSVaishali Kulkarni break; 494*14b24e2bSVaishali Kulkarni } 495*14b24e2bSVaishali Kulkarni case MAC_RING_TYPE_TX: { 496*14b24e2bSVaishali Kulkarni qede_fastpath_t *fp; 497*14b24e2bSVaishali Kulkarni qede_tx_ring_t *tx_ring; 498*14b24e2bSVaishali Kulkarni int i, tc; 499*14b24e2bSVaishali Kulkarni 500*14b24e2bSVaishali Kulkarni ASSERT(ring_index < qede->num_fp); 501*14b24e2bSVaishali Kulkarni 502*14b24e2bSVaishali Kulkarni fp = &qede->fp_array[ring_index]; 503*14b24e2bSVaishali Kulkarni fp->qede = qede; 504*14b24e2bSVaishali Kulkarni tx_ring = fp->tx_ring[0]; 505*14b24e2bSVaishali Kulkarni tx_ring->mac_ring_handle = rh; 506*14b24e2bSVaishali Kulkarni qede_info(qede, "tx_ring %d mac_ring_handle %p", 507*14b24e2bSVaishali Kulkarni tx_ring->tx_queue_index, rh); 508*14b24e2bSVaishali Kulkarni infop->mri_driver = (mac_ring_driver_t)fp; 509*14b24e2bSVaishali Kulkarni infop->mri_start = NULL; 510*14b24e2bSVaishali Kulkarni infop->mri_stop = NULL; 511*14b24e2bSVaishali Kulkarni infop->mri_tx = qede_ring_tx; 512*14b24e2bSVaishali Kulkarni infop->mri_stat = qede_tx_ring_stat; 513*14b24e2bSVaishali Kulkarni if (qede->intr_ctx.intr_type_in_use & 514*14b24e2bSVaishali Kulkarni (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) { 515*14b24e2bSVaishali Kulkarni mintr->mi_ddi_handle = 516*14b24e2bSVaishali Kulkarni qede->intr_ctx. 517*14b24e2bSVaishali Kulkarni intr_hdl_array[ring_index + qede->num_hwfns]; 518*14b24e2bSVaishali Kulkarni } 519*14b24e2bSVaishali Kulkarni break; 520*14b24e2bSVaishali Kulkarni } 521*14b24e2bSVaishali Kulkarni default: 522*14b24e2bSVaishali Kulkarni break; 523*14b24e2bSVaishali Kulkarni } 524*14b24e2bSVaishali Kulkarni } 525*14b24e2bSVaishali Kulkarni 526*14b24e2bSVaishali Kulkarni /* 527*14b24e2bSVaishali Kulkarni * Callback function from mac layer to register group 528*14b24e2bSVaishali Kulkarni */ 529*14b24e2bSVaishali Kulkarni void 530*14b24e2bSVaishali Kulkarni qede_fill_group(void *arg, mac_ring_type_t rtype, const int index, 531*14b24e2bSVaishali Kulkarni mac_group_info_t *infop, mac_group_handle_t gh) 532*14b24e2bSVaishali Kulkarni { 533*14b24e2bSVaishali Kulkarni qede_t *qede = (qede_t *)arg; 534*14b24e2bSVaishali Kulkarni 535*14b24e2bSVaishali Kulkarni switch (rtype) { 536*14b24e2bSVaishali Kulkarni case MAC_RING_TYPE_RX: { 537*14b24e2bSVaishali Kulkarni qede_mac_group_t *rx_group; 538*14b24e2bSVaishali Kulkarni 539*14b24e2bSVaishali Kulkarni rx_group = &qede->rx_groups[index]; 540*14b24e2bSVaishali Kulkarni rx_group->group_handle = gh; 541*14b24e2bSVaishali Kulkarni rx_group->group_index = index; 542*14b24e2bSVaishali Kulkarni rx_group->qede = qede; 543*14b24e2bSVaishali Kulkarni infop->mgi_driver = (mac_group_driver_t)rx_group; 544*14b24e2bSVaishali Kulkarni infop->mgi_start = NULL; 545*14b24e2bSVaishali Kulkarni infop->mgi_stop = NULL; 546*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS 547*14b24e2bSVaishali Kulkarni infop->mgi_addvlan = NULL; 548*14b24e2bSVaishali Kulkarni infop->mgi_remvlan = NULL; 549*14b24e2bSVaishali Kulkarni infop->mgi_getsriov_info = NULL; 550*14b24e2bSVaishali Kulkarni infop->mgi_setmtu = NULL; 551*14b24e2bSVaishali Kulkarni #endif 552*14b24e2bSVaishali Kulkarni infop->mgi_addmac = qede_add_mac_addr; 553*14b24e2bSVaishali Kulkarni infop->mgi_remmac = qede_rem_mac_addr; 554*14b24e2bSVaishali Kulkarni infop->mgi_count = qede->num_fp; 555*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS 556*14b24e2bSVaishali Kulkarni if (index == 0) { 557*14b24e2bSVaishali Kulkarni infop->mgi_flags = MAC_GROUP_DEFAULT; 558*14b24e2bSVaishali Kulkarni } 559*14b24e2bSVaishali Kulkarni #endif 560*14b24e2bSVaishali Kulkarni 561*14b24e2bSVaishali Kulkarni break; 562*14b24e2bSVaishali Kulkarni } 563*14b24e2bSVaishali Kulkarni case MAC_RING_TYPE_TX: { 564*14b24e2bSVaishali Kulkarni qede_mac_group_t *tx_group; 565*14b24e2bSVaishali Kulkarni 566*14b24e2bSVaishali Kulkarni tx_group = &qede->tx_groups[index]; 567*14b24e2bSVaishali Kulkarni tx_group->group_handle = gh; 568*14b24e2bSVaishali Kulkarni tx_group->group_index = index; 569*14b24e2bSVaishali Kulkarni tx_group->qede = qede; 570*14b24e2bSVaishali Kulkarni 571*14b24e2bSVaishali Kulkarni infop->mgi_driver = (mac_group_driver_t)tx_group; 572*14b24e2bSVaishali Kulkarni infop->mgi_start = NULL; 573*14b24e2bSVaishali Kulkarni infop->mgi_stop = NULL; 574*14b24e2bSVaishali Kulkarni infop->mgi_addmac = NULL; 575*14b24e2bSVaishali Kulkarni infop->mgi_remmac = NULL; 576*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS 577*14b24e2bSVaishali Kulkarni infop->mgi_addvlan = NULL; 578*14b24e2bSVaishali Kulkarni infop->mgi_remvlan = NULL; 579*14b24e2bSVaishali Kulkarni infop->mgi_setmtu = NULL; 580*14b24e2bSVaishali Kulkarni infop->mgi_getsriov_info = NULL; 581*14b24e2bSVaishali Kulkarni #endif 582*14b24e2bSVaishali Kulkarni 583*14b24e2bSVaishali Kulkarni infop->mgi_count = qede->num_fp; 584*14b24e2bSVaishali Kulkarni 585*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS 586*14b24e2bSVaishali Kulkarni if (index == 0) { 587*14b24e2bSVaishali Kulkarni infop->mgi_flags = MAC_GROUP_DEFAULT; 588*14b24e2bSVaishali Kulkarni } 589*14b24e2bSVaishali Kulkarni #endif 590*14b24e2bSVaishali Kulkarni break; 591*14b24e2bSVaishali Kulkarni } 592*14b24e2bSVaishali Kulkarni default: 593*14b24e2bSVaishali Kulkarni break; 594*14b24e2bSVaishali Kulkarni } 595*14b24e2bSVaishali Kulkarni } 596*14b24e2bSVaishali Kulkarni 597*14b24e2bSVaishali Kulkarni #ifdef ILLUMOS 598*14b24e2bSVaishali Kulkarni static int 599*14b24e2bSVaishali Kulkarni qede_transceiver_info(void *arg, uint_t id, mac_transceiver_info_t *infop) 600*14b24e2bSVaishali Kulkarni { 601*14b24e2bSVaishali Kulkarni qede_t *qede = arg; 602*14b24e2bSVaishali Kulkarni struct ecore_dev *edev = &qede->edev; 603*14b24e2bSVaishali Kulkarni struct ecore_hwfn *hwfn; 604*14b24e2bSVaishali Kulkarni struct ecore_ptt *ptt; 605*14b24e2bSVaishali Kulkarni uint32_t transceiver_state; 606*14b24e2bSVaishali Kulkarni 607*14b24e2bSVaishali Kulkarni if (id >= edev->num_hwfns || arg == NULL || infop == NULL) 608*14b24e2bSVaishali Kulkarni return (EINVAL); 609*14b24e2bSVaishali Kulkarni 610*14b24e2bSVaishali Kulkarni hwfn = &edev->hwfns[id]; 611*14b24e2bSVaishali Kulkarni ptt = ecore_ptt_acquire(hwfn); 612*14b24e2bSVaishali Kulkarni if (ptt == NULL) { 613*14b24e2bSVaishali Kulkarni return (EIO); 614*14b24e2bSVaishali Kulkarni } 615*14b24e2bSVaishali Kulkarni /* 616*14b24e2bSVaishali Kulkarni * Use the underlying raw API to get this information. While the 617*14b24e2bSVaishali Kulkarni * ecore_phy routines have some ways of getting to this information, it 618*14b24e2bSVaishali Kulkarni * ends up writing the raw data as ASCII characters which doesn't help 619*14b24e2bSVaishali Kulkarni * us one bit. 620*14b24e2bSVaishali Kulkarni */ 621*14b24e2bSVaishali Kulkarni transceiver_state = ecore_rd(hwfn, ptt, hwfn->mcp_info->port_addr + 622*14b24e2bSVaishali Kulkarni OFFSETOF(struct public_port, transceiver_data)); 623*14b24e2bSVaishali Kulkarni transceiver_state = GET_FIELD(transceiver_state, ETH_TRANSCEIVER_STATE); 624*14b24e2bSVaishali Kulkarni ecore_ptt_release(hwfn, ptt); 625*14b24e2bSVaishali Kulkarni 626*14b24e2bSVaishali Kulkarni if ((transceiver_state & ETH_TRANSCEIVER_STATE_PRESENT) != 0) { 627*14b24e2bSVaishali Kulkarni mac_transceiver_info_set_present(infop, B_TRUE); 628*14b24e2bSVaishali Kulkarni /* 629*14b24e2bSVaishali Kulkarni * Based on our testing, the ETH_TRANSCEIVER_STATE_VALID flag is 630*14b24e2bSVaishali Kulkarni * not set, so we cannot rely on it. Instead, we have found that 631*14b24e2bSVaishali Kulkarni * the ETH_TRANSCEIVER_STATE_UPDATING will be set when we cannot 632*14b24e2bSVaishali Kulkarni * use the transceiver. 633*14b24e2bSVaishali Kulkarni */ 634*14b24e2bSVaishali Kulkarni if ((transceiver_state & ETH_TRANSCEIVER_STATE_UPDATING) != 0) { 635*14b24e2bSVaishali Kulkarni mac_transceiver_info_set_usable(infop, B_FALSE); 636*14b24e2bSVaishali Kulkarni } else { 637*14b24e2bSVaishali Kulkarni mac_transceiver_info_set_usable(infop, B_TRUE); 638*14b24e2bSVaishali Kulkarni } 639*14b24e2bSVaishali Kulkarni } else { 640*14b24e2bSVaishali Kulkarni mac_transceiver_info_set_present(infop, B_FALSE); 641*14b24e2bSVaishali Kulkarni mac_transceiver_info_set_usable(infop, B_FALSE); 642*14b24e2bSVaishali Kulkarni } 643*14b24e2bSVaishali Kulkarni 644*14b24e2bSVaishali Kulkarni return (0); 645*14b24e2bSVaishali Kulkarni } 646*14b24e2bSVaishali Kulkarni 647*14b24e2bSVaishali Kulkarni static int 648*14b24e2bSVaishali Kulkarni qede_transceiver_read(void *arg, uint_t id, uint_t page, void *buf, 649*14b24e2bSVaishali Kulkarni size_t nbytes, off_t offset, size_t *nread) 650*14b24e2bSVaishali Kulkarni { 651*14b24e2bSVaishali Kulkarni qede_t *qede = arg; 652*14b24e2bSVaishali Kulkarni struct ecore_dev *edev = &qede->edev; 653*14b24e2bSVaishali Kulkarni struct ecore_hwfn *hwfn; 654*14b24e2bSVaishali Kulkarni uint32_t port, lane; 655*14b24e2bSVaishali Kulkarni struct ecore_ptt *ptt; 656*14b24e2bSVaishali Kulkarni enum _ecore_status_t ret; 657*14b24e2bSVaishali Kulkarni 658*14b24e2bSVaishali Kulkarni if (id >= edev->num_hwfns || buf == NULL || nbytes == 0 || nread == NULL || 659*14b24e2bSVaishali Kulkarni (page != 0xa0 && page != 0xa2) || offset < 0) 660*14b24e2bSVaishali Kulkarni return (EINVAL); 661*14b24e2bSVaishali Kulkarni 662*14b24e2bSVaishali Kulkarni /* 663*14b24e2bSVaishali Kulkarni * Both supported pages have a length of 256 bytes, ensure nothing asks 664*14b24e2bSVaishali Kulkarni * us to go beyond that. 665*14b24e2bSVaishali Kulkarni */ 666*14b24e2bSVaishali Kulkarni if (nbytes > 256 || offset >= 256 || (offset + nbytes > 256)) { 667*14b24e2bSVaishali Kulkarni return (EINVAL); 668*14b24e2bSVaishali Kulkarni } 669*14b24e2bSVaishali Kulkarni 670*14b24e2bSVaishali Kulkarni hwfn = &edev->hwfns[id]; 671*14b24e2bSVaishali Kulkarni ptt = ecore_ptt_acquire(hwfn); 672*14b24e2bSVaishali Kulkarni if (ptt == NULL) { 673*14b24e2bSVaishali Kulkarni return (EIO); 674*14b24e2bSVaishali Kulkarni } 675*14b24e2bSVaishali Kulkarni 676*14b24e2bSVaishali Kulkarni ret = ecore_mcp_phy_sfp_read(hwfn, ptt, hwfn->port_id, page, offset, 677*14b24e2bSVaishali Kulkarni nbytes, buf); 678*14b24e2bSVaishali Kulkarni ecore_ptt_release(hwfn, ptt); 679*14b24e2bSVaishali Kulkarni if (ret != ECORE_SUCCESS) { 680*14b24e2bSVaishali Kulkarni return (EIO); 681*14b24e2bSVaishali Kulkarni } 682*14b24e2bSVaishali Kulkarni *nread = nbytes; 683*14b24e2bSVaishali Kulkarni return (0); 684*14b24e2bSVaishali Kulkarni } 685*14b24e2bSVaishali Kulkarni #endif /* ILLUMOS */ 686*14b24e2bSVaishali Kulkarni 687*14b24e2bSVaishali Kulkarni 688*14b24e2bSVaishali Kulkarni static int 689*14b24e2bSVaishali Kulkarni qede_mac_stats(void * arg, 690*14b24e2bSVaishali Kulkarni uint_t stat, 691*14b24e2bSVaishali Kulkarni uint64_t * value) 692*14b24e2bSVaishali Kulkarni { 693*14b24e2bSVaishali Kulkarni qede_t * qede = (qede_t *)arg; 694*14b24e2bSVaishali Kulkarni struct ecore_eth_stats vstats; 695*14b24e2bSVaishali Kulkarni struct ecore_dev *edev = &qede->edev; 696*14b24e2bSVaishali Kulkarni struct qede_link_cfg lnkcfg; 697*14b24e2bSVaishali Kulkarni int rc = 0; 698*14b24e2bSVaishali Kulkarni qede_fastpath_t *fp = &qede->fp_array[0]; 699*14b24e2bSVaishali Kulkarni qede_rx_ring_t *rx_ring; 700*14b24e2bSVaishali Kulkarni qede_tx_ring_t *tx_ring; 701*14b24e2bSVaishali Kulkarni 702*14b24e2bSVaishali Kulkarni if ((qede == NULL) || (value == NULL)) { 703*14b24e2bSVaishali Kulkarni return EINVAL; 704*14b24e2bSVaishali Kulkarni } 705*14b24e2bSVaishali Kulkarni 706*14b24e2bSVaishali Kulkarni 707*14b24e2bSVaishali Kulkarni mutex_enter(&qede->gld_lock); 708*14b24e2bSVaishali Kulkarni 709*14b24e2bSVaishali Kulkarni if(qede->qede_state != QEDE_STATE_STARTED) { 710*14b24e2bSVaishali Kulkarni mutex_exit(&qede->gld_lock); 711*14b24e2bSVaishali Kulkarni return EAGAIN; 712*14b24e2bSVaishali Kulkarni } 713*14b24e2bSVaishali Kulkarni 714*14b24e2bSVaishali Kulkarni *value = 0; 715*14b24e2bSVaishali Kulkarni 716*14b24e2bSVaishali Kulkarni memset(&vstats, 0, sizeof(struct ecore_eth_stats)); 717*14b24e2bSVaishali Kulkarni ecore_get_vport_stats(edev, &vstats); 718*14b24e2bSVaishali Kulkarni 719*14b24e2bSVaishali Kulkarni 720*14b24e2bSVaishali Kulkarni memset(&qede->curcfg, 0, sizeof(struct qede_link_cfg)); 721*14b24e2bSVaishali Kulkarni qede_get_link_info(&edev->hwfns[0], &qede->curcfg); 722*14b24e2bSVaishali Kulkarni 723*14b24e2bSVaishali Kulkarni 724*14b24e2bSVaishali Kulkarni 725*14b24e2bSVaishali Kulkarni switch (stat) 726*14b24e2bSVaishali Kulkarni { 727*14b24e2bSVaishali Kulkarni case MAC_STAT_IFSPEED: 728*14b24e2bSVaishali Kulkarni *value = (qede->props.link_speed * 1000000ULL); 729*14b24e2bSVaishali Kulkarni break; 730*14b24e2bSVaishali Kulkarni case MAC_STAT_MULTIRCV: 731*14b24e2bSVaishali Kulkarni *value = vstats.common.rx_mcast_pkts; 732*14b24e2bSVaishali Kulkarni break; 733*14b24e2bSVaishali Kulkarni case MAC_STAT_BRDCSTRCV: 734*14b24e2bSVaishali Kulkarni *value = vstats.common.rx_bcast_pkts; 735*14b24e2bSVaishali Kulkarni break; 736*14b24e2bSVaishali Kulkarni case MAC_STAT_MULTIXMT: 737*14b24e2bSVaishali Kulkarni *value = vstats.common.tx_mcast_pkts; 738*14b24e2bSVaishali Kulkarni break; 739*14b24e2bSVaishali Kulkarni case MAC_STAT_BRDCSTXMT: 740*14b24e2bSVaishali Kulkarni *value = vstats.common.tx_bcast_pkts; 741*14b24e2bSVaishali Kulkarni break; 742*14b24e2bSVaishali Kulkarni case MAC_STAT_NORCVBUF: 743*14b24e2bSVaishali Kulkarni *value = vstats.common.no_buff_discards; 744*14b24e2bSVaishali Kulkarni break; 745*14b24e2bSVaishali Kulkarni case MAC_STAT_NOXMTBUF: 746*14b24e2bSVaishali Kulkarni *value = 0; 747*14b24e2bSVaishali Kulkarni break; 748*14b24e2bSVaishali Kulkarni case MAC_STAT_IERRORS: 749*14b24e2bSVaishali Kulkarni case ETHER_STAT_MACRCV_ERRORS: 750*14b24e2bSVaishali Kulkarni *value = vstats.common.mac_filter_discards + 751*14b24e2bSVaishali Kulkarni vstats.common.packet_too_big_discard + 752*14b24e2bSVaishali Kulkarni vstats.common.rx_crc_errors; 753*14b24e2bSVaishali Kulkarni break; 754*14b24e2bSVaishali Kulkarni 755*14b24e2bSVaishali Kulkarni case MAC_STAT_OERRORS: 756*14b24e2bSVaishali Kulkarni break; 757*14b24e2bSVaishali Kulkarni 758*14b24e2bSVaishali Kulkarni case MAC_STAT_COLLISIONS: 759*14b24e2bSVaishali Kulkarni *value = vstats.bb.tx_total_collisions; 760*14b24e2bSVaishali Kulkarni break; 761*14b24e2bSVaishali Kulkarni 762*14b24e2bSVaishali Kulkarni case MAC_STAT_RBYTES: 763*14b24e2bSVaishali Kulkarni *value = vstats.common.rx_ucast_bytes + 764*14b24e2bSVaishali Kulkarni vstats.common.rx_mcast_bytes + 765*14b24e2bSVaishali Kulkarni vstats.common.rx_bcast_bytes; 766*14b24e2bSVaishali Kulkarni break; 767*14b24e2bSVaishali Kulkarni 768*14b24e2bSVaishali Kulkarni case MAC_STAT_IPACKETS: 769*14b24e2bSVaishali Kulkarni *value = vstats.common.rx_ucast_pkts + 770*14b24e2bSVaishali Kulkarni vstats.common.rx_mcast_pkts + 771*14b24e2bSVaishali Kulkarni vstats.common.rx_bcast_pkts; 772*14b24e2bSVaishali Kulkarni break; 773*14b24e2bSVaishali Kulkarni 774*14b24e2bSVaishali Kulkarni case MAC_STAT_OBYTES: 775*14b24e2bSVaishali Kulkarni *value = vstats.common.tx_ucast_bytes + 776*14b24e2bSVaishali Kulkarni vstats.common.tx_mcast_bytes + 777*14b24e2bSVaishali Kulkarni vstats.common.tx_bcast_bytes; 778*14b24e2bSVaishali Kulkarni break; 779*14b24e2bSVaishali Kulkarni 780*14b24e2bSVaishali Kulkarni case MAC_STAT_OPACKETS: 781*14b24e2bSVaishali Kulkarni *value = vstats.common.tx_ucast_pkts + 782*14b24e2bSVaishali Kulkarni vstats.common.tx_mcast_pkts + 783*14b24e2bSVaishali Kulkarni vstats.common.tx_bcast_pkts; 784*14b24e2bSVaishali Kulkarni break; 785*14b24e2bSVaishali Kulkarni 786*14b24e2bSVaishali Kulkarni case ETHER_STAT_ALIGN_ERRORS: 787*14b24e2bSVaishali Kulkarni *value = vstats.common.rx_align_errors; 788*14b24e2bSVaishali Kulkarni break; 789*14b24e2bSVaishali Kulkarni 790*14b24e2bSVaishali Kulkarni case ETHER_STAT_FCS_ERRORS: 791*14b24e2bSVaishali Kulkarni *value = vstats.common.rx_crc_errors; 792*14b24e2bSVaishali Kulkarni break; 793*14b24e2bSVaishali Kulkarni 794*14b24e2bSVaishali Kulkarni case ETHER_STAT_FIRST_COLLISIONS: 795*14b24e2bSVaishali Kulkarni break; 796*14b24e2bSVaishali Kulkarni 797*14b24e2bSVaishali Kulkarni case ETHER_STAT_MULTI_COLLISIONS: 798*14b24e2bSVaishali Kulkarni break; 799*14b24e2bSVaishali Kulkarni 800*14b24e2bSVaishali Kulkarni case ETHER_STAT_DEFER_XMTS: 801*14b24e2bSVaishali Kulkarni break; 802*14b24e2bSVaishali Kulkarni 803*14b24e2bSVaishali Kulkarni case ETHER_STAT_TX_LATE_COLLISIONS: 804*14b24e2bSVaishali Kulkarni break; 805*14b24e2bSVaishali Kulkarni 806*14b24e2bSVaishali Kulkarni case ETHER_STAT_EX_COLLISIONS: 807*14b24e2bSVaishali Kulkarni break; 808*14b24e2bSVaishali Kulkarni 809*14b24e2bSVaishali Kulkarni case ETHER_STAT_MACXMT_ERRORS: 810*14b24e2bSVaishali Kulkarni *value = 0; 811*14b24e2bSVaishali Kulkarni break; 812*14b24e2bSVaishali Kulkarni 813*14b24e2bSVaishali Kulkarni case ETHER_STAT_CARRIER_ERRORS: 814*14b24e2bSVaishali Kulkarni break; 815*14b24e2bSVaishali Kulkarni 816*14b24e2bSVaishali Kulkarni case ETHER_STAT_TOOLONG_ERRORS: 817*14b24e2bSVaishali Kulkarni *value = vstats.common.rx_oversize_packets; 818*14b24e2bSVaishali Kulkarni break; 819*14b24e2bSVaishali Kulkarni 820*14b24e2bSVaishali Kulkarni #if (MAC_VERSION > 1) 821*14b24e2bSVaishali Kulkarni case ETHER_STAT_TOOSHORT_ERRORS: 822*14b24e2bSVaishali Kulkarni *value = vstats.common.rx_undersize_packets; 823*14b24e2bSVaishali Kulkarni break; 824*14b24e2bSVaishali Kulkarni #endif 825*14b24e2bSVaishali Kulkarni 826*14b24e2bSVaishali Kulkarni case ETHER_STAT_XCVR_ADDR: 827*14b24e2bSVaishali Kulkarni *value = 0; 828*14b24e2bSVaishali Kulkarni break; 829*14b24e2bSVaishali Kulkarni 830*14b24e2bSVaishali Kulkarni case ETHER_STAT_XCVR_ID: 831*14b24e2bSVaishali Kulkarni *value = 0; 832*14b24e2bSVaishali Kulkarni break; 833*14b24e2bSVaishali Kulkarni 834*14b24e2bSVaishali Kulkarni case ETHER_STAT_XCVR_INUSE: 835*14b24e2bSVaishali Kulkarni switch (qede->props.link_speed) { 836*14b24e2bSVaishali Kulkarni default: 837*14b24e2bSVaishali Kulkarni *value = XCVR_UNDEFINED; 838*14b24e2bSVaishali Kulkarni } 839*14b24e2bSVaishali Kulkarni break; 840*14b24e2bSVaishali Kulkarni #if (MAC_VERSION > 1) 841*14b24e2bSVaishali Kulkarni case ETHER_STAT_CAP_10GFDX: 842*14b24e2bSVaishali Kulkarni *value = 0; 843*14b24e2bSVaishali Kulkarni break; 844*14b24e2bSVaishali Kulkarni #endif 845*14b24e2bSVaishali Kulkarni case ETHER_STAT_CAP_100FDX: 846*14b24e2bSVaishali Kulkarni *value = 0; 847*14b24e2bSVaishali Kulkarni break; 848*14b24e2bSVaishali Kulkarni case ETHER_STAT_CAP_100HDX: 849*14b24e2bSVaishali Kulkarni *value = 0; 850*14b24e2bSVaishali Kulkarni break; 851*14b24e2bSVaishali Kulkarni case ETHER_STAT_CAP_ASMPAUSE: 852*14b24e2bSVaishali Kulkarni *value = 1; 853*14b24e2bSVaishali Kulkarni break; 854*14b24e2bSVaishali Kulkarni case ETHER_STAT_CAP_PAUSE: 855*14b24e2bSVaishali Kulkarni *value = 1; 856*14b24e2bSVaishali Kulkarni break; 857*14b24e2bSVaishali Kulkarni case ETHER_STAT_CAP_AUTONEG: 858*14b24e2bSVaishali Kulkarni *value = 1; 859*14b24e2bSVaishali Kulkarni break; 860*14b24e2bSVaishali Kulkarni 861*14b24e2bSVaishali Kulkarni #if (MAC_VERSION > 1) 862*14b24e2bSVaishali Kulkarni case ETHER_STAT_CAP_REMFAULT: 863*14b24e2bSVaishali Kulkarni *value = 0; 864*14b24e2bSVaishali Kulkarni break; 865*14b24e2bSVaishali Kulkarni #endif 866*14b24e2bSVaishali Kulkarni 867*14b24e2bSVaishali Kulkarni #if (MAC_VERSION > 1) 868*14b24e2bSVaishali Kulkarni case ETHER_STAT_ADV_CAP_10GFDX: 869*14b24e2bSVaishali Kulkarni *value = 0; 870*14b24e2bSVaishali Kulkarni break; 871*14b24e2bSVaishali Kulkarni #endif 872*14b24e2bSVaishali Kulkarni case ETHER_STAT_ADV_CAP_ASMPAUSE: 873*14b24e2bSVaishali Kulkarni *value = 1; 874*14b24e2bSVaishali Kulkarni break; 875*14b24e2bSVaishali Kulkarni 876*14b24e2bSVaishali Kulkarni case ETHER_STAT_ADV_CAP_PAUSE: 877*14b24e2bSVaishali Kulkarni *value = 1; 878*14b24e2bSVaishali Kulkarni break; 879*14b24e2bSVaishali Kulkarni 880*14b24e2bSVaishali Kulkarni case ETHER_STAT_ADV_CAP_AUTONEG: 881*14b24e2bSVaishali Kulkarni *value = qede->curcfg.adv_capab.autoneg; 882*14b24e2bSVaishali Kulkarni break; 883*14b24e2bSVaishali Kulkarni 884*14b24e2bSVaishali Kulkarni #if (MAC_VERSION > 1) 885*14b24e2bSVaishali Kulkarni case ETHER_STAT_ADV_REMFAULT: 886*14b24e2bSVaishali Kulkarni *value = 0; 887*14b24e2bSVaishali Kulkarni break; 888*14b24e2bSVaishali Kulkarni #endif 889*14b24e2bSVaishali Kulkarni 890*14b24e2bSVaishali Kulkarni case ETHER_STAT_LINK_AUTONEG: 891*14b24e2bSVaishali Kulkarni *value = qede->curcfg.autoneg; 892*14b24e2bSVaishali Kulkarni break; 893*14b24e2bSVaishali Kulkarni 894*14b24e2bSVaishali Kulkarni case ETHER_STAT_LINK_DUPLEX: 895*14b24e2bSVaishali Kulkarni *value = (qede->props.link_duplex == DUPLEX_FULL) ? 896*14b24e2bSVaishali Kulkarni LINK_DUPLEX_FULL : LINK_DUPLEX_HALF; 897*14b24e2bSVaishali Kulkarni break; 898*14b24e2bSVaishali Kulkarni /* 899*14b24e2bSVaishali Kulkarni * Supported speeds. These indicate what hardware is capable of. 900*14b24e2bSVaishali Kulkarni */ 901*14b24e2bSVaishali Kulkarni case ETHER_STAT_CAP_1000HDX: 902*14b24e2bSVaishali Kulkarni *value = qede->curcfg.supp_capab.param_1000hdx; 903*14b24e2bSVaishali Kulkarni break; 904*14b24e2bSVaishali Kulkarni 905*14b24e2bSVaishali Kulkarni case ETHER_STAT_CAP_1000FDX: 906*14b24e2bSVaishali Kulkarni *value = qede->curcfg.supp_capab.param_1000fdx; 907*14b24e2bSVaishali Kulkarni break; 908*14b24e2bSVaishali Kulkarni 909*14b24e2bSVaishali Kulkarni case ETHER_STAT_CAP_10GFDX: 910*14b24e2bSVaishali Kulkarni *value = qede->curcfg.supp_capab.param_10000fdx; 911*14b24e2bSVaishali Kulkarni break; 912*14b24e2bSVaishali Kulkarni 913*14b24e2bSVaishali Kulkarni case ETHER_STAT_CAP_25GFDX: 914*14b24e2bSVaishali Kulkarni *value = qede->curcfg.supp_capab.param_25000fdx; 915*14b24e2bSVaishali Kulkarni break; 916*14b24e2bSVaishali Kulkarni 917*14b24e2bSVaishali Kulkarni case ETHER_STAT_CAP_40GFDX: 918*14b24e2bSVaishali Kulkarni *value = qede->curcfg.supp_capab.param_40000fdx; 919*14b24e2bSVaishali Kulkarni break; 920*14b24e2bSVaishali Kulkarni 921*14b24e2bSVaishali Kulkarni case ETHER_STAT_CAP_50GFDX: 922*14b24e2bSVaishali Kulkarni *value = qede->curcfg.supp_capab.param_50000fdx; 923*14b24e2bSVaishali Kulkarni break; 924*14b24e2bSVaishali Kulkarni 925*14b24e2bSVaishali Kulkarni case ETHER_STAT_CAP_100GFDX: 926*14b24e2bSVaishali Kulkarni *value = qede->curcfg.supp_capab.param_100000fdx; 927*14b24e2bSVaishali Kulkarni break; 928*14b24e2bSVaishali Kulkarni 929*14b24e2bSVaishali Kulkarni /* 930*14b24e2bSVaishali Kulkarni * Advertised speeds. These indicate what hardware is currently sending. 931*14b24e2bSVaishali Kulkarni */ 932*14b24e2bSVaishali Kulkarni case ETHER_STAT_ADV_CAP_1000HDX: 933*14b24e2bSVaishali Kulkarni *value = qede->curcfg.adv_capab.param_1000hdx; 934*14b24e2bSVaishali Kulkarni break; 935*14b24e2bSVaishali Kulkarni 936*14b24e2bSVaishali Kulkarni case ETHER_STAT_ADV_CAP_1000FDX: 937*14b24e2bSVaishali Kulkarni *value = qede->curcfg.adv_capab.param_1000fdx; 938*14b24e2bSVaishali Kulkarni break; 939*14b24e2bSVaishali Kulkarni 940*14b24e2bSVaishali Kulkarni case ETHER_STAT_ADV_CAP_10GFDX: 941*14b24e2bSVaishali Kulkarni *value = qede->curcfg.adv_capab.param_10000fdx; 942*14b24e2bSVaishali Kulkarni break; 943*14b24e2bSVaishali Kulkarni 944*14b24e2bSVaishali Kulkarni case ETHER_STAT_ADV_CAP_25GFDX: 945*14b24e2bSVaishali Kulkarni *value = qede->curcfg.adv_capab.param_25000fdx; 946*14b24e2bSVaishali Kulkarni break; 947*14b24e2bSVaishali Kulkarni 948*14b24e2bSVaishali Kulkarni case ETHER_STAT_ADV_CAP_40GFDX: 949*14b24e2bSVaishali Kulkarni *value = qede->curcfg.adv_capab.param_40000fdx; 950*14b24e2bSVaishali Kulkarni break; 951*14b24e2bSVaishali Kulkarni 952*14b24e2bSVaishali Kulkarni case ETHER_STAT_ADV_CAP_50GFDX: 953*14b24e2bSVaishali Kulkarni *value = qede->curcfg.adv_capab.param_50000fdx; 954*14b24e2bSVaishali Kulkarni break; 955*14b24e2bSVaishali Kulkarni 956*14b24e2bSVaishali Kulkarni case ETHER_STAT_ADV_CAP_100GFDX: 957*14b24e2bSVaishali Kulkarni *value = qede->curcfg.adv_capab.param_100000fdx; 958*14b24e2bSVaishali Kulkarni break; 959*14b24e2bSVaishali Kulkarni 960*14b24e2bSVaishali Kulkarni default: 961*14b24e2bSVaishali Kulkarni rc = ENOTSUP; 962*14b24e2bSVaishali Kulkarni } 963*14b24e2bSVaishali Kulkarni 964*14b24e2bSVaishali Kulkarni mutex_exit(&qede->gld_lock); 965*14b24e2bSVaishali Kulkarni return (rc); 966*14b24e2bSVaishali Kulkarni } 967*14b24e2bSVaishali Kulkarni 968*14b24e2bSVaishali Kulkarni /* (flag) TRUE = on, FALSE = off */ 969*14b24e2bSVaishali Kulkarni static int 970*14b24e2bSVaishali Kulkarni qede_mac_promiscuous(void *arg, 971*14b24e2bSVaishali Kulkarni boolean_t on) 972*14b24e2bSVaishali Kulkarni { 973*14b24e2bSVaishali Kulkarni qede_t *qede = (qede_t *)arg; 974*14b24e2bSVaishali Kulkarni qede_print("!%s(%d): called", __func__,qede->instance); 975*14b24e2bSVaishali Kulkarni int ret = DDI_SUCCESS; 976*14b24e2bSVaishali Kulkarni enum qede_filter_rx_mode_type mode; 977*14b24e2bSVaishali Kulkarni 978*14b24e2bSVaishali Kulkarni mutex_enter(&qede->drv_lock); 979*14b24e2bSVaishali Kulkarni 980*14b24e2bSVaishali Kulkarni if (qede->qede_state == QEDE_STATE_SUSPENDED) { 981*14b24e2bSVaishali Kulkarni ret = ECANCELED; 982*14b24e2bSVaishali Kulkarni goto exit; 983*14b24e2bSVaishali Kulkarni } 984*14b24e2bSVaishali Kulkarni 985*14b24e2bSVaishali Kulkarni if (on) { 986*14b24e2bSVaishali Kulkarni qede_info(qede, "Entering promiscuous mode"); 987*14b24e2bSVaishali Kulkarni mode = QEDE_FILTER_RX_MODE_PROMISC; 988*14b24e2bSVaishali Kulkarni qede->params.promisc_fl = B_TRUE; 989*14b24e2bSVaishali Kulkarni } else { 990*14b24e2bSVaishali Kulkarni qede_info(qede, "Leaving promiscuous mode"); 991*14b24e2bSVaishali Kulkarni if(qede->params.multi_promisc_fl == B_TRUE) { 992*14b24e2bSVaishali Kulkarni mode = QEDE_FILTER_RX_MODE_MULTI_PROMISC; 993*14b24e2bSVaishali Kulkarni } else { 994*14b24e2bSVaishali Kulkarni mode = QEDE_FILTER_RX_MODE_REGULAR; 995*14b24e2bSVaishali Kulkarni } 996*14b24e2bSVaishali Kulkarni qede->params.promisc_fl = B_FALSE; 997*14b24e2bSVaishali Kulkarni } 998*14b24e2bSVaishali Kulkarni 999*14b24e2bSVaishali Kulkarni ret = qede_set_filter_rx_mode(qede, mode); 1000*14b24e2bSVaishali Kulkarni 1001*14b24e2bSVaishali Kulkarni exit: 1002*14b24e2bSVaishali Kulkarni mutex_exit(&qede->drv_lock); 1003*14b24e2bSVaishali Kulkarni return (ret); 1004*14b24e2bSVaishali Kulkarni } 1005*14b24e2bSVaishali Kulkarni 1006*14b24e2bSVaishali Kulkarni int qede_set_rx_mac_mcast(qede_t *qede, enum ecore_filter_opcode opcode, 1007*14b24e2bSVaishali Kulkarni uint8_t *mac, int mc_cnt) 1008*14b24e2bSVaishali Kulkarni { 1009*14b24e2bSVaishali Kulkarni struct ecore_filter_mcast cmd; 1010*14b24e2bSVaishali Kulkarni int i; 1011*14b24e2bSVaishali Kulkarni memset(&cmd, 0, sizeof(cmd)); 1012*14b24e2bSVaishali Kulkarni cmd.opcode = opcode; 1013*14b24e2bSVaishali Kulkarni cmd.num_mc_addrs = mc_cnt; 1014*14b24e2bSVaishali Kulkarni 1015*14b24e2bSVaishali Kulkarni for (i = 0; i < mc_cnt; i++, mac += ETH_ALLEN) { 1016*14b24e2bSVaishali Kulkarni COPY_ETH_ADDRESS(mac, cmd.mac[i]); 1017*14b24e2bSVaishali Kulkarni } 1018*14b24e2bSVaishali Kulkarni 1019*14b24e2bSVaishali Kulkarni 1020*14b24e2bSVaishali Kulkarni return (ecore_filter_mcast_cmd(&qede->edev, &cmd, 1021*14b24e2bSVaishali Kulkarni ECORE_SPQ_MODE_CB, NULL)); 1022*14b24e2bSVaishali Kulkarni 1023*14b24e2bSVaishali Kulkarni } 1024*14b24e2bSVaishali Kulkarni 1025*14b24e2bSVaishali Kulkarni int 1026*14b24e2bSVaishali Kulkarni qede_set_filter_rx_mode(qede_t * qede, enum qede_filter_rx_mode_type type) 1027*14b24e2bSVaishali Kulkarni { 1028*14b24e2bSVaishali Kulkarni struct ecore_filter_accept_flags flg; 1029*14b24e2bSVaishali Kulkarni 1030*14b24e2bSVaishali Kulkarni memset(&flg, 0, sizeof(flg)); 1031*14b24e2bSVaishali Kulkarni 1032*14b24e2bSVaishali Kulkarni flg.update_rx_mode_config = 1; 1033*14b24e2bSVaishali Kulkarni flg.update_tx_mode_config = 1; 1034*14b24e2bSVaishali Kulkarni flg.rx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED | 1035*14b24e2bSVaishali Kulkarni ECORE_ACCEPT_MCAST_MATCHED | ECORE_ACCEPT_BCAST; 1036*14b24e2bSVaishali Kulkarni flg.tx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED | 1037*14b24e2bSVaishali Kulkarni ECORE_ACCEPT_MCAST_MATCHED | ECORE_ACCEPT_BCAST; 1038*14b24e2bSVaishali Kulkarni 1039*14b24e2bSVaishali Kulkarni if (type == QEDE_FILTER_RX_MODE_PROMISC) 1040*14b24e2bSVaishali Kulkarni flg.rx_accept_filter |= ECORE_ACCEPT_UCAST_UNMATCHED | 1041*14b24e2bSVaishali Kulkarni ECORE_ACCEPT_MCAST_UNMATCHED; 1042*14b24e2bSVaishali Kulkarni else if (type == QEDE_FILTER_RX_MODE_MULTI_PROMISC) 1043*14b24e2bSVaishali Kulkarni flg.rx_accept_filter |= ECORE_ACCEPT_MCAST_UNMATCHED; 1044*14b24e2bSVaishali Kulkarni qede_info(qede, "rx_mode rx_filter=0x%x tx_filter=0x%x type=0x%x\n", 1045*14b24e2bSVaishali Kulkarni flg.rx_accept_filter, flg.tx_accept_filter, type); 1046*14b24e2bSVaishali Kulkarni return (ecore_filter_accept_cmd(&qede->edev, 0, flg, 1047*14b24e2bSVaishali Kulkarni 0, /* update_accept_any_vlan */ 1048*14b24e2bSVaishali Kulkarni 0, /* accept_any_vlan */ 1049*14b24e2bSVaishali Kulkarni ECORE_SPQ_MODE_CB, NULL)); 1050*14b24e2bSVaishali Kulkarni } 1051*14b24e2bSVaishali Kulkarni 1052*14b24e2bSVaishali Kulkarni int 1053*14b24e2bSVaishali Kulkarni qede_multicast(qede_t *qede, boolean_t flag, const uint8_t *ptr_mcaddr) 1054*14b24e2bSVaishali Kulkarni { 1055*14b24e2bSVaishali Kulkarni int i, ret = DDI_SUCCESS; 1056*14b24e2bSVaishali Kulkarni qede_mcast_list_entry_t *ptr_mlist; 1057*14b24e2bSVaishali Kulkarni qede_mcast_list_entry_t *ptr_entry; 1058*14b24e2bSVaishali Kulkarni int mc_cnt; 1059*14b24e2bSVaishali Kulkarni unsigned char *mc_macs, *tmpmc; 1060*14b24e2bSVaishali Kulkarni size_t size; 1061*14b24e2bSVaishali Kulkarni boolean_t mcmac_exists = B_FALSE; 1062*14b24e2bSVaishali Kulkarni enum qede_filter_rx_mode_type mode; 1063*14b24e2bSVaishali Kulkarni 1064*14b24e2bSVaishali Kulkarni if (!ptr_mcaddr) { 1065*14b24e2bSVaishali Kulkarni cmn_err(CE_NOTE, "Removing all multicast"); 1066*14b24e2bSVaishali Kulkarni } else { 1067*14b24e2bSVaishali Kulkarni cmn_err(CE_NOTE, 1068*14b24e2bSVaishali Kulkarni "qede=%p %s multicast: %02x:%02x:%02x:%02x:%02x:%02x", 1069*14b24e2bSVaishali Kulkarni qede, (flag) ? "Adding" : "Removing", ptr_mcaddr[0], 1070*14b24e2bSVaishali Kulkarni ptr_mcaddr[1],ptr_mcaddr[2],ptr_mcaddr[3],ptr_mcaddr[4], 1071*14b24e2bSVaishali Kulkarni ptr_mcaddr[5]); 1072*14b24e2bSVaishali Kulkarni } 1073*14b24e2bSVaishali Kulkarni 1074*14b24e2bSVaishali Kulkarni 1075*14b24e2bSVaishali Kulkarni if (flag && (ptr_mcaddr == NULL)) { 1076*14b24e2bSVaishali Kulkarni cmn_err(CE_WARN, "ERROR: Multicast address not specified"); 1077*14b24e2bSVaishali Kulkarni return EINVAL; 1078*14b24e2bSVaishali Kulkarni } 1079*14b24e2bSVaishali Kulkarni 1080*14b24e2bSVaishali Kulkarni 1081*14b24e2bSVaishali Kulkarni /* exceeds addition of mcaddr above limit */ 1082*14b24e2bSVaishali Kulkarni if (flag && (qede->mc_cnt >= MAX_MC_SOFT_LIMIT)) { 1083*14b24e2bSVaishali Kulkarni qede_info(qede, "Cannot add more than MAX_MC_SOFT_LIMIT"); 1084*14b24e2bSVaishali Kulkarni return ENOENT; 1085*14b24e2bSVaishali Kulkarni } 1086*14b24e2bSVaishali Kulkarni 1087*14b24e2bSVaishali Kulkarni size = MAX_MC_SOFT_LIMIT * ETH_ALLEN; 1088*14b24e2bSVaishali Kulkarni 1089*14b24e2bSVaishali Kulkarni mc_macs = kmem_zalloc(size, KM_NOSLEEP); 1090*14b24e2bSVaishali Kulkarni if (!mc_macs) { 1091*14b24e2bSVaishali Kulkarni cmn_err(CE_WARN, "ERROR: Failed to allocate for mc_macs"); 1092*14b24e2bSVaishali Kulkarni return EINVAL; 1093*14b24e2bSVaishali Kulkarni } 1094*14b24e2bSVaishali Kulkarni 1095*14b24e2bSVaishali Kulkarni tmpmc = mc_macs; 1096*14b24e2bSVaishali Kulkarni 1097*14b24e2bSVaishali Kulkarni /* remove all multicast - as flag not set and mcaddr not specified*/ 1098*14b24e2bSVaishali Kulkarni if (!flag && (ptr_mcaddr == NULL)) { 1099*14b24e2bSVaishali Kulkarni QEDE_LIST_FOR_EACH_ENTRY(ptr_entry, 1100*14b24e2bSVaishali Kulkarni &qede->mclist.head, qede_mcast_list_entry_t, mclist_entry) 1101*14b24e2bSVaishali Kulkarni { 1102*14b24e2bSVaishali Kulkarni if (ptr_entry != NULL) { 1103*14b24e2bSVaishali Kulkarni QEDE_LIST_REMOVE(&ptr_entry->mclist_entry, 1104*14b24e2bSVaishali Kulkarni &qede->mclist.head); 1105*14b24e2bSVaishali Kulkarni kmem_free(ptr_entry, 1106*14b24e2bSVaishali Kulkarni sizeof (qede_mcast_list_entry_t) + ETH_ALLEN); 1107*14b24e2bSVaishali Kulkarni } 1108*14b24e2bSVaishali Kulkarni } 1109*14b24e2bSVaishali Kulkarni 1110*14b24e2bSVaishali Kulkarni ret = qede_set_rx_mac_mcast(qede, 1111*14b24e2bSVaishali Kulkarni ECORE_FILTER_REMOVE, mc_macs, 1); 1112*14b24e2bSVaishali Kulkarni qede->mc_cnt = 0; 1113*14b24e2bSVaishali Kulkarni goto exit; 1114*14b24e2bSVaishali Kulkarni } 1115*14b24e2bSVaishali Kulkarni 1116*14b24e2bSVaishali Kulkarni QEDE_LIST_FOR_EACH_ENTRY(ptr_entry, 1117*14b24e2bSVaishali Kulkarni &qede->mclist.head, qede_mcast_list_entry_t, mclist_entry) 1118*14b24e2bSVaishali Kulkarni { 1119*14b24e2bSVaishali Kulkarni if ((ptr_entry != NULL) && 1120*14b24e2bSVaishali Kulkarni IS_ETH_ADDRESS_EQUAL(ptr_mcaddr, ptr_entry->mac)) { 1121*14b24e2bSVaishali Kulkarni mcmac_exists = B_TRUE; 1122*14b24e2bSVaishali Kulkarni break; 1123*14b24e2bSVaishali Kulkarni } 1124*14b24e2bSVaishali Kulkarni } 1125*14b24e2bSVaishali Kulkarni if (flag && mcmac_exists) { 1126*14b24e2bSVaishali Kulkarni ret = DDI_SUCCESS; 1127*14b24e2bSVaishali Kulkarni goto exit; 1128*14b24e2bSVaishali Kulkarni } else if (!flag && !mcmac_exists) { 1129*14b24e2bSVaishali Kulkarni ret = DDI_SUCCESS; 1130*14b24e2bSVaishali Kulkarni goto exit; 1131*14b24e2bSVaishali Kulkarni } 1132*14b24e2bSVaishali Kulkarni 1133*14b24e2bSVaishali Kulkarni if (flag) { 1134*14b24e2bSVaishali Kulkarni ptr_entry = kmem_zalloc((sizeof (qede_mcast_list_entry_t) + 1135*14b24e2bSVaishali Kulkarni ETH_ALLEN), KM_NOSLEEP); 1136*14b24e2bSVaishali Kulkarni ptr_entry->mac = (uint8_t *)ptr_entry + 1137*14b24e2bSVaishali Kulkarni sizeof (qede_mcast_list_entry_t); 1138*14b24e2bSVaishali Kulkarni COPY_ETH_ADDRESS(ptr_mcaddr, ptr_entry->mac); 1139*14b24e2bSVaishali Kulkarni QEDE_LIST_ADD(&ptr_entry->mclist_entry, &qede->mclist.head); 1140*14b24e2bSVaishali Kulkarni } else { 1141*14b24e2bSVaishali Kulkarni QEDE_LIST_REMOVE(&ptr_entry->mclist_entry, &qede->mclist.head); 1142*14b24e2bSVaishali Kulkarni kmem_free(ptr_entry, sizeof(qede_mcast_list_entry_t) + 1143*14b24e2bSVaishali Kulkarni ETH_ALLEN); 1144*14b24e2bSVaishali Kulkarni } 1145*14b24e2bSVaishali Kulkarni 1146*14b24e2bSVaishali Kulkarni mc_cnt = 0; 1147*14b24e2bSVaishali Kulkarni QEDE_LIST_FOR_EACH_ENTRY(ptr_entry, &qede->mclist.head, 1148*14b24e2bSVaishali Kulkarni qede_mcast_list_entry_t, mclist_entry) { 1149*14b24e2bSVaishali Kulkarni COPY_ETH_ADDRESS(ptr_entry->mac, tmpmc); 1150*14b24e2bSVaishali Kulkarni tmpmc += ETH_ALLEN; 1151*14b24e2bSVaishali Kulkarni mc_cnt++; 1152*14b24e2bSVaishali Kulkarni } 1153*14b24e2bSVaishali Kulkarni qede->mc_cnt = mc_cnt; 1154*14b24e2bSVaishali Kulkarni if (mc_cnt <=64) { 1155*14b24e2bSVaishali Kulkarni ret = qede_set_rx_mac_mcast(qede, ECORE_FILTER_ADD, 1156*14b24e2bSVaishali Kulkarni (unsigned char *)mc_macs, mc_cnt); 1157*14b24e2bSVaishali Kulkarni if ((qede->params.multi_promisc_fl == B_TRUE) && 1158*14b24e2bSVaishali Kulkarni (qede->params.promisc_fl == B_FALSE)) { 1159*14b24e2bSVaishali Kulkarni mode = QEDE_FILTER_RX_MODE_REGULAR; 1160*14b24e2bSVaishali Kulkarni ret = qede_set_filter_rx_mode(qede, mode); 1161*14b24e2bSVaishali Kulkarni } 1162*14b24e2bSVaishali Kulkarni qede->params.multi_promisc_fl = B_FALSE; 1163*14b24e2bSVaishali Kulkarni } else { 1164*14b24e2bSVaishali Kulkarni if ((qede->params.multi_promisc_fl == B_FALSE) && 1165*14b24e2bSVaishali Kulkarni (qede->params.promisc_fl = B_FALSE)) { 1166*14b24e2bSVaishali Kulkarni ret = qede_set_filter_rx_mode(qede, 1167*14b24e2bSVaishali Kulkarni QEDE_FILTER_RX_MODE_MULTI_PROMISC); 1168*14b24e2bSVaishali Kulkarni } 1169*14b24e2bSVaishali Kulkarni qede->params.multi_promisc_fl = B_TRUE; 1170*14b24e2bSVaishali Kulkarni qede_info(qede, "mode is MULTI_PROMISC"); 1171*14b24e2bSVaishali Kulkarni } 1172*14b24e2bSVaishali Kulkarni exit: 1173*14b24e2bSVaishali Kulkarni kmem_free(mc_macs, size); 1174*14b24e2bSVaishali Kulkarni qede_info(qede, "multicast ret %d mc_cnt %d\n", ret, qede->mc_cnt); 1175*14b24e2bSVaishali Kulkarni return (ret); 1176*14b24e2bSVaishali Kulkarni } 1177*14b24e2bSVaishali Kulkarni 1178*14b24e2bSVaishali Kulkarni /* 1179*14b24e2bSVaishali Kulkarni * This function is used to enable or disable multicast packet reception for 1180*14b24e2bSVaishali Kulkarni * particular multicast addresses. 1181*14b24e2bSVaishali Kulkarni * (flag) TRUE = add, FALSE = remove 1182*14b24e2bSVaishali Kulkarni */ 1183*14b24e2bSVaishali Kulkarni static int 1184*14b24e2bSVaishali Kulkarni qede_mac_multicast(void *arg, 1185*14b24e2bSVaishali Kulkarni boolean_t flag, 1186*14b24e2bSVaishali Kulkarni const uint8_t * mcast_addr) 1187*14b24e2bSVaishali Kulkarni { 1188*14b24e2bSVaishali Kulkarni qede_t *qede = (qede_t *)arg; 1189*14b24e2bSVaishali Kulkarni int ret = DDI_SUCCESS; 1190*14b24e2bSVaishali Kulkarni 1191*14b24e2bSVaishali Kulkarni 1192*14b24e2bSVaishali Kulkarni mutex_enter(&qede->gld_lock); 1193*14b24e2bSVaishali Kulkarni if(qede->qede_state != QEDE_STATE_STARTED) { 1194*14b24e2bSVaishali Kulkarni mutex_exit(&qede->gld_lock); 1195*14b24e2bSVaishali Kulkarni return (EAGAIN); 1196*14b24e2bSVaishali Kulkarni } 1197*14b24e2bSVaishali Kulkarni ret = qede_multicast(qede, flag, mcast_addr); 1198*14b24e2bSVaishali Kulkarni 1199*14b24e2bSVaishali Kulkarni mutex_exit(&qede->gld_lock); 1200*14b24e2bSVaishali Kulkarni 1201*14b24e2bSVaishali Kulkarni return (ret); 1202*14b24e2bSVaishali Kulkarni } 1203*14b24e2bSVaishali Kulkarni int 1204*14b24e2bSVaishali Kulkarni qede_clear_filters(qede_t *qede) 1205*14b24e2bSVaishali Kulkarni { 1206*14b24e2bSVaishali Kulkarni int ret = 0; 1207*14b24e2bSVaishali Kulkarni int i; 1208*14b24e2bSVaishali Kulkarni if ((qede->params.promisc_fl == B_TRUE) || 1209*14b24e2bSVaishali Kulkarni (qede->params.multi_promisc_fl == B_TRUE)) { 1210*14b24e2bSVaishali Kulkarni ret = qede_set_filter_rx_mode(qede, 1211*14b24e2bSVaishali Kulkarni QEDE_FILTER_RX_MODE_REGULAR); 1212*14b24e2bSVaishali Kulkarni if (ret) { 1213*14b24e2bSVaishali Kulkarni qede_info(qede, 1214*14b24e2bSVaishali Kulkarni "qede_clear_filters failed to set rx_mode"); 1215*14b24e2bSVaishali Kulkarni } 1216*14b24e2bSVaishali Kulkarni } 1217*14b24e2bSVaishali Kulkarni for (i=0; i < qede->ucst_total; i++) 1218*14b24e2bSVaishali Kulkarni { 1219*14b24e2bSVaishali Kulkarni if (qede->ucst_mac[i].set) { 1220*14b24e2bSVaishali Kulkarni qede_rem_macaddr(qede, 1221*14b24e2bSVaishali Kulkarni qede->ucst_mac[i].mac_addr.ether_addr_octet); 1222*14b24e2bSVaishali Kulkarni } 1223*14b24e2bSVaishali Kulkarni } 1224*14b24e2bSVaishali Kulkarni qede_multicast(qede, B_FALSE, NULL); 1225*14b24e2bSVaishali Kulkarni return (ret); 1226*14b24e2bSVaishali Kulkarni } 1227*14b24e2bSVaishali Kulkarni 1228*14b24e2bSVaishali Kulkarni 1229*14b24e2bSVaishali Kulkarni #ifdef NO_CROSSBOW 1230*14b24e2bSVaishali Kulkarni static int 1231*14b24e2bSVaishali Kulkarni qede_mac_unicast(void *arg, 1232*14b24e2bSVaishali Kulkarni const uint8_t * mac_addr) 1233*14b24e2bSVaishali Kulkarni { 1234*14b24e2bSVaishali Kulkarni qede_t *qede = (qede_t *)arg; 1235*14b24e2bSVaishali Kulkarni return 0; 1236*14b24e2bSVaishali Kulkarni } 1237*14b24e2bSVaishali Kulkarni 1238*14b24e2bSVaishali Kulkarni 1239*14b24e2bSVaishali Kulkarni static mblk_t * 1240*14b24e2bSVaishali Kulkarni qede_mac_tx(void *arg, 1241*14b24e2bSVaishali Kulkarni mblk_t * mblk) 1242*14b24e2bSVaishali Kulkarni { 1243*14b24e2bSVaishali Kulkarni qede_t *qede = (qede_t *)arg; 1244*14b24e2bSVaishali Kulkarni qede_fastpath_t *fp = &qede->fp_array[0]; 1245*14b24e2bSVaishali Kulkarni 1246*14b24e2bSVaishali Kulkarni mblk = qede_ring_tx((void *)fp, mblk); 1247*14b24e2bSVaishali Kulkarni 1248*14b24e2bSVaishali Kulkarni return (mblk); 1249*14b24e2bSVaishali Kulkarni } 1250*14b24e2bSVaishali Kulkarni #endif /* NO_CROSSBOW */ 1251*14b24e2bSVaishali Kulkarni 1252*14b24e2bSVaishali Kulkarni 1253*14b24e2bSVaishali Kulkarni static lb_property_t loopmodes[] = { 1254*14b24e2bSVaishali Kulkarni { normal, "normal", QEDE_LOOP_NONE }, 1255*14b24e2bSVaishali Kulkarni { internal, "internal", QEDE_LOOP_INTERNAL }, 1256*14b24e2bSVaishali Kulkarni { external, "external", QEDE_LOOP_EXTERNAL }, 1257*14b24e2bSVaishali Kulkarni }; 1258*14b24e2bSVaishali Kulkarni 1259*14b24e2bSVaishali Kulkarni /* 1260*14b24e2bSVaishali Kulkarni * Set Loopback mode 1261*14b24e2bSVaishali Kulkarni */ 1262*14b24e2bSVaishali Kulkarni 1263*14b24e2bSVaishali Kulkarni static enum ioc_reply 1264*14b24e2bSVaishali Kulkarni qede_set_loopback_mode(qede_t *qede, uint32_t mode) 1265*14b24e2bSVaishali Kulkarni { 1266*14b24e2bSVaishali Kulkarni int ret, i = 0; 1267*14b24e2bSVaishali Kulkarni struct ecore_dev *edev = &qede->edev; 1268*14b24e2bSVaishali Kulkarni struct ecore_hwfn *hwfn; 1269*14b24e2bSVaishali Kulkarni struct ecore_ptt *ptt = NULL; 1270*14b24e2bSVaishali Kulkarni struct ecore_mcp_link_params *link_params; 1271*14b24e2bSVaishali Kulkarni 1272*14b24e2bSVaishali Kulkarni hwfn = &edev->hwfns[0]; 1273*14b24e2bSVaishali Kulkarni link_params = ecore_mcp_get_link_params(hwfn); 1274*14b24e2bSVaishali Kulkarni ptt = ecore_ptt_acquire(hwfn); 1275*14b24e2bSVaishali Kulkarni 1276*14b24e2bSVaishali Kulkarni switch(mode) { 1277*14b24e2bSVaishali Kulkarni default: 1278*14b24e2bSVaishali Kulkarni qede_info(qede, "unknown loopback mode !!"); 1279*14b24e2bSVaishali Kulkarni ecore_ptt_release(hwfn, ptt); 1280*14b24e2bSVaishali Kulkarni return IOC_INVAL; 1281*14b24e2bSVaishali Kulkarni 1282*14b24e2bSVaishali Kulkarni case QEDE_LOOP_NONE: 1283*14b24e2bSVaishali Kulkarni ecore_mcp_set_link(hwfn, ptt, 0); 1284*14b24e2bSVaishali Kulkarni 1285*14b24e2bSVaishali Kulkarni while (qede->params.link_state && i < 5000) { 1286*14b24e2bSVaishali Kulkarni OSAL_MSLEEP(1); 1287*14b24e2bSVaishali Kulkarni i++; 1288*14b24e2bSVaishali Kulkarni } 1289*14b24e2bSVaishali Kulkarni i = 0; 1290*14b24e2bSVaishali Kulkarni 1291*14b24e2bSVaishali Kulkarni link_params->loopback_mode = ETH_LOOPBACK_NONE; 1292*14b24e2bSVaishali Kulkarni qede->loop_back_mode = QEDE_LOOP_NONE; 1293*14b24e2bSVaishali Kulkarni ret = ecore_mcp_set_link(hwfn, ptt, 1); 1294*14b24e2bSVaishali Kulkarni ecore_ptt_release(hwfn, ptt); 1295*14b24e2bSVaishali Kulkarni 1296*14b24e2bSVaishali Kulkarni while (!qede->params.link_state && i < 5000) { 1297*14b24e2bSVaishali Kulkarni OSAL_MSLEEP(1); 1298*14b24e2bSVaishali Kulkarni i++; 1299*14b24e2bSVaishali Kulkarni } 1300*14b24e2bSVaishali Kulkarni return IOC_REPLY; 1301*14b24e2bSVaishali Kulkarni 1302*14b24e2bSVaishali Kulkarni case QEDE_LOOP_INTERNAL: 1303*14b24e2bSVaishali Kulkarni qede_print("!%s(%d) : loopback mode (INTERNAL) is set!", 1304*14b24e2bSVaishali Kulkarni __func__, qede->instance); 1305*14b24e2bSVaishali Kulkarni ecore_mcp_set_link(hwfn, ptt, 0); 1306*14b24e2bSVaishali Kulkarni 1307*14b24e2bSVaishali Kulkarni while(qede->params.link_state && i < 5000) { 1308*14b24e2bSVaishali Kulkarni OSAL_MSLEEP(1); 1309*14b24e2bSVaishali Kulkarni i++; 1310*14b24e2bSVaishali Kulkarni } 1311*14b24e2bSVaishali Kulkarni i = 0; 1312*14b24e2bSVaishali Kulkarni link_params->loopback_mode = ETH_LOOPBACK_INT_PHY; 1313*14b24e2bSVaishali Kulkarni qede->loop_back_mode = QEDE_LOOP_INTERNAL; 1314*14b24e2bSVaishali Kulkarni ret = ecore_mcp_set_link(hwfn, ptt, 1); 1315*14b24e2bSVaishali Kulkarni ecore_ptt_release(hwfn, ptt); 1316*14b24e2bSVaishali Kulkarni 1317*14b24e2bSVaishali Kulkarni while(!qede->params.link_state && i < 5000) { 1318*14b24e2bSVaishali Kulkarni OSAL_MSLEEP(1); 1319*14b24e2bSVaishali Kulkarni i++; 1320*14b24e2bSVaishali Kulkarni } 1321*14b24e2bSVaishali Kulkarni return IOC_REPLY; 1322*14b24e2bSVaishali Kulkarni 1323*14b24e2bSVaishali Kulkarni case QEDE_LOOP_EXTERNAL: 1324*14b24e2bSVaishali Kulkarni qede_print("!%s(%d) : External loopback mode is not supported", 1325*14b24e2bSVaishali Kulkarni __func__, qede->instance); 1326*14b24e2bSVaishali Kulkarni ecore_ptt_release(hwfn, ptt); 1327*14b24e2bSVaishali Kulkarni return IOC_INVAL; 1328*14b24e2bSVaishali Kulkarni } 1329*14b24e2bSVaishali Kulkarni } 1330*14b24e2bSVaishali Kulkarni 1331*14b24e2bSVaishali Kulkarni static int 1332*14b24e2bSVaishali Kulkarni qede_ioctl_pcicfg_rd(qede_t *qede, u32 addr, void *data, 1333*14b24e2bSVaishali Kulkarni int len) 1334*14b24e2bSVaishali Kulkarni { 1335*14b24e2bSVaishali Kulkarni u32 crb, actual_crb; 1336*14b24e2bSVaishali Kulkarni uint32_t ret = 0; 1337*14b24e2bSVaishali Kulkarni int cap_offset = 0, cap_id = 0, next_cap = 0; 1338*14b24e2bSVaishali Kulkarni ddi_acc_handle_t pci_cfg_handle = qede->pci_cfg_handle; 1339*14b24e2bSVaishali Kulkarni qede_ioctl_data_t * data1 = (qede_ioctl_data_t *) data; 1340*14b24e2bSVaishali Kulkarni 1341*14b24e2bSVaishali Kulkarni cap_offset = pci_config_get8(pci_cfg_handle, PCI_CONF_CAP_PTR); 1342*14b24e2bSVaishali Kulkarni while (cap_offset != 0) { 1343*14b24e2bSVaishali Kulkarni /* Check for an invalid PCI read. */ 1344*14b24e2bSVaishali Kulkarni if (cap_offset == PCI_EINVAL8) { 1345*14b24e2bSVaishali Kulkarni return DDI_FAILURE; 1346*14b24e2bSVaishali Kulkarni } 1347*14b24e2bSVaishali Kulkarni cap_id = pci_config_get8(pci_cfg_handle, cap_offset); 1348*14b24e2bSVaishali Kulkarni if (cap_id == PCI_CAP_ID_PCI_E) { 1349*14b24e2bSVaishali Kulkarni /* PCIe expr capab struct found */ 1350*14b24e2bSVaishali Kulkarni break; 1351*14b24e2bSVaishali Kulkarni } else { 1352*14b24e2bSVaishali Kulkarni next_cap = pci_config_get8(pci_cfg_handle, 1353*14b24e2bSVaishali Kulkarni cap_offset + 1); 1354*14b24e2bSVaishali Kulkarni cap_offset = next_cap; 1355*14b24e2bSVaishali Kulkarni } 1356*14b24e2bSVaishali Kulkarni } 1357*14b24e2bSVaishali Kulkarni 1358*14b24e2bSVaishali Kulkarni switch (len) { 1359*14b24e2bSVaishali Kulkarni case 1: 1360*14b24e2bSVaishali Kulkarni ret = pci_config_get8(qede->pci_cfg_handle, addr); 1361*14b24e2bSVaishali Kulkarni (void) memcpy(data, &ret, sizeof(uint8_t)); 1362*14b24e2bSVaishali Kulkarni break; 1363*14b24e2bSVaishali Kulkarni case 2: 1364*14b24e2bSVaishali Kulkarni ret = pci_config_get16(qede->pci_cfg_handle, addr); 1365*14b24e2bSVaishali Kulkarni (void) memcpy(data, &ret, sizeof(uint16_t)); 1366*14b24e2bSVaishali Kulkarni break; 1367*14b24e2bSVaishali Kulkarni case 4: 1368*14b24e2bSVaishali Kulkarni ret = pci_config_get32(qede->pci_cfg_handle, addr); 1369*14b24e2bSVaishali Kulkarni (void) memcpy(data, &ret, sizeof(uint32_t)); 1370*14b24e2bSVaishali Kulkarni break; 1371*14b24e2bSVaishali Kulkarni default: 1372*14b24e2bSVaishali Kulkarni cmn_err(CE_WARN, "bad length for pci config read\n"); 1373*14b24e2bSVaishali Kulkarni return (1); 1374*14b24e2bSVaishali Kulkarni } 1375*14b24e2bSVaishali Kulkarni return (0); 1376*14b24e2bSVaishali Kulkarni } 1377*14b24e2bSVaishali Kulkarni 1378*14b24e2bSVaishali Kulkarni static int 1379*14b24e2bSVaishali Kulkarni qede_ioctl_pcicfg_wr(qede_t *qede, u32 addr, void *data, 1380*14b24e2bSVaishali Kulkarni int len) 1381*14b24e2bSVaishali Kulkarni { 1382*14b24e2bSVaishali Kulkarni uint16_t ret = 0; 1383*14b24e2bSVaishali Kulkarni int cap_offset = 0, cap_id = 0, next_cap = 0; 1384*14b24e2bSVaishali Kulkarni qede_ioctl_data_t * data1 = (qede_ioctl_data_t *) data; 1385*14b24e2bSVaishali Kulkarni ddi_acc_handle_t pci_cfg_handle = qede->pci_cfg_handle; 1386*14b24e2bSVaishali Kulkarni #if 1 1387*14b24e2bSVaishali Kulkarni cap_offset = pci_config_get8(pci_cfg_handle, PCI_CONF_CAP_PTR); 1388*14b24e2bSVaishali Kulkarni while (cap_offset != 0) { 1389*14b24e2bSVaishali Kulkarni cap_id = pci_config_get8(pci_cfg_handle, cap_offset); 1390*14b24e2bSVaishali Kulkarni if (cap_id == PCI_CAP_ID_PCI_E) { 1391*14b24e2bSVaishali Kulkarni /* PCIe expr capab struct found */ 1392*14b24e2bSVaishali Kulkarni break; 1393*14b24e2bSVaishali Kulkarni } else { 1394*14b24e2bSVaishali Kulkarni next_cap = pci_config_get8(pci_cfg_handle, 1395*14b24e2bSVaishali Kulkarni cap_offset + 1); 1396*14b24e2bSVaishali Kulkarni cap_offset = next_cap; 1397*14b24e2bSVaishali Kulkarni } 1398*14b24e2bSVaishali Kulkarni } 1399*14b24e2bSVaishali Kulkarni #endif 1400*14b24e2bSVaishali Kulkarni 1401*14b24e2bSVaishali Kulkarni switch(len) { 1402*14b24e2bSVaishali Kulkarni case 1: 1403*14b24e2bSVaishali Kulkarni pci_config_put8(qede->pci_cfg_handle, addr, 1404*14b24e2bSVaishali Kulkarni *(char *)&(data)); 1405*14b24e2bSVaishali Kulkarni break; 1406*14b24e2bSVaishali Kulkarni case 2: 1407*14b24e2bSVaishali Kulkarni ret = pci_config_get16(qede->pci_cfg_handle, addr); 1408*14b24e2bSVaishali Kulkarni ret = ret | *(uint16_t *)data1->uabc; 1409*14b24e2bSVaishali Kulkarni 1410*14b24e2bSVaishali Kulkarni pci_config_put16(qede->pci_cfg_handle, addr, 1411*14b24e2bSVaishali Kulkarni ret); 1412*14b24e2bSVaishali Kulkarni break; 1413*14b24e2bSVaishali Kulkarni case 4: 1414*14b24e2bSVaishali Kulkarni pci_config_put32(qede->pci_cfg_handle, addr, *(uint32_t *)data1->uabc); 1415*14b24e2bSVaishali Kulkarni break; 1416*14b24e2bSVaishali Kulkarni 1417*14b24e2bSVaishali Kulkarni default: 1418*14b24e2bSVaishali Kulkarni return (1); 1419*14b24e2bSVaishali Kulkarni } 1420*14b24e2bSVaishali Kulkarni return (0); 1421*14b24e2bSVaishali Kulkarni } 1422*14b24e2bSVaishali Kulkarni 1423*14b24e2bSVaishali Kulkarni static int 1424*14b24e2bSVaishali Kulkarni qede_ioctl_rd_wr_reg(qede_t *qede, void *data) 1425*14b24e2bSVaishali Kulkarni { 1426*14b24e2bSVaishali Kulkarni struct ecore_hwfn *p_hwfn; 1427*14b24e2bSVaishali Kulkarni struct ecore_dev *edev = &qede->edev; 1428*14b24e2bSVaishali Kulkarni struct ecore_ptt *ptt; 1429*14b24e2bSVaishali Kulkarni qede_ioctl_data_t *data1 = (qede_ioctl_data_t *)data; 1430*14b24e2bSVaishali Kulkarni uint32_t ret = 0; 1431*14b24e2bSVaishali Kulkarni uint8_t cmd = (uint8_t) data1->unused1; 1432*14b24e2bSVaishali Kulkarni uint32_t addr = data1->off; 1433*14b24e2bSVaishali Kulkarni uint32_t val = *(uint32_t *)&data1->uabc[1]; 1434*14b24e2bSVaishali Kulkarni uint32_t hwfn_index = *(uint32_t *)&data1->uabc[5]; 1435*14b24e2bSVaishali Kulkarni uint32_t *reg_addr; 1436*14b24e2bSVaishali Kulkarni 1437*14b24e2bSVaishali Kulkarni if (hwfn_index > qede->num_hwfns) { 1438*14b24e2bSVaishali Kulkarni cmn_err(CE_WARN, "invalid hwfn index from application\n"); 1439*14b24e2bSVaishali Kulkarni return (EINVAL); 1440*14b24e2bSVaishali Kulkarni } 1441*14b24e2bSVaishali Kulkarni p_hwfn = &edev->hwfns[hwfn_index]; 1442*14b24e2bSVaishali Kulkarni 1443*14b24e2bSVaishali Kulkarni switch(cmd) { 1444*14b24e2bSVaishali Kulkarni case QEDE_REG_READ: 1445*14b24e2bSVaishali Kulkarni ret = ecore_rd(p_hwfn, p_hwfn->p_main_ptt, addr); 1446*14b24e2bSVaishali Kulkarni (void) memcpy(data1->uabc, &ret, sizeof(uint32_t)); 1447*14b24e2bSVaishali Kulkarni break; 1448*14b24e2bSVaishali Kulkarni 1449*14b24e2bSVaishali Kulkarni case QEDE_REG_WRITE: 1450*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_hwfn->p_main_ptt, addr, val); 1451*14b24e2bSVaishali Kulkarni break; 1452*14b24e2bSVaishali Kulkarni 1453*14b24e2bSVaishali Kulkarni default: 1454*14b24e2bSVaishali Kulkarni cmn_err(CE_WARN, 1455*14b24e2bSVaishali Kulkarni "wrong command in register read/write from application\n"); 1456*14b24e2bSVaishali Kulkarni break; 1457*14b24e2bSVaishali Kulkarni } 1458*14b24e2bSVaishali Kulkarni return (ret); 1459*14b24e2bSVaishali Kulkarni } 1460*14b24e2bSVaishali Kulkarni 1461*14b24e2bSVaishali Kulkarni static int 1462*14b24e2bSVaishali Kulkarni qede_ioctl_rd_wr_nvram(qede_t *qede, mblk_t *mp) 1463*14b24e2bSVaishali Kulkarni { 1464*14b24e2bSVaishali Kulkarni qede_nvram_data_t *data1 = (qede_nvram_data_t *)(mp->b_cont->b_rptr); 1465*14b24e2bSVaishali Kulkarni qede_nvram_data_t *data2, *next_data; 1466*14b24e2bSVaishali Kulkarni struct ecore_dev *edev = &qede->edev; 1467*14b24e2bSVaishali Kulkarni uint32_t ret = 0, hdr_size = 24, bytes_to_copy, copy_len = 0; 1468*14b24e2bSVaishali Kulkarni uint32_t copy_len1 = 0; 1469*14b24e2bSVaishali Kulkarni uint32_t addr = data1->off; 1470*14b24e2bSVaishali Kulkarni uint32_t size = data1->size, i, buf_size; 1471*14b24e2bSVaishali Kulkarni uint8_t cmd, cmd2; 1472*14b24e2bSVaishali Kulkarni uint8_t *buf, *tmp_buf; 1473*14b24e2bSVaishali Kulkarni mblk_t *mp1; 1474*14b24e2bSVaishali Kulkarni 1475*14b24e2bSVaishali Kulkarni cmd = (uint8_t)data1->unused1; 1476*14b24e2bSVaishali Kulkarni 1477*14b24e2bSVaishali Kulkarni switch(cmd) { 1478*14b24e2bSVaishali Kulkarni case QEDE_NVRAM_CMD_READ: 1479*14b24e2bSVaishali Kulkarni buf = kmem_zalloc(size, GFP_KERNEL); 1480*14b24e2bSVaishali Kulkarni if(buf == NULL) { 1481*14b24e2bSVaishali Kulkarni cmn_err(CE_WARN, "memory allocation failed" 1482*14b24e2bSVaishali Kulkarni " in nvram read ioctl\n"); 1483*14b24e2bSVaishali Kulkarni return (DDI_FAILURE); 1484*14b24e2bSVaishali Kulkarni } 1485*14b24e2bSVaishali Kulkarni ret = ecore_mcp_nvm_read(edev, addr, buf, data1->size); 1486*14b24e2bSVaishali Kulkarni 1487*14b24e2bSVaishali Kulkarni copy_len = (MBLKL(mp->b_cont)) - hdr_size; 1488*14b24e2bSVaishali Kulkarni if(copy_len > size) { 1489*14b24e2bSVaishali Kulkarni (void) memcpy(data1->uabc, buf, size); 1490*14b24e2bSVaishali Kulkarni kmem_free(buf, size); 1491*14b24e2bSVaishali Kulkarni //OSAL_FREE(edev, buf); 1492*14b24e2bSVaishali Kulkarni ret = 0; 1493*14b24e2bSVaishali Kulkarni break; 1494*14b24e2bSVaishali Kulkarni } 1495*14b24e2bSVaishali Kulkarni (void) memcpy(data1->uabc, buf, copy_len); 1496*14b24e2bSVaishali Kulkarni bytes_to_copy = size - copy_len; 1497*14b24e2bSVaishali Kulkarni tmp_buf = ((uint8_t *)buf) + copy_len; 1498*14b24e2bSVaishali Kulkarni copy_len1 = copy_len; 1499*14b24e2bSVaishali Kulkarni mp1 = mp->b_cont; 1500*14b24e2bSVaishali Kulkarni mp1 = mp1->b_cont; 1501*14b24e2bSVaishali Kulkarni 1502*14b24e2bSVaishali Kulkarni while (mp1) { 1503*14b24e2bSVaishali Kulkarni copy_len = MBLKL(mp1); 1504*14b24e2bSVaishali Kulkarni if(mp1->b_cont == NULL) { 1505*14b24e2bSVaishali Kulkarni copy_len = MBLKL(mp1) - 4; 1506*14b24e2bSVaishali Kulkarni } 1507*14b24e2bSVaishali Kulkarni data2 = (qede_nvram_data_t *)mp1->b_rptr; 1508*14b24e2bSVaishali Kulkarni if (copy_len > bytes_to_copy) { 1509*14b24e2bSVaishali Kulkarni (void) memcpy(data2->uabc, tmp_buf, 1510*14b24e2bSVaishali Kulkarni bytes_to_copy); 1511*14b24e2bSVaishali Kulkarni kmem_free(buf, size); 1512*14b24e2bSVaishali Kulkarni //OSAL_FREE(edev, buf); 1513*14b24e2bSVaishali Kulkarni break; 1514*14b24e2bSVaishali Kulkarni } 1515*14b24e2bSVaishali Kulkarni (void) memcpy(data2->uabc, tmp_buf, copy_len); 1516*14b24e2bSVaishali Kulkarni tmp_buf = tmp_buf + copy_len; 1517*14b24e2bSVaishali Kulkarni copy_len += copy_len; 1518*14b24e2bSVaishali Kulkarni mp1 = mp1->b_cont; 1519*14b24e2bSVaishali Kulkarni bytes_to_copy = bytes_to_copy - copy_len; 1520*14b24e2bSVaishali Kulkarni } 1521*14b24e2bSVaishali Kulkarni 1522*14b24e2bSVaishali Kulkarni kmem_free(buf, size); 1523*14b24e2bSVaishali Kulkarni //OSAL_FREE(edev, buf); 1524*14b24e2bSVaishali Kulkarni break; 1525*14b24e2bSVaishali Kulkarni 1526*14b24e2bSVaishali Kulkarni case QEDE_NVRAM_CMD_WRITE: 1527*14b24e2bSVaishali Kulkarni cmd2 = (uint8_t )data1->cmd2; 1528*14b24e2bSVaishali Kulkarni size = data1->size; 1529*14b24e2bSVaishali Kulkarni addr = data1->off; 1530*14b24e2bSVaishali Kulkarni buf_size = size; //data1->buf_size; 1531*14b24e2bSVaishali Kulkarni //buf_size = data1->buf_size; 1532*14b24e2bSVaishali Kulkarni ret = 0; 1533*14b24e2bSVaishali Kulkarni 1534*14b24e2bSVaishali Kulkarni switch(cmd2){ 1535*14b24e2bSVaishali Kulkarni case START_NVM_WRITE: 1536*14b24e2bSVaishali Kulkarni buf = kmem_zalloc(size, GFP_KERNEL); 1537*14b24e2bSVaishali Kulkarni //buf = qede->reserved_buf; 1538*14b24e2bSVaishali Kulkarni qede->nvm_buf_size = data1->size; 1539*14b24e2bSVaishali Kulkarni if(buf == NULL) { 1540*14b24e2bSVaishali Kulkarni cmn_err(CE_WARN, 1541*14b24e2bSVaishali Kulkarni "memory allocation failed in START_NVM_WRITE\n"); 1542*14b24e2bSVaishali Kulkarni return DDI_FAILURE; 1543*14b24e2bSVaishali Kulkarni } 1544*14b24e2bSVaishali Kulkarni qede->nvm_buf_start = buf; 1545*14b24e2bSVaishali Kulkarni cmn_err(CE_NOTE, 1546*14b24e2bSVaishali Kulkarni "buf = %p, size = %x\n", qede->nvm_buf_start, size); 1547*14b24e2bSVaishali Kulkarni qede->nvm_buf = buf; 1548*14b24e2bSVaishali Kulkarni qede->copy_len = 0; 1549*14b24e2bSVaishali Kulkarni //tmp_buf = buf + addr; 1550*14b24e2bSVaishali Kulkarni ret = 0; 1551*14b24e2bSVaishali Kulkarni break; 1552*14b24e2bSVaishali Kulkarni 1553*14b24e2bSVaishali Kulkarni case ACCUMULATE_NVM_BUF: 1554*14b24e2bSVaishali Kulkarni tmp_buf = qede->nvm_buf; 1555*14b24e2bSVaishali Kulkarni copy_len = MBLKL(mp->b_cont) - hdr_size; 1556*14b24e2bSVaishali Kulkarni if(copy_len > buf_size) { 1557*14b24e2bSVaishali Kulkarni if (buf_size < qede->nvm_buf_size) { 1558*14b24e2bSVaishali Kulkarni (void) memcpy(tmp_buf, data1->uabc, buf_size); 1559*14b24e2bSVaishali Kulkarni qede->copy_len = qede->copy_len + 1560*14b24e2bSVaishali Kulkarni buf_size; 1561*14b24e2bSVaishali Kulkarni } else { 1562*14b24e2bSVaishali Kulkarni (void) memcpy(tmp_buf, 1563*14b24e2bSVaishali Kulkarni data1->uabc, qede->nvm_buf_size); 1564*14b24e2bSVaishali Kulkarni qede->copy_len = 1565*14b24e2bSVaishali Kulkarni qede->copy_len + qede->nvm_buf_size; 1566*14b24e2bSVaishali Kulkarni } 1567*14b24e2bSVaishali Kulkarni tmp_buf = tmp_buf + buf_size; 1568*14b24e2bSVaishali Kulkarni qede->nvm_buf = tmp_buf; 1569*14b24e2bSVaishali Kulkarni //qede->copy_len = qede->copy_len + buf_size; 1570*14b24e2bSVaishali Kulkarni cmn_err(CE_NOTE, 1571*14b24e2bSVaishali Kulkarni "buf_size from app = %x\n", copy_len); 1572*14b24e2bSVaishali Kulkarni ret = 0; 1573*14b24e2bSVaishali Kulkarni break; 1574*14b24e2bSVaishali Kulkarni } 1575*14b24e2bSVaishali Kulkarni (void) memcpy(tmp_buf, data1->uabc, copy_len); 1576*14b24e2bSVaishali Kulkarni tmp_buf = tmp_buf + copy_len; 1577*14b24e2bSVaishali Kulkarni bytes_to_copy = buf_size - copy_len; 1578*14b24e2bSVaishali Kulkarni mp1 = mp->b_cont; 1579*14b24e2bSVaishali Kulkarni mp1 = mp1->b_cont; 1580*14b24e2bSVaishali Kulkarni copy_len1 = copy_len; 1581*14b24e2bSVaishali Kulkarni 1582*14b24e2bSVaishali Kulkarni while (mp1) { 1583*14b24e2bSVaishali Kulkarni copy_len = MBLKL(mp1); 1584*14b24e2bSVaishali Kulkarni if (mp1->b_cont == NULL) { 1585*14b24e2bSVaishali Kulkarni copy_len = MBLKL(mp1) - 4; 1586*14b24e2bSVaishali Kulkarni } 1587*14b24e2bSVaishali Kulkarni next_data = (qede_nvram_data_t *) mp1->b_rptr; 1588*14b24e2bSVaishali Kulkarni if (copy_len > bytes_to_copy){ 1589*14b24e2bSVaishali Kulkarni (void) memcpy(tmp_buf, next_data->uabc, 1590*14b24e2bSVaishali Kulkarni bytes_to_copy); 1591*14b24e2bSVaishali Kulkarni qede->copy_len = qede->copy_len + 1592*14b24e2bSVaishali Kulkarni bytes_to_copy; 1593*14b24e2bSVaishali Kulkarni ret = 0; 1594*14b24e2bSVaishali Kulkarni break; 1595*14b24e2bSVaishali Kulkarni } 1596*14b24e2bSVaishali Kulkarni (void) memcpy(tmp_buf, next_data->uabc, 1597*14b24e2bSVaishali Kulkarni copy_len); 1598*14b24e2bSVaishali Kulkarni qede->copy_len = qede->copy_len + copy_len; 1599*14b24e2bSVaishali Kulkarni tmp_buf = tmp_buf + copy_len; 1600*14b24e2bSVaishali Kulkarni copy_len = copy_len1 + copy_len; 1601*14b24e2bSVaishali Kulkarni bytes_to_copy = bytes_to_copy - copy_len; 1602*14b24e2bSVaishali Kulkarni mp1 = mp1->b_cont; 1603*14b24e2bSVaishali Kulkarni } 1604*14b24e2bSVaishali Kulkarni qede->nvm_buf = tmp_buf; 1605*14b24e2bSVaishali Kulkarni ret = 0; 1606*14b24e2bSVaishali Kulkarni break; 1607*14b24e2bSVaishali Kulkarni 1608*14b24e2bSVaishali Kulkarni case STOP_NVM_WRITE: 1609*14b24e2bSVaishali Kulkarni //qede->nvm_buf = tmp_buf; 1610*14b24e2bSVaishali Kulkarni ret = 0; 1611*14b24e2bSVaishali Kulkarni break; 1612*14b24e2bSVaishali Kulkarni case READ_BUF: 1613*14b24e2bSVaishali Kulkarni tmp_buf = (uint8_t *)qede->nvm_buf_start; 1614*14b24e2bSVaishali Kulkarni for(i = 0; i < size ; i++){ 1615*14b24e2bSVaishali Kulkarni cmn_err(CE_NOTE, 1616*14b24e2bSVaishali Kulkarni "buff (%d) : %d\n", i, *tmp_buf); 1617*14b24e2bSVaishali Kulkarni tmp_buf ++; 1618*14b24e2bSVaishali Kulkarni } 1619*14b24e2bSVaishali Kulkarni ret = 0; 1620*14b24e2bSVaishali Kulkarni break; 1621*14b24e2bSVaishali Kulkarni } 1622*14b24e2bSVaishali Kulkarni break; 1623*14b24e2bSVaishali Kulkarni case QEDE_NVRAM_CMD_PUT_FILE_DATA: 1624*14b24e2bSVaishali Kulkarni tmp_buf = qede->nvm_buf_start; 1625*14b24e2bSVaishali Kulkarni ret = ecore_mcp_nvm_write(edev, ECORE_PUT_FILE_DATA, 1626*14b24e2bSVaishali Kulkarni addr, tmp_buf, size); 1627*14b24e2bSVaishali Kulkarni kmem_free(qede->nvm_buf_start, size); 1628*14b24e2bSVaishali Kulkarni //OSAL_FREE(edev, tmp_buf); 1629*14b24e2bSVaishali Kulkarni cmn_err(CE_NOTE, "total size = %x, copied size = %x\n", 1630*14b24e2bSVaishali Kulkarni qede->nvm_buf_size, qede->copy_len); 1631*14b24e2bSVaishali Kulkarni tmp_buf = NULL; 1632*14b24e2bSVaishali Kulkarni qede->nvm_buf = NULL; 1633*14b24e2bSVaishali Kulkarni qede->nvm_buf_start = NULL; 1634*14b24e2bSVaishali Kulkarni ret = 0; 1635*14b24e2bSVaishali Kulkarni break; 1636*14b24e2bSVaishali Kulkarni 1637*14b24e2bSVaishali Kulkarni case QEDE_NVRAM_CMD_SET_SECURE_MODE: 1638*14b24e2bSVaishali Kulkarni ret = ecore_mcp_nvm_set_secure_mode(edev, addr); 1639*14b24e2bSVaishali Kulkarni break; 1640*14b24e2bSVaishali Kulkarni 1641*14b24e2bSVaishali Kulkarni case QEDE_NVRAM_CMD_DEL_FILE: 1642*14b24e2bSVaishali Kulkarni ret = ecore_mcp_nvm_del_file(edev, addr); 1643*14b24e2bSVaishali Kulkarni break; 1644*14b24e2bSVaishali Kulkarni 1645*14b24e2bSVaishali Kulkarni case QEDE_NVRAM_CMD_PUT_FILE_BEGIN: 1646*14b24e2bSVaishali Kulkarni ret = ecore_mcp_nvm_put_file_begin(edev, addr); 1647*14b24e2bSVaishali Kulkarni break; 1648*14b24e2bSVaishali Kulkarni 1649*14b24e2bSVaishali Kulkarni case QEDE_NVRAM_CMD_GET_NVRAM_RESP: 1650*14b24e2bSVaishali Kulkarni buf = kmem_zalloc(size, KM_SLEEP); 1651*14b24e2bSVaishali Kulkarni ret = ecore_mcp_nvm_resp(edev, buf); 1652*14b24e2bSVaishali Kulkarni (void)memcpy(data1->uabc, buf, size); 1653*14b24e2bSVaishali Kulkarni kmem_free(buf, size); 1654*14b24e2bSVaishali Kulkarni break; 1655*14b24e2bSVaishali Kulkarni 1656*14b24e2bSVaishali Kulkarni default: 1657*14b24e2bSVaishali Kulkarni cmn_err(CE_WARN, 1658*14b24e2bSVaishali Kulkarni "wrong command in NVRAM read/write from application\n"); 1659*14b24e2bSVaishali Kulkarni break; 1660*14b24e2bSVaishali Kulkarni } 1661*14b24e2bSVaishali Kulkarni return (DDI_SUCCESS); 1662*14b24e2bSVaishali Kulkarni } 1663*14b24e2bSVaishali Kulkarni 1664*14b24e2bSVaishali Kulkarni static int 1665*14b24e2bSVaishali Kulkarni qede_get_func_info(qede_t *qede, void *data) 1666*14b24e2bSVaishali Kulkarni { 1667*14b24e2bSVaishali Kulkarni qede_link_output_t link_op; 1668*14b24e2bSVaishali Kulkarni qede_func_info_t func_info; 1669*14b24e2bSVaishali Kulkarni qede_ioctl_data_t *data1 = (qede_ioctl_data_t *)data; 1670*14b24e2bSVaishali Kulkarni struct ecore_dev *edev = &qede->edev; 1671*14b24e2bSVaishali Kulkarni struct ecore_hwfn *hwfn; 1672*14b24e2bSVaishali Kulkarni struct ecore_mcp_link_params params; 1673*14b24e2bSVaishali Kulkarni struct ecore_mcp_link_state link; 1674*14b24e2bSVaishali Kulkarni 1675*14b24e2bSVaishali Kulkarni hwfn = &edev->hwfns[0]; 1676*14b24e2bSVaishali Kulkarni 1677*14b24e2bSVaishali Kulkarni if(hwfn == NULL){ 1678*14b24e2bSVaishali Kulkarni cmn_err(CE_WARN, "(%s) : cannot acquire hwfn\n", 1679*14b24e2bSVaishali Kulkarni __func__); 1680*14b24e2bSVaishali Kulkarni return (DDI_FAILURE); 1681*14b24e2bSVaishali Kulkarni } 1682*14b24e2bSVaishali Kulkarni memcpy(¶ms, &hwfn->mcp_info->link_input, sizeof(params)); 1683*14b24e2bSVaishali Kulkarni memcpy(&link, &hwfn->mcp_info->link_output, sizeof(link)); 1684*14b24e2bSVaishali Kulkarni 1685*14b24e2bSVaishali Kulkarni if(link.link_up) { 1686*14b24e2bSVaishali Kulkarni link_op.link_up = true; 1687*14b24e2bSVaishali Kulkarni } 1688*14b24e2bSVaishali Kulkarni 1689*14b24e2bSVaishali Kulkarni link_op.supported_caps = SUPPORTED_FIBRE; 1690*14b24e2bSVaishali Kulkarni if(params.speed.autoneg) { 1691*14b24e2bSVaishali Kulkarni link_op.supported_caps |= SUPPORTED_Autoneg; 1692*14b24e2bSVaishali Kulkarni } 1693*14b24e2bSVaishali Kulkarni 1694*14b24e2bSVaishali Kulkarni if(params.pause.autoneg || 1695*14b24e2bSVaishali Kulkarni (params.pause.forced_rx && params.pause.forced_tx)) { 1696*14b24e2bSVaishali Kulkarni link_op.supported_caps |= SUPPORTED_Asym_Pause; 1697*14b24e2bSVaishali Kulkarni } 1698*14b24e2bSVaishali Kulkarni 1699*14b24e2bSVaishali Kulkarni if (params.pause.autoneg || params.pause.forced_rx || 1700*14b24e2bSVaishali Kulkarni params.pause.forced_tx) { 1701*14b24e2bSVaishali Kulkarni link_op.supported_caps |= SUPPORTED_Pause; 1702*14b24e2bSVaishali Kulkarni } 1703*14b24e2bSVaishali Kulkarni 1704*14b24e2bSVaishali Kulkarni if (params.speed.advertised_speeds & 1705*14b24e2bSVaishali Kulkarni NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) { 1706*14b24e2bSVaishali Kulkarni link_op.supported_caps |= SUPPORTED_1000baseT_Half | 1707*14b24e2bSVaishali Kulkarni SUPPORTED_1000baseT_Full; 1708*14b24e2bSVaishali Kulkarni } 1709*14b24e2bSVaishali Kulkarni 1710*14b24e2bSVaishali Kulkarni if (params.speed.advertised_speeds & 1711*14b24e2bSVaishali Kulkarni NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) { 1712*14b24e2bSVaishali Kulkarni link_op.supported_caps |= SUPPORTED_10000baseKR_Full; 1713*14b24e2bSVaishali Kulkarni } 1714*14b24e2bSVaishali Kulkarni 1715*14b24e2bSVaishali Kulkarni if (params.speed.advertised_speeds & 1716*14b24e2bSVaishali Kulkarni NVM_CFG1_PORT_DRV_LINK_SPEED_40G) { 1717*14b24e2bSVaishali Kulkarni link_op.supported_caps |= SUPPORTED_40000baseLR4_Full; 1718*14b24e2bSVaishali Kulkarni } 1719*14b24e2bSVaishali Kulkarni 1720*14b24e2bSVaishali Kulkarni link_op.advertised_caps = link_op.supported_caps; 1721*14b24e2bSVaishali Kulkarni 1722*14b24e2bSVaishali Kulkarni if(link.link_up) { 1723*14b24e2bSVaishali Kulkarni link_op.speed = link.speed; 1724*14b24e2bSVaishali Kulkarni } else { 1725*14b24e2bSVaishali Kulkarni link_op.speed = 0; 1726*14b24e2bSVaishali Kulkarni } 1727*14b24e2bSVaishali Kulkarni 1728*14b24e2bSVaishali Kulkarni link_op.duplex = DUPLEX_FULL; 1729*14b24e2bSVaishali Kulkarni link_op.port = PORT_FIBRE; 1730*14b24e2bSVaishali Kulkarni 1731*14b24e2bSVaishali Kulkarni link_op.autoneg = params.speed.autoneg; 1732*14b24e2bSVaishali Kulkarni 1733*14b24e2bSVaishali Kulkarni /* Link partner capabilities */ 1734*14b24e2bSVaishali Kulkarni if (link.partner_adv_speed & 1735*14b24e2bSVaishali Kulkarni ECORE_LINK_PARTNER_SPEED_1G_HD) { 1736*14b24e2bSVaishali Kulkarni link_op.lp_caps |= SUPPORTED_1000baseT_Half; 1737*14b24e2bSVaishali Kulkarni } 1738*14b24e2bSVaishali Kulkarni 1739*14b24e2bSVaishali Kulkarni if (link.partner_adv_speed & 1740*14b24e2bSVaishali Kulkarni ECORE_LINK_PARTNER_SPEED_1G_FD) { 1741*14b24e2bSVaishali Kulkarni link_op.lp_caps |= SUPPORTED_1000baseT_Full; 1742*14b24e2bSVaishali Kulkarni } 1743*14b24e2bSVaishali Kulkarni 1744*14b24e2bSVaishali Kulkarni if (link.partner_adv_speed & 1745*14b24e2bSVaishali Kulkarni ECORE_LINK_PARTNER_SPEED_10G) { 1746*14b24e2bSVaishali Kulkarni link_op.lp_caps |= SUPPORTED_10000baseKR_Full; 1747*14b24e2bSVaishali Kulkarni } 1748*14b24e2bSVaishali Kulkarni 1749*14b24e2bSVaishali Kulkarni if (link.partner_adv_speed & 1750*14b24e2bSVaishali Kulkarni ECORE_LINK_PARTNER_SPEED_20G) { 1751*14b24e2bSVaishali Kulkarni link_op.lp_caps |= SUPPORTED_20000baseKR2_Full; 1752*14b24e2bSVaishali Kulkarni } 1753*14b24e2bSVaishali Kulkarni 1754*14b24e2bSVaishali Kulkarni if (link.partner_adv_speed & 1755*14b24e2bSVaishali Kulkarni ECORE_LINK_PARTNER_SPEED_40G) { 1756*14b24e2bSVaishali Kulkarni link_op.lp_caps |= SUPPORTED_40000baseLR4_Full; 1757*14b24e2bSVaishali Kulkarni } 1758*14b24e2bSVaishali Kulkarni 1759*14b24e2bSVaishali Kulkarni if (link.an_complete) { 1760*14b24e2bSVaishali Kulkarni link_op.lp_caps |= SUPPORTED_Autoneg; 1761*14b24e2bSVaishali Kulkarni } 1762*14b24e2bSVaishali Kulkarni 1763*14b24e2bSVaishali Kulkarni if (link.partner_adv_pause) { 1764*14b24e2bSVaishali Kulkarni link_op.lp_caps |= SUPPORTED_Pause; 1765*14b24e2bSVaishali Kulkarni } 1766*14b24e2bSVaishali Kulkarni 1767*14b24e2bSVaishali Kulkarni if (link.partner_adv_pause == ECORE_LINK_PARTNER_ASYMMETRIC_PAUSE || 1768*14b24e2bSVaishali Kulkarni link.partner_adv_pause == ECORE_LINK_PARTNER_BOTH_PAUSE) { 1769*14b24e2bSVaishali Kulkarni link_op.lp_caps |= SUPPORTED_Asym_Pause; 1770*14b24e2bSVaishali Kulkarni } 1771*14b24e2bSVaishali Kulkarni 1772*14b24e2bSVaishali Kulkarni func_info.supported = link_op.supported_caps; 1773*14b24e2bSVaishali Kulkarni func_info.advertising = link_op.advertised_caps; 1774*14b24e2bSVaishali Kulkarni func_info.speed = link_op.speed; 1775*14b24e2bSVaishali Kulkarni func_info.duplex = link_op.duplex; 1776*14b24e2bSVaishali Kulkarni func_info.port = qede->pci_func & 0x1; 1777*14b24e2bSVaishali Kulkarni func_info.autoneg = link_op.autoneg; 1778*14b24e2bSVaishali Kulkarni 1779*14b24e2bSVaishali Kulkarni (void) memcpy(data1->uabc, &func_info, sizeof(qede_func_info_t)); 1780*14b24e2bSVaishali Kulkarni 1781*14b24e2bSVaishali Kulkarni return (0); 1782*14b24e2bSVaishali Kulkarni } 1783*14b24e2bSVaishali Kulkarni 1784*14b24e2bSVaishali Kulkarni static int 1785*14b24e2bSVaishali Kulkarni qede_do_ioctl(qede_t *qede, queue_t *q, mblk_t *mp) 1786*14b24e2bSVaishali Kulkarni { 1787*14b24e2bSVaishali Kulkarni qede_ioctl_data_t *up_data; 1788*14b24e2bSVaishali Kulkarni qede_driver_info_t driver_info; 1789*14b24e2bSVaishali Kulkarni struct ecore_dev *edev = &qede->edev; 1790*14b24e2bSVaishali Kulkarni struct ecore_hwfn *hwfn; 1791*14b24e2bSVaishali Kulkarni struct ecore_ptt *ptt = NULL; 1792*14b24e2bSVaishali Kulkarni struct mcp_file_att attrib; 1793*14b24e2bSVaishali Kulkarni uint32_t flash_size; 1794*14b24e2bSVaishali Kulkarni uint32_t mcp_resp, mcp_param, txn_size; 1795*14b24e2bSVaishali Kulkarni uint32_t cmd, size, ret = 0; 1796*14b24e2bSVaishali Kulkarni uint64_t off; 1797*14b24e2bSVaishali Kulkarni int * up_data1; 1798*14b24e2bSVaishali Kulkarni void * ptr; 1799*14b24e2bSVaishali Kulkarni mblk_t *mp1 = mp; 1800*14b24e2bSVaishali Kulkarni char mac_addr[32]; 1801*14b24e2bSVaishali Kulkarni 1802*14b24e2bSVaishali Kulkarni up_data = (qede_ioctl_data_t *)(mp->b_cont->b_rptr); 1803*14b24e2bSVaishali Kulkarni 1804*14b24e2bSVaishali Kulkarni cmd = up_data->cmd; 1805*14b24e2bSVaishali Kulkarni off = up_data->off; 1806*14b24e2bSVaishali Kulkarni size = up_data->size; 1807*14b24e2bSVaishali Kulkarni 1808*14b24e2bSVaishali Kulkarni switch (cmd) { 1809*14b24e2bSVaishali Kulkarni case QEDE_DRV_INFO: 1810*14b24e2bSVaishali Kulkarni hwfn = &edev->hwfns[0]; 1811*14b24e2bSVaishali Kulkarni ptt = ecore_ptt_acquire(hwfn); 1812*14b24e2bSVaishali Kulkarni 1813*14b24e2bSVaishali Kulkarni snprintf(driver_info.drv_name, MAX_QEDE_NAME_LEN, "%s", "qede"); 1814*14b24e2bSVaishali Kulkarni snprintf(driver_info.drv_version, QEDE_STR_SIZE, 1815*14b24e2bSVaishali Kulkarni "v:%s", qede->version); 1816*14b24e2bSVaishali Kulkarni snprintf(driver_info.mfw_version, QEDE_STR_SIZE, 1817*14b24e2bSVaishali Kulkarni "%s", qede->versionMFW); 1818*14b24e2bSVaishali Kulkarni snprintf(driver_info.stormfw_version, QEDE_STR_SIZE, 1819*14b24e2bSVaishali Kulkarni "%s", qede->versionFW); 1820*14b24e2bSVaishali Kulkarni snprintf(driver_info.bus_info, QEDE_STR_SIZE, 1821*14b24e2bSVaishali Kulkarni "%s", qede->bus_dev_func); 1822*14b24e2bSVaishali Kulkarni 1823*14b24e2bSVaishali Kulkarni 1824*14b24e2bSVaishali Kulkarni /* 1825*14b24e2bSVaishali Kulkarni * calling ecore_mcp_nvm_rd_cmd to find the flash length, i 1826*14b24e2bSVaishali Kulkarni * 0x08 is equivalent of NVM_TYPE_MFW_TRACE1 1827*14b24e2bSVaishali Kulkarni */ 1828*14b24e2bSVaishali Kulkarni ecore_mcp_get_flash_size(hwfn, ptt, &flash_size); 1829*14b24e2bSVaishali Kulkarni driver_info.eeprom_dump_len = flash_size; 1830*14b24e2bSVaishali Kulkarni (void) memcpy(up_data->uabc, &driver_info, 1831*14b24e2bSVaishali Kulkarni sizeof (qede_driver_info_t)); 1832*14b24e2bSVaishali Kulkarni up_data->size = sizeof (qede_driver_info_t); 1833*14b24e2bSVaishali Kulkarni 1834*14b24e2bSVaishali Kulkarni ecore_ptt_release(hwfn, ptt); 1835*14b24e2bSVaishali Kulkarni break; 1836*14b24e2bSVaishali Kulkarni 1837*14b24e2bSVaishali Kulkarni case QEDE_RD_PCICFG: 1838*14b24e2bSVaishali Kulkarni ret = qede_ioctl_pcicfg_rd(qede, off, up_data->uabc, size); 1839*14b24e2bSVaishali Kulkarni break; 1840*14b24e2bSVaishali Kulkarni 1841*14b24e2bSVaishali Kulkarni case QEDE_WR_PCICFG: 1842*14b24e2bSVaishali Kulkarni ret = qede_ioctl_pcicfg_wr(qede, off, up_data, size); 1843*14b24e2bSVaishali Kulkarni break; 1844*14b24e2bSVaishali Kulkarni 1845*14b24e2bSVaishali Kulkarni case QEDE_RW_REG: 1846*14b24e2bSVaishali Kulkarni ret = qede_ioctl_rd_wr_reg(qede, (void *)up_data); 1847*14b24e2bSVaishali Kulkarni break; 1848*14b24e2bSVaishali Kulkarni 1849*14b24e2bSVaishali Kulkarni case QEDE_RW_NVRAM: 1850*14b24e2bSVaishali Kulkarni ret = qede_ioctl_rd_wr_nvram(qede, mp1); 1851*14b24e2bSVaishali Kulkarni break; 1852*14b24e2bSVaishali Kulkarni 1853*14b24e2bSVaishali Kulkarni case QEDE_FUNC_INFO: 1854*14b24e2bSVaishali Kulkarni ret = qede_get_func_info(qede, (void *)up_data); 1855*14b24e2bSVaishali Kulkarni break; 1856*14b24e2bSVaishali Kulkarni 1857*14b24e2bSVaishali Kulkarni case QEDE_MAC_ADDR: 1858*14b24e2bSVaishali Kulkarni snprintf(mac_addr, sizeof(mac_addr), 1859*14b24e2bSVaishali Kulkarni "%02x:%02x:%02x:%02x:%02x:%02x", 1860*14b24e2bSVaishali Kulkarni qede->ether_addr[0], qede->ether_addr[1], 1861*14b24e2bSVaishali Kulkarni qede->ether_addr[2], qede->ether_addr[3], 1862*14b24e2bSVaishali Kulkarni qede->ether_addr[4], qede->ether_addr[5]); 1863*14b24e2bSVaishali Kulkarni (void) memcpy(up_data->uabc, &mac_addr, sizeof(mac_addr)); 1864*14b24e2bSVaishali Kulkarni break; 1865*14b24e2bSVaishali Kulkarni 1866*14b24e2bSVaishali Kulkarni } 1867*14b24e2bSVaishali Kulkarni //if (cmd == QEDE_RW_NVRAM) { 1868*14b24e2bSVaishali Kulkarni // miocack (q, mp, (sizeof(qede_ioctl_data_t)), 0); 1869*14b24e2bSVaishali Kulkarni // return IOC_REPLY; 1870*14b24e2bSVaishali Kulkarni //} 1871*14b24e2bSVaishali Kulkarni miocack (q, mp, (sizeof(qede_ioctl_data_t)), ret); 1872*14b24e2bSVaishali Kulkarni //miocack (q, mp, 0, ret); 1873*14b24e2bSVaishali Kulkarni return (IOC_REPLY); 1874*14b24e2bSVaishali Kulkarni } 1875*14b24e2bSVaishali Kulkarni 1876*14b24e2bSVaishali Kulkarni static void 1877*14b24e2bSVaishali Kulkarni qede_ioctl(qede_t *qede, int cmd, queue_t *q, mblk_t *mp) 1878*14b24e2bSVaishali Kulkarni { 1879*14b24e2bSVaishali Kulkarni void *ptr; 1880*14b24e2bSVaishali Kulkarni 1881*14b24e2bSVaishali Kulkarni switch(cmd) { 1882*14b24e2bSVaishali Kulkarni case QEDE_CMD: 1883*14b24e2bSVaishali Kulkarni (void) qede_do_ioctl(qede, q, mp); 1884*14b24e2bSVaishali Kulkarni break; 1885*14b24e2bSVaishali Kulkarni default : 1886*14b24e2bSVaishali Kulkarni cmn_err(CE_WARN, "qede ioctl command %x not supported\n", cmd); 1887*14b24e2bSVaishali Kulkarni break; 1888*14b24e2bSVaishali Kulkarni } 1889*14b24e2bSVaishali Kulkarni return; 1890*14b24e2bSVaishali Kulkarni } 1891*14b24e2bSVaishali Kulkarni enum ioc_reply 1892*14b24e2bSVaishali Kulkarni qede_loopback_ioctl(qede_t *qede, queue_t *wq, mblk_t *mp, 1893*14b24e2bSVaishali Kulkarni struct iocblk *iocp) 1894*14b24e2bSVaishali Kulkarni { 1895*14b24e2bSVaishali Kulkarni lb_info_sz_t *lb_info_size; 1896*14b24e2bSVaishali Kulkarni lb_property_t *lb_prop; 1897*14b24e2bSVaishali Kulkarni uint32_t *lb_mode; 1898*14b24e2bSVaishali Kulkarni int cmd; 1899*14b24e2bSVaishali Kulkarni 1900*14b24e2bSVaishali Kulkarni /* 1901*14b24e2bSVaishali Kulkarni * Validate format of ioctl 1902*14b24e2bSVaishali Kulkarni */ 1903*14b24e2bSVaishali Kulkarni if(mp->b_cont == NULL) { 1904*14b24e2bSVaishali Kulkarni return IOC_INVAL; 1905*14b24e2bSVaishali Kulkarni } 1906*14b24e2bSVaishali Kulkarni 1907*14b24e2bSVaishali Kulkarni cmd = iocp->ioc_cmd; 1908*14b24e2bSVaishali Kulkarni 1909*14b24e2bSVaishali Kulkarni switch(cmd) { 1910*14b24e2bSVaishali Kulkarni default: 1911*14b24e2bSVaishali Kulkarni qede_print("!%s(%d): unknown ioctl command %x\n", 1912*14b24e2bSVaishali Kulkarni __func__, qede->instance, cmd); 1913*14b24e2bSVaishali Kulkarni return IOC_INVAL; 1914*14b24e2bSVaishali Kulkarni case LB_GET_INFO_SIZE: 1915*14b24e2bSVaishali Kulkarni if (iocp->ioc_count != sizeof(lb_info_sz_t)) { 1916*14b24e2bSVaishali Kulkarni qede_info(qede, "error: ioc_count %d, sizeof %d", 1917*14b24e2bSVaishali Kulkarni iocp->ioc_count, sizeof(lb_info_sz_t)); 1918*14b24e2bSVaishali Kulkarni return IOC_INVAL; 1919*14b24e2bSVaishali Kulkarni } 1920*14b24e2bSVaishali Kulkarni lb_info_size = (void *)mp->b_cont->b_rptr; 1921*14b24e2bSVaishali Kulkarni *lb_info_size = sizeof(loopmodes); 1922*14b24e2bSVaishali Kulkarni return IOC_REPLY; 1923*14b24e2bSVaishali Kulkarni case LB_GET_INFO: 1924*14b24e2bSVaishali Kulkarni if (iocp->ioc_count != sizeof (loopmodes)) { 1925*14b24e2bSVaishali Kulkarni qede_info(qede, "error: iocp->ioc_count %d, sizepof %d", 1926*14b24e2bSVaishali Kulkarni iocp->ioc_count, sizeof (loopmodes)); 1927*14b24e2bSVaishali Kulkarni return (IOC_INVAL); 1928*14b24e2bSVaishali Kulkarni } 1929*14b24e2bSVaishali Kulkarni lb_prop = (void *)mp->b_cont->b_rptr; 1930*14b24e2bSVaishali Kulkarni bcopy(loopmodes, lb_prop, sizeof (loopmodes)); 1931*14b24e2bSVaishali Kulkarni return IOC_REPLY; 1932*14b24e2bSVaishali Kulkarni case LB_GET_MODE: 1933*14b24e2bSVaishali Kulkarni if (iocp->ioc_count != sizeof (uint32_t)) { 1934*14b24e2bSVaishali Kulkarni qede_info(qede, "iocp->ioc_count %d, sizeof : %d\n", 1935*14b24e2bSVaishali Kulkarni iocp->ioc_count, sizeof (uint32_t)); 1936*14b24e2bSVaishali Kulkarni return (IOC_INVAL); 1937*14b24e2bSVaishali Kulkarni } 1938*14b24e2bSVaishali Kulkarni lb_mode = (void *)mp->b_cont->b_rptr; 1939*14b24e2bSVaishali Kulkarni *lb_mode = qede->loop_back_mode; 1940*14b24e2bSVaishali Kulkarni return IOC_REPLY; 1941*14b24e2bSVaishali Kulkarni case LB_SET_MODE: 1942*14b24e2bSVaishali Kulkarni if (iocp->ioc_count != sizeof (uint32_t)) { 1943*14b24e2bSVaishali Kulkarni qede_info(qede, "iocp->ioc_count %d, sizeof : %d\n", 1944*14b24e2bSVaishali Kulkarni iocp->ioc_count, sizeof (uint32_t)); 1945*14b24e2bSVaishali Kulkarni return (IOC_INVAL); 1946*14b24e2bSVaishali Kulkarni } 1947*14b24e2bSVaishali Kulkarni lb_mode = (void *)mp->b_cont->b_rptr; 1948*14b24e2bSVaishali Kulkarni return (qede_set_loopback_mode(qede,*lb_mode)); 1949*14b24e2bSVaishali Kulkarni } 1950*14b24e2bSVaishali Kulkarni } 1951*14b24e2bSVaishali Kulkarni 1952*14b24e2bSVaishali Kulkarni static void 1953*14b24e2bSVaishali Kulkarni qede_mac_ioctl(void * arg, 1954*14b24e2bSVaishali Kulkarni queue_t * wq, 1955*14b24e2bSVaishali Kulkarni mblk_t * mp) 1956*14b24e2bSVaishali Kulkarni { 1957*14b24e2bSVaishali Kulkarni int err, cmd; 1958*14b24e2bSVaishali Kulkarni qede_t * qede = (qede_t *)arg; 1959*14b24e2bSVaishali Kulkarni struct iocblk *iocp = (struct iocblk *) (uintptr_t)mp->b_rptr; 1960*14b24e2bSVaishali Kulkarni enum ioc_reply status = IOC_DONE; 1961*14b24e2bSVaishali Kulkarni boolean_t need_privilege = B_TRUE; 1962*14b24e2bSVaishali Kulkarni 1963*14b24e2bSVaishali Kulkarni iocp->ioc_error = 0; 1964*14b24e2bSVaishali Kulkarni cmd = iocp->ioc_cmd; 1965*14b24e2bSVaishali Kulkarni 1966*14b24e2bSVaishali Kulkarni mutex_enter(&qede->drv_lock); 1967*14b24e2bSVaishali Kulkarni if ((qede->qede_state == QEDE_STATE_SUSPENDING) || 1968*14b24e2bSVaishali Kulkarni (qede->qede_state == QEDE_STATE_SUSPENDED)) { 1969*14b24e2bSVaishali Kulkarni mutex_exit(&qede->drv_lock); 1970*14b24e2bSVaishali Kulkarni miocnak(wq, mp, 0, EINVAL); 1971*14b24e2bSVaishali Kulkarni return; 1972*14b24e2bSVaishali Kulkarni } 1973*14b24e2bSVaishali Kulkarni 1974*14b24e2bSVaishali Kulkarni switch(cmd) { 1975*14b24e2bSVaishali Kulkarni case QEDE_CMD: 1976*14b24e2bSVaishali Kulkarni break; 1977*14b24e2bSVaishali Kulkarni case LB_GET_INFO_SIZE: 1978*14b24e2bSVaishali Kulkarni case LB_GET_INFO: 1979*14b24e2bSVaishali Kulkarni case LB_GET_MODE: 1980*14b24e2bSVaishali Kulkarni need_privilege = B_FALSE; 1981*14b24e2bSVaishali Kulkarni case LB_SET_MODE: 1982*14b24e2bSVaishali Kulkarni break; 1983*14b24e2bSVaishali Kulkarni default: 1984*14b24e2bSVaishali Kulkarni qede_print("!%s(%d) unknown ioctl command %x\n", 1985*14b24e2bSVaishali Kulkarni __func__, qede->instance, cmd); 1986*14b24e2bSVaishali Kulkarni miocnak(wq, mp, 0, EINVAL); 1987*14b24e2bSVaishali Kulkarni mutex_exit(&qede->drv_lock); 1988*14b24e2bSVaishali Kulkarni return; 1989*14b24e2bSVaishali Kulkarni } 1990*14b24e2bSVaishali Kulkarni 1991*14b24e2bSVaishali Kulkarni if(need_privilege) { 1992*14b24e2bSVaishali Kulkarni err = secpolicy_net_config(iocp->ioc_cr, B_FALSE); 1993*14b24e2bSVaishali Kulkarni if(err){ 1994*14b24e2bSVaishali Kulkarni qede_info(qede, "secpolicy() failed"); 1995*14b24e2bSVaishali Kulkarni miocnak(wq, mp, 0, err); 1996*14b24e2bSVaishali Kulkarni mutex_exit(&qede->drv_lock); 1997*14b24e2bSVaishali Kulkarni return; 1998*14b24e2bSVaishali Kulkarni } 1999*14b24e2bSVaishali Kulkarni } 2000*14b24e2bSVaishali Kulkarni 2001*14b24e2bSVaishali Kulkarni switch (cmd) { 2002*14b24e2bSVaishali Kulkarni default: 2003*14b24e2bSVaishali Kulkarni qede_print("!%s(%d) : unknown ioctl command %x\n", 2004*14b24e2bSVaishali Kulkarni __func__, qede->instance, cmd); 2005*14b24e2bSVaishali Kulkarni status = IOC_INVAL; 2006*14b24e2bSVaishali Kulkarni mutex_exit(&qede->drv_lock); 2007*14b24e2bSVaishali Kulkarni return; 2008*14b24e2bSVaishali Kulkarni case LB_GET_INFO_SIZE: 2009*14b24e2bSVaishali Kulkarni case LB_GET_INFO: 2010*14b24e2bSVaishali Kulkarni case LB_GET_MODE: 2011*14b24e2bSVaishali Kulkarni case LB_SET_MODE: 2012*14b24e2bSVaishali Kulkarni status = qede_loopback_ioctl(qede, wq, mp, iocp); 2013*14b24e2bSVaishali Kulkarni break; 2014*14b24e2bSVaishali Kulkarni case QEDE_CMD: 2015*14b24e2bSVaishali Kulkarni qede_ioctl(qede, cmd, wq, mp); 2016*14b24e2bSVaishali Kulkarni status = IOC_DONE; 2017*14b24e2bSVaishali Kulkarni break; 2018*14b24e2bSVaishali Kulkarni } 2019*14b24e2bSVaishali Kulkarni 2020*14b24e2bSVaishali Kulkarni switch(status){ 2021*14b24e2bSVaishali Kulkarni default: 2022*14b24e2bSVaishali Kulkarni qede_print("!%s(%d) : invalid status from ioctl", 2023*14b24e2bSVaishali Kulkarni __func__,qede->instance); 2024*14b24e2bSVaishali Kulkarni break; 2025*14b24e2bSVaishali Kulkarni case IOC_DONE: 2026*14b24e2bSVaishali Kulkarni /* 2027*14b24e2bSVaishali Kulkarni * OK, Reply already sent 2028*14b24e2bSVaishali Kulkarni */ 2029*14b24e2bSVaishali Kulkarni 2030*14b24e2bSVaishali Kulkarni break; 2031*14b24e2bSVaishali Kulkarni case IOC_REPLY: 2032*14b24e2bSVaishali Kulkarni mp->b_datap->db_type = iocp->ioc_error == 0 ? 2033*14b24e2bSVaishali Kulkarni M_IOCACK : M_IOCNAK; 2034*14b24e2bSVaishali Kulkarni qreply(wq, mp); 2035*14b24e2bSVaishali Kulkarni break; 2036*14b24e2bSVaishali Kulkarni case IOC_INVAL: 2037*14b24e2bSVaishali Kulkarni mutex_exit(&qede->drv_lock); 2038*14b24e2bSVaishali Kulkarni //miocack(wq, mp, 0, 0); 2039*14b24e2bSVaishali Kulkarni miocnak(wq, mp, 0, iocp->ioc_error == 0 ? 2040*14b24e2bSVaishali Kulkarni EINVAL : iocp->ioc_error); 2041*14b24e2bSVaishali Kulkarni return; 2042*14b24e2bSVaishali Kulkarni } 2043*14b24e2bSVaishali Kulkarni mutex_exit(&qede->drv_lock); 2044*14b24e2bSVaishali Kulkarni } 2045*14b24e2bSVaishali Kulkarni 2046*14b24e2bSVaishali Kulkarni extern ddi_dma_attr_t qede_buf2k_dma_attr_txbuf; 2047*14b24e2bSVaishali Kulkarni extern ddi_dma_attr_t qede_dma_attr_rxbuf; 2048*14b24e2bSVaishali Kulkarni extern ddi_dma_attr_t qede_dma_attr_desc; 2049*14b24e2bSVaishali Kulkarni 2050*14b24e2bSVaishali Kulkarni static boolean_t 2051*14b24e2bSVaishali Kulkarni qede_mac_get_capability(void *arg, 2052*14b24e2bSVaishali Kulkarni mac_capab_t capability, 2053*14b24e2bSVaishali Kulkarni void * cap_data) 2054*14b24e2bSVaishali Kulkarni { 2055*14b24e2bSVaishali Kulkarni qede_t * qede = (qede_t *)arg; 2056*14b24e2bSVaishali Kulkarni uint32_t *txflags = cap_data; 2057*14b24e2bSVaishali Kulkarni boolean_t ret = B_FALSE; 2058*14b24e2bSVaishali Kulkarni 2059*14b24e2bSVaishali Kulkarni switch (capability) { 2060*14b24e2bSVaishali Kulkarni case MAC_CAPAB_HCKSUM: { 2061*14b24e2bSVaishali Kulkarni u32 *tx_flags = cap_data; 2062*14b24e2bSVaishali Kulkarni /* 2063*14b24e2bSVaishali Kulkarni * Check if checksum is enabled on 2064*14b24e2bSVaishali Kulkarni * tx and advertise the cksum capab 2065*14b24e2bSVaishali Kulkarni * to mac layer accordingly. On Rx 2066*14b24e2bSVaishali Kulkarni * side checksummed packets are 2067*14b24e2bSVaishali Kulkarni * reveiced anyway 2068*14b24e2bSVaishali Kulkarni */ 2069*14b24e2bSVaishali Kulkarni qede_info(qede, "%s tx checksum offload", 2070*14b24e2bSVaishali Kulkarni (qede->checksum == DEFAULT_CKSUM_OFFLOAD) ? 2071*14b24e2bSVaishali Kulkarni "Enabling": 2072*14b24e2bSVaishali Kulkarni "Disabling"); 2073*14b24e2bSVaishali Kulkarni 2074*14b24e2bSVaishali Kulkarni if (qede->checksum != DEFAULT_CKSUM_OFFLOAD) { 2075*14b24e2bSVaishali Kulkarni ret = B_FALSE; 2076*14b24e2bSVaishali Kulkarni break; 2077*14b24e2bSVaishali Kulkarni } 2078*14b24e2bSVaishali Kulkarni /* 2079*14b24e2bSVaishali Kulkarni * Hardware does not support ICMPv6 checksumming. Right now the 2080*14b24e2bSVaishali Kulkarni * GLDv3 doesn't provide us a way to specify that we don't 2081*14b24e2bSVaishali Kulkarni * support that. As such, we cannot indicate 2082*14b24e2bSVaishali Kulkarni * HCKSUM_INET_FULL_V6. 2083*14b24e2bSVaishali Kulkarni */ 2084*14b24e2bSVaishali Kulkarni 2085*14b24e2bSVaishali Kulkarni *tx_flags = HCKSUM_INET_FULL_V4 | 2086*14b24e2bSVaishali Kulkarni HCKSUM_IPHDRCKSUM; 2087*14b24e2bSVaishali Kulkarni ret = B_TRUE; 2088*14b24e2bSVaishali Kulkarni break; 2089*14b24e2bSVaishali Kulkarni } 2090*14b24e2bSVaishali Kulkarni case MAC_CAPAB_LSO: { 2091*14b24e2bSVaishali Kulkarni mac_capab_lso_t *cap_lso = (mac_capab_lso_t *)cap_data; 2092*14b24e2bSVaishali Kulkarni 2093*14b24e2bSVaishali Kulkarni qede_info(qede, "%s large segmentation offload", 2094*14b24e2bSVaishali Kulkarni qede->lso_enable ? "Enabling": "Disabling"); 2095*14b24e2bSVaishali Kulkarni if (qede->lso_enable) { 2096*14b24e2bSVaishali Kulkarni cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4; 2097*14b24e2bSVaishali Kulkarni cap_lso->lso_basic_tcp_ipv4.lso_max = QEDE_LSO_MAXLEN; 2098*14b24e2bSVaishali Kulkarni ret = B_TRUE; 2099*14b24e2bSVaishali Kulkarni } 2100*14b24e2bSVaishali Kulkarni break; 2101*14b24e2bSVaishali Kulkarni } 2102*14b24e2bSVaishali Kulkarni case MAC_CAPAB_RINGS: { 2103*14b24e2bSVaishali Kulkarni #ifndef NO_CROSSBOW 2104*14b24e2bSVaishali Kulkarni mac_capab_rings_t *cap_rings = cap_data; 2105*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS 2106*14b24e2bSVaishali Kulkarni cap_rings->mr_version = MAC_RINGS_VERSION_1; 2107*14b24e2bSVaishali Kulkarni #endif 2108*14b24e2bSVaishali Kulkarni 2109*14b24e2bSVaishali Kulkarni switch (cap_rings->mr_type) { 2110*14b24e2bSVaishali Kulkarni case MAC_RING_TYPE_RX: 2111*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS 2112*14b24e2bSVaishali Kulkarni cap_rings->mr_flags = MAC_RINGS_VLAN_TRANSPARENT; 2113*14b24e2bSVaishali Kulkarni #endif 2114*14b24e2bSVaishali Kulkarni cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 2115*14b24e2bSVaishali Kulkarni //cap_rings->mr_rnum = 1; /* qede variable */ 2116*14b24e2bSVaishali Kulkarni cap_rings->mr_rnum = qede->num_fp; /* qede variable */ 2117*14b24e2bSVaishali Kulkarni cap_rings->mr_gnum = 1; 2118*14b24e2bSVaishali Kulkarni cap_rings->mr_rget = qede_fill_ring; 2119*14b24e2bSVaishali Kulkarni cap_rings->mr_gget = qede_fill_group; 2120*14b24e2bSVaishali Kulkarni cap_rings->mr_gaddring = NULL; 2121*14b24e2bSVaishali Kulkarni cap_rings->mr_gremring = NULL; 2122*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS 2123*14b24e2bSVaishali Kulkarni cap_rings->mr_ggetringtc = NULL; 2124*14b24e2bSVaishali Kulkarni #endif 2125*14b24e2bSVaishali Kulkarni ret = B_TRUE; 2126*14b24e2bSVaishali Kulkarni break; 2127*14b24e2bSVaishali Kulkarni case MAC_RING_TYPE_TX: 2128*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS 2129*14b24e2bSVaishali Kulkarni cap_rings->mr_flags = MAC_RINGS_VLAN_TRANSPARENT; 2130*14b24e2bSVaishali Kulkarni #endif 2131*14b24e2bSVaishali Kulkarni cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 2132*14b24e2bSVaishali Kulkarni //cap_rings->mr_rnum = 1; 2133*14b24e2bSVaishali Kulkarni cap_rings->mr_rnum = qede->num_fp; 2134*14b24e2bSVaishali Kulkarni cap_rings->mr_gnum = 0; 2135*14b24e2bSVaishali Kulkarni cap_rings->mr_rget = qede_fill_ring; 2136*14b24e2bSVaishali Kulkarni cap_rings->mr_gget = qede_fill_group; 2137*14b24e2bSVaishali Kulkarni cap_rings->mr_gaddring = NULL; 2138*14b24e2bSVaishali Kulkarni cap_rings->mr_gremring = NULL; 2139*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS 2140*14b24e2bSVaishali Kulkarni cap_rings->mr_ggetringtc = NULL; 2141*14b24e2bSVaishali Kulkarni #endif 2142*14b24e2bSVaishali Kulkarni ret = B_TRUE; 2143*14b24e2bSVaishali Kulkarni break; 2144*14b24e2bSVaishali Kulkarni default: 2145*14b24e2bSVaishali Kulkarni ret = B_FALSE; 2146*14b24e2bSVaishali Kulkarni break; 2147*14b24e2bSVaishali Kulkarni } 2148*14b24e2bSVaishali Kulkarni #endif 2149*14b24e2bSVaishali Kulkarni break; /* CASE MAC_CAPAB_RINGS */ 2150*14b24e2bSVaishali Kulkarni } 2151*14b24e2bSVaishali Kulkarni #ifdef ILLUMOS 2152*14b24e2bSVaishali Kulkarni case MAC_CAPAB_TRANSCEIVER: { 2153*14b24e2bSVaishali Kulkarni mac_capab_transceiver_t *mct = cap_data; 2154*14b24e2bSVaishali Kulkarni 2155*14b24e2bSVaishali Kulkarni mct->mct_flags = 0; 2156*14b24e2bSVaishali Kulkarni mct->mct_ntransceivers = qede->edev.num_hwfns; 2157*14b24e2bSVaishali Kulkarni mct->mct_info = qede_transceiver_info; 2158*14b24e2bSVaishali Kulkarni mct->mct_read = qede_transceiver_read; 2159*14b24e2bSVaishali Kulkarni 2160*14b24e2bSVaishali Kulkarni ret = B_TRUE; 2161*14b24e2bSVaishali Kulkarni break; 2162*14b24e2bSVaishali Kulkarni } 2163*14b24e2bSVaishali Kulkarni #endif 2164*14b24e2bSVaishali Kulkarni default: 2165*14b24e2bSVaishali Kulkarni break; 2166*14b24e2bSVaishali Kulkarni } 2167*14b24e2bSVaishali Kulkarni 2168*14b24e2bSVaishali Kulkarni return (ret); 2169*14b24e2bSVaishali Kulkarni } 2170*14b24e2bSVaishali Kulkarni 2171*14b24e2bSVaishali Kulkarni int 2172*14b24e2bSVaishali Kulkarni qede_configure_link(qede_t *qede, bool op); 2173*14b24e2bSVaishali Kulkarni 2174*14b24e2bSVaishali Kulkarni static int 2175*14b24e2bSVaishali Kulkarni qede_mac_set_property(void * arg, 2176*14b24e2bSVaishali Kulkarni const char * pr_name, 2177*14b24e2bSVaishali Kulkarni mac_prop_id_t pr_num, 2178*14b24e2bSVaishali Kulkarni uint_t pr_valsize, 2179*14b24e2bSVaishali Kulkarni const void * pr_val) 2180*14b24e2bSVaishali Kulkarni { 2181*14b24e2bSVaishali Kulkarni qede_t * qede = (qede_t *)arg; 2182*14b24e2bSVaishali Kulkarni struct ecore_mcp_link_params *link_params; 2183*14b24e2bSVaishali Kulkarni struct ecore_dev *edev = &qede->edev; 2184*14b24e2bSVaishali Kulkarni struct ecore_hwfn *hwfn; 2185*14b24e2bSVaishali Kulkarni int ret_val = 0, i; 2186*14b24e2bSVaishali Kulkarni uint32_t option; 2187*14b24e2bSVaishali Kulkarni 2188*14b24e2bSVaishali Kulkarni mutex_enter(&qede->gld_lock); 2189*14b24e2bSVaishali Kulkarni switch (pr_num) 2190*14b24e2bSVaishali Kulkarni { 2191*14b24e2bSVaishali Kulkarni case MAC_PROP_MTU: 2192*14b24e2bSVaishali Kulkarni bcopy(pr_val, &option, sizeof (option)); 2193*14b24e2bSVaishali Kulkarni 2194*14b24e2bSVaishali Kulkarni if(option == qede->mtu) { 2195*14b24e2bSVaishali Kulkarni ret_val = 0; 2196*14b24e2bSVaishali Kulkarni break; 2197*14b24e2bSVaishali Kulkarni } 2198*14b24e2bSVaishali Kulkarni if ((option != DEFAULT_JUMBO_MTU) && 2199*14b24e2bSVaishali Kulkarni (option != DEFAULT_MTU)) { 2200*14b24e2bSVaishali Kulkarni ret_val = EINVAL; 2201*14b24e2bSVaishali Kulkarni break; 2202*14b24e2bSVaishali Kulkarni } 2203*14b24e2bSVaishali Kulkarni if(qede->qede_state == QEDE_STATE_STARTED) { 2204*14b24e2bSVaishali Kulkarni ret_val = EBUSY; 2205*14b24e2bSVaishali Kulkarni break; 2206*14b24e2bSVaishali Kulkarni } 2207*14b24e2bSVaishali Kulkarni 2208*14b24e2bSVaishali Kulkarni ret_val = mac_maxsdu_update(qede->mac_handle, qede->mtu); 2209*14b24e2bSVaishali Kulkarni if (ret_val == 0) { 2210*14b24e2bSVaishali Kulkarni 2211*14b24e2bSVaishali Kulkarni qede->mtu = option; 2212*14b24e2bSVaishali Kulkarni if (option == DEFAULT_JUMBO_MTU) { 2213*14b24e2bSVaishali Kulkarni qede->jumbo_enable = B_TRUE; 2214*14b24e2bSVaishali Kulkarni } else { 2215*14b24e2bSVaishali Kulkarni qede->jumbo_enable = B_FALSE; 2216*14b24e2bSVaishali Kulkarni } 2217*14b24e2bSVaishali Kulkarni 2218*14b24e2bSVaishali Kulkarni hwfn = ECORE_LEADING_HWFN(edev); 2219*14b24e2bSVaishali Kulkarni hwfn->hw_info.mtu = qede->mtu; 2220*14b24e2bSVaishali Kulkarni ret_val = ecore_mcp_ov_update_mtu(hwfn, 2221*14b24e2bSVaishali Kulkarni hwfn->p_main_ptt, 2222*14b24e2bSVaishali Kulkarni hwfn->hw_info.mtu); 2223*14b24e2bSVaishali Kulkarni if (ret_val != ECORE_SUCCESS) { 2224*14b24e2bSVaishali Kulkarni qede_print("!%s(%d): MTU change %d option %d" 2225*14b24e2bSVaishali Kulkarni "FAILED", 2226*14b24e2bSVaishali Kulkarni __func__,qede->instance, qede->mtu, option); 2227*14b24e2bSVaishali Kulkarni break; 2228*14b24e2bSVaishali Kulkarni } 2229*14b24e2bSVaishali Kulkarni qede_print("!%s(%d): MTU changed %d MTU option" 2230*14b24e2bSVaishali Kulkarni " %d hwfn %d", 2231*14b24e2bSVaishali Kulkarni __func__,qede->instance, qede->mtu, 2232*14b24e2bSVaishali Kulkarni option, hwfn->hw_info.mtu); 2233*14b24e2bSVaishali Kulkarni } 2234*14b24e2bSVaishali Kulkarni break; 2235*14b24e2bSVaishali Kulkarni 2236*14b24e2bSVaishali Kulkarni case MAC_PROP_EN_10GFDX_CAP: 2237*14b24e2bSVaishali Kulkarni hwfn = &edev->hwfns[0]; 2238*14b24e2bSVaishali Kulkarni link_params = ecore_mcp_get_link_params(hwfn); 2239*14b24e2bSVaishali Kulkarni if (*(uint8_t *) pr_val) { 2240*14b24e2bSVaishali Kulkarni link_params->speed.autoneg = 0; 2241*14b24e2bSVaishali Kulkarni link_params->speed.forced_speed = 10000; 2242*14b24e2bSVaishali Kulkarni link_params->speed.advertised_speeds = 2243*14b24e2bSVaishali Kulkarni NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G; 2244*14b24e2bSVaishali Kulkarni qede->forced_speed_10G = *(uint8_t *)pr_val; 2245*14b24e2bSVaishali Kulkarni } 2246*14b24e2bSVaishali Kulkarni else { 2247*14b24e2bSVaishali Kulkarni memcpy(link_params, 2248*14b24e2bSVaishali Kulkarni &qede->link_input_params.default_link_params, 2249*14b24e2bSVaishali Kulkarni sizeof (struct ecore_mcp_link_params)); 2250*14b24e2bSVaishali Kulkarni qede->forced_speed_10G = *(uint8_t *)pr_val; 2251*14b24e2bSVaishali Kulkarni } 2252*14b24e2bSVaishali Kulkarni if (qede->qede_state == QEDE_STATE_STARTED) { 2253*14b24e2bSVaishali Kulkarni qede_configure_link(qede,1); 2254*14b24e2bSVaishali Kulkarni } else { 2255*14b24e2bSVaishali Kulkarni mutex_exit(&qede->gld_lock); 2256*14b24e2bSVaishali Kulkarni return (0); 2257*14b24e2bSVaishali Kulkarni } 2258*14b24e2bSVaishali Kulkarni break; 2259*14b24e2bSVaishali Kulkarni default: 2260*14b24e2bSVaishali Kulkarni ret_val = ENOTSUP; 2261*14b24e2bSVaishali Kulkarni break; 2262*14b24e2bSVaishali Kulkarni } 2263*14b24e2bSVaishali Kulkarni mutex_exit(&qede->gld_lock); 2264*14b24e2bSVaishali Kulkarni return (ret_val); 2265*14b24e2bSVaishali Kulkarni } 2266*14b24e2bSVaishali Kulkarni 2267*14b24e2bSVaishali Kulkarni static void 2268*14b24e2bSVaishali Kulkarni qede_mac_stop(void *arg) 2269*14b24e2bSVaishali Kulkarni { 2270*14b24e2bSVaishali Kulkarni qede_t *qede = (qede_t *)arg; 2271*14b24e2bSVaishali Kulkarni int status; 2272*14b24e2bSVaishali Kulkarni 2273*14b24e2bSVaishali Kulkarni qede_print("!%s(%d): called", 2274*14b24e2bSVaishali Kulkarni __func__,qede->instance); 2275*14b24e2bSVaishali Kulkarni mutex_enter(&qede->drv_lock); 2276*14b24e2bSVaishali Kulkarni status = qede_stop(qede); 2277*14b24e2bSVaishali Kulkarni if (status != DDI_SUCCESS) { 2278*14b24e2bSVaishali Kulkarni qede_print("!%s(%d): qede_stop " 2279*14b24e2bSVaishali Kulkarni "FAILED", 2280*14b24e2bSVaishali Kulkarni __func__,qede->instance); 2281*14b24e2bSVaishali Kulkarni } 2282*14b24e2bSVaishali Kulkarni 2283*14b24e2bSVaishali Kulkarni mac_link_update(qede->mac_handle, LINK_STATE_UNKNOWN); 2284*14b24e2bSVaishali Kulkarni mutex_exit(&qede->drv_lock); 2285*14b24e2bSVaishali Kulkarni } 2286*14b24e2bSVaishali Kulkarni 2287*14b24e2bSVaishali Kulkarni static int 2288*14b24e2bSVaishali Kulkarni qede_mac_start(void *arg) 2289*14b24e2bSVaishali Kulkarni { 2290*14b24e2bSVaishali Kulkarni qede_t *qede = (qede_t *)arg; 2291*14b24e2bSVaishali Kulkarni int status; 2292*14b24e2bSVaishali Kulkarni 2293*14b24e2bSVaishali Kulkarni qede_print("!%s(%d): called", __func__,qede->instance); 2294*14b24e2bSVaishali Kulkarni if (!mutex_tryenter(&qede->drv_lock)) { 2295*14b24e2bSVaishali Kulkarni return (EAGAIN); 2296*14b24e2bSVaishali Kulkarni } 2297*14b24e2bSVaishali Kulkarni 2298*14b24e2bSVaishali Kulkarni if (qede->qede_state == QEDE_STATE_SUSPENDED) { 2299*14b24e2bSVaishali Kulkarni mutex_exit(&qede->drv_lock); 2300*14b24e2bSVaishali Kulkarni return (ECANCELED); 2301*14b24e2bSVaishali Kulkarni } 2302*14b24e2bSVaishali Kulkarni 2303*14b24e2bSVaishali Kulkarni status = qede_start(qede); 2304*14b24e2bSVaishali Kulkarni if (status != DDI_SUCCESS) { 2305*14b24e2bSVaishali Kulkarni mutex_exit(&qede->drv_lock); 2306*14b24e2bSVaishali Kulkarni return (EIO); 2307*14b24e2bSVaishali Kulkarni } 2308*14b24e2bSVaishali Kulkarni 2309*14b24e2bSVaishali Kulkarni mutex_exit(&qede->drv_lock); 2310*14b24e2bSVaishali Kulkarni 2311*14b24e2bSVaishali Kulkarni #ifdef DBLK_DMA_PREMAP 2312*14b24e2bSVaishali Kulkarni qede->pm_handle = mac_pmh_tx_get(qede->mac_handle); 2313*14b24e2bSVaishali Kulkarni #endif 2314*14b24e2bSVaishali Kulkarni return (0); 2315*14b24e2bSVaishali Kulkarni } 2316*14b24e2bSVaishali Kulkarni 2317*14b24e2bSVaishali Kulkarni static int 2318*14b24e2bSVaishali Kulkarni qede_mac_get_property(void *arg, 2319*14b24e2bSVaishali Kulkarni const char *pr_name, 2320*14b24e2bSVaishali Kulkarni mac_prop_id_t pr_num, 2321*14b24e2bSVaishali Kulkarni uint_t pr_valsize, 2322*14b24e2bSVaishali Kulkarni void *pr_val) 2323*14b24e2bSVaishali Kulkarni { 2324*14b24e2bSVaishali Kulkarni qede_t *qede = (qede_t *)arg; 2325*14b24e2bSVaishali Kulkarni struct ecore_dev *edev = &qede->edev; 2326*14b24e2bSVaishali Kulkarni link_state_t link_state; 2327*14b24e2bSVaishali Kulkarni link_duplex_t link_duplex; 2328*14b24e2bSVaishali Kulkarni uint64_t link_speed; 2329*14b24e2bSVaishali Kulkarni link_flowctrl_t link_flowctrl; 2330*14b24e2bSVaishali Kulkarni struct qede_link_cfg link_cfg; 2331*14b24e2bSVaishali Kulkarni qede_link_cfg_t *hw_cfg = &qede->hwinit; 2332*14b24e2bSVaishali Kulkarni int ret_val = 0; 2333*14b24e2bSVaishali Kulkarni 2334*14b24e2bSVaishali Kulkarni memset(&link_cfg, 0, sizeof (struct qede_link_cfg)); 2335*14b24e2bSVaishali Kulkarni qede_get_link_info(&edev->hwfns[0], &link_cfg); 2336*14b24e2bSVaishali Kulkarni 2337*14b24e2bSVaishali Kulkarni 2338*14b24e2bSVaishali Kulkarni 2339*14b24e2bSVaishali Kulkarni switch (pr_num) 2340*14b24e2bSVaishali Kulkarni { 2341*14b24e2bSVaishali Kulkarni case MAC_PROP_MTU: 2342*14b24e2bSVaishali Kulkarni 2343*14b24e2bSVaishali Kulkarni ASSERT(pr_valsize >= sizeof(uint32_t)); 2344*14b24e2bSVaishali Kulkarni bcopy(&qede->mtu, pr_val, sizeof(uint32_t)); 2345*14b24e2bSVaishali Kulkarni break; 2346*14b24e2bSVaishali Kulkarni 2347*14b24e2bSVaishali Kulkarni case MAC_PROP_DUPLEX: 2348*14b24e2bSVaishali Kulkarni 2349*14b24e2bSVaishali Kulkarni ASSERT(pr_valsize >= sizeof(link_duplex_t)); 2350*14b24e2bSVaishali Kulkarni link_duplex = (qede->props.link_duplex) ? 2351*14b24e2bSVaishali Kulkarni LINK_DUPLEX_FULL : LINK_DUPLEX_HALF; 2352*14b24e2bSVaishali Kulkarni bcopy(&link_duplex, pr_val, sizeof(link_duplex_t)); 2353*14b24e2bSVaishali Kulkarni break; 2354*14b24e2bSVaishali Kulkarni 2355*14b24e2bSVaishali Kulkarni case MAC_PROP_SPEED: 2356*14b24e2bSVaishali Kulkarni 2357*14b24e2bSVaishali Kulkarni ASSERT(pr_valsize >= sizeof(link_speed)); 2358*14b24e2bSVaishali Kulkarni 2359*14b24e2bSVaishali Kulkarni link_speed = (qede->props.link_speed * 1000000ULL); 2360*14b24e2bSVaishali Kulkarni bcopy(&link_speed, pr_val, sizeof(link_speed)); 2361*14b24e2bSVaishali Kulkarni break; 2362*14b24e2bSVaishali Kulkarni 2363*14b24e2bSVaishali Kulkarni case MAC_PROP_STATUS: 2364*14b24e2bSVaishali Kulkarni 2365*14b24e2bSVaishali Kulkarni ASSERT(pr_valsize >= sizeof(link_state_t)); 2366*14b24e2bSVaishali Kulkarni 2367*14b24e2bSVaishali Kulkarni link_state = (qede->params.link_state) ? 2368*14b24e2bSVaishali Kulkarni LINK_STATE_UP : LINK_STATE_DOWN; 2369*14b24e2bSVaishali Kulkarni bcopy(&link_state, pr_val, sizeof(link_state_t)); 2370*14b24e2bSVaishali Kulkarni qede_info(qede, "mac_prop_status %d\n", link_state); 2371*14b24e2bSVaishali Kulkarni break; 2372*14b24e2bSVaishali Kulkarni 2373*14b24e2bSVaishali Kulkarni case MAC_PROP_AUTONEG: 2374*14b24e2bSVaishali Kulkarni 2375*14b24e2bSVaishali Kulkarni *(uint8_t *)pr_val = link_cfg.autoneg; 2376*14b24e2bSVaishali Kulkarni break; 2377*14b24e2bSVaishali Kulkarni 2378*14b24e2bSVaishali Kulkarni case MAC_PROP_FLOWCTRL: 2379*14b24e2bSVaishali Kulkarni 2380*14b24e2bSVaishali Kulkarni ASSERT(pr_valsize >= sizeof(link_flowctrl_t)); 2381*14b24e2bSVaishali Kulkarni 2382*14b24e2bSVaishali Kulkarni /* 2383*14b24e2bSVaishali Kulkarni * illumos does not have the notion of LINK_FLOWCTRL_AUTO at this time. 2384*14b24e2bSVaishali Kulkarni */ 2385*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS 2386*14b24e2bSVaishali Kulkarni if (link_cfg.pause_cfg & QEDE_LINK_PAUSE_AUTONEG_ENABLE) { 2387*14b24e2bSVaishali Kulkarni link_flowctrl = LINK_FLOWCTRL_AUTO; 2388*14b24e2bSVaishali Kulkarni } 2389*14b24e2bSVaishali Kulkarni #endif 2390*14b24e2bSVaishali Kulkarni 2391*14b24e2bSVaishali Kulkarni if (!(link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) && 2392*14b24e2bSVaishali Kulkarni !(link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) { 2393*14b24e2bSVaishali Kulkarni link_flowctrl = LINK_FLOWCTRL_NONE; 2394*14b24e2bSVaishali Kulkarni } 2395*14b24e2bSVaishali Kulkarni if ((link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) && 2396*14b24e2bSVaishali Kulkarni !(link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) { 2397*14b24e2bSVaishali Kulkarni link_flowctrl = LINK_FLOWCTRL_RX; 2398*14b24e2bSVaishali Kulkarni } 2399*14b24e2bSVaishali Kulkarni if (!(link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) && 2400*14b24e2bSVaishali Kulkarni (link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) { 2401*14b24e2bSVaishali Kulkarni link_flowctrl = LINK_FLOWCTRL_TX; 2402*14b24e2bSVaishali Kulkarni } 2403*14b24e2bSVaishali Kulkarni if ((link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) && 2404*14b24e2bSVaishali Kulkarni (link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) { 2405*14b24e2bSVaishali Kulkarni link_flowctrl = LINK_FLOWCTRL_BI; 2406*14b24e2bSVaishali Kulkarni } 2407*14b24e2bSVaishali Kulkarni 2408*14b24e2bSVaishali Kulkarni bcopy(&link_flowctrl, pr_val, sizeof (link_flowctrl_t)); 2409*14b24e2bSVaishali Kulkarni break; 2410*14b24e2bSVaishali Kulkarni 2411*14b24e2bSVaishali Kulkarni case MAC_PROP_ADV_10GFDX_CAP: 2412*14b24e2bSVaishali Kulkarni *(uint8_t *)pr_val = link_cfg.adv_capab.param_10000fdx; 2413*14b24e2bSVaishali Kulkarni break; 2414*14b24e2bSVaishali Kulkarni 2415*14b24e2bSVaishali Kulkarni case MAC_PROP_EN_10GFDX_CAP: 2416*14b24e2bSVaishali Kulkarni *(uint8_t *)pr_val = qede->forced_speed_10G; 2417*14b24e2bSVaishali Kulkarni break; 2418*14b24e2bSVaishali Kulkarni 2419*14b24e2bSVaishali Kulkarni case MAC_PROP_PRIVATE: 2420*14b24e2bSVaishali Kulkarni default: 2421*14b24e2bSVaishali Kulkarni return (ENOTSUP); 2422*14b24e2bSVaishali Kulkarni 2423*14b24e2bSVaishali Kulkarni } 2424*14b24e2bSVaishali Kulkarni 2425*14b24e2bSVaishali Kulkarni return (0); 2426*14b24e2bSVaishali Kulkarni } 2427*14b24e2bSVaishali Kulkarni 2428*14b24e2bSVaishali Kulkarni static void 2429*14b24e2bSVaishali Kulkarni qede_mac_property_info(void *arg, 2430*14b24e2bSVaishali Kulkarni const char *pr_name, 2431*14b24e2bSVaishali Kulkarni mac_prop_id_t pr_num, 2432*14b24e2bSVaishali Kulkarni mac_prop_info_handle_t prh) 2433*14b24e2bSVaishali Kulkarni { 2434*14b24e2bSVaishali Kulkarni qede_t *qede = (qede_t *)arg; 2435*14b24e2bSVaishali Kulkarni qede_link_props_t *def_cfg = &qede_def_link_props; 2436*14b24e2bSVaishali Kulkarni link_flowctrl_t link_flowctrl; 2437*14b24e2bSVaishali Kulkarni 2438*14b24e2bSVaishali Kulkarni 2439*14b24e2bSVaishali Kulkarni switch (pr_num) 2440*14b24e2bSVaishali Kulkarni { 2441*14b24e2bSVaishali Kulkarni 2442*14b24e2bSVaishali Kulkarni case MAC_PROP_STATUS: 2443*14b24e2bSVaishali Kulkarni case MAC_PROP_SPEED: 2444*14b24e2bSVaishali Kulkarni case MAC_PROP_DUPLEX: 2445*14b24e2bSVaishali Kulkarni mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 2446*14b24e2bSVaishali Kulkarni break; 2447*14b24e2bSVaishali Kulkarni 2448*14b24e2bSVaishali Kulkarni case MAC_PROP_MTU: 2449*14b24e2bSVaishali Kulkarni 2450*14b24e2bSVaishali Kulkarni mac_prop_info_set_range_uint32(prh, 2451*14b24e2bSVaishali Kulkarni MIN_MTU, 2452*14b24e2bSVaishali Kulkarni MAX_MTU); 2453*14b24e2bSVaishali Kulkarni break; 2454*14b24e2bSVaishali Kulkarni 2455*14b24e2bSVaishali Kulkarni case MAC_PROP_AUTONEG: 2456*14b24e2bSVaishali Kulkarni 2457*14b24e2bSVaishali Kulkarni mac_prop_info_set_default_uint8(prh, def_cfg->autoneg); 2458*14b24e2bSVaishali Kulkarni break; 2459*14b24e2bSVaishali Kulkarni 2460*14b24e2bSVaishali Kulkarni case MAC_PROP_FLOWCTRL: 2461*14b24e2bSVaishali Kulkarni 2462*14b24e2bSVaishali Kulkarni if (!def_cfg->pause) { 2463*14b24e2bSVaishali Kulkarni link_flowctrl = LINK_FLOWCTRL_NONE; 2464*14b24e2bSVaishali Kulkarni } else { 2465*14b24e2bSVaishali Kulkarni link_flowctrl = LINK_FLOWCTRL_BI; 2466*14b24e2bSVaishali Kulkarni } 2467*14b24e2bSVaishali Kulkarni 2468*14b24e2bSVaishali Kulkarni mac_prop_info_set_default_link_flowctrl(prh, link_flowctrl); 2469*14b24e2bSVaishali Kulkarni break; 2470*14b24e2bSVaishali Kulkarni 2471*14b24e2bSVaishali Kulkarni case MAC_PROP_EN_10GFDX_CAP: 2472*14b24e2bSVaishali Kulkarni mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW); 2473*14b24e2bSVaishali Kulkarni break; 2474*14b24e2bSVaishali Kulkarni 2475*14b24e2bSVaishali Kulkarni case MAC_PROP_ADV_10GFDX_CAP: 2476*14b24e2bSVaishali Kulkarni mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 2477*14b24e2bSVaishali Kulkarni break; 2478*14b24e2bSVaishali Kulkarni 2479*14b24e2bSVaishali Kulkarni default: 2480*14b24e2bSVaishali Kulkarni mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 2481*14b24e2bSVaishali Kulkarni break; 2482*14b24e2bSVaishali Kulkarni 2483*14b24e2bSVaishali Kulkarni } 2484*14b24e2bSVaishali Kulkarni } 2485*14b24e2bSVaishali Kulkarni 2486*14b24e2bSVaishali Kulkarni static mac_callbacks_t qede_callbacks = 2487*14b24e2bSVaishali Kulkarni { 2488*14b24e2bSVaishali Kulkarni ( 2489*14b24e2bSVaishali Kulkarni MC_IOCTL 2490*14b24e2bSVaishali Kulkarni /* | MC_RESOURCES */ 2491*14b24e2bSVaishali Kulkarni | MC_SETPROP 2492*14b24e2bSVaishali Kulkarni | MC_GETPROP 2493*14b24e2bSVaishali Kulkarni | MC_PROPINFO 2494*14b24e2bSVaishali Kulkarni | MC_GETCAPAB 2495*14b24e2bSVaishali Kulkarni ), 2496*14b24e2bSVaishali Kulkarni qede_mac_stats, 2497*14b24e2bSVaishali Kulkarni qede_mac_start, 2498*14b24e2bSVaishali Kulkarni qede_mac_stop, 2499*14b24e2bSVaishali Kulkarni qede_mac_promiscuous, 2500*14b24e2bSVaishali Kulkarni qede_mac_multicast, 2501*14b24e2bSVaishali Kulkarni NULL, 2502*14b24e2bSVaishali Kulkarni #ifndef NO_CROSSBOW 2503*14b24e2bSVaishali Kulkarni NULL, 2504*14b24e2bSVaishali Kulkarni #else 2505*14b24e2bSVaishali Kulkarni qede_mac_tx, 2506*14b24e2bSVaishali Kulkarni #endif 2507*14b24e2bSVaishali Kulkarni NULL, /* qede_mac_resources, */ 2508*14b24e2bSVaishali Kulkarni qede_mac_ioctl, 2509*14b24e2bSVaishali Kulkarni qede_mac_get_capability, 2510*14b24e2bSVaishali Kulkarni NULL, 2511*14b24e2bSVaishali Kulkarni NULL, 2512*14b24e2bSVaishali Kulkarni qede_mac_set_property, 2513*14b24e2bSVaishali Kulkarni qede_mac_get_property, 2514*14b24e2bSVaishali Kulkarni #ifdef MC_PROPINFO 2515*14b24e2bSVaishali Kulkarni qede_mac_property_info 2516*14b24e2bSVaishali Kulkarni #endif 2517*14b24e2bSVaishali Kulkarni }; 2518*14b24e2bSVaishali Kulkarni 2519*14b24e2bSVaishali Kulkarni boolean_t 2520*14b24e2bSVaishali Kulkarni qede_gld_init(qede_t *qede) 2521*14b24e2bSVaishali Kulkarni { 2522*14b24e2bSVaishali Kulkarni int status, ret; 2523*14b24e2bSVaishali Kulkarni mac_register_t *macp; 2524*14b24e2bSVaishali Kulkarni 2525*14b24e2bSVaishali Kulkarni macp = mac_alloc(MAC_VERSION); 2526*14b24e2bSVaishali Kulkarni if (macp == NULL) { 2527*14b24e2bSVaishali Kulkarni cmn_err(CE_NOTE, "%s: mac_alloc() failed\n", __func__); 2528*14b24e2bSVaishali Kulkarni return (B_FALSE); 2529*14b24e2bSVaishali Kulkarni } 2530*14b24e2bSVaishali Kulkarni 2531*14b24e2bSVaishali Kulkarni macp->m_driver = qede; 2532*14b24e2bSVaishali Kulkarni macp->m_dip = qede->dip; 2533*14b24e2bSVaishali Kulkarni macp->m_instance = qede->instance; 2534*14b24e2bSVaishali Kulkarni macp->m_priv_props = NULL; 2535*14b24e2bSVaishali Kulkarni macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 2536*14b24e2bSVaishali Kulkarni macp->m_src_addr = qede->ether_addr; 2537*14b24e2bSVaishali Kulkarni macp->m_callbacks = &qede_callbacks; 2538*14b24e2bSVaishali Kulkarni macp->m_min_sdu = 0; 2539*14b24e2bSVaishali Kulkarni macp->m_max_sdu = qede->mtu; 2540*14b24e2bSVaishali Kulkarni macp->m_margin = VLAN_TAGSZ; 2541*14b24e2bSVaishali Kulkarni #ifdef ILLUMOS 2542*14b24e2bSVaishali Kulkarni macp->m_v12n = MAC_VIRT_LEVEL1; 2543*14b24e2bSVaishali Kulkarni #endif 2544*14b24e2bSVaishali Kulkarni 2545*14b24e2bSVaishali Kulkarni status = mac_register(macp, &qede->mac_handle); 2546*14b24e2bSVaishali Kulkarni if (status != 0) { 2547*14b24e2bSVaishali Kulkarni cmn_err(CE_NOTE, "%s: mac_register() failed\n", __func__); 2548*14b24e2bSVaishali Kulkarni } 2549*14b24e2bSVaishali Kulkarni 2550*14b24e2bSVaishali Kulkarni mac_free(macp); 2551*14b24e2bSVaishali Kulkarni if (status == 0) { 2552*14b24e2bSVaishali Kulkarni return (B_TRUE); 2553*14b24e2bSVaishali Kulkarni } 2554*14b24e2bSVaishali Kulkarni return (B_FALSE); 2555*14b24e2bSVaishali Kulkarni } 2556*14b24e2bSVaishali Kulkarni 2557*14b24e2bSVaishali Kulkarni boolean_t qede_gld_fini(qede_t * qede) 2558*14b24e2bSVaishali Kulkarni { 2559*14b24e2bSVaishali Kulkarni return (B_TRUE); 2560*14b24e2bSVaishali Kulkarni } 2561*14b24e2bSVaishali Kulkarni 2562*14b24e2bSVaishali Kulkarni 2563*14b24e2bSVaishali Kulkarni void qede_link_update(qede_t * qede, 2564*14b24e2bSVaishali Kulkarni link_state_t state) 2565*14b24e2bSVaishali Kulkarni { 2566*14b24e2bSVaishali Kulkarni mac_link_update(qede->mac_handle, state); 2567*14b24e2bSVaishali Kulkarni } 2568*14b24e2bSVaishali Kulkarni 2569