Depending on version of Solaris and the hardware it’s running on, you will either use ndd utility or use kstat or dladm commands to change speed and duplex. Remember that for example, e1000g driver will let you manipulate settings using dladm in Solaris 10, but you will not be able to do so using ndd. This is also true among different Solaris versions. For example, dladm is present only in Solaris 10.

First, let’s see what the current settings are. To do that you can use kstat or ndd commands. The following output is truncated to include only info we are interested in.

bash-3.00# kstat -m e1000g -i 0
module: e1000g                          instance: 0     
name:   mac                             class:    net
     adv_cap_1000fdx                 1
     adv_cap_1000hdx                 0
     adv_cap_100fdx                  1
     adv_cap_100hdx                  1
     adv_cap_10fdx                   1
     adv_cap_10hdx                   1
     adv_cap_asmpause                1
     adv_cap_autoneg                 1

Setting these variables on or off basically tells the driver if it should advertise corresponding capability. So setting adv_cap_100hdx to 0 will cause Solaris to stop advertising 100 half duplex capability.

If you are using hme driver you will need to use ndd command to view current setting:

bash-3.00# ndd -get /dev/hme link_speed

The “disadvantage” here is that you have to remember the name of the setting you are trying to query. If you are running Solaris 10 with GLDv3 (project Nemo) driver you can use dladm command:

bash-3.0# dladm show-dev
e1000g0         link: up        speed: 1000  Mbps       duplex: full

Now let see how to change the settings. You can immediately disable advertisement of 100 half-duplex capability using ndd:

bash-3.00# ndd -set /dev/hme adv_cap_100hdx 0

Similarly you can do the same using dladm:

bash-3.00# dladm set-linkprop -p adv_1000hdx_cap=0 e1000g0

Note that in neither case will changes persist across reboot. To make the changes stick after a reboot you can edit /etc/system file and add approriate entries for your hardware:

set eri:adv_100hdx_cap=0

Another option is to edit driver’s .conf file in /kernel/drv directory. For example, /kernel/drv/e1000g.conf

Next option is to create an rc script in /etc/rc3.d directory that contains individual ndd or dladm commands.

One last option, which only work in Solaris 10 is described in dladm man page. You can create SMF manifest. This is straight from dladm man page:

<?xml version='1.0'?>
<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
<service_bundle type='manifest'name='apply_linkprop'>
<service>
       name='network/apply_linkprop'
       type='service'
       version='1'>

       <instance name='default' enabled='true'>

       <dependency
               name='dlmgmtd'
               grouping='require_all'
               restart_ov='none'
               type='service'>
       <service_fmri value='svc:/network/datalink-management:default' />
       </dependency>

       <exec_method
               type='method'
               name='stop'
               exec=':true'
               timeout_seconds='3' />

       <property_group name='startd' type='framework'>
               <propval name='duration' type='astring' value='transient' />
       </property_group>

       </instance>

              <stability value='Evolving' />
</service>
</service_bundle>

Store the manifest in /lib/svc/manifest/network. Then create method in /lib/svc/method that contains appropriate commands, for example:

dladm set-linkprop -p adv_1000hdx_cap=0 e1000g0

I think this last option is the most elegant as it nicely integrates with the system.