# hotplug scripts problem with prism54 driver.

## dopey

I picked up an Xterasys mini-PCI 802.11g card.  It works perfectly under linux except for the problem below:

I'm working on trying to get the prism54 driver to transparently work at startup and I'm running into one snag. Based on the logs that I'm seeing, it appears that hotplug is registering the net device first, therefore running net.agent (and starting net.[interface]), then it registers the firmware and loads that (via firmware.agent).

The problem is I use dhcp to grab an address.. dhcpcd fails to work because net.eth0 is being run before the firmware is loaded (i.e. the hardware is completely ready to go). I can kill dhcpcd, and restart net.eth0 and all is good.  If I go static, it's fine, since ifconfig doesn't really care that the device is ready to go (as long as eth0 itself is already registered) but at work I pretty much HAVE to use DHCP.

I have a modified net.eth0 used to load ssid and wep keys and such. Any suggestions around this problem would be greatly appreciated.

----------

## dopey

Problem solved.

I modified Faye Pearson's net.ath0 script.  Actually, I more or less took her changes, plopped them into the latest stable net.eth0 script and made a few changes since a number of things don't work properly with the prism54.  Also modified the gateway and dhcpd handling of the script to be a little more SSID specific.

This seems to work okay for me.

There's one problem.  The line 

wireless_IFACE="$(iwconfig 2>/dev/null | gawk -v IFACE="${IFACE}" '/XG-600/ { if ($1 == IFACE) print "yes" }')"

uses XG-600 because it's the only unique string that always occurs on the first line of the ethX output.  I tried to make it more generic and look for the interface line and then check if "no wireless extensions" is in the latter part of the string, but for some reason gawk seems to pull the whole line as one string.  I don't know what characters iwconfig is using for breaking up the line, but whatever it is gawk isn't breaking it.

begin script:

#!/sbin/runscript

# Copyright 1999-2003 Gentoo Technologies, Inc.

# Distributed under the terms of the GNU General Public License v2

# $Header: /home/cvsroot/gentoo-src/rc-scripts/init.d/net.eth0,v 1.31 2003/09/08 00:11:54 azarah Exp $

#NB: Config is in /etc/conf.d/net

# For pcmcia users. note that pcmcia must be added to the same

# runlevel as the net.* script that needs it.

depend() {

        use hotplug pcmcia

}

checkconfig() {

        if [ -z "${iface_IFACE}" ]

        then

                eerror "Please make sure that /etc/conf.d/net has \$iface_$IFACE set"

                return 1

        fi

        if [ -n "${vlans}" -a \! -x /sbin/vconfig ]

        then

                eerror "For VLAN (802.1q) support, emerge net-misc/vconfig"

                return 1

        fi

}

setup_env() {

        # No reason to check these multiple times in the file

        iface="${1/\./_}"

        iface_IFACE="$(eval echo \$\{iface_${iface}\})"

        dhcpcd_IFACE="$(eval echo \$\{dhcpcd_${iface}\})"

        inet6_IFACE="$(eval echo \$\{inet6_${iface}\})"

        alias_IFACE="$(eval echo \$\{alias_${iface}\})"

        status_IFACE="$(ifconfig | gawk -v IFACE="${iface}" '/Link/ { if ($1 == IFACE) print "up" }')"

        vlans="$(eval echo \$\{iface_${IFACE}_vlans\})"

        if [ -x `which iwconfig` ]; then

                wireless_IFACE="$(iwconfig 2>/dev/null | gawk -v IFACE="${IFACE}" '/XG-600/ { if ($1 == IFACE) print "yes" }')"

        fi

        wireless_IFACE=${wireless_IFACE:-"no"}

# mii-tool doesn't work with prism54

#        if [ -x `which mii-tool` ]; then

#                link_IFACE=$(mii-tool ${IFACE} 2>/dev/null | gawk '{print $2}')

#        fi

#        link_IFACE=${link_IFACE:-"yes"}

}

setup_wireless() {

        # Reset to some defaults

        iwconfig $IFACE mode Managed

# setting rate doesn't work with prism54

#        iwconfig $IFACE rate auto

        iwconfig $IFACE key off

        iwconfig $IFACE rts off

        iwconfig $IFACE frag off

        iwconfig $IFACE essid any

        # Initiate a scan

        ifconfig $IFACE up

        # Wait for a response

        sleep 2

        # Find known access points

        for AP in `iwlist ${IFACE} scan 2>/dev/null | grep ESSID | awk -F: '{print $2}' | sed 's/[-"]//g'`; do

                if [ -z ${essid_AP} ]; then

                        essid_AP="$(eval echo \$\{essid_${AP}\})"

                        if [ ! -z ${essid_AP} ]; then

                                # setup variables

                                key_AP="$(eval echo \$\{key_${AP}\})"

                                iface_IFACE="$(eval echo \$\{iface_${AP}\})"

                                dhcpcd_IFACE="$(eval echo \$\{dhcpcd_${AP}\})"

                                gateway_AP="$(eval echo \$\{gateway_${AP}\})"

                                if [ ! -z ${gateway_AP} ]; then

                                    gateway="${IFACE}/${gateway_AP}"

                                fi

                        fi

                fi

        done

        # Bring interface down to apply changes

        ifconfig $IFACE down

#ewarn "Setting wireless parameters ${essid_AP} and ${key_AP}"

        if [ ! -z ${essid_AP} ]; then

                iwconfig ${IFACE} essid ${essid_AP}

        fi

        if [ ! -z ${key_AP} ]; then

                iwconfig ${IFACE} key ${key_AP}

        fi

        # Bring the interface up

        ifconfig $IFACE up

        # Wait for the system to associate

        # prism54 stuff defaults to 00:00:00:00:00:00 for AP MAC address when not associated

        while [ `iwconfig $IFACE | awk '/\<..:..:..:..:..:..\>/{print}' | sed 's/^.*\<\(..:..:..:..:..:..\)\>.*$/\1/g'` = 00:00:00:00:00:00 ]; do

                LC_NUMERIC=C sleep 0.5

        done

        return 0

}

iface_start() {

        local retval=0

        setup_env ${1}

        checkconfig || return 1

        if [ ${wireless_IFACE} == "yes" ]; then

                ebegin "Detecting network for ${IFACE}"

                setup_wireless

                eend 0

        fi

        local IFACE="${1}"

        ebegin "Bringing ${IFACE} up"

        if [ "${iface_IFACE}" != "dhcp" ]

        then

                /sbin/ifconfig ${IFACE} ${iface_IFACE} >/dev/null || {

                        retval=$?

                        eend ${retval} "Failed to bring ${IFACE} up"

                        return ${retval}

                }

                # ifconfig do not always return failure ..

                /sbin/ifconfig ${IFACE} &> /dev/null || {

                        retval=$?

                        eend ${retval} "Failed to bring ${IFACE} up"

                        return ${retval}

                }

        else

                # Check that eth0 was not brough up by the kernel ...

                if [ "${status_IFACE}" != "up" ]

                then

                        /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} >/dev/null || {

                                retval=$?

                                eend ${retval} "Failed to bring ${IFACE} up"

                                return ${retval}

                        }

                fi

        fi

        eend 0

        if [ -n "${alias_IFACE}" ]

        then

                local x=""

                local num=0

                local aliasbcast=""

                local aliasnmask=""

                ebegin "  Adding aliases"

                for x in ${alias_IFACE}

                do

                        aliasbcast="$(eval echo \$\{broadcast_${iface}\} \| awk \'\{ print \$$((num + 1)) \}\')"

                        if [ -n "${aliasbcast}" ]

                        then

                                aliasbcast="broadcast ${aliasbcast}"

                        fi

                        aliasnmask="$(eval echo \$\{netmask_${iface}\} \| awk \'\{ print \$$((num + 1)) \}\')"

                        if [ -n "${aliasnmask}" ]

                        then

                                aliasnmask="netmask ${aliasnmask}"

                        fi

                        ebegin "    ${IFACE}:${num}"

                        /sbin/ifconfig ${IFACE}:${num} ${x} \

                                ${aliasbcast} ${aliasnmask} >/dev/null

                        num=$((num + 1))

                        eend 0

                done

                save_options "alias" "${alias_IFACE}"

        fi

        if [ -n "${inet6_IFACE}" ]

        then

                local x=""

                ebegin "  Adding inet6 addresses"

                for x in ${inet6_IFACE}

                do

                        ebegin "    ${IFACE} inet6 add ${x}"

                        /sbin/ifconfig ${IFACE} inet6 add ${x} >/dev/null

                        eend 0

                done

                save_options "inet6" "${inet6_IFACE}"

        fi

        if [ -n "${gateway}" ] && [ "${gateway%/*}" = "${IFACE}" ]

        then

                ebegin "  Setting default gateway"

                # First delete any existing routes if it was setup by kernel ..

                /sbin/route del default dev ${gateway%/*} &>/dev/null

                /sbin/route add default gw ${gateway#*/} dev ${gateway%/*} \

                        netmask 0.0.0.0 metric 1 >/dev/null || {

                        local error=$?

                        ifconfig ${IFACE} down &>/dev/null

                        eend ${error} "Failed to bring ${IFACE} up"

                        stop

                        return ${error}

                }

                eend 0

        fi

        # Enabling rp_filter causes wacky packets to be auto-dropped by

        # the kernel.  Note that we only do this if it is not set via

        # /etc/sysctl.conf ...

        if [ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter ] && \

           [ -z "$(egrep '^[^#]*rp_filter' /etc/sysctl.conf 2>/dev/null)" ]

        then

                echo 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter

        fi

}

iface_stop() {

        local myalias="$(get_options alias)"

        local myinet6="$(get_options inet6)"

        setup_env ${1}

        local IFACE="${1}"

        ebegin "Bringing ${IFACE} down"

        # Also down the inet6 interfaces

        if [ -n "${myinet6}" ]

        then

                local x=""

                for x in ${myinet6}

                do

                        /sbin/ifconfig ${IFACE} inet6 del ${x} >/dev/null

                done

        fi

        # Do some cleanup in case the amount of aliases change

        if [ -n "${myalias}" ]

        then

                local x=""

                local num=0

                for x in ${myalias}

                do

                        /sbin/ifconfig ${IFACE}:${num} down >/dev/null

                        num=$((num + 1))

                done

        fi

        if [ "${iface_IFACE}" = "dhcp" ]

        then

                local count=0

                while /sbin/dhcpcd -z ${IFACE} &>/dev/null && [ "${count}" -lt 9 ]

                do

                        # Give dhcpcd time to properly shutdown

                        sleep 1

                        count=$((count + 1))

                done

                if [ "${count}" -ge 9 ]

                then

                        eerror "Timed out trying to stop dhcpcd"

                fi

        else

                /sbin/ifconfig ${IFACE} down >/dev/null

        fi

        eend 0

}

start() {

        iface_start ${IFACE} || return 1

        for vlan in ${vlans}

        do

                /sbin/vconfig add ${IFACE} ${vlan} >/dev/null

                iface_start ${IFACE}.${vlan}

        done

}

stop () {

        setup_env ${IFACE}

        checkconfig || return 1

        for vlan in ${vlans}

        do

                iface_stop ${IFACE}.${vlan}

                /sbin/vconfig rem ${IFACE}.${vlan} >/dev/null

        done

        iface_stop ${IFACE}

}

# vim:ts=4

----------

## nigelhannam

Interesting...

I went down a kinda different route and prevented the networking side being triggered by hotplug, leaving it to just initialize the card.  I then have ifplugd looking out for the interface appearing, then bringing up the connection with the standard script.

I can have a look at exactly what changes I needed to make if you're interested

Nigel

----------

## dopey

hmmm.  this ifplugd you speak of intriques me  :Smile: .

It actually sounds very cool.  I'm going to look into it.  Did you disable networking completely for hotplug? or just hack the net.agent script to disable it for certain interfaces?  I was going to go down the disabling hotplug route until I found the net.ath0 script.  After that I didn't have a need for it but I always just assumed rm'ing or mv'ing net.agent would be enough to disable the network portion of hotplug.

----------

## nigelhannam

OK, I think these are the only steps I needed to take:

In  the net.agent file, I added the device that my wireless card comes up as to the list of ' # interfaces that are registered after being "up" (?)'

This prevents the net.$IF script being run by the hotplug event.

After emerge'ing ifplugd I set AUTO and MONITOR to yes in /etc/conf.d/ifplugd.

I also modified the net.ethX init scripts status detection line to:

status_IFACE="$(ifconfig ${iface} | gawk '/addr:/{a=1}/ UP /{ if (a == 1) print "up" }')"

(as per comment #3 in bug 28362 referred to in the ifplugd conf file when setting AUTO to yes)

I do remember that I played around a bit before settling on these settings, but they seem to work for both my wireless device and the onboard NIC so that I can now happily plug / unplug either device.

----------

## nigelhannam

Oh, and there's currently some kind of bug in the prism54 driver that requires the SSID to be set twice before it configures properly when SSID broadcast is disabled on the AP.  This prevents my current setup from working correctly

At the moment I've left SSID broadcast on, but I think adding another iwconfig call to set the SSID in the net.ethX script should get round the problem.

I'd rather avoid this change if possible, as it means having the SSID info in more than one config file, and I'd rather just see if the driver gets fixed in the near future.

----------

## dopey

i don't have that problem with my prism54 driver.  With SSID broadcast disabled, it still appears to work okay for me.  I have to have ssid broadcast enabled for now because the driver for one of my other systems using wireless doesn't like any non-broadcasted SSID.

----------

## nigelhannam

Strange.

This thread on the prism54.org forums was what I was basing that last comment on.

Calling iwconfig again as described seemed to fix the problem for me.

Do you remember what date snapshot of the driver you are using?  I think the version I'm using is only a couple of weeks old.

I suppose it could be something that only affects certain cards, but I don't really know enough about drivers to say if that's likely  :Sad: 

----------

## jay

If your prism54 card is a cardbus card, hotplug will invoke the pci agent instead of the net agent.

Just compile the prism54 driver as module and then create an executable bash script in /etc/hotplug/pci/prism54 and place all commands you need to get the card running into it:

```

#!/bin/bash

/etc/init.d/net.eth1 start

sleep 2

 ifconfig eth1 up

sleep 1

 iwconfig eth1 mode Managed

 iwconfig eth1 nickname "mynick"

 iwconfig eth1 key MY108BITWEPKEYHERE restricted

 iwconfig eth1 essid "MYESSID"

```

Now just plug in the card and everything should be up and running  :Smile: 

----------

## MasterK

I solved the problem with these steps:

 *Quote:*   

> In the net.agent file, I added the device that my wireless card comes up as to the list of ' # interfaces that are registered after being "up" (?)'
> 
> This prevents the net.$IF script being run by the hotplug event. 

 

After that, I created a new init-skript: /etc/init.d/wlan

```

#!/sbin/runscript

#depend() {

#   provide wlan   

#   }

start() {

#load module for rfswitch on Amilo M7400 if it's not done.

#modprobe fsam7400

   iwconfig eth1 essid 'your essid'

   iwconfig eth1 enc 'yourkey'

   sleep 5

   /etc/init.d/net.ethX start

   }

stop() {

   /etc/init.d/net.ethX stop

#unload rfswitch module...

#   rmmod fsam7400

   }

```

Just place your correct interface instead of net.ethX.

Now you can do 

```
rc-update add wlan default
```

and the device works after every reboot.

This works for me with ipw2100 too, so I think it could work for every wlan Adapter. I used MiniPCI Adapters.

MasterK

----------

