31
31
static int vmxnet3_start(void *);
32
32
static void vmxnet3_stop(void *);
33
33
static int vmxnet3_setpromisc(void *, boolean_t);
34
static void vmxnet3_ioctl(void *arg, queue_t *wq, mblk_t *mp);
34
35
static int vmxnet3_multicst(void *, boolean_t, const uint8_t *);
35
36
static int vmxnet3_unicst(void *, const uint8_t *);
36
37
static boolean_t vmxnet3_getcapab(void *, mac_capab_t, void *);
38
39
/* MAC callbacks */
39
40
static mac_callbacks_t vmxnet3_mac_callbacks = {
40
MC_GETCAPAB, /* mc_callbacks */
41
vmxnet3_getstat, /* mc_getstat */
42
vmxnet3_start, /* mc_start */
43
vmxnet3_stop, /* mc_stop */
44
vmxnet3_setpromisc, /* mc_setpromisc */
45
vmxnet3_multicst, /* mc_multicst */
46
vmxnet3_unicst, /* mc_unicst */
47
vmxnet3_tx, /* mc_tx */
41
.mc_callbacks = MC_GETCAPAB | MC_IOCTL,
42
.mc_getstat = vmxnet3_getstat,
43
.mc_start = vmxnet3_start,
44
.mc_stop = vmxnet3_stop,
45
.mc_setpromisc = vmxnet3_setpromisc,
46
.mc_multicst = vmxnet3_multicst,
47
.mc_unicst = vmxnet3_unicst,
48
49
#ifndef OPEN_SOLARIS
49
NULL, /* mc_resources */
52
vmxnet3_getcapab /* mc_getcapab */
52
.mc_ioctl = vmxnet3_ioctl,
53
.mc_getcapab = *vmxnet3_getcapab,
55
56
/* Tx DMA engine description */
938
940
return DDI_SUCCESS;
945
*---------------------------------------------------------------------------
947
* vmxnet3_change_mtu --
949
* Change the MTU as seen by the driver. Reset the device and tx/rx queues
950
* so that buffers of right size are posted in rx queues.
953
* EINVAL for invalid MTUs or other failures. 0 for success.
958
*---------------------------------------------------------------------------
962
vmxnet3_change_mtu(vmxnet3_softc_t *dp, uint32_t new_mtu)
964
int ret = 0, do_reset = 0;
966
if (new_mtu == dp->cur_mtu) {
967
VMXNET3_WARN(dp, "New MTU is same as old mtu : %d.\n", new_mtu);
971
if (new_mtu < VMXNET3_MIN_MTU || new_mtu > VMXNET3_MAX_MTU) {
972
VMXNET3_WARN(dp, "New MTU not in valid range [%d, %d].\n",
973
VMXNET3_MIN_MTU, VMXNET3_MAX_MTU);
977
if (dp->devEnabled) {
980
VMXNET3_BAR1_PUT32(dp, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
983
dp->cur_mtu = new_mtu;
986
ret = vmxnet3_start(dp);
993
*---------------------------------------------------------------------------
997
* DDI/DDK callback to handle IOCTL in driver. Currently it only handles
998
* ND_SET ioctl. Rest all are ignored. The ND_SET is used to set/reset
999
* accept-jumbo ndd parameted for the interface.
1002
* Nothing is returned directly. An ACK or NACK is conveyed to the calling
1003
* function from the mblk which was used to call this function.
1006
* MTU can be changed and device can be reset.
1008
*---------------------------------------------------------------------------
1012
vmxnet3_ioctl(void *arg, queue_t *wq, mblk_t *mp)
1014
vmxnet3_softc_t *dp = arg;
1021
iocp = (void *)mp->b_rptr;
1022
iocp->ioc_error = 0;
1024
switch (iocp->ioc_cmd) {
1027
/* the mblk in continuation would contain the ndd parameter name
1028
* and data value to be set
1032
VMXNET3_WARN(dp, "Error locating parameter name.\n");
1037
mp1->b_datap->db_lim[-1] = '\0'; /* Force null termination */
1040
* From /usr/src/uts/common/inet/nd.c : nd_getset()
1041
* "logic throughout nd_xxx assumes single data block for ioctl.
1042
* However, existing code sends in some big buffers."
1045
freemsg(mp1->b_cont);
1049
valp = (char *)mp1->b_rptr; /* Points to param name*/
1052
VMXNET3_DEBUG(dp, 3, "ND Set ioctl for %s\n", param);
1054
/* Go past the end of this null terminated string to get the data value.*/
1055
while (*valp && valp <= (char *)mp1->b_wptr)
1058
if (valp > (char *)mp1->b_wptr) {
1059
/* We are already beyond the readable area of mblk and still havent
1060
* found the end of param string.
1062
VMXNET3_WARN(dp, "No data value found to be set to param.\n");
1065
valp++; /* Now this points to data string */
1066
data = (int)*valp - (int)'0'; /* Get numeric value of first letter */
1069
if (strcmp("accept-jumbo", param) == 0) {
1071
VMXNET3_DEBUG(dp, 2, "Accepting jumbo frames\n");
1072
ret = vmxnet3_change_mtu(dp, VMXNET3_MAX_MTU);
1073
} else if (data == 0) {
1074
VMXNET3_DEBUG(dp, 2, "Rejecting jumbo frames\n");
1075
ret = vmxnet3_change_mtu(dp, ETHERMTU);
1077
VMXNET3_WARN(dp, "Invalid data value to be set, use 1 or 0.\n");
1087
freemsg(mp->b_cont);
1095
miocack(wq, mp, 0, 0);
1097
miocnak(wq, mp, 0, EINVAL);
942
1102
*---------------------------------------------------------------------------
1274
1436
case VMXNET3_IT_AUTO:
1275
1437
case VMXNET3_IT_MSIX:
1276
1438
dp->intrType = DDI_INTR_TYPE_MSIX;
1277
if (ddi_intr_alloc(dip, &dp->intrHandle, dp->intrType, 0, 1,
1278
&ret, DDI_INTR_ALLOC_STRICT) == DDI_SUCCESS) {
1439
err = ddi_intr_alloc(dip, &dp->intrHandle, dp->intrType, 0, 1,
1440
&ret, DDI_INTR_ALLOC_STRICT);
1441
if (err == DDI_SUCCESS)
1281
VMXNET3_DEBUG(dp, 2, "DDI_INTR_TYPE_MSIX failed\n");
1443
VMXNET3_DEBUG(dp, 2, "DDI_INTR_TYPE_MSIX failed, err:%d\n", err);
1282
1444
case VMXNET3_IT_MSI:
1283
1445
dp->intrType = DDI_INTR_TYPE_MSI;
1284
1446
if (ddi_intr_alloc(dip, &dp->intrHandle, dp->intrType, 0, 1,
1285
&ret, DDI_INTR_ALLOC_STRICT) == DDI_SUCCESS) {
1447
&ret, DDI_INTR_ALLOC_STRICT) == DDI_SUCCESS)
1288
1449
VMXNET3_DEBUG(dp, 2, "DDI_INTR_TYPE_MSI failed\n");
1289
1450
case VMXNET3_IT_INTX:
1290
1451
dp->intrType = DDI_INTR_TYPE_FIXED;
1335
1496
goto error_mutexes;
1338
if (ddi_intr_enable(dp->intrHandle) != DDI_SUCCESS) {
1339
VMXNET3_WARN(dp, "ddi_intr_enable() failed\n");
1499
err = ddi_intr_get_cap(dp->intrHandle, &dp->intrCap);
1500
if (err != DDI_SUCCESS) {
1501
VMXNET3_WARN(dp, "ddi_intr_get_cap() failed %d", err);
1340
1502
goto error_intr_handler;
1505
if (dp->intrCap & DDI_INTR_FLAG_BLOCK) {
1506
err = ddi_intr_block_enable(&dp->intrHandle, 1);
1507
if (err != DDI_SUCCESS) {
1508
VMXNET3_WARN(dp, "ddi_intr_block_enable() failed, err:%d\n", err);
1509
goto error_intr_handler;
1512
err = ddi_intr_enable(dp->intrHandle);
1513
if ((err != DDI_SUCCESS)) {
1514
VMXNET3_WARN(dp, "ddi_intr_enable() failed, err:%d\n", err);
1515
goto error_intr_handler;
1343
1519
return DDI_SUCCESS;
1345
1521
error_intr_handler: